119 cout <<
" The following keywords are common to all dynamic models :" << endl;
120 cout <<
" 'Number_of_iterations_before_image_update: x' Set a number 'x' of iteration to reach before using the model to generate the images at each frames/gates" << endl;
121 cout <<
" (Default x == 0) " << endl;
122 cout <<
" 'No_image_update: x' If set to 1, the reconstructed images for the next iteration/subset are not reestimated using the model" << endl;
123 cout <<
" (Default x == 0) (the code just performs standard independent reconstruction of each frames/gates) " << endl;
124 cout <<
" 'No_parameters_update: x' If set to 1, the parameters / functions of the model are not estimated with the image" << endl;
125 cout <<
" (Default x == 0) (this could be used to test The EstimateImageWithModel() function with specific user-provided parametric images) " << endl;
126 cout <<
" 'Save_parametric_images : x' Enable (1)/Disable(0) saving parametric images on disk" << endl;
127 cout <<
" (Default x == 1) " << endl;
128 cout <<
" 'Save_blacklisted_voxels_images : x' Enable (1)/Disable(0) saving blacklisted voxels images on disk" << endl;
129 cout <<
" (Default x == 0) " << endl;
130 cout <<
" 'Mask:' Path to an interfile image containing a mask indicating if the model must be applied (1) or not (0) in each voxel" << endl;
131 cout <<
" (Default: model applies everywhere) " << endl;
151 if(
m_verbose>=2)
Cout(
"vDynamicModel::CheckParameters ..."<< endl);
156 Cerr(
"***** vDynamicModel::CheckParameters() -> No image dimensions provided !" << endl);
163 Cerr(
"***** vDynamicModel::CheckParameters() -> Wrong verbosity level provided !" << endl);
170 Cerr(
"***** vDynamicModel::CheckParameters() -> Basis functions number has not been initialized !" << endl);
177 Cerr(
"***** vDynamicModel::CheckParameters() -> Number of model parameter has not been initialized !" << endl);
184 Cerr(
"***** vDynamicModel::CheckParameters() -> Number of model parameter has not been initialized !" << endl);
191 Cerr(
"***** vDynamicModel::CheckParameters() -> An error occurred while checking parameters of the child dynamic class !" << endl);
217 if(
m_verbose >=2)
Cout(
"vDynamicModel::Initialize ..."<< endl);
222 Cerr(
"***** vDynamicModel::Initialize() -> Must call CheckParameters functions before Initialize() !" << endl);
229 if(
m_verbose >=2)
Cout(
"vDynamicModel::Initialize Arterial Input Curve"<< endl);
239 Cerr(
"***** vDynamicModel::Initialize() -> Error while initializing Arterial Input Curve " << endl);
245 Cerr(
"***** vDynamicModel::Initialize() -> Error while checking Arterial Input Curve parameters " << endl);
248 if(
m_verbose >=3)
Cout(
"vDynamicModel::Interpolating Arterial Input Curve ..."<< endl);
263 Cerr(
"***** vDynamicModel::Initialize() -> Wrong initial values in mask (must be either 0 or 1) !" << endl);
276 Cerr(
"***** vDynamicModel::Initialize() -> A problem occurred while initializing stuff specific to the dynamic model !" << endl);
295 if(
m_verbose >=2)
Cout(
"vDynamicModel::ComputeOutputParImage ..." <<endl);
307 if(
m_verbose >=3)
Cout(
" Setting parametric image #: " << p+1 << endl );
337 Cout(
"vDynamicModel::ApplyOutputFOVMaskingOnParametricImages() -> Mask output image" << endl);
353 squared_radius_x *= squared_radius_x;
356 squared_radius_y *= squared_radius_y;
364 #pragma omp parallel for private(x) schedule(guided) 369 squared_distance_x *= squared_distance_x;
375 squared_distance_y *= squared_distance_y;
377 if ( squared_distance_x/squared_radius_x + squared_distance_y/squared_radius_y <= 1. )
continue;
401 for (
int z=0; z<removed_slices; z++)
408 INTNB index = base_z_first + i;
416 INTNB index = base_z_last + i;
444 if(
m_verbose >= 2)
Cout(
"vDynamicModel::EstimateModel ... " <<endl);
449 Cerr(
"***** vDynamicModel::EstimateModel() -> Called while not initialized !" << endl);
457 Cerr(
"***** vDynamicModel::EstimateModel() -> A problem occurred while estimating dynamic image series with model parameters !" << endl);
482 if(
m_verbose >= 2)
Cout(
"vDynamicModel::EstimateImage ... " <<endl);
487 Cerr(
"***** vDynamicModel::EstimateImage() -> Called while not initialized !" << endl);
495 Cerr(
"***** vDynamicModel::EstimateImage() -> A problem occurred while applying dynamic model to current estimate images !" << endl);
520 if(
m_verbose >=3)
Cout(
"vDynamicModel::ReadAndCheckConfigurationFile ..."<< endl);
522 ifstream in_file(a_fileOptions.c_str(), ios::in);
527 string dtag =
"No_image_update";
535 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
541 dtag =
"No_parameters_update";
549 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
555 dtag =
"Number_of_iterations_before_image_update";
563 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
569 dtag =
"Save_parametric_images";
577 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
583 dtag =
"Save_blacklisted_voxels_images";
591 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
596 string path_to_mask =
"";
601 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " <<
m_fileOptions << endl);
605 if(!path_to_mask.empty())
615 Cerr(
"***** ivDynamicModel::ReadAndCheckConfigurationFile()-> Error reading Interfile : " << path_to_mask <<
" !" << endl);
620 Cout(
"vDynamicModel::ReadAndCheckConfigurationFile() -> The following mask will be used for the 2nd model parameters estimation: " << path_to_mask << endl);
632 dtag =
"AIC_input_file";
640 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '" << dtag<<
"' flag in " << a_fileOptions << endl);
654 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error occurred when trying to process the configuration file from a dynamic model child class " << endl);
660 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile -> Error while trying to read configuration file at: " << a_fileOptions << endl);
684 if(
m_verbose >=3)
Cout(
"vDynamicModel::SaveParametricImages ..." <<endl);
699 if (a_iteration >= 0)
701 stringstream ss; ss << a_iteration + 1;
702 path_to_image.append(
"_it").append(ss.str());
708 stringstream ss; ss << a_subset + 1;
709 path_to_image.append(
"_ss").append(ss.str());
718 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);
722 if(
m_verbose >=3)
Cout(
"vDynamicModel::SaveBlackListedVoxelsMask ..." <<endl);
727 if (a_iteration >= 0)
730 ss << a_iteration + 1;
731 path_to_image.append(
"_it").append(ss.str());
737 path_to_image.append(
"_ss").append(ss.str());
744 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing image of blacklisted voxels !" 760 if (a_iteration >= 0)
762 stringstream ss; ss << a_iteration + 1;
763 path_to_image.append(
"parRGmodel_it").append(ss.str());
769 stringstream ss; ss << a_subset + 1;
770 path_to_image.append(
"_ss").append(ss.str());
779 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);
791 if (a_iteration >= 0)
793 stringstream ss; ss << a_iteration + 1;
794 path_to_image.append(
"parCGmodel_it").append(ss.str());
800 stringstream ss; ss << a_subset + 1;
801 path_to_image.append(
"_ss").append(ss.str());
810 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);
874 int pfeas, iz, jz, iz1, iz2, npp1, *index;
875 FLTNB d1, d2, sm, up, ss, *w, *zz;
876 int iter, k, j=0, l, itmax, izmax=0, nsetp, ii, jj=0, ip;
877 FLTNB temp, wmax, t, alpha, asave, dummy, unorm, ztest, cc;
880 if(m<=0 || n<=0 || A==NULL || B==NULL || X==NULL)
882 Cerr(
"***** vDynamicModel::NNLS()-> Incorrect input parameters !" << endl);
887 if(wp!=NULL) w=wp;
else w=(
FLTNB*)calloc(n,
sizeof(
FLTNB));
888 if(zzp!=NULL) zz=zzp;
else zz=(
FLTNB*)calloc(m,
sizeof(
FLTNB));
889 if(indexp!=NULL) index=indexp;
else index=(
int*)calloc(n,
sizeof(
int));
891 if(w==NULL || zz==NULL || index==NULL)
893 Cerr(
"***** vDynamicModel::NNLS()-> Incorrect memory allocation on working space !" << endl);
904 iz2=n-1; iz1=0; nsetp=0; npp1=0;
915 while(iz1<=iz2 && nsetp<m)
918 for(iz=iz1; iz<=iz2; iz++)
921 for(l=npp1; l<m; l++)
930 for(wmax=0., iz=iz1; iz<=iz2; iz++)
944 iz=izmax; j=index[iz];
949 asave=A[j][npp1]; up=0.0;
951 NNLS_LSS_H12(1, npp1, npp1+1, m, &A[j][0], 1, &up, &dummy, 1, 1, 0);
955 for(l=0; l<nsetp; l++)
961 d2 = unorm + (d1=A[j][npp1], fabs(d1)) * 0.01;
969 NNLS_LSS_H12(2, npp1, npp1+1, m, &A[j][0], 1, &up, zz, 1, 1, 1);
971 ztest = zz[npp1]/A[j][npp1];
990 index[iz]=index[iz1]; index[iz1]=j; iz1++; nsetp=npp1+1; npp1++;
992 if(iz1<=iz2)
for(jz=iz1; jz<=iz2; jz++)
995 NNLS_LSS_H12(2, nsetp-1, npp1, m, &A[j][0], 1, &up, &A[jj][0], 1, m, 1);
998 if(nsetp!=m)
for(l=npp1; l<m; l++) A[j][l]=0.;
1002 for(l=0; l<nsetp; l++)
1006 for(ii=0; ii<=ip; ii++)
1007 zz[ii] -= A[jj][ii] * zz[ip+1];
1009 zz[ip] /= A[jj][ip];
1013 while( ++iter<itmax )
1016 for(alpha=2.0, ip=0; ip<nsetp; ip++)
1021 t = -X[l] / (zz[ip]-X[l]);
1032 if(alpha==2.0)
break;
1035 for(ip=0; ip<nsetp; ip++)
1038 X[l] += alpha*(zz[ip]-X[l]);
1043 k=index[jj+1]; pfeas=1;
1050 for(j=jj+1; j<nsetp; j++)
1052 ii=index[j]; index[j-1]=ii;
1054 NNLS_LSS_G1(A[ii][j-1], A[ii][j], &cc, &ss, &A[ii][j-1]);
1056 for(A[ii][j]=0., l=0; l<n; l++)
if(l!=ii)
1060 A[l][j-1] = cc*temp+ss*A[l][j];
1061 A[l][j] = -ss*temp+cc*A[l][j];
1064 temp=B[j-1]; B[j-1]=cc*temp+ss*B[j]; B[j]=-ss*temp+cc*B[j];
1067 npp1=nsetp-1; nsetp--; iz1--; index[iz1]=k;
1073 for(jj=0, pfeas=1; jj<nsetp; jj++)
1088 for(l=0; l<nsetp; l++)
1092 for(ii=0; ii<=ip; ii++)
1093 zz[ii] -= A[jj][ii]*zz[ip+1];
1095 zz[ip] /= A[jj][ip];
1104 for(ip=0; ip<nsetp; ip++)
1119 for(k=npp1; k<m; k++)
1132 if(wp==NULL) free(w);
1133 if(zzp==NULL) free(zz);
1134 if(indexp==NULL) free(index);
1193 FLTNB d1, b, clinv, cl, sm;
1197 if(mode!=1 && mode!=2)
return(1);
1198 if(m<1 || u==NULL || u_dim1<1 || cm==NULL)
return(1);
1199 if(lpivot<0 || lpivot>=l1 || l1>m)
return(1);
1202 cl = fabs(u[lpivot*u_dim1]);
1206 if(cl<=0.)
return(0);
1210 for(j=l1; j<m; j++) {
1211 cl = fmax(fabs(u[j*u_dim1]), cl);
1214 if(cl<=0.)
return(0);
1219 d1=u[lpivot*u_dim1]*clinv;
1221 for(j=l1; j<m; j++) {
1222 d1=u[j*u_dim1]*clinv;
1227 if(u[lpivot*u_dim1] > 0.) cl=-cl;
1228 *up = u[lpivot*u_dim1] - cl;
1229 u[lpivot*u_dim1]=cl;
1233 b=(*up)*u[lpivot*u_dim1];
1236 if(b>=0.0)
return(0);
1239 for(j=0; j<ncv; j++) {
1241 sm = cm[ lpivot*ice + j*icv ] * (*up);
1242 for(k=l1; k<m; k++) sm += cm[ k * ice + j*icv ] * u[ k*u_dim1 ];
1246 cm[ lpivot * ice + j*icv] += sm*(*up);
1248 for(k=l1; k<m; k++) cm[ k*ice + j*icv] += u[k * u_dim1]*sm;
1285 xr=b/a; d1=xr; yr=sqrt(d1*d1 + 1.); d1=1./yr;
1286 *cterm=(a>=0.0 ? fabs(d1) : -fabs(d1));
1287 *sterm=(*cterm)*xr; *sig=fabs(a)*yr;
1291 xr=a/b; d1=xr; yr=sqrt(d1*d1 + 1.); d1=1./yr;
1292 *sterm=(b>=0.0 ? fabs(d1) : -fabs(d1));
1293 *cterm=(*sterm)*xr; *sig=fabs(b)*yr;
1297 *sig=0.; *cterm=0.; *sterm=1.;
virtual int CheckSpecificParameters()=0
This function is used to check the parameters of the child functions before initialization if require...
#define INTF_LERP_DISABLED
void NNLS_LSS_G1(FLTNB a, FLTNB b, FLTNB *cterm, FLTNB *sterm, FLTNB *sig)
This function is used by the NNLS function() Construction and/or application of a single Householder ...
int NNLS(FLTNB **A, int m, int n, FLTNB *B, FLTNB *X, FLTNB *rnorm, FLTNB *wp, FLTNB *zzp, int *indexp)
Implementation of NNLS (non-negative least squares) algorithm Derived from Turku PET center libraries...
virtual int CheckParameters()
This function is used to check parameters after the latter have been all set using Set functions...
int IntfWriteImgDynCoeffFile(const string &a_pathToImg, FLTNB **a2p_ImgMatrix, oImageDimensionsAndQuantification *ap_ID, int a_nbParImgs, int vb, bool a_mergeDynImgFlag=false)
virtual int InitializeSpecific()=0
A private function used to initialize everything specific to the child model.
FLTNB GetVoxSizeX()
Get the voxel's size along the X axis, in mm.
FLTNB GetFOVOutPercent()
Get the percentage of transaxial unmasked FOV.
oArterialInputCurve * mp_ArterialInputCurve
void ShowHelp()
This function is used to print out general help about dynamic models.
int ReadAndCheckConfigurationFile(string a_fileOptions)
This function is used to read options from a configuration file. It looks for the parameters implem...
int NNLS_LSS_H12(int mode, int lpivot, int l1, int m, FLTNB *u, int u_dim1, FLTNB *up, FLTNB *cm, int ice, int icv, int ncv)
oImageDimensionsAndQuantification * mp_ID
bool m_saveBlacklistedImageMaskFlag
virtual int ApplyOutputFOVMaskingOnParametricImages()
Mask the outside of the transaxial FOV based on the m_fovOutPercent.
FLTNB ** m2p_RGParametricImages
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
virtual int EstimateImage(oImageSpace *ap_Image, int a_ite, int a_sset)
FLTNB GetVoxSizeY()
Get the voxel's size along the Y axis, in mm.
const string & GetPathName()
virtual int EstimateModel(oImageSpace *ap_Image, int a_ite, int a_sset)
This function checks if the EstimateModelParameters() function (specific to each model) must be calle...
uint32_t * GetFramesTimeStopArray(int a_bed)
Singleton class that manages output writing on disk (images, sinograms, etc). It also manages loggi...
FLTNB ** m2p_outputParImages
FLTNB ** m2p_CGParametricImages
int ReadDataASCIIFile(const string &a_file, const string &a_keyword, T *ap_return, int a_nbElts, bool a_mandatoryFlag)
Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter a...
bool m_ModelSpecificBasisFunctionsRequired
INTNB GetNbVoxXY()
Get the number of voxels in a slice.
virtual int ReadAndCheckConfigurationFileSpecific()=0
This function is used to read options from a configuration file. It is pure virtual so must be impl...
int Initialize()
A public function used to initialize the dynamic model.
FLTNB ** m2p_nestedModelTimeBasisFunctions
bool m_noParametersUpdateFlag
virtual ~vDynamicModel()
Destructor of vDynamicModel.
vDynamicModel()
Constructor of vDynamicModel. Simply set all data members to default values.
const string & GetBaseName()
uint32_t * GetFramesTimeStartsArray(int a_bed)
Get the array of frame start times for a bed in Ms at uint32_t.
FLTNB ** m2p_parametricImages
This class holds all the matrices in the image domain that can be used in the algorithm: image...
int GetNbTimeFrames()
Get the number of time frames.
INTNB GetNbVoxXYZ()
Get the total number of voxels.
virtual int EstimateImageWithModel(oImageSpace *ap_Image, int a_ite, int a_sset)=0
This function checks if the EstimateImageWithModel() function (specific to each model) must be called...
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
Declaration of class vDynamicModel.
virtual void ComputeOutputParImage()
Compute output image using the m2p_parametricImages matrix Store the result in the m2p_outputParImage...
virtual int EstimateModelParameters(oImageSpace *ap_Image, int a_ite, int a_sset)=0
This function is pure virtual so must be implemented by children. It can be used to estimate any te...
int SaveParametricImages(int a_iteration, int a_subset=-1)
This function is virtual it can be overloaded by children if required.
int IntfReadImage(const string &a_pathToHeaderFile, FLTNB *ap_ImgMatrix, oImageDimensionsAndQuantification *ap_ID, int vb, bool a_lerpFlag)
Main function dedicated to Interfile 3D image loading.
FLTNB * mp_blackListedvoxelsImage
int IntfWriteImgFile(const string &a_pathToImg, FLTNB *ap_ImgMatrix, const Intf_fields &ap_IntfF, int vb)
Main function dedicated to Interfile 3D image writing. Recover image information from a provided In...
INTNB GetNbSliceOutMask()
Get the number of extrem slices that will be masked at each side.
INTNB GetNbVoxY()
Get the number of voxels along the Y axis.