Beispiel #1
0
void shape_rf (RF_PULSE_T *rf, char rfBase[MAX_STR], char rfName[MAX_STR], double pw, double flip,
              double rof1, double rof2)
   {
   if ((ix > 1) && !sglarray) {
     rf->flip = flip;
     return;
   }
   initRf(rf);
   strcpy(rf->pulseBase,rfBase);
   strcpy(rf->pulseName,rfName);
   strcpy(rf->rfcoil,rfcoil);
   rf->rfDuration = pw;
   rf->flip = flip;
   rf->flipmult = 1.0;
   rf->rof1 = rof1;
   rf->rof2 = rof2;

   /* Generate the pulse shape if rf->pulseName is appropriate */
   genRf(rf);

   /* If the pulse shape has not been generated proceed as for init_rf */
   switch (rf->type) {
     case RF_NULL:
       rf->rfDuration = shapelistpw(rfName,pw);  /* Round to 200ns resolution*/
       readRfPulse(rf);

       /* Set actual bandwidth according to pulse duration */
       if ((FP_LT(rf->flip,FLIPLIMIT_LOW)) || (FP_GT(rf->flip,FLIPLIMIT_HIGH)))
         /* use excitation bandwidth */
         rf->bandwidth = rf->header.bandwidth/rf->rfDuration;
       else
         /* use inversion bandwidth */
         rf->bandwidth = rf->header.inversionBw/rf->rfDuration;
              
       break;
     default:
       /* Even though shape is properly quantized for some reason we need to 
          use shapelistpw to round to 200ns resolution, otherwise duration may 
          be significantly wrong ?? */
       rf->rfDuration = shapelistpw(rf->pulseName,pw);
       break;
   }

   switch (rf->error) {
     case ERR_RF_SHAPE_MISSING:
       sgl_abort_message("ERROR: Can not find RF shape '%s.RF'",rfName);
       break;
     case ERR_RF_HEADER_ENTRIES:
       sgl_abort_message("ERROR rf shape '%s': incorrect header information",rfName);
       break;
     default:
       break;
   }
   if ((rf->header.rfFraction < 0) || (rf->header.rfFraction > 1))
     sgl_abort_message("ERROR rf shape '%s': RF Fraction must be between 0 and 1",rfName);
   }
