Exemplo n.º 1
0
void pulsesequence()
{
   double pd, seqtime;
   double n,r,bigtau;
   double restol, resto_local;

   init_mri();

   restol=getval("restol");   //local frequency offset
   roff=getval("roff");       //receiver offset

   init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);   /* hard pulse */
   calc_rf(&p1_rf,"tpwr1","tpwr1f");
   init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);   /* hard pulse */
   calc_rf(&p2_rf,"tpwr2","tpwr2f");

/* calculate 'big tau' values */
   bigtau = getval("bigtau");
   n =  bigtau/(2.0*d2);
   n = (double)((int)((n/2.0) + 0.5)) * 2.0;
   initval(n,v3);

   seqtime = at+p1+rof1+rof2;
   seqtime += 2*d2+p2+rof1+rof2;  /* cpmg pulse and delay */
   
   pd = tr - seqtime;  /* predelay based on tr */
   if (pd <= 0.0) {
      abort_message("%s: Requested tr too short.  Min tr = %f ms",seqfil,seqtime*1e3);
    }

   resto_local=resto-restol; 

   status(A);
   delay(pd);
   xgate(ticks);
   
/* calculate exact delay and phases */

   r = d2-p2/2.0-rof2;   /* correct delay for pulse width */
   mod2(oph,v2);   /* 0,1,0,1 */
   incr(v2);   /* 1,2,1,2 = y,y,-y,-y */

   obsoffset(resto_local); 
   obspower(p1_rf.powerCoarse);
   obspwrf(p1_rf.powerFine);
   rgpulse(p1,oph,rof1,rof2);  /* 90deg */
   obspower(p2_rf.powerCoarse);
   obspwrf(p2_rf.powerFine);
   starthardloop(v3);
      delay(r);
      rgpulse(p2,v2,rof1,rof2);   /* 180deg pulse */
      delay(r);
   endhardloop();
   startacq(alfa);
   acquire(np,1.0/sw);
   endacq();
}
Exemplo n.º 2
0
pulsesequence()
{
   double pd, seqtime;
   double minte,ted1,ted2;
   double restol, resto_local;

   int  vph180     = v2;  /* Phase of 180 pulse */
   init_mri();              /****needed ****/

   restol=getval("restol");   //local frequency offset
   roff=getval("roff");       //receiver offset

   init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);   /* hard pulse */
   calc_rf(&p1_rf,"tpwr1","tpwr1f");
   init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);   /* hard pulse */
   calc_rf(&p2_rf,"tpwr2","tpwr2f");

   seqtime = at+(p1/2.0)+rof1+d2;

   pd = tr - seqtime;  /* predelay based on tr */
   if (pd <= 0.0) {
      abort_message("%s: Requested tr too short.  Min tr = %f ms",seqfil,seqtime*1e3);
    }
   minte = p1/2.0 + p2 + 2*rof2 + rof1;
   if(d2 > 0) {
     if(d2 < minte+4e-6) 
       abort_message("%s: TE too short. Min te = %f ms",seqfil,minte*1e3);
   }
   ted1 = d2/2 - p1/2 - p2/2 + rof2 + rof1;
   ted2 = d2/2 - p2/2 + rof2;
   resto_local=resto-restol; 

   status(A);
   xgate(ticks);
   delay(pd);

   /* --- observe period --- */
   obsoffset(resto_local);
   obspower(p1_rf.powerCoarse);
   obspwrf(p1_rf.powerFine);
   shapedpulse(p1pat,p1,oph,rof1,rof2);
   /* if d2=0 no 180 pulse applied */
   if (d2 > 0) {
     obspower(p2_rf.powerCoarse);
     obspwrf(p2_rf.powerFine);   
     settable(t2,2,ph180);        /* initialize phase tables and variables */
     getelem(t2,ct,v6);  /* 180 deg pulse phase alternates +/- 90 off the rcvr */
     add(oph,v6,vph180);      /* oph=zero */
     delay(ted1);
     shapedpulse(p2pat,p2,vph180,rof1,rof2);
     delay(ted2);
   }
   startacq(alfa);
   acquire(np,1.0/sw);
   endacq();
}
Exemplo n.º 3
0
pulsesequence()
{
  double sign,currentlimit,RMScurrentlimit,dutycycle;
  int calcpower;

  /* Initialize paramaters **********************************/
  init_mri();
  calcpower=(int)getval("calcpower");
  dutycycle=getval("dutycycle");
  currentlimit=getval("currentlimit");
  RMScurrentlimit=getval("RMScurrentlimit");

  if (gspoil>0.0) sign = 1.0;
  else sign = -1.0;

  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);
  if (calcpower) calc_rf(&p1_rf,"tpwr1","tpwr1f");

  if (tspoil>0.0) {
    gspoil = sqrt(dutycycle/100.0)*gmax*RMScurrentlimit/currentlimit;
    init_generic(&spoil_grad,"spoil",gspoil,tspoil);
    spoil_grad.rollOut=FALSE;
    calc_generic(&spoil_grad,WRITE,"gspoil","tspoil");
  }

  xgate(ticks);

  rotate();

  status(A);
  mod4(ct,oph);
  delay(d1);

  /* TTL scope trigger **********************************/       
  sp1on(); delay(4e-6); sp1off();

  if (calcpower) {
    obspower(p1_rf.powerCoarse);
    obspwrf(p1_rf.powerFine);
  } 
  else obspower(tpwr1);
  delay(4e-6);

  if (tspoil>0.0) {
    obl_shapedgradient(spoil_grad.name,spoil_grad.duration,0,0,spoil_grad.amp*sign,WAIT);
    delay(d2);
  }

  shapedpulse(p1pat,p1,ct,rof1,rof2);

  startacq(alfa);
  acquire(np,1.0/sw);
  endacq();
		
}
Exemplo n.º 4
0
Arquivo: board.c Projeto: RELJEF/dapp
void board_init( void )
{
    _BIC_SR( GIE ); /* Disable interrupts during initialization. */

    WDTCTL = WDTPW | WDTHOLD; /* Stop WDT */

    init_ports( );
    init_button_led( );
    init_rf( );

    _BIS_SR( GIE ); /* Enable interrupts after initialization. */
}
Exemplo n.º 5
0
int main(int argc, const char* argv[]) {
    char pass_string[100] = "przekaz dalej";
    char fifo_name[200];
    char fifo_name2[200];  
    char host[20] = "127.0.0.1";
    
    // create unique names    
    sprintf(fifo_name, "/test.fifo-%d", getpid());
    sprintf(fifo_name2, "/test2.fifo-%d", getpid());
    
    printf("@ Remote FIFO - test program started @\n");
    sem_init(&finished_test, 0, 0);
    init_rf(host);
    create_rf(fifo_name, create_callback, pass_string);
    create_rf(fifo_name2, create_callback, pass_string);
    fflush(NULL);
    sem_wait(&finished_test);
    sem_wait(&finished_test);
    
    return 0;
}
Exemplo n.º 6
0
pulsesequence()
{
   double pd, seqtime;
   double mintDELTA,ted1,ted2,gf;
   double restol, resto_local;

   init_mri();              /****needed ****/

   restol=getval("restol");   //local frequency offset
   roff=getval("roff");       //receiver offset

   init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);   /* hard pulse */
   calc_rf(&p1_rf,"tpwr1","tpwr1f");
   init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);   /* hard pulse */
   calc_rf(&p2_rf,"tpwr2","tpwr2f");

   gf=1.0;
   if(diff[0] == 'n') gf=0;
   int  vph180     = v2;  /* Phase of 180 pulse */

   mintDELTA = tdelta + trise + rof1 + p2 + rof2;
   if(tDELTA <= mintDELTA) {
       abort_message("%s: tDELTA too short. Min tDELTA = %f ms",seqfil,mintDELTA*1e3);
   }
   ted1 = tDELTA - tdelta + trise + p2 + rof1 + rof2;
   te = p1/2 + rof2 + tdelta + trise + ted1 + rof1 + p2/2;   /* first half-te */
   ted2 = te - p2/2 - rof2 - tdelta - trise;
   if((ted1 <= 0)||(ted2 <= 0) ) {
       abort_message("%s: tDELTA too short. Min tDELTA = %f ms",seqfil,mintDELTA*1e3);
   }
   te = te*2.0;
   putvalue("te",te);
   seqtime = at+(p1/2.0)+rof1+te;
   pd = tr - seqtime;  /* predelay based on tr */
   if (pd <= 0.0) {
      abort_message("%s: Requested tr too short.  Min tr = %f ms",seqfil,seqtime*1e3);
   }

   resto_local=resto-restol; 

   status(A);
   rotate();
   delay(pd);
   xgate(ticks);

   /* --- observe period --- */
   obsoffset(resto_local); 
   obspower(p1_rf.powerCoarse);
   obspwrf(p1_rf.powerFine);
   shapedpulse(p1pat,p1,oph,rof1,rof2);

   obl_gradient(0,0,gdiff*gf);   /* x,y,z gradients selected via orient */
   delay(tdelta);
   zero_all_gradients();
   delay(trise);
   delay(ted1);
     
   obspower(p2_rf.powerCoarse);
   obspwrf(p2_rf.powerFine);   
   settable(t2,2,ph180);        /* initialize phase tables and variables */
   getelem(t2,ct,v6);  /* 180 deg pulse phase alternates +/- 90 off the rcvr */
   add(oph,v6,vph180);      /* oph=zero */
   shapedpulse(p2pat,p2,vph180,rof1,rof2);

   obl_gradient(0,0,gdiff);   /* x,y,z gradients selected via orient */
   delay(tdelta);
   zero_all_gradients();
   delay(trise);
   delay(ted2);
   startacq(alfa);
   acquire(np,1.0/sw);
   endacq();
}
Exemplo n.º 7
0
pulsesequence() {
  /* Internal variable declarations *************************/
  int     shapelist90,shapelist180,shapelistIR;
  double  nseg;
  double  seqtime,tau1,tau2,tau3,
          te1_delay,te2_delay,te3_delay,
	  iti_delay, ti_delay,
	  tr_delay;
  double  kzero;
  double  freq90[MAXNSLICE], freq180[MAXNSLICE], freqIR[MAXNSLICE];

  /* Real-time variables used in this sequence **************/
  int  vpe_ctr    = v2;      // PE loop counter
  int  vpe_mult   = v3;      // PE multiplier, ranges from -PE/2 to PE/2
  int  vms_slices = v4;      // Number of slices
  int  vms_ctr    = v5;      // Slice loop counter
  int  vseg       = v6;      // Number of ETL segments 
  int  vseg_ctr   = v7;      // Segment counter
  int  vetl       = v8;      // Echo train length
  int  vetl_ctr   = v9;      // Echo train loop counter
  int  vssc       = v10;     // Compressed steady-states
  int  vtrimage   = v11;     // Counts down from nt, trimage delay when 0
  int  vacquire   = v12;     // Argument for setacqvar, to skip steady state acquires
  int  vphase180  = v13;     // phase of 180 degree refocusing pulse

  /* Initialize paramaters **********************************/
  init_mri();

  /*  Load external PE table ********************************/
  if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) {
    loadtable(petable);
  } else {
    abort_message("petable undefined");
  }
    
  seqtime = 0.0;
  espmin = 0.0;
  kzero = getval("kzero");

  /* RF Power & Bandwidth Calculations **********************/
  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);
  init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);
  calc_rf(&p1_rf,"tpwr1","tpwr1f");
  calc_rf(&p2_rf,"tpwr2","tpwr2f");
 
  /* Initialize gradient structures *************************/
  init_readout_butterfly(&ro_grad,"ro",lro,np,sw,gcrushro,tcrushro);
  init_readout_refocus(&ror_grad,"ror");
  init_phase(&pe_grad,"pe",lpe,nv);
  init_slice(&ss_grad,"ss",thk);   /* NOTE assume same band widths for p1 and p2 */     
  init_slice_butterfly(&ss2_grad,"ss2",thk,gcrush,tcrush); 
  init_slice_refocus(&ssr_grad,"ssr");

  /* Gradient calculations **********************************/
  calc_readout(&ro_grad,WRITE,"gro","sw","at");
  calc_readout_refocus(&ror_grad,&ro_grad,NOWRITE,"gror");
  calc_phase(&pe_grad,WRITE,"gpe","tpe");
  calc_slice(&ss_grad,&p1_rf,WRITE,"gss");
  calc_slice(&ss2_grad,&p1_rf,WRITE,"");
  calc_slice_refocus(&ssr_grad,&ss_grad,NOWRITE,"gssr");

  /* Equalize refocus and PE gradient durations *************/
  calc_sim_gradient(&ror_grad,&null_grad,&ssr_grad,0.0,WRITE);

  /* Create optional prepulse events ************************/
  if (sat[0] == 'y')  create_satbands();
  if (fsat[0] == 'y') create_fatsat();
  if (mt[0] == 'y')   create_mtc();

  if (ir[0] == 'y') {
    init_rf(&ir_rf,pipat,pi,flipir,rof1,rof2);
    calc_rf(&ir_rf,"tpwri","tpwrif");
    init_slice_butterfly(&ssi_grad,"ssi",thk,gcrushir,tcrushir);
    calc_slice(&ssi_grad,&ir_rf,WRITE,"gssi");
  }

  /* Set up frequency offset pulse shape list ********/
  offsetlist(pss,ss_grad.ssamp, 0,freq90, ns,seqcon[1]);
  offsetlist(pss,ss2_grad.ssamp,0,freq180,ns,seqcon[1]);
  offsetlist(pss,ssi_grad.ssamp,0,freqIR, ns,seqcon[1]);
  shapelist90  = shapelist(p1pat,ss_grad.rfDuration, freq90, ns,0,seqcon[1]);
  shapelist180 = shapelist(p2pat,ss2_grad.rfDuration,freq180,ns,0,seqcon[1]);
  shapelistIR  = shapelist(pipat,ssi_grad.rfDuration,freqIR, ns,0,seqcon[1]);

  /* same slice selection gradient and RF pattern used */
  if (ss_grad.rfFraction != 0.5)
    abort_message("ERROR %s: RF pulse must be symmetric (RF fraction = %.2f)",
      seqfil,ss_grad.rfFraction);
  if (ro_grad.echoFraction != 1)
    abort_message("ERROR %s: Echo Fraction must be 1",seqfil);

  /* Find sum of all events in each half-echo period ********/
  tau1 = ss_grad.rfCenterBack  + ssr_grad.duration + ss2_grad.rfCenterFront;
  tau2 = ss2_grad.rfCenterBack + pe_grad.duration  + ro_grad.timeToEcho; 
  tau3 = ro_grad.timeFromEcho  + pe_grad.duration  + ss2_grad.rfCenterFront;

  espmin = 2*MAX(MAX(tau1,tau2),tau3);   // Minimum echo spacing

  if (minesp[0] == 'y') {
    esp = espmin + 8e-6;  // ensure at least 4us delays in both TE periods
    putvalue("esp",esp);
  }
  else if (((espmin+8e-6)-esp) > 12.5e-9) {
    abort_message("ERROR %s: Echo spacing too small, minimum is %.2fms\n",seqfil,(espmin+8e-6)*1000);
  }
  te1_delay = esp/2.0 - tau1;    // Intra-esp delays
  te2_delay = esp/2.0 - tau2;
  te3_delay = esp/2.0 - tau3;

  te = kzero*esp;                // Return effective TE
  putvalue("te",te);

  /* Minimum TR **************************************/
  /* seqtime is total time per slice */
  seqtime = 2*4e-6 + ss_grad.rfCenterFront + etl*esp + ro_grad.timeFromEcho + pe_grad.duration + te3_delay;

  /* Increase TR if any options are selected****************/
  if (sat[0]  == 'y') seqtime += ns*satTime;
  if (fsat[0] == 'y') seqtime += ns*fsatTime;
  if (mt[0]   == 'y') seqtime += ns*mtTime;


  if (ir[0] == 'y') {

    /* Inter-IR delay */
    if (ns > 1) 
      iti_delay = seqtime - ssi_grad.duration;
      /* it is probably safe to assume that seqtime is always > the pulse widths */
    else 
      iti_delay = 0;

    /* Inversion Recovery */
    timin  = ssi_grad.rfCenterBack + ss_grad.rfCenterFront;
    timin += 8e-6; // from sp1on/off and after 90 pulse power setting 
    timin += seqtime*(ns-1) + iti_delay;

    if (ti < timin + 4e-6)  // ensure at least a 4us delay
      abort_message("%s: ti too short, minimum is %.2fms",seqfil,timin*1000);

    /* Delay after the last IR pulse */
    ti_delay = ti - timin;
    
    /* force all slices to be acquired back-to-back, with a single TR delay at end */
    trtype = 1;  

  }
  else {
    iti_delay = ti_delay = 0;
  }

  trmin = ns*(seqtime + 4e-6);
  
  if (ir[0] == 'y') {
    trmin += (4e-6 + ssi_grad.rfCenterFront + ti);
  }
  if (mintr[0] == 'y'){
    tr = trmin;
    putvalue("tr",tr);
  }


  if ((trmin-tr) > 12.5e-9) {
    abort_message("TR too short.  Minimum TR = %.2fms\n",trmin*1000);
  }
  tr_delay = (tr - trmin)/ns;



  /* Set number of segments for profile or full image **********/
  nseg = prep_profile(profile[0],nv/etl,&pe_grad,&per_grad);

  /* Shift DDR for pro *******************************/
  roff = -poffset(pro,ro_grad.roamp);

  /* Calculate total acquisition time */
  g_setExpTime(tr*(nt*nseg*getval("arraydim") + ssc) + trimage*getval("arraydim"));


  /* Return parameters to VnmrJ */
  putvalue("rgss",ss_grad.tramp);  //90  slice ramp
  if (ss2_grad.enableButterfly) {   //180 slice ramps
    putvalue("rcrush",ss2_grad.crusher1RampToCrusherDuration);
    putvalue("rgss2",ss2_grad.crusher1RampToSsDuration);
  }
  else {
    putvalue("rgss2",ss2_grad.tramp);
  }
  if (ro_grad.enableButterfly) {
    putvalue("rgro",ro_grad.crusher1RampToSsDuration);
  }
  else {   
    putvalue("rgro",ro_grad.tramp);      //RO ramp
  }
  putvalue("tror",ror_grad.duration);  //ROR duration
  putvalue("rgror",ror_grad.tramp);    //ROR ramp
  putvalue("gpe",pe_grad.peamp);         //PE max amp
  putvalue("gss",ss_grad.ssamp);
  putvalue("gro",ro_grad.roamp);



  /* PULSE SEQUENCE *************************************/
  initval(fabs(ssc),vssc);      // Compressed steady-state counter
  assign(one,vacquire);         // real-time acquire flag

  /* Phase cycle: Alternate 180 phase to cancel residual FID */
  mod2(ct,vphase180);           // 0101
  dbl(vphase180,vphase180);     // 0202
  add(vphase180,one,vphase180); // 1313 Phase difference from 90
  add(vphase180,oph,vphase180);

  obsoffset(resto);
  delay(4e-6);
    
  initval(nseg,vseg);
  loop(vseg,vseg_ctr);

    /* TTL scope trigger **********************************/       
    sp1on(); delay(4e-6); sp1off();

    /* Compressed steady-states: 1st array & transient, all arrays if ssc is negative */
    if ((ix > 1) && (ssc > 0))
      assign(zero,vssc);
    sub(vseg_ctr,vssc,vseg_ctr);   // vpe_ctr counts up from -ssc
    assign(zero,vssc);
    ifzero(vseg_ctr);
      assign(zero,vacquire);       // Start acquiring when vseg_ctr reaches zero
    endif(vseg_ctr);
    setacqvar(vacquire);           // Turn on acquire when vacquire is zero

    if (ticks) {
      xgate(ticks);
      grad_advance(gpropdelay);
      delay(4e-6);
    }

    if(ir[0] == 'y') {  /* IR for all slices prior to data acquisition */
      obspower(ir_rf.powerCoarse);
      obspwrf(ir_rf.powerFine);
      delay(4e-6);
      msloop(seqcon[1],ns,vms_slices,vms_ctr);
	obl_shapedgradient(ssi_grad.name,ssi_grad.duration,0,0,ssi_grad.amp,NOWAIT);   
	delay(ssi_grad.rfDelayFront);
	shapedpulselist(shapelistIR,ssi_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
	delay(ssi_grad.rfDelayBack);
	delay(iti_delay);
      endmsloop(seqcon[1],vms_ctr);
      delay(ti_delay);
    }

    msloop(seqcon[1],ns,vms_slices,vms_ctr);

      /* Prepulse options ***********************************/
      if (sat[0]  == 'y') satbands();
      if (fsat[0] == 'y') fatsat();
      if (mt[0]   == 'y') mtc();

      /* 90 degree pulse ************************************/         
      rotate();
      obspower(p1_rf.powerCoarse);
      obspwrf(p1_rf.powerFine);
      delay(4e-6);
      obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT);   
      delay(ss_grad.rfDelayFront);
      shapedpulselist(shapelist90,ss_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
      delay(ss_grad.rfDelayBack);

      /* Read dephase and Slice refocus *********************/
      obl_shapedgradient(ssr_grad.name,ssr_grad.duration,ror_grad.amp,0.0,-ssr_grad.amp,WAIT);

      /* First half-TE delay ********************************/
      obspower(p2_rf.powerCoarse);
      obspwrf(p2_rf.powerFine);
      delay(te1_delay);
	
      peloop(seqcon[2],etl,vetl,vetl_ctr);
        mult(vseg_ctr,vetl,vpe_ctr);
        add(vpe_ctr,vetl_ctr,vpe_ctr);
        getelem(t1,vpe_ctr,vpe_mult);

        /* 180 degree pulse *******************************/
        /* Note, ss2_grad.amp is max gradient for butterfly shape; flat top = _.ssamp */ 
        obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0,0,ss2_grad.amp,NOWAIT);   
    	delay(ss2_grad.rfDelayFront); 
        shapedpulselist(shapelist180,ss2_grad.rfDuration,vphase180,rof1,rof2,seqcon[1],vms_ctr);
        delay(ss2_grad.rfDelayBack);   

        /* Phase-encode gradient ******************************/
        pe_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,-pe_grad.increment,vpe_mult,WAIT);

        /* Second half-TE period ******************************/
	delay(te2_delay);
	 
        /* Readout gradient ************************************/
        obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.amp,0,0,NOWAIT);
        delay(ro_grad.atDelayFront);

        /* Acquire data ****************************************/
        startacq(alfa);
        acquire(np,1.0/sw);
        endacq();

        delay(ro_grad.atDelayBack);

        /* Rewinding phase-encode gradient ********************/
        /* Phase encode, refocus, and dephase gradient ******************/
        pe_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,pe_grad.increment,vpe_mult,WAIT);

        /* Second half-TE delay *******************************/
        delay(te3_delay);
      endpeloop(seqcon[2],vetl_ctr);

      /* Relaxation delay ***********************************/
      if (!trtype)
        delay(tr_delay);
    endmsloop(seqcon[1],vms_ctr);
    if (trtype)
      delay(ns*tr_delay);
  endloop(vseg_ctr);

  /* Inter-image delay **********************************/
  sub(ntrt,ct,vtrimage);
  decr(vtrimage);
  ifzero(vtrimage);
    delay(trimage);
  endif(vtrimage);
}
Exemplo n.º 8
0
pulsesequence()
{

  /* Internal variable declarations *************************/

  /*timing*/
  double tr_delay;
  double te_d1,te_d2,te_d3;             /* delays */
  double tau1,tau2,tau3;
  
  
  /*voxel crusher multipliers */
  double fx,fy,fz;
  
  /*localization parameters*/
  double freq1,freq2,freq3;
  double vox1_cr,vox2_cr, vox3_cr;
  int nDim;
 

  double rprof,pprof,sprof;
  char profile_vox[MAXSTR],profile_ovs[MAXSTR];

  double restol, resto_local, csd_ppm;

  /*phase cycle****/
  int counter,noph;
  char autoph[MAXSTR], pcflag[MAXSTR];
  int rf1_phase[64]  = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
			1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3}; 
  int rf2_phase[64]  = {0,0,0,0,2,2,2,2,1,1,1,1,3,3,3,3,0,0,0,0,2,2,2,2,1,1,1,1,3,3,3,3,
			0,0,0,0,2,2,2,2,1,1,1,1,3,3,3,3,0,0,0,0,2,2,2,2,1,1,1,1,3,3,3,3}; 
  int rf3_phase[64]  = {0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,
			0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3,0,2,1,3}; 
 
 
  /* Initialize paramaters **********************************/
  init_mri();  //this gets all the parameters that are defined in acqparms.h, etc
  get_wsparameters();
  get_ovsparameters();

  rprof = getval("rprof");
  pprof = getval("pprof");
  sprof = getval("sprof");

  //read the crusher factors that are designed to create grad on the same axis without refoc 
  fx=getval("fx");
  fy=getval("fy");
  fz=getval("fz");

  
  getstr("profile_vox",profile_vox);
  getstr("profile_ovs",profile_ovs);

  /*set voxel sizes for butterfly crushers to 10^6 to set the slice portion to zero ***/
  vox1_cr=1000000;
  vox2_cr=1000000;
  vox3_cr=1000000;
  
  /***** RF power initialize *****/
  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);
  init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);

 

  
  
  /***** Initialize gradient structs *****/
  trampfixed=trise; //rise time =trise 
  tcrush=granularity(tcrush,GRADIENT_RES); //this is to avoid the granularity errors
  //if trampfixed is used, rise time needs to be checked 
  if (trise*2>tcrush){
  
   abort_message("tcrush too short. Minimum tcrush = %fms \n",1000*trise*2);
  }

  if (gcrush>gmax){
  
   abort_message("gcrush too large. Max gcrush = %f \n",gmax*0.95);
  }

  init_slice_butterfly(&vox1_grad,"vox1",vox1,gcrush,tcrush);
  init_slice_butterfly(&vox2_grad,"vox2",vox2,gcrush,tcrush);
  init_slice_butterfly(&vox3_grad,"vox3",vox3,gcrush,tcrush);

  init_slice_butterfly(&vox1_crush,"vox1_crush",vox1_cr,gcrush,tcrush);
  init_slice_butterfly(&vox2_crush,"vox2_crush",vox2_cr,gcrush,tcrush);
  init_slice_butterfly(&vox3_crush,"vox3_crush",vox3_cr,gcrush,tcrush); 
  if (profile_vox[0] == 'y') {
    init_readout_butterfly(&ro_grad,"ro",lro,np,sw,gcrushro,tcrushro);
    init_readout_refocus(&ror_grad,"ror");
  }
 
  /***** RF and Gradient calculations *****/
  calc_rf(&p1_rf,"tpwr1","tpwr1f");
  calc_rf(&p2_rf,"tpwr2","tpwr2f");
  
  calc_slice(&vox1_grad,&p2_rf,WRITE,"gvox1");
  calc_slice(&vox2_grad,&p2_rf,WRITE,"gvox2");
  calc_slice(&vox3_grad,&p2_rf,WRITE,"gvox3");

  calc_slice(&vox1_crush,&p2_rf,WRITE,"vox1_crush");
  calc_slice(&vox2_crush,&p2_rf,WRITE,"vox2_crush");
  calc_slice(&vox3_crush,&p2_rf,WRITE,"vox3_crush");

  if (profile_vox[0] == 'y') {
    calc_readout(&ro_grad,WRITE,"gro","sw","at");
    putvalue("gro",ro_grad.roamp);       // RO grad
    calc_readout_refocus(&ror_grad,&ro_grad,WRITE,"gror");
    putvalue("tror",ror_grad.duration);  // ROR duration
  }

  //set all gradients along a particular direction to zero if profile is needed

  if (profile_ovs[0]=='y'){
     if (rprof==1) {
       vox1_grad.amp=0; //set slice selection in read direction to none 
       vox3_crush.amp=0; // set corresponding crusher gradients to none
       
     }
     else if(pprof==1) {
     vox2_grad.amp=0;
     vox1_crush.amp=0;
     }     
     else if(sprof==1) {
     vox3_grad.amp=0;
     vox2_crush.amp=0;
     }
  }


  

  /* Optional OVS and Water Suppression */
  
  if (ovs[0] == 'y')  create_ovsbands();
  if (sat[0] == 'y')  create_satbands();
  if (ws[0]  == 'y')  create_watersuppress();

  //Read in parameters not defined in acqparms.h and sglHelper 
  nDim=getval("nDim");
  restol=getval("restol");  //local frequency offset 
  roff=getval("roff");       //receiver offset
  csd_ppm=getval("csd_ppm"); //chemical shift displacement factor
  
  noph=getval("noph");
  getstr("autoph",autoph);
  getstr("pcflag",pcflag);
  settable(t3,noph,rf1_phase);
  settable(t2,noph,rf2_phase);
  settable(t1,noph,rf3_phase);

  /* tau1, tau2 and tau3 are sums of all events in TE*/
  tau1 = vox1_grad.rfCenterFront+GDELAY+rof2;
  tau2 = vox1_grad.rfCenterBack + vox1_grad.rfCenterFront+2*(GDELAY+rof2);
  tau3 = vox3_grad.rfCenterBack+GDELAY+rof2;
  temin  = tau1+5.0*tau2+tau3;  

  if (minte[0] == 'y') {
   
    te = temin;
    putvalue("te",te);
   }
  if (te < temin) {
    abort_message("te too short. Minimum te = %.2f ms\n",temin*1000);
  }
  

  /***** Calculate TE delays *****/
  te_d1 = te/12.0 - tau1+GDELAY;
  te_d2 = te/6.0 - tau2+2*(GDELAY+rof2);
  te_d3 = te/12.0 - tau3+GDELAY+rof2;

  
  //Calculate delta from resto to include local frequency line+ chemical shift offset
  resto_local=resto-restol;  


