pulsesequence() { /* Acquisition variables */ double dw; /* nominal dwell time, = 1/sw */ double aqtm = getval("aqtm"); /* Delay variables */ double tref, te_delay1, te_delay2, tr_delay, ti_delay, del1, del2, del3, del4, del5, /* before and after diffusion gradients */ busy1, busy2, /* time spent on rf pulses etc. in TE periods */ seqtime, invTime; int use_minte; /* RF and receiver frequency variables */ double freq90[MAXNSLICE],freq180[MAXNSLICE],freqIR[MAXNSLICE]; /* frequencies for multi-slice */ int shape90=0, shape180=0, shapeIR=0; /* List ID for RF shapes */ double roff1, roff2, roffn; /* Receiver offsets when FOV is offset along readout */ /* Gradient amplitudes, may vary depending on "image" parameter */ double peramp, perinc, peamp, roamp, roramp; /* diffusion variables */ #define MAXDIR 1024 /* Will anybody do more than 1024 directions or b-values? */ int diff_in_one = 0; double tmp, tmp_ss2; double roarr[MAXDIR], pearr[MAXDIR], slarr[MAXDIR]; int nbval, /* Total number of bvalues*directions */ nbro, nbpe, nbsl; /* bvalues*directions along RO, PE, and SL */ double bro[MAXDIR], bpe[MAXDIR], bsl[MAXDIR], /* b-values along RO, PE, SL */ brs[MAXDIR], brp[MAXDIR], bsp[MAXDIR], /* the cross-terms */ btrace[MAXDIR], /* and the trace */ max_bval=0, dcrush, dgss2, /* "delta" for crusher and gss2 gradients */ Dro, Dcrush, Dgss2; /* "DELTA" for readout, crusher and gss2 gradients */ /* loop variable */ int i; /* Real-time variables used in this sequence **************/ int vms_slices = v3; // Number of slices int vms_ctr = v4; // Slice loop counter int vnseg = v5; // Number of segments int vnseg_ctr = v6; // Segment loop counter int vetl = v7; // Number of choes in readout train int vetl_ctr = v8; // etl loop counter int vblip = v9; // Sign on blips in multi-shot experiment int vssepi = v10; // Number of Gradient Steady States lobes int vssepi_ctr = v11; // Steady State counter int vacquire = v12; // Argument for setacqvar, to skip steady states /******************************************************/ /* VARIABLE INITIALIZATIONS ***************************/ /******************************************************/ get_parameters(); euler_test(); if (tep < 0) { // adjust by reducing gpropdelay by that amount gpropdelay += tep; tep = 0; } setacqmode(WACQ|NZ); // Necessary for variable rate sampling use_minte = (minte[0] == 'y'); /******************************************************/ /* CALCULATIONS ***************************************/ /******************************************************/ if (ix == 1) { /* Calculate RF pulse */ init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2); calc_rf(&p1_rf,"tpwr1","tpwr1f"); /* Calculate gradients: */ init_slice(&ss_grad,"ss",thk); calc_slice(&ss_grad, &p1_rf,WRITE,"gss"); init_slice_refocus(&ssr_grad,"ssr"); calc_slice_refocus(&ssr_grad, &ss_grad, WRITE,"gssr"); if (spinecho[0] == 'y') { init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof1); calc_rf(&p2_rf,"tpwr2","tpwr2f"); init_slice_butterfly(&ss2_grad,"ss2",thk,gcrush,tcrush); calc_slice(&ss2_grad,&p2_rf,WRITE,"gss2"); } else ss2_grad.duration = 0; /* used for diffusion calculations */ init_readout(&epiro_grad,"epiro",lro,np,sw); init_readout_refocus(&ror_grad,"ror"); init_phase(&epipe_grad, "epipe",lpe,nv); init_phase(&per_grad,"per",lpe,nv); init_readout(&nav_grad,"nav",lro,np,sw); init_epi(&epi_grad); if (!strcmp(orient,"oblique")) { if ((phi != 90) || (psi != 90) || (theta != 90)) { /* oblique slice - this should take care of most cases */ epiro_grad.slewRate /= 3; /* = gmax/trise */ epipe_grad.slewRate /= 3; } } calc_epi(&epi_grad,&epiro_grad,&epipe_grad,&ror_grad,&per_grad,&nav_grad,NOWRITE); /* Make sure the slice refocus, readout refocus, and phase dephaser fit in the same duration */ tref = calc_sim_gradient(&ror_grad, &per_grad, &null_grad, getval("tpe"), WRITE); if (sgldisplay) displayEPI(&epi_grad); /* calc_sim_gradient recalculates per_grad, so reset its base amplitude for centric ordering or fractional k-space*/ switch(ky_order[0]) { case 'l': per_grad.amp *= (fract_ky/(epipe_grad.steps/2)); break; case 'c': per_grad.amp = (nseg/2-1)*per_grad.increment; break; } if (ir[0] == 'y') { init_rf(&ir_rf,pipat,pi,flipir,rof1,rof1); calc_rf(&ir_rf,"tpwri","tpwrif"); init_slice_butterfly(&ssi_grad,"ssi",thk,gcrush,tcrush); calc_slice(&ssi_grad,&ir_rf,WRITE,"gssi"); } if (fsat[0] == 'y') { create_fatsat(); } if (diff[0] == 'y') { init_generic(&diff_grad,"diff",gdiff,tdelta); diff_grad.maxGrad = gmax; calc_generic(&diff_grad,NOWRITE,"",""); /* adjust duration, so tdelta is from start ramp up to start ramp down */ if (ix == 1) { diff_grad.duration += diff_grad.tramp; calc_generic(&diff_grad,WRITE,"",""); } } /* Acquire top-down or bottom-up ? */ if (ky_order[1] == 'r') { epipe_grad.amp *= -1; per_grad.amp *= -1; per_grad.increment *= -1; } } /* end gradient setup if ix == 1 */ /* Load table used to determine multi-shot direction */ settable(t2,(int) nseg,epi_grad.table2); /* What is happening in the 2 TE/2 periods (except for diffusion)? */ busy1 = ss_grad.rfCenterBack + ssr_grad.duration; busy2 = tep + nav_grad.duration*(epi_grad.center_echo + 0.5); if (navigator[0] == 'y') busy2 += (tep + nav_grad.duration + per_grad.duration); /* How much extra time do we have in each TE/2 period? */ if (spinecho[0] == 'y') { busy1 += (GDELAY + ss2_grad.rfCenterFront); busy2 += ss2_grad.rfCenterBack; temin = MAX(busy1,busy2)*2; if (use_minte) te = temin; te_delay1 = te/2 - busy1; te_delay2 = te/2 - busy2; if (temin > te) { /* Use min TE and try and catch further violations of min TE */ te_delay1 = temin/2 - busy1; te_delay2 = temin/2 - busy2; } } else { /* Gradient echo */ temin = (busy1 + busy2); if (use_minte) te = temin; te_delay1 = te - temin; te_delay2 = 0; if (temin > te) te_delay1 = 0; } /* Now fill in the diffusion delays: del1 = between 90 and 1st diffusion gradient del2 = after 1st diffusion gradient del3 = before 2nd diffusion gradient when both in same TE/2 period del4 = before 2nd diffusion gradient when in different TE/2 period del5 = before acquisition Ie, the order is: 90 - del1 - diff - del2 - (diff - del3) - 180 - (del4 - diff) - del5 - acq where one and only one of the two options (diff - del3) or (del4 - diff) is used */ if (diff[0] == 'y') { tmp_ss2 = GDELAY + ss2_grad.duration; /* ss2 grad + 4us delay */ del1 = del2 = del3 = del4 = del5 = 0; if (tDELTA < (diff_grad.duration + tmp_ss2)) /* Minimum DELTA */ abort_message("ERROR %s: tDELTA is too short, minimum is %.2fms\n", seqfil,(diff_grad.duration + tmp_ss2)*1000+0.005); if (tDELTA + diff_grad.duration > te_delay1 + tmp_ss2 + te_delay2) { if (!use_minte) { abort_message("ERROR %s: Maximum tDELTA is %.2fms", seqfil,te_delay1 + ss2_grad.duration + te_delay2 - diff_grad.duration); } else { tmp = (tDELTA + diff_grad.duration) - (te_delay1 + tmp_ss2 + te_delay2); if (spinecho[0] == 'y') { te_delay1 += (tmp/2); te_delay2 += (tmp/2); } else te_delay1 += tmp; temin += tmp; } } if (spinecho[0] == 'y') { if (te_delay1 >= (tDELTA + diff_grad.duration)) { /* Put them both in 1st TE/2 period, */ diff_in_one = (diff[0] == 'y'); /* no need to increase temin */ del2 = tDELTA - diff_grad.duration; /* time between diffusion gradients */ del3 = te_delay1 - (tDELTA+diff_grad.duration); /* time after diffusion gradients */ del5 = te_delay2; /* delay in second TE/2 period */ } else { /* put them on each side of the 180 */ diff_in_one = 0; busy1 += diff_grad.duration; busy2 += diff_grad.duration; temin = 2*MAX(busy1,busy2); /* Optimally, the 2nd diff grad is right after the 180 */ del2 = tDELTA - diff_grad.duration - tmp_ss2; /* This is always > 0, or we would have aborted above */ del1 = te_delay1 - (diff_grad.duration + del2); if (del1 < 0) { del1 = 0; /* Place the 1st right after the 90 and push the 2nd out */ del4 = tDELTA - te_delay1 - ss2_grad.duration; } del5 = te_delay2 - (del4 + diff_grad.duration); /* del5 could still be < 0, when te_delay2 < diff_grad.duration */ if (del5 < 0) { del1 += fabs(del5); /* Increase each TE/2 period by abs(del5) */ del5 = 0; } } } else { /* gradient echo */ diff_in_one = (diff[0] == 'y'); del1 = 0; del2 = tDELTA - diff_grad.duration; /* time between diffusion gradients */ del3 = 0; del4 = 0; if (!use_minte) /* user defined TE */ del5 = te_delay1 - (tDELTA + diff_grad.duration); } } /* End of Diffusion block */ else { del1 = te_delay1; del5 = te_delay2; del2 = del3 = del4 = 0; } if (sgldisplay) { text_message("busy1/2, temin = %f, %f, %f",busy1*1e3, busy2*1e3, temin*1e3); text_message("te_delay1/2 = %f, %f",te_delay1*1e3, te_delay2*1e3); text_message("delays 1-5: %.2f, %.2f, %.2f, %.2f, %.2fms\n",del1*1000,del2*1000,del3*1000,del4*1000,del5*1000); } /* Check if TE is long enough */ temin = ceil(temin*1e6)/1e6; /* round to nearest us */ if (use_minte) { te = temin; putvalue("te",te); } else if (temin > te) { abort_message("TE too short, minimum is %.2f ms\n",temin*1000); } if (ir[0] == 'y') { ti_delay = ti - (pi*ssi_grad.rfFraction + rof2 + ssi_grad.rfDelayBack) - (ss_grad.rfDelayFront + rof1 + p1*(1-ss_grad.rfFraction)); if (ti_delay < 0) { abort_message("TI too short, minimum is %.2f ms\n",(ti-ti_delay)*1000); } } else ti_delay = 0; invTime = GDELAY + ssi_grad.duration + ti_delay; /* Minimum TR per slice, w/o options */ seqtime = GDELAY + ss_grad.rfCenterFront // Before TE + te + (epiro_grad.duration - nav_grad.duration*(epi_grad.center_echo+0.5)); // After TE /* Add in time for options outside of TE */ if (ir[0] == 'y') seqtime += invTime; if (fsat[0] == 'y') seqtime += fsatTime; trmin = seqtime + 4e-6; /* ensure a minimum of 4us in tr_delay */ trmin *= ns; if (tr - trmin < 0.0) { abort_message("%s: Requested tr too short. Min tr = %.2f ms\n", seqfil,ceil(trmin*100000)/100.00); } /* spread out multi-slice acquisition over total TR */ tr_delay = (tr - ns*seqtime)/ns; /******************************************************/ /* Return gradient values to VnmrJ interface */ /******************************************************/ putvalue("etl",epi_grad.etl+2*ssepi); putvalue("gro",epiro_grad.amp); putvalue("rgro",epiro_grad.tramp); putvalue("gror",ror_grad.amp); putvalue("tror",ror_grad.duration); putvalue("rgror",ror_grad.tramp); putvalue("gpe",epipe_grad.amp); putvalue("rgpe",epipe_grad.tramp); putvalue("gped",per_grad.amp); putvalue("tped",per_grad.duration); putvalue("rgped",per_grad.tramp); putvalue("gss",ss_grad.amp); putvalue("gss2",ss2_grad.ssamp); putvalue("rgss",ss_grad.tramp); putvalue("gssr",ssr_grad.amp); putvalue("tssr",ssr_grad.duration); putvalue("rgssr",ssr_grad.tramp); putvalue("rgss2",ss2_grad.crusher1RampToSsDuration); putvalue("rgssi",ssi_grad.crusher1RampToSsDuration); putvalue("rgcrush",ssi_grad.crusher1RampToCrusherDuration); putvalue("at_full",epi_grad.duration); putvalue("at_one",nav_grad.duration); putvalue("rcrush",ss2_grad.crusher1RampToCrusherDuration); putvalue("np_ramp",epi_grad.np_ramp); putvalue("np_flat",epi_grad.np_flat); if (diff[0] == 'y') { /* CALCULATE B VALUES */ /* Get multiplication factors and make sure they have same # elements */ /* All this is only necessary because putCmd only work for ix==1 */ nbro = (int) getarray("dro",roarr); nbval = nbro; nbpe = (int) getarray("dpe",pearr); if (nbpe > nbval) nbval = nbpe; nbsl = (int) getarray("dsl",slarr); if (nbsl > nbval) nbval = nbsl; if ((nbro != nbval) && (nbro != 1)) abort_message("%s: Number of directions/b-values must be the same for all axes (readout)",seqfil); if ((nbpe != nbval) && (nbpe != 1)) abort_message("%s: Number of directions/b-values must be the same for all axes (phase)",seqfil); if ((nbsl != nbval) && (nbsl != 1)) abort_message("%s: Number of directions/b-values must be the same for all axes (slice)",seqfil); if (nbro == 1) for (i = 1; i < nbval; i++) roarr[i] = roarr[0]; if (nbpe == 1) for (i = 1; i < nbval; i++) pearr[i] = pearr[0]; if (nbsl == 1) for (i = 1; i < nbval; i++) slarr[i] = slarr[0]; } else { nbval = 1; roarr[0] = 0; pearr[0] = 0; slarr[0] = 0; } for (i = 0; i < nbval; i++) { /* We need to worry about slice gradients & crushers for slice gradients */ /* Everything else is outside diffusion gradients, and thus constant */ /* for all b-values/directions */ /* Readout */ bro[i] = bval(gdiff*roarr[i],tdelta,tDELTA); /* Phase */ bpe[i] = bval(gdiff*pearr[i],tdelta,tDELTA); /* Slice */ dgss2 = p2/2; Dgss2 = dgss2; dcrush = tcrush; Dcrush = dcrush + p2; bsl[i] = bval(gdiff*slarr[i],tdelta,tDELTA); if (spinecho[0] == 'y') { bsl[i] += bval(ss2_grad.ssamp,dgss2,Dgss2); bsl[i] += bval(gcrush,dcrush,Dcrush); bsl[i] += bval_nested(gcrush,dcrush,Dcrush,ss2_grad.ssamp,dgss2,Dgss2); } if (!diff_in_one) { bsl[i] += bval_nested(gdiff*slarr[i],tdelta,tDELTA,gcrush,dcrush,Dcrush); bsl[i] += bval_nested(gdiff*slarr[i],tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2); } /* Readout/Slice Cross-terms */ brs[i] = bval2(gdiff*roarr[i],gdiff*slarr[i],tdelta,tDELTA); if (spinecho[0] == 'y') { brs[i] += bval_cross(gdiff*roarr[i],tdelta,tDELTA,gcrush,dcrush,Dcrush); brs[i] += bval_cross(gdiff*roarr[i],tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2); } /* Readout/Phase Cross-terms */ brp[i] = bval2(gdiff*roarr[i],gdiff*pearr[i],tdelta,tDELTA); /* Slice/Phase Cross-terms */ bsp[i] = bval2(gdiff*slarr[i],gdiff*pearr[i],tdelta,tDELTA); bsp[i] += bval_cross(gdiff*pearr[i],tdelta,tDELTA,gcrush,dcrush,Dcrush); bsp[i] += bval_cross(gdiff*pearr[i],tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2); btrace[i] = (bro[i]+bsl[i]+bpe[i]); if (max_bval < btrace[i]) { max_bval = (bro[i]+bsl[i]+bpe[i]); } } /* End for-all-directions */ putarray("bvalrr",bro,nbval); putarray("bvalpp",bpe,nbval); putarray("bvalss",bsl,nbval); putarray("bvalrp",brp,nbval); putarray("bvalrs",brs,nbval); putarray("bvalsp",bsp,nbval); putarray("bvalue",btrace,nbval); putvalue("max_bval",max_bval); /* Set all gradients depending on whether we do */ /* Use separate variables, because we only initialize & calculate gradients for ix==1 */ peamp = epipe_grad.amp; perinc = per_grad.increment; peramp = per_grad.amp; roamp = epiro_grad.amp; roramp = ror_grad.amp; switch ((int)image) { case 1: /* Real image scan, don't change anything */ break; case 0: /* Normal reference scan */ peamp = 0; perinc = 0; peramp = 0; roamp = epiro_grad.amp; roramp = ror_grad.amp; break; case -1: /* Inverted image scan */ roamp = -epiro_grad.amp; roramp = -ror_grad.amp; break; case -2: /* Inverted reference scan */ peamp = 0; perinc = 0; peramp = 0; roamp = -epiro_grad.amp; roramp = -ror_grad.amp; break; default: break; } /* Generate phase-ramped pulses: 90, 180, and IR */ offsetlist(pss,ss_grad.ssamp,0,freq90,ns,seqcon[1]); shape90 = shapelist(p1pat,ss_grad.rfDuration,freq90,ns,0,seqcon[1]); if (spinecho[0] == 'y') { offsetlist(pss,ss2_grad.ssamp,0,freq180,ns,seqcon[1]); shape180 = shapelist(p2pat,ss2_grad.rfDuration,freq180,ns,0,seqcon[1]); } if (ir[0] == 'y') { offsetlist(pss,ssi_grad.ssamp,0,freqIR,ns,seqcon[1]); shapeIR = shapelist(pipat,ssi_grad.rfDuration,freqIR,ns,0,seqcon[1]); } sgl_error_check(sglerror); roff1 = -poffset(pro,epi_grad.amppos); roff2 = -poffset(pro,epi_grad.ampneg); roffn = -poffset(pro,nav_grad.amp); roff1 = -poffset(pro,epi_grad.amppos*roamp/epiro_grad.amp); roff2 = -poffset(pro,epi_grad.ampneg*roamp/epiro_grad.amp); roffn = -poffset(pro,nav_grad.amp); dw = granularity(1/sw,1/epi_grad.ddrsr); /* Total Scan Time */ g_setExpTime(tr*nt*nseg*arraydim); /******************************************************/ /* PULSE SEQUENCE *************************************/ /******************************************************/ rotate(); F_initval(epi_grad.etl/2, vetl); /* vetl is the loop counter in the acquisition loop */ /* that includes both a positive and negative readout lobe */ F_initval(nseg, vnseg); /* NB. F_initval(-ssepi,vssepi); currently gives errors */ initval(-ssepi,vssepi); /* gradient steady state lobes */ obsoffset(resto); delay(GDELAY); ifzero(rtonce); grad_advance(gpropdelay); endif(rtonce); loop(vnseg,vnseg_ctr); /* Loop through segments in segmented EPI */ msloop(seqcon[1],ns,vms_slices,vms_ctr); /* Multislice loop */ assign(vssepi,vssepi_ctr); sp1on(); delay(4e-6); sp1off(); /* Output trigger to look at scope */ if (ticks) { xgate(ticks); grad_advance(gpropdelay); delay(4e-6); } getelem(t2,vnseg_ctr,vblip); /* vblip = t2[vnseg_ctr]; either 1 or -1 for pos/neg blip */ /* Optional FAT SAT */ if (fsat[0] == 'y') { fatsat(); } /* Optional IR + TI delay */ if (ir[0] == 'y') { obspower(ir_rf.powerCoarse); obspwrf(ir_rf.powerFine); delay(GDELAY); obl_shapedgradient(ssi_grad.name,ssi_grad.duration,0.0,0.0,ssi_grad.amp,NOWAIT); delay(ssi_grad.rfDelayBack); shapedpulselist(shapeIR,ssi_grad.rfDuration,oph,rof1,rof1,seqcon[1],vms_ctr); delay(ssi_grad.rfDelayBack); delay(ti_delay); } /* 90 ss degree pulse */ obspower(p1_rf.powerCoarse); obspwrf(p1_rf.powerFine); delay(GDELAY); obl_shapedgradient(ss_grad.name,ss_grad.duration,0.0,0.0,ss_grad.amp,NOWAIT); delay(ss_grad.rfDelayFront); shapedpulselist(shape90,p1_rf.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr); delay(ss_grad.rfDelayBack); /* Slice refocus */ obl_shapedgradient(ssr_grad.name,ssr_grad.duration,0,0,-ssr_grad.amp,WAIT); delay(del1); if (diff[0] == 'y') obl_shapedgradient(diff_grad.name,diff_grad.duration, diff_grad.amp*dro,diff_grad.amp*dpe,diff_grad.amp*dsl,WAIT); delay(del2); if (diff_in_one) obl_shapedgradient(diff_grad.name,diff_grad.duration, -diff_grad.amp*dro,-diff_grad.amp*dpe,-diff_grad.amp*dsl,WAIT); delay(del3); /* Optional 180 ss degree pulse with crushers */ if (spinecho[0] == 'y') { obspower(p2_rf.powerCoarse); obspwrf(p2_rf.powerFine); delay(GDELAY); obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0.0,0.0,ss2_grad.amp,NOWAIT); delay(ss2_grad.rfDelayFront); shapedpulselist(shape180,ss2_grad.rfDuration,oph,rof1,rof1,seqcon[1],vms_ctr); delay(ss2_grad.rfDelayBack); } delay(del4); if ((diff[0] == 'y') && !diff_in_one) obl_shapedgradient(diff_grad.name,diff_grad.duration, diff_grad.amp*dro,diff_grad.amp*dpe,diff_grad.amp*dsl,WAIT); delay(del5); /* Optional navigator echo */ if (navigator[0] == 'y') { obl_shapedgradient(ror_grad.name,ror_grad.duration,roramp,0,0,WAIT); obl_shapedgradient(nav_grad.name,nav_grad.duration, -nav_grad.amp,0,0,NOWAIT); delay(tep); roff = roffn; /* Set receiver offset for navigator gradient */ delay(epi_grad.skip-alfa); /* ramp up */ startacq(alfa); for(i=0;i<np/2;i++){ sample(dw); delay((epi_grad.dwell[i] - dw)); } sample(aqtm-at); endacq(); delay(epi_grad.skip - dw - (aqtm-at)); /* Phase encode dephaser here if navigator echo was acquired */ var_shapedgradient(per_grad.name,per_grad.duration,0,-peramp,0,perinc,vnseg_ctr,WAIT); } else { var_shapedgradient(per_grad.name,per_grad.duration, -roramp,-peramp,0,perinc,vnseg_ctr,WAIT); } /* Start readout and phase encode gradient waveforms, NOWAIT */ /* If alternating ky-ordering, get polarity on blips from table */ var_shaped3gradient(epiro_grad.name,epipe_grad.name,"", /* patterns */ epiro_grad.duration, /* duration */ roamp,0,0, /* amplitudes */ peamp,vblip, /* step and multiplier */ NOWAIT); /* Don't wait */ delay(tep); /* Acquisition loop */ assign(one,vacquire); // real-time acquire flag nowait_loop(epi_grad.etl/2 + ssepi,vetl,vetl_ctr); ifzero(vssepi_ctr); //vssepi_ctr = -ssepi, -ssepi+1, ..., 0, 1,2,... assign(zero,vacquire); // turn on acquisition after all ss lobes endif(vssepi_ctr); incr(vssepi_ctr); setacqvar(vacquire); // Set acquire flag roff = roff1; /* Set receiver offset for positive gradient */ delay(epi_grad.skip-alfa); /* ramp up */ startacq(alfa); for(i=0;i<np/2;i++){ sample(dw); //dw = 1/sw delay((epi_grad.dwell[i] - dw)); } if (aqtm > at) sample(aqtm-at); endacq(); delay(epi_grad.skip - dw - (aqtm-at)); roff = roff2; /* Set receiver offset for negative gradient */ delay(epi_grad.skip-alfa); startacq(alfa); for(i=0;i<np/2;i++){ sample(dw); delay((epi_grad.dwell[i] - dw)); } if (aqtm > at) sample(aqtm-at); endacq(); delay(epi_grad.skip - dw - (aqtm-at)); nowait_endloop(vetl_ctr); delay(tr_delay); endmsloop(seqcon[1],vms_ctr); /* end multislice loop */ endloop(vnseg_ctr); /* end segments loop */ } /* end pulsesequence */
pulsesequence() { double freq,fstart,fend; double attn,attnd,attnd2,attnd3,attnd4,tattn;/* 5 channels supported */ double tunesw,tuneswd,tuneswd2,tuneswd3,tuneswd4,tsw; double gain,gaind,gaind2,gaind3,gaind4,tgain; int chan; double offset_sec; int np2; int nfv,index; nfv = (int) getval("nf"); np2 = np / 2; status(A); /* getRealSetDefault reduces logic - not in Inova */ getRealSetDefault(CURRENT,"tunesw",&tunesw,10000000.0); getRealSetDefault(CURRENT,"tuneswd",&tuneswd,tunesw); getRealSetDefault(CURRENT,"tuneswd2",&tuneswd2,tunesw); getRealSetDefault(CURRENT,"tuneswd3",&tuneswd3,tunesw); getRealSetDefault(CURRENT,"tuneswd4",&tuneswd4,tunesw); getRealSetDefault(CURRENT,"tupwr",&attn,10.0); getRealSetDefault(CURRENT,"tupwrd",&attnd,10.0); getRealSetDefault(CURRENT,"tupwrd2",&attnd2,10.0); getRealSetDefault(CURRENT,"tupwrd3",&attnd3,10.0); getRealSetDefault(CURRENT,"tupwrd4",&attnd4,10.0); getRealSetDefault(CURRENT,"gain",&gain,10.0); getRealSetDefault(CURRENT,"gaind",&gaind,gain); getRealSetDefault(CURRENT,"gaind2",&gaind2,gain); getRealSetDefault(CURRENT,"gaind3",&gaind3,gain); getRealSetDefault(CURRENT,"gaind4",&gaind4,gain); offset_sec = (0.5 / sw); setacqmode(WACQ|NZ); for (index = 0; index < nf; index++) { switch(index) { case 0: chan = OBSch; freq = sfrq; tattn = attn; tgain = gain; tsw = tunesw; break; case 1: chan = DECch; freq = dfrq; tattn = attnd; tgain = gaind; tsw = tuneswd; break; case 2: chan = DEC2ch; freq = dfrq2; tattn = attnd2; tgain = gaind2; tsw = tuneswd2; break; case 3: chan = DEC3ch; freq = dfrq3; tattn = attnd3; tgain = gaind3; tsw = tuneswd3; break; case 4: chan = DEC4ch; freq = dfrq4; tattn = attnd4; tgain = gaind4; tsw = tuneswd4; break; default: exit(-1); } fstart = freq - (tsw/2) * 1e-6; fend = freq + (tsw/2) * 1.0e-6; //printf("channel = %d frequency = %f\n",chan,freq); //printf("channel = %d frequency span = %f\n",chan, tsw); //printf("start=%f stop = %f\n",fstart,fend); //printf("gain = %f power = %f\n",tgain,tattn); hsdelay(d1); set4Tune(chan,tgain); assign(zero,oph); genPower(tattn,chan); delay(0.001); startacq(alfa); SweepNOffsetAcquire(fstart, fend, np2, chan, offset_sec); endacq(); delay(0.001); } }
void pulsesequence() { double gzlvlE = getval("gzlvlE"), gtE = getval("gtE"), EDratio = getval("EDratio"), gstab = getval("gstab"), mult = getval("mult"), pwx180 = getval("pwx180"), pwxlvl180 = getval("pwxlvl180"), pwx180r = getval("pwx180r"), pwxlvl180r = getval("pwxlvl180r"), hsglvl = getval("hsglvl"), hsgt = getval("hsgt"), tauA=getval("tauA"), //compensation for tauB and tauD tauB=getval("tauB"), //effect of rof2 tauD=getval("tauD"), //effect of alfa tBal=getval("tBal"), //supports inova console if ~1/(fb*1.3) pwr_XBIP = getval("pwr_XBIP"), pw_XBIP = getval("pw_XBIP"), pwr_HBIP = getval("pwr_HBIP"), pw_HBIP = getval("pw_HBIP"), gzlvlcr = getval("gzlvlcr"), gtcr = getval("gtcr"), //crusher gradient in BIRD npoints = getval("npoints"), // npoints should be an integer multiple of np tau, evolcorr, taug,cycles; int prgcycle = (int)(getval("prgcycle")+0.5), phase1 = (int)(getval("phase")+0.5), icosel, ZZgsign; char pwx180ad[MAXSTR], pwx180adR[MAXSTR], pwx180ref[MAXSTR], shp_XBIP[MAXSTR], shp_HBIP[MAXSTR], BIRD[MAXSTR], BIRDmode[MAXSTR]; //synchronize gradients to srate for probetype='nano' // Preserve gradient "area" gtE = syncGradTime("gtE","gzlvlE",0.5); gzlvlE = syncGradLvl("gtE","gzlvlE",0.5); getstr("pwx180ad", pwx180ad); getstr("pwx180adR", pwx180adR); getstr("pwx180ref", pwx180ref); getstr("shp_XBIP",shp_XBIP); getstr("shp_HBIP",shp_HBIP); getstr("BIRD",BIRD); getstr("BIRDmode",BIRDmode); tau = 1 / (4*(getval("j1xh"))); evolcorr = (4*pwx/PI)+2*pw+8.0e-6; cycles=np/npoints; cycles = (double)((int)((cycles))); initval(cycles,v20); if (mult > 0.5) taug = 2*tau + getval("tauC"); else taug = gtE + gstab + 2 * GRADIENT_DELAY; ZZgsign=-1; if (mult == 2) ZZgsign=1; icosel = 1; assign(ct,v17); assign(zero,v18); assign(zero,v19); if (getflag("prgflg") && (satmode[0] == 'y') && (prgcycle > 1.5)) { hlv(ct,v17); mod2(ct,v18); dbl(v18,v18); if (prgcycle > 2.5) { hlv(v17,v17); hlv(ct,v19); mod2(v19,v19); dbl(v19,v19); } } if (BIRD[0]=='n') //gHSQC phases { settable(t1,4,ph1); settable(t2,2,ph2); settable(t3,8,ph3); settable(t4,16,ph4); settable(t5,16,ph5); } else //rtgHSQC-BIRD phases { settable(t1,8,ph11); settable(t2,2,ph12); settable(t3,16,ph13); settable(t4,32,ph14); settable(t5,32,ph15); settable(t7,4,ph17); settable(t8,4,ph18); settable(t9,4,ph19); getelem(t7, v17, v7); getelem(t8, v17, v8); getelem(t9, v17, v9); } getelem(t1, v17, v1); getelem(t3, v17, v3); getelem(t4, v17, v4); getelem(t2, v17, v2); getelem(t5, v17, oph); assign(zero,v6); add(oph,v18,oph); add(oph,v19,oph); if ((phase1 == 2) || (phase1 == 5)) icosel = -1; initval(2.0*(double)(((int)(d2*getval("sw1")+0.5)%2)),v14); add(v2, v14, v2); add(oph, v14, oph); status(A); obspower(tpwr); decpower(pwxlvl); delay(5.0e-5); if (getflag("sspul")) steadystate(); if (satmode[0] == 'y') { if ((d1-satdly) > 0.02) delay(d1-satdly); else delay(0.02); if (getflag("slpsat")) { shaped_satpulse("relaxD",satdly,zero); if (getflag("prgflg")) shaped_purge(v6,zero,v18,v19); } else { satpulse(satdly,zero,rof1,rof1); if (getflag("prgflg")) purge(v6,zero,v18,v19); } } else delay(d1); if (getflag("wet")) wet4(zero,one); status(B); /****** null flag starts here *****/ if (getflag("nullflg")) { rgpulse(0.5 * pw, zero, rof1, rof1); delay(2 * tau); decpower(pwxlvl180); decshaped_pulse(pwx180ad, pwx180, zero, rof1, rof1); rgpulse(2.0 * pw, zero, rof1, rof1); delay(2 * tau + 2 * POWER_DELAY); decshaped_pulse(pwx180adR, pwx180, zero, rof1, rof1); decpower(pwxlvl); rgpulse(1.5 * pw, two, rof1, rof1); zgradpulse(hsglvl, hsgt); delay(1e-3); } /*********gHSQC or gHSQC part of pure shift starts here *****/ if (getflag("cpmgflg")) { rgpulse(pw, v6, rof1, 0.0); cpmg(v6, v15); } else rgpulse(pw, v6, rof1, rof1); delay(tau); decpower(pwxlvl180); decshaped_pulse(pwx180ad, pwx180, zero, rof1, rof1); rgpulse(2.0 * pw, zero, rof1, rof1); delay(tau + 2 * POWER_DELAY); decshaped_pulse(pwx180adR, pwx180, zero, rof1, rof1); decpower(pwxlvl); rgpulse(pw, v1, rof1, rof1); zgradpulse(hsglvl, 2 * hsgt); delay(1e-3); decrgpulse(pwx, v2, rof1, 2.0e-6); delay(d2 / 2); rgpulse(2 * pw, zero, 2.0e-6, 2.0e-6); delay(d2 / 2); delay(taug - POWER_DELAY); if (mult > 0.5) { decpower(pwxlvl180r); decshaped_pulse(pwx180ref, pwx180r, zero, rof1, rof1); rgpulse(mult * pw, zero, rof1, rof1); delay(taug - mult * pw - 2 * rof1 + POWER_DELAY - gtE - gstab - 2 * GRADIENT_DELAY+evolcorr); zgradpulse(gzlvlE, gtE); delay(gstab); decshaped_pulse(pwx180ref, pwx180r, zero, rof1, rof1); } else { decpower(pwxlvl180); decshaped_pulse(pwx180ad, pwx180, zero, rof1, rof1); delay(taug + POWER_DELAY - gtE - gstab - 2 * GRADIENT_DELAY+evolcorr); zgradpulse(gzlvlE, gtE); delay(gstab); decshaped_pulse(pwx180ad, pwx180, zero, rof1, rof1); } decpower(pwxlvl); decrgpulse(pwx, v4, 2.0e-6, rof1); zgradpulse(ZZgsign*0.6 * hsglvl, 1.2 * hsgt); delay(1e-3); rgpulse(pw, v3, rof1, rof1); decpower(pwxlvl180); decshaped_pulse(pwx180adR, pwx180, zero, rof1, rof1); decpower(dpwr); delay(tau - (2 * pw / PI) - 2*rof1); rgpulse(2 * pw, zero, rof1, rof2); decpower(pwxlvl180); decshaped_pulse(pwx180ad, pwx180, zero, rof1, rof1); decpower(dpwr); zgradpulse(icosel * 2.0*gzlvlE/EDratio, gtE/2.0); delay(tau - gtE/2.0 - 2 * GRADIENT_DELAY); /********gHSQC part stops and BIRD Acquisition starts here*************/ // delay(tBal); //filter delay (Hoult) for inova; adjust tBal manually for the same effect //delay(1.0/(getval("fb")*1.3)) if (BIRD[0]=='y') { #ifdef NVPSG setacqmode(WACQ|NZ); //use this line only for vnmrs console; comment this out in inova #endif obsblank(); // delay(rof2); startacq(alfa); } /*---------------------------------------------------------------------------- Observe the 1st half chunk -----------------------------------------------------------------------------*/ if (BIRD[0]=='y') { status(C); acquire(npoints/2.0,1.0/sw); rcvroff(); status(B); obspower(tpwr); /*------------------------------------------------------------------------ Using hard 13C inversion pulse in BIRD --------------------------------------------------------------------------*/ if (BIRDmode[0]== 'h') { rgpulse(pw,v7,rof1,rof1); decpower(pwxlvl); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); simpulse(2.0*pw,2.0*pwx,v8,v8,rof1,rof1); decpower(dpwr); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); rgpulse(pw,v9,rof1,rof1); } /*--------------------------------------------------------------------------- Using BIP 13C inversion pulse in BIRD ----------------------------------------------------------------------------*/ if (BIRDmode[0]== 'b') { rgpulse(pw,v7,rof1,rof1); if (pwr_XBIP!=pwxlvl) decpower(pwr_XBIP); else decpower(pwxlvl); if (pwr_HBIP!=tpwr) obspower(pwr_HBIP); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); simshaped_pulse(shp_HBIP,shp_XBIP,2.0*pw,pw_XBIP,v8,v8,rof1,rof1); if (pwr_HBIP!=tpwr) obspower(tpwr); decpower(dpwr); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); rgpulse(pw,v9,rof1,rof1); } delay(tauA); rgpulse(pw*2.0,v7,rof1,rof1); // hard 180 degree refocusing pulse obsblank(); delay(tauB); rcvron(); //this includes rof3 delay(tauD); decr(v20); /*------------------------------------------------------------------------------ Loops for more chunks ------------------------------------------------------------------------------*/ starthardloop(v20); status(C); acquire(npoints,1.0/sw); rcvroff(); status(B); obspower(tpwr); /*------------------------------------------------------------------------ Using hard 13C inversion pulse in BIRD --------------------------------------------------------------------------*/ if (BIRDmode[0]== 'h') { rgpulse(pw,v7,rof1,rof1); decpower(pwxlvl); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); simpulse(2.0*pw,2.0*pwx,v8,v8,rof1,rof1); decpower(dpwr); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); rgpulse(pw,v9,rof1,rof1); } /*--------------------------------------------------------------------------- Using BIP 13C inversion pulse in BIRD ----------------------------------------------------------------------------*/ // if (BIRDmode[0]== 'b') if (BIRDmode[0]== 'b') { rgpulse(pw,v7,rof1,rof1); if (pwr_XBIP!=pwxlvl) decpower(pwr_XBIP); else decpower(pwxlvl); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); simshaped_pulse(shp_HBIP,shp_XBIP,2*pw,pw_XBIP,v8,v8,rof1,rof1); decpower(dpwr); delay(tau); zgradpulse(gzlvlcr,gtcr); delay(tau-gtcr); rgpulse(pw,v9,rof1,rof1); } delay(tauA); rgpulse(pw*2.0,v7,rof1,rof1); // hard 180 degree refocusing pulse obsblank(); delay(tauB); rcvron(); //this includes rof3 delay(tauD); endhardloop(); /*---------------------------------------------------------------- Acquisition of last half chunk ----------------------------------------------------------------*/ status(C); acquire(npoints/2.0,1.0/sw); rcvroff(); endacq(); incr(v20); } /****** BIRD ends here for all *****/ /***************** ACQ for conventional gHSQC ******************************/ else status(C); }