]> Creatis software - clitk.git/blob - segmentation/clitkRelativePositionList.txx
Small debug for args_info stuff
[clitk.git] / segmentation / clitkRelativePositionList.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ======================================================================-====*/
18
19
20 //--------------------------------------------------------------------
21 template <class TImageType>
22 clitk::RelativePositionList<TImageType>::
23 RelativePositionList() {
24 }
25 //--------------------------------------------------------------------
26
27
28 //--------------------------------------------------------------------
29 template <class TImageType>
30 void
31 clitk::RelativePositionList<TImageType>::
32 Read(std::string filename) {
33   /*
34     The goal here is to read a text file that contains options for the
35     RelativePosition filter. The text file contains options in the
36     same form of the config file of the clitkRelativePosition tool. In
37     this text file, each time a "object" option is found, a new set of
38     options is considered.
39    */
40
41   // Open the file
42   std::ifstream is;
43   openFileForReading(is, filename);
44
45   // Read input -> the structure name that will be used as input
46   // (initial support)
47   skipComment(is);
48   std::string s;
49   is >> s;
50   if (s != "input") {
51     FATAL("while reading RelativePositionList file. This file must start with 'input = '");
52     exit(0);
53   }
54   is >> s; 
55   if (s != "=") {
56     FATAL("while reading RelativePositionList file. This file must start with 'input = '");
57     exit(0);
58   }
59   std::string name;
60   is >> name;
61   skipComment(is);
62
63   // Create a temporary filename 
64   char n[] = "tmp_clitkRelativePosition_XXXXXX";
65   mkstemp(n); // tmpnam(n); 
66   std::string tmpfilename(n);
67   
68   // Loop on the file text ; Every time we see a "object" token, we
69   // split the file.
70   while (is) {
71     bool stop=false;
72     std::ostringstream ss;
73     // first part of ss is the last 'object = ' found, stored in s
74     ss << s << std::endl; 
75     while (!stop) {
76       skipComment(is);
77       if (!is) stop = true;
78       else {
79         std::getline(is, s);
80         if (s.find("object") != std::string::npos) stop=true;
81         else ss << s << std::endl;
82         if (!is) stop = true;
83       }
84     }
85     std::string text = ss.str();
86     if (text.size() > 10) { // if too small, it is not a list of option
87       std::ofstream os;
88       openFileForWriting(os, tmpfilename);
89       os << text;
90       os << "input = nothing" << std::endl;
91       os << "output = nothing" << std::endl;
92       os.close();
93
94       // Create a struct to store options. I use two step to allow to
95       // fill the args values with de default and then check
96       // automatically the options.
97       ArgsInfoType args_info;
98       std::vector<char> writable(tmpfilename.size() + 1);
99       std::copy(tmpfilename.begin(), tmpfilename.end(), writable.begin());
100       char ** argv = new char*[1];
101       argv[0] = new char[1];
102       struct cmdline_parser_clitkRelativePosition_params params;
103       params.override = 0;
104       params.initialize = 1;
105       params.check_required = 0;
106       cmdline_parser_clitkRelativePosition_configfile(&writable[0], &args_info, 1, 1, 1);
107       mArgsInfoList.push_back(args_info);
108       
109       // Delete the temporary file
110       std::remove(tmpfilename.c_str());
111     }
112   }
113
114   // Set the main input name
115   SetInputName(name);
116 }
117 //--------------------------------------------------------------------
118
119
120 //--------------------------------------------------------------------
121 template <class TImageType>
122 void 
123 clitk::RelativePositionList<TImageType>::
124 GenerateInputRequestedRegion() 
125 {
126   // Call default
127   itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
128   // Get input pointers and set requested region to common region
129   ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
130   input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
131 }
132 //--------------------------------------------------------------------
133
134
135
136 //--------------------------------------------------------------------
137 template <class TImageType>
138 void
139 clitk::RelativePositionList<TImageType>::
140 GenerateOutputInformation() {
141
142   // Get input
143   m_working_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
144
145   // Loop on RelativePositionList of operations
146   std::string s = GetInputName();
147   for(uint i=0; i<mArgsInfoList.size(); i++) {
148     // clitk::PrintMemory(true, "Start"); 
149     std::string text = "["+s+"] limits ";
150     if (mArgsInfoList[i].orientation_given) text += std::string(mArgsInfoList[i].orientation_arg[0])+" ";
151     else text = text+"("+toString(mArgsInfoList[i].angle1_arg)+" "+
152            toString(mArgsInfoList[i].angle2_arg)+" "+
153            (mArgsInfoList[i].inverse_flag?"true":"false")+") ";
154     text = text+mArgsInfoList[i].object_arg+" "+toString(mArgsInfoList[i].threshold_arg);
155     if (mArgsInfoList[i].sliceBySlice_flag) {
156       text += " slice by slice";
157     }
158     else text += " 3D";
159     text += " spacing=" + toString(mArgsInfoList[i].spacing_arg);
160
161     StartNewStep(text);  
162     typename RelPosFilterType::Pointer relPosFilter;
163
164     // Is it slice by slice or 3D ?
165     if (mArgsInfoList[i].sliceBySlice_flag) {
166       typename SliceRelPosFilterType::Pointer f = SliceRelPosFilterType::New();
167       relPosFilter = f;
168       SetFilterOptions(relPosFilter, mArgsInfoList[i]);  
169       f->SetDirection(2);
170       // Set SbS specific options
171       f->SetUniqueConnectedComponentBySliceFlag(mArgsInfoList[i].uniqueCCL_flag);
172       f->SetObjectCCLSelectionFlag(mArgsInfoList[i].uniqueObjectCCL_flag);
173       f->IgnoreEmptySliceObjectFlagOn();
174       //f->SetObjectCCLSelectionDimension(0);
175       //f->SetObjectCCLSelectionDirection(-1);
176       //f->SetAutoCropFlag(false);
177       // Print if needed
178       if (mArgsInfoList[i].verboseOptions_flag) f->PrintOptions();
179     }
180     else {
181       relPosFilter = clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::New();
182       SetFilterOptions(relPosFilter, mArgsInfoList[i]);  
183       // Print if needed
184       if (mArgsInfoList[i].verboseOptions_flag) relPosFilter->PrintOptions();
185     }
186
187     // Set input
188     relPosFilter->SetInput(m_working_input);  
189   
190     // Run the filter
191     relPosFilter->Update();
192     m_working_input = relPosFilter->GetOutput();  
193     StopCurrentStep<ImageType>(m_working_input);
194     // clitk::PrintMemory(true, "End"); 
195   }
196 }
197 //--------------------------------------------------------------------
198
199
200 //--------------------------------------------------------------------
201 template <class TImageType>
202 void
203 clitk::RelativePositionList<TImageType>::
204 GenerateData() 
205 {
206   // Final Step -> set output
207   this->GraftOutput(m_working_input);
208 }
209 //--------------------------------------------------------------------
210
211
212 //--------------------------------------------------------------------
213 template <class TImageType>
214 void
215 clitk::RelativePositionList<TImageType>::
216 SetFilterOptions(typename RelPosFilterType::Pointer filter, ArgsInfoType & options) {
217
218   if (options.orientation_given > 1) {
219     clitkExceptionMacro("Error in the RelPos options. I need a single --orientation (for the moment)."
220                         << " Current options are for obj = '" << options.object_arg
221                         << "', threshold = " << options.threshold_arg << std::endl);
222   }
223
224   ImagePointer object = GetAFDB()->template GetImage<ImageType>(options.object_arg);
225   filter->SetInputObject(object);
226   filter->WriteStepFlagOff();
227   filter->SetVerboseImageSizeFlag(GetVerboseImageSizeFlag());
228   filter->SetFuzzyThreshold(options.threshold_arg);
229   filter->SetInverseOrientationFlag(options.inverse_flag); // MUST BE BEFORE AddOrientationTypeString
230
231   if (options.orientation_given == 1)  {
232     for(uint i=0; i<options.orientation_given; i++) 
233       filter->AddOrientationTypeString(options.orientation_arg[i]);
234   }
235   else {
236     if (options.angle1_given && options.angle2_given) {
237       filter->AddAnglesInDeg(options.angle1_arg, options.angle2_arg);
238     }
239     else {
240       clitkExceptionMacro("Error in the RelPos options. I need --orientation or (--angle1 and --angle2)."
241                           << " Current options are for obj = '" << options.object_arg
242                           << "', threshold = " << options.threshold_arg << std::endl);
243     }
244   }
245   filter->SetIntermediateSpacing(options.spacing_arg);
246   if (options.spacing_arg == -1) filter->IntermediateSpacingFlagOff();
247   else filter->IntermediateSpacingFlagOn();
248   filter->SetVerboseStepFlag(options.verboseStep_flag);
249   filter->SetAutoCropFlag(!options.noAutoCrop_flag); 
250 }
251 //--------------------------------------------------------------------