/***** Min TR *****/
  trmin = GDELAY + p1 + te + at+rof1+rof2;

  if (ws[0]  == 'y') trmin += wsTime;
  if (ovs[0] == 'y') trmin += ovsTime;
  if (sat[0] == 'y') trmin += satTime;
  if (profile_vox[0] == 'y') trmin += ror_grad.duration + ro_grad.duration - at; 

  if (mintr[0] == 'y') {
    tr = trmin;  // ensure at least 4us between gradient events
    putvalue("tr",tr);
  }
  if ((trmin-tr) > 12.5e-9) {
    abort_message("TR too short.  Minimum TR= %.2fms\n",trmin*1000);
  }
/***** Calculate TR delay *****/
  tr_delay = tr - trmin;

/* Frequency offsets */
  freq1    = poffset(pos1,vox1_grad.ssamp); // First  RF pulse
  freq2    = poffset(pos2,vox2_grad.ssamp); // Second RF pulse
  freq3    = poffset(pos3,vox3_grad.ssamp); // Third  RF pulse
 

  freq1=freq1-csd_ppm*sfrq;
  freq2=freq2-csd_ppm*sfrq;
  freq3=freq3-csd_ppm*sfrq;
  


 /* Frequency offsets */
  if (profile_vox[0] == 'y') {
    /* Shift DDR for pro ************************************/
    roff = -poffset(pro,ro_grad.roamp);
  } 


  /* Put gradient information back into VnmrJ parameters */
  putvalue("gvox1",vox1_grad.ssamp);
  putvalue("gvox2",vox2_grad.ssamp);
  putvalue("gvox3",vox3_grad.ssamp);
  putvalue("rgvox1",vox1_grad.tramp);
  putvalue("rgvox2",vox2_grad.tramp);
  putvalue("rgvox3",vox3_grad.tramp);
  
  
  
  sgl_error_check(sglerror);
  
  if (ss<0) g_setExpTime(tr*(nt-ss)*arraydim);
  else g_setExpTime(tr*(nt*arraydim+ss));

