static MRI_IMAGE * mri_make_xxt( MRI_IMAGE *fim ) { MRI_IMAGE *aim ; int nn , mm , n1 ; float *xx ; if( fim == NULL || fim->kind != MRI_float ) return NULL ; nn = fim->nx ; mm = fim->ny ; if( nn < mm || mm < 2 ) return NULL ; xx = MRI_FLOAT_PTR(fim) ; if( xx == NULL ) return NULL ; n1 = nn-1 ; aim = mri_new( mm , mm , MRI_double ) ; asym = MRI_DOUBLE_PTR(aim) ; /** setup m x m [A] = [X]'[X] matrix to eigensolve **/ AFNI_OMP_START ; #pragma omp parallel if( mm > 7 && nn > 999 ) { int jj , kk , ii ; register double sum ; register float *xj,*xk ; #pragma omp for for( jj=0 ; jj < mm ; jj++ ){ xj = xx + jj*nn ; /* j-th column */ for( kk=0 ; kk <= jj ; kk++ ){ sum = 0.0 ; xk = xx + kk*nn ; /* k-th column */ for( ii=0 ; ii < n1 ; ii+=2 ) sum += xj[ii]*xk[ii] + xj[ii+1]*xk[ii+1]; if( ii == n1 ) sum += xj[ii]*xk[ii] ; A(jj,kk) = sum ; if( kk < jj ) A(kk,jj) = sum ; } } } /* end OpenMP */ AFNI_OMP_END ; return aim ; }
MRI_IMAGE * mri_bport_contig( float dt , float fbot , float ftop , int ntime , int nbefore , int nafter ) { MRI_IMAGE *fim ; float *far , *fii , *fip ; int nfbot , nftop , ff , ii,jj , nev=(ntime%2==0) , ncol,nrow ; float df , freq ; ENTRY("mri_bport_contig") ; if( dt <= 0.0f ) dt = 1.0f ; if( fbot < 0.0f ) fbot = 0.0f ; if( ntime < 9 || ftop < fbot ) RETURN(NULL) ; if( nbefore < 0 ) nbefore = 0 ; if( nafter < 0 ) nafter = 0 ; df = 1.0f / (ntime * dt) ; /* frequency spacing */ nfbot = (int)rintf(fbot/df+0.1666666f) ; if( nfbot > ntime/2 ) nfbot = ntime/2 ; if( nfbot < BP_ffbot ) nfbot = BP_ffbot ; nftop = (int)rintf(ftop/df-0.1666666f) ; if( nftop < nfbot ) nftop = nfbot ; if( nftop > ntime/2 ) nftop = ntime/2 ; #if 1 ININFO_message("Frequency indexes: blocklen=%d nfbot=%d nftop=%d",ntime,nfbot,nftop) ; #endif ncol = 2*(nftop-nfbot-1) ; if( ncol < 0 ) ncol = 0 ; ncol += (nfbot == 0 || (nfbot == ntime/2 && nev==1) ) ? 1 : 2 ; if( nftop > nfbot ) ncol += (nftop == ntime/2 && nev) ? 1 : 2 ; if( ncol <= 0 ){ ININFO_message("Failure :-(") ; RETURN(NULL) ; /* should never happen */ } nrow = ntime + nbefore + nafter ; fim = mri_new( nrow , ncol , MRI_float ) ; far = MRI_FLOAT_PTR(fim) ; for( ii=0,ff=nfbot ; ff <= nftop ; ff++ ){ fii = far + (ii*nrow + nbefore) ; if( ff == 0 ){ for( jj=0 ; jj < ntime ; jj++ ) fii[jj] = 1.0f ; ii++ ; } else if( ff == ntime/2 && nev ){ for( jj=0 ; jj < ntime ; jj++ ) fii[jj] = 2*(jj%2)-1 ; ii++ ; } else { fip = fii + nrow ; freq = ff*df * (2.0f*3.141593f) * dt ; for( jj=0 ; jj < ntime ; jj++ ){ fii[jj] = cos(freq*jj) ; fip[jj] = sin(freq*jj) ; } ii += 2 ; } } RETURN(fim) ; }
MRI_IMAGE * PH_fakeim( int nx , int ny , int code , float val ) { MRI_IMAGE * im ; float * far ; int ii , nvox ; im = mri_new( nx , ny , MRI_float ) ; far = MRI_FLOAT_PTR(im) ; nvox = im->nvox ; #if 0 fprintf(stderr,"PH_fakeim: code=%d val=%f\n",code,val) ; #endif switch( code ){ default: case CONST: for( ii=0 ; ii < nvox ; ii++ ) far[ii] = val ; break ; case NOISE: for( ii=0 ; ii < nvox ; ii++ ) far[ii] = val * drand48() ; break ; } return im ; }
MRI_IMAGE * mri_colorsetup( int ngray , int nrr , int ngg , int nbb ) { MRI_IMAGE *im ; rgbyte *ar ; int rr,gg,bb , nn ; float rac,gac,bac ; im = mri_new( ngray + nrr*ngg*nbb - 1 , 1 , MRI_rgb ) ; ar = (rgbyte *) MRI_RGB_PTR(im) ; gac = 255.9f / ngray ; nn = 0 ; /* actually, ngray+1 levels */ for( gg=0 ; gg <= ngray ; gg++,nn++ ){ ar[nn].r = ar[nn].g = ar[nn].b = (byte)(gac*gg) ; } rac = 255.9f/(nrr-1) ; gac = 255.9f/(ngg-1) ; bac=255.9f/(nbb-1) ; for( bb=0 ; bb < nbb ; bb++ ){ /* skip the all black and */ for( gg=0 ; gg < ngg ; gg++ ){ /* the all white colors */ for( rr=0 ; rr < nrr ; rr++ ){ if( rr==0 && gg==0 && bb==0 ) continue ; if( rr==nrr-1 && gg==ngg-1 && bb==nbb-1 ) continue ; ar[nn].r = (byte)(rac*rr) ; ar[nn].g = (byte)(gac*gg) ; ar[nn].b = (byte)(bac*bb) ; nn++ ; } } } return im ; }
MRI_IMAGE * mri_fft2D( MRI_IMAGE * im , int mode ) { MRI_IMAGE * cxim , * outim ; int nx,ny , nxup,nyup , ii,jj ; complex * cxar , * outar , * cpt , * opt ; float fac ; if( im == NULL ) return NULL ; /* convert input to complex */ cxim = mri_to_complex(im) ; cxar = MRI_COMPLEX_PTR(cxim) ; /* compute size of output */ nx = cxim->nx ; nxup = csfft_nextup_even(nx) ; ny = cxim->ny ; nyup = csfft_nextup_even(ny) ; /* create output array */ outim = mri_new( nxup , nyup , MRI_complex ) ; outar = MRI_COMPLEX_PTR(outim) ; /* copy input to output, zero padding along the way */ opt = outar ; cpt = cxar ; for( jj=0 ; jj < ny ; jj++ ){ for( ii=0 ; ii < nx ; ii++ ){opt->r=cpt->r; opt->i=cpt->i; opt++; cpt++;} for( ; ii < nxup ; ii++ ){opt->r=opt->i=0.0; opt++;} } for( ; jj < nyup ; jj++ ){opt->r=opt->i=0.0; opt++;} mri_free(cxim) ; /* row FFTs */ for( jj=0 ; jj < ny ; jj++ ) csfft_cox( mode , nxup , outar+jj*nxup ) ; /* column FFTs */ cxar = (complex *) malloc(sizeof(complex)*nyup) ; for( ii=0 ; ii < nxup ; ii++ ){ for( jj=0 ; jj < nyup ; jj++ ) cxar[jj] = outar[ii+jj*nxup] ; csfft_cox( mode , nyup , cxar ) ; for( jj=0 ; jj < nyup ; jj++ ) outar[ii+jj*nxup] = cxar[jj] ; } fac = sqrt(1.0/(nxup*nyup)) ; for( ii=0 ; ii < nxup*nyup ; ii++ ){ outar[ii].r *= fac ; outar[ii].i *= fac ; } free(cxar) ; return outim ; }
MRI_IMAGE * mri_genARMA11( int nlen, int nvec, float ap, float lm, float sg ) { int kk,ii , do_rcmat ; double aa=ap, lam=lm , sig=sg ; int do_norm = (sg<=0.0f) ; double *rvec ; rcmat *rcm=NULL ; MRI_IMAGE *outim ; float *outar , *vv ; #if 0 long seed=0 ; seed = (long)time(NULL)+(long)getpid() ; srand48(seed) ; #endif ENTRY("mri_genARMA11") ; if( nlen <= 3 ){ ERROR_message("ARMA11 nlen < 4"); RETURN(NULL); } if( fabs(aa) >= 0.98 ){ ERROR_message("ARMA11 a too big"); RETURN(NULL); } if( fabs(lam) >= 0.97 ){ ERROR_message("ARMA11 lam too big"); RETURN(NULL); } do_rcmat = ( lam != 0.0 ) ; /* setup */ if( do_rcmat ){ rcm = rcmat_arma11( nlen , NULL , aa , lam ) ; if( rcm == NULL ){ ERROR_message("Can't setup ARMA11 matrix?!"); RETURN(NULL); } kk = rcmat_choleski( rcm ) ; if( kk > 0 ){ ERROR_message("ARMA11 Choleski fails at row %d",kk); RETURN(NULL); } } /* simulate */ outim = mri_new( nlen , nvec , MRI_float ) ; outar = MRI_FLOAT_PTR(outim) ; rvec = (double *)malloc(sizeof(double)*nlen) ; for( kk=0 ; kk < nvec ; kk++ ){ for( ii=0 ; ii < nlen ; ii++ ) rvec[ii] = zgaussian() ; if( do_rcmat ) rcmat_lowert_vecmul( rcm , rvec ) ; vv = outar + kk*nlen ; if( do_norm ){ sig = 0.0 ; for( ii=0 ; ii < nlen ; ii++ ) sig += rvec[ii]*rvec[ii] ; sig = 1.0 / sqrt(sig) ; } if( sig != 1.0 ){ for( ii=0 ; ii < nlen ; ii++ ) vv[ii] = sig * rvec[ii]; } } free(rvec) ; if( do_rcmat ) rcmat_destroy(rcm) ; RETURN(outim) ; }
MRI_IMAGE * CORMAT_fetch(void) { MRI_IMAGE *cim ; float *car ; int ii ; if( maxlag <= 0 || cor == NULL ) return NULL ; cim = mri_new(maxlag,1,MRI_float) ; car = MRI_FLOAT_PTR(cim) ; for( ii=0 ; ii < maxlag ; ii++ ) if( ncor[ii] > 0 ) car[ii] = cor[ii] / ncor[ii] ; return cim ; }
MRI_IMARR * LSS_mangle_matrix( MRI_IMAGE *ima, int jbot, int jtop ) { int ii , jj , jnew , jn , njj , nn,mm ; MRI_IMAGE *imb , *imc ; MRI_IMARR *imar ; float *aa , *bb , *cc , *acol , *bcol , *ccol ; ENTRY("LSS_mangle_matrix") ; if( ima == NULL || ima->kind != MRI_float ) RETURN(NULL) ; nn = ima->nx ; mm = ima->ny ; njj = jtop-jbot+1 ; if( njj <= 1 ) RETURN(NULL) ; if( jbot < 0 || jtop >= mm ) RETURN(NULL) ; imb = mri_new( nn , mm-njj+1 , MRI_float ) ; /* matrix without jbot..jtop */ imc = mri_new( nn , njj , MRI_float ) ; /* matrix with jbot..jtop */ aa = MRI_FLOAT_PTR(ima) ; bb = MRI_FLOAT_PTR(imb) ; cc = MRI_FLOAT_PTR(imc) ; /* copy non-excised columns into the new imb */ for( jn=jj=0 ; jj < mm ; jj++ ){ if( jj >= jbot && jj <= jtop ) continue ; acol = aa + jj*nn ; /* jj = old column index */ bcol = bb + jn*nn ; jn++ ; /* jn = new column index */ for( ii=0 ; ii < nn ; ii++ ) bcol[ii] = acol[ii] ; } /* copy excised columns into the new imc, and also add them up into the last column of imb */ bcol = bb + (mm-njj)*nn ; /* last col of imb */ for( jn=0,jj=jbot ; jj <= jtop ; jj++ ){ acol = aa + jj*nn ; ccol = cc + jn*nn ; jn++ ; for( ii=0 ; ii < nn ; ii++ ){ ccol[ii] = acol[ii] ; bcol[ii] += acol[ii] ; } } INIT_IMARR(imar) ; ADDTO_IMARR(imar,imb) ; ADDTO_IMARR(imar,imc) ; RETURN(imar) ; }
/* Implementation Note: Some of the calculations in the loops can be factored out, but I choose not to for clarity. This is all O(N) in the number of timepoints anyways (I think). */ MRI_IMAGE * RIC_ToCardiacPhase(MRI_IMAGE * card, float threshold) { int numSamps; /* Number of samples in vector */ MRI_IMAGE * cardphase; /* The cardiac phase vector to return */ float * cpdata; /* Pointer to cardiac phase vector data */ float * cdata; /* Pointer to cardiac vector data */ double twoPI = 2 * M_PI; /* 2 * PI (intermediate value for calculation) */ double twoPI_t2_t1; /* 2 * PI / (t_2 - t_1) (intermediate value) */ double phase; /* card phase: 2 * PI / (t_2 - t_1) * (t - t_1) */ int lastpeakpt = 0; /* The last cdata timepoint searched for a peak */ int t = 0; /* The current time */ int t_1 = 0; /* The previous cardiac peak time */ int t_2; /* The next cardiac peak time */ /* Quick check of arguments */ if (card == NULL || card->nx < 2 || card->kind != MRI_float) { return NULL; } /* Initialize */ numSamps = card->nx; cardphase = mri_new(numSamps, 1, MRI_float); cpdata = MRI_FLOAT_PTR(cardphase); cdata = MRI_FLOAT_PTR(card); /* Iterate over the cardiac peaks, assuming data start is peak */ while (_RIC_findNextCardiacPeak(cdata, numSamps, lastpeakpt, &t_2, &lastpeakpt, threshold) == 0) { /* Fill in the cardiac phase values between peaks */ twoPI_t2_t1 = twoPI / (t_2 - t_1); phase = 0.0; /* Since we always have t == t_1 at this point) */ for ( ; t < t_2; t += 1) { cpdata[t] = phase; phase += twoPI_t2_t1; } t_1 = t_2; } /* Fill in any remaining phase values, assuming end of data is peak */ twoPI_t2_t1 = twoPI / (numSamps - t_1); phase = 0.0; for ( ; t < numSamps; t += 1) { cpdata[t] = phase; phase += twoPI_t2_t1; } return cardphase; }
int main( int argc , char * argv[] ) { MRI_IMAGE * imbar , * imsdev , * imwt ; int ii , nvox , nsum ; float * bar , * sdev , * wt ; float bmax , smax , bcut , scl , bsum ; float hist[11] ; if( argc < 4 ){ printf("Usage: %s mean_image sdev_image wt_image\n",argv[0]) ; exit(0) ; } imbar = mri_read_just_one( argv[1] ) ; if( imbar == NULL ) exit(1) ; imsdev = mri_read_just_one( argv[2] ) ; if( imsdev== NULL ) exit(1) ; if( imbar->kind != MRI_float ){ imwt = mri_to_float(imbar) ; mri_free(imbar) ; imbar = imwt ; } if( imsdev->kind != MRI_float ){ imwt = mri_to_float(imsdev) ; mri_free(imsdev) ; imsdev = imwt ; } nvox = imbar->nvox ; imwt = mri_new( imbar->nx , imbar->ny , MRI_float ) ; bar = MRI_FLOAT_PTR(imbar) ; sdev = MRI_FLOAT_PTR(imsdev) ; wt = MRI_FLOAT_PTR(imwt) ; bcut = 0.05 * mri_maxabs(imbar) ; bsum = 0.0 ; nsum = 0 ; for( ii=0 ; ii < nvox ; ii++ ){ if( bar[ii] > bcut ){ bsum += bar[ii] ; nsum++ ; } } bcut = 0.25 * bsum / nsum ; smax = mri_maxabs(imsdev) ; scl = 0.25 * bcut*bcut ; printf("cutoff value = %f\n",bcut) ; for( ii=0 ; ii < nvox ; ii++ ){ if( bar[ii] < bcut || sdev[ii] <= 0.0 ) wt[ii] = 0.0 ; else wt[ii] = scl / SQR(sdev[ii]) ; } mri_write( argv[3] , imwt ) ; exit(0) ; }
MRI_IMAGE * DES_get_psinv( int ntim , int nref , float **ref ) { MRI_IMAGE *refim , *psinv ; float *refar , *jar ; int ii , jj ; refim = mri_new(ntim,nref,MRI_float) ; refar = MRI_FLOAT_PTR(refim) ; for( jj=0 ; jj < nref ; jj++ ){ jar = refar + jj*ntim ; for( ii=0 ; ii < ntim ; ii++ ) jar[ii] = ref[jj][ii] ; } mri_matrix_psinv_svd(1) ; psinv = mri_matrix_psinv(refim,NULL,0.0f) ; mri_free(refim) ; return psinv ; }
MRI_IMAGE * THD_dset_to_1Dmri( THD_3dim_dataset *dset ) { MRI_IMAGE *im ; float *far ; int nx , ny , ii ; ENTRY("THD_dset_to_1D") ; if( !ISVALID_DSET(dset) ) RETURN(NULL) ; DSET_load(dset) ; if( !DSET_LOADED(dset) ) RETURN(NULL) ; nx = DSET_NVALS(dset) ; ny = DSET_NVOX(dset) ; im = mri_new( nx , ny , MRI_float ) ; far = MRI_FLOAT_PTR(im) ; for( ii=0 ; ii < ny ; ii++ ) THD_extract_array( ii , dset , 0 , far + ii*nx ) ; RETURN(im) ; }
MRI_IMAGE * mri_make_rainbow( int nx , int ny , int ncol , rgbyte *col ) { MRI_IMAGE *bim ; byte *bar ; int ii,jj , pp ; float qq,rr ; if( ncol < 2 || col == NULL ) return NULL ; if( nx < 1 ) nx = 8 ; if( ny < 2*ncol ) ny = 2*ncol ; bim = mri_new(nx,ny,MRI_rgb) ; bar = MRI_RGB_PTR(bim) ; for( jj=0 ; jj < ny ; jj++ ){ qq = jj*(ncol-1.001f)/(ny-1.0f) ; pp = (int)qq ; qq = qq-pp ; rr = 1.0f-qq ; for( ii=0 ; ii < nx ; ii++ ){ bar[3*(ii+jj*nx)+0] = (byte)( rr*col[pp].r + qq*col[pp+1].r ) ; bar[3*(ii+jj*nx)+1] = (byte)( rr*col[pp].g + qq*col[pp+1].g ) ; bar[3*(ii+jj*nx)+2] = (byte)( rr*col[pp].b + qq*col[pp+1].b ) ; } } return bim ; }
MRI_IMAGE * mri_transpose_byte( MRI_IMAGE * im ) { MRI_IMAGE * om ; byte * iar , * oar ; int ii,jj,nx,ny ; ENTRY("mri_transpose_byte") ; if( im == NULL || im->kind != MRI_byte ) RETURN(NULL) ; nx = im->nx ; ny = im->ny ; om = mri_new( ny , nx , MRI_byte ) ; iar = MRI_BYTE_PTR(im) ; oar = MRI_BYTE_PTR(om) ; for( jj=0 ; jj < ny ; jj++ ) for( ii=0 ; ii < nx ; ii++ ) oar[jj+ii*ny] = iar[ii+jj*nx] ; MRI_COPY_AUX(om,im) ; RETURN(om) ; }
MRI_IMAGE * mri_jointhist( MRI_IMAGE *imp , MRI_IMAGE *imq , byte *mmm ) { int nvox , nmmm=0 ; float *rst ; byte *par, *qar ; float fac ; register int ii,jj,kk ; MRI_IMAGE *imqq, *impp , *imh ; if( imp == NULL || imq == NULL || imp->nvox != imq->nvox ) return NULL; nvox = imp->nvox ; impp = (imp->kind==MRI_byte) ? imp : mri_to_byte(imp) ; imqq = (imq->kind==MRI_byte) ? imq : mri_to_byte(imq) ; par = MRI_BYTE_PTR(impp) ; qar = MRI_BYTE_PTR(imqq) ; imh = mri_new( 256,256,MRI_float ) ; rst = MRI_FLOAT_PTR(imh) ; if( mmm != NULL ){ for( kk=0 ; kk < nvox ; kk++ ) if( mmm[kk] ) nmmm++ ; fac = 1.0f / nmmm ; for( kk=0 ; kk < nvox ; kk++ ){ if( mmm[kk] == 0 ) continue ; ii = par[kk] ; jj = qar[kk] ; rst[ii+256*jj] += fac ; } } else { fac = 1.0f / nvox ; for( kk=0 ; kk < nvox ; kk++ ){ ii = par[kk] ; jj = qar[kk] ; rst[ii+256*jj] += fac ; } } if( impp != imp ) mri_free(impp) ; if( imqq != imq ) mri_free(imqq) ; return imh ; }
MRI_IMAGE * THD_extract_series( int ind , THD_3dim_dataset *dset , int raw ) { int nv , typ , ii ; MRI_IMAGE *im ; void *imar ; ENTRY("THD_extract_series") ; if( !ISVALID_DSET(dset) ) RETURN(NULL) ; nv = dset->dblk->nvals ; if( raw ) typ = DSET_BRICK_TYPE(dset,0) ; /* type of output array */ else typ = MRI_float ; im = mri_new( nv , 1 , typ ) ; /* output image */ imar = mri_data_pointer(im) ; ii = THD_extract_array( ind , dset , raw , imar ) ; /* get data */ if( ii != 0 ){ mri_free(im) ; RETURN(NULL) ; } /* bad */ if( dset->taxis != NULL ){ /* 21 Oct 1996 */ float zz , tt ; int kz = ind / ( dset->daxes->nxx * dset->daxes->nyy ) ; zz = dset->daxes->zzorg + kz * dset->daxes->zzdel ; tt = THD_timeof( 0 , zz , dset->taxis ) ; im->xo = tt ; im->dx = dset->taxis->ttdel ; /* origin and delta */ if( dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */ im->xo *= 0.001 ; im->dx *= 0.001 ; } } else { im->xo = 0.0 ; im->dx = 1.0 ; /* 08 Nov 1996 */ } RETURN(im) ; }
static MRI_IMAGE * mri_dup2D_rgb_NN( MRI_IMAGE *inim, int nup ) { rgbyte *bin , *bout , *bin1 ; MRI_IMAGE *outim ; int ii,jj,kk,ll , nx,ny , nxup,nyup ; ENTRY("mri_dup2D_rgb_NN") ; if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL); bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL); /* make output image **/ nx = inim->nx ; ny = inim->ny ; nxup = nup*nx ; nyup = nup*ny ; outim = mri_new( nxup , nyup , MRI_rgb ) ; bout = (rgbyte *) MRI_RGB_PTR(outim) ; for( jj=0 ; jj < ny ; jj++ ){ /* loop over input rows */ for ( kk= 0; kk < nup; kk++ ) { /* do rows nup times */ bin1 = bin; for( ii=0 ; ii < nx ; ii++ ){ for ( ll= 0; ll < nup; ll++ ) { *bout++ = *bin1; } bin1++; } } bin += nx ; } MRI_COPY_AUX(outim,inim) ; RETURN(outim) ; }
MRI_IMAGE * mri_extract_from_mask( MRI_IMAGE *imin , byte *mask , int invert ) { byte bmmm = (invert == 0) ? 1 : 0 ; int ii,jj , ngood , nvox ; float *iar , *oar ; MRI_IMAGE *outim ; ENTRY("mri_extract_mask") ; if( imin == NULL || mask == NULL ) RETURN(NULL) ; /* bad user == luser */ /*-- not float? create a float image and recurse! --*/ if( imin->kind != MRI_float ){ MRI_IMAGE *qim = mri_to_float(imin) ; outim = mri_extract_from_mask( qim , mask , invert ) ; mri_free(qim) ; RETURN(outim) ; } /*-- count up the good voxels --*/ nvox = imin->nvox ; for( ngood=ii=0 ; ii < nvox ; ii++ ) if( GOOD(ii) ) ngood++ ; if( ngood == 0 ) RETURN(NULL) ; /*-- create the output --*/ outim = mri_new( ngood , 1 , MRI_float ) ; oar = MRI_FLOAT_PTR(outim) ; iar = MRI_FLOAT_PTR(imin) ; /*-- fill the output --*/ for( jj=ii=0 ; ii < nvox ; ii++ ) if( GOOD(ii) ) oar[jj++] = iar[ii] ; RETURN(outim) ; }
static MRI_IMAGE * mri_warp3D_align_fitim( MRI_warp3D_align_basis *bas , MRI_IMAGE *cim , int warp_mode , float delfac ) { MRI_IMAGE *fitim , *pim , *mim ; float *fitar , *car=MRI_FLOAT_PTR(cim) ; int nfree=bas->nfree , *ima=MRI_INT_PTR(bas->imap) , nmap=bas->imap->nx ; int npar =bas->nparam ; float *pvec , *par , *mar ; int ii , pp , cc ; float dpar , delta ; /*-- create image containing basis columns --*/ fitim = mri_new( nmap , nfree+1 , MRI_float ) ; fitar = MRI_FLOAT_PTR(fitim) ; pvec = (float *)malloc(sizeof(float) * npar) ; #undef FMAT #define FMAT(i,j) fitar[(i)+(j)*nmap] /* col dim=nmap, row dim=nfree+1 */ /* column #nfree = base image itself */ for( ii=0 ; ii < nmap ; ii++ ) FMAT(ii,nfree) = car[ima[ii]] ; pvec = (float *)malloc(sizeof(float) * npar) ; /* for each free parameter: apply inverse transform to base image with param value up and down compute central difference to approximate derivative of base image wrt parameter store as a column in the fitim matrix */ mri_warp3D_method( warp_mode ) ; /* set interpolation mode */ mri_warp3D_set_womask( bas->imsk ) ; for( pp=0,cc=0 ; pp < npar ; pp++ ){ if( bas->param[pp].fixed ) continue ; /* don't do this one! */ /* init all params to their identity transform value */ for( ii=0 ; ii < npar ; ii++ ) pvec[ii] = (bas->param[ii].fixed) ? bas->param[ii].val_fixed : bas->param[ii].ident ; /* change in the pp-th parameter to use for derivative */ dpar = delfac * bas->param[pp].delta ; if( bas->verb ) fprintf(stderr,"+ difference base by %f in param#%d [%s]\n", dpar , pp+1 , bas->param[pp].name ) ; pvec[pp] = bas->param[pp].ident + dpar ; /* set positive change */ bas->vwset( npar , pvec ) ; /* put into transform */ pim = mri_warp3D( cim , 0,0,0 , bas->vwinv ) ; /* warp image */ pvec[pp] = bas->param[pp].ident - dpar ; /* set negative change */ bas->vwset( npar , pvec ) ; mim = mri_warp3D( cim , 0,0,0 , bas->vwinv ) ; /* compute derivative */ delta = bas->scale_init / ( 2.0f * dpar ) ; par = MRI_FLOAT_PTR(pim) ; mar = MRI_FLOAT_PTR(mim) ; for( ii=0 ; ii < nmap ; ii++ ) FMAT(ii,cc) = delta * ( par[ima[ii]] - mar[ima[ii]] ) ; #if 0 { float psum=0.0f,msum=0.0f,dsum=0.0f; for( ii=0 ; ii < nmap ; ii++ ){ psum += fabsf(par[ima[ii]]) ; msum += fabsf(mar[ima[ii]]) ; dsum += fabsf(FMAT(ii,cc)) ; } fprintf(stderr," pp=%d psum=%g msum=%g dsum=%g\n",pp,psum,msum,dsum) ; } #endif mri_free(pim) ; mri_free(mim) ; /* no longer needed */ cc++ ; /* oopsie */ } mri_warp3D_set_womask( NULL ) ; free((void *)pvec) ; #if 0 { int zz , jj ; for( jj=0 ; jj <= nfree ; jj++ ){ zz = 0 ; for( ii=0 ; ii < nmap ; ii++ ) if( FMAT(ii,jj) == 0.0 ) zz++ ; fprintf(stderr," fitim: col#%d has %d zeros out of %d\n",jj,zz,nmap) ; } } #endif return(fitim) ; }
static MRI_IMAGE * mri_psinv( MRI_IMAGE *imc , float *wt ) { float *rmat=MRI_FLOAT_PTR(imc) ; int m=imc->nx , n=imc->ny , ii,jj,kk ; double *amat , *umat , *vmat , *sval , *xfac , smax,del,ww ; MRI_IMAGE *imp ; float *pmat ; register double sum ; int do_svd=0 ; amat = (double *)calloc( sizeof(double),m*n ) ; /* input matrix */ xfac = (double *)calloc( sizeof(double),n ) ; /* column norms of [a] */ #define R(i,j) rmat[(i)+(j)*m] /* i=0..m-1 , j=0..n-1 */ #define A(i,j) amat[(i)+(j)*m] /* i=0..m-1 , j=0..n-1 */ #define P(i,j) pmat[(i)+(j)*n] /* i=0..n-1 , j=0..m-1 */ /* copy input matrix (float) into amat (double) */ for( ii=0 ; ii < m ; ii++ ) for( jj=0 ; jj < n ; jj++ ) A(ii,jj) = R(ii,jj) ; /* weight rows? */ if( wt != NULL ){ for( ii=0 ; ii < m ; ii++ ){ ww = wt[ii] ; if( ww > 0.0 ) for( jj=0 ; jj < n ; jj++ ) A(ii,jj) *= ww ; } } /* scale each column to have norm 1 */ for( jj=0 ; jj < n ; jj++ ){ sum = 0.0 ; for( ii=0 ; ii < m ; ii++ ) sum += A(ii,jj)*A(ii,jj) ; if( sum > 0.0 ) sum = 1.0/sqrt(sum) ; else { do_svd = 1 ; ERROR_message("mri_psinv[%d]=0\n",jj);} xfac[jj] = sum ; for( ii=0 ; ii < m ; ii++ ) A(ii,jj) *= sum ; } /*** compute using Choleski or SVD ***/ if( do_svd || AFNI_yesenv("AFNI_WARPDRIVE_SVD") ){ /***--- SVD method ---***/ #define U(i,j) umat[(i)+(j)*m] #define V(i,j) vmat[(i)+(j)*n] umat = (double *)calloc( sizeof(double),m*n ); /* left singular vectors */ vmat = (double *)calloc( sizeof(double),n*n ); /* right singular vectors */ sval = (double *)calloc( sizeof(double),n ); /* singular values */ /* compute SVD of scaled matrix */ svd_double( m , n , amat , sval , umat , vmat ) ; free((void *)amat) ; /* done with this */ /* find largest singular value */ smax = sval[0] ; for( ii=1 ; ii < n ; ii++ ) if( sval[ii] > smax ) smax = sval[ii] ; if( smax <= 0.0 ){ /* this is bad */ ERROR_message("SVD fails in mri_warp3D_align_setup!\n"); free((void *)xfac); free((void *)sval); free((void *)vmat); free((void *)umat); return NULL; } for( ii=0 ; ii < n ; ii++ ) if( sval[ii] < 0.0 ) sval[ii] = 0.0 ; /* should not happen */ #define PSINV_EPS 1.e-8 /* "reciprocals" of singular values: 1/s is actually s/(s^2+del) */ del = PSINV_EPS * smax*smax ; for( ii=0 ; ii < n ; ii++ ) sval[ii] = sval[ii] / ( sval[ii]*sval[ii] + del ) ; /* create pseudo-inverse */ imp = mri_new( n , m , MRI_float ) ; /* recall that m > n */ pmat = MRI_FLOAT_PTR(imp) ; for( ii=0 ; ii < n ; ii++ ){ for( jj=0 ; jj < m ; jj++ ){ sum = 0.0 ; for( kk=0 ; kk < n ; kk++ ) sum += sval[kk] * V(ii,kk) * U(jj,kk) ; P(ii,jj) = (float)sum ; } } free((void *)sval); free((void *)vmat); free((void *)umat); } else { /***----- Choleski method -----***/ vmat = (double *)calloc( sizeof(double),n*n ); /* normal matrix */ for( ii=0 ; ii < n ; ii++ ){ for( jj=0 ; jj <= ii ; jj++ ){ sum = 0.0 ; for( kk=0 ; kk < m ; kk++ ) sum += A(kk,ii) * A(kk,jj) ; V(ii,jj) = sum ; } V(ii,ii) += PSINV_EPS ; /* note V(ii,ii)==1 before this */ } /* Choleski factor */ for( ii=0 ; ii < n ; ii++ ){ for( jj=0 ; jj < ii ; jj++ ){ sum = V(ii,jj) ; for( kk=0 ; kk < jj ; kk++ ) sum -= V(ii,kk) * V(jj,kk) ; V(ii,jj) = sum / V(jj,jj) ; } sum = V(ii,ii) ; for( kk=0 ; kk < ii ; kk++ ) sum -= V(ii,kk) * V(ii,kk) ; if( sum <= 0.0 ){ ERROR_message("Choleski fails in mri_warp3D_align_setup!\n"); free((void *)xfac); free((void *)amat); free((void *)vmat); return NULL ; } V(ii,ii) = sqrt(sum) ; } /* create pseudo-inverse */ imp = mri_new( n , m , MRI_float ) ; /* recall that m > n */ pmat = MRI_FLOAT_PTR(imp) ; sval = (double *)calloc( sizeof(double),n ) ; /* row #jj of A */ for( jj=0 ; jj < m ; jj++ ){ for( ii=0 ; ii < n ; ii++ ) sval[ii] = A(jj,ii) ; /* extract row */ for( ii=0 ; ii < n ; ii++ ){ /* forward solve */ sum = sval[ii] ; for( kk=0 ; kk < ii ; kk++ ) sum -= V(ii,kk) * sval[kk] ; sval[ii] = sum / V(ii,ii) ; } for( ii=n-1 ; ii >= 0 ; ii-- ){ /* backward solve */ sum = sval[ii] ; for( kk=ii+1 ; kk < n ; kk++ ) sum -= V(kk,ii) * sval[kk] ; sval[ii] = sum / V(ii,ii) ; } for( ii=0 ; ii < n ; ii++ ) P(ii,jj) = (float)sval[ii] ; } free((void *)amat); free((void *)vmat); free((void *)sval); } /* rescale rows from norming */ for( ii=0 ; ii < n ; ii++ ){ for( jj=0 ; jj < m ; jj++ ) P(ii,jj) *= xfac[ii] ; } free((void *)xfac); /* rescale cols for weight? */ if( wt != NULL ){ for( ii=0 ; ii < m ; ii++ ){ ww = wt[ii] ; if( ww > 0.0 ) for( jj=0 ; jj < n ; jj++ ) P(jj,ii) *= ww ; } } return imp; }
int main( int argc , char * argv[] ) { int lin , kim , kbot,ktop , nx,ny , npix , ii , lbase , lup,ldown ; MRI_IMAGE ** stat_ret ; MRI_IMAGE * imb=NULL ; float * bar , * bav ; printf( "MCW SFIM: Stepwise Functional IMages, by RW Cox\n") ; if( argc < 2 ) SFIM_syntax("type sfim -help for usage details") ; else if( strcmp(argv[1],"-help") == 0 ) SFIM_syntax(NULL) ; machdep() ; SFIM_getopts( argc , argv ) ; /*----- average over each interval -----*/ nx = SF_imts->imarr[0]->nx ; ny = SF_imts->imarr[0]->ny ; npix = nx * ny ; lin = 0 ; kbot = 0 ; do { ktop = kbot + SF_int[lin].count ; if( ktop > SF_imts->num ) ktop = SF_imts->num ; if( isalpha(SF_int[lin].name[0]) ){ /* average if a good name */ for( kim=kbot ; kim < ktop ; kim++ ) (void) mri_stat_seq( SF_imts->imarr[kim] ) ; stat_ret = mri_stat_seq( NULL ) ; SF_int[lin].avim = stat_ret[0] ; SF_int[lin].sdim = stat_ret[1] ; } kbot = ktop ; lin ++ ; } while( SF_int[lin].count > 0 && kbot < SF_imts->num ) ; SF_numint = lin ; /*----- find the number of base intervals -----*/ lbase = 0 ; for( lin=0 ; lin < SF_numint ; lin++ ) if( strcmp(SF_int[lin].name,SF_bname) == 0 ) lbase++ ; /* no bases --> write averages out now and quit */ if( lbase <= 0 ){ printf("** no 'base' intervals --> task means not adjusted\n") ; SFIM_write_avs() ; exit(0) ; } /* bases yes, but not localbase --> compute global average of bases */ if( ! SF_localbase ){ int knum = 0 ; kbot = 0 ; for( lin=0 ; lin < SF_numint ; lin++ ){ ktop = kbot + SF_int[lin].count ; if( ktop > SF_imts->num ) ktop = SF_imts->num ; if( strcmp(SF_int[lin].name,SF_bname) == 0 ){ /* if a base */ for( kim=kbot ; kim < ktop ; kim++ ){ (void) mri_stat_seq( SF_imts->imarr[kim] ) ; /* average in */ knum ++ ; } } kbot = ktop ; } stat_ret = mri_stat_seq( NULL ) ; imb = stat_ret[0] ; /* average of all bases */ mri_free( stat_ret[1] ) ; /* don't keep st. dev. */ printf("** global base = average of %d images\n",knum) ; } /*----- for each non-base interval, subtract the relevant base average -----*/ for( lin=0 ; lin < SF_numint ; lin++ ){ int free_imb = 0 ; if( !isalpha(SF_int[lin].name[0]) || strcmp(SF_int[lin].name,SF_bname) == 0 ) continue ; /* skip this */ if( SF_localbase ){ for( lup=lin+1 ; lup < SF_numint ; lup++ ) /* look for a base above */ if( strcmp(SF_int[lup].name,SF_bname) == 0 ) break ; for( ldown=lin-1 ; ldown >=0 ; ldown-- ) /* look for a base below */ if( strcmp(SF_int[ldown].name,SF_bname) == 0 ) break ; if( ldown < 0 && lup >= SF_numint ){ /* no base? an error! */ fprintf(stderr,"*** can't find base above or below at lin=%d\n",lin) ; SFIM_syntax("INTERNAL ERROR -- should not occur!") ; } /* if only have one neighbor, use it, otherwise make average */ if( ldown < 0 ){ imb = SF_int[lup].avim ; free_imb = 0 ; printf("** local base for %s = average of %d images above\n", SF_int[lin].name , SF_int[lup].count ) ; } else if( lup >= SF_numint ){ imb = SF_int[ldown].avim ; free_imb = 0 ; printf("** local base for %s = average of %d images below\n", SF_int[lin].name , SF_int[ldown].count ) ; } else { float * bup , * bdown ; bup = mri_data_pointer( SF_int[lup].avim ) ; bdown = mri_data_pointer( SF_int[ldown].avim ) ; imb = mri_new( nx , ny , MRI_float ) ; free_imb = 1 ; bar = mri_data_pointer( imb ) ; for( ii=0 ; ii < npix ; ii++ ) bar[ii] = 0.5 * ( bup[ii] + bdown[ii] ) ; printf("** local base for %s = average of %d below, %d above\n", SF_int[lin].name, SF_int[ldown].count, SF_int[lup].count ) ; } } /* subtract imb (base average) from current interval average */ bar = mri_data_pointer( imb ) ; bav = mri_data_pointer( SF_int[lin].avim ) ; for( ii=0 ; ii < npix ; ii++ ) bav[ii] -= bar[ii] ; if( SF_localbase && free_imb ) mri_free( imb ) ; } /*----- now write the averages out -----*/ SFIM_write_avs() ; exit(0) ; }
int main( int argc , char * argv[] ) { int iarg , pos = 0 ; float thresh=0.0 ; MRI_IMAGE * maskim=NULL , *imin , *imout ; float * maskar ; int nxim , nyim , ii , npix ; if( argc < 3 || strncmp(argv[1],"-help",4) == 0 ){ printf("Usage: immask [-thresh #] [-mask mask_image] [-pos] input_image output_image\n" "* Masks the input_image and produces the output_image;\n" "* Use of -thresh # means all pixels with absolute value below # in\n" " input_image will be set to zero in the output_image\n" "* Use of -mask mask_image means that only locations that are nonzero\n" " in the mask_image will be nonzero in the output_image\n" "* Use of -pos means only positive pixels from input_image will be used\n" "* At least one of -thresh, -mask, -pos must be used; more than one is OK.\n" ) ; exit(0) ; } machdep() ; iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ /*** -pos ***/ if( strncmp(argv[iarg],"-pos",4) == 0 ){ pos = 1 ; iarg++ ; continue ; } /*** -thresh # ***/ if( strncmp(argv[iarg],"-thresh",5) == 0 ){ thresh = strtod( argv[++iarg] , NULL ) ; if( iarg >= argc || thresh <= 0.0 ){ fprintf(stderr,"Illegal -thresh!\a\n") ; exit(1) ; } iarg++ ; continue ; } if( strncmp(argv[iarg],"-mask",5) == 0 ){ maskim = mri_read_just_one( argv[++iarg] ) ; if( maskim == NULL || iarg >= argc || ! MRI_IS_2D(maskim) ){ fprintf(stderr,"Illegal -mask!\a\n") ; exit(1) ; } if( maskim->kind != MRI_float ){ imin = mri_to_float( maskim ) ; mri_free( maskim ) ; maskim = imin ; } iarg++ ; continue ; } fprintf(stderr,"** Illegal option: %s\a\n",argv[iarg]) ; exit(1) ; } if( thresh <= 0.0 && maskim == NULL && pos == 0 ){ fprintf(stderr,"No -thresh, -mask, -pos ==> can't go on!\a\n") ; exit(1) ; } if( iarg+1 >= argc ){ fprintf(stderr,"Must have input_image and output_image on command line!\a\n") ; exit(1) ; } imin = mri_read_just_one( argv[iarg++] ) ; if( imin == NULL ) exit(1) ; if( ! MRI_IS_2D(imin) ){ fprintf(stderr,"can only process 2D images!\a\n") ; exit(1) ; } nxim = imin->nx ; nyim = imin->ny ; npix = nxim * nyim ; if( maskim == NULL ){ maskim = mri_new( nxim , nyim , MRI_float ) ; maskar = MRI_FLOAT_PTR(maskim) ; for( ii=0 ; ii < npix ; ii++ ) maskar[ii] = 1.0 ; } else if( maskim->nx != nxim || maskim->ny != nyim ){ fprintf(stderr,"Mask and input image not same size!\a\n") ; exit(1) ; } else { maskar = MRI_FLOAT_PTR(maskim) ; } imout = mri_new( nxim , nyim , imin->kind ) ; switch( imin->kind ){ default: fprintf(stderr,"Unrecognized input image type!\a\n") ; exit(1) ; case MRI_byte:{ byte * arin , * arout , val ; arin = mri_data_pointer(imin) ; arout = mri_data_pointer(imout) ; for( ii=0 ; ii < npix ; ii++ ){ val = arin[ii] ; if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ; else arout[ii] = 0 ; } } break ; case MRI_short:{ short * arin , * arout , val ; arin = mri_data_pointer(imin) ; arout = mri_data_pointer(imout) ; for( ii=0 ; ii < npix ; ii++ ){ val = arin[ii] ; if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ; else arout[ii] = 0 ; } if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ; } break ; case MRI_float:{ float * arin , * arout , val ; arin = mri_data_pointer(imin) ; arout = mri_data_pointer(imout) ; for( ii=0 ; ii < npix ; ii++ ){ val = arin[ii] ; if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ; else arout[ii] = 0 ; } if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ; } break ; case MRI_int:{ int * arin , * arout , val ; arin = mri_data_pointer(imin) ; arout = mri_data_pointer(imout) ; for( ii=0 ; ii < npix ; ii++ ){ val = arin[ii] ; if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ; else arout[ii] = 0 ; } if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ; } break ; case MRI_double:{ double * arin , * arout , val ; arin = mri_data_pointer(imin) ; arout = mri_data_pointer(imout) ; for( ii=0 ; ii < npix ; ii++ ){ val = arin[ii] ; if( maskar[ii] != 0.0 && ABS(val) >= thresh ) arout[ii] = val ; else arout[ii] = 0 ; } if( pos ) for( ii=0 ; ii < npix ; ii++ ) if( arout[ii] < 0 ) arout[ii] = 0 ; } break ; case MRI_complex:{ complex * arin , * arout , val ; arin = mri_data_pointer(imin) ; arout = mri_data_pointer(imout) ; for( ii=0 ; ii < npix ; ii++ ){ val = arin[ii] ; if( maskar[ii] != 0.0 && CABS(val) >= thresh ) arout[ii] = val ; else arout[ii] = CMPLX(0,0) ; } } break ; } mri_write( argv[iarg] , imout ) ; exit(0) ; }
int main( int argc , char *argv[] ) { THD_3dim_dataset *inset=NULL , *outset=NULL ; MCW_cluster *nbhd=NULL ; byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , automask=0 ; char *prefix="./LocalCormat" ; int iarg=1 , verb=1 , ntype=0 , kk,nx,ny,nz,nxy,nxyz,nt , xx,yy,zz, vstep ; float na,nb,nc , dx,dy,dz ; MRI_IMARR *imar=NULL ; MRI_IMAGE *pim=NULL ; int mmlag=10 , ii,jj , do_arma=0 , nvout ; MRI_IMAGE *concim=NULL ; float *concar=NULL ; if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "Usage: 3dLocalCORMAT [options] inputdataset\n" "\n" "Compute the correlation matrix (in time) of the input dataset,\n" "up to lag given by -maxlag. The matrix is averaged over the\n" "neighborhood specified by the -nbhd option, and then the entries\n" "are output at each voxel in a new dataset.\n" "\n" "Normally, the input to this program would be the -errts output\n" "from 3dDeconvolve, or the equivalent residuals from some other\n" "analysis. If you input a non-residual time series file, you at\n" "least should use an appropriate -polort level for detrending!\n" "\n" "Options:\n" " -input inputdataset\n" " -prefix ppp\n" " -mask mset {these 2 options are}\n" " -automask {mutually exclusive.}\n" " -nbhd nnn [e.g., 'SPHERE(9)' for 9 mm radius]\n" " -polort ppp [default = 0, which is reasonable for -errts output]\n" " -concat ccc [as in 3dDeconvolve]\n" " -maxlag mmm [default = 10]\n" " -ARMA [estimate ARMA(1,1) parameters into last 2 sub-bricks]\n" "\n" "A quick hack for my own benignant purposes -- RWCox -- June 2008\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } /*---- official startup ---*/ PRINT_VERSION("3dLocalCormat"); mainENTRY("3dLocalCormat main"); machdep(); AFNI_logger("3dLocalCormat",argc,argv); AUTHOR("Zhark the Toeplitzer"); /*---- loop over options ----*/ while( iarg < argc && argv[iarg][0] == '-' ){ #if 0 fprintf(stderr,"argv[%d] = %s\n",iarg,argv[iarg]) ; #endif if( strcmp(argv[iarg],"-ARMA") == 0 ){ do_arma = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-polort") == 0 ){ char *cpt ; if( ++iarg >= argc ) ERROR_exit("Need argument after option %s",argv[iarg-1]) ; pport = (int)strtod(argv[iarg],&cpt) ; if( *cpt != '\0' ) WARNING_message("Illegal non-numeric value after -polort") ; if( pport > 3 ){ pport = 3 ; WARNING_message("-polort set to 3 == max implemented") ; } else if( pport < 0 ){ pport = 0 ; WARNING_message("-polort set to 0 == min implemented") ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-input") == 0 ){ if( inset != NULL ) ERROR_exit("Can't have two -input options") ; if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ; inset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(inset,argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-prefix'") ; prefix = strdup(argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask") == 0 ){ THD_3dim_dataset *mset ; int mmm ; if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ; if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ; mset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(mset,argv[iarg]) ; DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset); mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ; if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ; mmm = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ; INFO_message("Number of voxels in mask = %d",mmm) ; if( mmm < 2 ) ERROR_exit("Mask is too small to process") ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-automask") == 0 ){ if( mask != NULL ) ERROR_exit("Can't have -automask and -mask") ; automask = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-nbhd") == 0 ){ char *cpt ; if( ntype > 0 ) ERROR_exit("Can't have 2 '-nbhd' options") ; if( ++iarg >= argc ) ERROR_exit("Need argument after '-nbhd'") ; cpt = argv[iarg] ; if( strncasecmp(cpt,"SPHERE",6) == 0 ){ sscanf( cpt+7 , "%f" , &na ) ; if( na == 0.0f ) ERROR_exit("Can't have a SPHERE of radius 0") ; ntype = NTYPE_SPHERE ; } else if( strncasecmp(cpt,"RECT",4) == 0 ){ sscanf( cpt+5 , "%f,%f,%f" , &na,&nb,&nc ) ; if( na == 0.0f && nb == 0.0f && nc == 0.0f ) ERROR_exit("'RECT(0,0,0)' is not a legal neighborhood") ; ntype = NTYPE_RECT ; } else if( strncasecmp(cpt,"RHDD",4) == 0 ){ sscanf( cpt+5 , "%f" , &na ) ; if( na == 0.0f ) ERROR_exit("Can't have a RHDD of radius 0") ; ntype = NTYPE_RHDD ; } else { ERROR_exit("Unknown -nbhd shape: '%s'",cpt) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-maxlag") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after option %s",argv[iarg-1]) ; mmlag = (int)strtod(argv[iarg],NULL) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-concat") == 0 ){ if( concim != NULL ) ERROR_exit("Can't have two %s options!",argv[iarg]) ; if( ++iarg >= argc ) ERROR_exit("Need argument after option %s",argv[iarg-1]) ; concim = mri_read_1D( argv[iarg] ) ; if( concim == NULL ) ERROR_exit("Can't read -concat file '%s'",argv[iarg]) ; if( concim->nx < 2 ) ERROR_exit("-concat file '%s' must have at least 2 entries!", argv[iarg]) ; concar = MRI_FLOAT_PTR(concim) ; for( ii=1 ; ii < concim->nx ; ii++ ) if( (int)concar[ii-1] >= (int)concar[ii] ) ERROR_exit("-concat file '%s' is not ordered increasingly!", argv[iarg]) ; iarg++ ; continue ; } ERROR_exit("Unknown option '%s'",argv[iarg]) ; } /*--- end of loop over options ---*/ if( do_arma && mmlag > 0 && mmlag < 5 ) ERROR_exit("Can't do -ARMA with -maxlag %d",mmlag) ; /*---- deal with input dataset ----*/ if( inset == NULL ){ if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ; inset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(inset,argv[iarg]) ; } ntime = DSET_NVALS(inset) ; if( ntime < 9 ) ERROR_exit("Must have at least 9 values per voxel") ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; if( mask != NULL ){ if( mask_nx != DSET_NX(inset) || mask_ny != DSET_NY(inset) || mask_nz != DSET_NZ(inset) ) ERROR_exit("-mask dataset grid doesn't match input dataset") ; } else if( automask ){ int mmm ; mask = THD_automask( inset ) ; if( mask == NULL ) ERROR_message("Can't create -automask from input dataset?") ; mmm = THD_countmask( DSET_NVOX(inset) , mask ) ; INFO_message("Number of voxels in automask = %d",mmm) ; if( mmm < 2 ) ERROR_exit("Automask is too small to process") ; } /*-- set up blocks of continuous time data --*/ if( DSET_IS_TCAT(inset) ){ if( concim != NULL ){ WARNING_message("Ignoring -concat, since dataset is auto-catenated") ; mri_free(concim) ; } concim = mri_new(inset->tcat_num,1,MRI_float) ; concar = MRI_FLOAT_PTR(concim) ; concar[0] = 0.0 ; for( ii=0 ; ii < inset->tcat_num-1 ; ii++ ) concar[ii+1] = concar[ii] + inset->tcat_len[ii] ; } else if( concim == NULL ){ concim = mri_new(1,1,MRI_float) ; concar = MRI_FLOAT_PTR(concim) ; concar[0] = 0 ; } nbk = concim->nx ; bk = (int *)malloc(sizeof(int)*(nbk+1)) ; for( ii=0 ; ii < nbk ; ii++ ) bk[ii] = (int)concar[ii] ; bk[nbk] = ntime ; mri_free(concim) ; mlag = DSET_NVALS(inset) ; for( ii=0 ; ii < nbk ; ii++ ){ jj = bk[ii+1]-bk[ii] ; if( jj < mlag ) mlag = jj ; if( bk[ii] < 0 || jj < 9 ) ERROR_exit("something is rotten in the dataset run lengths") ; } mlag-- ; if( mmlag > 0 && mlag > mmlag ) mlag = mmlag ; else INFO_message("Max lag set to %d",mlag) ; if( do_arma && mlag < 5 ) ERROR_exit("Can't do -ARMA with maxlag=%d",mlag) ; /*---- create neighborhood (as a cluster) -----*/ if( ntype <= 0 ){ /* default neighborhood */ ntype = NTYPE_SPHERE ; na = -1.01f ; INFO_message("Using default neighborhood = self + 6 neighbors") ; } switch( ntype ){ default: ERROR_exit("WTF? ntype=%d",ntype) ; case NTYPE_SPHERE:{ if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; } else { dx = fabsf(DSET_DX(inset)) ; dy = fabsf(DSET_DY(inset)) ; dz = fabsf(DSET_DZ(inset)) ; } nbhd = MCW_spheremask( dx,dy,dz , na ) ; } break ; case NTYPE_RECT:{ if( na < 0.0f ){ dx = 1.0f; na = -na; } else dx = fabsf(DSET_DX(inset)); if( nb < 0.0f ){ dy = 1.0f; nb = -nb; } else dy = fabsf(DSET_DY(inset)); if( nc < 0.0f ){ dz = 1.0f; nc = -nc; } else dz = fabsf(DSET_DZ(inset)); nbhd = MCW_rectmask( dx,dy,dz , na,nb,nc ) ; } break ; case NTYPE_RHDD:{ if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; } else { dx = fabsf(DSET_DX(inset)) ; dy = fabsf(DSET_DY(inset)) ; dz = fabsf(DSET_DZ(inset)) ; } nbhd = MCW_rhddmask( dx,dy,dz , na ) ; } break ; } MCW_radsort_cluster( nbhd , dx,dy,dz ) ; /* 26 Feb 2008 */ INFO_message("Neighborhood comprises %d voxels",nbhd->num_pt) ; /** create output dataset **/ outset = EDIT_empty_copy(inset) ; nvout = mlag ; if( do_arma ) nvout += 2 ; EDIT_dset_items( outset, ADN_prefix , prefix, ADN_brick_fac, NULL , ADN_nvals , nvout , ADN_ntt , nvout , ADN_none ); tross_Copy_History( inset , outset ) ; tross_Make_History( "3dLocalCormat" , argc,argv , outset ) ; for( kk=0 ; kk < nvout ; kk++ ) EDIT_substitute_brick( outset , kk , MRI_float , NULL ) ; nx = DSET_NX(outset) ; ny = DSET_NY(outset) ; nxy = nx*ny ; nz = DSET_NZ(outset) ; nxyz = nxy*nz ; vstep = (verb && nxyz > 999) ? nxyz/50 : 0 ; if( vstep ) fprintf(stderr,"++ voxel loop: ") ; /** actually do the long long slog through all voxels **/ for( kk=0 ; kk < nxyz ; kk++ ){ if( vstep && kk%vstep==vstep-1 ) vstep_print() ; if( !INMASK(kk) ) continue ; IJK_TO_THREE( kk , xx,yy,zz , nx,nxy ) ; imar = THD_get_dset_nbhd_array( inset , mask , xx,yy,zz , nbhd ) ; if( imar == NULL ) continue ; pim = mri_cormat_vector(imar) ; DESTROY_IMARR(imar) ; if( pim == NULL ) continue ; THD_insert_series( kk, outset, pim->nx, MRI_float, MRI_FLOAT_PTR(pim), 0 ) ; if( do_arma ){ /* estimate ARMA(1,1) params and store those, too */ float_pair ab ; float *aa=DSET_ARRAY(outset,mlag), *bb=DSET_ARRAY(outset,mlag+1) ; ab = estimate_arma11( pim->nx , MRI_FLOAT_PTR(pim) ) ; aa[kk] = ab.a ; bb[kk] = ab.b ; } mri_free(pim) ; } if( vstep ) fprintf(stderr,"\n") ; DSET_delete(inset) ; DSET_write(outset) ; WROTE_DSET(outset) ; exit(0) ; }
MRI_IMAGE *mri_rota( MRI_IMAGE *im, float aa, float bb, float phi ) { float rot_dx , rot_dy , rot_cph , rot_sph , top,bot,val ; MRI_IMAGE *imfl , *newImg ; MRI_IMARR *impair ; float *far , *nar ; float xx,yy , fx,fy ; int ii,jj, nx,ny , ix,jy , ifx,jfy ; float f_jm1,f_j00,f_jp1,f_jp2 , wt_m1,wt_00,wt_p1,wt_p2 ; #ifdef USE_CGRID if( p_first ){ p_first = 0 ; xx = 1.0 / CGRID ; for( ii=0 ; ii <= CGRID ; ii++ ){ yy = ii * xx ; p_m1[ii] = P_M1(yy) ; p_00[ii] = P_00(yy) ; p_p1[ii] = P_P1(yy) ; p_p2[ii] = P_P2(yy) ; } } #endif if( im == NULL || ! MRI_IS_2D(im) ){ fprintf(stderr,"*** mri_rota only works on 2D images!\n") ; EXIT(1) ; } /** if complex image, break into pairs, do each separately, put back together **/ if( im->kind == MRI_complex ){ MRI_IMARR *impair ; MRI_IMAGE * rim , * iim , * tim ; impair = mri_complex_to_pair( im ) ; if( impair == NULL ){ fprintf(stderr,"*** mri_complex_to_pair fails in mri_rota!\n") ; EXIT(1) ; } rim = IMAGE_IN_IMARR(impair,0) ; iim = IMAGE_IN_IMARR(impair,1) ; FREE_IMARR(impair) ; tim = mri_rota( rim , aa,bb,phi ) ; mri_free( rim ) ; rim = tim ; tim = mri_rota( iim , aa,bb,phi ) ; mri_free( iim ) ; iim = tim ; newImg = mri_pair_to_complex( rim , iim ) ; mri_free( rim ) ; mri_free( iim ) ; MRI_COPY_AUX(newImg,im) ; return newImg ; } /** rotation params **/ rot_cph = cos(phi) ; rot_sph = sin(phi) ; rot_dx = (0.5 * im->nx) * (1.0-rot_cph) - aa*rot_cph - bb*rot_sph -(0.5 * im->ny) * rot_sph ; rot_dy = (0.5 * im->nx) * rot_sph + aa*rot_sph - bb*rot_cph +(0.5 * im->ny) * (1.0-rot_cph) ; /** other initialization **/ nx = im->nx ; /* image dimensions */ ny = im->ny ; if( im->kind == MRI_float ) imfl = im ; else imfl = mri_to_float( im ) ; far = MRI_FLOAT_PTR(imfl) ; /* access to float data */ newImg = mri_new( nx , nx , MRI_float ) ; /* output image */ nar = MRI_FLOAT_PTR(newImg) ; /* output image data */ bot = top = far[0] ; for( ii=0 ; ii < nx*ny ; ii++ ) if( far[ii] < bot ) bot = far[ii] ; else if( far[ii] > top ) top = far[ii] ; /*** loop over output points and warp to them ***/ for( jj=0 ; jj < nx ; jj++ ){ xx = rot_sph * jj + rot_dx - rot_cph ; yy = rot_cph * jj + rot_dy + rot_sph ; for( ii=0 ; ii < nx ; ii++ ){ xx += rot_cph ; /* get x,y in original image */ yy -= rot_sph ; ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ; /* floor */ jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ; #ifdef USE_CGRID ifx = (xx-ix)*CGRID + 0.499 ; wt_m1 = p_m1[ifx] ; wt_00 = p_00[ifx] ; wt_p1 = p_p1[ifx] ; wt_p2 = p_p2[ifx] ; #else fx = xx-ix ; wt_m1 = P_M1(fx) ; wt_00 = P_00(fx) ; wt_p1 = P_P1(fx) ; wt_p2 = P_P2(fx) ; #endif if( ix > 0 && ix < nx-2 && jy > 0 && jy < ny-2 ){ float * fym1, *fy00 , *fyp1 , *fyp2 ; fym1 = far + (ix-1 + (jy-1)*nx) ; fy00 = fym1 + nx ; fyp1 = fy00 + nx ; fyp2 = fyp1 + nx ; f_jm1 = wt_m1 * fym1[0] + wt_00 * fym1[1] + wt_p1 * fym1[2] + wt_p2 * fym1[3] ; f_j00 = wt_m1 * fy00[0] + wt_00 * fy00[1] + wt_p1 * fy00[2] + wt_p2 * fy00[3] ; f_jp1 = wt_m1 * fyp1[0] + wt_00 * fyp1[1] + wt_p1 * fyp1[2] + wt_p2 * fyp1[3] ; f_jp2 = wt_m1 * fyp2[0] + wt_00 * fyp2[1] + wt_p1 * fyp2[2] + wt_p2 * fyp2[3] ; } else { f_jm1 = wt_m1 * FINS(ix-1,jy-1) + wt_00 * FINS(ix ,jy-1) + wt_p1 * FINS(ix+1,jy-1) + wt_p2 * FINS(ix+2,jy-1) ; f_j00 = wt_m1 * FINS(ix-1,jy) + wt_00 * FINS(ix ,jy) + wt_p1 * FINS(ix+1,jy) + wt_p2 * FINS(ix+2,jy) ; f_jp1 = wt_m1 * FINS(ix-1,jy+1) + wt_00 * FINS(ix ,jy+1) + wt_p1 * FINS(ix+1,jy+1) + wt_p2 * FINS(ix+2,jy+1) ; f_jp2 = wt_m1 * FINS(ix-1,jy+2) + wt_00 * FINS(ix ,jy+2) + wt_p1 * FINS(ix+1,jy+2) + wt_p2 * FINS(ix+2,jy+2) ; } #define THIRTYSIX 2.7777778e-2 /* 1./36.0, actually */ #ifdef USE_CGRID jfy = (yy-jy)*CGRID + 0.499 ; val = ( p_m1[jfy] * f_jm1 + p_00[jfy] * f_j00 + p_p1[jfy] * f_jp1 + p_p2[jfy] * f_jp2 ) * THIRTYSIX ; #else fy = yy-jy ; val = ( P_M1(fy) * f_jm1 + P_00(fy) * f_j00 + P_P1(fy) * f_jp1 + P_P2(fy) * f_jp2 ) * THIRTYSIX ; #endif if( val < bot ) nar[ii+jj*nx] = bot ; /* too small! */ else if( val > top ) nar[ii+jj*nx] = top ; /* too big! */ else nar[ii+jj*nx] = val ; /* just right */ } } /*** cleanup and return ***/ if( im != imfl ) mri_free(imfl) ; /* throw away unneeded workspace */ MRI_COPY_AUX(newImg,im) ; return newImg ; }
MRI_IMAGE *mri_rota_bilinear( MRI_IMAGE *im, float aa, float bb, float phi ) { float rot_dx , rot_dy , rot_cph , rot_sph ; MRI_IMAGE *imfl , *newImg ; MRI_IMARR *impair ; float *far , *nar ; float xx,yy , fx,fy ; int ii,jj, nx,ny , ix,jy ; float f_j00,f_jp1 , wt_00,wt_p1 ; if( im == NULL || ! MRI_IS_2D(im) ){ fprintf(stderr,"*** mri_rota_bilinear only works on 2D images!\n") ; EXIT(1) ; } /** if complex image, break into pairs, do each separately, put back together **/ if( im->kind == MRI_complex ){ MRI_IMARR *impair ; MRI_IMAGE * rim , * iim , * tim ; impair = mri_complex_to_pair( im ) ; if( impair == NULL ){ fprintf(stderr,"*** mri_complex_to_pair fails in mri_rota!\n") ; EXIT(1) ; } rim = IMAGE_IN_IMARR(impair,0) ; iim = IMAGE_IN_IMARR(impair,1) ; FREE_IMARR(impair) ; tim = mri_rota_bilinear( rim , aa,bb,phi ) ; mri_free( rim ) ; rim = tim ; tim = mri_rota_bilinear( iim , aa,bb,phi ) ; mri_free( iim ) ; iim = tim ; newImg = mri_pair_to_complex( rim , iim ) ; mri_free( rim ) ; mri_free( iim ) ; MRI_COPY_AUX(newImg,im) ; return newImg ; } /** rotation params **/ rot_cph = cos(phi) ; rot_sph = sin(phi) ; rot_dx = (0.5 * im->nx) * (1.0-rot_cph) - aa*rot_cph - bb*rot_sph -(0.5 * im->ny) * rot_sph ; rot_dy = (0.5 * im->nx) * rot_sph + aa*rot_sph - bb*rot_cph +(0.5 * im->ny) * (1.0-rot_cph) ; /** other initialization **/ nx = im->nx ; /* image dimensions */ ny = im->ny ; if( im->kind == MRI_float ) imfl = im ; else imfl = mri_to_float( im ) ; far = MRI_FLOAT_PTR(imfl) ; /* access to float data */ newImg = mri_new( nx , nx , MRI_float ) ; /* output image */ nar = MRI_FLOAT_PTR(newImg) ; /* output image data */ /*** loop over output points and warp to them ***/ for( jj=0 ; jj < nx ; jj++ ){ xx = rot_sph * jj + rot_dx - rot_cph ; yy = rot_cph * jj + rot_dy + rot_sph ; for( ii=0 ; ii < nx ; ii++ ){ xx += rot_cph ; /* get x,y in original image */ yy -= rot_sph ; ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ; /* floor */ jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ; fx = xx-ix ; wt_00 = 1.0 - fx ; wt_p1 = fx ; if( ix >= 0 && ix < nx-1 && jy >= 0 && jy < ny-1 ){ float *fy00 , *fyp1 ; fy00 = far + (ix + jy*nx) ; fyp1 = fy00 + nx ; f_j00 = wt_00 * fy00[0] + wt_p1 * fy00[1] ; f_jp1 = wt_00 * fyp1[0] + wt_p1 * fyp1[1] ; } else { f_j00 = wt_00 * FINS(ix,jy ) + wt_p1 * FINS(ix+1,jy ) ; f_jp1 = wt_00 * FINS(ix,jy+1) + wt_p1 * FINS(ix+1,jy+1) ; } fy = yy-jy ; nar[ii+jj*nx] = (1.0-fy) * f_j00 + fy * f_jp1 ; } } /*** cleanup and return ***/ if( im != imfl ) mri_free(imfl) ; /* throw away unneeded workspace */ MRI_COPY_AUX(newImg,im) ; return newImg ; }
int mri_warp3D_align_setup( MRI_warp3D_align_basis *bas ) { MRI_IMAGE *cim , *fitim ; int nx, ny, nz, nxy, nxyz , ii,jj,kk , nmap, *im ; float *wf , *wtar , clip , clip2 ; int *ima , pp , wtproc , npar , nfree ; byte *msk ; int ctstart ; ENTRY("mri_warp3D_align_setup") ; ctstart = NI_clock_time() ; /*- check for good inputs -*/ if( bas == NULL || bas->imbase == NULL ) RETURN(1) ; if( bas->nparam < 1 || bas->param == NULL ) RETURN(1) ; if( bas->vwfor == NULL || bas->vwinv == NULL || bas->vwset == NULL ) RETURN(1) ; /*- set defaults in bas, if values weren't set by user -*/ if( bas->scale_init <= 0.0f ) bas->scale_init = 1.0f ; if( bas->delfac <= 0.0f ) bas->delfac = 1.0f ; if( bas->regmode <= 0 ) bas->regmode = MRI_LINEAR ; if( bas->max_iter <= 0 ) bas->max_iter = 9 ; /* process the weight image? */ wtproc = (bas->imwt == NULL) ? 1 : bas->wtproc ; npar = bas->nparam ; nfree = npar ; for( pp=0 ; pp < npar ; pp++ ) if( bas->param[pp].fixed ) nfree-- ; if( nfree <= 0 ) RETURN(1) ; bas->nfree = nfree ; /*- clean out anything from last call -*/ mri_warp3D_align_cleanup( bas ) ; /*-- need local copy of input base image --*/ cim = mri_to_float( bas->imbase ) ; nx=cim->nx ; ny=cim->ny ; nz=cim->nz ; nxy = nx*ny ; nxyz=nxy*nz ; /*-- make weight image up from the base image if it isn't supplied --*/ if( bas->verb ) fprintf(stderr,"++ mri_warp3D_align_setup ENTRY\n") ; if( bas->imwt == NULL || bas->imwt->nx != nx || bas->imwt->ny != ny || bas->imwt->nz != nz ) bas->imww = mri_copy( cim ) ; else bas->imww = mri_to_float( bas->imwt ) ; if( bas->twoblur > 0.0f ){ float bmax = cbrt((double)nxyz) * 0.03 ; if( bmax < bas->twoblur ){ if( bas->verb ) fprintf(stderr,"+ shrink bas->twoblur from %.3f to %.3f\n", bas->twoblur , bmax ) ; bas->twoblur = bmax ; } } if( bas->verb ) fprintf(stderr,"+ processing weight:") ; /* make sure weight is non-negative */ wf = MRI_FLOAT_PTR(bas->imww) ; for( ii=0 ; ii < nxyz ; ii++ ) wf[ii] = fabs(wf[ii]) ; /* trim off edges of weight */ if( wtproc ){ int ff ; int xfade=bas->xedge , yfade=bas->yedge , zfade=bas->zedge ; if( xfade < 0 || yfade < 0 || zfade < 0 ) mri_warp3D_align_edging_default(nx,ny,nz,&xfade,&yfade,&zfade) ; if( bas->twoblur > 0.0f ){ xfade += (int)rint(1.5*bas->twoblur) ; yfade += (int)rint(1.5*bas->twoblur) ; zfade += (int)rint(1.5*bas->twoblur) ; } if( 3*zfade >= nz ) zfade = (nz-1)/3 ; if( 3*xfade >= nx ) xfade = (nx-1)/3 ; if( 3*yfade >= ny ) yfade = (ny-1)/3 ; if( bas->verb ) fprintf(stderr," [edge(%d,%d,%d)]",xfade,yfade,zfade) ; for( jj=0 ; jj < ny ; jj++ ) for( ii=0 ; ii < nx ; ii++ ) for( ff=0 ; ff < zfade ; ff++ ) WW(ii,jj,ff) = WW(ii,jj,nz-1-ff) = 0.0f ; for( kk=0 ; kk < nz ; kk++ ) for( jj=0 ; jj < ny ; jj++ ) for( ff=0 ; ff < xfade ; ff++ ) WW(ff,jj,kk) = WW(nx-1-ff,jj,kk) = 0.0f ; for( kk=0 ; kk < nz ; kk++ ) for( ii=0 ; ii < nx ; ii++ ) for( ff=0 ; ff < yfade ; ff++ ) WW(ii,ff,kk) = WW(ii,ny-1-ff,kk) = 0.0f ; } /* spatially blur weight a little */ if( wtproc ){ float blur ; blur = 1.0f + MAX(1.5f,bas->twoblur) ; if( bas->verb ) fprintf(stderr," [blur(%.1f)]",blur) ; EDIT_blur_volume_3d( nx,ny,nz , 1.0f,1.0f,1.0f , MRI_float , wf , blur,blur,blur ) ; } /* get rid of low-weight voxels */ clip = 0.035 * mri_max(bas->imww) ; clip2 = 0.5*THD_cliplevel(bas->imww,0.4) ; if( clip2 > clip ) clip = clip2 ; if( bas->verb ) fprintf(stderr," [clip(%.1f)]",clip) ; for( ii=0 ; ii < nxyz ; ii++ ) if( wf[ii] < clip ) wf[ii] = 0.0f ; /* keep only the largest cluster of nonzero voxels */ { byte *mmm = (byte *)malloc( sizeof(byte)*nxyz ) ; for( ii=0 ; ii < nxyz ; ii++ ) mmm[ii] = (wf[ii] > 0.0f) ; THD_mask_clust( nx,ny,nz, mmm ) ; THD_mask_erode( nx,ny,nz, mmm, 1 ) ; /* cf. thd_automask.c */ THD_mask_clust( nx,ny,nz, mmm ) ; for( ii=0 ; ii < nxyz ; ii++ ) if( !mmm[ii] ) wf[ii] = 0.0f ; free((void *)mmm) ; } if( bas->verb ) fprintf(stderr,"\n") ; /*-- make integer index map of weight > 0 voxels --*/ nmap = 0 ; for( ii=0 ; ii < nxyz ; ii++ ) if( wf[ii] > 0.0f ) nmap++ ; if( bas->verb ) fprintf(stderr,"+ using %d [%.3f%%] voxels\n",nmap,(100.0*nmap)/nxyz); if( nmap < 7*nfree+13 ){ fprintf(stderr,"** mri_warp3D_align error: weight image too zero-ish!\n") ; mri_warp3D_align_cleanup( bas ) ; mri_free(cim) ; RETURN(1) ; } bas->imap = mri_new( nmap , 1 , MRI_int ) ; ima = MRI_INT_PTR(bas->imap) ; bas->imsk = mri_new_conforming( bas->imww , MRI_byte ) ; msk = MRI_BYTE_PTR(bas->imsk) ; for( ii=jj=0 ; ii < nxyz ; ii++ ){ if( wf[ii] > 0.0f ){ ima[jj++] = ii; msk[ii] = 1; } } /* make copy of sqrt(weight), but only at mapped indexes */ wtar = (float *)malloc(sizeof(float)*nmap) ; for( ii=0 ; ii < nmap ; ii++ ) wtar[ii] = sqrt(wf[ima[ii]]) ; /*-- for parameters that don't come with a step size, find one --*/ clip = bas->tolfac ; if( clip <= 0.0f ) clip = 0.03f ; for( ii=0 ; ii < npar ; ii++ ){ if( bas->param[ii].fixed ) continue ; /* don't need this */ if( bas->param[ii].delta <= 0.0f ) mri_warp3D_get_delta( bas , ii ) ; /* find step size */ if( bas->param[ii].toler <= 0.0f ){ /* and set default tolerance */ bas->param[ii].toler = clip * bas->param[ii].delta ; if( bas->verb ) fprintf(stderr,"+ set toler param#%d [%s] = %f\n", ii+1,bas->param[ii].name,bas->param[ii].toler) ; } } /* don't need the computed weight image anymore */ mri_free(bas->imww) ; bas->imww = NULL ; wf = NULL ; /*-- create image containing basis columns, then pseudo-invert it --*/ if( bas->verb ) fprintf(stderr,"+ Compute Derivatives of Base\n") ; fitim = mri_warp3D_align_fitim( bas , cim , bas->regmode , bas->delfac ) ; if( bas->verb ) fprintf(stderr,"+ calculate pseudo-inverse\n") ; bas->imps = mri_psinv( fitim , wtar ) ; mri_free(fitim) ; if( bas->imps == NULL ){ /* bad bad bad */ fprintf(stderr,"** mri_warp3D_align error: can't invert Base matrix!\n") ; free((void *)wtar) ; mri_warp3D_align_cleanup( bas ) ; mri_free(cim) ; RETURN(1) ; } /*--- twoblur? ---*/ if( bas->twoblur > 0.0f ){ float *car=MRI_FLOAT_PTR(cim) ; float blur = bas->twoblur ; float bfac = blur ; if( bfac < 1.1234f ) bfac = 1.1234f ; else if( bfac > 1.3456f ) bfac = 1.3456f ; if( bas->verb ) fprintf(stderr,"+ Compute Derivatives of Blurred Base\n") ; EDIT_blur_volume_3d( nx,ny,nz , 1.0f,1.0f,1.0f , MRI_float , car, blur,blur,blur ) ; fitim = mri_warp3D_align_fitim( bas , cim , MRI_LINEAR , bfac*bas->delfac ) ; if( bas->verb ) fprintf(stderr,"+ calculate pseudo-inverse\n") ; bas->imps_blur = mri_psinv( fitim , wtar ) ; mri_free(fitim) ; if( bas->imps_blur == NULL ){ /* bad */ fprintf(stderr,"** mri_warp3D_align error: can't invert Blur matrix!\n") ; } } /*--- done ---*/ mri_free(cim) ; free((void *)wtar) ; if( bas->verb ){ double st = (NI_clock_time()-ctstart) * 0.001 ; fprintf(stderr,"++ mri_warp3D_align_setup EXIT: %.2f seconds elapsed\n",st); } RETURN(0); }
static MRI_IMAGE * mri_dup2D_rgb3( MRI_IMAGE *inim ) { rgbyte *bin , *bout , *bin1,*bin2 , *bout1,*bout2,*bout3 ; MRI_IMAGE *outim ; int ii,jj , nx,ny , nxup,nyup ; ENTRY("mri_dup2D_rgb3") ; if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL) ; bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL); /* make output image **/ nx = inim->nx ; ny = inim->ny ; nxup = 3*nx ; nyup = 3*ny ; outim = mri_new( nxup , nyup , MRI_rgb ) ; bout = (rgbyte *) MRI_RGB_PTR(outim) ; /** macros for the 9 different interpolations between the four corners: ul ur > 00 10 20 >=> 01 11 21 ll lr > 02 12 22 **/ #define COUT_00(ul,ur,ll,lr) ( ul ) #define COUT_10(ul,ur,ll,lr) ((171*ul + 85*ur ) >> 8) #define COUT_20(ul,ur,ll,lr) (( 85*ul +171*ur ) >> 8) #define COUT_01(ul,ur,ll,lr) ((171*ul + 85*ll ) >> 8) #define COUT_11(ul,ur,ll,lr) ((114*ul + 57*ur + 57*ll + 28*lr) >> 8) #define COUT_21(ul,ur,ll,lr) (( 57*ul +114*ur + 28*ll + 57*lr) >> 8) #define COUT_02(ul,ur,ll,lr) (( 85*ul + 171*ll ) >> 8) #define COUT_12(ul,ur,ll,lr) (( 57*ul + 28*ur +114*ll + 57*lr) >> 8) #define COUT_22(ul,ur,ll,lr) (( 28*ul + 57*ur + 57*ll +114*lr) >> 8) /** do 9 interpolations between ul ur ll lr for index #k, color #c **/ #define THREE_ROWS(k,c,ul,ur,ll,lr) \ { bout1[3*k+1].c = COUT_00(ul.c,ur.c,ll.c,lr.c) ; \ bout1[3*k+2].c = COUT_10(ul.c,ur.c,ll.c,lr.c) ; \ bout1[3*k+3].c = COUT_20(ul.c,ur.c,ll.c,lr.c) ; \ bout2[3*k+1].c = COUT_01(ul.c,ur.c,ll.c,lr.c) ; \ bout2[3*k+2].c = COUT_11(ul.c,ur.c,ll.c,lr.c) ; \ bout2[3*k+3].c = COUT_21(ul.c,ur.c,ll.c,lr.c) ; \ bout3[3*k+1].c = COUT_02(ul.c,ur.c,ll.c,lr.c) ; \ bout3[3*k+2].c = COUT_12(ul.c,ur.c,ll.c,lr.c) ; \ bout3[3*k+3].c = COUT_22(ul.c,ur.c,ll.c,lr.c) ; } /** do the above for all 3 colors **/ #define THREE_RGB(k,ul,ur,ll,lr) { THREE_ROWS(k,r,ul,ur,ll,lr) ; \ THREE_ROWS(k,g,ul,ur,ll,lr) ; \ THREE_ROWS(k,b,ul,ur,ll,lr) ; } bin1 = bin ; bin2 = bin+nx ; /* 2 input rows */ bout1 = bout +nxup; bout2 = bout1+nxup; /* 3 output rows */ bout3 = bout2+nxup; for( jj=0 ; jj < ny-1 ; jj++ ){ /* loop over input rows */ for( ii=0 ; ii < nx-1 ; ii++ ){ THREE_RGB(ii,bin1[ii],bin1[ii+1],bin2[ii],bin2[ii+1]) ; } /* here, ii=nx-1; can't use ii+1 */ /* do the 3*ii+1 output only, */ /* and copy into 3*ii+2 column */ bout1[3*ii+1].r = COUT_00(bin1[ii].r,0,bin2[ii].r,0) ; bout2[3*ii+1].r = COUT_01(bin1[ii].r,0,bin2[ii].r,0) ; bout3[3*ii+1].r = COUT_02(bin1[ii].r,0,bin2[ii].r,0) ; bout1[3*ii+1].g = COUT_00(bin1[ii].g,0,bin2[ii].g,0) ; bout2[3*ii+1].g = COUT_01(bin1[ii].g,0,bin2[ii].g,0) ; bout3[3*ii+1].g = COUT_02(bin1[ii].g,0,bin2[ii].g,0) ; bout1[3*ii+1].b = COUT_00(bin1[ii].b,0,bin2[ii].b,0) ; bout2[3*ii+1].b = COUT_01(bin1[ii].b,0,bin2[ii].b,0) ; bout3[3*ii+1].b = COUT_02(bin1[ii].b,0,bin2[ii].b,0) ; bout1[3*ii+2] = bout1[3*ii+1] ; bout2[3*ii+2] = bout2[3*ii+1] ; bout3[3*ii+2] = bout3[3*ii+1] ; /* also copy [0] column output from column [1] */ bout1[0] = bout1[1] ; bout2[0] = bout2[1] ; bout3[0] = bout3[1] ; /* advance input and output rows */ bin1 = bin2; bin2 += nx ; bout1 = bout3+nxup; bout2 = bout1+nxup; bout3 = bout2+nxup; } /* here, jj=ny-1, so can't use jj+1 (bin2) */ /* do the bout1 output row only, copy into bout2 */ for( ii=0 ; ii < nx-1 ; ii++ ){ bout1[3*ii+1].r = COUT_00(bin1[ii].r,bin1[ii+1].r,0,0) ; bout1[3*ii+2].r = COUT_10(bin1[ii].r,bin1[ii+1].r,0,0) ; bout1[3*ii+3].r = COUT_20(bin1[ii].r,bin1[ii+1].r,0,0) ; bout1[3*ii+1].g = COUT_00(bin1[ii].g,bin1[ii+1].g,0,0) ; bout1[3*ii+2].g = COUT_10(bin1[ii].g,bin1[ii+1].g,0,0) ; bout1[3*ii+3].g = COUT_20(bin1[ii].g,bin1[ii+1].g,0,0) ; bout1[3*ii+1].b = COUT_00(bin1[ii].b,bin1[ii+1].b,0,0) ; bout1[3*ii+2].b = COUT_10(bin1[ii].b,bin1[ii+1].b,0,0) ; bout1[3*ii+3].b = COUT_20(bin1[ii].b,bin1[ii+1].b,0,0) ; bout2[3*ii+1] = bout1[3*ii+1] ; bout2[3*ii+2] = bout1[3*ii+2] ; bout2[3*ii+3] = bout1[3*ii+3] ; } /* do bottom corners */ bout1[0] = bout2[0] = bout2[1] = bout1[1] ; bout1[nxup-2] = bout1[nxup-1] = bout2[nxup-2] = bout2[nxup-1] = bout1[nxup-3] ; /* do first row of output as well */ bout3 = bout+nxup ; for( ii=0 ; ii < nxup ; ii++ ) bout[ii] = bout3[ii] ; MRI_COPY_AUX(outim,inim) ; RETURN(outim) ; }
static MRI_IMAGE * mri_dup2D_rgb2( MRI_IMAGE *inim ) { rgbyte *bin , *bout , *bin1,*bin2 , *bout1,*bout2 ; MRI_IMAGE *outim ; int ii,jj , nx,ny , nxup,nyup ; ENTRY("mri_dup2D_rgb2") ; if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL) ; bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL); /* make output image **/ nx = inim->nx ; ny = inim->ny ; nxup = 2*nx ; nyup = 2*ny ; outim = mri_new( nxup , nyup , MRI_rgb ) ; bout = (rgbyte *) MRI_RGB_PTR(outim) ; /** macros for the 4 different interpolations between the four corners: ul ur >=> 00 10 ll lr >=> 01 11 **/ #define DOUT(ul,ur,ll,lr,a,b,c,d) ((a*ul+b*ur+c*ll+d*lr) >> 4) #define DOUT_00(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,9,3,3,1) #define DOUT_10(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,3,9,1,3) #define DOUT_01(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,3,1,9,3) #define DOUT_11(ul,ur,ll,lr) DOUT(ul,ur,ll,lr,1,3,3,9) /** do r interpolations between ul ur ll lr for index #k, color #c **/ #define TWO_ROWS(k,c,ul,ur,ll,lr) \ { bout1[2*k+1].c = DOUT_00(ul.c,ur.c,ll.c,lr.c) ; \ bout1[2*k+2].c = DOUT_10(ul.c,ur.c,ll.c,lr.c) ; \ bout2[2*k+1].c = DOUT_01(ul.c,ur.c,ll.c,lr.c) ; \ bout2[2*k+2].c = DOUT_11(ul.c,ur.c,ll.c,lr.c) ; } /** do the above for all 3 colors */ #define TWO_RGB(k,ul,ur,ll,lr) { TWO_ROWS(k,r,ul,ur,ll,lr) ; \ TWO_ROWS(k,g,ul,ur,ll,lr) ; \ TWO_ROWS(k,b,ul,ur,ll,lr) ; } bin1 = bin ; /* 2 input rows */ bin2 = bin+nx ; bout1 = bout +nxup ; /* 2 output rows */ bout2 = bout1+nxup ; for( jj=0 ; jj < ny-1 ; jj++ ){ /* loop over input rows */ for( ii=0 ; ii < nx-1 ; ii++ ){ TWO_RGB(ii,bin1[ii],bin1[ii+1],bin2[ii],bin2[ii+1]) ; } /* at this point, output rows have elements [1..2*nx-2] filled; now copy [1] into [0] and [2*nx-2] into [2*nx-1] */ bout1[0] = bout1[1] ; bout2[0] = bout2[1] ; bout1[nxup-1] = bout1[nxup-2] ; bout2[nxup-1] = bout2[nxup-2] ; /* advance input and output rows */ bin1 = bin2; bin2 += nx ; bout1 = bout2+nxup; bout2 = bout1+nxup; } /* copy row 1 into row 0 */ bout1 = bout ; bout2 = bout1+nxup ; for( ii=0 ; ii < nxup ; ii++ ) bout1[ii] = bout2[ii] ; /* copy rown nyup-2 into row nyup-1 */ bout1 = bout + (nyup-2)*nxup ; bout2 = bout1+nxup ; for( ii=0 ; ii < nxup ; ii++ ) bout2[ii] = bout1[ii] ; MRI_COPY_AUX(outim,inim) ; RETURN(outim) ; }
int main( int argc , char * argv[] ) { THD_3dim_dataset * dset ; THD_dataxes * daxes ; FD_brick ** brarr , * baxi , * bsag , * bcor ; int iarg , ii ; Boolean ok ; MRI_IMAGE * pim , * flim , * slim ; float * flar ; dset_range dr ; float val , fimfac ; int ival,ityp , kk ; float xbot=BIGG,xtop=BIGG , ybot=BIGG,ytop=BIGG , zbot=BIGG,ztop=BIGG ; int xgood=0 , ygood=0 , zgood=0 , proj_code=PROJ_SUM , mirror_code=MIRR_NO , nsize=0 ; char root[THD_MAX_NAME] = "proj." ; char fname[THD_MAX_NAME] ; int ixbot=0,ixtop=0 , jybot=0,jytop=0 , kzbot=0,kztop=0 ; THD_fvec3 fv ; THD_ivec3 iv ; /*--- read command line arguments ---*/ if( argc < 2 || strncmp(argv[1],"-help",6) == 0 ) Syntax() ; INIT_EDOPT( &PRED_edopt ) ; iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ DB("new arg:",argv[iarg]) ; /**** check for editing option ****/ ii = EDIT_check_argv( argc , argv , iarg , &PRED_edopt ) ; if( ii > 0 ){ iarg += ii ; continue ; } /**** -sum or -max ****/ if( strncmp(argv[iarg],"-sum",6) == 0 ){ proj_code = PROJ_SUM ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-max",6) == 0 ){ proj_code = PROJ_MMAX ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-amax",6) == 0 ){ proj_code = PROJ_AMAX ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-smax",6) == 0 ){ proj_code = PROJ_SMAX ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-first") == 0 ){ /* 02 Nov 2000 */ proj_code = PROJ_FIRST ; first_thresh = strtod( argv[++iarg] , NULL ) ; iarg++ ; continue ; } /**** -mirror ****/ if( strncmp(argv[iarg],"-mirror",6) == 0 ){ mirror_code = MIRR_YES ; iarg++ ; continue ; } /**** -nsize ****/ if( strncmp(argv[iarg],"-nsize",6) == 0 ){ nsize = 1 ; iarg++ ; continue ; } /**** -output root ****/ if( strncmp(argv[iarg],"-output",6) == 0 || strncmp(argv[iarg],"-root",6) == 0 ){ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } MCW_strncpy( root , argv[++iarg] , THD_MAX_NAME-1 ) ; ii = strlen(root) ; if( ii == 0 ){ fprintf(stderr,"\n*** illegal rootname!\n") ; exit(-1) ; } if( root[ii-1] != '.' ){ root[ii] = '.' ; root[ii+1] = '\0' ; } iarg++ ; continue ; } /**** -ALL ****/ if( strncmp(argv[iarg],"-ALL",6) == 0 || strncmp(argv[iarg],"-all",6) == 0 ){ xgood = ygood = zgood = 1 ; xbot = ybot = zbot = -BIGG ; xtop = ytop = ztop = BIGG ; iarg++ ; continue ; } /**** -RL {all | x1 x2} ****/ if( strncmp(argv[iarg],"-RL",6) == 0 || strncmp(argv[iarg],"-LR",6) == 0 || strncmp(argv[iarg],"-rl",6) == 0 || strncmp(argv[iarg],"-lr",6) == 0 || strncmp(argv[iarg],"-sag",6)== 0 ){ char * cerr ; float tf ; xgood = 1 ; /* mark for x projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ xbot = -BIGG; xtop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } xbot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'R' && xbot > 0.0 ) xbot = -xbot ; xtop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'R' && xtop > 0.0 ) xtop = -xtop ; if( xbot > xtop ){ tf = xbot ; xbot = xtop ; xtop = tf ; } iarg +=3 ; continue ; } /**** -AP {all | y1 y2} ****/ if( strncmp(argv[iarg],"-AP",6) == 0 || strncmp(argv[iarg],"-PA",6) == 0 || strncmp(argv[iarg],"-ap",6) == 0 || strncmp(argv[iarg],"-pa",6) == 0 || strncmp(argv[iarg],"-cor",6)== 0 ){ char * cerr ; float tf ; ygood = 1 ; /* mark for y projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ ybot = -BIGG ; ytop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } ybot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'A' && ybot > 0.0 ) ybot = -ybot ; ytop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'A' && ytop > 0.0 ) ytop = -ytop ; if( ybot > ytop ){ tf = ybot ; ybot = ytop ; ytop = tf ; } iarg +=3 ; continue ; } /**** -IS {all | z1 z2} ****/ if( strncmp(argv[iarg],"-IS",6) == 0 || strncmp(argv[iarg],"-SI",6) == 0 || strncmp(argv[iarg],"-is",6) == 0 || strncmp(argv[iarg],"-si",6) == 0 || strncmp(argv[iarg],"-axi",6)== 0 ){ char * cerr ; float tf ; zgood = 1 ; /* mark for y projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ zbot = -BIGG ; ztop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } zbot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'I' && zbot > 0.0 ) zbot = -zbot ; ztop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'I' && ztop > 0.0 ) ztop = -ztop ; if( zbot > ztop ){ tf = zbot ; zbot = ztop ; ztop = tf ; } iarg +=3 ; continue ; } /**** unknown option ****/ fprintf(stderr,"\n*** Unknown option: %s\n",argv[iarg]) ; exit(-1) ; } /* end of loop over input options */ if( ! xgood && ! ygood && ! zgood ){ fprintf(stderr,"\n*** No projections ordered!?\n") ; exit(-1) ; } /*--- open dataset and set up to extract data slices ---*/ dset = THD_open_dataset( argv[iarg] ) ; if( dset == NULL ){ fprintf(stderr,"\n*** Can't open dataset file %s\n",argv[iarg]) ; exit(-1) ; } if( DSET_NUM_TIMES(dset) > 1 ){ fprintf(stderr,"\n*** Can't project time-dependent dataset!\n") ; exit(1) ; } EDIT_one_dataset( dset, &PRED_edopt ) ; daxes = dset->daxes ; brarr = THD_setup_bricks( dset ) ; baxi = brarr[0] ; bsag = brarr[1] ; bcor = brarr[2] ; /*--- determine index range for each direction ---*/ dr = PR_get_range( dset ) ; if( xgood ){ if( xbot < dr.xbot ) xbot = dr.xbot ; if( xtop > dr.xtop ) xtop = dr.xtop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xbot,0,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bsag , iv ) ; ixbot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xtop,0,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bsag , iv ) ; ixtop = iv.ijk[2] ; if( ixbot > ixtop ) { ii = ixbot ; ixbot = ixtop ; ixtop = ii ; } if( ixbot < 0 ) ixbot = 0 ; if( ixtop >= bsag->n3 ) ixtop = bsag->n3 - 1 ; } if( ygood ){ if( ybot < dr.ybot ) ybot = dr.ybot ; if( ytop > dr.ytop ) ytop = dr.ytop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ybot,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bcor , iv ) ; jybot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ytop,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bcor , iv ) ; jytop = iv.ijk[2] ; if( jybot > jytop ) { ii = jybot ; jybot = jytop ; jytop = ii ; } if( jybot < 0 ) jybot = 0 ; if( jytop >= bcor->n3 ) jytop = bcor->n3 - 1 ; } if( zgood ){ if( zbot < dr.zbot ) zbot = dr.zbot ; if( ztop > dr.ztop ) ztop = dr.ztop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,zbot) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( baxi , iv ) ; kzbot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,ztop) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( baxi , iv ) ; kztop = iv.ijk[2] ; if( kzbot > kztop ) { ii = kzbot ; kzbot = kztop ; kztop = ii ; } if( kzbot < 0 ) kzbot = 0 ; if( kztop >= baxi->n3 ) kztop = baxi->n3 - 1 ; } ival = DSET_PRINCIPAL_VALUE(dset) ; /* index to project */ ityp = DSET_BRICK_TYPE(dset,ival) ; /* type of this data */ fimfac = DSET_BRICK_FACTOR(dset,ival) ; /* scale factor of this data */ /*--- project the x direction, if desired ---*/ if( xgood ){ int n1 = bsag->n1 , n2 = bsag->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=ixbot ; ss <= ixtop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , bsag ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Sagittal projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Sagittal projection min = %g max = %g\n",fmin,fmax) ; strcpy(fname,root) ; strcat(fname,"sag") ; mri_write( fname, pim ) ; mri_free(pim) ; } /*--- project the y direction, if desired ---*/ if( ygood ){ int n1 = bcor->n1 , n2 = bcor->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=jybot ; ss <= jytop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , bcor ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Coronal projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Coronal projection min = %g max = %g\n",fmin,fmax) ; if( mirror_code == MIRR_YES ){ slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ; mri_free(pim) ; pim = slim ; } strcpy(fname,root) ; strcat(fname,"cor") ; mri_write( fname, pim ) ; mri_free(pim) ; } /*--- project the z direction, if desired ---*/ if( zgood ){ int n1 = baxi->n1 , n2 = baxi->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=kzbot ; ss <= kztop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , baxi ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Axial projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Axial projection min = %g max = %g\n",fmin,fmax) ; if( mirror_code == MIRR_YES ){ slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ; mri_free(pim) ; pim = slim ; } strcpy(fname,root) ; strcat(fname,"axi") ; mri_write( fname, pim ) ; mri_free(pim) ; } exit(0) ; }
static MRI_IMAGE * mri_dup2D_rgb4( MRI_IMAGE *inim ) { rgbyte *bin , *bout , *bin1,*bin2 , *bout1,*bout2,*bout3,*bout4 ; MRI_IMAGE *outim ; int ii,jj , nx,ny , nxup,nyup ; ENTRY("mri_dup2D_rgb4") ; if( inim == NULL || inim->kind != MRI_rgb ) RETURN(NULL); bin = (rgbyte *) MRI_RGB_PTR(inim); if( bin == NULL ) RETURN(NULL); /* make output image **/ nx = inim->nx ; ny = inim->ny ; nxup = 4*nx ; nyup = 4*ny ; outim = mri_new( nxup , nyup , MRI_rgb ) ; bout = (rgbyte *) MRI_RGB_PTR(outim) ; /** macros for the 16 different interpolations between the four corners: ul ur > 00 10 20 30 >=> 01 11 21 31 >=> 02 12 22 32 ll lr > 03 13 23 33 **/ #define BOUT(ul,ur,ll,lr,a,b,c,d) ((a*ul+b*ur+c*ll+d*lr) >> 6) #define BOUT_00(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,49, 7, 7, 1) #define BOUT_10(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,35,21, 5, 3) #define BOUT_20(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,21,35, 3, 5) #define BOUT_30(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 7,49, 1, 7) #define BOUT_01(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,35, 5,21, 3) #define BOUT_11(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,25,15,15, 9) #define BOUT_21(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,15,25, 9,15) #define BOUT_31(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 5,35, 3,21) #define BOUT_02(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,21, 3,35, 5) #define BOUT_12(ul,ur,ll,lr) BOUT(ul,ur,ll,lr,15, 9,25,15) #define BOUT_22(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 9,15,15,25) #define BOUT_32(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 3,21, 5,35) #define BOUT_03(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 7, 1,49, 7) #define BOUT_13(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 5, 3,35,21) #define BOUT_23(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 3, 5,21,35) #define BOUT_33(ul,ur,ll,lr) BOUT(ul,ur,ll,lr, 1, 7, 7,49) /** do 16 interpolations between ul ur ll lr for index #k, color #c **/ #define FOUR_ROWS(k,c,ul,ur,ll,lr) \ { bout1[4*k+2].c = BOUT_00(ul.c,ur.c,ll.c,lr.c) ; \ bout1[4*k+3].c = BOUT_10(ul.c,ur.c,ll.c,lr.c) ; \ bout1[4*k+4].c = BOUT_20(ul.c,ur.c,ll.c,lr.c) ; \ bout1[4*k+5].c = BOUT_30(ul.c,ur.c,ll.c,lr.c) ; \ bout2[4*k+2].c = BOUT_01(ul.c,ur.c,ll.c,lr.c) ; \ bout2[4*k+3].c = BOUT_11(ul.c,ur.c,ll.c,lr.c) ; \ bout2[4*k+4].c = BOUT_21(ul.c,ur.c,ll.c,lr.c) ; \ bout2[4*k+5].c = BOUT_31(ul.c,ur.c,ll.c,lr.c) ; \ bout3[4*k+2].c = BOUT_02(ul.c,ur.c,ll.c,lr.c) ; \ bout3[4*k+3].c = BOUT_12(ul.c,ur.c,ll.c,lr.c) ; \ bout3[4*k+4].c = BOUT_22(ul.c,ur.c,ll.c,lr.c) ; \ bout3[4*k+5].c = BOUT_32(ul.c,ur.c,ll.c,lr.c) ; \ bout4[4*k+2].c = BOUT_03(ul.c,ur.c,ll.c,lr.c) ; \ bout4[4*k+3].c = BOUT_13(ul.c,ur.c,ll.c,lr.c) ; \ bout4[4*k+4].c = BOUT_23(ul.c,ur.c,ll.c,lr.c) ; \ bout4[4*k+5].c = BOUT_33(ul.c,ur.c,ll.c,lr.c) ; } /** do the above for all 3 colors */ #define FOUR_RGB(k,ul,ur,ll,lr) { FOUR_ROWS(k,r,ul,ur,ll,lr) ; \ FOUR_ROWS(k,g,ul,ur,ll,lr) ; \ FOUR_ROWS(k,b,ul,ur,ll,lr) ; } bin1 = bin ; /* 2 input rows */ bin2 = bin+nx ; bout1 = bout+2*nxup ; /* 4 output rows */ bout2 = bout1+nxup ; bout3 = bout2+nxup ; bout4 = bout3+nxup ; for( jj=0 ; jj < ny-1 ; jj++ ){ /* loop over input rows */ for( ii=0 ; ii < nx-1 ; ii++ ){ FOUR_RGB(ii,bin1[ii],bin1[ii+1],bin2[ii],bin2[ii+1]) ; } /* at this point, output rows have elements [2..4*nx-3] filled; now copy [2] into [0..1] and [4*nx-3] into [4*nx-2..4*nx-1] */ bout1[0] = bout1[1] = bout1[2] ; bout2[0] = bout2[1] = bout2[2] ; bout3[0] = bout3[1] = bout3[2] ; bout4[0] = bout4[1] = bout4[2] ; bout1[nxup-2] = bout1[nxup-1] = bout1[nxup-2] ; bout2[nxup-2] = bout2[nxup-1] = bout2[nxup-2] ; bout3[nxup-2] = bout3[nxup-1] = bout3[nxup-2] ; bout4[nxup-2] = bout4[nxup-1] = bout4[nxup-2] ; /* advance input and output rows */ bin1 = bin2; bin2 += nx ; bout1 = bout4+nxup; bout2 = bout1+nxup; bout3 = bout2+nxup; bout4 = bout3+nxup; } /* copy row 2 into rows 0 and row 1 */ bout1 = bout ; bout2 = bout1+nxup ; bout3 = bout2+nxup ; for( ii=0 ; ii < nxup ; ii++ ) bout1[ii] = bout2[ii] = bout3[ii] ; /* copy rown nyup-3 into rows nyup-2 and nyup-1 */ bout1 = bout + (nyup-3)*nxup ; bout2 = bout1+nxup ; bout3 = bout2+nxup ; for( ii=0 ; ii < nxup ; ii++ ) bout2[ii] = bout3[ii] = bout1[ii] ; MRI_COPY_AUX(outim,inim) ; RETURN(outim) ; }