8 #include "vDynamicModel.hh" 97 cout <<
" The following keywords are common to all dynamic models :" << endl;
98 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;
99 cout <<
" (Default x == 0) " << endl;
100 cout <<
" 'No_image_update: x' If set to 1, the reconstructed images for the next iteration/subset are not reestimated using the model" << endl;
101 cout <<
" (Default x == 0) (the code just performs standard independent reconstruction of each frames/gates) " << endl;
102 cout <<
" 'No_parameters_update: x' If set to 1, the parameters / functions of the model are not estimated with the image" << endl;
103 cout <<
" (Default x == 0) (this could be used to test The EstimateImageWithModel() function with specific user-provided parametric images) " << endl;
104 cout <<
" 'Save_parametric_images : x' Enable (1)/Disable(0) saving parametric images on disk" << endl;
105 cout <<
" (Default x == 1) " << endl;
106 cout <<
" 'Save_blacklisted_voxels_images : x' Enable (1)/Disable(0) saving blacklisted voxels images on disk" << endl;
107 cout <<
" (Default x == 0) " << endl;
108 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;
109 cout <<
" (Default: model applies everywhere) " << endl;
129 if(
m_verbose>=2)
Cout(
"vDynamicModel::CheckParameters ..."<< endl);
134 Cerr(
"***** vDynamicModel::CheckParameters() -> No image dimensions provided !" << endl);
141 Cerr(
"***** vDynamicModel::CheckParameters() -> Wrong verbosity level provided !" << endl);
148 Cerr(
"***** vDynamicModel::CheckParameters() -> Basis functions number has not been initialized !" << endl);
155 Cerr(
"***** vDynamicModel::CheckParameters() -> Number of model parameter has not been initialized !" << endl);
162 Cerr(
"***** vDynamicModel::CheckParameters() -> Number of model parameter has not been initialized !" << endl);
169 Cerr(
"***** vDynamicModel::CheckParameters() -> An error occurred while checking parameters of the child dynamic class !" << endl);
195 if(
m_verbose >=2)
Cout(
"vDynamicModel::Initialize ..."<< endl);
200 Cerr(
"***** vDynamicModel::Initialize() -> Must call CheckParameters functions before Initialize() !" << endl);
207 if(
m_verbose >=2)
Cout(
"vDynamicModel::Initialize Arterial Input Curve"<< endl);
217 Cerr(
"***** vDynamicModel::Initialize() -> Error while initializing Arterial Input Curve " << endl);
223 Cerr(
"***** vDynamicModel::Initialize() -> Error while checking Arterial Input Curve parameters " << endl);
226 if(
m_verbose >=3)
Cout(
"vDynamicModel::Interpolating Arterial Input Curve ..."<< endl);
241 Cerr(
"***** vDynamicModel::Initialize() -> Wrong initial values in mask (must be either 0 or 1) !" << endl);
254 Cerr(
"***** vDynamicModel::Initialize() -> A problem occurred while initializing stuff specific to the dynamic model !" << endl);
273 if(
m_verbose >=2)
Cout(
"vDynamicModel::ComputeOutputParImage ..." <<endl);
285 if(
m_verbose >=3)
Cout(
" Setting parametric image #: " << p+1 << endl );
315 Cout(
"vDynamicModel::ApplyOutputFOVMaskingOnParametricImages() -> Mask output image" << endl);
331 squared_radius_x *= squared_radius_x;
334 squared_radius_y *= squared_radius_y;
342 #pragma omp parallel for private(x) schedule(guided) 347 squared_distance_x *= squared_distance_x;
353 squared_distance_y *= squared_distance_y;
355 if ( squared_distance_x/squared_radius_x + squared_distance_y/squared_radius_y <= 1. )
continue;
379 for (
int z=0; z<removed_slices; z++)
386 INTNB index = base_z_first + i;
394 INTNB index = base_z_last + i;
422 if(
m_verbose >= 2)
Cout(
"vDynamicModel::EstimateModel ... " <<endl);
427 Cerr(
"***** vDynamicModel::EstimateModel() -> Called while not initialized !" << endl);
435 Cerr(
"***** vDynamicModel::EstimateModel() -> A problem occurred while estimating dynamic image series with model parameters !" << endl);
460 if(
m_verbose >= 2)
Cout(
"vDynamicModel::EstimateImage ... " <<endl);
465 Cerr(
"***** vDynamicModel::EstimateImage() -> Called while not initialized !" << endl);
473 Cerr(
"***** vDynamicModel::EstimateImage() -> A problem occurred while applying dynamic model to current estimate images !" << endl);
498 if(
m_verbose >=3)
Cout(
"vDynamicModel::ReadAndCheckConfigurationFile ..."<< endl);
500 ifstream in_file(a_fileOptions.c_str(), ios::in);
505 string dtag =
"No_image_update";
513 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
519 dtag =
"No_parameters_update";
527 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
533 dtag =
"Number_of_iterations_before_image_update";
541 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
547 dtag =
"Save_parametric_images";
555 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
561 dtag =
"Save_blacklisted_voxels_images";
569 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " << a_fileOptions << endl);
574 string path_to_mask =
"";
579 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '"<< dtag <<
"' flag in " <<
m_fileOptions << endl);
583 if(!path_to_mask.empty())
593 Cerr(
"***** ivDynamicModel::ReadAndCheckConfigurationFile()-> Error reading Interfile : " << path_to_mask <<
" !" << endl);
598 Cout(
"vDynamicModel::ReadAndCheckConfigurationFile() -> The following mask will be used for the 2nd model parameters estimation: " << path_to_mask << endl);
610 dtag =
"AIC_input_file";
618 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error while trying to read '" << dtag<<
"' flag in " << a_fileOptions << endl);
632 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile() -> Error occurred when trying to process the configuration file from a dynamic model child class " << endl);
638 Cerr(
"***** vDynamicModel::ReadAndCheckConfigurationFile -> Error while trying to read configuration file at: " << a_fileOptions << endl);
662 if(
m_verbose >=3)
Cout(
"vDynamicModel::SaveParametricImages ..." <<endl);
677 if (a_iteration >= 0)
679 stringstream ss; ss << a_iteration + 1;
680 path_to_image.append(
"_it").append(ss.str());
686 stringstream ss; ss << a_subset + 1;
687 path_to_image.append(
"_ss").append(ss.str());
696 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);
700 if(
m_verbose >=3)
Cout(
"vDynamicModel::SaveBlackListedVoxelsMask ..." <<endl);
705 if (a_iteration >= 0)
708 ss << a_iteration + 1;
709 path_to_image.append(
"_it").append(ss.str());
715 path_to_image.append(
"_ss").append(ss.str());
722 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing image of blacklisted voxels !" 738 if (a_iteration >= 0)
740 stringstream ss; ss << a_iteration + 1;
741 path_to_image.append(
"parRGmodel_it").append(ss.str());
747 stringstream ss; ss << a_subset + 1;
748 path_to_image.append(
"_ss").append(ss.str());
757 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);
769 if (a_iteration >= 0)
771 stringstream ss; ss << a_iteration + 1;
772 path_to_image.append(
"parCGmodel_it").append(ss.str());
778 stringstream ss; ss << a_subset + 1;
779 path_to_image.append(
"_ss").append(ss.str());
788 Cerr(
"***** iLinearModel::SaveParametricImages()-> Error writing Interfile of output image !" << endl);
852 int pfeas, iz, jz, iz1, iz2, npp1, *index;
853 FLTNB d1, d2, sm, up, ss, *w, *zz;
854 int iter, k, j=0, l, itmax, izmax=0, nsetp, ii, jj=0, ip;
855 FLTNB temp, wmax, t, alpha, asave, dummy, unorm, ztest, cc;
858 if(m<=0 || n<=0 || A==NULL || B==NULL || X==NULL)
860 Cerr(
"***** vDynamicModel::NNLS()-> Incorrect input parameters !" << endl);
865 if(wp!=NULL) w=wp;
else w=(
FLTNB*)calloc(n,
sizeof(
FLTNB));
866 if(zzp!=NULL) zz=zzp;
else zz=(
FLTNB*)calloc(m,
sizeof(
FLTNB));
867 if(indexp!=NULL) index=indexp;
else index=(
int*)calloc(n,
sizeof(
int));
869 if(w==NULL || zz==NULL || index==NULL)
871 Cerr(
"***** vDynamicModel::NNLS()-> Incorrect memory allocation on working space !" << endl);
882 iz2=n-1; iz1=0; nsetp=0; npp1=0;
893 while(iz1<=iz2 && nsetp<m)
896 for(iz=iz1; iz<=iz2; iz++)
899 for(l=npp1; l<m; l++)
908 for(wmax=0., iz=iz1; iz<=iz2; iz++)
922 iz=izmax; j=index[iz];
927 asave=A[j][npp1]; up=0.0;
929 NNLS_LSS_H12(1, npp1, npp1+1, m, &A[j][0], 1, &up, &dummy, 1, 1, 0);
933 for(l=0; l<nsetp; l++)
939 d2 = unorm + (d1=A[j][npp1], fabs(d1)) * 0.01;
947 NNLS_LSS_H12(2, npp1, npp1+1, m, &A[j][0], 1, &up, zz, 1, 1, 1);
949 ztest = zz[npp1]/A[j][npp1];
968 index[iz]=index[iz1]; index[iz1]=j; iz1++; nsetp=npp1+1; npp1++;
970 if(iz1<=iz2)
for(jz=iz1; jz<=iz2; jz++)
973 NNLS_LSS_H12(2, nsetp-1, npp1, m, &A[j][0], 1, &up, &A[jj][0], 1, m, 1);
976 if(nsetp!=m)
for(l=npp1; l<m; l++) A[j][l]=0.;
980 for(l=0; l<nsetp; l++)
984 for(ii=0; ii<=ip; ii++)
985 zz[ii] -= A[jj][ii] * zz[ip+1];
991 while( ++iter<itmax )
994 for(alpha=2.0, ip=0; ip<nsetp; ip++)
999 t = -X[l] / (zz[ip]-X[l]);
1010 if(alpha==2.0)
break;
1013 for(ip=0; ip<nsetp; ip++)
1016 X[l] += alpha*(zz[ip]-X[l]);
1021 k=index[jj+1]; pfeas=1;
1028 for(j=jj+1; j<nsetp; j++)
1030 ii=index[j]; index[j-1]=ii;
1032 NNLS_LSS_G1(A[ii][j-1], A[ii][j], &cc, &ss, &A[ii][j-1]);
1034 for(A[ii][j]=0., l=0; l<n; l++)
if(l!=ii)
1038 A[l][j-1] = cc*temp+ss*A[l][j];
1039 A[l][j] = -ss*temp+cc*A[l][j];
1042 temp=B[j-1]; B[j-1]=cc*temp+ss*B[j]; B[j]=-ss*temp+cc*B[j];
1045 npp1=nsetp-1; nsetp--; iz1--; index[iz1]=k;
1051 for(jj=0, pfeas=1; jj<nsetp; jj++)
1066 for(l=0; l<nsetp; l++)
1070 for(ii=0; ii<=ip; ii++)
1071 zz[ii] -= A[jj][ii]*zz[ip+1];
1073 zz[ip] /= A[jj][ip];
1082 for(ip=0; ip<nsetp; ip++)
1097 for(k=npp1; k<m; k++)
1110 if(wp==NULL) free(w);
1111 if(zzp==NULL) free(zz);
1112 if(indexp==NULL) free(index);
1171 FLTNB d1, b, clinv, cl, sm;
1175 if(mode!=1 && mode!=2)
return(1);
1176 if(m<1 || u==NULL || u_dim1<1 || cm==NULL)
return(1);
1177 if(lpivot<0 || lpivot>=l1 || l1>m)
return(1);
1180 cl = fabs(u[lpivot*u_dim1]);
1184 if(cl<=0.)
return(0);
1188 for(j=l1; j<m; j++) {
1189 cl = fmax(fabs(u[j*u_dim1]), cl);
1192 if(cl<=0.)
return(0);
1197 d1=u[lpivot*u_dim1]*clinv;
1199 for(j=l1; j<m; j++) {
1200 d1=u[j*u_dim1]*clinv;
1205 if(u[lpivot*u_dim1] > 0.) cl=-cl;
1206 *up = u[lpivot*u_dim1] - cl;
1207 u[lpivot*u_dim1]=cl;
1211 b=(*up)*u[lpivot*u_dim1];
1214 if(b>=0.0)
return(0);
1217 for(j=0; j<ncv; j++) {
1219 sm = cm[ lpivot*ice + j*icv ] * (*up);
1220 for(k=l1; k<m; k++) sm += cm[ k * ice + j*icv ] * u[ k*u_dim1 ];
1224 cm[ lpivot * ice + j*icv] += sm*(*up);
1226 for(k=l1; k<m; k++) cm[ k*ice + j*icv] += u[k * u_dim1]*sm;
1263 xr=b/a; d1=xr; yr=sqrt(d1*d1 + 1.); d1=1./yr;
1264 *cterm=(a>=0.0 ? fabs(d1) : -fabs(d1));
1265 *sterm=(*cterm)*xr; *sig=fabs(a)*yr;
1269 xr=a/b; d1=xr; yr=sqrt(d1*d1 + 1.); d1=1./yr;
1270 *sterm=(b>=0.0 ? fabs(d1) : -fabs(d1));
1271 *cterm=(*sterm)*xr; *sig=fabs(b)*yr;
1275 *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)
int NNLS(FLTNB **A, int m, int n, FLTNB *B, FLTNB *X, FLTNB *rnorm, FLTNB *wp, FLTNB *zzp, int *indexp)
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 EstimateImageWithModel(oImageSpace *ap_Image, int a_ite, int a_sset)=0
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.
oImageDimensionsAndQuantification * mp_ID
void ShowHelp()
This function is used to print out general help about dynamic models.
int ReadAndCheckConfigurationFile(string a_fileOptions)
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)
FLTNB ** m2p_parametricImages
bool m_saveBlacklistedImageMaskFlag
virtual int ApplyOutputFOVMaskingOnParametricImages()
Mask the outside of the transaxial FOV based on the m_fovOutPercent.
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
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...
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.
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.
const string & GetPathName()
virtual int EstimateModel(oImageSpace *ap_Image, int a_ite, int a_sset)
uint32_t * GetFramesTimeStopArray(int a_bed)
Singleton class that manages output writing on disk (images, sinograms, etc). It also manages loggi...
FLTNB ** m2p_nestedModelTimeBasisFunctions
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.
bool m_noParametersUpdateFlag
virtual ~vDynamicModel()
Destructor of vDynamicModel.
vDynamicModel()
Constructor of vDynamicModel. Simply set all data members to default values.
uint32_t * GetFramesTimeStartsArray(int a_bed)
const string & GetBaseName()
virtual int EstimateModelParameters(oImageSpace *ap_Image, int a_ite, int a_sset)=0
oArterialInputCurve * mp_ArterialInputCurve
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.
FLTNB ** m2p_outputParImages
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
virtual void ComputeOutputParImage()
Compute output image using the m2p_parametricImages matrix Store the result in the m2p_outputParImage...
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...
int SaveParametricImages(int a_iteration, int a_subset=-1)
FLTNB ** m2p_RGParametricImages
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.
FLTNB ** m2p_CGParametricImages