/**[2.7] PHASE CYCLING ******************************************************/

  assign(zero, oph); 
  counter=(double)nt*(ix-1);
  if (autoph[0] == 'n') counter=0.0; //only goes through nt, if 'y' goes through nt*array
  initval(counter,v1);
  initval(noph,v3);
  add(v1,ct,v2);
  modn(v2,v3,v2);
  
  /* Full phase cycling requires 64 steps*/
  
  if (pcflag[0] == 'n') {
  assign(zero,v2);
  getelem(t1,v2,v10);
  getelem(t2,v2,v11);
  getelem(t3,v2,v12); 
  }
  else
  {
  getelem(t1,v2,v10);
  getelem(t2,v2,v11);
  getelem(t3,v2,v12); 
  }
  

 
 
  /*Start of the sequence*/
  obsoffset(resto_local);  // need it here for water suppression to work
  delay(GDELAY);
  rot_angle(vpsi,vphi,vtheta);

  if (ticks) {
    xgate(ticks);
    grad_advance(gpropdelay);
    delay(4e-6);
  }

  /* TTL scope trigger **********************************/
  //sp1on(); delay(4e-6); sp1off();

  /* Saturation bands ***********************************/
  
  
  if (ovs[0] == 'y') ovsbands();
  if (sat[0] == 'y') satbands();

  /* Water suppression **********************************/
  if (ws[0]  == 'y') watersuppress();

  /* Slice selective 90 degree RF pulse *****/
  obspower(p1_rf.powerCoarse);
  obspwrf(p1_rf.powerFine);
  delay(GDELAY);
  
  shaped_pulse(p1pat,p1,zero,rof1,rof2);

   /* start localization */
  obspower(p2_rf.powerCoarse);
  obspwrf(p2_rf.powerFine);
  
  if (nDim > 2.5) {
  
  delay(te_d1);   //this is at least GDELAY == 4 us
  
  obl_shaped3gradient(vox1_grad.name,vox1_crush.name,"",vox1_grad.duration,vox1_grad.amp,fy*vox1_crush.amp,0,NOWAIT);
  delay(vox1_grad.rfDelayFront);
  if (profile_ovs[0]=='y'&& rprof==1) freq1=0.0;
  shapedpulseoffset(p2_rf.pulseName,vox1_grad.rfDuration,v12,rof1,rof2,freq1);
  delay(vox1_grad.rfDelayBack);  
  delay(te_d2);
  obl_shaped3gradient (vox1_grad.name,vox1_crush.name,"",vox1_grad.duration,vox1_grad.amp,fy*0.777*vox1_crush.amp,0,NOWAIT);
  delay(vox1_grad.rfDelayFront);
  if (profile_ovs[0]=='y'&& rprof==1) freq1=0.0;
  shapedpulseoffset(p2_rf.pulseName,vox1_grad.rfDuration,v12,rof1,rof2,freq1);
  delay(vox1_grad.rfDelayBack);
  
  delay(te_d2);
  }
  
  if (nDim > 1.5) {   //this is 2nd slice selection
  obl_shaped3gradient("",vox2_grad.name,vox2_crush.name,vox2_grad.duration,0,vox2_grad.amp,fz*vox2_crush.amp,NOWAIT);
  delay(vox2_grad.rfDelayFront);
  if (profile_ovs[0]=='y'&& pprof==1) freq2=0.0;
  shapedpulseoffset(p2_rf.pulseName,vox2_grad.rfDuration,v11,rof1,rof2,freq2);
  delay(vox2_grad.rfDelayBack);
  
  delay(te_d2);
  
  obl_shaped3gradient("",vox2_grad.name,vox2_crush.name,vox2_grad.duration,0,vox2_grad.amp,fz*0.777*vox2_crush.amp,NOWAIT);
  delay(vox2_grad.rfDelayFront);
  if (profile_ovs[0]=='y'&& pprof==1) freq2=0.0;
  shapedpulseoffset(p2_rf.pulseName,vox2_grad.rfDuration,v11,rof1,rof2,freq2);
  delay(vox2_grad.rfDelayBack);
  
  delay(te_d2);
  }

  if (nDim > 0.5){    //this is 3rd slice selection
  obl_shaped3gradient(vox3_crush.name,"",vox3_grad.name,vox3_grad.duration,fx*vox3_crush.amp,0,vox3_grad.amp,NOWAIT);
  delay(vox3_grad.rfDelayFront);
  if (profile_ovs[0]=='y'&& sprof==1) freq3=0.0;
  shapedpulseoffset(p2_rf.pulseName,vox3_grad.rfDuration,v10,rof1,rof2,freq3);
  delay(vox3_grad.rfDelayBack);
  
  delay(te_d2);
   obl_shaped3gradient(vox3_crush.name,"",vox3_grad.name,vox3_grad.duration,fx*vox3_crush.amp,0,vox3_grad.amp,NOWAIT);
  delay(vox3_grad.rfDelayFront);
  if (profile_ovs[0]=='y'&& sprof==1) freq3=0.0;
  shapedpulseoffset(p2_rf.pulseName,vox3_grad.rfDuration,v10,rof1,rof2,freq3);
  delay(vox3_grad.rfDelayBack);
  
  delay(te_d3);
  }
  if (profile_vox[0] == 'y') {
    obl_shapedgradient(ror_grad.name,ror_grad.duration,
      -rprof*ror_grad.amp,-pprof*ror_grad.amp,-sprof*ror_grad.amp,WAIT);
    delay(GDELAY);
    obl_shapedgradient(ro_grad.name,ro_grad.duration,
      rprof*ro_grad.amp,pprof*ro_grad.amp,sprof*ro_grad.amp,NOWAIT); 
    delay(ro_grad.atDelayFront);
    startacq(alfa);
    acquire(np,1.0/sw);
    delay(ro_grad.atDelayBack);
    endacq();
  } else {
    startacq(alfa);
    acquire(np,1.0/sw);
    endacq();
  }

  delay(tr_delay);
