]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of /home/dsarrut/clitk3.server
authorDavid Sarrut <david.sarrut@gmail.com>
Fri, 4 Nov 2011 09:36:31 +0000 (10:36 +0100)
committerDavid Sarrut <david.sarrut@gmail.com>
Fri, 4 Nov 2011 09:36:31 +0000 (10:36 +0100)
45 files changed:
common/CMakeLists.txt
common/clitkCommon.h
common/clitkGateAsciiImageIO.cxx [new file with mode: 0644]
common/clitkGateAsciiImageIO.h [new file with mode: 0644]
common/clitkGateAsciiImageIOFactory.cxx [new file with mode: 0644]
common/clitkGateAsciiImageIOFactory.h [new file with mode: 0644]
common/clitkIO.cxx
registration/clitkGenericOptimizer.h
scripts/create_midP-2.0.sh
scripts/create_midP_masks-2.0.sh
scripts/midp_common.sh
scripts/registration.sh
segmentation/clitkExtractBones.cxx
segmentation/clitkExtractLung.cxx
segmentation/clitkExtractLung.ggo
segmentation/clitkExtractLungFilter.h
segmentation/clitkExtractLungFilter.txx
segmentation/clitkExtractLungGenericFilter.txx
segmentation/clitkExtractPatient.cxx
segmentation/clitkExtractPatientGenericFilter.cxx
segmentation/clitkMorphoMath.cxx
segmentation/clitkMotionMask.cxx
tools/CMakeLists.txt
tools/clitkAverageTemporalDimension.cxx
tools/clitkBinarizeImage.cxx
tools/clitkCombineImage.cxx
tools/clitkComposeVF.cxx
tools/clitkGammaIndex.cxx
tools/clitkImageArithm.cxx
tools/clitkImageConvert.cxx
tools/clitkInvertVF.cxx
tools/clitkMedianTemporalDimension.cxx
tools/clitkResampleImage.cxx
tools/clitkSetBackground.cxx
tools/clitkWarpImage.cxx
tools/clitkZeroVF.cxx
vv/CMakeLists.txt
vv/qt_ui/vvMainWindow.ui
vv/vv.cxx
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvReadState.cxx [new file with mode: 0644]
vv/vvReadState.h [new file with mode: 0644]
vv/vvSaveState.cxx [new file with mode: 0644]
vv/vvSaveState.h [new file with mode: 0644]

