]> Creatis software - clitk.git/blob - segmentation/clitkExtractLymphStation_Supports.txx
Remove debug and correct slice position for CaudlaMarginOf BV
[clitk.git] / segmentation / clitkExtractLymphStation_Supports.txx
1
2 #include <itkBinaryDilateImageFilter.h>
3 #include <itkMirrorPadImageFilter.h>
4
5 //--------------------------------------------------------------------
6 template <class ImageType>
7 void 
8 clitk::ExtractLymphStationsFilter<ImageType>::
9 ExtractStationSupports()
10 {
11   // Get initial Mediastinum
12   m_Working_Support = m_Mediastinum = this->GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true);
13
14   // Consider sup/inf to Carina
15   double m_CarinaZ = FindCarina();
16   MaskImagePointer m_Support_Superior_to_Carina = 
17     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
18                                                    m_CarinaZ, true, GetBackgroundValue());
19   MaskImagePointer m_Support_Inferior_to_Carina = 
20     clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2, 
21                                                      m_CarinaZ, true, GetBackgroundValue());
22   m_ListOfSupports["Support_Superior_to_Carina"] = m_Support_Superior_to_Carina;
23   m_ListOfSupports["Support_Inferior_to_Carina"] = m_Support_Inferior_to_Carina;
24   writeImage<MaskImageType>(m_Support_Inferior_to_Carina, "seg/Support_Inf_Carina.mhd");
25   this->GetAFDB()->SetImageFilename("Support_Inf_Carina", "seg/Support_Inf_Carina.mhd");
26   writeImage<MaskImageType>(m_Support_Superior_to_Carina, "seg/Support_Sup_Carina.mhd");
27   this->GetAFDB()->SetImageFilename("Support_Sup_Carina", "seg/Support_Sup_Carina.mhd");
28
29   // S1RL
30   Support_SupInf_S1RL();
31   Support_LeftRight_S1R_S1L();
32
33   // S2RL
34   Support_SupInf_S2R_S2L();
35   Support_LeftRight_S2R_S2L();
36
37   // S4RL
38   Support_SupInf_S4R_S4L();
39   Support_LeftRight_S4R_S4L();
40   
41   // Post limits of S1,S2,S4
42   Support_Post_S1S2S4();
43
44   // S3AP
45   Support_S3P();
46   Support_S3A();
47   
48   // S5, S6
49   Support_S5();
50   Support_S6();
51   
52   // Below Carina S7,8,9,10
53   m_ListOfSupports["S7"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
54   m_ListOfSupports["S8"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
55   m_ListOfSupports["S9"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
56   m_ListOfSupports["S10"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
57   m_ListOfSupports["S11"] = clitk::Clone<MaskImageType>(m_Support_Inferior_to_Carina);
58
59   // Store image filenames into AFDB 
60   writeImage<MaskImageType>(m_ListOfSupports["S1R"], "seg/Support_S1R.mhd");
61   this->GetAFDB()->SetImageFilename("Support_S1R", "seg/Support_S1R.mhd");
62   writeImage<MaskImageType>(m_ListOfSupports["S1L"], "seg/Support_S1L.mhd");
63   this->GetAFDB()->SetImageFilename("Support_S1L", "seg/Support_S1L.mhd");
64
65   writeImage<MaskImageType>(m_ListOfSupports["S2L"], "seg/Support_S2L.mhd");
66   this->GetAFDB()->SetImageFilename("Support_S2L", "seg/Support_S2L.mhd");
67   writeImage<MaskImageType>(m_ListOfSupports["S2R"], "seg/Support_S2R.mhd");
68   this->GetAFDB()->SetImageFilename("Support_S2R", "seg/Support_S2R.mhd");
69
70   writeImage<MaskImageType>(m_ListOfSupports["S3P"], "seg/Support_S3P.mhd");
71   this->GetAFDB()->SetImageFilename("Support_S3P", "seg/Support_S3P.mhd");
72   writeImage<MaskImageType>(m_ListOfSupports["S3A"], "seg/Support_S3A.mhd");
73   this->GetAFDB()->SetImageFilename("Support_S3A", "seg/Support_S3A.mhd");
74
75   writeImage<MaskImageType>(m_ListOfSupports["S4L"], "seg/Support_S4L.mhd");
76   this->GetAFDB()->SetImageFilename("Support_S4L", "seg/Support_S4L.mhd");
77   writeImage<MaskImageType>(m_ListOfSupports["S4R"], "seg/Support_S4R.mhd");
78   this->GetAFDB()->SetImageFilename("Support_S4R", "seg/Support_S4R.mhd");
79
80   writeImage<MaskImageType>(m_ListOfSupports["S5"], "seg/Support_S5.mhd");
81   this->GetAFDB()->SetImageFilename("Support_S5", "seg/Support_S5.mhd");
82   writeImage<MaskImageType>(m_ListOfSupports["S6"], "seg/Support_S6.mhd");
83   this->GetAFDB()->SetImageFilename("Support_S6", "seg/Support_S6.mhd");
84
85   writeImage<MaskImageType>(m_ListOfSupports["S7"], "seg/Support_S7.mhd");
86   this->GetAFDB()->SetImageFilename("Support_S7", "seg/Support_S7.mhd");
87
88   writeImage<MaskImageType>(m_ListOfSupports["S8"], "seg/Support_S8.mhd");
89   this->GetAFDB()->SetImageFilename("Support_S8", "seg/Support_S8.mhd");
90
91   writeImage<MaskImageType>(m_ListOfSupports["S9"], "seg/Support_S9.mhd");
92   this->GetAFDB()->SetImageFilename("Support_S9", "seg/Support_S9.mhd");
93
94   writeImage<MaskImageType>(m_ListOfSupports["S10"], "seg/Support_S10.mhd");
95   this->GetAFDB()->SetImageFilename("Support_S10", "seg/Support_S10.mhd");  
96
97   writeImage<MaskImageType>(m_ListOfSupports["S11"], "seg/Support_S11.mhd");
98   this->GetAFDB()->SetImageFilename("Support_S11", "seg/Support_S11.mhd");  
99   WriteAFDB();
100 }
101 //--------------------------------------------------------------------
102
103
104 //--------------------------------------------------------------------
105 template <class ImageType>
106 void 
107 clitk::ExtractLymphStationsFilter<ImageType>::
108 Support_SupInf_S1RL()
109 {
110   // Step : S1RL
111   StartNewStep("[Support] Sup-Inf S1RL");
112   /*
113     2R: Upper border: apex of the right lung and pleural space, and in
114     the midline, the upper border of the manubrium
115     
116     2L: Upper border: apex of the left lung and pleural space, and in the
117     midline, the upper border of the manubrium
118
119     => apex / manubrium = up Sternum
120   */
121   m_Working_Support = m_ListOfSupports["Support_Superior_to_Carina"];
122   MaskImagePointer Sternum = this->GetAFDB()->template GetImage <MaskImageType>("Sternum");
123   MaskImagePointType p;
124   p[0] = p[1] = p[2] =  0.0; // to avoid warning
125   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
126   MaskImagePointer S1RL = 
127     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
128                                                    p[2], true, GetBackgroundValue());
129   m_Working_Support = 
130     clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2, 
131                                                      p[2], true, GetBackgroundValue());
132   m_ListOfSupports["S1RL"] = S1RL;
133 }
134 //--------------------------------------------------------------------
135
136
137 //--------------------------------------------------------------------
138 template <class ImageType>
139 void 
140 clitk::ExtractLymphStationsFilter<ImageType>::
141 Support_LeftRight_S1R_S1L()
142 {
143   // Step S1RL : Left-Right
144   StartNewStep("[Support] Left-Right S1R S1L");
145   std::vector<ImagePointType> A;
146   std::vector<ImagePointType> B;
147   // Search for centroid positions of trachea
148   MaskImagePointer Trachea = this->GetAFDB()->template GetImage <MaskImageType>("Trachea");
149   MaskImagePointer S1RL = m_ListOfSupports["S1RL"];
150   Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, S1RL, GetBackgroundValue());
151   std::vector<MaskSlicePointer> slices;
152   clitk::ExtractSlices<MaskImageType>(Trachea, 2, slices);
153   for(uint i=0; i<slices.size(); i++) {
154     slices[i] = Labelize<MaskSliceType>(slices[i], 0, false, 10);
155     std::vector<typename MaskSliceType::PointType> c;
156     clitk::ComputeCentroids<MaskSliceType>(slices[i], GetBackgroundValue(), c);
157     ImagePointType a,b;
158     clitk::PointsUtils<MaskImageType>::Convert2DTo3D(c[1], Trachea, i, a);
159     A.push_back(a);
160     b = a; 
161     b[1] += 50;
162     B.push_back(b);
163   }
164   clitk::WriteListOfLandmarks<MaskImageType>(A, "S1LR_A.txt");
165   clitk::WriteListOfLandmarks<MaskImageType>(B, "S1LR_B.txt");
166
167   // Clone support
168   MaskImagePointer S1R = clitk::Clone<MaskImageType>(S1RL);
169   MaskImagePointer S1L = clitk::Clone<MaskImageType>(S1RL);
170
171   // Right part
172   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1R, A, B, 
173                                                                     GetBackgroundValue(), 0, -10);
174   S1R = clitk::AutoCrop<MaskImageType>(S1R, GetBackgroundValue());
175   m_ListOfSupports["S1R"] = S1R;
176
177   // Left part
178   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(S1L, A, B, 
179                                                                     GetBackgroundValue(), 0, 10);
180   S1L = clitk::AutoCrop<MaskImageType>(S1L, GetBackgroundValue());
181   m_ListOfSupports["S1L"] = S1L;
182 }
183 //--------------------------------------------------------------------
184
185
186 //--------------------------------------------------------------------
187 template <class ImageType>
188 void 
189 clitk::ExtractLymphStationsFilter<ImageType>::
190 Support_SupInf_S2R_S2L()
191 {
192   // Step : S2RL Sup-Inf limits
193   /*
194     2R Lower border: intersection of caudal margin of innominate vein with
195     the trachea
196     2L Lower border: superior border of the aortic arch
197   */
198   StartNewStep("[Support] Sup-Inf S2RL");
199   m_Working_Support = m_ListOfSupports["Support_Superior_to_Carina"];
200   
201   // S2R Caudal Margin Of Left BrachiocephalicVein
202   MaskImagePointer BrachioCephalicVein = this->GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicVein");
203   MaskImagePointType p;
204   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicVein, GetBackgroundValue(), 2, true, p);
205
206   // I add slightly more than a slice --> NO !!
207   double CaudalMarginOfLeftBrachiocephalicVeinZ=p[2];//+ 1.1*m_Working_Support->GetSpacing()[2];
208
209   this->GetAFDB()->SetDouble("CaudalMarginOfLeftBrachiocephalicVeinZ", CaudalMarginOfLeftBrachiocephalicVeinZ);
210   MaskImagePointer S2R = 
211     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
212                                                    CaudalMarginOfLeftBrachiocephalicVeinZ, true,
213                                                    GetBackgroundValue());
214   // S2L : Top Of Aortic Arch
215   MaskImagePointer Aorta = this->GetAFDB()->template GetImage<MaskImageType>("Aorta");
216   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Aorta, GetBackgroundValue(), 2, false, p);
217
218   // Save the TopOfAorticArchZ
219   this->GetAFDB()->SetDouble("TopOfAorticArchZ", p[2]);
220
221   // I substract slightly more than a slice to respect delineation
222   double TopOfAorticArchZ=p[2]- 1.1*m_Working_Support->GetSpacing()[2];
223   //  this->GetAFDB()->SetDouble("TopOfAorticArchZ", TopOfAorticArchZ);
224
225   MaskImagePointer S2L = 
226     clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
227                                                    TopOfAorticArchZ, true,
228                                                    GetBackgroundValue());
229
230   /*
231   // S2RL: Superior support, I use inferior part of S1RL
232   MaskImagePointer S1L = m_ListOfSupports["S1L"];
233   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S1L, GetBackgroundValue(), 2, true, p);
234   DD(p);
235   S2L = 
236     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2L, 2, 
237                                                      p[2], true,
238                                                      GetBackgroundValue());
239
240   MaskImagePointer S1R = m_ListOfSupports["S1R"];
241   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S1R, GetBackgroundValue(), 2, true, p);
242   DD(p);
243   S2R = 
244     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2R, 2, 
245                                                      p[2], true,
246                                                      GetBackgroundValue());          
247   */
248
249   // Superior limits, use Sternum (but not strictly inf to S1RL
250   MaskImagePointer Sternum = this->GetAFDB()->template GetImage <MaskImageType>("Sternum");
251   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
252   // Add one slice
253   p[2] = p[2] +  m_Working_Support->GetSpacing()[2];
254   S2L = 
255     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2L, 2, 
256                                                      p[2], true, GetBackgroundValue());
257   S2R = 
258     clitk::CropImageRemoveGreaterThan<MaskImageType>(S2R, 2, 
259                                                      p[2], true, GetBackgroundValue());
260
261   // The is the end
262   m_ListOfSupports["S2L"] = S2L;
263   m_ListOfSupports["S2R"] = S2R;
264 }
265 //--------------------------------------------------------------------
266
267
268
269 //--------------------------------------------------------------------
270 template <class ImageType>
271 void 
272 clitk::ExtractLymphStationsFilter<ImageType>::
273 Support_LeftRight_S2R_S2L()
274 {
275   // ---------------------------------------------------------------------------
276   /* Step : S2RL LeftRight
277      As for lymph node station 4R, 2R includes nodes extending to the
278      left lateral border of the trachea
279      Rod says:  "For station 2 there is a shift, dividing 2R from 2L, from midline
280      to the left paratracheal border."
281   */
282   StartNewStep("[Support] Separate 2R/2L according to Trachea");
283   MaskImagePointer S2R = m_ListOfSupports["S2R"];
284   MaskImagePointer S2L = m_ListOfSupports["S2L"];
285   S2R = LimitsWithTrachea(S2R, 0, 1, -10);
286   S2L = LimitsWithTrachea(S2L, 0, 1, 10);
287   m_ListOfSupports["S2R"] = S2R;
288   m_ListOfSupports["S2L"] = S2L;  
289   this->GetAFDB()->template ReleaseImage<MaskImageType>("Trachea");
290 }
291 //--------------------------------------------------------------------
292
293
294 //--------------------------------------------------------------------
295 template <class ImageType>
296 void 
297 clitk::ExtractLymphStationsFilter<ImageType>::
298 Support_SupInf_S4R_S4L()
299 {
300   // ---------------------------------------------------------------------------
301   /* Step : S4RL Sup-Inf
302      - start at the end of 2R and 2L
303      - stop ?
304      - 4R
305      Rod says : "The inferior border is at the lower border of the azygous vein."
306      Rod says : difficulties
307      (was : "ends at the upper lobe bronchus or where the right pulmonary artery
308      crosses the midline of the mediastinum ")
309      - 4L
310      Rod says : "The lower border is to upper margin of the left main pulmonary artery."
311      (was LLL bronchus)
312   */
313   StartNewStep("[Support] Sup-Inf limits of 4R/4L");
314
315   // Start from the support
316   MaskImagePointer S4RL = clitk::Clone<MaskImageType>(m_Working_Support);
317   MaskImagePointer S4R = clitk::Clone<MaskImageType>(S4RL);
318   MaskImagePointer S4L = clitk::Clone<MaskImageType>(S4RL);
319
320   // Keep only what is lower than S2
321   MaskImagePointer S2R = m_ListOfSupports["S2R"];
322   MaskImagePointer S2L = m_ListOfSupports["S2L"];
323   MaskImagePointType p;
324   // Right part
325   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S2R, GetBackgroundValue(), 
326                                                           2, true, p);
327   S4R = clitk::CropImageRemoveGreaterThan<MaskImageType>(S4R, 2, 
328                                                        p[2], true, GetBackgroundValue());
329   // Left part
330   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(S2L, GetBackgroundValue(), 
331                                                           2, true, p);
332   S4L = clitk::CropImageRemoveGreaterThan<MaskImageType>(S4L, 2, 
333                                                          p[2], true, GetBackgroundValue());
334
335   // Get AzygousVein and limit according to LowerBorderAzygousVein
336   MaskImagePointer LowerBorderAzygousVein 
337     = this->GetAFDB()->template GetImage<MaskImageType>("LowerBorderAzygousVein");
338   std::vector<MaskImagePointType> c;
339   clitk::ComputeCentroids<MaskImageType>(LowerBorderAzygousVein, GetBackgroundValue(), c);
340   S4R = clitk::CropImageRemoveLowerThan<MaskImageType>(S4R, 2, 
341                                                        c[1][2], true, GetBackgroundValue());
342   S4R = clitk::AutoCrop<MaskImageType>(S4R, GetBackgroundValue());
343   m_ListOfSupports["S4R"] = S4R;
344
345
346   // Limit according to LeftPulmonaryArtery
347   MaskImagePointer LeftPulmonaryArtery 
348     = this->GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
349   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(LeftPulmonaryArtery, GetBackgroundValue(), 
350                                                           2, false, p);
351   S4L = clitk::CropImageRemoveLowerThan<MaskImageType>(S4L, 2, 
352                                                        p[2], true, GetBackgroundValue());
353   S4L = clitk::AutoCrop<MaskImageType>(S4L, GetBackgroundValue());
354   m_ListOfSupports["S4L"] = S4L;
355 }
356 //--------------------------------------------------------------------
357
358
359 //--------------------------------------------------------------------
360 template <class ImageType>
361 void 
362 clitk::ExtractLymphStationsFilter<ImageType>::
363 Support_LeftRight_S4R_S4L()
364 {
365   // ---------------------------------------------------------------------------
366   /* Step : S4RL LeftRight 
367      
368      - 4R: includes right paratracheal nodes, and pretracheal nodes
369      extending to the left lateral border of trachea
370      
371      - 4L: includes nodes to the left of the left lateral border of
372      the trachea, medial to the ligamentum arteriosum
373      
374      => same than 2RL
375   */
376   StartNewStep("[Support] Left Right separation of 4R/4L");
377
378   MaskImagePointer S4R = m_ListOfSupports["S4R"];
379   MaskImagePointer S4L = m_ListOfSupports["S4L"];
380   S4R = LimitsWithTrachea(S4R, 0, 1, -10);
381   S4L = LimitsWithTrachea(S4L, 0, 1, 10);
382   m_ListOfSupports["S4R"] = S4R;
383   m_ListOfSupports["S4L"] = S4L;
384 }
385 //--------------------------------------------------------------------
386
387
388 //--------------------------------------------------------------------
389 template <class ImageType>
390 typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
391 clitk::ExtractLymphStationsFilter<ImageType>::
392 LimitsWithTrachea(MaskImageType * input, int extremaDirection, int lineDirection, 
393                   double offset) 
394 {
395   MaskImagePointType min, max;
396   GetMinMaxBoundary<MaskImageType>(input, min, max);
397   return LimitsWithTrachea(input, extremaDirection, lineDirection, offset, max[2]);
398 }
399 template <class ImageType>
400 typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
401 clitk::ExtractLymphStationsFilter<ImageType>::
402 LimitsWithTrachea(MaskImageType * input, int extremaDirection, int lineDirection, 
403                   double offset, double maxSupPosition)
404 {
405   /*
406     Take the input mask, consider the trachea and limit according to
407     Left border of the trachea. Keep at Left or at Right according to
408     the offset
409   */
410   // Read the trachea
411   MaskImagePointer Trachea = this->GetAFDB()->template GetImage<MaskImageType>("Trachea");
412
413   // Find extrema post positions
414   std::vector<MaskImagePointType> tracheaLeftPositionsA;
415   std::vector<MaskImagePointType> tracheaLeftPositionsB;
416
417   // Crop Trachea only on the Sup-Inf axes, without autocrop
418   //  Trachea = clitk::ResizeImageLike<MaskImageType>(Trachea, input, GetBackgroundValue());
419   MaskImagePointType min, max;
420   GetMinMaxBoundary<MaskImageType>(input, min, max);
421   Trachea = clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, min[2], max[2], 
422                                                         false, GetBackgroundValue()); 
423   
424   // Select the main CCL (because of bronchus)
425   Trachea = SliceBySliceKeepMainCCL<MaskImageType>(Trachea, GetBackgroundValue(), GetForegroundValue());
426
427   // Slice by slice, build the separation line 
428   clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(Trachea, 
429                                                                                GetBackgroundValue(), 2, 
430                                                                                extremaDirection, false, // Left
431                                                                                lineDirection, // Vertical line 
432                                                                                -1, // margins 
433                                                                                tracheaLeftPositionsA, 
434                                                                                tracheaLeftPositionsB);
435   // Do not consider trachea above the limit
436   int indexMax=tracheaLeftPositionsA.size();
437   for(uint i=0; i<tracheaLeftPositionsA.size(); i++) {
438     if (tracheaLeftPositionsA[i][2] > maxSupPosition) {
439       indexMax = i;
440       i = tracheaLeftPositionsA.size(); // stop loop
441     }
442   }  
443   tracheaLeftPositionsA.erase(tracheaLeftPositionsA.begin()+indexMax, tracheaLeftPositionsA.end());
444   tracheaLeftPositionsB.erase(tracheaLeftPositionsB.begin()+indexMax, tracheaLeftPositionsB.end());
445
446   // Cut post to this line 
447   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(input, 
448                                                                     tracheaLeftPositionsA,
449                                                                     tracheaLeftPositionsB,
450                                                                     GetBackgroundValue(), 
451                                                                     extremaDirection, offset); 
452   MaskImagePointer output = clitk::AutoCrop<MaskImageType>(input, GetBackgroundValue());
453   return output;
454 }
455 //--------------------------------------------------------------------
456
457
458 //--------------------------------------------------------------------
459 template <class ImageType>
460 void
461 clitk::ExtractLymphStationsFilter<ImageType>::
462 Support_Post_S1S2S4()
463 {
464   StartNewStep("[Support] Post limits of S1RL, S2RL, S4RL");
465   
466   double m_ApexOfTheChest = FindApexOfTheChest();
467   
468   // Post limits with Trachea 
469   MaskImagePointer S1R = m_ListOfSupports["S1R"];
470   MaskImagePointer S1L = m_ListOfSupports["S1L"];
471   MaskImagePointer S2R = m_ListOfSupports["S2R"];
472   MaskImagePointer S2L = m_ListOfSupports["S2L"];
473   MaskImagePointer S4R = m_ListOfSupports["S4R"];
474   MaskImagePointer S4L = m_ListOfSupports["S4L"];
475   S1L = LimitsWithTrachea(S1L, 1, 0, -10, m_ApexOfTheChest);
476   S1R = LimitsWithTrachea(S1R, 1, 0, -10, m_ApexOfTheChest);
477   S2R = LimitsWithTrachea(S2R, 1, 0, -10, m_ApexOfTheChest);
478   S2L = LimitsWithTrachea(S2L, 1, 0, -10, m_ApexOfTheChest);
479   S4R = LimitsWithTrachea(S4R, 1, 0, -10, m_ApexOfTheChest);
480   S4L = LimitsWithTrachea(S4L, 1, 0, -10, m_ApexOfTheChest);
481 }
482 //--------------------------------------------------------------------
483
484
485 //--------------------------------------------------------------------
486 template <class ImageType>
487 void
488 clitk::ExtractLymphStationsFilter<ImageType>::
489 Support_S3P()
490 {
491   StartNewStep("[Support] Ant limits of S3P and Post limits of S1RL, S2RL, S4RL");
492   
493   // Initial S3P support
494   MaskImagePointer S3P = clitk::Clone<MaskImageType>(m_ListOfSupports["Support_Superior_to_Carina"]);
495
496   // Stop at Lung Apex
497   double m_ApexOfTheChest = FindApexOfTheChest();
498   S3P = 
499     clitk::CropImageRemoveGreaterThan<MaskImageType>(S3P, 2, 
500                                                      m_ApexOfTheChest, true,
501                                                      GetBackgroundValue());
502   // Ant limits with Trachea
503   S3P = LimitsWithTrachea(S3P, 1, 0, 10);
504   m_ListOfSupports["S3P"] = S3P;
505 }
506 //--------------------------------------------------------------------
507
508
509 //--------------------------------------------------------------------
510 template <class ImageType>
511 void
512 clitk::ExtractLymphStationsFilter<ImageType>::
513 Support_S3A()
514 {
515   StartNewStep("[Support] Sup-Inf and Post limits for S3A");
516
517   // Initial S3A support
518   MaskImagePointer S3A = clitk::Clone<MaskImageType>(m_ListOfSupports["Support_Superior_to_Carina"]);
519
520   // Stop at Lung Apex or like S2/S1 (upper border Sternum - manubrium) ?
521
522   //double m_ApexOfTheChest = FindApexOfTheChest();
523
524   MaskImagePointer Sternum = this->GetAFDB()->template GetImage <MaskImageType>("Sternum");
525   MaskImagePointType p;
526   p[0] = p[1] = p[2] =  0.0; // to avoid warning
527   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Sternum, GetBackgroundValue(), 2, false, p);
528   p[2] += Sternum->GetSpacing()[2]; // we add one slice to stop 3A at the same slice than Sternum stop
529   S3A = 
530     clitk::CropImageRemoveGreaterThan<MaskImageType>(S3A, 2, 
531                                                      //m_ApexOfTheChest
532                                                      p[2], true,
533                                                      GetBackgroundValue());
534   // Ant limits with Trachea
535   S3A = LimitsWithTrachea(S3A, 1, 0, -10);
536   m_ListOfSupports["S3A"] = S3A;  
537 }
538 //--------------------------------------------------------------------
539
540
541 //--------------------------------------------------------------------
542 template <class ImageType>
543 void
544 clitk::ExtractLymphStationsFilter<ImageType>::
545 Support_S5()
546 {
547   StartNewStep("[Support] Sup-Inf limits S5 with aorta");
548
549   // Initial S5 support
550   MaskImagePointer S5 = 
551     clitk::Clone<MaskImageType>(this->GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true));
552
553   // Sup limits with Aorta
554   double sup = FindInferiorBorderOfAorticArch();
555   
556   // Inf limits with "upper rim of the left main pulmonary artery"
557   // For the moment only, it will change.
558   MaskImagePointer PulmonaryTrunk = this->GetAFDB()->template GetImage<MaskImageType>("PulmonaryTrunk");
559   MaskImagePointType p;
560   p[0] = p[1] = p[2] =  0.0; // to avoid warning
561   clitk::FindExtremaPointInAGivenDirection<MaskImageType>(PulmonaryTrunk, GetBackgroundValue(), 2, false, p);
562   p[2] += PulmonaryTrunk->GetSpacing()[2];
563   
564   // Cut Sup/Inf
565   S5 = clitk::CropImageAlongOneAxis<MaskImageType>(S5, 2, p[2], sup, true, GetBackgroundValue());
566
567   m_ListOfSupports["S5"] = S5; 
568 }
569 //--------------------------------------------------------------------
570
571 //--------------------------------------------------------------------
572 template <class ImageType>
573 void
574 clitk::ExtractLymphStationsFilter<ImageType>::
575 Support_S6()
576 {
577   StartNewStep("[Support] Sup-Inf limits S6 with aorta");
578
579   // Initial S6 support like S3A
580   MaskImagePointer S6 = clitk::Clone<MaskImageType>(m_ListOfSupports["S3A"]);
581
582   // Inf Sup limits with Aorta
583   double sup = FindSuperiorBorderOfAorticArch();
584   double inf = FindInferiorBorderOfAorticArch();
585   
586   // Cut Sup/Inf
587   S6 = clitk::CropImageAlongOneAxis<MaskImageType>(S6, 2, inf, sup, true, GetBackgroundValue());
588
589   m_ListOfSupports["S6"] = S6;  
590 }
591 //--------------------------------------------------------------------
592