Exemplo n.º 9
0
void prep_asl() {
  double pssir[MAXSLICE],pss_q2tips[MAXSLICE],
         ir_dist;
  double freqIR[MAXSLICE],freqQ[MAXSLICE];
  int    s;

  /* Calculate all RF and Gradient shapes */    
  init_rf(&ir_rf,pipat,pi,flipir,rof1,rof1); 
  calc_rf(&ir_rf,"tpwri","tpwrif"); 

  init_slice(&ssi_grad,"aslssi",irthk);
  calc_slice(&ssi_grad,&ir_rf,WRITE,"");
  
  init_generic(&aslcrush_grad,"aslcrush",gcrushir,tcrushir);
  calc_generic(&aslcrush_grad,WRITE,"","");
  
  
  if (diff[0] == 'y') {
    init_generic(&diff_grad,"asldiff",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,"","");
    }
  }


  /* Set up list of phase ramped pulses */
  /* Create list of slice positions for IR pulse, based on tag type */
  ir_dist = thk/10/2 + irgap + irthk/10/2;  // thk & irthk in mm
  ssiamp = ssi_grad.amp;  // keep in ssiamp; ssi_grad is only calculated for ix==1
  for (s = 0; s < ns; s++) {
    switch (asltype) {
      case FAIR:   // IR on imaging slice, selective vs non-selective
                   pssir[s]  = pss[s];
		   pss_q2tips[s] = pss[s] + (thk/10/2 + irgap + satthk[0]/10/2);
		   /* quipss with FAIR doesn't make sense, but set it just in case */
		   if (asltag == -1) ssiamp = 0;
                   break;
      case STAR:   // IR proximal vs distal to imaging slice 
                   if (asltag == 1){
		     pssir[s]      = pss[s] + ir_dist;
		   }
		   else if (asltag == -1) {
		     pssir[s]      = pss[s] - ir_dist;
		   }
		   else {
		     pssir[s]      = pss[s] + ir_dist;  // not used
		   }
                   break;
      case PICORE: // IR proximal to imaging slice, selective vs non-selective
                   pssir[s]      = pss[s] + ir_dist;
		   if (asltag == -1) ssiamp = 0;
                   break;
      default:     break;
    }
  }
  offsetlist(pssir,ssiamp,0,freqIR,ns,seqcon[1]);
  shapeIR = shapelist(pipat,ssi_grad.rfDuration,freqIR,ns,0,seqcon[1]);
  

  /* Set up Q2TIPS RF and Gradients */
  if (quipss[0] == 'y') {
    init_rf(&sat_rf,satpat,psat,flipsat,rof1,rof2); 
    calc_rf(&sat_rf,"tpwrsat","tpwrsatf"); 

    init_slice(&sat_grad,"q2tips",satthk[0]);
    calc_slice(&sat_grad,&sat_rf,WRITE,"");

    init_generic(&qcrush_grad,"qcrush",qgcrush,qtcrush);
    calc_generic(&qcrush_grad,WRITE,"","");

    for (s = 0; s < ns; s++) {
      if (asltag == 1){
        pss_q2tips[s] = pss[s] + (thk/10/2 + irgap + satthk[0]/10/2);
      }
      else if (asltag == -1) {
        pss_q2tips[s] = pss[s] - (thk/10/2 + irgap + satthk[0]/10/2);
      }
      else {
        pss_q2tips[s] = pss[s] + (thk/10/2 + irgap + satthk[0]/10/2);
      }
    }


    offsetlist(pss_q2tips,sat_grad.ssamp,0,freqQ,ns,seqcon[1]);
    shapeQtag = shapelist(satpat,sat_grad.rfDuration,freqQ,ns,0,seqcon[1]);
    
    qTime   = nsat*(sat_grad.duration + qcrush_grad.duration);
  
  }


}
Exemplo n.º 10
0
pulsesequence()
{
  /* Internal variable declarations *************************/
  double  freqEx[MAXNSLICE], freqIR[MAXNSLICE];
  double  pe_steps,pespoil_amp;
  double  perTime, seqtime, tau1, tauIR=0, te_delay, tr_delay, ti_delay=0;
  int     table, shapeEx, shapeIR=0;
  char    spoilflag[MAXSTR],per_name[MAXSTR];

  /* Real-time variables used in this sequence **************/
  int  vpe_steps    = v1;      // Number of PE steps
  int  vpe_ctr      = v2;      // PE loop counter
  int  vms_slices   = v3;      // Number of slices
  int  vms_ctr      = v4;      // Slice loop counter
  int  vpe_offset   = v5;      // PE/2 for non-table offset
  int  vpe_mult     = v6;      // PE multiplier, ranges from -PE/2 to PE/2
  int  vper_mult    = v7;      // PE rewinder multiplier; turn off rewinder when 0
  int  vssc         = v8;      // Compressed steady-states
  int  vacquire     = v9;      // Argument for setacqvar, to skip steady state acquires
  int  vrfspoil_ctr = v10;     // RF spoil counter
  int  vrfspoil     = v11;     // RF spoil multiplier
  int  vtrimage     = v12;     // Counts down from nt, trimage delay when 0

  /* Initialize paramaters **********************************/
  get_parameters();
  get_ovsparameters();
  getstr("spoilflag",spoilflag);

  /*  Check for external PE table ***************************/
  table = 0;
  if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) {
    loadtable(petable);
    table = 1;
  }

  /* Set Rcvr/Xmtr phase increments for RF Spoiling ********/
  /* Ref:  Zur, Y., Magn. Res. Med., 21, 251, (1991) *******/
  if (rfspoil[0] == 'y') {
    rcvrstepsize(rfphase);
    obsstepsize(rfphase);
  }

  /* Initialize gradient structures *************************/
  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2 );         // excitation pulse
  init_slice(&ss_grad,"ss",thk);                     // slice select gradient
  init_slice_refocus(&ssr_grad,"ssr");               // slice refocus gradient
  init_readout(&ro_grad,"ro",lro,np,sw);             // readout gradient
  init_readout_refocus(&ror_grad,"ror");             // dephase gradient
  init_phase(&pe_grad,"pe",lpe,nv);                  // phase encode gradient
  init_phase(&per_grad,"per",lpe,nv);                // phase encode gradient
  init_generic(&spoil_grad,"spoil",gspoil,tspoil);   // spoiler gradient

  /* RF Calculations ****************************************/
  calc_rf(&p1_rf,"tpwr1","tpwr1f");

  /* Gradient calculations **********************************/
  calc_slice(&ss_grad,&p1_rf,WRITE,"gss");
  calc_slice_refocus(&ssr_grad, &ss_grad, NOWRITE,"gssr");
  calc_readout(&ro_grad, WRITE, "gro","sw","at");
  calc_readout_refocus(&ror_grad, &ro_grad, NOWRITE, "gror");
  calc_phase(&pe_grad, NOWRITE, "gpe","tpe");

  /* Equalize refocus and PE gradient durations *************/
  calc_sim_gradient(&ror_grad, &pe_grad, &ssr_grad,tpemin, WRITE);

  /* Calculate phase-rewind & spoiler gradients *************/
  pespoil_amp = 0.0;
  perTime = 0.0;
  if ((perewind[0] == 'y') && (spoilflag[0] == 'n')) {       // Rewinder, no spoiler
    calc_phase(&per_grad,WRITE,"","");
    strcpy(per_name,per_grad.name);
    perTime = per_grad.duration;
    spoil_grad.amp = 0.0;
  }
  else if ((perewind[0] == 'n') && (spoilflag[0] == 'y')) {  // Spoiler, no rewinder
    calc_generic(&spoil_grad,WRITE,"","");
    strcpy(per_name,spoil_grad.name);
    perTime = spoil_grad.duration;
    pespoil_amp = spoil_grad.amp;      // Apply spoiler on PE axis if no rewinder
  }
  else if ((perewind[0] == 'y') && (spoilflag[0] == 'y')) {  // Rewinder and spoiler
    calc_phase(&per_grad,NOWRITE,"","");
    calc_generic(&spoil_grad,NOWRITE,"","");
    calc_sim_gradient(&per_grad,&spoil_grad,&null_grad,0.0,WRITE);
    strcpy(per_name,per_grad.name);
    perTime = per_grad.duration;
  }

  /* Create optional prepulse events ************************/
  if (sat[0] == 'y')  create_satbands();
  if (fsat[0] == 'y') create_fatsat();
  if (mt[0] == 'y')   create_mtc();
  if (ovs[0] == 'y') {
    /* Must set up a few voxel specific parameters for create_ovsbands() to function */
    vox1_grad.thickness   = vox1;
    vox2_grad.thickness   = vox2;
    vox3_grad.thickness   = vox3;
    vox1_grad.rfBandwidth = vox2_grad.rfBandwidth = vox3_grad.rfBandwidth = p1_rf.bandwidth;
    create_ovsbands();
  }

  if (ir[0] == 'y') {
    init_rf(&ir_rf,pipat,pi,flipir,rof2,rof2); 
    calc_rf(&ir_rf,"tpwri","tpwrif");
    init_slice_butterfly(&ssi_grad,"ssi",thk,gcrush,tcrush);
    calc_slice(&ssi_grad,&ir_rf,WRITE,"gssi");

    tauIR = ss_grad.duration - ss_grad.rfCenterBack; // Duration of ss_grad before RF center
    ti_delay = ti - (ssi_grad.rfCenterFront + tauIR);

    if (ti_delay < 0) {
      abort_message("TI too short, Minimum TI = %.2fms\n",(ti-ti_delay)*1000);
    }
    irTime = 4e-6 + ti + ssi_grad.duration - ssi_grad.rfCenterBack;  // Time to add to TR
  }
  
  /* Check that all Gradient calculations are ok ************/
  sgl_error_check(sglerror);

  /* Min TE ******************************************/
  tau1 = ss_grad.rfCenterBack + pe_grad.duration + alfa + ro_grad.timeToEcho;

  temin = tau1 + 4e-6;  /* ensure that te_delay is at least 4us */
  if (minte[0] == 'y') {
    te = temin;
    putvalue("te",te);
  }
  if (te < temin) {
    abort_message("TE too short.  Minimum TE= %.2fms\n",temin*1000+0.005);   
  }
  te_delay = te - tau1;
   
  /* Min TR ******************************************/   	
  seqtime  = ss_grad.duration + te_delay + pe_grad.duration
           + ro_grad.duration + perTime + tep + alfa;

  /* Increase TR if any options are selected ****************/
  if (sat[0] == 'y')  seqtime += satTime;
  if (fsat[0] == 'y') seqtime += fsatTime;
  if (mt[0] == 'y')   seqtime += mtTime;
  if (ovs[0] == 'y')  seqtime += ovsTime;
  if (ir[0] == 'y') {
    seqtime += irTime;
    seqtime -= tauIR;  /* subtract out ss_grad which was already included in TR */
  }

  trmin = seqtime + 4e-6;  /* ensure that tr_delay is at least 4us */
  trmin *= ns;
  if (mintr[0] == 'y') {
    tr = trmin;
    putvalue("tr",tr);
  }
  if (tr < trmin) {
    abort_message("TR too short.  Minimum TR= %.2fms\n",trmin*1000+0.005);   
  }
  tr_delay = (tr - seqtime*ns)/ns;

  /* Set up frequency offset pulse shape list ********/   	
  offsetlist(pss,ss_grad.ssamp,0,freqEx,ns,seqcon[1]);
  shapeEx = shapelist(p1pat,ss_grad.rfDuration,freqEx,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]);
  }
  
  /* Set pe_steps for profile or full image **********/   	
  pe_steps = prep_profile(profile[0],nv,&pe_grad,&per_grad);
  initval(pe_steps/2.0,vpe_offset);

  /* Shift DDR for pro *******************************/   	
  roff = -poffset(pro,ro_grad.roamp);

  g_setExpTime(tr*(nt*pe_steps*arraydim + ssc));

  /* PULSE SEQUENCE *************************************/
  status(A);
  rotate();
  obsoffset(resto);
  delay(4e-6);
  initval(fabs(ssc),vssc);      // Compressed steady-state counter
  assign(zero,vrfspoil_ctr);    // RF spoil phase counter
  assign(zero,vrfspoil);        // RF spoil multiplier
  assign(one,vacquire);         // real-time acquire flag
  setacqvar(vacquire);          // Turn on acquire when vacquire is zero 

  /* Delay all channels except gradient *****************/       
  sub(ssval,ssctr,v30);
  add(v30,ct,v30);
  if (ix == 1) { ifzero(v30); grad_advance(tep); endif(v30); }

  /* Begin phase-encode loop ****************************/       
  peloop(seqcon[2],pe_steps,vpe_steps,vpe_ctr);

    /* Compressed steady-states: 1st array & transient, all arrays if ssc is negative */
    if ((ix > 1) && (ssc > 0))
      assign(zero,vssc);
    sub(vpe_ctr,vssc,vpe_ctr);  // vpe_ctr counts up from -ssc
    assign(zero,vssc);
    if (seqcon[2] == 's')
      assign(zero,vacquire);    // Always acquire for non-compressed loop
    else {
      ifzero(vpe_ctr);
        assign(zero,vacquire);  // Start acquiring when vpe_ctr reaches zero
      endif(vpe_ctr);
    }

    /* Set rcvr/xmtr phase for RF spoiling *******************/
    if (rfspoil[0] == 'y') {
      incr(vrfspoil_ctr);                    // vrfspoil_ctr = 1  2  3  4  5  6
      add(vrfspoil,vrfspoil_ctr,vrfspoil);   // vrfspoil =     1  3  6 10 15 21
      xmtrphase(vrfspoil);
      rcvrphase(vrfspoil);
    }

    /* Read external kspace table if set ******************/       
    if (table)
      getelem(t1,vpe_ctr,vpe_mult);
    else {
      ifzero(vacquire);
        sub(vpe_ctr,vpe_offset,vpe_mult);
      elsenz(vacquire);
        sub(zero,vpe_offset,vpe_mult);  // Hold PE mult at initial value for steady states
      endif(vacquire);
    }

    /* PE rewinder follows PE table; zero if turned off ***/       
    if (perewind[0] == 'y')
      assign(vpe_mult,vper_mult);
    else
      assign(zero,vper_mult);

    /* Begin multislice loop ******************************/       
    msloop(seqcon[1],ns,vms_slices,vms_ctr);
      triggerSelect(trigger);           // Selectable trigger input
      delay(4e-6);
      if (ticks) {
        xgate(ticks);
        grad_advance(tep);              // Gradient propagation delay
      }

      /* TTL scope trigger **********************************/       
      sp1on(); delay(4e-6); sp1off();

      /* Prepulse options ***********************************/       
      if (sat[0]  == 'y') satbands();
      if (fsat[0] == 'y') fatsat();
      if (mt[0]   == 'y') mtc();
      if (ovs[0]  == 'y') {ovsbands(); rotate();}

      /* Optional IR pulse **********************************/ 
      if (ir[0] == 'y') {
	obspower(ir_rf.powerCoarse);
	obspwrf(ir_rf.powerFine);
	delay(4e-6);
	obl_shapedgradient(ssi_grad.name,ssi_grad.duration,0,0,ssi_grad.amp,NOWAIT);
	delay(ssi_grad.rfDelayFront);
	shapedpulselist(shapeIR,ssi_grad.rfDuration,oph,rof2,rof2,seqcon[1],vms_ctr);
	delay(ssi_grad.rfDelayBack);
	delay(ti_delay);
      }

      /* Slice select RF pulse ******************************/ 
      obspower(p1_rf.powerCoarse);
      obspwrf(p1_rf.powerFine);
      delay(4e-6);
      obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT);
      delay(ss_grad.rfDelayFront);
      shapedpulselist(shapeEx,ss_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
      delay(ss_grad.rfDelayBack);

      /* Phase encode, refocus, and dephase gradient ********/
      pe_shapedgradient(pe_grad.name,pe_grad.duration,-ror_grad.amp,0,-ssr_grad.amp,
          -pe_grad.increment,vpe_mult,WAIT);

      /* TE delay *******************************************/
      delay(te_delay);

      /* Readout gradient and acquisition ********************/
      obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.amp,0,0,NOWAIT);
      delay(ro_grad.atDelayFront);
      startacq(alfa);
      acquire(np,1.0/sw);
      delay(ro_grad.atDelayBack);
      endacq();

      /* Rewind / spoiler gradient *********************************/
      if ((perewind[0] == 'y') || (spoilflag[0] == 'y')) {
        pe_shapedgradient(per_name,perTime,spoil_grad.amp,pespoil_amp,spoil_grad.amp,
            per_grad.increment,vper_mult,WAIT);
      }

      /* Relaxation delay ***********************************/       
      if (!trtype)
        delay(tr_delay);
    endmsloop(seqcon[1],vms_ctr);

    if (trtype)
      delay(ns*tr_delay);
  endpeloop(seqcon[2],vpe_ctr);

  /* Inter-image delay **********************************/
  sub(ntrt,ct,vtrimage);
  decr(vtrimage);
  ifzero(vtrimage);
    delay(trimage);
  endif(vtrimage);

}
Exemplo n.º 11
0
pulsesequence()
{
  /* Internal variable declarations *************************/
  double  freq90[MAXNSLICE],freq180[MAXNSLICE],freqIR[MAXNSLICE];
  int     shape90=0, shape180=0, shapeIR=0;
  double  te_delay1, te_delay2, tr_delay, ti_delay = 0;
  double  del1=0, del2=0, del3=0, del4=0;
  double  tau1=0, tau2=0, difftime=0, tetime=0;
  int     table=0;

  /* Diffusion parameters */
#define MAXDIR 1024           /* Will anybody do more than 1024 directions or b-values? */
  double roarr[MAXDIR], pearr[MAXDIR], slarr[MAXDIR];
  int    nbval,               /* Total number of bvalues*directions */
         nbro, nbpe, nbsl,
	 i;    
  double bro[MAXDIR], bpe[MAXDIR], bsl[MAXDIR], /* b-values along RO, PE, SL */
         brs[MAXDIR], brp[MAXDIR], bsp[MAXDIR], /* and 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 */

  /* Real-time variables ************************************/
  int  vpe_steps  = v1;
  int  vpe_ctr    = v2;
  int  vms_slices = v3;
  int  vms_ctr    = v4;
  int  vpe_offset = v5;
  int  vpe_index  = v6;
  int  vph180     = v7;  // Phase of 180 pulse
  int  vph2       = v8;  // alternate phase of 180 on odd transients

  /*  Initialize paramaters *********************************/
  init_mri();

  /*  Check for external PE table ***************************/
  if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) {
    loadtable(petable);
    table = 1;
  }
  if ((diff[0] == 'y') && (gcrush < 4))
    warn_message("Advisory: set gcrush to higher value to avoid image artifacts");

  /* Initialize gradient structures *************************/
  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);
  init_rf(&p2_rf,p2pat,p2,flip2,rof2,rof2);
  init_slice(&ss_grad,"ss",thk);
  init_slice_butterfly(&ss2_grad,"ss2",thk*1.1,gcrush,tcrush);
  init_slice_refocus(&ssr_grad,"ssr");
  init_readout_butterfly(&ro_grad,"ro",lro,np,sw,gcrushro,tcrushro);
  init_readout_refocus(&ror_grad,"ror");
  init_phase(&pe_grad,"pe",lpe,nv);

  /* RF Calculations ****************************************/
  calc_rf(&p1_rf,"tpwr1","tpwr1f");
  calc_rf(&p2_rf,"tpwr2","tpwr2f");
  if (p2_rf.header.rfFraction != 0.5)
    abort_message("RF pulse for refocusing (%s) must be symmetric",p2pat);

  /* Gradient calculations **********************************/
  calc_slice(&ss_grad,&p1_rf,WRITE,"gss");
  calc_slice(&ss2_grad,&p2_rf,WRITE,"gss2");
    
  calc_slice_refocus(&ssr_grad, &ss_grad, NOWRITE,"gssr");
  calc_readout(&ro_grad, WRITE, "gro","sw","at");
  ro_grad.m0ref *= grof;
  calc_readout_refocus(&ror_grad, &ro_grad, NOWRITE, "gror");

  calc_phase(&pe_grad, NOWRITE, "gpe","tpe");

  /* Equalize refocus and PE gradient durations *************/
  calc_sim_gradient(&ror_grad, &pe_grad, &ssr_grad,0,WRITE);

  /* Set up diffusion gradient */
  if (diff[0] == 'y') {
    init_generic(&diff_grad,"diff",gdiff,tdelta);
    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,"","");
  }

  /* Min TE *************************************************/
  tau1 = ss_grad.rfCenterBack + pe_grad.duration + 4e-6 + ss2_grad.rfCenterFront;
  tau2 = ss2_grad.rfCenterBack + ror_grad.duration + ro_grad.timeToEcho + alfa;

  temin = 2*(MAX(tau1,tau2) + 2*4e-6);  /* have at least 4us between gradient events */

  /* Calculate te_delays with the current TE, then later see how diffusion fits */
  if ((minte[0] == 'y') || (te < temin)) {
    te_delay1 = temin/2 - tau1;
    te_delay2 = temin/2 - tau2;
  }
  else {
    te_delay1 = te/2 - tau1;
    te_delay2 = te/2 - tau2;
  }

  if (diff[0] =='y') {
    /* Is tDELTA long enough for RF refocusing gradient? */
    if (tDELTA < diff_grad.duration + ss2_grad.duration)
      abort_message("DELTA too short, increase to %.2fms",
        (diff_grad.duration + ss2_grad.duration)*1000+0.005);

    /* Is tDELTA too long for TE dead time? */
    difftime = tDELTA + diff_grad.duration;    // tDELTA + front & back half diff_grad
    tetime = ss2_grad.duration + te_delay1 + te_delay2;
    if (difftime > tetime) {
      temin += (difftime - tetime);
    }
  }

  /* We now know the minimum TE incl. diffusion */
  if (minte[0] == 'y') {
    te = temin;
    putvalue("te",ceil(te*1e6)*1e-6); /* round up to nearest us */
  }
  if (te < temin) {
    if (diff[0] == 'n') {
      abort_message("TE too short.  Minimum TE = %.2fms\n",temin*1000);   
    }
    else {
      abort_message("TE too short, increase to %.2fms or reduce DELTA to %.2fms",
        temin*1000,(tetime-diff_grad.duration)*1000);
    }
  }
  te_delay1 = te/2 - tau1;
  te_delay2 = te/2 - tau2;

  /* Set up delays around diffusion gradients */
  /* RF1 - del1 - diff - del2 - RF2 - del3 - diff - del4 - ACQ */
  if (diff[0] == 'y') {
    del1 = (tetime - difftime)/2;
    del4 = del1;
    del2 = te_delay1 - diff_grad.duration;
    del3 = te_delay2 - diff_grad.duration;

    if (del3 < 0.0) {             // shift diff block to right
      del1 += del3;
      del2 -= del3;
      del4 -= del3;
      del3 = 0;
    } else if (del2 < 0.0) {      // shift diff block to left
      del1 -= del2;
      del3 -= del2;
      del4 += del2;
      del2 = 0;
    }
  }
  else {  /* No diffusion */
    del1 = 0;
    del3 = 0;
    del2 = te_delay1;
    del4 = te_delay2;
  }

  /* Min TR *************************************************/   	
  trmin = (ss_grad.duration - ss_grad.rfCenterBack) + te + ro_grad.timeFromEcho;
  if (navigator[0] == 'y')
    trmin += (pe_grad.duration + ro_grad.duration);
  
  /* Optional prepulse calculations *************************/
  if (sat[0] == 'y') {
    create_satbands();
    trmin += satTime;
  }
  
  if (fsat[0] == 'y') {
    create_fatsat();
    trmin += fsatTime;
  }

  if (mt[0] == 'y') {
    create_mtc();
    trmin += mtTime;
  }

  if (ir[0] == 'y') {
    init_rf(&ir_rf,pipat,pi,flipir,rof2,rof2); 
    calc_rf(&ir_rf,"tpwri","tpwrif");
    init_slice_butterfly(&ssi_grad,"ssi",thk,gcrushir,tcrushir);
    calc_slice(&ssi_grad,&ir_rf,WRITE,"gssi");

    tau1 = ss_grad.duration - ss_grad.rfCenterBack; /* duration of ss_grad before RF center */
    ti_delay = ti - (ssi_grad.rfCenterBack + tau1);

    if (ti_delay < 0) {
      abort_message("TI too short, Minimum TI = %.2fms\n",(ti-ti_delay)*1000);
    }

    irTime = ti + ssi_grad.duration - ssi_grad.rfCenterBack;  /* time to add to TR */
    trmin += irTime;
    trmin -= tau1;  /* but subtract out ss_grad which was already included in TR */
  }

  trmin *= ns;
  if (mintr[0] == 'y'){
    tr = trmin + ns*4e-6;
    putvalue("tr",tr);
  }
  if (tr < trmin) {
    abort_message("TR too short.  Minimum TR= %.2fms\n",trmin*1000);   
  }
  tr_delay = (tr - trmin)/ns > 4e-6 ? (tr - trmin)/ns : 4e-6;


  /***************************************************/
  /* CALCULATE B VALUES ******************************/
  if (diff[0] == 'y') {
    /* 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++)  {
    /* Readout */
    Dro     = ror_grad.duration;
    bro[i]  = bval(gdiff*roarr[i],tdelta,tDELTA);
    bro[i] += bval(ro_grad.amp,ro_grad.timeToEcho,Dro);

    /* Slice */
    dgss2   = Dgss2 = ss_grad.rfCenterFront;
    dcrush  = tcrush;                      //"delta" for crusher part of butterfly 
    Dcrush  = dcrush + ss_grad.rfDuration; //"DELTA" for crusher
    bsl[i]  = bval(gdiff*slarr[i],tdelta,tDELTA);
    bsl[i] += bval(gcrush,dcrush,Dcrush);
    bsl[i] += bval(ss2_grad.ssamp,dgss2,Dgss2);
    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);
    bsl[i] += bval_nested(gcrush,dcrush,Dcrush,ss2_grad.ssamp,dgss2,Dgss2);

    /* Phase */
    bpe[i] = bval(gdiff*pearr[i],tdelta,tDELTA);

    /* Readout/Slice Cross-terms */
    brs[i]  = bval2(gdiff*roarr[i],gdiff*slarr[i],tdelta,tDELTA);
    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);



  /* 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]);

  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]);
  }

  /* Set pe_steps for profile or full image **********/   	
  pe_steps = prep_profile(profile[0],nv,&pe_grad,&null_grad);
  initval(pe_steps/2.0,vpe_offset);

  sgl_error_check(sglerror);


  /* Return parameters to VnmrJ */
  putvalue("rgss",ss_grad.tramp);  //90  slice ramp
  if (ss2_grad.enableButterfly) {   //180 slice ramps
    putvalue("rcrush",ss2_grad.crusher1RampToCrusherDuration);
    putvalue("rgss2",ss2_grad.crusher1RampToSsDuration);
  }
  else {
    putvalue("rgss2",ss2_grad.tramp);
  }
  if (ro_grad.enableButterfly) {
    putvalue("rgro",ro_grad.crusher1RampToSsDuration);
  }
  else {   
    putvalue("rgro",ro_grad.tramp);      //RO ramp
  }
  putvalue("tror",ror_grad.duration);  //ROR duration
  putvalue("rgror",ror_grad.tramp);    //ROR ramp
  putvalue("gpe",pe_grad.peamp);         //PE max amp
  putvalue("gss",ss_grad.ssamp);
  putvalue("gro",ro_grad.roamp);


  g_setExpTime(tr*(nt*pe_steps*arraydim + ssc));


  /* PULSE SEQUENCE *************************************/
  rotate();
  obsoffset(resto);
  roff = -poffset(pro,ro_grad.roamp);
  delay(4e-6);

  /* Begin phase-encode loop ****************************/       
  peloop(seqcon[2],pe_steps,vpe_steps,vpe_ctr);

    /* Read external kspace table if set ******************/       
    if (table)
      getelem(t1,vpe_ctr,vpe_index);
    else
      sub(vpe_ctr,vpe_offset,vpe_index);

    settable(t2,2,ph180);        // initialize phase tables and variables
    getelem(t2,vpe_ctr,vph180);
    add(oph,vph180,vph180);      // 180 deg pulse phase alternates +/- 90 from receiver
    mod2(ct,vph2);
    dbl(vph2,vph2);
    add(vph180,vph2,vph180);     // Alternate phase for 180 on odd transients

    /* Begin multislice loop ******************************/       
    msloop(seqcon[1],ns,vms_slices,vms_ctr);
      if (ticks) {
        xgate(ticks);
        grad_advance(gpropdelay);
      }
      /* TTL scope trigger **********************************/       
       sp1on(); delay(5e-6); sp1off();

      /* Prepulses ******************************************/       
      if (sat[0]  == 'y') satbands();
      if (fsat[0] == 'y') fatsat();
      if (mt[0]   == 'y') mtc();

      /* Optional IR pulse **********************************/ 
      if (ir[0] == 'y') {
	obspower(ir_rf.powerCoarse);
	obspwrf(ir_rf.powerFine);
	delay(4e-6);
	obl_shapedgradient(ssi_grad.name,ssi_grad.duration,0,0,ssi_grad.amp,NOWAIT);
	delay(ssi_grad.rfDelayFront);
	shapedpulselist(shapeIR,ssi_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
	delay(ssi_grad.rfDelayBack);
	delay(ti_delay);
      }

      /* Slice select RF pulse ******************************/ 
      obspower(p1_rf.powerCoarse);
      obspwrf(p1_rf.powerFine);
      delay(4e-6);
      obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT);
      delay(ss_grad.rfDelayFront);
      shapedpulselist(shape90,ss_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
      delay(ss_grad.rfDelayBack);

      /* Phase encode, refocus, and dephase gradient ********/
      pe_shapedgradient(pe_grad.name,pe_grad.duration,0,0,-ssr_grad.amp,
          pe_grad.increment,vpe_index,WAIT);

      delay(del1);           // delay to start of first diffusion gradient
      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);           // delay from end of diffusion to slice refocusing

      /* Refocusing RF pulse ********************************/ 
      obspower(p2_rf.powerCoarse);
      obspwrf(p2_rf.powerFine);
      delay(4e-6);
      obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0,0,ss2_grad.amp,NOWAIT);
      delay(ss2_grad.rfDelayFront);
      shapedpulselist(shape180,ss2_grad.rfDuration,vph180,rof2,rof2,seqcon[1],vms_ctr);
      delay(ss2_grad.rfDelayBack);

      delay(del3);           // delay from slice refocusing to second diffusion gradient
      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(del4);           // delay from end of diffusion gradient to readout event

      /* Readout gradient and acquisition ********************/
      roff = -poffset(pro,ro_grad.roamp);
      obl_shapedgradient(ror_grad.name,ror_grad.duration,-ror_grad.amp,0,0,WAIT);
      obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.amp,0,0,NOWAIT);
      delay(ro_grad.atDelayFront);
      startacq(alfa);
      acquire(np,1.0/sw);
      delay(ro_grad.atDelayBack);
      endacq();

      /* Rewind Phase encoding ******************************/
      pe_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,
          pe_grad.increment,vpe_index,WAIT);

      if (navigator[0] == 'y') {
  roff = -poffset(pro,-ro_grad.roamp);
	obl_shapedgradient(ro_grad.name,ro_grad.duration,-ro_grad.amp,0,0,NOWAIT);
	delay(ro_grad.atDelayFront);
	startacq(alfa);
	acquire(np,1.0/sw);
	delay(ro_grad.atDelayBack);
	endacq();
      }

      /* Relaxation delay ***********************************/       
      delay(tr_delay);

    endmsloop(seqcon[1],vms_ctr);
  endpeloop(seqcon[2],vpe_ctr);
}
Exemplo n.º 12
0
void create_watersuppress2() {
  int i;
  int sglpowerSave;

  /* Check that water suppression scheme is one of the allowed */
  if (strcmp(wss,"vapor") && 
      strcmp(wss,"wet")   && 
      strcmp(wss,"dry")   &&
      strcmp(wss,"1chess")) {
    abort_message("wss (water suppression scheme) must be vapor, wet, dry or 1chess (%s)",wss);
  }

  /* Initialize all inter-pulse ovs to zero; only modified for vapor */
  for (i = 0; i < 7; i++) vapor_ovs[i] = 0;
  global_ovs = 1;


  /***** Gradient spoil *****/
  init_generic(&wscrush_grad,"wscrush",gcrushws,tcrushws);
  calc_generic(&wscrush_grad,WRITE,"","");

  /***********************************************************/
  /** VAPOR **************************************************/
  /***********************************************************/
  if (!strcmp(wss,"vapor")) {
    nwsp = 7; /* 7 pulses */

    /* Original VAPOR (Tkac et al, MRM 1999, 41(4), 649-656) 
       has flip angle ratios 
          1 : 1 : 1.78 : 1 : 1.78 : 1 : 1.78
       and interpulse delays
         150, 80, 160, 80, 100, 30, 26 ms
       
       To allow longer (32ms gauss) RF pulses, this may be modified 
       without a significant hit in performance (Kinchesh, unpublished)
       to use flip angle ratios
          1 : 1 : 1.78 : 1 : 1.78 : 1.04 : 1.86
       and interpulse delays
         150, 80, 160, 80, 100, 40, 35 ms

       1.86 is the largest scaling factor on the flip angle;
       Calculate the power levels for the largest flip angle
       and adjust the fine power down for the rest.
       wsflipf is a fudge factor for optimization purposes. */

    sglpowerSave=sglpower;
    sglpower=0;
    

    init_rf(&ws_rf,wspat,pws,wsflipf*1.86*flipws,rof1,rof2);
    calc_rf(&ws_rf,"wstpwr","wstpwrf");
    wsfpwr[0] = ws_rf.powerFine*1.00/1.86;  
    wsfpwr[1] = ws_rf.powerFine*1.00/1.86;
    wsfpwr[2] = ws_rf.powerFine*1.78/1.86;  
    wsfpwr[3] = ws_rf.powerFine*1.00/1.86;
    wsfpwr[4] = ws_rf.powerFine*1.78/1.86; 
    wsfpwr[5] = ws_rf.powerFine*1.04/1.86;
    wsfpwr[6] = ws_rf.powerFine*wsflipf_last;

   sglpower=sglpowerSave;

    /* Delays between pulses */
    wsduration = ws_rf.rfDuration + rof1 + rof2 + wscrush_grad.duration;
    wsdel[0] = 0.150 - wsduration;  
    wsdel[1] = 0.080 - wsduration;
    wsdel[2] = 0.160 - wsduration; 
    wsdel[3] = 0.080 - wsduration;
    wsdel[4] = 0.100 - wsduration;  
    wsdel[5] = 0.040 - wsduration;
    wsdel[6] = 0.035 - wsduration + rof1 + ws_rf.rfDuration/2 + d1;
  //wsdel[6] =  d1;  //should have the ability to have the shortest delay in vapor
      /* ideally, one would also subtract the duration of the 
         initial slice select RF pulse, but we don't know that 
	 at this point */

    /* Spoiler gradient amplitudes */
    for (i=0; i<nwsp; i++) {
      wsgspoilamp[i] = wscrush_grad.amp;
      

      if (wsdel[i] < 0)
        abort_message("Water suppression pulse (pws) or gradient crusher duration (tcrushws) too long for VAPOR");
    }

    kx[0]=0;ky[0]=1;kz[0]=0;
    kx[1]=1;ky[1]=0;kz[1]=0;
    kx[2]=0;ky[2]=0;kz[2]=1;
    kx[3]=0;ky[3]=1;kz[3]=0;
    kx[4]=1;ky[4]=0;kz[4]=0;
    kx[5]=0;ky[5]=0;kz[5]=1;
    kx[6]=0;ky[6]=1;kz[6]=0;

    
    /* Set flag for applying ovs between pulses 4-5 and after 7 */
    printf("ovsTime is %f \n", ovsTime);
    printf("wsdel3 is %f \n", wsdel[3]);
    printf("wsdel6 is %f \n", wsdel[6]);
    printf("wsdel2 is %f \n", wsdel[2]);
    printf("wsdel5 is %f \n", wsdel[5]);
    if (ovs[0] == 'y') {
      if (wsdel[2] >= ovsTime) {
        vapor_ovs[2] = 1;
	wsdel[2] -= ovsTime;
	global_ovs = 0;
      }
      

     if (wsdel[3] >= ovsTime) {
        vapor_ovs[3] = 1;
	wsdel[3] -= ovsTime;
	global_ovs = 0;
      }

      if (wsdel[4] >= ovsTime) {
        vapor_ovs[4] = 1;
	wsdel[4] -= ovsTime;
	global_ovs = 0;
      }
    }
  }  /* end of VAPOR part */

  /***********************************************************/
  /** WET ****************************************************/
  /***********************************************************/
  else {
    if (!strcmp(wss,"wet")) {
      nwsp = 4; /* 4 pulses */

      /* Original WET has flip angles 81.4 : 101.4 : 69.3 : 161.0
         Ogg et al, JMR B 1994, 104(1), 1-10  
	 
	 Calculate the power levels for the 161 degree flip
	 and adjust the rest down through the fine power */
	 
      init_rf(&ws_rf,wspat,pws,wsflipf*(161.0/69.3)*flipws,rof1,rof2);
      calc_rf(&ws_rf,"wstpwr","wstpwrf");
      wsfpwr[0] = ws_rf.powerFine*81.4/161.0; 
      wsfpwr[1] = ws_rf.powerFine*101.4/161.0;
      wsfpwr[2] = ws_rf.powerFine*69.3/161.0; 
      wsfpwr[3] = ws_rf.powerFine*wsflipf_last;

      wsgspoilamp[0] = wscrush_grad.amp;
      wsgspoilamp[1] = wscrush_grad.amp/2.0; 
      wsgspoilamp[2] = wscrush_grad.amp/4.0; 
      wsgspoilamp[3] = wscrush_grad.amp/8.0; 

    kx[0]=1;ky[0]=1;kz[0]=1;
    kx[1]=1;ky[1]=1;kz[1]=1;
    kx[2]=1;ky[2]=1;kz[2]=1;
    kx[3]=1;ky[3]=1;kz[3]=1;
   
    }

    /***********************************************************/
    /** DRY; 3 identical CHESS pulses **************************/
    /***********************************************************/
    else {
      init_rf(&ws_rf,wspat,pws,wsflipf*1.0*flipws,rof1,rof2);
      calc_rf(&ws_rf,"wstpwr","wstpwrf");
      if (!strcmp(wss,"dry")) {
        nwsp = 3; /* 3 pulses */
        wsgspoilamp[0] = wscrush_grad.amp/4.0;
        wsgspoilamp[1] = wscrush_grad.amp/2.0;
        wsgspoilamp[2] = wscrush_grad.amp;


       kx[0]=1;ky[0]=1;kz[0]=1;
       kx[1]=1;ky[1]=1;kz[1]=1;
       kx[2]=1;ky[2]=1;kz[2]=1;
       
      wsfpwr[0] = ws_rf.powerFine; 
      wsfpwr[1] = ws_rf.powerFine;
      wsfpwr[2] = ws_rf.powerFine*wsflipf_last; 
	}
     

      /***********************************************************/
      /** SINGLE CHESS PULSE *************************************/
      /***********************************************************/
      /* 1chess is used by some to correct for coil loading in quantitation */
      if (!strcmp(wss,"1chess")) {
        nwsp = 1; /* single pulse */
        wsgspoilamp[0] = wscrush_grad.amp;
        wsfpwr[0]      = ws_rf.powerFine;
        kx[0]=1;ky[0]=1;kz[0]=1;
   
      }
    }

    /* For both WET, DRY and Single CHESS */
    for (i=0; i<nwsp; i++) wsdel[i] = ws_delay;

    wsdel[nwsp-1] += d1;   /* d1 tweaker delay */

  }
  
  /* Total duration of water supression module */
  wsTime = nwsp*(rof1 + ws_rf.rfDuration + rof2 + wscrush_grad.duration);
  for (i=0; i<nwsp; i++) {
    wsTime += wsdel[i];
    if (vapor_ovs[i]) wsTime += ovsTime;
  }

}
Exemplo n.º 13
0
pulsesequence() {
  /* Internal variable declarations *********************/
  double  freq90[MAXNSLICE],freq180[MAXNSLICE];
  int     shape90,shape180;
  double  minTE, te_delay1, te_delay2, minTR, tr_delay;
  double  tref, te1, te2;
  int     tpwr1f, tpwr2f;
    
  /* Real-time variables ****************************/
  int  vms_slices = v1;
  int  vms_ctr    = v2;

  /*  Initialize parameters *************************/
  init_mri();
  tpwr1f = (int) getval("tpwr1f");
  tpwr2f = (int) getval("tpwr2f");


  if ((nv > 0) && (profile[0] == 'n'))
    abort_message("Sorry, this sequence only acquires a profile, check the profile flag");

  /* Read RF shape but don't calculate powers *******/
  init_rf(&p1_rf,p1pat,p1,-1,rof1,rof2);
  calc_rf(&p1_rf,"","");
  init_rf(&p2_rf,p2pat,p2,-1,rof1,rof1);
  calc_rf(&p2_rf,"","");

  /* Gradient Calculations **************************/
  init_slice(&ss_grad,"gss",thk); 
  calc_slice(&ss_grad,&p1_rf,WRITE,"gss");
  init_slice_refocus(&ssr_grad, "ssr"); 
  calc_slice_refocus(&ssr_grad, &ss_grad, NOWRITE,"gssr");
  init_slice_butterfly(&ss2_grad,"gss2",thk,gcrush,tcrush); 
  calc_slice(&ss2_grad,&p2_rf,WRITE,"gss");

  init_readout(&ro_grad,"ro",lro,np,sw);
  calc_readout(&ro_grad, WRITE, "gro","sw","at"); 
  init_readout_refocus(&ror_grad,"ror");
  calc_readout_refocus(&ror_grad, &ro_grad, NOWRITE, "gror"); 

  /* Equalize Refocus Gradients  ********************/
  tref = calc_sim_gradient(&ror_grad, &ssr_grad, &null_grad, 0, WRITE); 

  /*  Min TE ******************************************/
  te1 = ss_grad.rfCenterBack + tref + 4e-6 + ss2_grad.rfCenterFront;
  te2 = ss2_grad.rfCenterBack + alfa + ro_grad.timeToEcho;
  minTE = 2*(te1 > te2 ? te1 : te2) + 2*4e-6;
  
  if (minte[0] == 'y') {
    te = minTE;
    putvalue("te",ceil(te*1e6)*1e-6); /* round up to nearest us */
  }
  if (te < minTE) {
    abort_message("TE too short.  Minimum TE= %.2fms\n",minTE*1000);   
  }
  te_delay1 = te/2 - te1;
  te_delay2 = te/2 - te2;

  /*  Min TR ******************************************/   	
  minTR =  (GDELAY + ss_grad.rfCenterFront + te + ro_grad.timeFromEcho) * ns;

  if (mintr[0] == 'y') {
    tr = minTR + 4e-6;
    putvalue("tr",tr);
  }
  if (tr < minTR + 4e-6) {
     abort_message("TR too short.  Minimum TR= %.2fms\n",(minTR + 4e-6)*1000);   
  }
  tr_delay = (tr - minTR)/ns;

  if (sglerror)
    abort_message("Sequence has error(s) and will not execute - See error message(s)!\n");


  offsetlist(pss,ss_grad.ssamp,0,freq90,ns,seqcon[1]);
  offsetlist(pss,ss2_grad.ssamp,0,freq180,ns,seqcon[1]);
  shape90  = shapelist(p1pat,ss_grad.rfDuration,freq90,ns,0,seqcon[1]);
  shape180 = shapelist(p2pat,ss2_grad.rfDuration,freq180,ns,0,seqcon[1]);


  /* PULSE SEQUENCE *************************************/
  settable(t1,4,phr);
  getelem(t1,ct,oph);    /* receiver phase */

  rotate();
  obsoffset(resto);
  delay(GDELAY);

  /* Begin multislice loop ******************************/       
  msloop(seqcon[1],ns,vms_slices,vms_ctr);
    if (ticks) {
      xgate(ticks);
      grad_advance(gpropdelay);
      delay(4e-6);
    }

    /* RF pulse *******************************************/ 
    obspower(tpwr1);
    obspwrf(tpwr1f);
    delay(GDELAY);
    obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT);   
    delay(ss_grad.rfDelayFront);
    shapedpulselist(shape90,ss_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
    delay(ss_grad.rfDelayBack);

    /* Refocusing gradients ******************/
    obl_shaped3gradient(ror_grad.name,"",ssr_grad.name,
                        ssr_grad.duration,
		        ror_grad.amp,0,-ssr_grad.amp,WAIT);   

    delay(te_delay1);

    /* RF pulse *******************************************/ 
    obspower(tpwr2);
    obspwrf(tpwr2f);
    delay(GDELAY);
    obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0,0,ss2_grad.amp,NOWAIT);   
    delay(ss2_grad.rfDelayFront);
    shapedpulselist(shape90,ss_grad.rfDuration,oph,rof1,rof1,seqcon[1],vms_ctr);
    delay(ss2_grad.rfDelayBack);

    delay(te_delay2);

    /* Readout gradient and acquisition ********************/
    obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.amp,0,0,NOWAIT);
    delay(ro_grad.atDelayFront);
    startacq(alfa);
    acquire(np,1.0/sw);
    endacq();
    delay(ro_grad.atDelayBack);
    
    delay(tr_delay);

  endmsloop(seqcon[1],vms_ctr);
}
Exemplo n.º 14
0
Arquivo: epi.c Projeto: timburrow/ovj3
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 */
Exemplo n.º 15
0
/***************************************************************************
Declaration : int main(void)

Function :    Main Loop
***************************************************************************/
int main(void)
{
	init_mcu();
	init_rf();
	init_buffer();
	init_protocol();
	init_freq();
	
	#ifdef TEST_TX_CW
		test_rf_transmitter(78);
	#endif
	#ifdef TEST_TX_MOD
		test_rf_modulator(81);
	#endif
	#ifdef TEST_RX
		test_rf_receiver(78);
	#endif
		
	/* Main Background loop */
	call_state = CALL_IDLE;
	
	while(1)
	{
		/* Call States */	
		switch (call_state)
		{
			case CALL_IDLE:
				#ifdef DONGLE
					sleep(WDT_TIMEOUT_60MS,STANDBY_MODE);
					call_status = CALL_NO_ACTIVITY;
					#ifdef USB
						SET_VOLUME_DOWN;
						SET_VOLUME_UP;
						SET_MUTE_PLAY;
						SET_MUTE_REC;
						if(CALL_ACTIVITY_PIN)
							call_status = CALL_ACTIVITY;
					#else
						if(!CALL_SETUP_KEY)
							call_status = CALL_ACTIVITY;
					#endif
					if(call_status == CALL_ACTIVITY)
						call_state = CALL_SETUP;
				#endif
				
				#ifdef HEADSET
					sleep(WDT_TIMEOUT_1S,POWER_DOWN_MODE);
					call_state = CALL_SETUP;
				#endif
				
			break;
			
			case CALL_SETUP:
				#ifdef DONGLE
					LED_ON;
					call_status = call_setup(&setup_freq[0],N_FREQ_SETUP);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						start_codec();
						#ifdef USB
							// Enable watchdog to handle USB Suspend Mode
							wdt_enable(WDT_TIMEOUT_15MS);
						#else
							start_timer1(0,FRAME_PERIOD, DIV1);
						#endif
						call_state = CALL_CONNECTED;
					}	
					else
						call_state = CALL_IDLE;
				#endif
								
				#ifdef HEADSET
					LED_ON;
					call_status = call_detect(&setup_freq[0],N_FREQ_SETUP,N_REP_SETUP);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						call_status &= ~MASTER_SYNC;
						start_timer1(0,FRAME_PERIOD, DIV1);
						call_state = CALL_CONNECTED;
					}
					else
						call_state = CALL_IDLE;
				#endif
			break;
			
			case CALL_CONNECTED:
				#ifdef DONGLE
					while(1)
					{
						// USB Dongle clears watchdog handling USB Suspend Mode
						#ifdef USB
							wdt_reset();
						#endif
						
						// Send and receive audio packet
						audio_transfer();
						
						// Handle key code from HEADSET
						key_code = (signal_in[1] & 0x1F);
						if(key_code != 0)
							LED_ON;
						else
							LED_OFF;
							
						#ifdef USB
							if(key_code & VOLUME_DOWN)
								CLEAR_VOLUME_DOWN;
							else
								SET_VOLUME_DOWN;
								
							if(key_code & VOLUME_UP)
								CLEAR_VOLUME_UP;
							else
								SET_VOLUME_UP;
								
							if(key_code & MUTE_PLAY)
								CLEAR_MUTE_PLAY;
							else
								SET_MUTE_PLAY;
								
							if(key_code & MUTE_REC)
								CLEAR_MUTE_REC;
							else
								SET_MUTE_REC;
						#endif
						
						// Check if call is to be cleared	
						#ifdef USB
							if(!CALL_ACTIVITY_PIN)
							{
								call_activity_timer += 1;
								if(call_activity_timer >= TIMEOUT_CALL_ACTIVITY)
									call_status = CALL_CLEAR;
							}
							else
								call_activity_timer = 0;
						
						#else
							if(!CALL_CLEAR_KEY)
								call_status = CALL_CLEAR;
						#endif
						
						
							
						// Call clearing by HEADSET or DONGLE
						if((key_code == CALL_CLEARING) || (call_status == CALL_CLEAR))
						{
							signal_out[0] |= SIGNAL_CALL_CLEAR;
							call_timer += 1;
							if(call_timer >= TIMEOUT_CALL_CLEAR_MASTER)
							{
								call_state = CALL_IDLE;
								stop_codec();
								init_buffer();
								init_rf();
								init_protocol();
								init_codec();
								eeprom_write(freq[0],EEPROM_ADR_FREQ0);
								eeprom_write(freq[1],EEPROM_ADR_FREQ1);
								LED_OFF;
								#ifdef USB
									// Disable watchdog used to handle USB Suspend Mode
									wdt_disable();
								#endif
								break;
							}
						}
						else
							signal_out[0] &= ~SIGNAL_CALL_CLEAR;
	
						// Call clearing due to Frame Loss
						if(frame_loss >= TIMEOUT_FRAME_LOSS)
						{
							#ifdef USB
								call_state = CALL_RECONNECT;
								init_rf();
								init_protocol();
								// Disable watchdog used to handle USB Suspend Mode
								wdt_disable();
							#else
								call_state = CALL_RECONNECT;
								stop_codec();
								init_buffer();
								init_rf();
								init_protocol();
								init_codec();
							#endif
							break;
						}
					}
				#endif
				
				#ifdef HEADSET
					while(1)
					{
						if(call_status & MASTER_SYNC)
						{
							audio_transfer();
						}
						else
						{
							call_status = get_sync();
							if(call_status & MASTER_SYNC)
								start_codec();
							else
								frame_loss += 10;
						}
						
						// Read and handle keys
						key_code = read_key();
						signal_out[1] &= 0xE0;
						signal_out[1] |= key_code;
						
						
						// Call cleared by DONGLE
						if(signal_in[0] & SIGNAL_CALL_CLEAR)
						{
							call_timer += 1;
							if(call_timer >= TIMEOUT_CALL_CLEAR_SLAVE)
							{
								call_state = CALL_IDLE;
								stop_codec();
								init_buffer();
								init_rf();
								init_protocol();
								init_codec();
								break;
							}
						}
						else
							call_timer = 0;
						
						// Call clearing due to Frame Loss
						if(frame_loss >= TIMEOUT_FRAME_LOSS)
						{
							call_state = CALL_RECONNECT;
							stop_codec();
							init_buffer();
							init_rf();
							init_protocol();
							init_codec();
							break;
						}
					}
				#endif
			break;

			case CALL_RECONNECT:
				#ifdef DONGLE
					LED_ON;
					call_status = call_setup(&setup_freq[0],N_FREQ_SETUP);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						#ifdef USB
							init_rf();
							init_protocol();
							reset_codec();
							call_state = CALL_CONNECTED;
						#else
							init_buffer();
							init_rf();
							init_protocol();
							init_codec();
							start_codec();
							start_timer1(0,FRAME_PERIOD, DIV1);
							call_state = CALL_CONNECTED;
						#endif
					}	
					else
					{
						stop_codec();
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						call_state = CALL_IDLE;
					}
				#endif
				
				#ifdef HEADSET
					LED_ON;
					call_status = call_detect(&setup_freq[0],N_FREQ_SETUP,N_REP_RECONNECT);
					LED_OFF;
					if(call_status != CALL_SETUP_FAILURE)
					{
						init_buffer();
						init_rf();
						init_protocol();
						init_codec();
						call_status &= ~MASTER_SYNC;
						start_timer1(0,FRAME_PERIOD, DIV1);
						call_state = CALL_CONNECTED;
					}
					else
						call_state = CALL_IDLE;

				#endif
			break;

			default:
			break;
		}
	}
}
Exemplo n.º 16
0
void pulsesequence() {
  /* Internal variable declarations *************************/
  int     shapelist90,shapelist180;
  double  seqtime,tau1,tau2,tau3,te1_delay,te2_delay,te3_delay,tr_delay;
  double  freq90[MAXNSLICE], freq180[MAXNSLICE];
  
  /* Diffusion variables */
  double  te1, te1min, del1, del2, del3, del4;
  double  te_diff1, te_diff2, tmp1, tmp2;
  double  diffamp;
  char    diffpat[MAXSTR];
  
  /* Navigator variables */
  double  etlnav;
  
  /* Variable crushers */
  double  cscale;
  double  vcrush;  // flag

  /* Diffusion parameters */
#define MAXDIR 1024           /* Will anybody do more than 1024 directions or b-values? */
  double roarr[MAXDIR], pearr[MAXDIR], slarr[MAXDIR];
  int    nbval,               /* Total number of bvalues*directions */
         nbro, nbpe, nbsl,
	 i;    
  double bro[MAXDIR], bpe[MAXDIR], bsl[MAXDIR], /* b-values along RO, PE, SL */
         brs[MAXDIR], brp[MAXDIR], bsp[MAXDIR], /* and 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 */

  /* Real-time variables used in this sequence **************/
  int  vpe_ctr     = v1;      // PE loop counter
  int  vpe_mult    = v2;      // PE multiplier, ranges from -PE/2 to PE/2
  int  vpe2_ctr    = v3;      // PE loop counter
  int  vpe2_mult   = v4;      // PE multiplier, ranges from -PE/2 to PE/2
  int  vpe2_offset = v5;
  int  vpe2_steps  = v6;
  int  vms_slices  = v7;      // Number of slices
  int  vms_ctr     = v8;      // Slice loop counter
  int  vseg        = v9;      // Number of ETL segments 
  int  vseg_ctr    = v10;      // Segment counter
  int  vetl        = v11;      // Echo train length
  int  vetl_ctr    = v12;      // Echo train loop counter
  int  vssc        = v13;     // Compressed steady-states
  int  vtrimage    = v14;     // Counts down from nt, trimage delay when 0
  int  vacquire    = v15;     // Argument for setacqvar, to skip steady state acquires
  int  vphase180   = v16;     // phase of 180 degree refocusing pulse
  int  vetl_loop   = v17;     // Echo train length MINUS ONE, used on etl loop
  int  vnav        = v18;     // Echo train length
  int  vcr_ctr     = v19;     // variable crusher, index into table
  int  vcr1        = v20;     // multiplier along RO
  int  vcr2        = v21;     // multiplier along PE
  int  vcr3        = v22;     // multiplier along SL
  int  vetl1       = v23;     // = etl-1, determine navigator echo location in echo loop
  int  vcr_reset   = v24;     // check for navigator echoes, reset crushers

  /* Initialize paramaters **********************************/
  get_parameters();
  te1    = getval("te1");     /* te1 is the echo time for the first echo */
  cscale = getval("cscale");  /* Scaling factor on first 180 crushers */
  vcrush = getval("vcrush");  /* Variable crusher or set amplitude? */
  getstr("diffpat",diffpat);


  /*  Load external PE table ********************************/
  if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) {
    loadtable(petable);
  } else {
    abort_message("petable undefined");
  }

  /* Hold variable crushers in tables 5, 6, 7 */
  settable(t5,8,crro);
  settable(t6,8,crpe);    
  settable(t7,8,crss);
    
  seqtime = 0.0;
  espmin = 0.0;

  /* RF Power & Bandwidth Calculations **********************/
  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);
  init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);
