void proj2D(struct data *d) { char seqcon[6]; /* For 2D projections we fake the data is 2D and recon accordingly */ /* Get the seqcon */ strcpy(seqcon,*sval("seqcon",&d->p)); /* ROxPE projection has profile='ny' */ if (spar(d,"profile","ny")) { /* Adjust seqcon for 2D */ seqcon[3]='n'; setsval(&d->p,"seqcon",seqcon); setseqmode(d); default2D(d); } /* ROxPE2 projection has profile='yn' */ if (spar(d,"profile","yn")) { /* Adjust seqcon for 2D */ seqcon[2]=seqcon[3]; seqcon[3]='n'; setsval(&d->p,"seqcon",seqcon); setval(&d->p,"nv",d->nv2); setval(&d->p,"nseg",d->nv2); setval(&d->p,"etl",1); setval(&d->p,"pelist",0); setval(&d->p,"nv2",1); setsval(&d->p,"apptype","im2D"); setdatapars(d); setseqmode(d); /* The following is required to be able to graphically plan on the output images: thk = lpe lpe = lpe2 ppe of each slice in turn = pss of each slice in turn psi, phi, theta need to be corrected (90 degree rotation about readout axis) */ /* For now just adjust FOV and offset for centre of slice(s) */ setval(&d->p,"thk",*val("lpe",&d->p)); setval(&d->p,"lpe",*val("lpe2",&d->p)); setval(&d->p,"ppe",*val("pss0",&d->p)); default2D(d); } }
void other3Dfdfs(struct data *d,char *par,char *outdir,int type,int precision,int volindex) { if ((spar(d,par,"y"))) { /* Output selected by par='y' */ if (d->nr>1) /* Multiple receivers */ gen3Dfdfs(d,'i',outdir,type,precision,volindex); else /* Single receiver */ gen3Dfdfs(d,'s',outdir,type,precision,volindex); } }
int magnitude3Dfdfs(struct data *d,char *par,char *parIR,char *outdir,int type,int precision,int volindex) { int output=0; if ((spar(d,par,"y"))) { /* Output selected by par='y' */ if (d->nr>1) { /* Multiple receivers */ if ((spar(d,parIR,"y"))) /* Individual Receiver output */ gen3Dfdfs(d,'i',outdir,type,precision,volindex); else {/* Combined output */ gen3Dfdfs(d,'c',outdir,type,precision,volindex); output=1; } } else { /* Single receiver */ gen3Dfdfs(d,'s',outdir,type,precision,volindex); output=1; } } return(output); }
void recon2D(struct data *d) { /* If profile flag is set then recon profiles */ if (d->profile) profile1D(d); /* Else check recon flag for non-standard recons ... */ /* Masking */ else if (spar(d,"recon","mask")) mask2D(d); /* Adding to masks */ else if (spar(d,"recon","add2mask")) add2mask2D(d); /* Sensitivity maps */ else if (spar(d,"recon","smap")) smap2D(d,SM); /* SENSE */ else if (spar(d,"recon","sense")) sense2D(d); /* Ability to perform SENSE */ else if (spar(d,"recon","sensibility")) sensibility2D(d); /* ASL test mode */ else if (spar(d,"recon","asltest")) asltest2D(d); /* Otherwise perform standard 2D recon */ else default2D(d); }
void recon2D(struct data *d) { /* If profile flag is set then recon profiles */ if (d->profile) profile1D(d); /* Else check recon flag for non-standard recons ... */ /* ASL test mode */ else if (spar(d,"recon","asltest")) asltest2D(d); /* Otherwise perform standard 2D recon */ else default2D(d); }
void setstartendvol(struct data *d) { if (spar(d,"allvolumes","n")) { /* Don't process all volumes */ d->startvol=(int)*val("startvol",&d->p)-1; d->endvol=(int)*val("endvol",&d->p); if (d->startvol > d->endvol) { /* Swap them */ d->vol=d->endvol; d->endvol=d->startvol; d->startvol=d->vol; } if (d->startvol < 0) d->startvol=0; if (d->endvol > d->nvols) d->endvol=d->nvols; } else { /* Process all volumes */ d->startvol=0; d->endvol=d->nvols; } }
void setreffile(struct file *datafile,struct data *d,char *refpar) { char filename[MAXPATHLEN],refname[MAXPATHLEN]; int i,filenamectr=0,refnamectr=0; /* Get the reference name from the reference parameter */ strcpy(refname,*sval(refpar,&d->p)); /* If recon is straight after acquisition ... */ if (vnmrj_recon && spar(d,"file","exp")) { /* Use the reference name as is */ setfile(datafile,refname); } else { if (vnmrj_recon) { /* Recon from within VnmrJ */ /* Use the path as defined in the parameter "file" */ strcpy(filename,*sval("file",&d->p)); } else { /* Recon outside of VnmrJ */ /* Use the path as defined in d->file */ strcpy(filename,d->file); filename[strlen(filename)-8]=0; /* NULL terminate to remove .fid/fid */ } /* Now use the path as defined in filename */ for (i=0;i<strlen(filename);i++) if (filename[i] == '/') filenamectr=i; if (filenamectr>0) filenamectr++; for (i=0;i<strlen(refname);i++) if (refname[i] == '/') refnamectr=i; if (refnamectr>0) refnamectr++; for (i=refnamectr;i<strlen(refname);i++) { filename[filenamectr]=refname[i]; filenamectr++; } filename[filenamectr]=0; /* NULL terminate */ setfile(datafile,filename); } }
int im2DLL(struct data *d) { if (spar(d,"recontype","LookLocker")) return(1); else return(0); }
void setseqmode(struct data *d) { char seqcon[6]; /* To figure the sequence mode insist we must have the following */ if ((ptype("seqcon",&d->p) < 0) || (ptype("apptype",&d->p) < 0)) { fprintf(stderr,"\n%s: %s()\n",__FILE__,__FUNCTION__); fprintf(stderr," The 'procpar' must contain 'seqcon' and 'apptype' parameters:\n\n"); fprintf(stderr," Aborting ...\n\n"); fflush(stderr); exit(1); } /* Set sequence mode */ d->seqmode=0; /* Standard cases */ strcpy(seqcon,*sval("seqcon",&d->p)); if ((seqcon[3] == 'n') && (seqcon[4] == 'n')) { /* standard 2D multislice */ if ((seqcon[1] == 'c') && (seqcon[2] == 'c')) d->seqmode=IM2DCC; if ((seqcon[1] == 'c') && (seqcon[2] == 's')) d->seqmode=IM2DCS; if ((seqcon[1] == 's') && (seqcon[2] == 'c')) d->seqmode=IM2DSC; if ((seqcon[1] == 's') && (seqcon[2] == 's')) d->seqmode=IM2DSS; } else { /* standard 3D */ if ((seqcon[2] == 'c') && (seqcon[3] == 'c')) d->seqmode=IM3DCC; if ((seqcon[2] == 'c') && (seqcon[3] == 's')) d->seqmode=IM3DCS; if ((seqcon[2] == 's') && (seqcon[3] == 'c')) d->seqmode=IM3DSC; if ((seqcon[2] == 's') && (seqcon[3] == 's')) d->seqmode=IM3DSS; } /* Special cases */ if (spar(d,"apptype","im1Dglobal")) d->seqmode=IM1D; if (spar(d,"apptype","im1D")) d->seqmode=IM1D; if (spar(d,"apptype","im2Dfse")) { if ((seqcon[1] == 'c') && (seqcon[2] == 'c')) d->seqmode=IM2DCCFSE; if ((seqcon[1] == 'c') && (seqcon[2] == 's')) d->seqmode=IM2DCSFSE; if ((seqcon[1] == 's') && (seqcon[2] == 'c')) d->seqmode=IM2DSCFSE; if ((seqcon[1] == 's') && (seqcon[2] == 's')) d->seqmode=IM2DSSFSE; } if (spar(d,"apptype","im2Depi")) d->seqmode=IM2DEPI; if (im2DLL(d)) { /* 2D LookLocker */ if ((seqcon[1] == 'c') && (seqcon[2] == 'c')) d->seqmode=IM2DCCLL; if ((seqcon[1] == 'c') && (seqcon[2] == 's')) d->seqmode=IM2DCSLL; if ((seqcon[1] == 's') && (seqcon[2] == 'c')) d->seqmode=IM2DSCLL; if ((seqcon[1] == 's') && (seqcon[2] == 's')) d->seqmode=IM2DSSLL; } if (spar(d,"apptype","im3Dfse")) { if (seqcon[3] == 'c') d->seqmode=IM3DCFSE; if (seqcon[3] == 's') d->seqmode=IM3DSFSE; } if (spar(d,"apptype","im2Dcsi")) { if(seqcon[2] == 'c'){ if(seqcon[3] == 's') d->seqmode=IM2DCSCSI; if(seqcon[3] == 'c') d->seqmode=IM2DCCCSI; } if(seqcon[2] == 's'){ if(seqcon[3] == 'c') d->seqmode=IM2DSCCSI; if(seqcon[3] == 's') d->seqmode=IM2DSSCSI; } } if (spar(d,"apptype","im3Dcsi")) { if ((seqcon[2] == 'c') && (seqcon[3] == 'c')) { if (seqcon[4] == 's')d->seqmode=IM3DCCSCSI; else d->seqmode=IM3DCCCCSI; } if ((seqcon[2] == 'c') && (seqcon[3] == 's')) { if (seqcon[4] == 's')d->seqmode=IM3DCSSCSI; else d->seqmode=IM3DCSCCSI; } if ((seqcon[2] == 's') && (seqcon[3] == 'c')) { if (seqcon[4] == 's')d->seqmode=IM3DSCSCSI; else d->seqmode=IM3DSCCCSI; } if ((seqcon[2] == 's') && (seqcon[3] == 's')) { if (seqcon[4] == 's')d->seqmode=IM3DSSSCSI; else d->seqmode=IM3DSSCCSI; } } #ifdef DEBUG fprintf(stdout,"\n%s: %s()\n",__FILE__,__FUNCTION__); fprintf(stdout," Sequence mode set to "); switch (d->seqmode) { case IM1D: fprintf(stdout,"1D\n"); break; case IM2DCC: fprintf(stdout,"2D with seqcon='*ccnn'\n"); break; case IM2DCS: fprintf(stdout,"2D with seqcon='*csnn'\n"); break; case IM2DSC: fprintf(stdout,"2D with seqcon='*scnn'\n"); break; case IM2DSS: fprintf(stdout,"2D with seqcon='*ssnn'\n"); break; case IM2DCCFSE: fprintf(stdout,"2D with appmode='im2Dfse' and seqcon='nccnn'\n"); break; case IM2DCSFSE: fprintf(stdout,"2D with appmode='im2Dfse' and seqcon='ncsnn'\n"); break; case IM2DSCFSE: fprintf(stdout,"2D with appmode='im2Dfse' and seqcon='nscnn'\n"); break; case IM2DSSFSE: fprintf(stdout,"2D with appmode='im2Dfse' and seqcon='nssnn'\n"); break; case IM2DEPI: fprintf(stdout,"2D with appmode='im2Depi'\n"); break; case IM2DCCLL: fprintf(stdout,"2D with recontype='LookLocker' and seqcon='nccnn'\n"); break; case IM2DCSLL: fprintf(stdout,"2D with recontype='LookLocker' and seqcon='ncsnn'\n"); break; case IM2DSCLL: fprintf(stdout,"2D with recontype='LookLocker' and seqcon='nscnn'\n"); break; case IM2DSSLL: fprintf(stdout,"2D with recontype='LookLocker' and seqcon='nssnn'\n"); break; case IM3DCC: fprintf(stdout,"3D with seqcon='**ccn'\n"); break; case IM3DCS: fprintf(stdout,"3D with seqcon='**csn'\n"); break; case IM3DSC: fprintf(stdout,"3D with seqcon='**scn'\n"); break; case IM3DSS: fprintf(stdout,"3D with seqcon='**ssn'\n"); break; case IM3DCFSE: fprintf(stdout,"3D with appmode='im3Dfse' and seqcon='ncccn'\n"); break; case IM3DSFSE: fprintf(stdout,"3D with appmode='im3Dfse' and seqcon='nccsn'\n"); break; default: break; } fflush(stdout); #endif }
void setdatapars(struct data *d) { int i; char rcvrs[MAXRCVRS]; /* Set the sequence mode from seqcon and apptype parameters */ setseqmode(d); /* Set data dimensions */ setdim(d); /* Number of segments and echo train length */ /* Number of segments takes precidence, as in the setloop macro */ d->nseg=(int)*val("nseg",&d->p); if (d->nseg>0) { d->etl=d->nv/d->nseg; if (d->nv%d->nseg>0) d->etl++; } else { d->etl=(int)*val("etl",&d->p); if (d->etl>0) { d->nseg=d->nv/d->etl; if (d->nv%d->etl>0) d->nseg++; } } if (d->nseg<1) { d->nseg=d->nv; d->etl=1; } /* Number of echoes */ d->ne=(int)*val("ne",&d->p); if (d->ne < 1) d->ne=1; /* Set ne to 1 if 'ne' does not exist */ /* Number of receivers */ strcpy(rcvrs,*sval("rcvrs",&d->p)); d->nr=0; for (i=0;i<strlen(rcvrs);i++) if (rcvrs[i] == 'y') d->nr++; /* Number of pss values = slices */ d->ns=nvals("pss",&d->p); /* There must be at least one block per volume */ d->nblocks=(int)*val("nblocks",&d->p); if (!d->nblocks) d->nblocks++; /* Number of points and views for resizing data */ d->fn=(int)*val("fn",&d->p); d->fn1=(int)*val("fn1",&d->p); d->fn2=(int)*val("fn2",&d->p); d->fn3=(int)*val("fn3",&d->p); /* for cropping csi result */ d->startd1 =(int)*val("snv",&d->p); d->startd1 += -1; d->startd2 =(int)*val("snv2",&d->p); d->startd2 += -1; d->cropd1 =(int)*val("cnv",&d->p); d->cropd2 =(int)*val("cnv2",&d->p); // for reversal of dimensions in csi d->d1rev = (int)*val("d1rev",&d->p); d->d2rev = (int)*val("d2rev",&d->p); d->d3rev = (int)*val("d3rev",&d->p); /* Navigators */ d->nav=FALSE; /* Default is no navigator */ if (spar(d,"navigator","y")) { d->nav=TRUE; d->nnav=nvals("nav_echo",&d->p); if (d->nnav>0) { if ((d->navpos = (int *)malloc(d->nnav*sizeof(int))) == NULL) nomem(__FILE__,__FUNCTION__,__LINE__); for (i=0;i<d->nnav;i++) d->navpos[i]=(int)val("nav_echo",&d->p)[i]; } } /* Set profile flag */ d->profile=FALSE; if (spar(d,"profile","y") && im2D(d)) d->profile=TRUE; if (spar(d,"profile","yy") && im3D(d)) d->profile=TRUE; /* Set proj2D flag */ d->proj2D=FALSE; if (im3D(d)) { if (spar(d,"profile","yn") || spar(d,"profile","ny")) d->proj2D=TRUE; } /* Set number of dimensions */ /* 1Ds are just 1D */ if (im1D(d)) d->ndim=1; /* Multislice 2Ds and 3Ds both work on volumes, i.e. 3D */ else if (im2D(d)) d->ndim=3; else if (im3D(d)) d->ndim=3; /* Set default status of each dimension to flag no data */ if ((d->dimstatus = (int *)malloc(d->ndim*sizeof(int))) == NULL) nomem(__FILE__,__FUNCTION__,__LINE__); for (i=0;i<d->ndim;i++) d->dimstatus[i]=NONE; #ifdef DEBUG fprintf(stdout,"\n%s: %s()\n",__FILE__,__FUNCTION__); fprintf(stdout," d->nseg = %d\n",d->nseg); fprintf(stdout," d->etl = %d\n",d->etl); fprintf(stdout," d->ne = %d\n",d->ne); fprintf(stdout," d->nr = %d\n",d->nr); fprintf(stdout," d->ns = %d\n",d->ns); fprintf(stdout," d->fn = %d\n",d->fn); fprintf(stdout," d->fn1 = %d\n",d->fn1); fprintf(stdout," d->fn2 = %d\n",d->fn2); if (d->nav) { fprintf(stdout," d->nnav = %d",d->nnav); fprintf(stdout,", d->navpos = %d",d->navpos[0]); for (i=1;i<d->nnav;i++) fprintf(stdout,",%d",d->navpos[i]); fprintf(stdout,"\n"); } if (d->profile) fprintf(stdout," d->profile = TRUE\n"); if (d->proj2D) fprintf(stdout," d->proj2D = TRUE\n"); fflush(stdout); #endif }
void default1D(struct data *d) { struct file fref; struct data ref; struct datablockhead *dbh; int /*dim1,dim2,*/dim3,nr; int i,j; int wref=FALSE; #ifdef DEBUG char function[20]; strcpy(function,"default1D"); /* Set function name */ #endif /* Open data and phasefile file pointers for writing */ openfpw(d,DATA_FILE); openfpw(d,PHAS_FILE); /* Write data and phasefile file headers */ wdfh(d,DATA_FILE); wdfh(d,PHAS_FILE); /* Set data dimensions */ //dim1=d->np/2; //dim2=1; dim3=d->fh.ntraces; nr=d->nr; /* Set nuber of "volumes" */ d->nvols=d->fh.nblocks/nr; /* Check if there is a water reference */ if (spar(d,"ws","y") && spar(d,"wref","y") && spar(d,"wrefstatus","ws")) wref=TRUE; /* Prepare water reference */ if (wref) { setreffile(&fref,d,"waterref"); /* Set reference file */ getpars(fref.procpar[0],&ref); /* Get pars from reference procpar */ opendata(fref.fid[0],&ref); /* Open reference data file fid */ getvol1D(&ref,0,NDCC); /* Get volume without applying dbh.lvl and dbh.tlt */ weightdata1D(&ref,STD,D1); /* Weight data using standard VnmrJ parameters */ } /* Allocate memory for blocks headers from all receivers */ if ((dbh = malloc(nr*sizeof(d->bh))) == NULL) nomem(); /* For spectra we anticipate there is easily sufficient memory for data from all receiver blocks */ for (d->vol=0;d->vol<d->nvols;d->vol++) { /* loop over "volumes" */ for (i=0;i<nr;i++) { /* loop over receivers */ getdbh(d,nr*d->vol+i); /* Get block header */ copydbh(&d->bh,&dbh[i]); /* Store the block headers for writing */ } getvol1D(d,d->vol,NDCC); /* Get data block without applying dbh.lvl and dbh.tlt */ weightdata1D(d,STD,D1); /* Weight data using standard VnmrJ parameters */ if (wref) refcorr1D(d,&ref); /* Phase correct using the reference */ else combine1D(d); /* Combine data from multiple receivers */ zerofill1D(d,STD,D1); /* Zero fill data using standard VnmrJ parameters */ fft1D(d,D1); /* 1D fft */ shiftdata1D(d,STD,D1); /* Shift data to get spectra */ for (i=0;i<nr;i++) { /* loop over receivers */ copydbh(&dbh[i],&d->bh); /* Copy block header for writing */ for (j=0;j<dim3;j++) { d->bh.index=d->vol*nr*dim3+i*dim3+j; /* Set block index */ wdbh(d,DATA_FILE); /* Write block header */ wdbh(d,PHAS_FILE); /* Write block header */ w1Dtrace(d,i,j,DATA_FILE); /* Write block */ w1Dtrace(d,i,j,PHAS_FILE); /* Write block */ } } clear1Ddata(d); /* Clear data "volume" from memory */ } clear1Dall(d); /* Clear everything from memory */ closefp(d,DATA_FILE); closefp(d,PHAS_FILE); }
void defaultEPI(struct data *d) { int DISCARD=-1; int refEPI=FALSE,refSGE=FALSE; int getscaleref=FALSE; double oversample; struct data ref1,ref2,ref3,ref4,ref5,ref6; struct segscale scale1,scale2; enum { OFF = 0, POINTWISE = 1, TRIPLE = 2, SCALED_TRIPLE = 3 } epi_pc; setnvolsEPI(d); /* Set the number of data volumes */ d->nv=(int)*val("nphase",&d->p); /* Set d->nv for dimorder2D */ d->pssorder=sliceorder(d,d->ns,"pss"); /* Fill pssorder with the slice order */ d->dim2order=phaseorder(d,d->nv,d->nv,"par_does_not_exist"); /* Set dim2order=-1 for sequential phase encode order */ d->dim3order=phaseorder(d,d->nv,d->nv,"sgepelist"); /* Fill dim3order with the standard gradient echo phase encode order */ d->nv2=d->nv; /* Set d->nv2 for dim3order */ d->nv=(int)*val("nseg",&d->p); /* Use d->nv for the number of shots */ /* Set EPI correction scheme */ if (spar(d,"epi_pc","POINTWISE")) epi_pc=POINTWISE; else if (spar(d,"epi_pc","TRIPLE")) epi_pc=TRIPLE; else if (spar(d,"epi_pc","SCALED_TRIPLE")) epi_pc=SCALED_TRIPLE; else epi_pc=OFF; /* Check whether to output or discard reference scans */ if (spar(d,"imRF","y")) refEPI=TRUE; if (spar(d,"imSGE","y")) refSGE=TRUE; /* Set reference data */ if (epi_pc > OFF) { /* Pointwise or triple reference phase correction */ initdatafrom(d,&ref1); initdatafrom(d,&ref3); /* ref3 used in pointwise phase correction of inverted reference scans if reference output is selected */ } if (epi_pc > POINTWISE) { /* Triple reference phase corrections */ initdatafrom(d,&ref2); initdatafrom(d,&ref4); } if (epi_pc > TRIPLE) { /* Scaled triple reference phase correction */ initdatafrom(d,&ref5); initdatafrom(d,&ref6); } /* Set default of no compressed segment scaling just in case it's never set */ scale1.data=FALSE; scale2.data=FALSE; /* Loop over data blocks */ for (d->block=0;d->block<d->nblocks;d->block++) { if (interupt) return; /* Interupt/cancel from VnmrJ */ d->outvol=0; /* Initialise output data volume (that will not include reference scans) */ for (d->vol=0;d->vol<d->nvols;d->vol++) { /* Loop over "volumes" */ setoutvolEPI(d); /* Set output data volume */ if (d->outvol>d->endvol) break; /* Break if last requested volume has been processed */ getblockEPI(d,d->vol,NDCC); /* Get block without applying dbh.lvl and dbh.tlt */ zeromax(d); /* Zero max structure & coordinates of maximum */ zeronoise(d); /* Zero values in noise structure */ #ifdef DEBUG fprintf(stdout,"\n%s: %s()\n",__FILE__,__FUNCTION__); switch (epi_pc) { case OFF: fprintf(stdout," Correction: OFF \n"); break; case POINTWISE: fprintf(stdout," Correction: POINTWISE \n"); break; case TRIPLE: fprintf(stdout," Correction: TRIPLE \n"); break; case SCALED_TRIPLE: fprintf(stdout," Correction: SCALED_TRIPLE \n"); break; } fflush(stdout); #endif /* Process data as directed by image parameter */ switch ((int)getelem(d,"image",d->vol)) { case 0: /* Reference, no phase-encode */ setblockEPI(d); /* Set block for 2D data (d->nv > 1) and navigators */ if (refEPI) w2Dfdfs(d,VJ,FLT32,d->vol); /* Output raw data for the volume, if requested */ if (epi_pc > OFF) { /* If there is phase correction */ ftnpEPI(d); /* FT along readout dimension */ clear2Ddata(&ref1); /* Clear ref1 */ copy2Ddata(d,&ref1); /* Copy to ref1 */ ref1.datamode=EPIREF; /* Flag as EPIREF data */ } else { /* else there is no phase correction */ ref1.datamode=NONE; /* Flag as no data */ if (refEPI) ftnpEPI(d); /* FT along readout dimension */ } setsegscale(d,&scale1); /* Set scaling for compressed segments */ segscale(d,&scale1); /* Scale compressed segments */ if (refEPI) /* If reference output is requested */ w2Dfdfs(d,VJ,FLT32,d->vol); /* Output data for the volume */ else w2Dfdfs(d,VJ,FLT32,DISCARD); /* Else use DISCARD to flag skip the volume */ wnifti(d,VJ,FLT32,DISCARD); break; case -1: /* Inverted Readout Reference, with phase-encode */ #ifdef DEBUG fprintf(stdout," Processing reference -1 data ...\n"); fflush(stdout); #endif setblockEPI(d); /* Set block for 2D data (d->nv > 1) and navigators */ if (refEPI) w2Dfdfs(d,VJ,FLT32,d->vol); /* Output raw data for the volume, if requested */ ftnpEPI(d); /* FT along readout dimension */ segscale(d,&scale2); /* Scale compressed segments */ if (epi_pc > POINTWISE) { /* if triple or scaled triple reference phase correction */ clear2Ddata(&ref2); /* Clear ref2 */ copy2Ddata(d,&ref2); /* Copy to ref2 */ ref2.datamode=EPIREF; /* Flag ref2 as EPIREF data */ if (ref3.datamode == EPIREF) { /* if there is ref3 reference data */ phaseEPIref(&ref2,&ref3,&ref4); /* Phase correct ref2 data using ref3 and put result in ref4 */ /* analyseEPInav(&ref4); // Analyse the navigators */ stripEPInav(&ref4); /* Strip the navigator scans */ ftnvEPI(&ref4); /* FT along phase encode dimension */ revreadEPI(&ref4); /* Reverse the data in readout dimension */ getscaleref=TRUE; /* Flag to store the next regular image for scaling in SCALED_TRIPLE */ } } if (refEPI) { /* if reference output is requested */ if (ref3.datamode == EPIREF) { /* if there is ref3 reference data */ phaseEPI(d,&ref3); /* Phase correct with the reference */ } navcorrEPI(d); /* Phase correct with the navigator */ stripEPInav(d); /* Strip the navigator scans */ ftnvEPI(d); /* FT along phase encode dimension */ revreadEPI(d); /* Reverse the data in readout dimension */ w2Dfdfs(d,VJ,FLT32,d->vol); /* Output data for the volume */ } else w2Dfdfs(d,VJ,FLT32,DISCARD); /* Use DISCARD to flag skip the volume */ wnifti(d,VJ,FLT32,DISCARD); break; case -2: /* Inverted Readout Reference, no phase-encode */ #ifdef DEBUG fprintf(stdout," Processing reference -2 data ...\n"); fflush(stdout); #endif setblockEPI(d); /* Set block for 2D data (d->nv > 1) and navigators */ if (refEPI) w2Dfdfs(d,VJ,FLT32,d->vol); ftnpEPI(d); /* FT along readout dimension */ setsegscale(d,&scale2); /* Set scaling for compressed segments */ segscale(d,&scale2); /* Scale compressed segments */ if (epi_pc > POINTWISE) { /* if old triple or triple reference phase correction */ clear2Ddata(&ref3); /* Clear ref3 */ copy2Ddata(d,&ref3); /* Copy to ref3 */ ref3.datamode=EPIREF; /* Flag ref3 as EPIREF data */ if (ref2.datamode == EPIREF) { /* if there is ref2 reference data */ phaseEPIref(&ref2,&ref3,&ref4); /* Phase correct ref2 data using ref3 and put result in ref4 */ /* analyseEPInav(&ref4); // Analyse the navigators */ stripEPInav(&ref4); /* Strip the navigator scans */ ftnvEPI(&ref4); /* FT along phase encode dimension */ revreadEPI(&ref4); /* Reverse the data in readout dimension */ getscaleref=TRUE; /* Flag to store the next regular image for scaling in SCALED_TRIPLE */ } } if (refEPI) { /* if reference output is requested */ if (epi_pc == POINTWISE) { /* if pointwise reference phase correction */ clear2Ddata(&ref3); /* Clear ref3 */ copy2Ddata(d,&ref3); /* Copy to ref3 */ ref3.datamode=EPIREF; /* Flag ref3 as EPIREF data */ } revreadEPI(d); /* Reverse the data in readout dimension */ w2Dfdfs(d,VJ,FLT32,d->vol); /* Output data for the volume */ } else w2Dfdfs(d,VJ,FLT32,DISCARD); /* Use DISCARD to flag skip the volume */ wnifti(d,VJ,FLT32,DISCARD); break; case 1: /* Regular image */ #ifdef DEBUG fprintf(stdout," Processing image 1 data ...\n"); fflush(stdout); #endif setblockEPI(d); /* Set block for 2D data (d->nv > 1) and navigators */ if (d->outvol>=d->startvol) w2Dfdfs(d,VJ,FLT32,d->vol); /* Output raw data for the volume, if requested */ switch (epi_pc) { case SCALED_TRIPLE: /* Scaled triple reference phase correction */ if (getscaleref) { /* If the scale reference has just been acquired */ clear2Ddata(&ref5); /* Clear ref5 */ copy2Ddata(d,&ref5); /* Copy to ref5 */ ref5.datamode=EPIREF; /* Flag ref5 as EPIREF data */ prepEPIref(&ref5,&ref1); /* Prepare ref5 data so it can be used to scale ref4 data */ } break; default: break; } ftnpEPI(d); /* FT along readout dimension */ segscale(d,&scale1); /* Scale compressed segments */ phaseEPI(d,&ref1); /* Phase correct with the reference */ navcorrEPI(d); /* Phase correct with the navigator */ /* analyseEPInav(d); // Analyse the navigators */ stripEPInav(d); /* Strip the navigator scans */ ftnvEPI(d); /* FT along phase encode dimension */ switch (epi_pc) { case TRIPLE: /* Triple reference phase correction */ addEPIref(d,&ref4); /* Add ref4 data to cancel N/2 ghost */ break; case SCALED_TRIPLE: /* Scaled triple reference phase correction */ if (getscaleref) { /* If the scale reference has just been acquired */ addEPIref(d,&ref4); /* Add ref4 data to cancel N/2 ghost */ getscaleref=FALSE; /* Flag that scale reference has been acquired */ } else { addscaledEPIref(d,&ref4,&ref5); /* Scale ref4 data according to d/ref5, then add to d */ } break; default: break; } if (d->outvol>=d->startvol) { phasedata2D(d,VJ); /* Phase data if required */ w2Dfdfs(d,VJ,FLT32,d->vol); /* Write 2D fdf data from volume */ wnifti(d,VJ,FLT32,d->vol); } break; default: /* Reference Standard Gradient Echo */ setblockSGE(d); if (refSGE) w2Dfdfs(d,VJ,FLT32,d->vol); /* Output raw data for the volume, if requested */ shiftdata2D(d,STD); /* Shift FID data for fft */ zeronoise(d); /* Zero any noise measurement */ equalizenoise(d,STD); /* Scale for equal noise in all receivers */ phaseramp2D(d,READ); /* Phase ramp the data to correct for readout offset pro */ phaseramp2D(d,PHASE); /* Phase ramp the data to correct for phase encode offset ppe */ weightdata2D(d,STD); /* Weight data using standard VnmrJ parameters */ zerofill2D(d,STD); /* Zero fill data using standard VnmrJ parameters */ fft2D(d,STD); /* 2D fft */ phasedata2D(d,VJ); /* Phase data if required */ shiftdata2D(d,STD); /* Shift data to get images */ oversample=*val("oversample",&d->p); /* Check to see if there is oversampling */ if (oversample>1) zoomEPI(d); /* If oversampled, zoom to get the requested FOV */ if (refSGE) /* If standard gradient echo reference output is requested */ w2Dfdfs(d,VJ,FLT32,d->vol); /* Output data for the volume */ else w2Dfdfs(d,VJ,FLT32,DISCARD); /* Else use DISCARD to flag skip the volume */ wnifti(d,VJ,FLT32,DISCARD); break; } /* end image parameter switch */ clear2Ddata(d); /* Clear data volume from memory */ setdim(d); /* Reset data dimensions in case data has been zerofilled (sets d->nv=1) */ d->nv=*val("nseg",&d->p); /* Use d->nv for the number of shots */ d->nv2=(int)*val("nphase",&d->p); /* Use d->nv2 for number of standard gradient echo phase encodes */ d->dimstatus[0] = NONE; /* Make sure ZEROFILL status is not set, otherwise setdim will be called in getblock() */ d->dimstatus[1] = NONE; /* Make sure ZEROFILL status is not set, otherwise setdim will be called in getblock() */ } /* end volume loop */ } /* end data block loop */ /* Clear all reference data */ if (epi_pc > OFF) { /* Pointwise or triple reference phase correction */ clear2Dall(&ref1); clear2Dall(&ref3); } if (epi_pc > POINTWISE) { /* Triple and scaled triple reference phase correction */ clear2Dall(&ref2); clear2Dall(&ref4); } if (epi_pc > TRIPLE) { /* Scaled triple reference phase correction */ clear2Dall(&ref5); clear2Dall(&ref6); } clear2Dall(d); /* Clear everything from memory */ }
void settep(struct data *d, int mode) { int dim1,dim2,dim3,nr; int **max; int i,j,k,l,n; int ix; int nseg,nnav,etl,altread,echo,oddcount,evencount; int steadyStates,flipLine; double re,im,M2,maxM,oddmax,evenmax,sw,tepadjust; char tepfile[MAXPATHLEN]; FILE *f_out; #ifdef DEBUG struct timeval tp; double t1,t2; int rtn; fprintf(stdout,"\n%s: %s()\n",__FILE__,__FUNCTION__); fprintf(stdout," Attempting to calculate correction for tep ...\n"); rtn=gettimeofday(&tp, NULL); t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; fflush(stdout); #endif /* Set data dimensions */ dim1=d->np/2; dim2=d->nv; dim3=d->endpos-d->startpos; nr=d->nr; /* Allow for arbitrary number of acquired steady state echoes (default 1) */ steadyStates = (int)*val("acquiredSteadyStates",&d->p); if (parindex("acquiredSteadyStates",&d->p) < 0) steadyStates = 1; /* Allow for sequences with readout polarity set constant for the first acquired EPI echo, i.e. the set polarity depends on # navigators and # acquired steady states */ flipLine = (int)*val("flipLine",&d->p); if (flipLine != 1) flipLine = 0; switch(mode) { case STD: /* Use maximum magnitude */ /* If noise data does not exist set it to zero */ if (!d->noise.data) zeronoise(d); /* If noise data is zero sample the noise */ if (d->noise.zero) getnoise(d,STD); /* Set some defaults */ zeromax(d); if ((max = (int **)malloc(nr*sizeof(int *))) == NULL) nomem(__FILE__,__FUNCTION__,__LINE__); for (i=0;i<nr;i++) if ((max[i] = (int *)malloc(dim2*sizeof(int))) == NULL) nomem(__FILE__,__FUNCTION__,__LINE__); /* Get coordinates of maxima for odd and even echoes */ for (i=0;i<nr;i++) { for (j=0;j<dim3;j++) { for (k=0;k<dim2;k++) { max[i][k]=-1; maxM=0.0; for (l=0;l<dim1;l++) { re=fabs(d->data[i][j][k*dim1+l][0]); im=fabs(d->data[i][j][k*dim1+l][1]); M2=re*re+im*im; if ((M2 > maxM) && (M2 > 4*d->noise.M2[i])) { maxM=M2; max[i][k]=l; } } } } } oddcount=0; oddmax=0.0; evencount=0; evenmax=0.0; nseg=(int)*val("nseg",&d->p); nnav=(int)*val("nnav",&d->p); etl=(int)*val("etl",&d->p); altread=spar(d,"altread","y"); /* alternating read gradient for alternate segments ... */ if (nseg<2) altread=FALSE; /* ... only if nseg>1 ... */ if (nseg%2==0) altread=FALSE; /* ... and only if nseg is odd */ for (n=0;n<nseg;n++) { ix=n*(nnav+etl); for (i=0;i<nr;i++) { echo=0; if (altread && n%2) echo=1; for (k=0;k<nnav;k++) { if (max[i][k] > -1) { if (echo%2==flipLine) { oddmax += max[i][ix+k]; oddcount++; } else { evenmax += max[i][ix+k]; evencount++; } } echo++; } /* Skip the steady state readout gradients */ echo += steadyStates; for (k=nnav;k<etl;k++) { if (max[i][k] > -1) { if (echo%2==flipLine) { oddmax += max[i][ix+k]; oddcount++; } else { evenmax += max[i][ix+k]; evencount++; } } echo++; } } } /* end nseg loop */ oddmax /=oddcount; evenmax /=evencount; for (i=0;i<nr;i++) free(max[i]); free(max); sw=*val("sw",&d->p); tepadjust=0.5e6*(oddmax-evenmax)/sw; strcpy(tepfile,vnmrj_path); strcat(tepfile,"tepadjust"); if ((f_out = fopen(tepfile, "w")) == NULL) { fprintf(stderr,"\n%s: %s()\n",__FILE__,__FUNCTION__); fprintf(stderr," Unable to write to %s\n",tepfile); fflush(stderr); return; } fprintf(f_out,"tepadjust %f",tepadjust); fclose(f_out); #ifdef DEBUG rtn=gettimeofday(&tp, NULL); t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; fprintf(stdout,"\n%s: %s()\n",__FILE__,__FUNCTION__); fprintf(stdout," Magnitude data suggests add %f us to value of tep\n",tepadjust); fprintf(stdout," Result written to file %s\n",tepfile); fflush(stdout); #endif break; default: break; } }
void prescanEPI(struct data *d) { int dim1,dim2,dim3,nr; double oversample; int nread; int rampsamp=FALSE,linearsamp=FALSE; setnvolsEPI(d); /* Set the number of data volumes */ d->nv=(int)*val("nphase",&d->p); /* Set d->nv for dimorder2D */ d->pssorder=sliceorder(d,d->ns,"pss"); /* Fill pssorder with the slice order */ d->dim2order=phaseorder(d,d->nv,d->nv,"par_does_not_exist"); /* Set dim2order=-1 for sequential phase encode order */ d->dim3order=phaseorder(d,d->nv,d->nv,"sgepelist"); /* Fill dim3order with the standard gradient echo phase encode order */ d->nv2=d->nv; /* Set d->nv2 for dim3order */ d->nv=(int)*val("nseg",&d->p); /* Use d->nv for the number of shots */ /* Set data dimensions */ dim3=d->endpos-d->startpos; nr=d->nr; /* Check for oversampling */ oversample=*val("oversample",&d->p); if (spar(d,"rampsamp","y")) rampsamp=TRUE; if (spar(d,"linearsamp","y")) linearsamp=TRUE; nread=(int)*val("nread",&d->p)/2; for (d->vol=0;d->vol<d->nvols;d->vol++) { /* loop over "volumes" */ if (interupt) return; /* Interupt/cancel from VnmrJ */ /* Loop over data blocks */ for (d->block=0;d->block<d->nblocks;d->block++) { getblockEPI(d,d->vol,NDCC); /* Get block without applying dbh.lvl and dbh.tlt */ zeromax(d); /* Zero max structure & coordinates of maximum */ zeronoise(d); /* Zero values in noise structure */ setblockEPI(d); /* Set data dimensions */ dim1=d->np/2; dim2=d->nv; if (vnmrj_recon) settep(d,STD); /* If oversampled or ramp and linear sampling, zoom to get the requested matrix size */ if ((oversample==1) && rampsamp && linearsamp) zoomdata2D(d,(dim1-nread)/2,nread,0,dim2); else if ((oversample>1) || (rampsamp && linearsamp)) zoomdata2D(d,(dim1-1.5*nread)/2,1.5*nread,0,dim2); /* Flag the data as IMAGE since magnitude output is combined from multiple receivers */ d->dimstatus[0]+=FFT; /* We always want to view prescan with same orientation so fix it as though it's axial */ setval(&d->p,"psi",180.0); setval(&d->p,"phi",0.0); setval(&d->p,"theta",0.0); w2Dfdfs(d,VJ,FLT32,d->vol); /* Write 2D fdf raw data from volume */ /* Properly flag the data as FID */ d->dimstatus[0]-=FFT; clear2Ddata(d); /* Clear data volume from memory */ setdim(d); /* Reset data dimensions in case data has been zerofilled (sets d->nv=1) */ d->nv=*val("nseg",&d->p); /* Use d->nv for the number of shots */ d->dimstatus[0] = NONE; /* Make sure ZEROFILL status is not set, otherwise setdim will be called in getblock() */ d->dimstatus[1] = NONE; /* Make sure ZEROFILL status is not set, otherwise setdim will be called in getblock() */ } } }