index 9f92d71426d8901a5dc0dc21cc76aa0a91af7f47..ec826a2340d4437e5d4dd546c865a2609671f74d 100644 (file)
@@ -24,6 +24,8 @@ SET(clitkCommon_SRC
   clitkXdrImageIOFactory.cxx
   clitkHndImageIO.cxx
   clitkHndImageIOFactory.cxx
+  clitkGateAsciiImageIO.cxx
+  clitkGateAsciiImageIOFactory.cxx
   clitkDicomRTDoseIO.cxx
   clitkDicomRTDoseIOFactory.cxx
   clitkOrientation.cxx
index 97808d8d870ba778887a8ba98542cd3ea7ddf8b5..769ca63f0bf4400cbb783cf53d3bd7b44b3fc293 100644 (file)
@@ -48,6 +48,24 @@ namespace clitk {
   typedef unsigned char uchar;
   typedef unsigned short ushort;
   typedef unsigned int uint;
+  
+#define CLITK_TRY_CATCH_EXIT(func) \
+  try { \
+    func; \
+  } \
+  catch (const itk::ExceptionObject& e) { \
+    e.Print(std::cout); \
+    exit(-1);\
+  } \
+  catch (const std::exception& e) { \
+    std::cout << e.what() << std::endl; \
+    exit(-2);\
+  } \
+  catch (...) { \
+    std::cout << "Unknown excpetion" << std::endl; \
+    exit(-3); \
+  }
+    
 
   //--------------------------------------------------------------------
   // when everything goes wrong
diff --git a/common/clitkGateAsciiImageIO.cxx b/common/clitkGateAsciiImageIO.cxx
new file mode 100644 (file)
index 0000000..f3d4a8d
--- /dev/null
@@ -0,0 +1,278 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+// std include
+#include <regex.h>
+#include <cstdio>
+#include <sstream>
+#include <iostream>
+using std::cout;
+using std::endl;
+
+// clitk include
+#include "clitkGateAsciiImageIO.h"
+#include "clitkCommon.h"
+
+// itk include
+#include <itkMetaDataObject.h>
+
+std::ostream& operator<<(std::ostream& os, const clitk::GateAsciiImageIO::GateAsciiHeader& header)
+{
+    os << "matrix_size=[" << header.matrix_size[0] << "," << header.matrix_size[1] << "," << header.matrix_size[2] << "]" << endl;
+    os << "resolution=[" << header.resolution[0] << "," << header.resolution[1] << "," << header.resolution[2] << "]" << endl;
+    os << "voxel_size=[" << header.voxel_size[0] << "," << header.voxel_size[1] << "," << header.voxel_size[2] << "]" << endl;
+    os << "nb_value=" << header.nb_value << endl;
+    return os;
+}
+
+//--------------------------------------------------------------------
+// Read Image Information
+void clitk::GateAsciiImageIO::ReadImageInformation()
+{
+    FILE* handle = fopen(m_FileName.c_str(),"r");
+    if (!handle) {
+       itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
+       return;
+    }
+
+    GateAsciiHeader header;
+    if (!ReadHeader(handle,header)) {
+       itkGenericExceptionMacro(<< "Could not read header: " << m_FileName);
+       fclose(handle);
+       return;
+    }
+    fclose(handle);
+
+    int real_length = -1;
+    double real_spacing = 0;
+    for (int kk=0; kk<3; kk++) {
+       if (header.resolution[kk]>1) {
+           if (real_length>0) {
+               itkGenericExceptionMacro(<< "Could not image dimension: " << m_FileName);
+               return;
+           }
+           real_length = header.resolution[kk];
+           real_spacing = header.voxel_size[kk];
+       }
+    }
+    assert(real_length == header.nb_value);
+
+    // Set image information
+    SetNumberOfDimensions(2);
+    SetDimensions(0, real_length);
+    SetDimensions(1, 1);
+    SetSpacing(0, real_spacing);
+    SetSpacing(1, 1);
+    SetOrigin(0, 0);
+    SetOrigin(1, 0);
+    SetComponentType(itk::ImageIOBase::DOUBLE);
+}
+
+//--------------------------------------------------------------------
+bool clitk::GateAsciiImageIO::CanReadFile(const char* FileNameToRead)
+{
+    std::string filename(FileNameToRead);
+
+    { // check extension
+       std::string filenameext = GetExtension(filename);
+       if (filenameext != "txt") return false;
+    }
+
+    { // check header
+       FILE* handle = fopen(filename.c_str(),"r");
+       if (!handle) return false;
+
+       GateAsciiHeader header;
+       if (!ReadHeader(handle,header)) { fclose(handle); return false; }
+       fclose(handle);
+    }
+
+    return true;
+}
+
+//--------------------------------------------------------------------
+// Read Line in file
+bool clitk::GateAsciiImageIO::ReadLine(FILE* handle, std::string& line)
+{
+    std::stringstream stream;
+    while (true)
+    {
+       char item;
+       if (ferror(handle)) return false;
+       if (fread(&item,1,1,handle) != 1) return false;
+
+       if (item=='\n' or feof(handle)) {
+           line = stream.str();
+           return true;
+       }
+
+       stream << item;
+    }
+}
+
+std::string ExtractMatch(const std::string& base, const regmatch_t& match) 
+{
+    return base.substr(match.rm_so,match.rm_eo-match.rm_so);
+}
+
+template <typename T>
+T ConvertFromString(const std::string& value)
+{
+    std::stringstream stream;
+    stream << value;
+    T converted;
+    stream >> converted;
+    return converted;
+}
+
+//--------------------------------------------------------------------
+// Read Image Header
+bool clitk::GateAsciiImageIO::ReadHeader(FILE* handle, GateAsciiHeader& header)
+{
+    assert(handle);
+    std::string line;
+
+    regex_t re_comment;
+    regex_t re_matrix_size;
+    regex_t re_resol;
+    regex_t re_voxel_size;
+    regex_t re_nb_value;
+    regmatch_t matches[4];
+
+    { // build regex
+       int ret = 0;
+       ret = regcomp(&re_comment,"^#.+$",REG_EXTENDED|REG_NEWLINE);
+       assert(ret == 0);
+       ret = regcomp(&re_matrix_size,"^# +Matrix *Size *= +\\(([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*)\\)$",REG_EXTENDED|REG_NEWLINE);
+       assert(ret == 0);
+       ret = regcomp(&re_resol,"^# +Resol *= +\\(([0-9]+),([0-9]+),([0-9]+)\\)$",REG_EXTENDED|REG_NEWLINE);
+       assert(ret == 0);
+       ret = regcomp(&re_voxel_size,"^# +Voxel *Size *= +\\(([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*)\\)$",REG_EXTENDED|REG_NEWLINE);
+       assert(ret == 0);
+       ret = regcomp(&re_nb_value,"^# +nbVal *= +([0-9]+)$",REG_EXTENDED|REG_NEWLINE);
+       assert(ret == 0);
+    }
+
+    if (!ReadLine(handle,line)) return false;
+    if (regexec(&re_comment,line.c_str(),1,matches,0) == REG_NOMATCH) return false;
+
+    if (!ReadLine(handle,line)) return false;
+    if (regexec(&re_matrix_size,line.c_str(),4,matches,0) == REG_NOMATCH) return false;
+    header.matrix_size[0] = ConvertFromString<double>(ExtractMatch(line,matches[1]));
+    header.matrix_size[1] = ConvertFromString<double>(ExtractMatch(line,matches[2]));
+    header.matrix_size[2] = ConvertFromString<double>(ExtractMatch(line,matches[3]));
+
+    if (!ReadLine(handle,line)) return false;
+    if (regexec(&re_resol,line.c_str(),4,matches,0) == REG_NOMATCH) return false;
+    header.resolution[0] = ConvertFromString<int>(ExtractMatch(line,matches[1]));
+    header.resolution[1] = ConvertFromString<int>(ExtractMatch(line,matches[2]));
+    header.resolution[2] = ConvertFromString<int>(ExtractMatch(line,matches[3]));
+
+    if (!ReadLine(handle,line)) return false;
+    if (regexec(&re_voxel_size,line.c_str(),4,matches,0) == REG_NOMATCH) return false;
+    header.voxel_size[0] = ConvertFromString<double>(ExtractMatch(line,matches[1]));
+    header.voxel_size[1] = ConvertFromString<double>(ExtractMatch(line,matches[2]));
+    header.voxel_size[2] = ConvertFromString<double>(ExtractMatch(line,matches[3]));
+
+    if (!ReadLine(handle,line)) return false;
+    if (regexec(&re_nb_value,line.c_str(),2,matches,0) == REG_NOMATCH) return false;
+    header.nb_value = ConvertFromString<int>(ExtractMatch(line,matches[1]));
+
+    if (!ReadLine(handle,line)) return false;
+    if (regexec(&re_comment,line.c_str(),1,matches,0) == REG_NOMATCH) return false;
+
+    return true;
+}
+
+//--------------------------------------------------------------------
+// Read Image Content
+void clitk::GateAsciiImageIO::Read(void* abstract_buffer)
+{
+    FILE* handle = fopen(m_FileName.c_str(),"r");
+    if (!handle) {
+       itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
+       return;
+    }
+
+    GateAsciiHeader header;
+    if (!ReadHeader(handle,header)) {
+       itkGenericExceptionMacro(<< "Could not read header: " << m_FileName);
+       fclose(handle);
+       return;
+    }
+
+    {
+       double* buffer = static_cast<double*>(abstract_buffer);
+       int read_count = 0;
+       while (true) { 
+           std::string line;
+           if (!ReadLine(handle,line)) break;
+           *buffer = ConvertFromString<double>(line);
+           read_count++;
+           buffer++;
+       }
+       assert(read_count == header.nb_value);
+    }
+
+    fclose(handle);
+}
+
+//--------------------------------------------------------------------
+bool clitk::GateAsciiImageIO::CanWriteFile(const char* FileNameToWrite)
+{
+    if (GetExtension(std::string(FileNameToWrite)) != "txt") return false;
+    return true;
+}
+
+void clitk::GateAsciiImageIO::WriteImageInformation()
+{
+    cout << GetNumberOfDimensions() << endl;
+}
+
+bool clitk::GateAsciiImageIO::SupportsDimension(unsigned long dim)
+{
+    if (dim==2) return true;
+    return false;
+}
+
+//--------------------------------------------------------------------
+// Write Image
+void clitk::GateAsciiImageIO::Write(const void* abstract_buffer)
+{
+    const unsigned long nb_value = GetDimensions(0)*GetDimensions(1);
+    std::stringstream stream;
+    stream << "######################" << endl;
+    stream << "# Matrix Size= (" << GetSpacing(0)*GetDimensions(0) << "," << GetSpacing(1)*GetDimensions(1) << ",1)" << endl;
+    stream << "# Resol      = (" << GetDimensions(0) << "," << GetDimensions(1) << ",1)" << endl;
+    stream << "# VoxelSize  = (" << GetSpacing(0) << "," << GetSpacing(1) << ",1)" << endl;
+    stream << "# nbVal      = " << nb_value << endl;
+    stream << "######################" << endl;
+
+    const double* buffer = static_cast<const double*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++) { stream << buffer[kk] << endl; }
+
+    FILE* handle = fopen(m_FileName.c_str(),"w");
+    if (!handle) {
+       itkGenericExceptionMacro(<< "Could not open file (for writing): " << m_FileName);
+       return;
+    }
+
+    fwrite(stream.str().c_str(),1,stream.str().size(),handle);
+
+    fclose(handle);
+}
diff --git a/common/clitkGateAsciiImageIO.h b/common/clitkGateAsciiImageIO.h
new file mode 100644 (file)
index 0000000..d0abbea
--- /dev/null
@@ -0,0 +1,84 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef CLITKGATEASCIIIMAGEIO_H
+#define CLITKGATEASCIIIMAGEIO_H
+
+// itk include
+#include "itkImageIOBase.h"
+
+#if defined (_MSC_VER) && (_MSC_VER < 1600)
+//SR: taken from
+//#include "msinttypes/stdint.h"
+typedef unsigned int uint32_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace clitk {
+
+    //====================================================================
+    // Class for reading gate ascii Image file format
+    class GateAsciiImageIO: public itk::ImageIOBase
+    {
+       public: 
+           /** Standard class typedefs. */
+           typedef GateAsciiImageIO        Self;
+           typedef itk::ImageIOBase        Superclass;
+           typedef itk::SmartPointer<Self> Pointer;    
+           typedef signed short int        PixelType;
+
+           struct GateAsciiHeader {
+               double matrix_size[3];
+               int resolution[3];
+               double voxel_size[3];
+               int nb_value;
+           };
+
+           GateAsciiImageIO():Superclass() {;}
+
+           /** Method for creation through the object factory. */
+           itkNewMacro(Self);
+
+           /** Run-time type information (and related methods). */
+           itkTypeMacro(GateAsciiImageIO, ImageIOBase);
+
+           /*-------- This part of the interface deals with reading data. ------ */
+           virtual void ReadImageInformation();
+           virtual bool CanReadFile( const char* FileNameToRead );
+           virtual void Read(void * buffer);
+
+           /*-------- This part of the interfaces deals with writing data. ----- */
+           virtual void WriteImageInformation();
+           virtual bool CanWriteFile(const char* filename);
+           virtual void Write(const void* buffer);
+
+           virtual bool SupportsDimension(unsigned long dim);
+
+       protected:
+
+           static bool ReadHeader(FILE* handle, GateAsciiHeader& header);
+           static bool ReadLine(FILE* handle, std::string& line);
+
+    }; // end class GateAsciiImageIO
+} // end namespace
+
+// explicit template instantiation
+//template class itk::CreateObjectFunction<clitk::GateAsciiImageIO>;
+
+#endif /* end #define CLITKGATEASCIIIMAGEIO_H */
+
diff --git a/common/clitkGateAsciiImageIOFactory.cxx b/common/clitkGateAsciiImageIOFactory.cxx
new file mode 100644 (file)
index 0000000..7c78f7d
--- /dev/null
@@ -0,0 +1,29 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#include "clitkGateAsciiImageIOFactory.h"
+
+//====================================================================
+clitk::GateAsciiImageIOFactory::GateAsciiImageIOFactory()
+{
+  this->RegisterOverride("itkImageIOBase",
+                         "GateAsciiImageIO",
+                         "GateAscii Image IO",
+                         1,
+                         itk::CreateObjectFunction<GateAsciiImageIO>::New());
+}
diff --git a/common/clitkGateAsciiImageIOFactory.h b/common/clitkGateAsciiImageIOFactory.h
new file mode 100644 (file)
index 0000000..bae5ac3
--- /dev/null
@@ -0,0 +1,74 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef CLITKGATEASCIIIMAGEIOFACTORY_H
+#define CLITKGATEASCIIIMAGEIOFACTORY_H
+
+// clitk include
+#include "clitkGateAsciiImageIO.h"
+
+// itk include
+#include "itkImageIOBase.h"
+#include "itkObjectFactoryBase.h"
+#include "itkVersion.h"
+
+namespace clitk {
+
+    //====================================================================
+    // Factory for reading GateAscii Image file format
+    class GateAsciiImageIOFactory: public itk::ObjectFactoryBase
+    {
+       public:
+           /** Standard class typedefs. */
+           typedef GateAsciiImageIOFactory        Self;
+           typedef itk::ObjectFactoryBase         Superclass;
+           typedef itk::SmartPointer<Self>        Pointer;
+           typedef itk::SmartPointer<const Self>  ConstPointer;
+
+           /** Class methods used to interface with the registered factories. */
+           const char* GetITKSourceVersion(void) const {
+               return ITK_SOURCE_VERSION;
+           }
+
+           const char* GetDescription(void) const {
+               return "GateAscii ImageIO Factory, allows the loading of gate ascii images into insight";
+           }
+
+           /** Method for class instantiation. */
+           itkFactorylessNewMacro(Self);
+
+           /** Run-time type information (and related methods). */
+           itkTypeMacro(GateAsciiImageIOFactory, ObjectFactoryBase);
+
+           /** Register one factory of this type  */
+           static void RegisterOneFactory(void) {
+               ObjectFactoryBase::RegisterFactory( Self::New() );
+           }   
+
+       protected:
+           GateAsciiImageIOFactory();
+           ~GateAsciiImageIOFactory() {};
+
+       private:
+           GateAsciiImageIOFactory(const Self&); //purposely not implemented
+           void operator=(const Self&); //purposely not implemented
+    };
+
+} // end namespace
+
+#endif /* end #define CLITKGATEASCIIIMAGEIOFACTORY_H */
+
index d2f775853a9433c7cd77663822ace3915e68aa79..1acd352808ba3ff8f01a8beaa6cd0e2db2ddc66e 100644 (file)
 #include "clitkVfImageIOFactory.h"
 #include "clitkXdrImageIOFactory.h"
 #include "clitkHndImageIOFactory.h"
+#include "clitkGateAsciiImageIOFactory.h"
 
 //--------------------------------------------------------------------
 // Register factories
 void clitk::RegisterClitkFactories()
 {
+  clitk::GateAsciiImageIOFactory::RegisterOneFactory();
   clitk::DicomRTDoseIOFactory::RegisterOneFactory();
 #if ITK_VERSION_MAJOR <= 3
   itk::ImageIOFactory::RegisterBuiltInFactories();
index ca8cace7593ef6451096eb0138183d22a7c14fed..04b849d0d7280b325a5d5b30a785069080c33b99 100644 (file)
@@ -323,7 +323,7 @@ public:
       std::cout<<std::setprecision(6);
       if (m_OutputIteration)  std::cout<<"Iteration: "<< o->GetCurrentIteration()<<std::endl;
       if (m_OutputPosition)  std::cout<<"Position: "<< o->GetCurrentPosition()<<std::endl;
-      if (m_OutputPosition)  std::cout<<"Step length: "<< o->GetCurrentStepLength()<<std::endl;
+      if (m_OutputValue)  std::cout<<"Step length: "<< o->GetCurrentStepLength()<<std::endl;
       if (m_OutputValue)  std::cout<<"Value: "<< o->GetValue()<<std::endl;
       if (m_OutputGradient)  std::cout<<"Gradient: "<< o->GetGradient()<<std::endl;
       std::cout<<std::endl;
index 8ea7e2c3903935ffc16c3927c5ce7a42b037916a..239745f5348c9daade6feefb3108ace546fea60a 100755 (executable)
@@ -80,8 +80,15 @@ registration()
       motion_mask=$mask_dir/mm_$phase_nb.mhd
       vf_result=$vf_dir/vf_${ref_phase_nb}_$phase_nb.mhd
       clitkCombineImage -i $vf_in -j $vf_out -m $motion_mask -o $vf_result
+      abort_on_error registration $? clean_up_registration
+
       clitkZeroVF -i $vf_in -o vf_zero.mhd
+      abort_on_error registration $? clean_up_registration
+
+      patient_mask=$mask_dir/patient_mask_$phase_nb.mhd
       clitkCombineImage -i $vf_result -j vf_zero.mhd -m $patient_mask -o $vf_result
+      abort_on_error registration $? clean_up_registration
+
       rm vf_zero.*
 
       # save for later...
@@ -91,6 +98,7 @@ registration()
 
   # create (zero) vf from reference to reference
   clitkZeroVF -i $vf_ref -o $vf_dir/vf_${ref_phase_nb}_${ref_phase_nb}.mhd
+  abort_on_error registration $? clean_up_registration
 
   # create 4D vf
   create_mhd_4D_pattern.sh $vf_dir/vf_${ref_phase_nb}_
@@ -120,14 +128,20 @@ midp()
   midp=$midp_dir/midp_$phase_nb.mhd
   # average the vf's from reference phase to phase
   clitkAverageTemporalDimension -i $vf_dir/vf_${ref_phase_nb}_4D.mhd -o $vf_midp
+  abort_on_error midp $? clean_up_midp
+
   # invert the vf (why?)
   clitkInvertVF -i $vf_midp -o $vf_midp
+  abort_on_error midp $? clean_up_midp
+
   # create the midp by warping the reference phase with the reference vf
   clitkWarpImage -i $ref_phase_file -o $midp --vf=$vf_midp -s 1
+  abort_on_error midp $? clean_up_midp
 
   ref_vf_midp=$vf_midp
   ref_midp=$midp
   clitkImageConvert -i $ref_midp -o $ref_midp -t float
+  abort_on_error midp $? clean_up_midp
 
   ########### calculate the midp wrt the other phases
   for i in $( seq 0 $((${#phase_files[@]} - 1))); do
@@ -141,16 +155,25 @@ midp()
       # calculate vf from phase to midp, using the vf from reference phase to midp (-i)
       # and the vf from reference phase to phase (-j)
       clitkComposeVF -i $ref_vf_midp -j $vf_dir/vf_$ref_phase_nb\_$phase_nb.mhd -o $vf_midp
+      abort_on_error midp $? clean_up_midp
+      
       clitkWarpImage -i $phase_file -o $midp --vf=$vf_midp -s 1
+      abort_on_error midp $? clean_up_midp
+      
       clitkImageConvert -i $midp -o $midp -t float
+      abort_on_error midp $? clean_up_midp
     fi
   done
 
   create_mhd_4D_pattern.sh $midp_dir/midp_
+
   echo "Calculating midp_avg.mhd..."
   clitkAverageTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_avg.mhd
+  abort_on_error midp $? clean_up_midp
+
   echo "Calculating midp_med.mhd..."
   clitkMedianTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_med.mhd
+  abort_on_error midp $? clean_up_midp
 
   # clean-up
   rm $midp_dir/vf_*
index f5738e0107c464a68fd0e97cba98a7e2719bd193..bbf44f0fa9a857da69581133681ddb046f715905 100755 (executable)
@@ -1,5 +1,5 @@
-#! /bin/bash -x
-
+#! /bin/bash 
+  
 ###############################################################################
 #
 # FILE: create_midP-2.0.sh
@@ -21,7 +21,10 @@ extract_patient()
 {
   echo "$phase_file -> Extracting patient..."
   clitkExtractPatient -i $phase_file -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --noAutoCrop -a $afdb_file $ExtractPatientExtra
+#   abort_on_error clitkExtractPatient $?
+
   clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000
+#   abort_on_error clitkSetBackground $?
 }
 
 extract_bones()
@@ -39,15 +42,16 @@ extract_bones()
 
 extract_lungs()
 {
-  echo "$phase_file -> Extracting lungs..."
-  clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop
+  echo "$phase_file -> Extracting lungs..."  
+  clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop --doNotSeparateLungs
 }
 
+
+
 resample()
 {
   echo "$phase_file -> Resampling..."
   clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
-
   clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
 }
 
@@ -198,6 +202,7 @@ motion_mask()
     mkdir -p $mask_log_dir
 
     # multi-threaded pre-processing for motion mask calcs
+    pids=( )
     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
       phase_nb=${phase_nbs[$i]}
       phase_file=${phase_files[$i]}
@@ -205,6 +210,12 @@ motion_mask()
 
       check_threads $MAX_THREADS
       mm_preprocessing &
+      pids=( "${pids[@]}" "$!" )
+    done
+
+    wait_pids ${pids[@]}
+    for ret in $ret_codes; do
+      abort_on_error mm_preprocessing $ret clean_up_masks
     done
 
     # single-threaded motion mask calc
@@ -215,16 +226,25 @@ motion_mask()
       check_threads 1
       echo "$phase_file -> Computing motion mask..."
       compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log
+      abort_on_error compute_motion_mask $? clean_up_masks
     done
 
     # multi-threaded post-processing of motion mask calcs
+    pids=( )
     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
       phase_nb=${phase_nbs[$i]}
       phase_file=${phase_files[$i]}
 
       check_threads $MAX_THREADS 
       mm_postprocessing &
+      pids=( "${pids[@]}" "$!" )
     done
+  
+    wait_pids ${pids[@]}
+    for ret in $ret_codes; do
+      abort_on_error mm_postprocessing $ret clean_up_masks
+    done
+
 
     # rename tmp mask directory after mask creation
     check_threads 1
index 0f767070e217639fc5b2548db0e2b315610f6608..aa500ae9a959885bd66eb8ee1cbf82426565e8ea 100755 (executable)
@@ -1,4 +1,4 @@
-#! /bin/sh +x
+#! /bin/sh -x
 
 ###############################################################################
 #
@@ -9,7 +9,72 @@
 #
 ###############################################################################
 
+#
+# check return value passed and abort if it represents an error (ie, ret != 0)
+# optionally, a function can be passed as a 3rd parameter, to be called just
+# before exiting. this is useful for cleaning up, for example.
+#
+abort_on_error()
+{
+  if [ $2 != 0 ]; then
+    echo Aborted at $1 with code $2
+    if [ $# = 3 ]; then
+      eval $3
+    fi
 
+    exit $2
+  fi
+}
+
+#
+# wait for all processes in the list and return their exit codes
+# in the ret_codes variable.
+#
+# OBS: this function must always be called in the same shell
+# that launched the processes.
+#
+wait_pids()
+{
+  local pids=$*
+  local ret=
+  local rets=
+#   echo PIDS: $pids
+  for p in $pids; do
+#     echo waiting $p
+    wait $p > /dev/null 2> /dev/null
+    ret=$?
+    if [ ret != 127 ]; then
+      rets=$rets" "$ret
+    else
+      rets=$rets" "0
+    fi
+      
+  done
+
+  ret_codes=$rets
+}
+
+#
+# clean-up functions for maks, registration, and midp
+#
+clean_up_masks()
+{
+  rm -fr $mask_dir_tmp
+}
+
+clean_up_midp()
+{
+  rm -fr $midp_dir
+}
+
+clean_up_registration()
+{
+  rm -fr $vf_dir
+  rm -fr $output_dir
+}
+
+
+#
 # block execution untill the number of threads (jobs) launched by the
 # current process is below the given number of threads. 
 MAX_THREADS=2
index 40d5fbe41dc7e0467faf028caab8bcffcb636f5d..724e3ac392f804e842e408bc67e92733fd52c6fa 100755 (executable)
@@ -31,6 +31,8 @@
 #
 ###############################################################################
 
+source `dirname $0`/midp_common.sh
+
 
 ################# BLUTDIR #####################
 registration_blutdir()
@@ -56,6 +58,8 @@ registration_blutdir()
   blutdir_params="--levels $nb_levels  --metric $metric --optimizer $optimizer --samples $nb_samples --spacing $spacing,$spacing,$spacing --bins $hist_bins --maxIt $nb_iter --interp $interpolator --verbose"
   cmd="clitkBLUTDIR -r $reference -t $target -m $mask_ref --targetMask $mask_targ --vf $vf -o $result $blutdir_params"
   $cmd > $log
+
+  abort_on_error registration_blutdir $? clean_up_registration
 }
 
 ################# ELASTIX #####################
@@ -105,10 +109,12 @@ registration_elastix()
   # image registration
   cmd="elastix -f $reference -m $target -fMask $mask_ref -mMask $mask_targ -out $result_dir -p params_BSpline_${suffix}.txt"
   $cmd  > /dev/null
+  abort_on_error registration_elastix $? clean_up_registration
 
   # generate vector field
   cmd="transformix -tp $result_dir/TransformParameters.0.txt -out $vf_dir -def all"
   $cmd  > /dev/null
+  abort_on_error registration_elastix $? clean_up_registration
 
   # post-processing
   mv $vf_dir/deformationField.mhd $vf
index 3e27657c57aa7250eaa9cd2c6950294ba3da05a4..4d3302fa502ca18f97eeabc6d1e03f0d8ffde396 100644 (file)
@@ -34,11 +34,7 @@ int main(int argc, char * argv[])
 
   filter->SetArgsInfo(args_info);
   
-  try {
-    filter->Update();
-  } catch(std::runtime_error e) {
-    std::cout << e.what() << std::endl;
-  }
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   return EXIT_SUCCESS;
 } // This is the end, my friend
index 36fa4e84be349ebc4277f5d9eadc954cc90df487..1b5fda927f4caf78a975afac9617b85ce58780e1 100644 (file)
@@ -33,11 +33,7 @@ int main(int argc, char * argv[])
 
   filter->SetArgsInfo(args_info);
   
-  try {
-    filter->Update();
-  } catch(std::runtime_error e) {
-    std::cerr << e.what() << std::endl;
-  }
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   return EXIT_SUCCESS;
 } // This is the end, my friend
index 12dd3e7040823c00e0676c005d95ec63d7522c94..98ddbd80d3dc29f1dcb53355d663a6dc7e1a4638 100644 (file)
@@ -61,4 +61,7 @@ section "Step 6 : fill holes"
 option "doNotFillHoles"                -  "Do not fill holes if set"                 flag on
 option "dir"                   d  "Directions (axes) to perform filling (defaults to 2,1,0)"   int multiple no
 
+section "Step 7 : lung separation (labelling)"
+option "doNotSeparateLungs"   -  "Do not separate lungs if set"                 flag off
+
 option "noAutoCrop"    -       "If set : do no crop final mask to BoundingBox"                         flag    off
index fa472ba711db3bff2c7ed8094380fc6b3505936c..23fbbc7a8fd427a8f5f749aaee81c69eae275064 100644 (file)
@@ -191,6 +191,11 @@ namespace clitk {
     itkGetConstMacro(FillHolesFlag, bool);
     itkBooleanMacro(FillHolesFlag);
 
+    // Separate lungs
+    itkSetMacro(SeparateLungsFlag, bool);
+    itkGetConstMacro(SeparateLungsFlag, bool);
+    itkBooleanMacro(SeparateLungsFlag);
+
     // Step Auto Crop
     itkSetMacro(AutoCrop, bool);
     itkGetConstMacro(AutoCrop, bool);
@@ -250,6 +255,8 @@ namespace clitk {
     bool m_FillHolesFlag;    
     InputImageSizeType m_FillHolesDirections;
 
+    bool m_SeparateLungsFlag;
+    
     // Main functions
     virtual void GenerateOutputInformation();
     virtual void GenerateInputRequestedRegion();
index 0954c2a3de46a11249c21237b9644e9a4a123404..d2bff5edd5962647512fd2d1070017b17a5dab34 100644 (file)
@@ -414,49 +414,51 @@ GenerateOutputInformation()
     StopCurrentStep<MaskImageType>(working_mask);
   }
 
-  //--------------------------------------------------------------------
-  //--------------------------------------------------------------------
-  StartNewStep("Separate Left/Right lungs");
-    PrintMemory(GetVerboseMemoryFlag(), "Before Separate");
-  // Initial label
-  working_mask = Labelize<MaskImageType>(working_mask, 
-                                         GetBackgroundValue(), 
-                                         false, 
-                                         GetMinimalComponentSize());
-
-  PrintMemory(GetVerboseMemoryFlag(), "After Labelize");
-
-  // Count the labels
-  typedef itk::StatisticsImageFilter<MaskImageType> StatisticsImageFilterType;
-  typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
-  statisticsImageFilter->SetInput(working_mask);
-  statisticsImageFilter->Update();
-  unsigned int initialNumberOfLabels = statisticsImageFilter->GetMaximum();
-  working_mask = statisticsImageFilter->GetOutput();   
+  if (GetSeparateLungsFlag()) {
+    //--------------------------------------------------------------------
+    //--------------------------------------------------------------------
+    StartNewStep("Separate Left/Right lungs");
+      PrintMemory(GetVerboseMemoryFlag(), "Before Separate");
+    // Initial label
+    working_mask = Labelize<MaskImageType>(working_mask, 
+                                          GetBackgroundValue(), 
+                                          false, 
+                                          GetMinimalComponentSize());
+
+    PrintMemory(GetVerboseMemoryFlag(), "After Labelize");
+
+    // Count the labels
+    typedef itk::StatisticsImageFilter<MaskImageType> StatisticsImageFilterType;
+    typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
+    statisticsImageFilter->SetInput(working_mask);
+    statisticsImageFilter->Update();
+    unsigned int initialNumberOfLabels = statisticsImageFilter->GetMaximum();
+    working_mask = statisticsImageFilter->GetOutput(); 
+    
+    PrintMemory(GetVerboseMemoryFlag(), "After count label");
   
-  PrintMemory(GetVerboseMemoryFlag(), "After count label");
-  // Decompose the first label
-  if (initialNumberOfLabels<2) {
-    // Structuring element radius
-    typename ImageType::SizeType radius;
-    for (unsigned int i=0;i<Dim;i++) radius[i]=1;
-    typedef clitk::DecomposeAndReconstructImageFilter<MaskImageType,MaskImageType> DecomposeAndReconstructFilterType;
-    typename DecomposeAndReconstructFilterType::Pointer decomposeAndReconstructFilter=DecomposeAndReconstructFilterType::New();
-    decomposeAndReconstructFilter->SetInput(working_mask);
-    decomposeAndReconstructFilter->SetVerbose(false);
-    decomposeAndReconstructFilter->SetRadius(radius);
-    decomposeAndReconstructFilter->SetMaximumNumberOfLabels(2);
-    decomposeAndReconstructFilter->SetMinimumObjectSize(this->GetMinimalComponentSize());
-    decomposeAndReconstructFilter->SetMinimumNumberOfIterations(1);
-    decomposeAndReconstructFilter->SetBackgroundValue(this->GetBackgroundValue());
-    decomposeAndReconstructFilter->SetForegroundValue(this->GetForegroundValue());
-    decomposeAndReconstructFilter->SetFullyConnected(true);
-    decomposeAndReconstructFilter->SetNumberOfNewLabels(1);
-    decomposeAndReconstructFilter->Update();
-    working_mask = decomposeAndReconstructFilter->GetOutput();      
+    // Decompose the first label
+    if (initialNumberOfLabels<2) {
+      // Structuring element radius
+      typename ImageType::SizeType radius;
+      for (unsigned int i=0;i<Dim;i++) radius[i]=1;
+      typedef clitk::DecomposeAndReconstructImageFilter<MaskImageType,MaskImageType> DecomposeAndReconstructFilterType;
+      typename DecomposeAndReconstructFilterType::Pointer decomposeAndReconstructFilter=DecomposeAndReconstructFilterType::New();
+      decomposeAndReconstructFilter->SetInput(working_mask);
+      decomposeAndReconstructFilter->SetVerbose(false);
+      decomposeAndReconstructFilter->SetRadius(radius);
+      decomposeAndReconstructFilter->SetMaximumNumberOfLabels(2);
+      decomposeAndReconstructFilter->SetMinimumObjectSize(this->GetMinimalComponentSize());
+      decomposeAndReconstructFilter->SetMinimumNumberOfIterations(1);
+      decomposeAndReconstructFilter->SetBackgroundValue(this->GetBackgroundValue());
+      decomposeAndReconstructFilter->SetForegroundValue(this->GetForegroundValue());
+      decomposeAndReconstructFilter->SetFullyConnected(true);
+      decomposeAndReconstructFilter->SetNumberOfNewLabels(1);
+      decomposeAndReconstructFilter->Update();
+      working_mask = decomposeAndReconstructFilter->GetOutput();      
+    }
+    PrintMemory(GetVerboseMemoryFlag(), "After decomposeAndReconstructFilter");
   }
-  PrintMemory(GetVerboseMemoryFlag(), "After decomposeAndReconstructFilter");
 
   // Retain labels ('1' is largset lung, so right. '2' is left)
   typedef itk::ThresholdImageFilter<MaskImageType> ThresholdImageFilterType;
index 2dd396fb3a2498fb0a5ff15e3dc01a2bf6af6db8..b40dc28fc49de81bd0a4784fba74158b7dd333f6 100644 (file)
@@ -108,6 +108,11 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
     f->SetFillHolesFlag(false);
   else
     f->SetFillHolesFlag(true);
+
+  if (mArgsInfo.doNotSeparateLungs_given)
+    f->SetSeparateLungsFlag(false);
+  else
+    f->SetSeparateLungsFlag(true);
 }
 //--------------------------------------------------------------------
 
index 43a086388a9b138e1e75d3d57c31b74a7c1227d5..ebbd3ade15618efb6dfaad1a3834a9100edfb046 100644 (file)
@@ -33,11 +33,7 @@ int main(int argc, char * argv[]) {
   
   filter->SetArgsInfo(args_info);
   
-  try {
-    filter->Update();
-  } catch(std::runtime_error e) {
-    std::cout << e.what() << std::endl;
-  }
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   return EXIT_SUCCESS;
 } // This is the end, my friend
index 3dfde0d0d46c180c2c9603c8920602fbd894303a..88c9cb8ea99e7bb4eb3906a501f2ba72ac3be6e7 100644 (file)
@@ -37,7 +37,7 @@ namespace clitk
   //-----------------------------------------------------------
   // Constructor
   //-----------------------------------------------------------
-  ExtractPatientGenericFilter::ExtractPatientGenericFilter()
+  ExtractPatientGenericFilter:::ExtractPatientGenericFilter()
   {
     m_Verbose=false;
     m_InputFileName="";
index 46e348971e8242433f42f7d6b755ec12c247278e..25c40df134f496ec960fab8db3032ae2dead8430 100644 (file)
@@ -36,11 +36,7 @@ int main(int argc, char * argv[]) {
   // Passing the arguments to the generic filter
   filter->SetArgsInfo(args_info);
  
-  try {
-    filter->Update();
-  } catch(std::runtime_error e) {
-    std::cout << e.what() << std::endl;
-  }
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   return EXIT_SUCCESS;
 } // This is the end, my friend
index fdc31c7024976b10a93f730918978d5e75fc86b4..fd65c6457b173ca4a02ec71e2edef7b9336a96b7 100644 (file)
@@ -43,7 +43,7 @@ int main(int argc, char * argv[]) {
   clitk::MotionMaskGenericFilter::Pointer genericFilter=clitk::MotionMaskGenericFilter::New();
   
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index 15bf04d396e249a14ac46dbbad3c03b8ea7b7edf..bd565421b4a05493b26ef8bcf3df9b1466c75b4b 100644 (file)
@@ -126,7 +126,7 @@ IF (CLITK_BUILD_TOOLS)
 
   WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
   ADD_EXECUTABLE(clitkGammaIndex clitkGammaIndex.cxx ${clitkGammaIndex_GGO_C})
-  TARGET_LINK_LIBRARIES(clitkGammaIndex vtkCommon vtkFiltering vtkGraphics vtkIO vtkImaging)
+  TARGET_LINK_LIBRARIES(clitkGammaIndex clitkCommon ${VTK_LIBRARIES} ${ITK_LIBRARIES} vtkIO)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGammaIndex)
 
   ADD_EXECUTABLE(clitkImageArithm clitkImageArithm.cxx)
index d6434547711f2da9763a7ea9833836efa6f021c9..6304aed44d0fdd0e578c9c1cc1f29af8dd4224e2 100644 (file)
@@ -45,7 +45,7 @@ int main(int argc, char * argv[])
   FilterType::Pointer genericFilter = FilterType::New();
 
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index 1bfc8386b96eb0f78bb4762bccfb227bb25e3e1a..70d99926cab3c705e05204ea34709f7805998890 100644 (file)
@@ -34,11 +34,7 @@ int main(int argc, char * argv[])
 
   filter->SetArgsInfo(args_info);
 
-  try {
-    filter->Update();
-  } catch(std::runtime_error e) {
-    std::cout << e.what() << std::endl;
-  }
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   return EXIT_SUCCESS;
 } // This is the end, my friend
index a78b131a7b3962f45ac7db46edb8813fa5419728..ee8de0ded1c3cf502a8050bf3ac345be504bd4bb 100644 (file)
@@ -43,7 +43,7 @@ int main(int argc, char * argv[]) {
   clitk::CombineImageGenericFilter::Pointer genericFilter=clitk::CombineImageGenericFilter::New();
   
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index 08cff6585d0e52022ad4ac23e83be208b36b7c4d..72b95cf3f0fce8d02792232b05e89a0c915b2d38 100644 (file)
@@ -39,7 +39,7 @@ int main( int argc, char *argv[] )
   //JV how to pass for different dims?
   //ComposeVFGenericFilter->SetEdgePaddingValue(args_info.pad_arg);
   ComposeVFGenericFilter->SetVerbose(args_info.verbose_flag);
-  ComposeVFGenericFilter->Update();  
+  CLITK_TRY_CATCH_EXIT(ComposeVFGenericFilter->Update());  
 
   return EXIT_SUCCESS;
 }
index 08d7aef9da81921110bf56365bd42d0d5137e8b1..be0f8072218330f4b82a99ddc7c1b7f50419698e 100644 (file)
@@ -32,241 +32,275 @@ using std::cout;
 
 #include "clitkGammaIndex_ggo.h"
 
-vtkImageData *loadImage(const std::string &filename) {
-  vtkImageReader2 *reader = vtkMetaImageReader::New();
-  //vtkImageReader2 *reader = vtkPNGReader::New();
-  reader->SetFileName(filename.c_str());
-  reader->Update();
+#include <clitkIO.h>
+#include <vvImage.h>
+#include <vvImageReader.h>
+#include <vvImageWriter.h>
 
-  vtkImageData *image = reader->GetOutput();
-  image->Register(NULL);
-  reader->Delete();
+#include <itkImage.h>
+#include <itkImageRegionIterator.h>
+typedef itk::Image<double> OutputImageType;
+typedef itk::ImageRegionIterator<OutputImageType> OutputImageIterator;
 
-  return image;
+vtkImageData* loadImage(const std::string& filename)
+{
+    vvImageReader::Pointer reader = vvImageReader::New();
+    reader->SetInputFilename(filename);
+    reader->Update();
+    vvImage::Pointer vvimage = reader->GetOutput();
+    if (!vvimage) { cerr << "can't load " << filename << endl; return NULL; }
+
+    vtkImageData *image = vtkImageData::New();
+    image->DeepCopy(vvimage->GetFirstVTKImageData());
+    return image;
 }
 
-void saveImage(vtkImageData *image,const std::string &filename) {
-  cout << "saving " << filename << endl;
-  vtkImageWriter *writer = vtkMetaImageWriter::New();
-  writer->SetFileName(filename.c_str());
-  writer->SetInput(image);
-  writer->Write();
-  writer->Delete();
+void saveImage(OutputImageType* image,const std::string &filename) {
+    vvImage::Pointer vvimage = vvImage::New();
+    vvimage->AddItkImage(image);
+
+    vvImageWriter::Pointer writer = vvImageWriter::New();
+    writer->SetOutputFileName(filename.c_str());
+    writer->SetInput(vvimage);
+    writer->Update();
 }
 
+
 void insertTriangles(vtkCellArray *cells, vtkPoints *points, const vtkIdType ids[4]) {
-  double p0[3]; points->GetPoint(ids[0],p0);
-  double p1[3]; points->GetPoint(ids[1],p1);
-  double p2[3]; points->GetPoint(ids[2],p2);
-  double p3[3]; points->GetPoint(ids[3],p3);
-  //cout << "----------------------------------" << endl;
-  //cout << "p0=[" << p0[0] << "," << p0[1] << "," << p0[2] << "]" << endl;
-  //cout << "p1=[" << p1[0] << "," << p1[1] << "," << p1[2] << "]" << endl;
-  //cout << "p2=[" << p2[0] << "," << p2[1] << "," << p2[2] << "]" << endl;
-  //cout << "p3=[" << p3[0] << "," << p3[1] << "," << p3[2] << "]" << endl;
-
-  double center[] = {0,0,0};
-  for (int kk=0; kk<3; kk++) {
-    center[kk] += p0[kk];
-    center[kk] += p1[kk];
-    center[kk] += p2[kk];
-    center[kk] += p3[kk];
-    center[kk] /= 4.;
-  }
-
-  vtkIdType center_id = points->InsertNextPoint(center);
-  //cout << "center=[" << center[0] << "," << center[1] << "," << center[2] << "]" << endl;
-
-  cells->InsertNextCell(3);
-  cells->InsertCellPoint(ids[0]);
-  cells->InsertCellPoint(ids[1]);
-  cells->InsertCellPoint(center_id);
-
-  cells->InsertNextCell(3);
-  cells->InsertCellPoint(ids[1]);
-  cells->InsertCellPoint(ids[3]);
-  cells->InsertCellPoint(center_id);
-
-  cells->InsertNextCell(3);
-  cells->InsertCellPoint(ids[3]);
-  cells->InsertCellPoint(ids[2]);
-  cells->InsertCellPoint(center_id);
-
-  cells->InsertNextCell(3);
-  cells->InsertCellPoint(ids[2]);
-  cells->InsertCellPoint(ids[0]);
-  cells->InsertCellPoint(center_id);
+    double p0[3]; points->GetPoint(ids[0],p0);
+    double p1[3]; points->GetPoint(ids[1],p1);
+    double p2[3]; points->GetPoint(ids[2],p2);
+    double p3[3]; points->GetPoint(ids[3],p3);
+    //cout << "----------------------------------" << endl;
+    //cout << "p0=[" << p0[0] << "," << p0[1] << "," << p0[2] << "]" << endl;
+    //cout << "p1=[" << p1[0] << "," << p1[1] << "," << p1[2] << "]" << endl;
+    //cout << "p2=[" << p2[0] << "," << p2[1] << "," << p2[2] << "]" << endl;
+    //cout << "p3=[" << p3[0] << "," << p3[1] << "," << p3[2] << "]" << endl;
+
+    double center[] = {0,0,0};
+    for (int kk=0; kk<3; kk++) {
+       center[kk] += p0[kk];
+       center[kk] += p1[kk];
+       center[kk] += p2[kk];
+       center[kk] += p3[kk];
+       center[kk] /= 4.;
+    }
+
+    vtkIdType center_id = points->InsertNextPoint(center);
+    //cout << "center=[" << center[0] << "," << center[1] << "," << center[2] << "]" << endl;
+
+    cells->InsertNextCell(3);
+    cells->InsertCellPoint(ids[0]);
+    cells->InsertCellPoint(ids[1]);
+    cells->InsertCellPoint(center_id);
+
+    cells->InsertNextCell(3);
+    cells->InsertCellPoint(ids[1]);
+    cells->InsertCellPoint(ids[3]);
+    cells->InsertCellPoint(center_id);
+
+    cells->InsertNextCell(3);
+    cells->InsertCellPoint(ids[3]);
+    cells->InsertCellPoint(ids[2]);
+    cells->InsertCellPoint(center_id);
+
+    cells->InsertNextCell(3);
+    cells->InsertCellPoint(ids[2]);
+    cells->InsertCellPoint(ids[0]);
+    cells->InsertCellPoint(center_id);
+}
+
+void insertLine(vtkCellArray *cells, vtkPoints *points, const vtkIdType ids[2]) {
+    cells->InsertNextCell(2);
+    cells->InsertCellPoint(ids[0]);
+    cells->InsertCellPoint(ids[1]);
 }
 
 double getMaximum(vtkImageData *image) {
-  bool first = true;
-  double maximum = 0;
+    bool first = true;
+    double maximum = 0;
 
-  for (int kk=0; kk<image->GetNumberOfPoints(); kk++) {
-    double value = image->GetPointData()->GetScalars()->GetTuple1(kk);
+    vtkPointData* point_data = image->GetPointData();
+    assert(point_data);
+    vtkDataArray* scalars = point_data->GetScalars();
+    assert(scalars);
 
-    if (first) {
-      maximum = value;
-      first = false;
-      continue;
-    }
+    for (int kk=0; kk<image->GetNumberOfPoints(); kk++) {
+       double value = scalars->GetTuple1(kk);
+
+       if (first) {
+           maximum = value;
+           first = false;
+           continue;
+       }
 
-    if (maximum<value) maximum = value;
-  }
+       if (maximum<value) maximum = value;
+    }
 
-  return maximum;
+    return maximum;
 }
 
+
 vtkPolyData *buildPlane(vtkImageData *image,double spatial_margin,double dose_margin) {
-  vtkPoints *points = vtkPoints::New();
-  for (int kk=0; kk<image->GetNumberOfPoints(); kk++) {
-    double *point = image->GetPoint(kk);
-    double value = image->GetPointData()->GetScalars()->GetTuple1(kk);
-    assert(value>=0);
-    assert(point[2]==0);
-    point[2] = value;
-
-    point[0] /= spatial_margin;
-    point[1] /= spatial_margin;
-    point[2] /= dose_margin;
+    vtkPoints *points = vtkPoints::New();
+    for (int kk=0; kk<image->GetNumberOfPoints(); kk++) {
+       double *point = image->GetPoint(kk);
+       double value = image->GetPointData()->GetScalars()->GetTuple1(kk);
+       assert(value>=0);
+       assert(point[2]==0);
+       point[2] = value;
+
+       point[0] /= spatial_margin;
+       point[1] /= spatial_margin;
+       point[2] /= dose_margin;
 
 #ifndef NDEBUG
-    vtkIdType point_id = points->InsertNextPoint(point);
-    assert(kk==point_id);
+       vtkIdType point_id = points->InsertNextPoint(point);
+       assert(kk==point_id);
 #else
-    points->InsertNextPoint(point);
+       points->InsertNextPoint(point);
 #endif
-  }
-
-  vtkCellArray *cells = vtkCellArray::New();
-  for (int kk=0; kk<image->GetNumberOfCells(); kk++) {
-    vtkCell *cell = image->GetCell(kk);
-    assert(cell->GetNumberOfPoints()==4);
-    insertTriangles(cells,points,cell->GetPointIds()->GetPointer(0));
-  }
-
-  vtkPolyData *data = vtkPolyData::New();
-  data->SetPoints(points);
-  data->SetPolys(cells);
-  points->Delete();
-  cells->Delete();
-
-  return data;
-}
+    }
 
-void assert2D(vtkImageData *image) {
-#ifndef NDEBUG
-  int *extent = image->GetWholeExtent();
-  assert(extent[4]==0);
-  assert(extent[5]==0);
-#endif
+    vtkCellArray *cells = vtkCellArray::New();
+    for (int kk=0; kk<image->GetNumberOfCells(); kk++) {
+       vtkCell *cell = image->GetCell(kk);
+
+       if (cell->GetNumberOfPoints()==4) {
+           insertTriangles(cells,points,cell->GetPointIds()->GetPointer(0));
+           continue;
+       }
+
+       if (cell->GetNumberOfPoints()==2) {
+           insertLine(cells,points,cell->GetPointIds()->GetPointer(0));
+           continue;
+       }
+
+       assert(false);
+    }
+
+    vtkPolyData *data = vtkPolyData::New();
+    data->SetPoints(points);
+    data->SetPolys(cells);
+    points->Delete();
+    cells->Delete();
+
+    return data;
 }
 
 int main(int argc,char * argv[])
 {
-  args_info_clitkGammaIndex args_info;
-
-  if (cmdline_parser_clitkGammaIndex(argc, argv, &args_info) != 0)
-    exit(1);
-
-  if (!args_info.absolute_dose_margin_given && !args_info.relative_dose_margin_given) {
-    std::cerr << "Specify either relative or absolute dose margin" << endl;
-    exit(1);
-  }
-
-  bool verbose = args_info.verbose_flag;
-
-  std::string reference_filename(args_info.reference_arg);
-  std::string target_filename(args_info.target_arg);
-  std::string gamma_filename(args_info.output_arg);
-  double space_margin = args_info.spatial_margin_arg;
-  double dose_rel_margin = args_info.relative_dose_margin_arg;
-  double dose_margin = args_info.absolute_dose_margin_arg;
-  bool use_dose_margin = args_info.absolute_dose_margin_given;
-
-  if (verbose) {
-    cout << "reference_filename=" << reference_filename << endl;
-    cout << "target_filename=" << target_filename << endl;
-    cout << "gamma_filename=" << gamma_filename << endl;
-    cout << "space_margin=" << space_margin << endl;
-    if (use_dose_margin) cout << "dose_margin=" << dose_margin << endl;
-    else cout << "dose_rel_margin=" << dose_rel_margin << endl;
-  }
-
-  // load reference
-  vtkImageData *reference = loadImage(reference_filename);
-  assert2D(reference);
-
-  // intensity normalisation
-  if (!use_dose_margin) {
-    dose_margin = getMaximum(reference)*dose_rel_margin;
-    if (verbose) cout << "dose_margin=" << dose_margin << endl;
-  }
-
-  // build surface
-  vtkPolyData *data = buildPlane(reference,space_margin,dose_margin);
-  reference->Delete();
-
-  vtkAbstractCellLocator *locator = vtkCellLocator::New();
-  locator->SetDataSet(data);
-  data->Delete();
-  locator->CacheCellBoundsOn();
-  locator->AutomaticOn();
-  locator->BuildLocator();
-
-  // load target
-  vtkImageData *target = loadImage(target_filename);
-  assert2D(target);
-
-  // allocate output
-  vtkImageData *output = vtkImageData::New();
-  output->SetExtent(target->GetWholeExtent());
-  output->SetOrigin(target->GetOrigin());
-  output->SetSpacing(target->GetSpacing());
-  output->SetScalarTypeToFloat();
-  output->AllocateScalars();
-
-  // fill output
-  unsigned long total = 0;
-  unsigned long over_one = 0;
-  for (int kk=0; kk<target->GetNumberOfPoints(); kk++) {
-    double *point = target->GetPoint(kk);
-    double value = target->GetPointData()->GetScalars()->GetTuple1(kk);
-    assert(value>=0);
-    assert(point[2]==0);
-    point[2] = value;
-
-    point[0] /= space_margin;
-    point[1] /= space_margin;
-    point[2] /= dose_margin;
-
-    double closest_point[3] = {0,0,0};
-    vtkIdType cell_id = 0;
-    int foo = 0;
-    double squared_distance = 0;
-
-    locator->FindClosestPoint(point,closest_point,cell_id,foo,squared_distance);
-
-    double distance = sqrt(squared_distance);
-    output->GetPointData()->GetScalars()->SetTuple1(kk,distance);
-
-    if (value>1) over_one++;
-    total++;
-
-  }
-
-  if (verbose) {
-    cout << "total=" << total << endl;
-    cout << "over_one=" << over_one << endl;
-    cout << "ratio=" << static_cast<float>(over_one)/total << endl;
-  }
-
-  locator->Delete();
-  target->Delete();
-
-  saveImage(output,gamma_filename);
-  output->Delete();
-
-  return 0;
+    clitk::RegisterClitkFactories();
+
+    args_info_clitkGammaIndex args_info;
+
+    if (cmdline_parser_clitkGammaIndex(argc, argv, &args_info) != 0)
+       exit(1);
+
+    if (!args_info.absolute_dose_margin_given && !args_info.relative_dose_margin_given) {
+       std::cerr << "Specify either relative or absolute dose margin" << endl;
+       exit(1);
+    }
+
+    bool verbose = args_info.verbose_flag;
+
+    std::string reference_filename(args_info.reference_arg);
+    std::string target_filename(args_info.target_arg);
+    std::string gamma_filename(args_info.output_arg);
+    double space_margin = args_info.spatial_margin_arg;
+    double dose_rel_margin = args_info.relative_dose_margin_arg;
+    double dose_margin = args_info.absolute_dose_margin_arg;
+    bool use_dose_margin = args_info.absolute_dose_margin_given;
+
+    if (verbose) {
+       cout << "reference_filename=" << reference_filename << endl;
+       cout << "target_filename=" << target_filename << endl;
+       cout << "gamma_filename=" << gamma_filename << endl;
+       cout << "space_margin=" << space_margin << endl;
+       if (use_dose_margin) cout << "dose_margin=" << dose_margin << endl;
+       else cout << "dose_rel_margin=" << dose_rel_margin << endl;
+    }
+
+    // load reference
+    vtkImageData* reference = loadImage(reference_filename);
+    assert(reference);
+
+    // intensity normalisation
+    if (!use_dose_margin) {
+       dose_margin = getMaximum(reference)*dose_rel_margin;
+       if (verbose) cout << "dose_margin=" << dose_margin << endl;
+    }
+
+    // build surface
+    vtkPolyData *data = buildPlane(reference,space_margin,dose_margin);
+    reference->Delete();
+
+    vtkAbstractCellLocator *locator = vtkCellLocator::New();
+    locator->SetDataSet(data);
+    data->Delete();
+    locator->CacheCellBoundsOn();
+    locator->AutomaticOn();
+    locator->BuildLocator();
+
+    // load target
+    vtkImageData* target = loadImage(target_filename);
+    assert(target);
+
+    // allocate output
+    OutputImageType::Pointer output = OutputImageType::New();
+    {
+       OutputImageType::SizeType::SizeValueType output_array_size[2];
+       output_array_size[0] = target->GetDimensions()[0];
+       output_array_size[1] = target->GetDimensions()[1];
+       OutputImageType::SizeType output_size;
+       output_size.SetSize(output_array_size);
+       output->SetRegions(OutputImageType::RegionType(output_size));
+       output->SetOrigin(target->GetOrigin());
+       output->SetSpacing(target->GetSpacing());
+       output->Allocate();
+    }
+
+    // fill output
+    unsigned long  kk = 0;
+    unsigned long over_one = 0;
+    OutputImageIterator iter(output,output->GetLargestPossibleRegion());
+    iter.GoToBegin();
+    while (!iter.IsAtEnd()) {
+       double *point = target->GetPoint(kk);
+       double value = target->GetPointData()->GetScalars()->GetTuple1(kk);
+       assert(value>=0);
+       assert(point[2]==0);
+       point[2] = value;
+
+       point[0] /= space_margin;
+       point[1] /= space_margin;
+       point[2] /= dose_margin;
+
+       double closest_point[3] = {0,0,0};
+       vtkIdType cell_id = 0;
+       int foo = 0;
+       double squared_distance = 0;
+
+       locator->FindClosestPoint(point,closest_point,cell_id,foo,squared_distance);
+       double distance = sqrt(squared_distance);
+       iter.Set(distance);
+
+       if (distance>1) over_one++;
+       kk++;
+       ++iter;
+    }
+
+    if (verbose) {
+       cout << "total=" << kk << endl;
+       cout << "over_one=" << over_one << endl;
+       cout << "ratio=" << static_cast<float>(over_one)/kk << endl;
+    }
+
+    locator->Delete();
+    target->Delete();
+
+    saveImage(output,gamma_filename);
+
+    return 0;
 }
 
index 61dbcb1de2e7dc7cd53cd5318a327c75e451cc19..4cb22ca85c806ae1bb0d9f941913e8e91a152b01 100644 (file)
@@ -43,7 +43,7 @@ int main(int argc, char * argv[])
 
   // Go !
   filter->SetArgsInfo(args_info);
-  filter->Update();
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   // this is the end my friend
   return EXIT_SUCCESS;
index 297b63711f6c107f389ea487b9049221582a4b44..64bcfe180a32a50f9f8759341e6e63d0d1b3efba 100644 (file)
@@ -60,7 +60,7 @@ int main(int argc, char * argv[])
   if (args_info.type_given) filter->SetOutputPixelType(args_info.type_arg);
 
   // Go !
-  filter->Update();
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   // this is the end my friend
   return 0;
index 0aec22548c64b5d7d6251bfbcec52cf61c0080ec..145863a93670c6c4d5afab0628a7bb35124ff33c 100644 (file)
@@ -45,7 +45,7 @@ int main(int argc, char * argv[])
   FilterType::Pointer genericFilter = FilterType::New();
 
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index 5af8a7fb44c117bcfb9cdb513c145d5ea736d351..cf50f6852797bdcb4c00af396229c5e1f95a568a 100644 (file)
@@ -45,7 +45,7 @@ int main(int argc, char * argv[])
   FilterType::Pointer genericFilter = FilterType::New();
 
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index 661e1839a86f5a9a4a3969d13a2ea0478a472b09..bd2f3747cc5e5d5c042eb6face19c04e7756b4fe 100644 (file)
@@ -33,7 +33,7 @@ int main(int argc, char * argv[])
   FilterType::Pointer filter = FilterType::New();
 
   filter->SetArgsInfo(args_info);
-  filter->Update();
+  CLITK_TRY_CATCH_EXIT(filter->Update());
 
   // this is the end my friend
   return EXIT_SUCCESS;
index a44b4eb00f7c9599231a1adf91947e9d2f04018c..b70799990b4044f0db55c468fb831bdf41d9742f 100644 (file)
@@ -34,7 +34,7 @@ int main(int argc, char * argv[])
   clitk::SetBackgroundGenericFilter::Pointer genericFilter=clitk::SetBackgroundGenericFilter::New();
 
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index cf1dec0fd8b07a814cc62f6a047db23a8a9357d2..3360661b1a74a0a76a0c0d33164e54d9f0b67fb6 100644 (file)
@@ -44,7 +44,7 @@ int main(int argc, char * argv[])
   clitk::WarpImageGenericFilter::Pointer genericFilter=clitk::WarpImageGenericFilter::New();
 
   genericFilter->SetArgsInfo(args_info);
-  genericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(genericFilter->Update());
 
   return EXIT_SUCCESS;
 }// end main
index f19e567fc5ab8e348cc81e7764790d80fe21e6c7..52b3a2af40784981ae0068bbaa52dccb86b4c533 100644 (file)
@@ -50,7 +50,7 @@ int main( int argc, char *argv[] )
   zeroVFGenericFilter->SetVerbose(args_info.verbose_flag);
 
   //update
-  zeroVFGenericFilter->Update();
+  CLITK_TRY_CATCH_EXIT(zeroVFGenericFilter->Update());
   return EXIT_SUCCESS;
 }
 #endif
index 3198e7edbbf147c6e44d2b055b3ff872c5d6e8eb..84ffae065db79a01b961670ff500f14ab79e9c43 100644 (file)
@@ -94,6 +94,8 @@ SET(vv_SRCS
   vvImageContour.cxx
   vvBinaryImageOverlayActor.cxx
   vvStructureSetActor.cxx
+  vvSaveState.cxx
+  vvReadState.cxx
   vvROIActor.cxx
   vvBlendImageActor.cxx
   vvToolManager.cxx
index e03cb231421f775fc2fc93c03ea5e447cce40b32..88eddcf87d9aef92a1a510ef23c8ece1fdf94e24 100644 (file)
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="NOViewWidget" native="true">
+           <widget class="QVTKWidget" name="NOViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="SOViewWidget" native="true">
+           <widget class="QVTKWidget" name="SOViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="NEViewWidget" native="true">
+           <widget class="QVTKWidget" name="NEViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="SEViewWidget" native="true">
+           <widget class="QVTKWidget" name="SEViewWidget">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
               <horstretch>0</horstretch>
    <property name="defaultUp">
     <bool>false</bool>
    </property>
-   <widget class="QMenu" name="menuFile">
-    <property name="title">
-     <string>File</string>
-    </property>
-    <addaction name="actionLoad_images"/>
-    <addaction name="actionOpen_Image_With_Time"/>
-    <addaction name="actionMerge_images_as_n_dim_t"/>
-    <addaction name="separator"/>
-    <addaction name="actionSlice_Image_As_Multiple_Images"/>
-    <addaction name="actionOpen_Multiple_Images_As_One"/>
-    <addaction name="separator"/>
-    <addaction name="actionOpen_Dicom"/>
-    <addaction name="actionOpen_Dicom_Struct"/>
-    <addaction name="actionOpen_VTK_contour"/>
-    <addaction name="separator"/>
-    <addaction name="actionSave_As"/>
-    <addaction name="separator"/>
-    <addaction name="actionExit"/>
-   </widget>
    <widget class="QMenu" name="menuHelp">
     <property name="title">
      <string>Help</string>
      <string>Tools</string>
     </property>
    </widget>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="actionLoad_images"/>
+    <addaction name="actionOpen_Image_With_Time"/>
+    <addaction name="actionMerge_images_as_n_dim_t"/>
+    <addaction name="separator"/>
+    <addaction name="actionSlice_Image_As_Multiple_Images"/>
+    <addaction name="actionOpen_Multiple_Images_As_One"/>
+    <addaction name="separator"/>
+    <addaction name="actionOpen_Dicom"/>
+    <addaction name="actionOpen_Dicom_Struct"/>
+    <addaction name="actionOpen_VTK_contour"/>
+    <addaction name="separator"/>
+    <addaction name="actionSave_As"/>
+    <addaction name="separator"/>
+    <addaction name="actionExit"/>
+    <addaction name="actionSave_current_state"/>
+    <addaction name="actionRead_saved_state"/>
+   </widget>
    <addaction name="menuFile"/>
    <addaction name="menuOverlay"/>
    <addaction name="menuScreenshots"/>
     <string>Save all slices (Top-Left view)</string>
    </property>
   </action>
+  <action name="actionSave_current_state">
+   <property name="icon">
+    <iconset>
+     <normaloff>../icons/filesave.png</normaloff>../icons/filesave.png</iconset>
+   </property>
+   <property name="text">
+    <string>Save current state</string>
+   </property>
+   <property name="toolTip">
+    <string>Save current window and file states</string>
+   </property>
+  </action>
+  <action name="actionRead_saved_state">
+   <property name="icon">
+    <iconset>
+     <normaloff>../icons/filesave.png</normaloff>../icons/filesave.png</iconset>
+   </property>
+   <property name="text">
+    <string>Read Saved State</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
index 301521b4662a8509197d81174b348964b4e5e140..7f640a52a0579d660b251643a0357c8a7ad42327 100644 (file)
--- a/vv/vv.cxx
+++ b/vv/vv.cxx
@@ -30,6 +30,7 @@
 
 #include "clitkIO.h"
 #include "vvMainWindow.h"
+#include "vvReadState.h"
 #include "vvToolsList.h"
 #include <vtkFileOutputWindow.h>
 #include <vtkSmartPointer.h>
@@ -168,7 +169,14 @@ int main( int argc, char** argv )
           vtk_log->FlushOn();
           vtk_log->AppendOn();
           vtkOutputWindow::SetInstance(vtk_log);
+        } else if (current == "--state") {
+          //window.ReadSavedStateFile(argv[i+1]);
+          vvReadState read_state;
+          read_state.Run(&window, argv[i+1]);
+          n_image_loaded += read_state.GetNumberOfImages();
+          i++;
         }
+        
       } else if (parse_mode == P_SEQUENCE) {
         sequence_filenames.push_back(current);
       } else if (parse_mode == P_WINDOW) {
index 7b83b7005b6e4debcc39be72531d4493c70cbd52..8884cbbb95bc3b040b4e093d80016ae84c5caf94 100644 (file)
@@ -45,6 +45,8 @@
 #include "vvMesh.h"
 #include "vvStructSelector.h"
 #include "vvMeshReader.h"
+#include "vvSaveState.h"
+#include "vvReadState.h"
 #include "clitkConfiguration.h"
 
 // ITK include
@@ -144,6 +146,16 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionSave_image,SIGNAL(triggered()),this,SLOT(SaveAs()));
   contextActions.push_back(actionSave_image);
 
+  QAction* actionSave_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
+                              tr("Save Current State"));
+  connect(actionSave_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState()));
+  contextActions.push_back(actionSave_state);
+
+  QAction* actionRead_state = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/filesave.png")),
+                              tr("Read Saved State"));
+  connect(actionRead_state,SIGNAL(triggered()),this,SLOT(ReadSavedState()));
+  contextActions.push_back(actionRead_state);
+
   contextMenu.addSeparator();
 
   contextMenu.addAction(actionAdd_VF_to_current_Image);
@@ -255,6 +267,8 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionOpen_Image_With_Time,SIGNAL(triggered()),this,SLOT(OpenImageWithTime()));
   connect(actionMerge_images_as_n_dim_t, SIGNAL(triggered()), this, SLOT(MergeImagesWithTime()));
   connect(actionSave_As,SIGNAL(triggered()),this,SLOT(SaveAs()));
