CASToR  1.0
Tomographic Reconstruction (PET/SPECT)
iPatlakModel.cc
Go to the documentation of this file.
00001 
00002 /*
00003   Implementation of class iPatlakModel
00004 
00005   - separators: X
00006   - doxygen: X
00007   - default initialization: none  (require user inputs (Patlak basis functions), no sense to provide 'standard' configuration file as for optimizer/projector)
00008   - CASTOR_DEBUG: X
00009   - CASTOR_VERBOSE: X
00010 */
00011 
00019 #include "iPatlakModel.hh"
00020 
00021 
00022 // =====================================================================
00023 // ---------------------------------------------------------------------
00024 // ---------------------------------------------------------------------
00025 // =====================================================================
00026 /*
00027   \fn iPatlakModel
00028   \brief Constructor of iPatlakModel. Simply set all data members to default values.
00029 */
00030 iPatlakModel::iPatlakModel() : vDynamicModel() 
00031 {
00032   m_nbTimeBF = 2; // Two basis functions in the Patlak model
00033   m2p_parametricImages = NULL;
00034   m2p_patlakTACs = NULL;
00035   
00036   m_fileOptions = "";
00037   m_listOptions = "";
00038     
00039   m_savePImgFlag = true;
00040 }
00041 
00042 
00043 
00044 
00045 // =====================================================================
00046 // ---------------------------------------------------------------------
00047 // ---------------------------------------------------------------------
00048 // =====================================================================
00049 /*
00050   \fn ~iPatlakModel
00051   \brief Destructor of iPatlakModel
00052 */
00053 iPatlakModel::~iPatlakModel() 
00054 {
00055   if(m_initialized)
00056   {
00057     for(int b=0 ; b<m_nbTimeBF ; b++)
00058     {
00059       if (m2p_patlakTACs[b]) delete m2p_patlakTACs[b];
00060       if (m2p_parametricImages[b]) delete m2p_parametricImages[b];
00061     }
00062   
00063     if (m2p_patlakTACs) delete[] m2p_patlakTACs;
00064     if (m2p_parametricImages) delete[] m2p_parametricImages;
00065   }
00066 }
00067 
00068 
00069 
00070 
00071 // =====================================================================
00072 // ---------------------------------------------------------------------
00073 // ---------------------------------------------------------------------
00074 // =====================================================================
00075 /*
00076   \fn ShowHelp
00077   \brief Print out specific help about the implementation of the Patlak
00078          model and its initialization
00079 */
00080 void iPatlakModel::ShowHelp()
00081 {
00082   cout << "-- This class implements the Patlak Reference Tissue Model : " << endl;
00083   cout << "-- Patlak CS, Blasberg RG: Graphical evaluation of blood-to-brain transfer constants from multiple-time uptake data" << endl;
00084   cout << "-- J Cereb Blood Flow Metab 1985, 5(4):5 84-590." << endl;
00085   cout << "-- DOI http://dx.doi.org/10.1038/jcbfm.1985.87" << endl;
00086   cout << "-- It is used to model radiotracers which follows as 2-tissue compartment model with irreversible trapping  " << endl;
00087   cout << "-- The Patlak temporal basis functions are composed of the Patlak slope (integral of the reference TAC from the injection time " << endl;
00088   cout << "   divided by the instantaneous reference activity), and intercept (reference tissue TAC)  " << endl;
00089   cout << endl;
00090   cout << " It can be initialized using either an ASCII file or a list of option with the following keywords and information :" << endl; 
00091   cout << " - The ASCII file must contain the following keywords :" << endl;
00092   cout << "   'Patlak_functions:'      (mandatory) Enter the coefficients of Patlak plot and intercept for each time frame (tf) ";
00093   cout << "                                        on two successive lines, separated by ',' :" << endl;
00094   cout << "                            -> Patlak_functions: " << endl;
00095   cout << "                            -> coeff_Pplot_tf1,coeff_Pplot_tf2,...,coeff_Pplot_tfn" << endl;
00096   cout << "                            -> coeff_Pintc_tf1,coeff_Pintc_tf2,...,coeff_Pintc_tfn" << endl;
00097   cout << "   'Parametric_image_init:' (optional) path to an interfile image to be used as initialization for the parametric images" << endl;
00098   cout << "   'Patlak_save_images:'    (optional) boolean indicating if the parametric images should be saved (1) or not (0)" << endl;
00099   cout << endl;
00100   cout << " - The list of options must contain the coefficients of both Patlak functions separated by commas, with the following template :" << endl;
00101   cout << "   coeff_Pplot_tf1,coeff_Pplot_tf2,...,coeff_Pplot_tfn,";
00102   cout << "   coeff_Pintc_tf1,coeff_Pintc_tf2,...,coeff_Pintc_tfn "<< endl;
00103   cout << "   Parametric images will be initialized with 1.0 by default " << endl;
00104   cout << "   The parametric images estimations will be written on disk for each iteration" << endl;
00105   cout << "    " << endl;
00106 }
00107 
00108 
00109 
00110 
00111 // =====================================================================
00112 // ---------------------------------------------------------------------
00113 // ---------------------------------------------------------------------
00114 // =====================================================================
00115 /*
00116   \fn ReadAndCheckConfigurationFile
00117   \param const string& a_configurationFile : ASCII file containing informations about a dynamic model
00118   \brief This function is used to read options from a configuration file.
00119   \return 0 if success, other value otherwise.
00120 */
00121 int iPatlakModel::ReadAndCheckConfigurationFile(string a_fileOptions)
00122 {
00123   if(m_verbose >=2) Cout("iPatlakModel::ReadAndCheckConfigurationFile ..."<< endl); 
00124   
00125   // Recover the file path here, it will be processed in the Initialize() function
00126   m_fileOptions = a_fileOptions;
00127   
00128   ifstream in_file(a_fileOptions.c_str(), ios::in);
00129   
00130   if(in_file)
00131   {
00132     if( ReadDataASCIIFile(a_fileOptions, "Patlak_save_images", &m_savePImgFlag, 1, KEYWORD_OPTIONAL) == 1)
00133     {
00134       Cerr("***** iPatlakModel::ReadAndCheckConfigurationFile -> Error while trying to read 'Patlak_save_images' flag in " << a_fileOptions << endl);
00135       return 1;
00136     }
00137   }
00138   else
00139   {
00140     Cerr("***** iPatlakModel::ReadAndCheckConfigurationFile -> Error while trying to read configuration file at: " << a_fileOptions << endl);
00141     return 1;
00142   }
00143     
00144   return 0;
00145 }
00146 
00147 
00148 
00149 
00150 // =====================================================================
00151 // ---------------------------------------------------------------------
00152 // ---------------------------------------------------------------------
00153 // =====================================================================
00154 /*
00155   \fn ReadAndCheckOptionsList
00156   \param const string& a_optionsList : a list of parameters separated by commas
00157   \brief This function is used to read parameters from a string.
00158   \return 0 if success, other value otherwise.
00159 */
00160 int iPatlakModel::ReadAndCheckOptionsList(string a_listOptions)
00161 {
00162   if(m_verbose >=2) Cout("iPatlakModel::ReadAndCheckOptionsList ..."<< endl); 
00163   
00164   // Just recover the string here, it will be processed in the Initialize() function
00165   m_listOptions = a_listOptions;
00166   
00167   // Normal end
00168   return 0;
00169 }
00170 
00171 
00172 
00173 
00174 // =====================================================================
00175 // ---------------------------------------------------------------------
00176 // ---------------------------------------------------------------------
00177 // =====================================================================
00178 /*
00179   \fn CheckSpecificParameters
00180   \brief This function is used to check whether all member variables
00181          have been correctly initialized or not.
00182   \return 0 if success, positive value otherwise.
00183 */
00184 int iPatlakModel::CheckSpecificParameters()
00185 {
00186   if(m_verbose >=2) Cout("iPatlakModel::CheckSpecificParameters ..."<< endl); 
00187   
00188   // Check image dimensions
00189   if (mp_ID==NULL)
00190   {
00191     Cerr("***** iPatlakModel::CheckParameters() -> ImageDimensions object has not been provided !" << endl);
00192     return 1;
00193   }
00194   
00195   // Check number time basis functions
00196   if (m_nbTimeBF<0)
00197   {
00198     Cerr("***** iPatlakModel::CheckParameters() -> Wrong number of time frame basis functions !" << endl);
00199     return 1;
00200   }
00201   
00202   // Check if we have somehow both a file and a list of options for init...
00203   if(m_listOptions != "" && m_fileOptions != "")
00204   {
00205     Cerr("***** iPatlakModel::Initialize -> Either a file or a list of options have to be selected to initialize the model, but not both ! " << endl);
00206     return 1;
00207   }
00208   
00209   // Check if we have no file not list of options for some reason...
00210   if(m_listOptions == "" && m_fileOptions == "")
00211   {
00212     Cerr("***** iPatlakModel::Initialize -> Either a file or a list of options should have been provided at this point ! " << endl);
00213     return 1;
00214   }
00215   
00216   // Check if we reconstruct gated data. Throw warning if it is the case
00217   if(mp_ID->GetNbRespGates()>1 || mp_ID->GetNbCardGates()>1)
00218   {
00219     Cerr("***** iPatlakModel::Initialize -> WARNING : the implemented Patlak model should not be used with gated reconstruction (parametric images will be the same for each gate)! " << endl);
00220     //return 1;
00221   }
00222   
00223   
00224   // Normal end
00225   return 0;
00226 }
00227 
00228 
00229 
00230 
00231 // =====================================================================
00232 // ---------------------------------------------------------------------
00233 // ---------------------------------------------------------------------
00234 // =====================================================================
00235 /*
00236   \fn Initialize
00237   \brief This function is used to initialize Patlak parametric images and basis functions
00238   \return 0 if success, other value otherwise.
00239 */
00240 int iPatlakModel::Initialize()
00241 {
00242   if(m_verbose >=2) Cout("iPatlakModel::Initialize ..."<< endl); 
00243 
00244   // Forbid initialization without check
00245   if (!m_checked)
00246   {
00247     Cerr("***** oDynamicModelManager::Initialize() -> Must call CheckParameters functions before Initialize() !" << endl);
00248     return 1;
00249   }
00250   
00251   // --- Memory Allocation --- //
00252   
00253   // Allocate memory for Parametric images and functions of Patlak model
00254   m2p_patlakTACs = new FLTNB*[m_nbTimeBF];
00255   m2p_parametricImages = new FLTNB*[m_nbTimeBF];
00256 
00257   for(int b=0 ; b<m_nbTimeBF ; b++)
00258   {
00259     m2p_patlakTACs[b] = new FLTNB[mp_ID->GetNbTimeFrames()];
00260     m2p_parametricImages[b] = new FLTNB[mp_ID->GetNbVoxXYZ()];
00261   }
00262 
00263 
00264   // --- Data Initialization with a configuration file --- //
00265 
00266   if(m_fileOptions != "")
00267   {
00268     ifstream in_file(m_fileOptions.c_str(), ios::in);
00269     
00270     if(in_file)
00271     {
00272       // Patlak basis functions Initialization
00273       if( ReadDataASCIIFile(m_fileOptions,
00274                             "Patlak_functions",
00275                             m2p_patlakTACs,
00276                             mp_ID->GetNbTimeFrames(),
00277                             m_nbTimeBF,
00278                             KEYWORD_MANDATORY) )
00279       {
00280         Cerr("***** iPatlakModel::Initialize -> Error while trying to read Patlak functions coefficients !" << endl);
00281         Cerr("                                  'Patlak_functions' keyword in " << m_fileOptions << endl);
00282         return 1;
00283       }
00284       
00285       // Patlak Parametric images initialization
00286       string input_image = "";
00287       int return_value = 0;
00288       
00289       return_value = ReadDataASCIIFile(m_fileOptions,
00290                                         "Parametric_images_init",
00291                                         &input_image,
00292                                         1,
00293                                         KEYWORD_OPTIONAL);
00294       
00295       if( return_value == 0) // Image have been provided
00296       {
00297         // Read image // INTF_LERP_DISABLED = interpolation disabled for input image reading
00298         if( IntfReadImgDynCoeffFile(input_image,
00299                                     m2p_parametricImages,
00300                                     mp_ID,
00301                                     m_nbTimeBF,
00302                                     m_verbose,
00303                                     INTF_LERP_DISABLED) ) // Image have been provided
00304         {
00305           Cerr("***** iPatlakModel::Initialize -> Error while trying to read the provided initialization parametric images : " << input_image << endl);
00306           return 1;
00307         }
00308         
00309         //normal end
00310         return 0;
00311       }
00312       else if( return_value == 1) // Error during reading
00313       {
00314         Cerr("***** iPatlakModel::Initialize -> Error while trying to read Patlak functions coefficients !" << endl);
00315         Cerr("                                  'Parametric_image_init' keyword in " << m_fileOptions << endl);
00316         return 1;
00317       }
00318       else //(return_value >= 1 ) // Keyword not found : no initialization provided
00319       {
00320         // Standard initialization
00321         for(int b=0 ; b<m_nbTimeBF ; b++)
00322           for(int v=0 ; v<mp_ID->GetNbVoxXYZ() ; v++)
00323             m2p_parametricImages[b][v] = 1.;
00324       }
00325       
00326     }
00327     
00328     else
00329     {
00330       Cerr("***** iPatlakModel::Initialize() -> Error while trying to read configuration file at: " << m_fileOptions << endl);
00331       return 1;
00332     }
00333   }
00334   
00335   
00336   // --- Data Initialization with a list of options --- //
00337 
00338   if(m_listOptions != "")
00339   {
00340     // We expect here the coefficients of the Patlak functions for each time point
00341     // Patlak slope before Patlak intercept
00342   
00343     // Allocate memory to recover the elements in one tmp vector
00344     FLTNB *p_coeffs = new FLTNB[m_nbTimeBF * mp_ID->GetNbTimeFrames()];
00345     
00346     // Read them
00347     if (ReadStringOption(m_listOptions,
00348                          p_coeffs,
00349                          m_nbTimeBF * mp_ID->GetNbTimeFrames(),
00350                          ",",
00351                          "Patlak model configuration"))
00352     {
00353       Cerr("***** iPatlakModel::Initialize() -> Failed to correctly read the list of options !" << endl);
00354       return 1;
00355     }
00356     
00357     // Affect coeffs
00358     for(int c=0 ; c<m_nbTimeBF * mp_ID->GetNbTimeFrames() ; c++)
00359     {
00360       int bf = int(c/mp_ID->GetNbTimeFrames()); // Patlak basis function index
00361       int fr = int(c%mp_ID->GetNbTimeFrames()); // Frame index
00362       m2p_patlakTACs[bf][fr] = p_coeffs[c];
00363     }
00364     
00365     // Delete the tmp vector
00366     delete[] p_coeffs;
00367     
00368     
00369     // Standard initialization for the parametric images
00370     for(int b=0 ; b<m_nbTimeBF ; b++)
00371       for(int v=0 ; v<mp_ID->GetNbVoxXYZ() ; v++)
00372         m2p_parametricImages[b][v] = 1.;
00373   }
00374 
00375   // Display Patlak TACs
00376   if(m_verbose >=2)
00377   {
00378     Cout("iPatlakModel::Initialize() -> Patlak Normalized Time TAC coefficients :" << endl);
00379     Cout("                              ");
00380     for(int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00381       Cout(m2p_patlakTACs[0][fr] << ", ");
00382     Cout(endl);
00383     Cout("iPatlakModel::Initialize() -> Patlak Reference Time TAC coefficients :" << endl);
00384     Cout("                              ");
00385     for(int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00386       Cout(m2p_patlakTACs[1][fr] << ", ");
00387     Cout(endl);
00388   }
00389   
00390   // Normal end
00391   m_initialized = true;
00392   return 0;
00393 }
00394 
00395 
00396 
00397 
00398 // =====================================================================
00399 // ---------------------------------------------------------------------
00400 // ---------------------------------------------------------------------
00401 // =====================================================================
00402 /*
00403   \fn EstimateModelParameters
00404   \param ap_ImageS : pointer to the ImageSpace
00405   \param a_ite : index of the actual iteration (not used)
00406   \param a_sset : index of the actual subset (not used)
00407   \brief Estimate Patlak parametric images
00408   \return 0 if success, other value otherwise.
00409 */
00410 int iPatlakModel::EstimateModelParameters(oImageSpace* ap_ImageS, int a_ite, int a_sset) 
00411 {
00412   if(m_verbose >=2) Cout("iPatlakModel::EstimateModelParameters ..." <<endl);
00413 
00414   #ifdef CASTOR_DEBUG
00415   if (!m_initialized)
00416   {
00417     Cerr("***** iPatlakModel::EstimateModelParameters() -> Called while not initialized !" << endl);
00418     Exit(EXIT_DEBUG);
00419   }
00420   #endif
00421   
00422   // Generate estimated image from coefficients and basis functions
00423   // (We use the backward image which is useless at this point, as temporary image
00424   // to estimate the image generated using the current estimation of the Patlak parametric images)
00425   for (int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00426     for (int rg=0 ; rg<mp_ID->GetNbRespGates() ; rg++) 
00427       for (int cg=0 ; cg<mp_ID->GetNbCardGates() ; cg++)
00428         for (int v=0 ; v<mp_ID->GetNbVoxXYZ() ; v++)
00429         {
00430           // Reset this voxel to 0
00431           ap_ImageS->m6p_backwardImage[0][0][fr][rg][cg][v] = 0;
00432 
00433           // Retrieve current estimation of image according to the current value of Patlak parametric images and basis functions
00434           // C(fr,v) = Patlak Parametric(v) * normalized time(fr) +
00435           //           Patlak Intercept(v)  * Reference tissue TAC(fr)
00436           for (int b=0 ; b<m_nbTimeBF ; b++)
00437             ap_ImageS->m6p_backwardImage[0][0][fr][rg][cg][v] += m2p_patlakTACs[b][fr] * m2p_parametricImages[b][v];
00438         }
00439 
00440   // Get correction images using the ratio of the current estimation of the image (m4p_image)
00441   // and the image generated with the combination of Patlak functions and parametric images (stored in ap_Image->m6p_backwardImage)
00442   // (Again, use backward image as temporary image to get the result)
00443   for (int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00444     for (int rg=0 ; rg<mp_ID->GetNbRespGates() ; rg++) 
00445       for (int cg=0 ; cg<mp_ID->GetNbCardGates() ; cg++)
00446         for (int v=0 ; v<mp_ID->GetNbVoxXYZ() ; v++)
00447           ap_ImageS->m6p_backwardImage[0][0][fr][rg][cg][v] = ap_ImageS->m4p_image[fr][rg][cg][v] / ap_ImageS->m6p_backwardImage[0][0][fr][rg][cg][v];
00448 
00449 
00450   // Loop on the 2 Patlak parametric images
00451   for (int b=0 ; b<m_nbTimeBF ; b++)
00452   {
00453     double temporal_basis_functions_norm = 0;
00454     
00455     // Compute normalization related to the temporal basis functions.
00456     for (int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00457       temporal_basis_functions_norm += m2p_patlakTACs[b][fr];
00458     
00459     // Compute voxelwise corrections for the parametric images
00460     int v;
00461     #pragma omp parallel for private(v) schedule(guided)
00462     for (v=0 ; v<mp_ID->GetNbVoxXYZ() ; v++)
00463     {
00464       double corr_factor = 0.;
00465       
00466       // Note : We don't consider here parametric images specific to respiratory (rg) or cardiac gates (cg)
00467       //        The model is applied to every voxels in the image
00468       for (int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00469         for (int rg=0 ; rg<mp_ID->GetNbRespGates() ; rg++) 
00470           for (int cg=0 ; cg<mp_ID->GetNbCardGates() ; cg++)
00471             corr_factor += ap_ImageS->m6p_backwardImage[0][0][fr][rg][cg][v] * m2p_patlakTACs[b][fr];
00472 
00473       // Apply corrections and normalization to the vowelwise time basis functions coefficients.
00474       if (corr_factor > 0.) 
00475         m2p_parametricImages[b][v] *= corr_factor/temporal_basis_functions_norm; 
00476     }
00477   }
00478   
00479   return 0;
00480 }
00481   
00482   
00483   
00484 // =====================================================================
00485 // ---------------------------------------------------------------------
00486 // ---------------------------------------------------------------------
00487 // =====================================================================
00488 /*
00489   \fn FitModel
00490   \param ap_ImageS : pointer to the ImageSpace
00491   \param a_ite : index of the actual iteration (not used)
00492   \param a_sset : index of the actual subset (not used)
00493   \brief Estimate image using Patlak parametric images and basis functions
00494   \return 0 if success, other value otherwise.
00495 */
00496 int iPatlakModel::FitModel(oImageSpace* ap_ImageS, int a_ite, int a_sset) 
00497 {
00498   if(m_verbose >= 2) Cout("iPatlakModel::FitModel ... " <<endl);
00499 
00500   #ifdef CASTOR_DEBUG
00501   if (!m_initialized)
00502   {
00503     Cerr("***** iPatlakModel::FitModel() -> Called while not initialized !" << endl);
00504     Exit(EXIT_DEBUG);
00505   }
00506   #endif
00507   
00508   for (int fr=0 ; fr<mp_ID->GetNbTimeFrames() ; fr++)
00509     for (int rg=0 ; rg<mp_ID->GetNbRespGates() ; rg++) 
00510       for (int cg=0 ; cg<mp_ID->GetNbCardGates() ; cg++)
00511         for (int v=0 ; v<mp_ID->GetNbVoxXYZ() ; v++)
00512         {
00513           // Reset current estimated value
00514           ap_ImageS->m4p_image[fr][rg][cg][v] = 0;
00515           
00516           // C(fr,v) = Patlak Parametric(v) * normalized time(fr) +
00517           //           Patlak Intercept(v)  * Reference tissue TAC(fr) 
00518           for (int b=0 ; b<m_nbTimeBF ; b++)
00519             ap_ImageS->m4p_image[fr][rg][cg][v] += m2p_parametricImages[b][v] * m2p_patlakTACs[b][fr];
00520         }
00521         
00522   return 0;
00523 }
00524 
00525 
00526 
00527 
00528 
00529 // =====================================================================
00530 // ---------------------------------------------------------------------
00531 // ---------------------------------------------------------------------
00532 // =====================================================================
00533 /*
00534   \fn SaveParametricImages
00535   \param ap_ImageS : pointer to the ImageSpace
00536   \param a_ite : index of the actual iteration
00537   \brief Write parametric images on disk if 'm_savePImgFlag' is enabled
00538   \todo Interfile management
00539   \return 0 if success, other value otherwise.
00540 */
00541 int iPatlakModel::SaveParametricImages(int a_ite)
00542 {
00543   if(m_verbose >=2) Cout("iPatlakModel::SaveParametricImages ..." <<endl);
00544   
00545   if(m_savePImgFlag)
00546   {
00547     // Get the output manager
00548     sOutputManager* p_output_manager = sOutputManager::GetInstance();  
00549     /*
00550     for(int bimg=0 ; bimg<m_nbTimeBF ; bimg++)
00551     {
00552       string data_file = p_output_manager->GetPathName() + p_output_manager->GetBaseName();
00553       if (a_ite >= 0) // Add a suffix for iteration
00554       {
00555         stringstream ss;
00556         ss << a_ite;
00557         data_file.append("_ite_").append(ss.str());
00558       }
00559     
00560       // Add a suffix for (basis functions) coefficients images
00561       stringstream ss;
00562       ss << bimg;
00563       data_file.append("_fbimg_").append(ss.str()).append(".bin");
00564       
00565       ofstream out_dfile;
00566     
00567       out_dfile.open(data_file.c_str(), ios::binary | ios::out);
00568           
00569       if(!out_dfile.is_open()) 
00570       {
00571         cout<<"***** iPatlakModel::SaveCoeffImages()->Failed to create output file for the dynamic image : "<< data_file.c_str() << endl;
00572         return 1;
00573       }
00574             
00575       out_dfile.write(reinterpret_cast<char*>(m2p_parametricImages[bimg]), mp_ID->GetNbVoxXYZ()*sizeof(FLTNB));
00576       out_dfile.close();
00577     }
00578     */
00579     
00580     // Interfile
00581     string path_to_image = p_output_manager->GetPathName() + p_output_manager->GetBaseName();
00582     
00583     // Add a suffix for iteration
00584     if (a_ite >= 0)
00585     {
00586       stringstream ss; ss << a_ite + 1;
00587       path_to_image.append("patlak_it").append(ss.str());
00588     }
00589     
00590     // Write interfile parametric image
00591     if(IntfWriteImgDynCoeffFile(path_to_image, 
00592                                 m2p_parametricImages, 
00593                                 mp_ID, 
00594                                 m_nbTimeBF, 
00595                                 m_verbose) )
00596     {
00597       Cerr("***** iPatlakModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);  
00598       return 1;
00599     }
00600     
00601   }
00602   
00603   return 0;
00604 }
00605 
00606 
 All Classes Files Functions Variables Typedefs Defines