clitkXdrImageIOFactory.cxx
clitkHndImageIO.cxx
clitkHndImageIOFactory.cxx
+ clitkGateAsciiImageIO.cxx
+ clitkGateAsciiImageIOFactory.cxx
clitkDicomRTDoseIO.cxx
clitkDicomRTDoseIOFactory.cxx
clitkOrientation.cxx
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
--- /dev/null
+/*=========================================================================
+ 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);
+}
--- /dev/null
+/*=========================================================================
+ 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 */
+
--- /dev/null
+/*=========================================================================
+ 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());
+}
--- /dev/null
+/*=========================================================================
+ 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 */
+
#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();
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;
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...
# 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}_
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
# 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_*
-#! /bin/bash -x
-
+#! /bin/bash
+
###############################################################################
#
# FILE: create_midP-2.0.sh
{
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()
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
}
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]}
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
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
-#! /bin/sh +x
+#! /bin/sh -x
###############################################################################
#
#
###############################################################################
+#
+# 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
#
###############################################################################
+source `dirname $0`/midp_common.sh
+
################# BLUTDIR #####################
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 #####################
# 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
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
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
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
itkGetConstMacro(FillHolesFlag, bool);
itkBooleanMacro(FillHolesFlag);
+ // Separate lungs
+ itkSetMacro(SeparateLungsFlag, bool);
+ itkGetConstMacro(SeparateLungsFlag, bool);
+ itkBooleanMacro(SeparateLungsFlag);
+
// Step Auto Crop
itkSetMacro(AutoCrop, bool);
itkGetConstMacro(AutoCrop, bool);
bool m_FillHolesFlag;
InputImageSizeType m_FillHolesDirections;
+ bool m_SeparateLungsFlag;
+
// Main functions
virtual void GenerateOutputInformation();
virtual void GenerateInputRequestedRegion();
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;
f->SetFillHolesFlag(false);
else
f->SetFillHolesFlag(true);
+
+ if (mArgsInfo.doNotSeparateLungs_given)
+ f->SetSeparateLungsFlag(false);
+ else
+ f->SetSeparateLungsFlag(true);
}
//--------------------------------------------------------------------
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
//-----------------------------------------------------------
// Constructor
//-----------------------------------------------------------
- ExtractPatientGenericFilter::ExtractPatientGenericFilter()
+ ExtractPatientGenericFilter:::ExtractPatientGenericFilter()
{
m_Verbose=false;
m_InputFileName="";
// 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
clitk::MotionMaskGenericFilter::Pointer genericFilter=clitk::MotionMaskGenericFilter::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
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)
FilterType::Pointer genericFilter = FilterType::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
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
clitk::CombineImageGenericFilter::Pointer genericFilter=clitk::CombineImageGenericFilter::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
//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;
}
#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;
}
// Go !
filter->SetArgsInfo(args_info);
- filter->Update();
+ CLITK_TRY_CATCH_EXIT(filter->Update());
// this is the end my friend
return EXIT_SUCCESS;
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;
FilterType::Pointer genericFilter = FilterType::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
FilterType::Pointer genericFilter = FilterType::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
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;
clitk::SetBackgroundGenericFilter::Pointer genericFilter=clitk::SetBackgroundGenericFilter::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
clitk::WarpImageGenericFilter::Pointer genericFilter=clitk::WarpImageGenericFilter::New();
genericFilter->SetArgsInfo(args_info);
- genericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(genericFilter->Update());
return EXIT_SUCCESS;
}// end main
zeroVFGenericFilter->SetVerbose(args_info.verbose_flag);
//update
- zeroVFGenericFilter->Update();
+ CLITK_TRY_CATCH_EXIT(zeroVFGenericFilter->Update());
return EXIT_SUCCESS;
}
#endif
vvImageContour.cxx
vvBinaryImageOverlayActor.cxx
vvStructureSetActor.cxx
+ vvSaveState.cxx
+ vvReadState.cxx
vvROIActor.cxx
vvBlendImageActor.cxx
vvToolManager.cxx
<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>
#include "clitkIO.h"
#include "vvMainWindow.h"
+#include "vvReadState.h"
#include "vvToolsList.h"
#include <vtkFileOutputWindow.h>
#include <vtkSmartPointer.h>
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) {
#include "vvMesh.h"
#include "vvStructSelector.h"
#include "vvMeshReader.h"
+#include "vvSaveState.h"
+#include "vvReadState.h"
#include "clitkConfiguration.h"
// ITK include
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);
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()));
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)));
}
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+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)
class vtkMatrix4x4;
class vvDicomSeriesSelector;
class vvSlicer;
+class QTreeWidget;
//------------------------------------------------------------------------------
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);
///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();
--- /dev/null
+#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()
+{
+
+}
+
--- /dev/null
+#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
--- /dev/null
+#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();
+}
+
--- /dev/null
+#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