+  connect(actionSave_current_state,SIGNAL(triggered()),this,SLOT(SaveCurrentState()));
+  connect(actionRead_saved_state,SIGNAL(triggered()),this,SLOT(ReadSavedState()));
   connect(actionExit,SIGNAL(triggered()),this,SLOT(close()));
   connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField()));
   connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
@@ -292,6 +306,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
 
   connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ShowContextMenu(QPoint)));
 
+#include "vvSaveState.h"
   connect(linkPanel,SIGNAL(addLink(QString,QString)),this,SLOT(AddLink(QString,QString)));
   connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString)));
   connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double)));
@@ -2263,6 +2278,48 @@ void vvMainWindow::SaveAs()
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::SaveCurrentState()
+{
+  QString Extensions = "XML Files(*.xml)";
+  QString fileName = QFileDialog::getSaveFileName(this,
+                     tr("Save Current Window State"),
+                     "",
+                     Extensions);
+                     
+  SaveCurrentStateAs(fileName.toStdString());
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::SaveCurrentStateAs(const std::string& stateFile)
+{
+  vvSaveState save_state;
+  save_state.Run(this, stateFile);
+  
+  std::cout << "void vvMainWindow::SaveCurrentState()" << std::endl;
+}
+
+//------------------------------------------------------------------------------
+void vvMainWindow::ReadSavedState()
+{
+  QString Extensions = "XML Files(*.xml)";
+  QString fileName = QFileDialog::getOpenFileName(this,
+                     tr("Load Window State"),
+                     "",
+                     Extensions);
+                     
+  ReadSavedStateFile(fileName.toStdString());
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::ReadSavedStateFile(const std::string& stateFile)
+{
+  vvReadState read_state;
+  read_state.Run(this, stateFile);
+}
+//------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 void vvMainWindow::AddLink(QString image1,QString image2)
index 8a2f0365ae6361f9a8d31e36edc6d22277292a3c..dfcbca6d40319fff99f8a23e1dd0edd5b6012240 100644 (file)
@@ -40,6 +40,7 @@ class vtkRenderer;
 class vtkMatrix4x4;
 class vvDicomSeriesSelector;
 class vvSlicer;
+class QTreeWidget;
 
 //------------------------------------------------------------------------------
 class vvMainWindow: public vvMainWindowBase,
@@ -60,9 +61,12 @@ class vvMainWindow: public vvMainWindowBase,
   void AddContour(int image_index, vvMesh::Pointer contour, bool propagation);
   ///This is used to show an image when opened or computed
   void ShowLastImage();
+  void SaveCurrentStateAs(const std::string& stateFile);
+  void ReadSavedStateFile(const std::string& stateFile);
 
   virtual void UpdateCurrentSlicer();
   virtual QTabWidget * GetTab();
+  QTreeWidget* GetTree() { return DataTree; }
   //vvMainWindowToolInfo * GetInfoForTool();
 //   void AddRunningTool(vvToolCreatorBase * tool);
 
@@ -82,6 +86,8 @@ public slots:
   ///Open a vtkPolyData surface mesh and display it over the current image
   void OpenVTKContour();
   void SaveAs();
+  void SaveCurrentState();
+  void ReadSavedState();
   void CurrentImageChanged(std::string id);
   void CurrentPickedImageChanged(std::string id);
   void ImageInfoChanged();
diff --git a/vv/vvReadState.cxx b/vv/vvReadState.cxx
new file mode 100644 (file)
index 0000000..83a7c5e
--- /dev/null
@@ -0,0 +1,149 @@
+#include "vvReadState.h"
+#include "vvMainWindow.h"
+
+#include <qtreewidget.h>
+
+#include <QFile>
+#include <QXmlStreamReader>
+
+#include <cassert>
+#include <string>
+
+vvReadState::vvReadState() : m_XmlReader(new QXmlStreamReader), m_File(new QFile)
+{
+  m_NumImages = 0;
+}
+
+vvReadState::~vvReadState()
+{
+}
+
+void vvReadState::Run(vvMainWindow* vvWindow, const std::string& file)
+{
+  assert(vvWindow);
+
+  m_NumImages = 0;
+  m_File->setFileName(file.c_str());
+  m_File->open(QIODevice::ReadOnly);
+  m_XmlReader->setDevice(m_File.get());
+  m_Window = vvWindow;
+  QTreeWidget* tree = m_Window->GetTree();
+  m_TreeItemCount = tree->topLevelItemCount();
+
+  ReadGUI();
+  ReadTree();
+}
+
+void vvReadState::ReadTree()
+{
+  std::string value;
+  
+  while (!m_XmlReader->atEnd()) {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "Image") 
+        value = ReadImage();
+    } 
+  }
+  
+  if (m_XmlReader->hasError())
+    std::cout << "Error " << m_XmlReader->error() << " XML " << std::endl;
+}
+
+std::string  vvReadState::ReadImage()
+{
+  std::string value;
+  int current_index = -1;
+  std::vector<std::string> files(1);
+
+  QXmlStreamAttributes attributes = m_XmlReader->attributes();
+  if (!m_XmlReader->hasError())
+    current_index = attributes.value("Index").toString().toInt();
+
+  current_index += m_TreeItemCount;
+  
+  while (!m_XmlReader->isEndElement() || value != "Image") { 
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    //std::cout << "Value = " << value << std::endl;
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        files[0] = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError()) {
+          m_Window->LoadImages(files, vvImageReader::IMAGE);
+        }
+      }
+      else if (current_index >= 0) {
+        if (value == "Fusion") 
+          value = ReadFusion(current_index);
+        else if (value == "Overlay")
+          value = ReadOverlay(current_index);
+        else if (value == "Vector")
+          value = ReadVector(current_index);
+      }
+    }
+  }
+  
+  if (!m_XmlReader->hasError())
+    m_NumImages++;
+
+  return value;
+}
+
+std::string vvReadState::ReadFusion(int index)
+{
+  std::string file, value;
+  while (!m_XmlReader->isEndElement() || value != "Fusion") {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        file = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError())
+          m_Window->AddFusionImage(index, file.c_str());
+      }
+    }
+  }
+  return value;
+}
+
+std::string vvReadState::ReadOverlay(int index)
+{
+  std::string file, value;
+  while (!m_XmlReader->isEndElement() || value != "Overlay") {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        file = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError())
+          m_Window->AddOverlayImage(index, file.c_str());
+      }
+    }
+  }
+  return value;
+}
+
+std::string vvReadState::ReadVector(int index)
+{
+  std::string file, value;
+  while (!m_XmlReader->isEndElement() || value != "Vector") {
+    m_XmlReader->readNext();
+    value = m_XmlReader->qualifiedName().toString().toStdString();
+    if (m_XmlReader->isStartElement()) {
+      if (value == "FileName") {
+        file = m_XmlReader->readElementText().toStdString();
+        if (!m_XmlReader->hasError())
+          m_Window->AddField(file.c_str(), index);
+      }
+    }
+  }
+  return value;
+}
+
+void vvReadState::ReadGUI()
+{
+
+}
+
diff --git a/vv/vvReadState.h b/vv/vvReadState.h
new file mode 100644 (file)
index 0000000..8d6d560
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef VVREADSTATE_H
+#define VVREADSTATE_H
+
+#include <string>
+#include <memory>
+
+class vvMainWindow;
+class QXmlStreamReader;
+class QFile;
+
+class vvReadState
+{
+public:
+  vvReadState();
+  virtual ~vvReadState();
+  
+  virtual void Run(vvMainWindow* vvWindow, const std::string& file);
+  int GetNumberOfImages() { return m_NumImages; }
+    
+protected:
+  
+  void ReadGUI();
+  void ReadTree();
+  std::string  ReadImage();
+  std::string  ReadFusion(int index);
+  std::string  ReadOverlay(int index);
+  std::string  ReadVector(int index);
+
+  std::auto_ptr<QXmlStreamReader> m_XmlReader;
+  std::auto_ptr<QFile> m_File;
+  vvMainWindow* m_Window;
+  int m_TreeItemCount;
+  int m_NumImages;
+};
+
+#endif // VVREADSTATE_H
diff --git a/vv/vvSaveState.cxx b/vv/vvSaveState.cxx
new file mode 100644 (file)
index 0000000..e573bb9
--- /dev/null
@@ -0,0 +1,119 @@
+#include "vvSaveState.h"
+#include "vvMainWindow.h"
+
+#include <QDir>
+#include <QFile>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QXmlStreamWriter>
+
+#include <cassert>
+#include <string>
+
+vvSaveState::vvSaveState() : m_XmlWriter(new QXmlStreamWriter), m_File(new QFile)
+{
+}
+
+vvSaveState::~vvSaveState()
+{
+}
+
+void vvSaveState::Run(vvMainWindow* vvWindow, const std::string& file)
+{
+  assert(vvWindow);
+
+  m_File->setFileName(file.c_str());
+  m_File->remove();
+  m_File->open(QIODevice::Text | QIODevice::ReadWrite);
+  
+  m_Window = vvWindow;
+
+  m_XmlWriter->setDevice(m_File.get());
+  m_XmlWriter->setAutoFormatting(true);
+  m_XmlWriter->setAutoFormattingIndent(2);
+  m_XmlWriter->writeStartDocument();
+  m_XmlWriter->writeStartElement("VVState");
+  SaveGlobals();
+  SaveGUI();
+  SaveTree();
+  m_XmlWriter->writeEndDocument();
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveGlobals()
+{
+  m_XmlWriter->writeStartElement("Globals");
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveTree()
+{
+  QTreeWidget* tree = m_Window->GetTree();
+  QTreeWidgetItem* item;
+  
+  m_XmlWriter->writeStartElement("Images");
+  for (int i = 0; i < tree->topLevelItemCount(); i++) {
+    item = tree->topLevelItem(i);
+    SaveImage(item, i);
+  }
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveImage(QTreeWidgetItem* item, int index)
+{
+  m_XmlWriter->writeStartElement("Image");
+  
+  std::ostringstream indexStr;
+  indexStr.str("");
+  indexStr << index;
+  m_XmlWriter->writeAttribute("Index", indexStr.str().c_str());
+
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  
+  QTreeWidgetItem* item_child;
+  std::string role;
+  for (int i = 0; i < item->childCount(); i++) {
+    item_child = item->child(i);
+    role = item_child->data(1,Qt::UserRole).toString().toStdString();
+    if (role == "fusion")
+      SaveFusion(item_child);
+    else if (role == "overlay")
+      SaveOverlay(item_child);
+    else if (role == "vector")
+      SaveVector(item_child);
+  }
+  
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveFusion(QTreeWidgetItem* item)
+{
+  m_XmlWriter->writeStartElement("Fusion");
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveOverlay(QTreeWidgetItem* item)
+{
+  m_XmlWriter->writeStartElement("Overlay");
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveVector(QTreeWidgetItem* item)
+{
+  m_XmlWriter->writeStartElement("Vector");
+  std::string filename = item->data(0, Qt::UserRole).toString().toStdString();
+  m_XmlWriter->writeTextElement("FileName", QDir::current().absoluteFilePath(filename.c_str()));
+  m_XmlWriter->writeEndElement();
+}
+
+void vvSaveState::SaveGUI()
+{
+  m_XmlWriter->writeStartElement("GUI");
+  m_XmlWriter->writeEndElement();
+}
+
diff --git a/vv/vvSaveState.h b/vv/vvSaveState.h
new file mode 100644 (file)
index 0000000..7a7cda9
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef VVSAVESTATE_H
+#define VVSAVESTATE_H
+
+#include <string>
+#include <memory>
+
+class vvMainWindow;
+class QXmlStreamWriter;
+class QFile;
+class QTreeWidgetItem;
+
+class vvSaveState
+{
+public:
+  vvSaveState();
+  virtual ~vvSaveState();
+  
+  virtual void Run(vvMainWindow* vvWindow, const std::string& file);
+    
+protected:
+  
+  void SaveGlobals();
+  void SaveGUI();
+  void SaveTree();
+  void SaveImage(QTreeWidgetItem* item, int index);
+  void SaveFusion(QTreeWidgetItem* item);
+  void SaveOverlay(QTreeWidgetItem* item);
+  void SaveVector(QTreeWidgetItem* item);
+
+  std::auto_ptr<QXmlStreamWriter> m_XmlWriter;
+  std::auto_ptr<QFile> m_File;
+  vvMainWindow* m_Window;
+};
+
+#endif // VVSAVESTATE_H