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