void scale2Ddata(struct data *d,double factor) { int dim1,dim2,dim3,nr; int i,j,k,l; #ifdef DEBUG struct timeval tp; double t1,t2; char function[20]; strcpy(function,"scale2Ddata"); /* Set function name */ fprintf(stdout,"\n%s: %s()\n",SOURCEFILE,function); gettimeofday(&tp, NULL); t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; fflush(stdout); #endif /* Data dimensions */ dim1=d->np/2; dim2=d->nv; dim3=d->endpos-d->startpos; nr=d->nr; /* Scale data */ for (i=0;i<nr;i++) { for (j=0;j<dim3;j++) { for(k=0;k<dim2;k++) { for (l=0;l<dim1;l++) { d->data[i][j][k*dim1+l][0] *=factor; d->data[i][j][k*dim1+l][1] *=factor; } } } } #ifdef DEBUG gettimeofday(&tp, NULL); t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; fprintf(stdout," Data scaled by %f: took %f secs\n",factor,t2-t1); fflush(stdout); #endif /* Zero noise data */ zeronoise(d); }
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() */ } } }
void getnoise2D(struct data *d,int mode) { int dim1,dim2,dim3,nr; double noisefrac; int i,j,k,l; double re,im,M2; int n=0; #ifdef DEBUG struct timeval tp; double t1,t2; char function[20]; strcpy(function,"getnoise2D"); /* Set function name */ fprintf(stdout,"\n%s: %s()\n",SOURCEFILE,function); gettimeofday(&tp, NULL); t1=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; fflush(stdout); #endif /* Data dimensions */ dim1=d->np/2; dim2=d->nv; dim3=d->endpos-d->startpos; nr=d->nr; noisefrac=0.0; switch(mode) { case MK: /* Mask parameters */ switch(d->datamode) { case FID: noisefrac=*val("masknoisefrac",&d->p); if (!noisefrac) noisefrac=Knoisefraction; break; default: noisefrac=*val("masklvlnoisefrac",&d->p); if (!noisefrac) noisefrac=IMnoisefraction; } /* end datamode switch */ break; case SM: /* Sensitivity map parameters */ switch(d->datamode) { case FID: noisefrac=*val("smapnoisefrac",&d->p); if (!noisefrac) noisefrac=Knoisefraction; break; default: noisefrac=*val("masklvlnoisefrac",&d->p); if (!noisefrac) noisefrac=IMnoisefraction; } /* end datamode switch */ break; default: /* Default parameters */ switch(d->datamode) { case FID: noisefrac=Knoisefraction; break; default: noisefrac=IMnoisefraction; } /* end datamode switch */ } /* end mode switch */ zeronoise(d); for (i=0;i<nr;i++) { n=0; if (((d->datamode == FID) && d->shift) || ((d->datamode == IMAGE) && !d->shift)) { /* For shifted FID and not-shifted IMAGE the noise is at centre */ for (j=0;j<dim3;j++) { for(k=dim2/2-dim2*noisefrac/2;k<dim2/2+dim2*noisefrac/2;k++) { for (l=dim1/2-dim1*noisefrac/2;l<dim1/2+dim1*noisefrac/2;l++) { re=d->data[i][j][k*dim1+l][0]; im=d->data[i][j][k*dim1+l][1]; M2=re*re+im*im; d->noise.M[i]+=sqrt(M2); d->noise.M2[i]+=M2; d->noise.Re[i]+=fabs(re); d->noise.Im[i]+=fabs(im); n++; } } } } else { /* For not shifted FID and shifted IMAGE the noise is at edges */ for (j=0;j<dim3;j++) { for(k=0;k<dim2*noisefrac/2;k++) { for (l=0;l<dim1*noisefrac/2;l++) { re=d->data[i][j][k*dim1+l][0]; im=d->data[i][j][k*dim1+l][1]; M2=re*re+im*im; d->noise.M[i]+=sqrt(M2); d->noise.M2[i]+=M2; d->noise.Re[i]+=fabs(re); d->noise.Im[i]+=fabs(im); n++; } for (l=dim1-dim1*noisefrac/2;l<dim1;l++) { re=d->data[i][j][k*dim1+l][0]; im=d->data[i][j][k*dim1+l][1]; M2=re*re+im*im; d->noise.M[i]+=sqrt(M2); d->noise.M2[i]+=M2; d->noise.Re[i]+=fabs(re); d->noise.Im[i]+=fabs(im); n++; } } for(k=dim2-dim2*noisefrac/2;k<dim2;k++) { for (l=0;l<dim1*noisefrac/2;l++) { re=d->data[i][j][k*dim1+l][0]; im=d->data[i][j][k*dim1+l][1]; M2=re*re+im*im; d->noise.M[i]+=sqrt(M2); d->noise.M2[i]+=M2; d->noise.Re[i]+=fabs(re); d->noise.Im[i]+=fabs(im); n++; } for (l=dim1-dim1*noisefrac/2;l<dim1;l++) { re=d->data[i][j][k*dim1+l][0]; im=d->data[i][j][k*dim1+l][1]; M2=re*re+im*im; d->noise.M[i]+=sqrt(M2); d->noise.M2[i]+=M2; d->noise.Re[i]+=fabs(re); d->noise.Im[i]+=fabs(im); n++; } } } } /* calculate the mean */ d->noise.M[i] /=n; d->noise.M2[i] /=n; /* For Real and Imaginary we must consider console type. The DDR in VNMRS produces equal noise Re and Im channels - no quad images */ if (!(strcmp(*sval("console",&d->p),"vnmrs"))) { /* VNMRS */ d->noise.Re[i] += d->noise.Im[i]; d->noise.Re[i] /=2.0; d->noise.Im[i] = d->noise.Re[i]; } d->noise.Re[i] /=n; d->noise.Im[i] /=n; } /* Now average over all receivers */ for (i=0;i<nr;i++) { d->noise.avM += d->noise.M[i]; d->noise.avM2 += d->noise.M2[i]; d->noise.avRe += d->noise.Re[i]; d->noise.avIm += d->noise.Im[i]; } d->noise.avM /=nr; d->noise.avM2 /=nr; d->noise.avRe /=nr; d->noise.avIm /=nr; /* Set data flag */ d->noise.data=TRUE; #ifdef DEBUG gettimeofday(&tp, NULL); t2=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; fprintf(stdout," Noise data averaged over %d points: took %f secs\n",n,t2-t1); for (i=0;i<nr;i++) { fprintf(stdout," Receiver %d: M = %.3f, M2 = %.3f, Re = %.3f, Im = %.3f\n", i,d->noise.M[i],d->noise.M2[i],d->noise.Re[i],d->noise.Im[i]); } fprintf(stdout," Average: M = %.3f, M2 = %.3f, Re = %.3f, Im = %.3f\n", d->noise.avM,d->noise.avM2,d->noise.avRe,d->noise.avIm); fflush(stdout); #endif }