//  shape_rf(&p1_rf,"p1",p1pat,p1,flip1,rof1,rof2);
//  shape_rf(&p2_rf,"p2",p2pat,p2,flip2,rof1,rof2);
  calc_rf(&p1_rf,"tpwr1","tpwr1f");
  calc_rf(&p2_rf,"tpwr2","tpwr2f");
 
  /* Initialize gradient structures *************************/
  init_readout(&ro_grad,"ro",lro,np,sw); 
  init_readout_refocus(&ror_grad,"ror");
  init_phase(&pe_grad,"pe",lpe,nv);
  init_phase(&pe2_grad,"pe2",lpe2,nv2);
  init_slice(&ss_grad,"ss",thk);   /* NOTE assume same band widths for p1 and p2 */     
  init_slice(&ss2_grad,"ss2",thk);   /* not butterfly, want to scale crushers w/ echo */
  init_slice_refocus(&ssr_grad,"ssr");

  /* Gradient calculations **********************************/
  calc_readout(&ro_grad,WRITE,"gro","sw","at");
  calc_readout_refocus(&ror_grad,&ro_grad,NOWRITE,"gror");
  calc_phase(&pe_grad,NOWRITE,"gpe","tpe");
  calc_phase(&pe2_grad,NOWRITE,"gpe2","tpe2");
  calc_slice(&ss_grad,&p1_rf,WRITE,"gss");
  calc_slice(&ss2_grad,&p1_rf,WRITE,"");
  calc_slice_refocus(&ssr_grad,&ss_grad,WRITE,"gssr");

  /* Equalize refocus and PE gradient durations *************/
  calc_sim_gradient(&ror_grad,&pe_grad,&pe2_grad,0.0,WRITE);

  /* Variable crusher */
  init_generic(&crush_grad,"crush",gcrush,tcrush);
  calc_generic(&crush_grad,WRITE,"","");

  /* Create optional prepulse events ************************/
  if (sat[0]  == 'y') create_satbands();
  if (fsat[0] == 'y') create_fatsat();
  if (mt[0]   == 'y') create_mtc();
  
  /* Optional Diffusion gradient */
  if (diff[0] == 'y') {
    init_generic(&diff_grad,"diff",gdiff,tdelta);
    if (!strcmp("sine",diffpat)) {
      diff_grad.shape = SINE;
      diffamp         = gdiff*1;
    }
 
    /* adjust duration, so tdelta is from start ramp up to start ramp down */   
    if ((ix == 1) && (diff_grad.shape == TRAPEZOID)) {
      calc_generic(&diff_grad,NOWRITE,"","");
      diff_grad.duration += diff_grad.tramp; 
    }
    calc_generic(&diff_grad,WRITE,"","");  
  }

  /* Set up frequency offset pulse shape list ********/
  offsetlist(pss,ss_grad.amp,0,freq90,ns,seqcon[1]);
  offsetlist(pss,ss2_grad.ssamp,0,freq180,ns,seqcon[1]);
  shapelist90  = shapelist(p1_rf.pulseName,ss_grad.rfDuration, freq90, ns,0,seqcon[1]);
  shapelist180 = shapelist(p2_rf.pulseName,ss2_grad.rfDuration,freq180,ns,0,seqcon[1]);

  /* same slice selection gradient and RF pattern used */
  if (ss_grad.rfFraction != 0.5)
    abort_message("RF pulse must be symmetric (RF fraction = %.2f)",ss_grad.rfFraction);
  if (ro_grad.echoFraction != 1)
    abort_message("Echo Fraction must be 1");


  /*****************************************************/
  /* TIMING FOR ECHOES *********************************/
  /*****************************************************/
  /* First echo time, without diffusion */
  tau1 = ss_grad.rfCenterBack + ssr_grad.duration + crush_grad.duration + ss2_grad.rfCenterFront;
  tau2 = ss2_grad.rfCenterBack + crush_grad.duration + pe_grad.duration + ro_grad.timeToEcho;
  te1min = 2*MAX(tau1,tau2);
  if (te1 < te1min + 2*4e-6) {
    abort_message("First echo time too small, minimum is %.2fms\n",(te1min+2*4e-6)*1000);
  }

  /* Each half-echo period in the ETL loop ********/
  tau3 = ro_grad.timeFromEcho + pe_grad.duration + crush_grad.duration + ss2_grad.rfCenterFront;
  espmin = 2*MAX(tau2,tau3);   // Minimum echo spacing
  if (minesp[0] == 'y') {
    esp = espmin + 2*4e-6;
    putvalue("esp",esp);
  }
  if (esp - (espmin + 2*4e-6) < -12.5e-9) {
    abort_message("Echo spacing too small, minimum is %.2fms\n",(espmin+2*4e-6)*1000);
  }


  te1_delay = te1/2.0 - tau1;
  te2_delay = esp/2.0 - tau2;
  te3_delay = esp/2.0 - tau3;


  /*****************************************************/
  /* TIMING FOR DIFFUSION ******************************/
  /*****************************************************/
  del1 = te1/2.0 - tau1;
  del2 = 0;
  del3 = te1/2.0 - tau2;
  del4 = 0;

  if (diff[0] == 'y') {
    tau1 += diff_grad.duration;
    tau2 += diff_grad.duration;

    te1min = 2*MAX(tau1,tau2);
    if (te1 < te1min + 4*4e-6) {  /* te1 is split into 4 delays, each of which must be >= 4us */
      abort_message("ERROR %s: First echo time too small, minimum is %.2fms\n",seqfil,te1min*1000);
    }

    /* te1 is the echo time for the first echo */
    te_diff1 = te1/2 - tau1;  /* Available time in first half of first echo */
    te_diff2 = te1/2 - tau2;  /* Available time in second half of first echo */

    tmp1 = ss2_grad.duration + 2*crush_grad.duration;  /* duration of 180 block */
    /* Is tDELTA long enough? */
    if (tDELTA < diff_grad.duration + tmp1)
      abort_message("DELTA too short, increase to %.2fms",
        (diff_grad.duration + tmp1)*1000);

    /* Is tDELTA too long? */
    tmp2 = diff_grad.duration + te_diff1 + tmp1 + te_diff2;
    if (tDELTA > tmp2) {
      abort_message("DELTA too long, increase te1 to %.2fms",
        (te1 + (tDELTA-tmp2))*1000);
    }

    /* First attempt to put lobes right after slice select, ie del1 = 0 */
    del1 = 4e-6;  /* At least 4us after setting power for 180 */
    del2 = te_diff1 - del1;
    del3 = tDELTA - (diff_grad.duration + del2 + tmp1);
    
    if (del3 < 4e-6) {  /* shift diffusion block towards acquisition */
      del3 = 4e-6;
      del2 = tDELTA - (diff_grad.duration + tmp1 + del3);
    }

    del1 = te_diff1 - del2;
    del4 = te_diff2 - del3;
    
    if (fabs(del4) < 12.5e-9) del4 = 0;
  
  }
  te = te1 + (kzero-1)*esp;                // Return effective TE
  putvalue("te",te);

  /* How many echoes in the echo loop, including navigators? */
  etlnav = (etl-1)+(navigator[0]=='y')*2.0;
  
  /* Minimum TR **************************************/
  seqtime  = 4e-6 + 2*nseg*ns*4e-6;  /* count all the 4us delays */
  seqtime += ns*(ss_grad.duration/2 + te1 + (etlnav)*esp + ro_grad.timeFromEcho + pe_grad.duration + te3_delay);

  /* Increase TR if any options are selected****************/
  if (sat[0] == 'y')  seqtime += ns*satTime;
  if (fsat[0] == 'y') seqtime += ns*fsatTime;
  if (mt[0] == 'y')   seqtime += ns*mtTime;

  trmin = seqtime + ns*4e-6;  /* Add 4us to ensure that tr_delay is always >= 4us */
  if (mintr[0] == 'y'){
    tr = trmin;
    putvalue("tr",tr+1e-6);
  }
  if (tr < trmin) {
    abort_message("TR too short.  Minimum TR = %.2fms\n",trmin*1000);
  }
  tr_delay = (tr - seqtime)/ns;


  /* Set number of segments for profile or full image **********/
  nseg      = prep_profile(profile[0],nv/etl,&pe_grad,&per_grad);
  pe2_steps = prep_profile(profile[1],nv2,&pe2_grad,&pe2r_grad);

  /* Calculate total scan time */
  g_setExpTime(tr*(nt*nseg*pe2_steps*arraydim + ssc));




  /***************************************************/
  /* CALCULATE B VALUES ******************************/
  if (diff[0] == 'y') {
    /* 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++)  {
    dcrush = crush_grad.duration;       //"delta" for crusher
    Dcrush = dcrush + ss_grad.duration; //"DELTA" for crusher

    /* Readout */
    Dro     = ror_grad.duration;
    bro[i]  = bval(gdiff*roarr[i],tdelta,tDELTA);
    bro[i] += bval(ro_grad.amp,ro_grad.timeToEcho,Dro);
    bro[i] += bval(crush_grad.amp,dcrush,Dcrush);
    bro[i] += bval_nested(gdiff*roarr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);

    /* Slice */
    dgss2   = Dgss2 = ss_grad.rfCenterFront;
    bsl[i]  = bval(gdiff*slarr[i],tdelta,tDELTA);
    bsl[i] += bval(crush_grad.amp,dcrush,Dcrush);
    bsl[i] += bval(ss2_grad.ssamp,dgss2,Dgss2);
    bsl[i] += bval_nested(gdiff*slarr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);
    bsl[i] += bval_nested(gdiff*slarr[i],tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2);
    bsl[i] += bval_nested(ss2_grad.ssamp,dgss2,Dgss2,
                crush_grad.amp,dcrush,Dcrush);

    /* Phase */
    bpe[i]  = bval(gdiff*pearr[i],tdelta,tDELTA);
    bpe[i] += bval(crush_grad.amp,dcrush,Dcrush);
    bpe[i] += bval_nested(gdiff*pearr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);

    /* Readout/Slice Cross-terms */
    brs[i]  = bval2(gdiff*roarr[i],gdiff*slarr[i],tdelta,tDELTA);
    brs[i] += bval2(crush_grad.amp,
                    crush_grad.amp,dcrush,Dcrush);
    brs[i] += bval_cross(gdiff*roarr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);
    brs[i] += bval_cross(gdiff*slarr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);
    brs[i] += bval_cross(gdiff*roarr[i],tdelta,tDELTA,
                ss2_grad.ssamp,dgss2,Dgss2);
    brs[i] += bval_cross(crush_grad.amp,dcrush,Dcrush,
                ss2_grad.ssamp,dgss2,Dgss2);

    /* Readout/Phase Cross-terms */
    brp[i]  = bval2(gdiff*roarr[i],gdiff*pearr[i],tdelta,tDELTA);
    brp[i] += bval2(crush_grad.amp,
                    crush_grad.amp,dcrush,Dcrush);
    brp[i] += bval_cross(gdiff*roarr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);
    brp[i] += bval_cross(gdiff*pearr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);

    /* Slice/Phase Cross-terms */
    bsp[i]  = bval2(gdiff*pearr[i],gdiff*slarr[i],tdelta,tDELTA);
    bsp[i] += bval2(crush_grad.amp,
                    crush_grad.amp,dcrush,Dcrush);
    bsp[i] += bval_cross(gdiff*pearr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);
    bsp[i] += bval_cross(gdiff*slarr[i],tdelta,tDELTA,
                crush_grad.amp,dcrush,Dcrush);
    bsp[i] += bval_cross(gdiff*pearr[i],tdelta,tDELTA,
                ss2_grad.ssamp,dgss2,Dgss2);
    bsp[i] += bval_cross(crush_grad.amp,dcrush,Dcrush,
                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);





  /* Shift DDR for pro *******************************/
  roff = -poffset(pro,ro_grad.roamp);


  /* PULSE SEQUENCE *************************************/
  if (ix == 1) grad_advance(tep);
  initval(fabs(ssc),vssc);      // Compressed steady-state counter
  setacqvar(vacquire);          // Control acquisition through vacquire
  assign(one,vacquire);         // Turn on acquire when vacquire is zero

  /* Phase cycle: Alternate 180 phase to cancel residual FID */
  mod2(ct,vphase180);           // 0101
  dbl(vphase180,vphase180);     // 0202
  add(vphase180,one,vphase180); // 1313 Phase difference from 90
  add(vphase180,oph,vphase180);

  obsoffset(resto);
  delay(4e-6);
    
  initval(nseg,vseg);
  initval(pe2_steps/2.0,vpe2_offset);
  
  initval(etl,vetl);
  initval(etl-1,vetl1);

  peloop2(seqcon[3],pe2_steps,vpe2_steps,vpe2_ctr);
  /* Use standard encoding order for 2nd PE dimension */
  sub(vpe2_ctr,vpe2_offset,vpe2_mult);

    loop(vseg,vseg_ctr);

      /* Compressed steady-states: 1st array & transient, all arrays if ssc is negative */
      if ((ix > 1) && (ssc > 0))
	assign(zero,vssc);
      sub(vseg_ctr,vssc,vseg_ctr);   // vpe_ctr counts up from -ssc
      assign(zero,vssc);
      ifzero(vseg_ctr);
	assign(zero,vacquire);       // Start acquiring when vseg_ctr reaches zero
      endif(vseg_ctr);

      msloop(seqcon[1],ns,vms_slices,vms_ctr);
	if (ticks) {
          xgate(ticks);
          grad_advance(tep);
	}
	sp1on(); delay(4e-6); sp1off();    // Scope trigger

	/* Prepulse options ***********************************/
	if (sat[0]  == 'y') satbands();
	if (fsat[0] == 'y') fatsat();
	if (mt[0]   == 'y') mtc();

	/* 90 degree pulse ************************************/         
	rotate();
	obspower(p1_rf.powerCoarse);
	obspwrf(p1_rf.powerFine);
	delay(4e-6);
	obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT);   
	delay(ss_grad.rfDelayFront);
	shapedpulselist(shapelist90,ss_grad.rfDuration,oph,rof1,rof2,seqcon[1],vms_ctr);
	delay(ss_grad.rfDelayBack);

	/* Read dephase and Slice refocus *********************/
	obl_shapedgradient(ssr_grad.name,ssr_grad.duration,0.0,0.0,-ssr_grad.amp,WAIT);

	/* First half-TE delay ********************************/
	obspower(p2_rf.powerCoarse);
	obspwrf(p2_rf.powerFine);
	delay(del1);

	/* DIFFUSION GRADIENT */
	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);


	/*****************************************************/
	    /* FIRST ECHO OUTSIDE LOOP ***************************/
	/*****************************************************/
	ifzero(vacquire);  // real acquisition, get PE multiplier from table
          mult(vseg_ctr,vetl,vpe_ctr);
          getelem(t1,vpe_ctr,vpe_mult);
	elsenz(vacquire);  // steady state scan 
          assign(zero,vpe_mult);
	endif(vacquire);

	/* Variable crusher */
	assign(zero,vcr_ctr);
	getelem(t5,vcr_ctr,vcr1); 
	getelem(t6,vcr_ctr,vcr2);	     
	getelem(t7,vcr_ctr,vcr3);

  if(vcrush) 
	phase_encode3_oblshapedgradient(crush_grad.name,crush_grad.name,crush_grad.name,
	  crush_grad.duration,
	  (double)0,(double)0,(double)0,                                     // base levels
	  crush_grad.amp*cscale,crush_grad.amp*cscale,crush_grad.amp*cscale, // step size
	  vcr1,vcr2,vcr3,                                                    // multipliers
	  (double)1.0,(double)1.0,(double)1.0,                               // upper limit on multipliers
	  1,WAIT,0);

  else 
  obl_shapedgradient(crush_grad.name,crush_grad.duration,
    crush_grad.amp,crush_grad.amp,crush_grad.amp,WAIT);

	/* 180 degree pulse *******************************/
	obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0,0,ss2_grad.amp,NOWAIT);   
	delay(ss2_grad.rfDelayFront); 
	shapedpulselist(shapelist180,ss2_grad.rfDuration,vphase180,rof1,rof2,seqcon[1],vms_ctr);
	delay(ss2_grad.rfDelayBack);   

  if (vcrush)
	phase_encode3_oblshapedgradient(crush_grad.name,crush_grad.name,crush_grad.name,
	  crush_grad.duration,
	  (double)0,(double)0,(double)0,                                     // base levels
	  crush_grad.amp*cscale,crush_grad.amp*cscale,crush_grad.amp*cscale, // step size
	  vcr1,vcr2,vcr3,                                                    // multipliers
	  (double)1.0,(double)1.0,(double)1.0,                               // upper limit on multipliers
	  1,WAIT,0);
  else
  obl_shapedgradient(crush_grad.name,crush_grad.duration,
    crush_grad.amp,crush_grad.amp,crush_grad.amp,WAIT);

	delay(del3);

	/* DIFFUSION GRADIENT */
	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(del4);

	/* Phase-encode gradient ******************************/
	pe2_shapedgradient(pe_grad.name,pe_grad.duration,-ror_grad.amp,0,0,
	  -pe_grad.increment,-pe2_grad.increment,vpe_mult,vpe2_mult,WAIT);

	/* Readout gradient ************************************/
	obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.roamp,0,0,NOWAIT);
	delay(ro_grad.atDelayFront);

	/* Acquire data ****************************************/
	startacq(10e-6);
	acquire(np,1.0/sw);
	endacq();

	delay(ro_grad.atDelayBack);

	/* Rewinding phase-encode gradient ********************/
	pe2_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,
	  pe_grad.increment,pe2_grad.increment,vpe_mult,vpe2_mult,WAIT);

	/* Second half-TE delay *******************************/
	delay(te3_delay);


	/*****************************************************/
	    /* LOOP THROUGH THE REST OF ETL **********************/
	/*****************************************************/
	peloop(seqcon[2],etlnav,vetl_loop,vetl_ctr);
	  ifzero(vacquire);  // real acquisition, get PE multiplier from table
            mult(vseg_ctr,vetl,vpe_ctr);
            add(vpe_ctr,vetl_ctr,vpe_ctr);
	    add(vpe_ctr,one,vpe_ctr);
            getelem(t1,vpe_ctr,vpe_mult);
    	  elsenz(vacquire);  // steady state scan 
	    assign(zero,vpe_mult);
	  endif(vacquire);

	  /* But don't phase encode navigator echoes */
          ifrtGE(vetl_ctr,vetl1,vnav);
	    assign(zero,vpe_mult);
	  endif(vnav);


    	  /* Variable crusher */
	  incr(vcr_ctr);  /* Get next crusher level */
	  /* Except if we're doing navigators, start over */
	  sub(vetl1,vetl_ctr,vcr_reset);
	  ifzero(vcr_reset);
	    assign(zero,vcr_ctr);
	  endif(vcr_reset);

    	  getelem(t5,vcr_ctr,vcr1); 
    	  getelem(t6,vcr_ctr,vcr2);	     
    	  getelem(t7,vcr_ctr,vcr3);

	  phase_encode3_oblshapedgradient(crush_grad.name,crush_grad.name,crush_grad.name,
	    crush_grad.duration,
	    (double)0,(double)0,(double)0,                                     // base levels
	    crush_grad.amp,crush_grad.amp,crush_grad.amp,                      // step size
	    vcr1,vcr2,vcr3,                                                    // multipliers
	    (double)1.0,(double)1.0,(double)1.0,                               // upper limit on multipliers
	    1,WAIT,0);

          /* 180 degree pulse *******************************/
          obl_shapedgradient(ss2_grad.name,ss2_grad.duration,0,0,ss2_grad.amp,NOWAIT);   
    	  delay(ss2_grad.rfDelayFront); 
          shapedpulselist(shapelist180,ss2_grad.rfDuration,vphase180,rof1,rof2,seqcon[1],vms_ctr);
          delay(ss2_grad.rfDelayBack);   

          /* Variable crusher */
	  phase_encode3_oblshapedgradient(crush_grad.name,crush_grad.name,crush_grad.name,
	    crush_grad.duration,
	    (double)0,(double)0,(double)0,                                     // base levels
	    crush_grad.amp,crush_grad.amp,crush_grad.amp,                      // step size
	    vcr1,vcr2,vcr3,                                                    // multipliers
	    (double)1.0,(double)1.0,(double)1.0,                               // upper limit on multipliers
	    1,WAIT,0);

          /* Phase-encode gradient ******************************/
	  pe2_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,
	    -pe_grad.increment,-pe2_grad.increment,vpe_mult,vpe2_mult,WAIT);

          /* Second half-TE period ******************************/
	  delay(te2_delay);

          /* Readout gradient ************************************/
          obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.roamp,0,0,NOWAIT);
          delay(ro_grad.atDelayFront);
          startacq(10e-6);
          acquire(np,1.0/sw);
	  endacq();
          delay(ro_grad.atDelayBack);

          /* Rewinding phase-encode gradient ********************/
	  pe2_shapedgradient(pe_grad.name,pe_grad.duration,0,0,0,
	    pe_grad.increment,pe2_grad.increment,vpe_mult,vpe2_mult,WAIT);

          /* Second half-TE delay *******************************/
          delay(te3_delay);
	endpeloop(seqcon[2],vetl_ctr);

	/* Relaxation delay ***********************************/
	if (!trtype)
          delay(tr_delay);
      endmsloop(seqcon[1],vms_ctr);
      if (trtype)
	delay(ns*tr_delay);
    endloop(vseg_ctr);
  endpeloop(seqcon[3],vpe2_ctr);

  /* Inter-image delay **********************************/
  sub(ntrt,ct,vtrimage);
  decr(vtrimage);
  ifzero(vtrimage);
    delay(trimage);
  endif(vtrimage);
}
Exemplo n.º 17
0
void cc1101_hw_init()
{
    reset_cc1101();
    init_rf();
    write_cc1101(CCxxx0_PATABLE,PaTabel,8,TYPE_BURST);
}
Exemplo n.º 18
0
pulsesequence()
{
  /* Internal variable declarations *************************/ 
  double  freqEx[MAXNSLICE];
  double  pespoil_amp,spoilMoment,maxgradtime,pe2_offsetamp=0.0,nvblock;
  double  tetime,te_delay,tr_delay,perTime;
  int     table=0,shapeEx=0,sepSliceRephase=0,image,blocknvs;
  char    spoilflag[MAXSTR],perName[MAXSTR],slab[MAXSTR];

  /* Real-time variables used in this sequence **************/
  int  vpe_steps    = v1;      // Number of PE steps
  int  vpe_ctr      = v2;      // PE loop counter
  int  vpe_offset   = v3;      // PE/2 for non-table offset
  int  vpe_mult     = v4;      // PE multiplier, ranges from -PE/2 to PE/2
  int  vper_mult    = v5;      // PE rewinder multiplier; turn off rewinder when 0
  int  vpe2_steps   = v6;      // Number of PE2 steps
  int  vpe2_ctr     = v7;      // PE2 loop counter
  int  vpe2_mult    = v8;      // PE2 multiplier
  int  vpe2_offset  = v9;      // PE2/2 for non-table offset
  int  vpe2r_mult   = v10;     // PE2 rewinder multiplier
  int  vtrigblock   = v11;     // Number of PE steps per trigger block
  int  vpe          = v12;     // Current PE step out of total PE*PE2 steps

  /*  Initialize paramaters *********************************/
  init_mri();
  getstr("spoilflag",spoilflag);                                     
  getstr("slab",slab);
  image = getval("image");
  blocknvs = (int)getval("blocknvs");
  nvblock = getval("nvblock");
  if (!blocknvs) nvblock=1;    // If blocked PEs for trigger not selected nvblock=1

  trmin = 0.0;
  temin = 0.0;

  /*  Check for external PE table ***************************/
  if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) {
    loadtable(petable);
    table = 1;
  }

  if (ns > 1)  abort_message("No of slices must be set to one");   

  /* RF Calculations ****************************************/
  init_rf(&p1_rf,p1pat,p1,flip1,rof1,rof2);   /* hard pulse */
  init_rf(&p2_rf,p2pat,p2,flip2,rof1,rof2);   /* soft pulse */
  calc_rf(&p1_rf,"tpwr1","tpwr1f");
  calc_rf(&p2_rf,"tpwr2","tpwr2f");

  /* Gradient calculations **********************************/
  if (slab[0] == 'y') {
    init_slice(&ss_grad,"ss",thk);
    init_slice_refocus(&ssr_grad,"ssr");
    calc_slice(&ss_grad,&p2_rf,WRITE,"gss");
    calc_slice_refocus(&ssr_grad,&ss_grad,WRITE,"gssr");
  }
  if (FP_GT(tcrushro,0.0))
    init_readout_butterfly(&ro_grad,"ro",lro,np,sw,gcrushro,tcrushro);
  else
    init_readout(&ro_grad,"ro",lro,np,sw);
  init_readout_refocus(&ror_grad,"ror");
  calc_readout(&ro_grad,WRITE,"gro","sw","at");
  ro_grad.m0ref *= grof;
  calc_readout_refocus(&ror_grad,&ro_grad,NOWRITE,"gror");
  init_phase(&pe_grad,"pe",lpe,nv);
  init_phase(&pe2_grad,"pe2",lpe2,nv2);
  calc_phase(&pe_grad,NOWRITE,"gpe","tpe");
  if (!blocknvs) nvblock=1;
  calc_phase(&pe2_grad,NOWRITE,"gpe2","");

  if (spoilflag[0] == 'y') {                         // Calculate spoil grad if spoiling is turned on
    init_dephase(&spoil_grad,"spoil");               // Optimized spoiler
    spoilMoment = ro_grad.acqTime*ro_grad.roamp;     // Optimal spoiling is at*gro for 2pi per pixel
    spoilMoment -= ro_grad.m0def;                    // Subtract partial spoiling from back half of readout
    calc_dephase(&spoil_grad,WRITE,spoilMoment,"gspoil","tspoil");
  }

  /* Is TE long enough for separate slab refocus? ***********/
  maxgradtime = MAX(ror_grad.duration,MAX(pe_grad.duration,pe2_grad.duration));
  if (spoilflag[0] == 'y')
    maxgradtime = MAX(maxgradtime,spoil_grad.duration);
  tetime = maxgradtime + alfa + ro_grad.timeToEcho + 4e-6;
  if (slab[0] == 'y') {
    tetime += ss_grad.rfCenterBack + ssr_grad.duration;
    if ((te >= tetime) && (minte[0] != 'y')) {
      sepSliceRephase = 1;                                 // Set flag for separate slice rephase
    } else {
      pe2_grad.areaOffset = ss_grad.m0ref;                 // Add slab refocus on pe2 axis
      calc_phase(&pe2_grad,NOWRITE,"gpe2","");             // Recalculate pe2 to include slab refocus
    }
  }
 
  /* Equalize refocus and PE gradient durations *************/
  pespoil_amp = 0.0;
  perTime = 0.0;
  if ((perewind[0] == 'y') && (spoilflag[0] == 'y')) {   // All four must be single shape
    if (ror_grad.duration > spoil_grad.duration) {       // calc_sim first with ror
      calc_sim_gradient(&pe_grad,&pe2_grad,&ror_grad,tpemin,WRITE);
      calc_sim_gradient(&ror_grad,&spoil_grad,&null_grad,tpemin,NOWRITE);
    } else {                                             // calc_sim first with spoil
      calc_sim_gradient(&pe_grad,&pe2_grad,&spoil_grad,tpemin,WRITE);
      calc_sim_gradient(&ror_grad,&spoil_grad,&null_grad,tpemin,NOWRITE);
    }
    strcpy(perName,pe_grad.name);
    perTime = pe_grad.duration;
    putvalue("tspoil",perTime);
    putvalue("gspoil",spoil_grad.amp);
  } else {                      // post-acquire shape will be either pe or spoil, but not both
    calc_sim_gradient(&ror_grad,&pe_grad,&pe2_grad,tpemin,WRITE);
    if ((perewind[0] == 'y') && (spoilflag[0] == 'n')) {     // Rewinder, no spoiler
      strcpy(perName,pe_grad.name);
      perTime = pe_grad.duration;
      spoil_grad.amp = 0.0;
      putvalue("tpe",perTime);
    } else if ((perewind[0] == 'n') && (spoilflag[0] == 'y')) {  // Spoiler, no rewinder
      strcpy(perName,spoil_grad.name);
      perTime = spoil_grad.duration;
      pespoil_amp = spoil_grad.amp;      // Apply spoiler on PE & PE2 axis if no rewinder
    }
  }

  if (slab[0] == 'y') pe2_offsetamp = sepSliceRephase ? 0.0 : pe2_grad.offsetamp;  // pe2 slab refocus

  /* Create optional prepulse events ************************/
  if (sat[0] == 'y')  create_satbands();
  if (fsat[0] == 'y') create_fatsat();

  sgl_error_check(sglerror);                               // Check for any SGL errors
  
  /* Min TE ******************************************/
  tetime = pe_grad.duration + alfa + ro_grad.timeToEcho;
  if (slab[0] == 'y') {
    tetime += ss_grad.rfCenterBack;
    tetime += (sepSliceRephase) ? ssr_grad.duration : 0.0;   // Add slice refocusing if separate event
  }
  else if (ws[0] == 'y')
    tetime += p2/2.0 + rof2;	/* soft pulse */
  else
    tetime += p1/2.0 + rof2;	/* hard pulse */
  temin = tetime + 4e-6;                                   // Ensure that te_delay is at least 4us
  if (minte[0] == 'y') {
    te = temin;
    putvalue("te",te);
  }
  if (te < temin) {
    abort_message("TE too short.  Minimum TE= %.2fms\n",temin*1000+0.005);   
  }
  te_delay = te - tetime;

  /* Min TR ******************************************/   	
  trmin  = te_delay + pe_grad.duration + ro_grad.duration + perTime;
  if (slab[0] == 'y') {
    trmin += ss_grad.duration;
    trmin += (sepSliceRephase) ? ssr_grad.duration : 0.0;   // Add slice refocusing if separate event
  }
  else if (ws[0] == 'y')
    trmin += p2 +rof1 + rof2;	/* soft pulse */
  else
    trmin += p1 +rof1 + rof2;	/* hard pulse */
  trmin += 8e-6;

  /* Increase TR if any options are selected *********/
  if (sat[0] == 'y')  trmin += satTime;
  if (fsat[0] == 'y') trmin += fsatTime;
  if (ticks > 0) trmin += 4e-6;

  if (mintr[0] == 'y') {
    tr = trmin;
    putvalue("tr",tr);
  }
  if (FP_LT(tr,trmin)) {
    abort_message("TR too short.  Minimum TR = %.2fms\n",trmin*1000+0.005);
  }

  /* Calculate tr delay */
  tr_delay = granularity(tr-trmin,GRADIENT_RES);

  if(slab[0] == 'y') {
    /* Generate phase-ramped pulses: 90 */
    offsetlist(pss,ss_grad.ssamp,0,freqEx,ns,seqcon[1]);
    shapeEx = shapelist(p1pat,ss_grad.rfDuration,freqEx,ns,ss_grad.rfFraction,seqcon[1]);
  }

  /* Set pe_steps for profile or full image **********/   	
  pe_steps = prep_profile(profile[0],nv,&pe_grad,&null_grad);
  F_initval(pe_steps/2.0,vpe_offset);

  pe2_steps = prep_profile(profile[1],nv2,&pe2_grad,&null_grad);
  F_initval(pe2_steps/2.0,vpe2_offset);

  assign(zero,oph);

  /* Shift DDR for pro *******************************/   	
  roff = -poffset(pro,ro_grad.roamp);

  /* Adjust experiment time for VnmrJ *******************/
  g_setExpTime(tr*(nt*pe_steps*pe2_steps));

  /* PULSE SEQUENCE *************************************/
  status(A);
  rotate();
  triggerSelect(trigger);       // Select trigger input 1/2/3
  obsoffset(resto);
  delay(4e-6);

  /* trigger */
  if (ticks > 0) F_initval((double)nvblock,vtrigblock);

  /* Begin phase-encode loop ****************************/       
  peloop2(seqcon[3],pe2_steps,vpe2_steps,vpe2_ctr);

    peloop(seqcon[2],pe_steps,vpe_steps,vpe_ctr);

      delay(tr_delay);   // relaxation delay

      sub(vpe_ctr,vpe_offset,vpe_mult);
      sub(vpe2_ctr,vpe2_offset,vpe2_mult);

      mult(vpe2_ctr,vpe_steps,vpe);
      add(vpe_ctr,vpe,vpe);

      /* PE rewinder follows PE table; zero if turned off ***/       
      if (perewind[0] == 'y') {
        assign(vpe_mult,vper_mult);
        assign(vpe2_mult,vpe2r_mult);
      }
      else {
        assign(zero,vper_mult);
        assign(zero,vpe2r_mult);
      }

      if (ticks > 0) {
        modn(vpe,vtrigblock,vtest);
        ifzero(vtest);                // if the beginning of an trigger block
          xgate(ticks);
          grad_advance(gpropdelay);
          delay(4e-6);
        elsenz(vtest);
          delay(4e-6);
        endif(vtest);
      }

      sp1on(); delay(4e-6); sp1off(); // Scope trigger

      /* Prepulse options ***********************************/
      if (sat[0] == 'y')  satbands();
      if (fsat[0] == 'y') fatsat();

      if (slab[0] == 'y') {
        obspower(p2_rf.powerCoarse);
        obspwrf(p2_rf.powerFine);
        delay(4e-6);
	obl_shapedgradient(ss_grad.name,ss_grad.duration,0,0,ss_grad.amp,NOWAIT);
	delay(ss_grad.rfDelayFront);
	shapedpulselist(shapeEx,ss_grad.rfDuration,zero,rof1,rof2,seqcon[1],zero);
	delay(ss_grad.rfDelayBack);
        if (sepSliceRephase) {
          obl_shapedgradient(ssr_grad.name,ssr_grad.duration,0,0,-ssr_grad.amp,WAIT);
          delay(te_delay + tau);   /* tau is current B0 encoding delay */
        }
      } else {
        obspower(p1_rf.powerCoarse);
        obspwrf(p1_rf.powerFine);
        delay(4e-6);
        if (ws[0] == 'y')
          shapedpulse(p2pat,p2,zero,rof1,rof2);   /* soft CS pulse */
        else
          shapedpulse(p1pat,p1,zero,rof1,rof2);   /* hard pulse */
        delay(te_delay + tau);   /* tau is current B0 encoding delay */
      }        

      pe2_shapedgradient(pe_grad.name,pe_grad.duration,-ror_grad.amp*image,0,-pe2_offsetamp,
          -pe_grad.increment,-pe2_grad.increment,vpe_mult,vpe2_mult,WAIT);

      if ((slab[0] == 'y') && !sepSliceRephase) delay(te_delay + tau);   /* tau is current B0 encoding delay */

      /* Readout gradient and acquisition ********************/
      obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.amp*image,0,0,NOWAIT);
      delay(ro_grad.atDelayFront);
      startacq(alfa);
      acquire(np,1.0/sw);
      delay(ro_grad.atDelayBack);
      endacq();

      /* Rewind / spoiler gradient *********************************/
      if (perewind[0] == 'y' || (spoilflag[0] == 'y')) {
        pe2_shapedgradient(perName,perTime,spoil_grad.amp,pespoil_amp,pespoil_amp,
          pe_grad.increment,pe2_grad.increment,vper_mult,vpe2r_mult,WAIT);
      }  

    endpeloop(seqcon[2],vpe_ctr);

  endpeloop(seqcon[3],vpe2_ctr);

}
Exemplo n.º 19
0
int main(void) {
	volatile int16_t* samples;
	unsigned int i;
	DISABLE_GLOBAL_INT();
	/* stop watchdog timer */
	WDTCTL = WDTPW +WDTHOLD;
	/* SET CPU to 5MHz */
	/* max DCO
	   MCLK = DCOCLK
	   SMCLK = DCOCLK
	   ACLK = 8KHz
	*/
	DCOCTL = DCO0 + DCO1 + DCO2;
	BCSCTL1 = RSEL0 + RSEL1 + RSEL2 + XT2OFF;
	BCSCTL2 = 0x00;

	delay_us(10000);

	/* activate Active Mode */
	__bic_SR_register(LPM4_bits);

	/* set LEDs when loaded */
	P5SEL = 0x00;
	P5DIR = 0x70;
	LED_RED_ON();
	LED_GREEN_OFF();
	LED_BLUE_OFF();

	check_for_clock();
	init_usb_serial();
#ifdef USE_DMA
	init_dma(&g_sample_flag);
#endif

#ifdef TX
	init_adc(&g_sample_flag);
#else
	init_dac();
#endif
	init_rf(RF_CHANNEL, PAN_ID, NODE_ADDR, &g_sample_flag);

	debug_print("Successfully booted.\n");
	/* set LEDS to signalize finished initilizing */
	LED_RED_OFF();
	ENABLE_GLOBAL_INT();

#ifdef TX
	/* TX */
	while(1) {
		if(g_sample_flag == 1) {
			g_sample_flag = 0;
#ifdef USE_DMA
			/* get samples */
			samples = get_samples_dma();
#else
			/* get samples */
			samples = get_samples();
#endif
			/* send oder radio, 2*num_words */
			send_rf_data(RF_RX_ADDR, (uint8_t*) samples, NUM_SAMPLES*2);
		}
		/* reset WDT */
		WDTCTL = WDTPW + WDTCNTCL;

	}
#else
	/* RX */
	while(1) {
		if(g_sample_flag == 1) {
			g_sample_flag = 0;
			samples = get_samples_rf();
#if 0
			uint8_t err = 0;
			for(i = 0; i < NUM_SAMPLES; ++i) {
				//samples[i] = 4095-7*i;
				usb_printf("%d\n", samples[i]);
				//if( ((uint16_t) samples[i]) > 4095) {
				//	usb_printf("i=%u\n", i);
				//	++err;
				//}
			}
			usb_printf("#error: %u\n", err);
			usb_printf("\n\n");
#endif			
			set_dma_data(samples, NUM_SAMPLES);
		}
		/* reset WDT */
		WDTCTL = WDTPW + WDTCNTCL;
	}
#endif
	return 0;
}
Exemplo n.º 20
0
void create_ovsbands2() {
  double posoff;        /* positional offset relative to voxel position */
  double csdvox,csdovs; /* chemical shift displacement errors */
  int sglpowerSave;

  if (ovs[0] == 'y') {
  
    if (sat[0] == 'y') {/* Disallow both OVS and sat bands */
      abort_message("Can not do both OVS and Sat bands, select one or the other.");
    }
    nsat = 6;
    
    /**************************************************/
    /* The OVS functions are built to support suppression of outer-voxel signal
       and assume that you use the vox1_grad, vox2_grad, vox3_grad structs to
       hold information about the voxels. 
       Check that these have been initialized properly */
    /**************************************************/
    if ((vox1_grad.rfBandwidth <= 0) || (vox2_grad.rfBandwidth <= 0) || (vox3_grad.rfBandwidth <= 0)
      ||(vox1_grad.thickness   <= 0) || (vox2_grad.thickness   <= 0) || (vox3_grad.thickness   <= 0)) {
      abort_message("create_ovs: voxel parameters are not initialized correctly");
    }  

    init_slice(&sat_grad,"ovs",ovsthk);
    init_generic(&satcrush_grad,"satcrush",gcrushsat,tcrushsat);

   
   // sglpowerSave=sglpower;
   // sglpower=0;
   
    //this is creating variable flip ovs sat pulses
    init_rf(&sat_rf,satpat,psat,ovsflipf*flipsat,rof1,rof2);
    calc_rf(&sat_rf,"satpwr","satpwrf");
    //sat_rf.powerCoarse=tpwr1;
    //satpwr=tpwr1; //this is to automatically set saturation pulses to the same pwr as P10 pulse of 512 us
    satfpwr[0] = sat_rf.powerFine*tpwrdx;  
    satfpwr[1] = sat_rf.powerFine*tpwrdx;
    satfpwr[2] = sat_rf.powerFine*tpwrdy;  
    satfpwr[3] = sat_rf.powerFine*tpwrdy;
    satfpwr[4] = sat_rf.powerFine*tpwrdz; 
    satfpwr[5] = sat_rf.powerFine*tpwrdz;

    
   // sglpower=sglpowerSave;
    
    calc_slice(&sat_grad,&sat_rf,WRITE,"");
    calc_generic(&satcrush_grad,WRITE,"","");

    /**************************************************/
    /* Calculate positions of OVS sat bands ***********/
    /* First Dimension, pos1 */
    /* chemical shift displacement errors */
    csdvox = csd_ppm*sfrq*vox1_grad.thickness/vox1_grad.rfBandwidth;
    csdovs = csd_ppm*sfrq*sat_grad.thickness/sat_grad.rfBandwidth;
    /* positional offset of centre of OVS bands relative to slice */
    posoff = csdvox + csdovs + (vox1_grad.thickness+sat_grad.thickness)/2.0;
    posoff *= 0.1; /* convert from mm to cm */

    satpos[0] = pos1 + posoff + ovsgap;
    satpos[1] = pos1 - posoff - ovsgap;

    printf("satpos1 is %f \n", satpos[0]);
    printf("true is %f \n", (vox1_grad.thickness+sat_grad.thickness)/2.0);

    /* Second Dimension, pos2 */
    csdvox = csd_ppm*sfrq*vox2_grad.thickness/vox2_grad.rfBandwidth;
    csdovs = csd_ppm*sfrq*sat_grad.thickness/sat_grad.rfBandwidth;
    posoff = csdvox + csdovs + (vox2_grad.thickness+sat_grad.thickness)/2.0;
    posoff *= 0.1; 
    satpos[2] = pos2 + posoff + ovsgap;
    satpos[3] = pos2 - posoff - ovsgap;

    /* Third Dimension, pos3 */
    csdvox = csd_ppm*sfrq*vox3_grad.thickness/vox3_grad.rfBandwidth;
    csdovs = csd_ppm*sfrq*sat_grad.thickness/sat_grad.rfBandwidth;
    posoff = csdvox + csdovs + (vox3_grad.thickness+sat_grad.thickness)/2.0;
    posoff *= 0.1; 
    satpos[4] = pos3 + posoff + ovsgap;
    satpos[5] = pos3 - posoff - ovsgap;

    /**************************************************/

    /* Total duration of OVS module */
    ovsTime = 6*(sat_grad.duration + satcrush_grad.duration);
  }
  else
    ovsTime = 0;
}