Beispiel #2
0
int lw_segment_envelope_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2)
{
    double minq=FP_MIN(q1->x,q2->x);
    double maxq=FP_MAX(q1->x,q2->x);
    double minp=FP_MIN(p1->x,p2->x);
    double maxp=FP_MAX(p1->x,p2->x);

    if (FP_GT(minp,maxq) || FP_LT(maxp,minq))
        return LW_FALSE;

    minq=FP_MIN(q1->y,q2->y);
    maxq=FP_MAX(q1->y,q2->y);
    minp=FP_MIN(p1->y,p2->y);
    maxp=FP_MAX(p1->y,p2->y);

    if (FP_GT(minp,maxq) || FP_LT(maxp,minq))
        return LW_FALSE;

    return LW_TRUE;
}
Beispiel #3
0
pulsesequence()
{
	/* Internal variable declarations *********************/
	char txphase[MAXSTR];
	char rxphase[MAXSTR];
    char blankmode[MAXSTR]={0};
	double  postDelay;
	double rfDuration;
	double acqt;
	int i,ret=-1;
	static int phs1[4] = {0,2,1,3}; /* from T1meas.c */

	/*************************************************/                                     
	/*  Initialize paramter **************************/
	i                = 0;
	postDelay        = 0.5;
	acqt             = 0.0;
	getstr("rxphase",rxphase);
	getstr("txphase",txphase);  

	ret = P_getstring(GLOBAL,"blankmode",blankmode,1,MAXSTR);
    //getparm("blankmode","string",GLOBAL,blankmode,MAXSTR);
	postDelay = tr - at;

   //printf("blankmode=%s\n",blankmode);
                        
	/*************************************************/
	/* check phase setting ***************************/
	if ( (txphase[0] =='n')   && (rxphase[0] =='n') )
	{
		abort_message("ERROR - Select at least one phase [Tx or Rx]\n");   
	}

	/**************************************************/
	/* check pulse width  *****************************/
	rfDuration = shapelistpw(p1pat, p1);     /* assign exitation pulse  duration */
	acqt = rfDuration + rof1 - alfa;
	if (FP_GT(acqt, at))
	{
		abort_message("Pulse duration too long. max [%.3f]    ms\n",(at-rof1+alfa)*1000.0);   
	}
    if(ret==0 && blankmode[0]=='u')
    	obsunblank();
	delay(postDelay);
    
	settable(t1,4,phs1); /*from T1meas.c */
	getelem(t1,ct,v11);  /*from T1meas.c */
	setreceiver(t1);                    
	/*==============================================*/
	/*  START LOOPBACK PULSE SEQUENCE               */
	/*==============================================*/
	status(A);
	obsoffset(resto);

	/* TTL trigger to scope sequence ****************************/       
	sp1on();             

	/* Relaxation delay ***********************************/       
    xgate(ticks);

	/* RF pulse *******************************************/ 
	obspower(tpwr);
	obspwrf(tpwrf);
	ShapedXmtNAcquire(p1pat, rfDuration, v11, rof1, OBSch);

	endacq();
	sp1off();
    if(ret==0 && blankmode[0]=='u')
 		obsunblank();
}
Beispiel #4
0
pulsesequence()
{
  /* Internal variable declarations *********************/
  double  freq90[MAXNSLICE],freq180[MAXNSLICE];
  double  te_delay1,te_delay2,tr_delay,tau1,tau2,thk2fact,te_delay3=0.0,te_delay4=0.0,navTime=0.0;
  double  crushm0,pem0,gcrushr,gcrushp,gcrushs,pecrush;
  double  refsign=1,crushsign=1,navsign=1;
  int     shape90,shape180,table=0,sepRefocus;
  char    slprofile[MAXSTR];

  /* sequence dependent diffusion variables */
  double Gro,Gss;          // "gdiff" for readout/readout refocus and slice/slice refocus
  double dgro,dgss;        // "delta" for readout/readout refocus and slice/slice refocus
  double Dgro,Dgss;        // "DELTA" for readout/readout refocus and slice/slice refocus
  double dcrush,dgss2;     // "delta" for crusher and gss2 gradients
  double Dcrush,Dgss2;     // "DELTA" for crusher and gss2 gradients

  int    i;

  /* 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  vph180     = v7;    // Phase of 180 pulse
  int  vph2       = v8;    // alternate phase of 180 on odd transients
  int  vssc       = v9;    // Compressed steady-states
  int  vtrimage   = v10;   // Counts down from nt, trimage delay when 0
  int  vacquire   = v11;   // Argument for setacqvar, to skip steady state acquires
  int  vtrigblock = v12;   // Number of slices per trigger block

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

  thk2fact=getval("thk2fact");
  pecrush=getval("pecrush");
  sepRefocus=getvalnwarn("sepRefocus");
  getstrnwarn("slprofile",slprofile);

  /*  Check for external PE table ***********************/
  init_tablepar("pelist");          // Initialize pelist parameter
  if (strcmp(petable,"n") && strcmp(petable,"N") && strcmp(petable,"")) {
    loadtable(petable);
    writetabletopar(t1,"pelist");   // Write t1 table to pelist parameter
    table = 1;
  }

  /* RF Power & Bandwidth Calculations ******************/
  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_slice(&ss_grad,"ss",thk);
  init_slice(&ss2_grad,"ss2",thk*thk2fact);
  init_dephase(&crush_grad,"crush");
  init_slice_refocus(&ssr_grad,"ssr");
  if (FP_LT(tcrushro,alfa)) tcrushro=alfa;
  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_generic(&spoil_grad,"spoil",gspoil,tspoil);

  /* Gradient calculations ******************************/
  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");
  calc_slice(&ss_grad,&p1_rf,WRITE,"gss");
  calc_slice(&ss2_grad,&p2_rf,WRITE,"gss2");
  calc_slice_refocus(&ssr_grad,&ss_grad,WRITE,"gssr");
  calc_generic(&spoil_grad,WRITE,"","");

  /* Make sure crushing in PE dimension does not refocus signal from 180 */
  crushm0=fabs(gcrush*tcrush);
  pem0=0.0; gcrushp=0.0;
  if (pecrush) pem0=pe_grad.m0;
  calc_dephase(&crush_grad,WRITE,crushm0+pem0,"","");
  gcrushr = crush_grad.amp*crushm0/crush_grad.m0;
  if (pecrush) gcrushp = crush_grad.amp;
  gcrushs = crush_grad.amp*crushm0/crush_grad.m0;

  /* Allow phase encode and read dephase to be separated from slice refocus */
  if (sepRefocus) {
    /* Equalize read dephase and PE gradient durations */
    calc_sim_gradient(&ror_grad,&pe_grad,&null_grad,0,WRITE);
    crushsign=-1;
  } else {
    if (slprofile[0] == 'y') {
      /* Combined slice refocusing and read dephasing,
         reverse gradient sign if ror > ssr integral */
      refsign = (ss_grad.m0ref > ro_grad.m0ref) ? 1.0 : -1.0;
      ss_grad.m0ref -= ro_grad.m0ref;
      calc_slice_refocus(&ssr_grad,&ss_grad,NOWRITE,"gssr");
    }
    /* Equalize both refocus and PE gradient durations */
    calc_sim_gradient(&ror_grad,&pe_grad,&ssr_grad,0,WRITE);
  }

  /* Create optional prepulse events ********************/
  if (fsat[0] == 'y') create_fatsat();
  if (sat[0] == 'y')  create_satbands();
  if (mt[0] == 'y')   create_mtc();
  if (ir[0] == 'y')   create_inversion_recovery();
  if (diff[0] == 'y') init_diffusion(&diffusion,&diff_grad,"diff",gdiff,tdelta);

  sgl_error_check(sglerror);

  /* Min TE *********************************************/
  te = granularity(te,2*GRADIENT_RES);
  /* tau1, tau2 are the sum of events in each half echo period */
  /* tau1, tau2 include a GRADIENT_RES as this is minimum delay time */
  tau1 = ss_grad.rfCenterBack + ssr_grad.duration + crush_grad.duration + ss2_grad.rfCenterFront + 2*GRADIENT_RES;
  tau2 = ss2_grad.rfCenterBack + crush_grad.duration + ro_grad.timeToEcho + GRADIENT_RES;
  if (sepRefocus) tau2 += ror_grad.duration;
  temin = 2*MAX(tau1,tau2);

  /* Diffusion ******************************************/
  if (diff[0] == 'y') {
    /* granulate tDELTA */
    tDELTA = granularity(tDELTA,GRADIENT_RES);
    /* taudiff is the duration of events between diffusion gradients */
    taudiff = ss2_grad.duration + 2*crush_grad.duration + GRADIENT_RES;
    /* set minimum diffusion structure requirements for gradient echo: taudiff, tDELTA, te and minte[0] */
    set_diffusion(&diffusion,taudiff,tDELTA,te,minte[0]);
    /* set additional diffusion structure requirements for spin echo: tau1 and tau2 */
    set_diffusion_se(&diffusion,tau1,tau2);
    /* calculate the diffusion structure delays.
       address &temin is required in order to update temin accordingly */
    calc_diffTime(&diffusion,&temin);
  }

  /* TE delays ******************************************/
  if (minte[0] == 'y') {
    te = temin;
    putvalue("te",te);
  }
  if (FP_LT(te,temin)) {
    abort_message("TE too short, minimum TE = %.3f ms\n",temin*1000);
  }
  te_delay1 = te/2 - tau1 + GRADIENT_RES;
  te_delay2 = te/2 - tau2 + GRADIENT_RES;

  if (navigator[0] == 'y') {
    /* tau1, tau2 are the sum of events in each half echo period */
    tau1 = ro_grad.timeFromEcho + pe_grad.duration + crush_grad.duration + ss2_grad.rfCenterFront;
    tau2 = ss2_grad.rfCenterBack + crush_grad.duration + ro_grad.timeToEcho;
    if (FP_GT(tau1,tau2)) {
      te_delay3 = GRADIENT_RES;
      te_delay4 = tau1-tau2+GRADIENT_RES;
    } else {
      te_delay3 = tau2-tau1+GRADIENT_RES;
      te_delay4 = GRADIENT_RES;
    }
    navTime = te_delay3 + ss2_grad.duration + 2*crush_grad.duration + ro_grad.duration + te_delay4 + 2*GRADIENT_RES;
  }

  /* Check nsblock, the number of slices blocked together
     (used for triggering and/or inversion recovery) */
  check_nsblock();

  /* Min TR *********************************************/   	
  trmin = ss_grad.rfCenterFront  + te + ro_grad.timeFromEcho + pe_grad.duration + 2*GRADIENT_RES;

  /* Increase TR if any options are selected ************/
  if (spoilflag[0] == 'y') trmin += spoil_grad.duration;
  if (navigator[0] == 'y') trmin += navTime;
  if (sat[0] == 'y')       trmin += satTime;
  if (fsat[0] == 'y')      trmin += fsatTime;
  if (mt[0] == 'y')        trmin += mtTime;
  if (ticks > 0)           trmin += GRADIENT_RES;

  /* Adjust for all slices ******************************/
  trmin *= ns;

  /* Inversion recovery *********************************/
  if (ir[0] == 'y') {
    /* tauti is the additional time beyond IR component to be included in ti */
    /* satTime, fsatTime and mtTime all included as those modules will be after IR */
    tauti = satTime + fsatTime + mtTime + GRADIENT_RES + ss_grad.rfCenterFront;
    /* calc_irTime checks ti and returns the time of all IR components */
    trmin += calc_irTime(tauti,trmin,mintr[0],tr,&trtype);
  }

  if (mintr[0] == 'y') {
    tr = trmin;
    putvalue("tr",tr);
  }
  if (FP_LT(tr,trmin)) {
    abort_message("TR too short, minimum TR = %.3f ms\n",trmin*1000);
  }

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

  /* Calculate B values *********************************/
  if (ix == 1) {
    /* Calculate bvalues according to main diffusion gradients */
    calc_bvalues(&diffusion,"dro","dpe","dsl");
    /* Add components from additional diffusion encoding imaging gradients peculiar to this sequence */
    /* Initialize variables */
    dgro = 0.5*(ror_grad.duration+ro_grad.timeToEcho);
    Gro = ro_grad.m0ref/dgro; Dgro = dgro;
    if (!sepRefocus) Dgro = te-ss_grad.rfCenterBack-ro_grad.timeToEcho;
    dgss = 0.5*(ss_grad.rfCenterBack+ssr_grad.duration);
    Gss = ss_grad.m0ref/dgss; Dgss = dgss;
    dgss2 = ss2_grad.duration/2; Dgss2 = dgss2;
    dcrush = crush_grad.duration-crush_grad.tramp; Dcrush = crush_grad.duration+ss2_grad.duration;
    for (i = 0; i < diffusion.nbval; i++)  {
      /* set droval, dpeval and dslval */
      set_dvalues(&diffusion,&droval,&dpeval,&dslval,i);
      /* Readout */
      diffusion.bro[i] += bval(Gro,dgro,Dgro);
      diffusion.bro[i] += bval(crushsign*gcrushr,dcrush,Dcrush);
      diffusion.bro[i] += bval_nested(gdiff*droval,tdelta,tDELTA,crushsign*gcrushr,dcrush,Dcrush);
      if (!sepRefocus) {
        diffusion.bro[i] += bval_nested(Gro,dgro,Dgro,gdiff*droval,tdelta,tDELTA);
        diffusion.bro[i] += bval_nested(Gro,dgro,Dgro,crushsign*gcrushr,dcrush,Dcrush);
      }
      /* Phase */
      if (pecrush) {
        diffusion.bpe[i] += bval(gcrushp,dcrush,Dcrush);
        diffusion.bpe[i] += bval_nested(gdiff*dpeval,tdelta,tDELTA,gcrushp,dcrush,Dcrush);
      }
      /* Slice */
      diffusion.bsl[i] += bval(Gss,dgss,Dgss);
      diffusion.bsl[i] += bval(gcrushs,dcrush,Dcrush);
      diffusion.bsl[i] += bval(ss2_grad.ssamp,dgss2,Dgss2);
      diffusion.bsl[i] += bval_nested(gdiff*dslval,tdelta,tDELTA,gcrushs,dcrush,Dcrush);
      diffusion.bsl[i] += bval_nested(gdiff*dslval,tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2);
      diffusion.bsl[i] += bval_nested(gcrushs,dcrush,Dcrush,ss2_grad.ssamp,dgss2,Dgss2);
      /* Readout/Phase Cross-terms */
      diffusion.brp[i] += bval_cross(gdiff*dpeval,tdelta,tDELTA,crushsign*gcrushr,dcrush,Dcrush);
      diffusion.brp[i] += bval_cross(gdiff*dpeval,tdelta,tDELTA,crushsign*gcrushr,dcrush,Dcrush);
      if (pecrush) diffusion.brp[i] += bval_cross(gdiff*droval,tdelta,tDELTA,gcrushp,dcrush,Dcrush);
      if (!sepRefocus) {
        diffusion.brp[i] += bval_cross(Gro,dgro,Dgro,gdiff*dpeval,tdelta,tDELTA);
        if (pecrush) diffusion.brp[i] += bval_cross(Gro,dgro,Dgro,gcrushp,dcrush,Dcrush);
      }
      /* Readout/Slice Cross-terms */
      diffusion.brs[i] += bval2(crushsign*gcrushr,gcrushs,dcrush,Dcrush);
      diffusion.brs[i] += bval_cross(gdiff*droval,tdelta,tDELTA,gcrushs,dcrush,Dcrush);
      diffusion.brs[i] += bval_cross(gdiff*dslval,tdelta,tDELTA,crushsign*gcrushr,dcrush,Dcrush);
      diffusion.brs[i] += bval_cross(gdiff*droval,tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2);
      if (!sepRefocus) {
        diffusion.brs[i] += bval_cross(Gro,dgro,Dgro,gdiff*dslval,tdelta,tDELTA);
        diffusion.brs[i] += bval_cross(Gro,dgro,Dgro,gcrushs,dcrush,Dcrush);
        diffusion.brs[i] += bval_cross(Gro,dgro,Dgro,ss2_grad.ssamp,dgss2,Dgss2);
      }
      /* Slice/Phase Cross-terms */
      diffusion.bsp[i] += bval_cross(gdiff*dpeval,tdelta,tDELTA,gcrushs,dcrush,Dcrush);
      diffusion.bsp[i] += bval_cross(gdiff*dpeval,tdelta,tDELTA,ss2_grad.ssamp,dgss2,Dgss2);
      if (pecrush) { 
        diffusion.bsp[i] += bval2(gcrushs,gcrushp,dcrush,Dcrush);
        diffusion.bsp[i] += bval_cross(gdiff*dslval,tdelta,tDELTA,gcrushp,dcrush,Dcrush);
        diffusion.bsp[i] += bval_cross(gcrushp,dcrush,Dcrush,ss2_grad.ssamp,dgss2,Dgss2);
      }
    }  /* End for-all-directions */
    /* Write the values */
    write_bvalues(&diffusion,"bval","bvalue","max_bval");
  }

  /* Generate phase-ramped pulses ***********************/
  offsetlist(pss,ss_grad.ssamp,0,freq90,ns,seqcon[1]);
  offsetlist(pss,ss2_grad.ssamp,0,freq180,ns,seqcon[1]);
  shape90 = shapelist(p1_rf.pulseName,ss_grad.rfDuration,freq90,ns,ss_grad.rfFraction,seqcon[1]);
  shape180 = shapelist(p2_rf.pulseName,ss2_grad.rfDuration,freq180,ns,ss2_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);

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

  /* Adjust experiment time for VnmrJ *******************/
  if (ssc<0) {
    if (seqcon[2] == 'c') g_setExpTime(trmean*(ntmean*pe_steps*arraydim - ssc*arraydim));
    else g_setExpTime(trmean*(ntmean*pe_steps*arraydim - ssc*pe_steps*arraydim));
  }
  else g_setExpTime(trmean*ntmean*pe_steps*arraydim + tr*ssc);

  /* Slice profile **************************************/
  if (slprofile[0] == 'y' && !sepRefocus) ror_grad.amp = 0;

  /* Set phase cycle table ******************************/
  if (sepRefocus) settable(t2,1,ph180); // Phase encode is just before readout
  else settable(t2,2,ph180);

  /* PULSE SEQUENCE *************************************/
  status(A);                          // Set status A
  rotate();                           // Set gradient rotation according to psi, phi and theta
  triggerSelect(trigger);             // Select trigger input 1/2/3
  obsoffset(resto);                   // Set spectrometer frequency
  delay(GRADIENT_RES);                // Delay for frequency setting
  initval(fabs(ssc),vssc);            // Compressed steady-state counter
  if (seqcon[2]=='s') assign(zero,vssc); // Zero for standard peloop
  assign(one,vacquire);               // real-time acquire flag
  setacqvar(vacquire);                // Turn on acquire when vacquire is zero 

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

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

    if (trtype) delay(ns*tr_delay);   // relaxation delay

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

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

    /* Phase cycle ****************************************/       
    getelem(t2,vpe_ctr,vph180);             // For phase encoding with slice rephase
    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 (!trtype) delay(tr_delay);         // Relaxation delay

      if (ticks > 0) {
        modn(vms_ctr,vtrigblock,vtest);
        ifzero(vtest);                      // if the beginning of an trigger block
          xgate(ticks);
          grad_advance(gpropdelay);
          delay(GRADIENT_RES);
        elsenz(vtest);
          delay(GRADIENT_RES);
        endif(vtest);
      }

      sp1on(); delay(GRADIENT_RES); sp1off();     // Scope trigger

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

      /* Slice select RF pulse ******************************/ 
      obspower(p1_rf.powerCoarse);
      obspwrf(p1_rf.powerFine);
      delay(GRADIENT_RES);
      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);

      /* Slice refocus gradient *****************************/
      if (sepRefocus) 
        obl_shapedgradient(ssr_grad.name,ssr_grad.duration,0,0,-ssr_grad.amp,WAIT);
      else
        /* Include phase encode and readout dephase gradient if refocus gradients not separated */
        pe_shapedgradient(pe_grad.name,pe_grad.duration,ror_grad.amp,0,-ssr_grad.amp*refsign,pe_grad.increment,vpe_mult,WAIT);

      if (diff[0] == 'y') {
        delay(diffusion.d1);
        diffusion_dephase(&diffusion,dro,dpe,dsl);
        delay(diffusion.d2);
      } 
      else 
        delay(te_delay1);

      /* Refocusing RF pulse ********************************/ 
      obspower(p2_rf.powerCoarse);
      obspwrf(p2_rf.powerFine);
      delay(GRADIENT_RES);
      obl_shapedgradient(crush_grad.name,crush_grad.duration,crushsign*gcrushr,gcrushp,gcrushs,WAIT);
      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);
      obl_shapedgradient(crush_grad.name,crush_grad.duration,crushsign*gcrushr,gcrushp,gcrushs,WAIT);

      if (diff[0] == 'y') {
        delay(diffusion.d3);
        diffusion_rephase(&diffusion,dro,dpe,dsl);
        delay(diffusion.d4);
      } 
      else 
        delay(te_delay2);

      /* Readout dephase, phase encode & readout gradients **/
      roff = -poffset(pro,ro_grad.roamp);  // incase inverted navigator is acquired
      if (slprofile[0] == 'y') {
        /* Readout gradient only if refocus gradients not separated */
        if (sepRefocus)
          obl_shapedgradient(ror_grad.name,ror_grad.duration,0,0,-ror_grad.amp,WAIT);
        obl_shapedgradient(ro_grad.name,ro_grad.duration,0,0,ro_grad.amp,NOWAIT);
      } else {
        /* Readout gradient only if refocus gradients not separated */
        if (sepRefocus) 
          pe_shapedgradient(pe_grad.name,pe_grad.duration,-ror_grad.amp,0,0,-pe_grad.increment,vpe_mult,WAIT);
        obl_shapedgradient(ro_grad.name,ro_grad.duration,ro_grad.amp,0,0,NOWAIT);
      }

      /* Acquisition ****************************************/
      delay(ro_grad.atDelayFront-alfa);
      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_mult,WAIT);

      /* Navigator acquisition ******************************/
      if (navigator[0] == 'y') {
        delay(te_delay3);
        obl_shapedgradient(crush_grad.name,crush_grad.duration,-crushsign*gcrushr,0,-gcrushs,WAIT);
        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);
        obl_shapedgradient(crush_grad.name,crush_grad.duration,-crushsign*gcrushr,0,-gcrushs,WAIT);
        delay(te_delay4);
        obl_shapedgradient(ro_grad.name,ro_grad.duration,navsign*ro_grad.amp,0,0,NOWAIT);
        delay(ro_grad.atDelayFront-alfa);
        startacq(alfa);
        acquire(np,1.0/sw);
        delay(ro_grad.atDelayBack);
        endacq();
      }

      if (spoilflag[0] == 'y') {
        obl_shapedgradient(spoil_grad.name,spoil_grad.duration,navsign*spoil_grad.amp,0,spoil_grad.amp,WAIT);
      }

    endmsloop(seqcon[1],vms_ctr);

  endpeloop(seqcon[2],vpe_ctr);

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

  /* Duty cycle *****************************************/
  calc_grad_duty(tr);

}
Beispiel #5
0
/*--------------------------------------*/
void gaussRf(RF_PULSE_T *rf)
{
  int i;
  double t;
  double a,b;

  /* Set gauss shape type */
  rf->type = RF_GAUSS;

  /* Set shape name */
  setshapeRf(rf);

  /* Get pulse parameters */
  getparsRf(rf);

  /* Round pulse resolution & duration and set the number of pulse points */
  roundparsRf(rf);

  /* Set default cutoff (% of maximum) */
  if (rf->cutoff < 0.001) rf->cutoff = 1.0;
  /* Otherwise make sure cutoff is 0.1, 0.5, 1.0, 5.0 or 10.0 */
  if (rf->cutoff < 0.25) rf->cutoff = 0.1;
  else if ((rf->cutoff >= 0.25) && (rf->cutoff < 0.75))
    rf->cutoff = 0.5;
  else if ((rf->cutoff >= 0.75) && (rf->cutoff < 2.5))
    rf->cutoff = 1.0;
  else if ((rf->cutoff >= 2.5) && (rf->cutoff < 7.5))
    rf->cutoff = 5.0;
  else if (rf->cutoff >= 7.5) rf->cutoff = 10.0;

  /* Set excitation and inversion bandwidths */
  if (rf->cutoff == 0.1) {
    rf->header.bandwidth = 3.308;
    rf->header.inversionBw = 1.863;
  }
  if (rf->cutoff == 0.5) {
    rf->header.bandwidth = 2.896;
    rf->header.inversionBw = 1.635;
  }
  if (rf->cutoff == 1.0) {
    rf->header.bandwidth = 2.705;
    rf->header.inversionBw = 1.528;
  }
  if (rf->cutoff == 5.0) {
    rf->header.bandwidth = 2.216;
    rf->header.inversionBw = 1.263;
  }
  if (rf->cutoff == 10.0) {
    rf->header.bandwidth = 1.997;
    rf->header.inversionBw = 1.1455;
  }

  /* Set modulation type */
  strcpy(rf->header.modulation,"amplitude");

  /* Set rf fraction */
  rf->header.rfFraction = 0.5;

  /* Set pulse type */
  strcpy(rf->header.type,"selective");

  /* Set actual bandwidth of pulse */
  if ((FP_LT(rf->flip,FLIPLIMIT_LOW)) || (FP_GT(rf->flip,FLIPLIMIT_HIGH)))
    /* use excitation bandwidth */
    rf->bandwidth = rf->header.bandwidth/rf->rfDuration;
  else
    /* use inversion bandwidth */
    rf->bandwidth = rf->header.inversionBw/rf->rfDuration;

  /* Set SPL version */
  rf->header.version = SPLVERSION;

  /* Allocate memory for pulse shape */
  if ((rf->amp=(double *)malloc(rf->pts*sizeof(double))) == NULL) nomem();
  if ((rf->phase=(double *)malloc(rf->pts*sizeof(double))) == NULL) nomem();

  /* Generate shape */
  a = -log(rf->cutoff/100.0)*4.0/(rf->rfDuration*rf->rfDuration);
  b = -rf->rfDuration/2.0 +  rf->res/2.0;
  for (i=0;i<rf->pts;i++) {
    t = b+rf->res*i; 
    rf->amp[i]=exp(-a*t*t);
    rf->phase[i]=0.0;
  }

  /* Calculate area under pulse */
  calcintRf(rf);

  /* Scale amplitude so max is 1023.0 */
  scaleampRf(rf);

  /* Write the pulse to disk */
  writeRf(rf);

  /* Write pulse parameters */  
  putparsRf(rf);  

  /* Update pulseName with new shape name */
  strcpy(rf->pulseName,rf->shapeName);

  /* Free memory */
  free(rf->amp);
  free(rf->phase);
}
Beispiel #6
0
/*----------------------------------*/
void sincRf(RF_PULSE_T *rf)
{
  int i;
  double t;
  double a,b;

  /* Set sinc shape type */
  rf->type = RF_SINC;

  /* Set shape name */
  setshapeRf(rf);

  /* Get pulse parameters */
  getparsRf(rf);

  /* Round pulse resolution & duration and set the number of pulse points */
  roundparsRf(rf);

  /* Set default number of lobes */
  if (rf->lobes == 0) rf->lobes = 5;
  /* Otherwise make sure lobes is odd and between 1 and 13 */
  if (rf->lobes < 1) rf->lobes = 1;
  if (rf->lobes > 13) rf->lobes = 13;
  if (rf->lobes%2 == 0) rf->lobes++;

  /* Set excitation and inversion bandwidths */
  switch (rf->lobes) {
    case 1:
      rf->header.bandwidth = 1.998;
      rf->header.inversionBw = 1.252;
      break;
    case 3:
      rf->header.bandwidth = 4.018;
      rf->header.inversionBw = 2.598;
      break;
    case 5:
      rf->header.bandwidth = 5.944;
      rf->header.inversionBw = 4.702;
      break;
    case 7:
      rf->header.bandwidth = 7.884;
      rf->header.inversionBw = 6.298;
      break;
    case 9:
      rf->header.bandwidth = 9.856;
      rf->header.inversionBw = 8.398;
      break;
    case 11:
      rf->header.bandwidth = 11.790;
      rf->header.inversionBw = 9.985;
      break;
    case 13:
      rf->header.bandwidth = 13.783;
      rf->header.inversionBw = 11.918;
      break;
  }

  /* Set modulation type */
  strcpy(rf->header.modulation,"amplitude");

  /* Set rf fraction */
  rf->header.rfFraction = 0.5;

  /* Set pulse type */
  strcpy(rf->header.type,"selective");

  /* Set actual bandwidth of pulse */
  if ((FP_LT(rf->flip,FLIPLIMIT_LOW)) || (FP_GT(rf->flip,FLIPLIMIT_HIGH)))
    /* use excitation bandwidth */
    rf->bandwidth = rf->header.bandwidth/rf->rfDuration;
  else
    /* use inversion bandwidth */
    rf->bandwidth = rf->header.inversionBw/rf->rfDuration;

  /* Set SPL version */
  rf->header.version = SPLVERSION;
  
  /* Allocate memory for pulse shape */
  if ((rf->amp=(double *)malloc(rf->pts*sizeof(double))) == NULL) nomem();
  if ((rf->phase=(double *)malloc(rf->pts*sizeof(double))) == NULL) nomem();

  /* Generate shape */
  a = -rf->rfDuration/2.0 + rf->res/2.0;
  b = M_PI*(rf->lobes + 1)/(rf->rfDuration - rf->res);
  for (i=0;i<rf->pts;i++) {
    t = b*(a+rf->res*i);
    if (t == 0.0) rf->amp[i]=1.0;
    else rf->amp[i]=sin(t)/t;
    rf->phase[i]=0.0;
  }

  /* Calculate area under pulse */
  calcintRf(rf);

  /* Scale amplitude so max is 1023.0 */
  scaleampRf(rf);

  /* Pulse amplitudes can't be negative, so set opposite phase instead */
  absampRf(rf);

  /* Write the pulse to disk */
  writeRf(rf);

  /* Write pulse parameters */  
  putparsRf(rf);  

  /* Update pulseName with new shape name */
  strcpy(rf->pulseName,rf->shapeName);

  /* Free memory */
  free(rf->amp);
  free(rf->phase);
}
Beispiel #7
0
BOX3D *
lwcircle_compute_box3d(POINT4D *p1, POINT4D *p2, POINT4D *p3)
{
	double x1, x2, y1, y2, z1, z2;
	double angle, radius, sweep;
	/* angles from center */
	double a1, a2, a3;
	/* angles from center once a1 is rotated to zero */
	double r2, r3;
	double xe = 0.0, ye = 0.0;
	POINT4D *center;
	int i;
	BOX3D *box;

	LWDEBUG(2, "lwcircle_compute_box3d called.");

	radius = lwcircle_center(p1, p2, p3, &center);
	if (radius < 0.0) 
	{
		LWDEBUG(3, "lwcircle_compute_box3d: zero radius");

		/* 
		 * We've got a straight line here.  Look to the end points for extents. 
		 * It's worth noting that when lwcircle_center returns < 0, center hasn't been allocated.
		 */

		x1 = (FP_LT(p1->x, p3->x)) ? p1->x : p3->x;
		x2 = (FP_GT(p1->x, p3->x)) ? p1->x : p3->x;
		y1 = (FP_LT(p1->y, p3->y)) ? p1->y : p3->y;
		y2 = (FP_GT(p1->y, p3->y)) ? p1->y : p3->y;
		z1 = (FP_LT(p1->z, p2->z)) ? p1->z : p2->z;
		z1 = (FP_LT(z1, p3->z)) ? z1 : p3->z;
		z2 = (FP_GT(p1->z, p2->z)) ? p1->z : p2->z;
		z2 = (FP_GT(z2, p3->z)) ? z2 : p3->z;

		box = lwalloc(sizeof(BOX3D));
		box->xmin = x1;
		box->xmax = x2;
		box->ymin = y1;
		box->ymax = y2;
		box->zmin = z1;
		box->zmax = z2;

		LWDEBUGF(3, "lwcircle_compute_box3d: extents %.16f %.16f %.16f, %.16f %.16f %.16f", x1, y1, z1, x2, y2, z2);

		return box;
	}

	/*
	top = center->y + radius;
	left = center->x - radius;

	LWDEBUGF(3, "lwcircle_compute_box3d: center (%.16f, %.16f)", center->x, center->y);
	*/

	x1 = MAXFLOAT;
	x2 = -1 * MAXFLOAT;
	y1 = MAXFLOAT;
	y2 = -1 * MAXFLOAT;

	a1 = atan2(p1->y - center->y, p1->x - center->x);
	a2 = atan2(p2->y - center->y, p2->x - center->x);
	a3 = atan2(p3->y - center->y, p3->x - center->x);

	/* Rotate a2 and a3 such that a1 = 0 */
	r2 = a2 - a1;
	r3 = a3 - a1;

	LWDEBUGF(4, "a1 %.16f, a2 %.16f, a3 %.16f", a1, a2, a3);
	LWDEBUGF(4, "r2 %.16f, r3 %.16f", r2, r3);

	/*
	 * There are six cases here I'm interested in
	 * Clockwise:
	 *   1. a1-a2 < 180 == r2 < 0 && (r3 > 0 || r3 < r2)
	 *   2. a1-a2 > 180 == r2 > 0 && (r3 > 0 && r3 < r2)
	 *   3. a1-a2 > 180 == r2 > 0 && (r3 > r2 || r3 < 0)
	 * Counter-clockwise:
	 *   4. a1-a2 < 180 == r2 > 0 && (r3 < 0 || r3 > r2)
	 *   5. a1-a2 > 180 == r2 < 0 && (r3 < 0 && r3 > r2)
	 *   6. a1-a2 > 180 == r2 < 0 && (r3 < r2 || r3 > 0)
	 * 3 and 6 are invalid cases where a3 is the midpoint.
	 * BBOX is fundamental, so these cannot error out and will instead
	 * calculate the sweep using a3 as the middle point.
	 */

	/* clockwise 1 */
	if (FP_LT(r2, 0) && (FP_GT(r3, 0) || FP_LT(r3, r2)))
	{
		sweep = (FP_GT(r3, 0)) ? (r3 - 2 * M_PI) : r3;
	}
	/* clockwise 2 */
	else if (FP_GT(r2, 0) && FP_GT(r3, 0) && FP_LT(r3, r2))
	{
		sweep = (FP_GT(r3, 0)) ? (r3 - 2 * M_PI) : r3;
	}
	/* counter-clockwise 4 */
	else if (FP_GT(r2, 0) && (FP_LT(r3, 0) || FP_GT(r3, r2)))
	{
		sweep = (FP_LT(r3, 0)) ? (r3 + 2 * M_PI) : r3;
	}
	/* counter-clockwise 5 */
	else if (FP_LT(r2, 0) && FP_LT(r3, 0) && FP_GT(r3, r2))
	{
		sweep = (FP_LT(r3, 0)) ? (r3 + 2 * M_PI) : r3;
	}
	/* clockwise invalid 3 */
	else if (FP_GT(r2, 0) && (FP_GT(r3, r2) || FP_LT(r3, 0)))
	{
		sweep = (FP_GT(r2, 0)) ? (r2 - 2 * M_PI) : r2;
	}
	/* clockwise invalid 6 */
	else
	{
		sweep = (FP_LT(r2, 0)) ? (r2 + 2 * M_PI) : r2;
	}

	LWDEBUGF(3, "a1 %.16f, a2 %.16f, a3 %.16f, sweep %.16f", a1, a2, a3, sweep);

	angle = 0.0;
	for (i=0; i < 6; i++)
	{
		switch (i)
		{
			/* right extent */
		case 0:
			angle = 0.0;
			xe = center->x + radius;
			ye = center->y;
			break;
			/* top extent */
		case 1:
			angle = M_PI_2;
			xe = center->x;
			ye = center->y + radius;
			break;
			/* left extent */
		case 2:
			angle = M_PI;
			xe = center->x - radius;
			ye = center->y;
			break;
			/* bottom extent */
		case 3:
			angle = -1 * M_PI_2;
			xe = center->x;
			ye = center->y - radius;
			break;
			/* first point */
		case 4:
			angle = a1;
			xe = p1->x;
			ye = p1->y;
			break;
			/* last point */
		case 5:
			angle = a3;
			xe = p3->x;
			ye = p3->y;
			break;
		}
		/* determine if the extents are outside the arc */
		if (i < 4)
		{
			if (FP_GT(sweep, 0.0))
			{
				if (FP_LT(a3, a1))
				{
					if (FP_GT(angle, (a3 + 2 * M_PI)) || FP_LT(angle, a1)) continue;
				}
				else
				{
					if (FP_GT(angle, a3) || FP_LT(angle, a1)) continue;
				}
			}
			else
			{
				if (FP_GT(a3, a1))
				{
					if (FP_LT(angle, (a3 - 2 * M_PI)) || FP_GT(angle, a1)) continue;
				}
				else
				{
					if (FP_LT(angle, a3) || FP_GT(angle, a1)) continue;
				}
			}
		}

		LWDEBUGF(3, "lwcircle_compute_box3d: potential extreame %d (%.16f, %.16f)", i, xe, ye);

		x1 = (FP_LT(x1, xe)) ? x1 : xe;
		y1 = (FP_LT(y1, ye)) ? y1 : ye;
		x2 = (FP_GT(x2, xe)) ? x2 : xe;
		y2 = (FP_GT(y2, ye)) ? y2 : ye;
	}

	LWDEBUGF(3, "lwcircle_compute_box3d: extreames found (%.16f %.16f, %.16f %.16f)", x1, y1, x2, y2);

	/*
	x1 = center->x + x1 * radius;
	x2 = center->x + x2 * radius;
	y1 = center->y + y1 * radius;
	y2 = center->y + y2 * radius;
	*/
	z1 = (FP_LT(p1->z, p2->z)) ? p1->z : p2->z;
	z1 = (FP_LT(z1, p3->z)) ? z1 : p3->z;
	z2 = (FP_GT(p1->z, p2->z)) ? p1->z : p2->z;
	z2 = (FP_GT(z2, p3->z)) ? z2 : p3->z;

	box = lwalloc(sizeof(BOX3D));
	box->xmin = x1;
	box->xmax = x2;
	box->ymin = y1;
	box->ymax = y2;
	box->zmin = z1;
	box->zmax = z2;

	lwfree(center);

	return box;
}
Beispiel #8
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);

}
Beispiel #9
0
static int lwcircle_calculate_gbox(POINT4D p1, POINT4D p2, POINT4D p3, GBOX *gbox)
{
	double x1, x2, y1, y2, z1, z2, m1, m2;
	double angle, radius, sweep;
	/* angles from center */
	double a1, a2, a3;
	/* angles from center once a1 is rotated to zero */
	double r2, r3;
	double xe = 0.0, ye = 0.0;
	POINT4D *center;
	int i;

	LWDEBUG(2, "lwcircle_calculate_gbox called.");

	radius = lwcircle_center(&p1, &p2, &p3, &center);
	if (radius < 0.0) return G_FAILURE;

	x1 = MAXFLOAT;
	x2 = -1 * MAXFLOAT;
	y1 = MAXFLOAT;
	y2 = -1 * MAXFLOAT;

	a1 = atan2(p1.y - center->y, p1.x - center->x);
	a2 = atan2(p2.y - center->y, p2.x - center->x);
	a3 = atan2(p3.y - center->y, p3.x - center->x);

	/* Rotate a2 and a3 such that a1 = 0 */
	r2 = a2 - a1;
	r3 = a3 - a1;

	/*
	 * There are six cases here I'm interested in
	 * Clockwise:
	 *   1. a1-a2 < 180 == r2 < 0 && (r3 > 0 || r3 < r2)
	 *   2. a1-a2 > 180 == r2 > 0 && (r3 > 0 && r3 < r2)
	 *   3. a1-a2 > 180 == r2 > 0 && (r3 > r2 || r3 < 0)
	 * Counter-clockwise:
	 *   4. a1-a2 < 180 == r2 > 0 && (r3 < 0 || r3 > r2)
	 *   5. a1-a2 > 180 == r2 < 0 && (r3 < 0 && r3 > r2)
	 *   6. a1-a2 > 180 == r2 < 0 && (r3 < r2 || r3 > 0)
	 * 3 and 6 are invalid cases where a3 is the midpoint.
	 * BBOX is fundamental, so these cannot error out and will instead
	 * calculate the sweep using a3 as the middle point.
	 */

	/* clockwise 1 */
	if (FP_LT(r2, 0) && (FP_GT(r3, 0) || FP_LT(r3, r2)))
	{
		sweep = (FP_GT(r3, 0)) ? (r3 - 2 * M_PI) : r3;
	}
	/* clockwise 2 */
	else if (FP_GT(r2, 0) && FP_GT(r3, 0) && FP_LT(r3, r2))
	{
		sweep = (FP_GT(r3, 0)) ? (r3 - 2 * M_PI) : r3;
	}
	/* counter-clockwise 4 */
	else if (FP_GT(r2, 0) && (FP_LT(r3, 0) || FP_GT(r3, r2)))
	{
		sweep = (FP_LT(r3, 0)) ? (r3 + 2 * M_PI) : r3;
	}
	/* counter-clockwise 5 */
	else if (FP_LT(r2, 0) && FP_LT(r3, 0) && FP_GT(r3, r2))
	{
		sweep = (FP_LT(r3, 0)) ? (r3 + 2 * M_PI) : r3;
	}
	/* clockwise invalid 3 */
	else if (FP_GT(r2, 0) && (FP_GT(r3, r2) || FP_LT(r3, 0)))
	{
		sweep = (FP_GT(r2, 0)) ? (r2 - 2 * M_PI) : r2;
	}
	/* clockwise invalid 6 */
	else
	{
		sweep = (FP_LT(r2, 0)) ? (r2 + 2 * M_PI) : r2;
	}

	LWDEBUGF(3, "a1 %.16f, a2 %.16f, a3 %.16f, sweep %.16f", a1, a2, a3, sweep);

	angle = 0.0;
	for (i=0; i < 6; i++)
	{
		switch (i)
		{
			/* right extent */
		case 0:
			angle = 0.0;
			xe = center->x + radius;
			ye = center->y;
			break;
			/* top extent */
		case 1:
			angle = M_PI_2;
			xe = center->x;
			ye = center->y + radius;
			break;
			/* left extent */
		case 2:
			angle = M_PI;
			xe = center->x - radius;
			ye = center->y;
			break;
			/* bottom extent */
		case 3:
			angle = -1 * M_PI_2;
			xe = center->x;
			ye = center->y - radius;
			break;
			/* first point */
		case 4:
			angle = a1;
			xe = p1.x;
			ye = p1.y;
			break;
			/* last point */
		case 5:
			angle = a3;
			xe = p3.x;
			ye = p3.y;
			break;
		}
		/* determine if the extents are outside the arc */
		if (i < 4)
		{
			if (FP_GT(sweep, 0.0))
			{
				if (FP_LT(a3, a1))
				{
					if (FP_GT(angle, (a3 + 2 * M_PI)) || FP_LT(angle, a1)) continue;
				}
				else
				{
					if (FP_GT(angle, a3) || FP_LT(angle, a1)) continue;
				}
			}
			else
			{
				if (FP_GT(a3, a1))
				{
					if (FP_LT(angle, (a3 - 2 * M_PI)) || FP_GT(angle, a1)) continue;
				}
				else
				{
					if (FP_LT(angle, a3) || FP_GT(angle, a1)) continue;
				}
			}
		}

		LWDEBUGF(3, "lwcircle_calculate_gbox: potential extreame %d (%.16f, %.16f)", i, xe, ye);

		x1 = (FP_LT(x1, xe)) ? x1 : xe;
		y1 = (FP_LT(y1, ye)) ? y1 : ye;
		x2 = (FP_GT(x2, xe)) ? x2 : xe;
		y2 = (FP_GT(y2, ye)) ? y2 : ye;
	}

	LWDEBUGF(3, "lwcircle_calculate_gbox: extreames found (%.16f %.16f, %.16f %.16f)", x1, y1, x2, y2);

	z1 = FP_MIN(p1.z, p2.z);
	z1 = FP_MIN(z1, p3.z);
	z2 = FP_MAX(p1.z, p2.z);
	z2 = FP_MAX(z2, p3.z);

	m1 = FP_MIN(p1.m, p2.m);
	m1 = FP_MIN(m1, p3.m);
	m2 = FP_MAX(p1.m, p2.m);
	m2 = FP_MAX(m2, p3.m);

	gbox->xmin = x1;
	gbox->xmax = x2;
	gbox->ymin = y1;
	gbox->ymax = y2;

	if ( FLAGS_GET_Z(gbox->flags) )
	{
		gbox->zmin = z1;
		gbox->zmax = z2;
	}
	if ( FLAGS_GET_M(gbox->flags) )
	{
		gbox->mmin = m1;
		gbox->mmax = m2;
	}

	return G_SUCCESS;
}
Beispiel #10
0
/**
** @brief returns the kind of #CG_SEGMENT_INTERSECTION_TYPE  behavior of lineseg 1 (constructed from p1 and p2) and lineseg 2 (constructed from q1 and q2)
**	@param p1 start point of first straight linesegment
**	@param p2 end point of first straight linesegment
**	@param q1 start point of second line segment
**	@param q2 end point of second line segment
**	@return a #CG_SEGMENT_INTERSECTION_TYPE
** 	Returns one of
**		SEG_ERROR = -1,
**		SEG_NO_INTERSECTION = 0,
**		SEG_COLINEAR = 1,
**		SEG_CROSS_LEFT = 2,
**		SEG_CROSS_RIGHT = 3,
*/
int lw_segment_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2)
{

    double pq1, pq2, qp1, qp2;

    /* No envelope interaction => we are done. */
    if (!lw_segment_envelope_intersects(p1, p2, q1, p2))
    {
        return SEG_NO_INTERSECTION;
    }

    /* Are the start and end points of q on the same side of p? */
    pq1=lw_segment_side(p1,p2,q1);
    pq2=lw_segment_side(p1,p2,q2);
    if ((pq1>0 && pq2>0) || (pq1<0 && pq2<0))
    {
        return SEG_NO_INTERSECTION;
    }

    /* Are the start and end points of p on the same side of q? */
    qp1=lw_segment_side(q1,q2,p1);
    qp2=lw_segment_side(q1,q2,p2);
    if ( (qp1 > 0.0 && qp2 > 0.0) || (qp1 < 0.0 && qp2 < 0.0) )
    {
        return SEG_NO_INTERSECTION;
    }

    /* Nobody is on one side or another? Must be colinear. */
    if ( pq1 == 0.0 && pq2 == 0.0 && qp1 == 0.0 && qp2 == 0.0 )
    {
        return SEG_COLINEAR;
    }

    /*
    ** When one end-point touches, the sidedness is determined by the
    ** location of the other end-point. Only touches by the first point
    ** will be considered "real" to avoid double counting.
    */
    LWDEBUGF(4, "pq1=%.15g pq2=%.15g", pq1, pq2);
    LWDEBUGF(4, "qp1=%.15g qp2=%.15g", qp1, qp2);

    /* Second point of p or q touches, it's not a crossing. */
    if ( pq2 == 0.0 || qp2 == 0.0 )
    {
        return SEG_NO_INTERSECTION;
    }

    /* First point of p touches, it's a "crossing". */
    if ( pq1 == 0.0 )
    {
        if ( FP_GT(pq2,0.0) )
            return SEG_CROSS_RIGHT;
        else
            return SEG_CROSS_LEFT;
    }

    /* First point of q touches, it's a crossing. */
    if ( qp1 == 0.0 )
    {
        if ( FP_LT(pq1,pq2) )
            return SEG_CROSS_RIGHT;
        else
            return SEG_CROSS_LEFT;
    }

    /* The segments cross, what direction is the crossing? */
    if ( FP_LT(pq1,pq2) )
        return SEG_CROSS_RIGHT;
    else
        return SEG_CROSS_LEFT;

    /* This should never happen! */
    return SEG_ERROR;
}
Beispiel #11
0
pulsesequence()
{
	/* Internal variable declarations *********************/
	char txphase[MAXSTR];
	char rxphase[MAXSTR];
        char my_p1pat[MAXSTR];
        char my_p4pat[MAXSTR];
        char my_p2pat[MAXSTR];
        char my_p3pat[MAXSTR];
        char blankmode[MAXSTR]={0};
        char tmpstr[MAXSTR];
	double  postDelay;
	double rfDuration;
	double acqt;
	int i,ret=-1;
	static int phs1[4] = {0,2,1,3}; /* from T1meas.c */
	
	int my_pulseID;
	double my_offsets[64];
	double my_tpwr[64];
	double my_tpwrf[64];
	int my_on_off[64];
	double mytmp;
	int my_numrfch;
	int my_retval;


	

	for(i=0;i<64;i++) my_offsets[i] = 0.0;

	/*************************************************/                                     
	/*  Initialize paramter **************************/
	i                = 0;
	postDelay        = 0.5;
	acqt             = 0.0;
//	getstr("rxphase",rxphase);
//	getstr("txphase",txphase); 
        getstr("p1pat",my_p1pat);
        getstr("p2pat",my_p2pat); 
        getstr("p3pat",my_p3pat); 
        getstr("p4pat",my_p4pat);  
         

	ret = P_getstring(GLOBAL,"blankmode",blankmode,1,MAXSTR);

	if ( P_getreal(CURRENT,"ampargs",&mytmp,2) < 0 )
		mytmp = 0.0;

    if ( P_getreal(GLOBAL, "numrfch", &mytmp, 1) < 0 )
    abort_message("Cannot proceed without global numrfch\n");   
    my_numrfch = (int)(mytmp+0.05);
    if(my_numrfch<2) abort_message("this is a single transmit system and you don't need this pulse sequence\n");   
    if(my_numrfch>16) abort_message("numrfch > 16 not supported \n");   

    printf("mytmp=%f\n",mytmp);
     

 // if((P_getstring(GLOBAL,"rfGroupMap",tmpstr,1,MAXSTR) < 0) || (strlen(tmp) < 2))
 //   {
   // abort_message("global rfGroupMap doesn't exist or is too short\n");   
 // }
 // else // rfGroupMap is set to all 1's for the same number as numrfch so we control everything here in the sequence
  //{
     strncpy(tmpstr,"111111111111111111111111111111111111111111111111111111111111111111",(size_t)my_numrfch);
     tmpstr[my_numrfch]=0;
     P_setstring(CURRENT, "rfGroupMap", tmpstr, 1);
  // }

    //getparm("blankmode","string",GLOBAL,blankmode,MAXSTR);
	postDelay = tr - at;

   //printf("blankmode=%s\n",blankmode);
                        
	/*************************************************/
	/* check phase setting ***************************/
//	if ( (txphase[0] =='n')   && (rxphase[0] =='n') )
//	{
//		abort_message("ERROR - Select at least one phase [Tx or Rx]\n");   
//	}

	/**************************************************/
	/* check pulse width  *****************************/
	rfDuration = shapelistpw(p1pat, pw);     /* assign exitation pulse  duration */
        printf("p1pat: %s\n",my_p1pat);                  
        printf("duration: %e\n",rfDuration);                  
	acqt = rfDuration + rof1 - alfa;
	if (FP_GT(acqt, at))
	{
		abort_message("Pulse duration too long. max [%.3f]    ms\n",(at-rof1+alfa)*1000.0);   
	}
    if(ret==0 && blankmode[0]=='u')
    	obsunblank();
	delay(postDelay);
    
	settable(t1,4,phs1); /*from T1meas.c */
	getelem(t1,ct,v11);  /*from T1meas.c */
	setreceiver(t1);  

        printf("mytmp=%d\n",my_numrfch);                  

	my_pulseID = initRFGroupPulse(rfDuration, my_p1pat, 's',  0.0, 0.0, v11, &my_offsets[0], my_numrfch-1);
        printf("pulse id = %d\n",my_pulseID);
         //modifyRFGroupName(my_pulseID,2,my_p2pat);
         //modifyRFGroupName(my_pulseID,3,my_p3pat);
         // modifyRFGroupName(my_pulseID,4,my_p4pat);

        
	for(i=0;i<64;i++) my_tpwr[i]=0.0;
	for(i=0;i<64;i++) my_tpwrf[i]=0.0;
	for(i=0;i<64;i++) my_on_off[i]=0;

//SAS turn everything off
	for(i=0;i<my_numrfch-1;i++) 

        {
        modifyRFGroupOnOff(my_pulseID, i+1,0);
        printf("here is i=%d\n",i);
        }
	for(i=0;i<my_numrfch-1;i++) modifyRFGroupPwrf(my_pulseID, i+1, 0.0);
	for(i=0;i<my_numrfch-1;i++) modifyRFGroupPwrC(my_pulseID, i+1, 0.0);

//SAS get the parameter arrays into the local arrays

     my_retval=(int)getarray("my_tpwr",my_tpwr);

/*
	printf("my tpwr0 was: %e\n",my_tpwr[0]);
	printf("my tpwr1 was: %e\n",my_tpwr[1]);
	printf("my tpwr2 was: %e\n",my_tpwr[2]);
	printf("my tpwr3 was: %e\n",my_tpwr[3]);
	printf("my tpwr4 was: %e\n",my_tpwr[4]);
	printf("my tpwr5 was: %e\n",my_tpwr[5]);
	printf("my tpwr6 was: %e\n",my_tpwr[6]);
	printf("my tpwr7 was: %e\n",my_tpwr[7]);
*/

     my_retval=(int)getarray("my_on_off",my_tpwrf); //dump the array of reals into a real array

	for(i=0;i<my_numrfch;i++) my_on_off[i] = (int)my_tpwrf[i]; //convert to integer

/*
	printf("my on_off_0 was: %d\n",my_on_off[0]);
	printf("my on_off_1 was: %d\n",my_on_off[1]);
	printf("my on_off_2 was: %d\n",my_on_off[2]);
	printf("my on_off_3 was: %d\n",my_on_off[3]);
	printf("my on_off_4 was: %d\n",my_on_off[4]);
	printf("my on_off_5 was: %d\n",my_on_off[5]);
	printf("my on_off_6 was: %d\n",my_on_off[6]);
	printf("my on_off_7 was: %d\n",my_on_off[7]);
*/
	for(i=0;i<64;i++) my_tpwrf[i]=2047.0;

//SAS set everything to array values

	for(i=0;i<my_numrfch;i++) modifyRFGroupOnOff(my_pulseID, i+1,my_on_off[i]);
	for(i=0;i<my_numrfch;i++) modifyRFGroupPwrf(my_pulseID, i+1, my_tpwrf[i]);
	for(i=0;i<my_numrfch;i++) modifyRFGroupPwrC(my_pulseID, i+1, my_tpwr[i]);


	/*==============================================*/
	/*  START LOOPBACK PULSE SEQUENCE               */
	/*==============================================*/
	status(A);
	obsoffset(resto);

	/* TTL trigger to scope sequence ****************************/       
	sp1on();             

	/* Relaxation delay ***********************************/       
    xgate(ticks);

	/* RF pulse *******************************************/ 
	GroupPulse(my_pulseID, rof1, rof2,  v11, 0);

	endacq();
	sp1off();
    if(ret==0 && blankmode[0]=='u')
 		obsunblank();
}