CASToR  1.0
Tomographic Reconstruction (PET/SPECT)
oImageConvolverManager.cc
Go to the documentation of this file.
00001 
00002 /*
00003   Implementation of class oImageConvolverManager
00004 
00005   - separators: done
00006   - doxygen: done
00007   - default initialization: done
00008   - CASTOR_DEBUG: 
00009   - CASTOR_VERBOSE: 
00010 */
00011 
00018 #include "oImageConvolverManager.hh"
00019 #include "sAddonManager.hh"
00020 
00021 // =====================================================================
00022 // ---------------------------------------------------------------------
00023 // ---------------------------------------------------------------------
00024 // =====================================================================
00025 
00026 oImageConvolverManager::oImageConvolverManager()
00027 {
00028   // Image dimensions
00029   mp_ImageDimensionsAndQuantification = NULL;
00030   // Options
00031   m_options = {};
00032   // Image convolver objects and associated bool
00033   m_nbImageConvolvers = 0;
00034   m2p_ImageConvolvers = NULL;
00035   mp_applyForward = NULL;
00036   mp_applyBackward = NULL;
00037   mp_applyIntra = NULL;
00038   mp_applyPost = NULL;
00039   // Booleans
00040   m_checked = false;
00041   m_initialized = false;
00042   // Verbosity
00043   m_verbose = -1;
00044 }
00045 
00046 // =====================================================================
00047 // ---------------------------------------------------------------------
00048 // ---------------------------------------------------------------------
00049 // =====================================================================
00050 
00051 oImageConvolverManager::~oImageConvolverManager() 
00052 {
00053   // Delete object
00054   if (m2p_ImageConvolvers)
00055   {
00056     for (int c=0; c<m_nbImageConvolvers; c++) if (m2p_ImageConvolvers[c]) delete m2p_ImageConvolvers[c];
00057     free(m2p_ImageConvolvers);
00058   }
00059 }
00060 
00061 // =====================================================================
00062 // ---------------------------------------------------------------------
00063 // ---------------------------------------------------------------------
00064 // =====================================================================
00065 
00066 int oImageConvolverManager::CheckParameters()
00067 {
00068   // Check image dimensions
00069   if (mp_ImageDimensionsAndQuantification==NULL)
00070   {
00071     Cerr("***** oImageConvolverManager::CheckParameters() -> No image dimensions provided !" << endl);
00072     return 1;
00073   }
00074   // Check verbosity
00075   if (m_verbose<0)
00076   {
00077     Cerr("***** oImageConvolverManager::CheckParameters() -> Wrong verbosity level provided !" << endl);
00078     return 1;
00079   }
00080   // All set
00081   m_checked = true;
00082   // Normal end
00083   return 0;
00084 }
00085 
00086 // =====================================================================
00087 // ---------------------------------------------------------------------
00088 // ---------------------------------------------------------------------
00089 // =====================================================================
00090 
00091 void oImageConvolverManager::ShowCommonHelp()
00092 {
00093   // Return when using MPI and mpi_rank is not 0
00094   #ifdef CASTOR_MPI
00095   int mpi_rank = 0;
00096   MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
00097   if (mpi_rank!=0) return;
00098   #endif
00099   // Show help
00100   cout << "------------------------------------------------------------------" << endl;
00101   cout << "-----  How to use an image convolver" << endl;
00102   cout << "------------------------------------------------------------------" << endl;
00103   cout << endl;
00104   cout << "An image convolver is called through the -conv option. The provided argument describes the convolver to be used, its options," << endl;
00105   cout << "and when to include it within the algorithm. The syntax of the argument must obey one of the three following options:" << endl;
00106   cout << "  conv::when (in this case, the default configuration file of the convolver is used to set the options values)" << endl;
00107   cout << "  conv:file.conf::when (in this case, the provided configuration is used)" << endl;
00108   cout << "  conv,param1,param2,...::when (in this case, the options values are directly provided in the argument)" << endl;
00109   cout << "In any case, the description of the options specific to each convolver, their order in the list and their configuration" << endl;
00110   cout << "files syntax are provided in the specific help of each convolver." << endl;
00111   cout << "The 'when' parameter is an argument describing when to include the convolver within the algorithm. It is a list of keywords" << endl;
00112   cout << "separating by commas. The following keywords can be used:" << endl;
00113   cout << "  forward  (include convolver into forward model; a convolution of the current estimate is forward-projected)" << endl;
00114   cout << "  backward (include convolver into backward model; a convolution of the correction terms is used for the update)" << endl;
00115   cout << "  post     (apply convolver before saving the image; the convolved image is not put back as the estimate for the next update)" << endl;
00116   cout << "  psf      (include both 'forward' and 'backward'; the standard image-based PSF modelling)" << endl;
00117   cout << "  sieve    (include both 'psf' and 'post'; the standard method of sieve)" << endl;
00118   cout << "  intra    (apply convolver to the updated image and use it as the current estimate for the next update)" << endl;
00119   cout << endl;
00120 }
00121 
00122 // =====================================================================
00123 // ---------------------------------------------------------------------
00124 // ---------------------------------------------------------------------
00125 // =====================================================================
00126 
00127 int oImageConvolverManager::Initialize()
00128 {
00129   // Check if parameters have been checked
00130   if (!m_checked)
00131   {
00132     Cerr("***** oImageConvolverManager::Initialize() -> Parameters have not been checked ! Please call CheckParameters() before." << endl);
00133     return 1;
00134   }
00135   // Case with no options (no convolver)
00136   if (m_options.size()==0)
00137   {
00138     m_initialized = true;
00139     return 0;
00140   }
00141   // Verbose
00142   if (m_verbose>=1) Cout("oImageConvolverManager::Initialize() -> Initialize image convolvers" << endl);
00143   // Parse image convolver options and initialize them
00144   if (ParseOptionsAndInitializeImageConvolvers())
00145   {
00146     Cerr("***** oImageConvolverManager::Initialize() -> A problem occured while parsing image convolvers options and initializing them !" << endl);
00147     return 1;
00148   }
00149   // All set
00150   m_initialized = true;
00151   // Normal end
00152   return 0;
00153 }
00154 
00155 // =====================================================================
00156 // ---------------------------------------------------------------------
00157 // ---------------------------------------------------------------------
00158 // =====================================================================
00159 
00160 int oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers()
00161 {
00162   // ==============================================================
00163   // First get the number of convolvers from the list of options
00164   // ==============================================================
00165 
00166   m_nbImageConvolvers = m_options.size();
00167 
00168   // Allocate the tables
00169   m2p_ImageConvolvers = (vImageConvolver**)malloc(m_nbImageConvolvers*sizeof(vImageConvolver*));
00170   mp_applyForward = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
00171   mp_applyBackward = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
00172   mp_applyIntra = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
00173   mp_applyPost = (bool*)malloc(m_nbImageConvolvers*sizeof(bool));
00174 
00175   // ==============================================================
00176   // Then we loop over all convolvers, read options and initialize
00177   // ==============================================================
00178 
00179   // This is for the automatic initialization of the convolvers
00180   typedef vImageConvolver *(*maker_image_convolver) ();
00181   // Get image convolver's list from addon manager
00182   std::map <string,maker_image_convolver> list = sAddonManager::GetInstance()->mp_listOfImageConvolvers;
00183 
00184   // Start the loop
00185   for (int c=0; c<m_nbImageConvolvers; c++)
00186   {
00187     // Default initializations
00188     m2p_ImageConvolvers[c] = NULL;
00189     mp_applyForward[c] = false;
00190     mp_applyBackward[c] = false;
00191     mp_applyIntra[c] = false;
00192     mp_applyPost[c] = false;
00193 
00194     // ___________________________________________________________________________________
00195     // Search for a double-colon and isolate the convolver's options from the 'when' actions
00196 
00197     size_t double_colon = m_options[c].find_first_of("::");
00198 
00199     // Send an error if no double-colon
00200     if (double_colon==string::npos)
00201     {
00202       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Wrong syntax in the " << c+1 << "th image convolver !" << endl);
00203       Cerr("                                                                            No double-colon \"::\" found." << endl);
00204       ShowCommonHelp();
00205       return 1;
00206     }
00207 
00208     // Separate the two arguments
00209     string conv_part_options = m_options[c].substr(0,double_colon);
00210     string when_part_options = m_options[c].substr(double_colon+2);
00211 
00212     // ___________________________________________________________________________________
00213     // Get the image convolver name in the options and isolate the actual image convolver's options
00214 
00215     // Useful strings
00216     string convolver = "";
00217     string list_options = "";
00218     string file_options = "";
00219 
00220     // Search for a colon ":", this indicates that a configuration file is provided after the image convolver name
00221     size_t colon = conv_part_options.find_first_of(":");
00222     size_t comma = conv_part_options.find_first_of(",");
00223 
00224     // Case 1: we have a colon
00225     if (colon!=string::npos)
00226     {
00227       // Get the image convolver name before the colon
00228       convolver = conv_part_options.substr(0,colon);
00229       // Get the configuration file after the colon
00230       file_options = conv_part_options.substr(colon+1);
00231       // List of options is empty
00232       list_options = "";
00233     }
00234     // Case 2: we have a comma
00235     else if (comma!=string::npos)
00236     {
00237       // Get the image convolver name before the first comma
00238       convolver = conv_part_options.substr(0,comma);
00239       // Get the list of options after the first comma
00240       list_options = conv_part_options.substr(comma+1);
00241       // Configuration file is empty
00242       file_options = "";
00243     }
00244     // Case 3: no colon and no comma (a single image convolver name)
00245     else
00246     {
00247       // Get the image convolver name
00248       convolver = conv_part_options;
00249       // List of options is empty
00250       list_options = "";
00251       // Build the default configuration file
00252       file_options = sOutputManager::GetInstance()->GetPathToConfigDir() + "/convolver/" + convolver + ".conf";
00253     }
00254 
00255     // ___________________________________________________________________________________
00256     // Read the 'when' actions
00257 
00258     // Loop while commas are found
00259     while ((comma=when_part_options.find_first_of(",")) != string::npos)
00260     {
00261       // Extract the first option
00262       string option = when_part_options.substr(0,comma);
00263       // Extract the rest
00264       when_part_options = when_part_options.substr(comma+1);
00265       // Check the meaning of the option
00266       if (option=="forward") {mp_applyForward[c] = true;}
00267       else if (option=="backward") {mp_applyBackward[c] = true;}
00268       else if (option=="post") {mp_applyPost[c] = true;}
00269       else if (option=="psf") {mp_applyForward[c] = true; mp_applyBackward[c] = true;}
00270       else if (option=="sieve") {mp_applyForward[c] = true; mp_applyBackward[c] = true; mp_applyPost[c] = true;}
00271       else if (option=="intra") {mp_applyIntra[c] = true;}
00272       else
00273       {
00274         Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Unknown keyword '" << option << "' provided in options list !" << endl);
00275         ShowCommonHelp();
00276         return 1;
00277       }
00278     }
00279     // Last option
00280     if (when_part_options=="forward") {mp_applyForward[c] = true;}
00281     else if (when_part_options=="backward") {mp_applyBackward[c] = true;}
00282     else if (when_part_options=="post") {mp_applyPost[c] = true;}
00283     else if (when_part_options=="psf") {mp_applyForward[c] = true; mp_applyBackward[c] = true;}
00284     else if (when_part_options=="sieve") {mp_applyForward[c] = true; mp_applyBackward[c] = true; mp_applyPost[c] = true;}
00285     else if (when_part_options=="intra") {mp_applyIntra[c] = true;}
00286     else
00287     {
00288       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Unknown keyword '" << when_part_options << "' provided in options list !" << endl);
00289       ShowCommonHelp();
00290       return 1;
00291     }
00292 
00293     // ______________________________________________________________________________
00294     // Create convolver and call associated functions
00295 
00296     // Create the image convolver
00297     if (list[convolver]) m2p_ImageConvolvers[c] = list[convolver]();
00298     else
00299     {
00300       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> Image convolver '" << convolver << "' does not exist !" << endl);
00301       sAddonManager::GetInstance()->ShowHelpImageConvolver();
00302       return 1;
00303     }
00304     // Set parameters
00305     m2p_ImageConvolvers[c]->SetImageDimensionsAndQuantification(mp_ImageDimensionsAndQuantification);
00306     m2p_ImageConvolvers[c]->SetVerbose(m_verbose);
00307     // Provide configuration file if any
00308     if (file_options!="" && m2p_ImageConvolvers[c]->ReadConfigurationFile(file_options))
00309     {
00310       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while reading and checking configuration file for image convolver '" << convolver << "' !" << endl);
00311       return 1;
00312     }
00313     // Provide options if any
00314     if (list_options!="" && m2p_ImageConvolvers[c]->ReadOptionsList(list_options))
00315     {
00316       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while parsing and reading options list for image convolver '" << convolver << "' !" << endl);
00317       return 1;
00318     }
00319     // Check parameters
00320     if (m2p_ImageConvolvers[c]->CheckParameters())
00321     {
00322       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while checking parameters for image convolver '" << convolver << "' !" << endl);
00323       return 1;
00324     }
00325     // Initialize the image convolver
00326     if (m2p_ImageConvolvers[c]->Initialize())
00327     {
00328       Cerr("***** oImageConvolverManager::ParseOptionsAndInitializeImageConvolvers() -> A problem occured while initializing image convolver '" << convolver << "' !" << endl);
00329       return 1;
00330     }
00331   }
00332 
00333   // Normal end
00334   return 0;
00335 }
00336 
00337 // =====================================================================
00338 // ---------------------------------------------------------------------
00339 // ---------------------------------------------------------------------
00340 // =====================================================================
00341 
00342 int oImageConvolverManager::ConvolveForward(oImageSpace* ap_ImageSpace)
00343 {
00344   #ifdef CASTOR_DEBUG
00345   // Check if initialized
00346   if (!m_initialized)
00347   {
00348     Cerr("***** oImageConvolverManager::ConvolveForward() -> Called while not initialized !" << endl);
00349     return 1;
00350   }
00351   #endif
00352   // Loop on convolvers
00353   for (int c=0; c<m_nbImageConvolvers; c++)
00354   {
00355     // Apply it only if asked for
00356     if (mp_applyForward[c])
00357     {
00358       // Verbose
00359       if (m_verbose>=2)
00360       {
00361         if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolveForward() -> Apply convolution " << c+1 << " to forward image" << endl);
00362         else Cout("oImageConvolverManager::ConvolveForward() -> Apply convolution to forward image" << endl);
00363       }
00364       // Loop on basis functions
00365       for (int tb=0; tb<mp_ImageDimensionsAndQuantification->GetNbTimeBasisFunctions(); tb++)
00366       {
00367         for (int rb=0; rb<mp_ImageDimensionsAndQuantification->GetNbRespBasisFunctions(); rb++)
00368         {
00369           for (int cb=0; cb<mp_ImageDimensionsAndQuantification->GetNbCardBasisFunctions(); cb++)
00370           {
00371             // Get the pointer to the image
00372             FLTNB* image = ap_ImageSpace->m4p_forwardImage[tb][rb][cb];
00373             // Apply convolution
00374             m2p_ImageConvolvers[c]->ApplyConvolution(image);
00375           }
00376         }
00377       }
00378     }
00379   }
00380   // Normal end
00381   return 0;
00382 }
00383 
00384 // =====================================================================
00385 // ---------------------------------------------------------------------
00386 // ---------------------------------------------------------------------
00387 // =====================================================================
00388 
00389 int oImageConvolverManager::ConvolveBackward(oImageSpace* ap_ImageSpace)
00390 {
00391   #ifdef CASTOR_DEBUG
00392   // Check if initialized
00393   if (!m_initialized)
00394   {
00395     Cerr("***** oImageConvolverManager::ConvolveBackward() -> Called while not initialized !" << endl);
00396     return 1;
00397   }
00398   #endif
00399   // Loop on convolvers
00400   for (int c=0; c<m_nbImageConvolvers; c++)
00401   {
00402     // Apply it only if asked for
00403     if (mp_applyBackward[c])
00404     {
00405       // Verbose
00406       if (m_verbose>=2)
00407       {
00408         if (m_nbImageConvolvers>1)
00409         {
00410           if (ap_ImageSpace->IsLoadedSensitivity()) Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution " << c+1 << " to backward image" << endl);
00411           else Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution " << c+1 << " to backward and sensitivity images" << endl);
00412         }
00413         else
00414         {
00415           if (ap_ImageSpace->IsLoadedSensitivity()) Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution to backward image" << endl);
00416           else Cout("oImageConvolverManager::ConvolveBackward() -> Apply convolution to backward and sensitivity images" << endl);
00417         }
00418       }
00419       // Deal with backward images, loop on number of images
00420       for (int img=0; img<ap_ImageSpace->GetNbBackwardImages(); img++)
00421       {
00422         // Loop on basis functions
00423         for (int tb=0; tb<mp_ImageDimensionsAndQuantification->GetNbTimeBasisFunctions(); tb++)
00424         {
00425           for (int rb=0; rb<mp_ImageDimensionsAndQuantification->GetNbRespBasisFunctions(); rb++)
00426           {
00427             for (int cb=0; cb<mp_ImageDimensionsAndQuantification->GetNbCardBasisFunctions(); cb++)
00428             {
00429               // Get the pointer to the image
00430               int thread_0 = 0;
00431               FLTNB* image = ap_ImageSpace->m6p_backwardImage[img][thread_0][tb][rb][cb];
00432               // Apply convolution
00433               m2p_ImageConvolvers[c]->ApplyConvolutionTranspose(image);
00434             }
00435           }
00436         }
00437       }
00438       // Deal with sensitivity images for histogram reconstructions
00439       if (!ap_ImageSpace->IsLoadedSensitivity())
00440       {
00441         // Loop on frames and gates
00442         for (int fr=0; fr<mp_ImageDimensionsAndQuantification->GetNbTimeFrames(); fr++)
00443         {
00444           for (int rg=0; rg<mp_ImageDimensionsAndQuantification->GetSensNbRespGates(); rg++)
00445           {
00446             for (int cg=0; cg<mp_ImageDimensionsAndQuantification->GetSensNbCardGates(); cg++)
00447             {
00448               // Get the pointer to the image
00449               int thread_0 = 0;
00450               FLTNB* image = ap_ImageSpace->m5p_sensitivity[thread_0][fr][rg][cg];
00451               // Apply convolution
00452               m2p_ImageConvolvers[c]->ApplyConvolutionTranspose(image);
00453             }
00454           }
00455         }
00456       }
00457     }
00458   }
00459   // Normal end
00460   return 0;
00461 }
00462 
00463 // =====================================================================
00464 // ---------------------------------------------------------------------
00465 // ---------------------------------------------------------------------
00466 // =====================================================================
00467 
00468 int oImageConvolverManager::ConvolveIntra(oImageSpace* ap_ImageSpace)
00469 {
00470   #ifdef CASTOR_DEBUG
00471   // Check if initialized
00472   if (!m_initialized)
00473   {
00474     Cerr("***** oImageConvolverManager::ConvolveIntra() -> Called while not initialized !" << endl);
00475     return 1;
00476   }
00477   #endif
00478   // Loop on convolvers
00479   for (int c=0; c<m_nbImageConvolvers; c++)
00480   {
00481     // Apply it only if asked for
00482     if (mp_applyIntra[c])
00483     {
00484       // Verbose
00485       if (m_verbose>=2)
00486       {
00487         if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolveIntra() -> Apply convolution " << c+1 << " to current image" << endl);
00488         else Cout("oImageConvolverManager::ConvolveIntra() -> Apply convolution to current image" << endl);
00489       }
00490       // Loop on basis functions
00491       for (int tb=0; tb<mp_ImageDimensionsAndQuantification->GetNbTimeBasisFunctions(); tb++)
00492       {
00493         for (int rb=0; rb<mp_ImageDimensionsAndQuantification->GetNbRespBasisFunctions(); rb++)
00494         {
00495           for (int cb=0; cb<mp_ImageDimensionsAndQuantification->GetNbCardBasisFunctions(); cb++)
00496           {
00497             // Get the pointer to the image
00498             FLTNB* image = ap_ImageSpace->m4p_image[tb][rb][cb];
00499             // Apply convolution
00500             m2p_ImageConvolvers[c]->ApplyConvolution(image);
00501           }
00502         }
00503       }
00504     }
00505   }
00506   // Normal end
00507   return 0;
00508 }
00509 
00510 // =====================================================================
00511 // ---------------------------------------------------------------------
00512 // ---------------------------------------------------------------------
00513 // =====================================================================
00514 
00515 int oImageConvolverManager::ConvolveSensitivity(oImageSpace* ap_ImageSpace)
00516 {
00517   #ifdef CASTOR_DEBUG
00518   // Check if initialized
00519   if (!m_initialized)
00520   {
00521     Cerr("***** oImageConvolverManager::ConvolveSensitivity() -> Called while not initialized !" << endl);
00522     return 1;
00523   }
00524   #endif
00525   // Loop on convolvers
00526   for (int c=0; c<m_nbImageConvolvers; c++)
00527   {
00528     // Apply it only if asked for
00529     if (mp_applyBackward[c])
00530     {
00531       // Verbose
00532       if (m_verbose>=2)
00533       {
00534         if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolveSensitivity() -> Apply convolution " << c+1 << " to sensitivity image" << endl);
00535         else Cout("oImageConvolverManager::ConvolveSensitivity() -> Apply convolution to sensitivity image" << endl);
00536       }
00537       // Loop on frames and gates
00538       for (int fr=0; fr<mp_ImageDimensionsAndQuantification->GetNbTimeFrames(); fr++)
00539       {
00540         for (int rg=0; rg<mp_ImageDimensionsAndQuantification->GetSensNbRespGates(); rg++)
00541         {
00542           for (int cg=0; cg<mp_ImageDimensionsAndQuantification->GetSensNbCardGates(); cg++)
00543           {
00544             // Get the pointer to the image
00545             int thread_0 = 0;
00546             FLTNB* image = ap_ImageSpace->m5p_sensitivity[thread_0][fr][rg][cg];
00547             // Apply convolution
00548             m2p_ImageConvolvers[c]->ApplyConvolutionTranspose(image);
00549           }
00550         }
00551       }
00552     }
00553   }
00554   // Normal end
00555   return 0;
00556 }
00557 
00558 // =====================================================================
00559 // ---------------------------------------------------------------------
00560 // ---------------------------------------------------------------------
00561 // =====================================================================
00562 
00563 int oImageConvolverManager::ConvolvePost(oImageSpace* ap_ImageSpace)
00564 {
00565   #ifdef CASTOR_DEBUG
00566   // Check if initialized
00567   if (!m_initialized)
00568   {
00569     Cerr("***** oImageConvolverManager::ConvolvePost() -> Called while not initialized !" << endl);
00570     return 1;
00571   }
00572   #endif
00573   // Loop on convolvers
00574   for (int c=0; c<m_nbImageConvolvers; c++)
00575   {
00576     // Apply it only if asked for
00577     if (mp_applyPost[c])
00578     {
00579       // Verbose
00580       if (m_verbose>=2)
00581       {
00582         if (m_nbImageConvolvers>1) Cout("oImageConvolverManager::ConvolvePost() -> Apply convolution " << c+1 << " to output image" << endl);
00583         else Cout("oImageConvolverManager::ConvolvePost() -> Apply convolution to output image" << endl);
00584       }
00585           
00586       // Loop on frames and respiratory/cardiac gates
00587       for (int fr=0; fr<mp_ImageDimensionsAndQuantification->GetNbTimeFrames(); fr++)
00588       {
00589         for (int rg=0; rg<mp_ImageDimensionsAndQuantification->GetNbRespGates(); rg++)
00590         {
00591           for (int cg=0; cg<mp_ImageDimensionsAndQuantification->GetNbCardGates(); cg++)
00592           {
00593             // Get the pointer to the output image
00594             FLTNB* image = ap_ImageSpace->m4p_outputImage[fr][rg][cg];
00595             // Apply convolution
00596             m2p_ImageConvolvers[c]->ApplyConvolution(image);
00597           }
00598         }
00599       }
00600     }
00601   }
00602   // Normal end
00603   return 0;
00604 }
00605 
00606 // =====================================================================
00607 // ---------------------------------------------------------------------
00608 // ---------------------------------------------------------------------
00609 // =====================================================================
 All Classes Files Functions Variables Typedefs Defines