Exemple #1
0
int main(int argc, char const *argv[])
{
	link *head = NULL;
	link *curr = NULL;
	int guests,time,value,i;

	printf("enter the number of guests\n");
	scanf("%d",&guests);

    int array[2*guests];

	for (i = 0; i < 2*guests; ++i)
	{
		if (i<guests)
			value = 1;
		else
			value = -1;
		scanf("%d",&time);
		insert(&head,&curr,time,value);
	}
	int times[2*guests];
	int values[2*guests];
	gettimevalues(head,times,values);
	sortarrays(times,values,2*guests);

	for (i = 0; i < 2*guests; ++i)
		printf("%d \t",times[i]);
    printf("\n");

    for (i = 0; i < 2*guests; ++i)
		printf("%d",values[i]);

	changevalues(&head,&curr,times,values);


	for ( i= 0; i < 2*guests; ++i)
		array[i] = 0;

	getarray(&head,&curr,array);

	printf("\n");
	for ( i = 0; i < 2*guests; ++i)
		printf("%d\t",array[i]);

	printf("\n\n%d",getmax(array,2*guests));


	return 0;
}
int main(void) {
     int *a; int n; 
     int r; int random; 
     int d;
     scanf("%d", &n); a = getarray(n);
     scanf("%d", &random); // Randomizer
     scanf("%d", &r); // Elements are 0 - r
     fill(random, r, n, a);
     arrayprint(n, a);
     scanf("%d", &d); // Looking for d
     lin_search(d, n, a);
     insertion_sort(n, a);
     arrayprint(n, a);
     lin_search(d, n, a);
     bin_search(d, n, a);
     return 0;
}
Exemple #3
0
/*-----------------------------------------------*/
void getparsRf(RF_PULSE_T *rf)
{
  int i;
  char parname[MAX_STR];

  /* Initialise pars */
  for (i=0;i<MAXRFPARS;i++) rf->pars[i]=0.0;

  /* Generate "*pars" name from the base name */  
  strcpy(parname,rf->pulseBase);
  strcat(parname,"pars");

  /* This will report a suitable error if the "*pars" parameter does not exist */
  rf->npars=(int)getarray(parname,rf->pars);

  /* Current "*pars" definition is that it contains the following elements:
  
        pulse resolution in usec
        pulse bandwidth in Hz
        number of lobes
        amplitude cutoff as a % of maximum
        HS mu
        HS beta in rad/s
        modulation frequency in Hz
  */

  /* There must be at least one value */
  rf->res = rf->pars[0];
  
  /* Now get the rest */
  if (rf->npars > 1) rf->bandwidth = rf->pars[1];
  if (rf->npars > 2) rf->lobes = (int)sglRoundPositive(rf->pars[2]);
  if (rf->npars > 3) rf->cutoff = rf->pars[3];
  if (rf->npars > 4) rf->mu = rf->pars[4];
  if (rf->npars > 5) rf->beta = rf->pars[5];
  if (rf->npars > 6) rf->modfrq = rf->pars[6];
}
Exemple #4
0
void eval(char* s, int pipes)
{
        pid_t* pids = malloc(sizeof(pid_t*)*(pipes+1));
        if (!pipes) pids[0] = run(s,0,1);
        else
        {
                char** programs = getarray(s,"|");
                if (programs == NULL) return;
                int* oldpipes = NULL;
                int* newpipes = NULL;
                for (int i = 0; i <= pipes; i++)
                {
                        newpipes = malloc(sizeof(int)*2);
                        if (newpipes == NULL)
                        {
                                perror("ish malloc newpipes");
                                return;
                        }
                        int p = pipe(newpipes);
                        if (p < 0)
                        {
                                perror("ish pipe");
                                return;
                        }
                        if (programs[i+1] == NULL) newpipes[1] = 1;
                        if (oldpipes == NULL) pids[i] = run(programs[i],0,newpipes[1]);
                        else pids[i] = run(programs[i],oldpipes[0],newpipes[1]);
                        free(oldpipes);
                        oldpipes = newpipes;
                }
        }
        // Allow everything to finish up
        for (int i = 0; i <= pipes; i++)
        {
                waitpid(pids[i],NULL,0);
        }
}
Exemple #5
0
int main(int argc, char *argv[]) {
  int     nelem, nimages;

  float  *tagon[MAXELEM], *tagoff[MAXELEM], *tagdiff[MAXELEM];  // Images
  double *tagctrl;            // tag control variable values
  float  *mean_on, *mean_off, // mean of tag on/off images
         *mean_diff,          // mean of pairwise difference images
	 *diff_mean;          // difference of mean on/off images
  double *image_arr;
  
  fdf_header      fdf_hdr;
  char    filename[MAXSTR];


  float noise_thr = 0;

  // Loop variables
  int slice, image, images, ndiff;
  int pixel, datapts;
  int i;
  int debug_pixel, debug;
  
  /* input arguments */
  user_input input = {
    0,          // debug
    "asltag",   // tagvar
    -1,         // noise
    -1,         // pixel 
    "ASL",      // outdir 
    ".",        // indir 
    0,          // write all pairs of subtracted images
    0,          // subtraction scheme (integer), default strict pairs
    "pair"      // subtraction scheme (string), default strict pairs
  };

  
  /*******************************************************************/  
  /*** Calculations **************************************************/  
  /*******************************************************************/  
  // Get arguments from commandline
  get_args(&input, argc, argv);
  debug = input.debug;
  if (debug) {
    if (input.pixel < 0) 
      debug_pixel = fdf_hdr.ro_size/2*fdf_hdr.pe_size + fdf_hdr.pe_size/2;
    else
      debug_pixel = input.pixel;
  }
  else debug_pixel = -1;

  /* Set up string for procpar; 
     this is for future expansion, to allow 
       - data to be in arbitrary directory
       - S(0) and S(non-zero)to be in different directories 
  */
  strcpy(procpar,input.indir);
  strcat(procpar,"/procpar");
  if (debug) printf("indir = %s, procpar = %s\n",input.indir,procpar);


  // Determine the number of images
  nelem = getstatus(input.tagvar);
  
  if (nelem == 0) {
    exit(0);  // error message is printed by getstatus
  }
    

  // Read tag control variable
  if ((tagctrl = (double *) malloc(sizeof(double)*nelem)) == NULL) nomem();
  getarray(input.tagvar,tagctrl);

  /* Is this an epi scan with reference scan(s)? */
  images = getstatus("image");
  if (images == nelem) { // assume image is arrayed in parallel with the variable
    //find out how many ref scans
    if ((image_arr = (double *) malloc(sizeof(double)*images)) == NULL) nomem();
    getarray("image",image_arr);
    nimages = 0;
    for (i = 0; i < images; i++)
      if (image_arr[i] == 1) 
        nimages++;
  }
  else nimages = nelem;

  if (debug) printf("nelem, nimages, images = %d, %d, %d\n",nelem, nimages, images);


/* XXX Check if we have an equal number of tag on/off ??? */

  
  /* Initialize fdf header */
  init_fdf_header(&fdf_hdr);


  /* Allocate memory for all images */
  datapts = fdf_hdr.ro_size*fdf_hdr.pe_size;
  switch(input.subtr) {
    case 0:  ndiff = nimages/2;   break; //strict pairwise
    case 1:  ndiff = nimages - 1; break; // adjacent pairs
    case 2:  ndiff = nimages - 2; break; // "surround" subtraction
    default: printf("Invalid subtraction scheme\n");exit(0);
  }
  
  
  for (image = 0; image < ndiff; image++) {
/* XXX CHECK if tagctrl = -1, 0 , 1 */
    if ((tagon[image]   = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();
    if ((tagoff[image]  = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();
    if ((tagdiff[image] = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();
  }
  if ((mean_on   = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();
  if ((mean_off  = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();
  if ((mean_diff = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();
  if ((diff_mean = (float *)malloc(datapts*sizeof(float))) == NULL) nomem();


  /* Create directory to put output in */
  if (strcmp(input.outdir, "./")) {
    if (debug) printf("Making directory %s\n",input.outdir);
    mkdir(input.outdir,0777);
  }

  
  /*******************************************************************/  
  /*** Slice by slice calculations ***********************************/  
  /*******************************************************************/  
  for (slice = 0; slice < fdf_hdr.slices; slice++) {
    i = 0;
    for (image = 0; image < nimages; image+=2) {
/* XXX check control variable */
      /* Read tag on */
      sprintf(filename,"%s/slice%03dimage%03decho001.fdf",
              input.indir,slice+1,image+1);
      if (debug) printf("tag on  [%d]: %s\n",i,filename);
      read_fdf_data(filename,tagon[i],&fdf_hdr);

      /* Read tag off */
      sprintf(filename,"%s/slice%03dimage%03decho001.fdf",
              input.indir,slice+1,image+2);
      if (debug) printf("tag off [%d]: %s\n",i,filename);
      read_fdf_data(filename,tagoff[i],&fdf_hdr);
      
      i++;
    } // end read image loop
    if (debug) printf("\n");    

    // Noise threshold - user input or based on histogram
    if (input.noise > 0) noise_thr = input.noise;
    else // Get noise from the first image
      noise_thr = threshold(tagon[0],&fdf_hdr);

    if (debug) printf("noise level %f\n",noise_thr);

    /*******************************************************************/  
    /*** Pixel loop ****************************************************/  
    /*******************************************************************/  
    for (pixel = 0; pixel < datapts; pixel++) {
      mean_diff[pixel] = 0;
     
      if (tagon[0][pixel] > noise_thr) {
        switch (input.subtr) {
	  case 0: // strictly pairwise: 0-0, 1-1, 2-2, ...
            for (image = 0; image < nimages/2; image++) {
	      tagdiff[image][pixel]  = (tagon[image][pixel] - tagoff[image][pixel]);
	      mean_diff[pixel]      += tagdiff[image][pixel];
            } 
	    break;

	  case 1:   // adjacent pairs: 0-0, 1-0, 1-1, 2-1, ...
	    i = 0;
            for (image = 0; image < nimages/2-1; image++) {
	      tagdiff[i][pixel] = (tagon[image][pixel] - tagoff[image][pixel]);
	      mean_diff[pixel] +=  tagdiff[i][pixel];
	      i++;
              if (pixel == debug_pixel) printf("subtract %d - %d\n",image,image);
	      
	      tagdiff[i][pixel] = (tagon[image+1][pixel] - tagoff[image][pixel]);
	      mean_diff[pixel] +=  tagdiff[i][pixel];
              if (pixel == debug_pixel) printf("subtract %d - %d\n",image+1,image);

	      i++;
            }
   	    tagdiff[i][pixel] = (tagon[nimages/2-1][pixel] - tagoff[nimages/2-1][pixel]);
            if (pixel == debug_pixel) printf("subtract %d - %d\n",nimages/2,nimages/2);

            mean_diff[pixel] +=  tagdiff[i][pixel];
	    break;

	  case 2: // surrounding pairs
	    i = 0;
            for (image = 0; image < nimages/2-1; image++) {
	      tagdiff[i][pixel] = ((tagon[image][pixel]+tagon[image+1][pixel])/2 - tagoff[image][pixel]);
	      mean_diff[pixel] +=  tagdiff[i][pixel];
	      i++;
              if (pixel == debug_pixel) printf("subtract %d+%d - %d\n",image,image+1,image);

	      tagdiff[i][pixel] = (tagon[image+1][pixel] - (tagoff[image][pixel]+tagoff[image+1][pixel])/2);
	      mean_diff[pixel] +=  tagdiff[i][pixel];
	      i++;
              if (pixel == debug_pixel) printf("subtract %d - %d+%d\n",image+1,image,image+1);
            }
	    break;
	  }
	  // divide by # pairs of images
	  mean_diff[pixel] /= ndiff;

      } // end check noise threshold 
    } // end pixel loop    
    

    /* Write Images maps: */
    fdf_hdr.array_dim     = 1 + input.write_all*ndiff;
    fdf_hdr.slice_no      = slice + 1;
    fdf_hdr.array_index   = 1;
    fdf_hdr.display_order = 1;

    if (input.write_all) {
      for (image = 0; image < ndiff; image++) {
	// write tag difference image
	sprintf(filename,"%s/tagdiff_%03d_%03d.fdf",input.outdir,image+1,slice+1);
	write_fdf(filename,tagdiff[image],&fdf_hdr);
	fdf_hdr.array_index++;
	fdf_hdr.display_order++;
      }
    }

    sprintf(filename,"%s/diff_%s_%03d.fdf",input.outdir,input.method,slice+1);
    write_fdf(filename,mean_diff,&fdf_hdr);
    fdf_hdr.array_index++;
    fdf_hdr.display_order++;

  } // end slice loop
  
}
Exemple #6
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);
}
Exemple #7
0
pulsesequence()
{

/* DECLARE AND LOAD VARIABLES */

void        makeHHdec(), makeCdec(); 	                /* utility functions */

char        f1180[MAXSTR],   		      /* Flag to start t1 @ halfdwell */
            mag_flg[MAXSTR],      /* magic-angle coherence transfer gradients */
	    C13refoc[MAXSTR],		/* C13 sech/tanh pulse in middle of t1*/
	    NH2only[MAXSTR],		       /* spectrum of only NH2 groups */
	    T1[MAXSTR],				/* insert T1 relaxation delay */
	    T1rho[MAXSTR],		     /* insert T1rho relaxation delay */
	    T2[MAXSTR],				/* insert T2 relaxation delay */
	    TROSY[MAXSTR],			    /* do TROSY on N15 and H1 */
	    Hdecflg[MAXSTR],                       /* HH-h**o decoupling flag */
	    Cdecflg[MAXSTR];                /* low power C-13 decoupling flag */
 
int         icosel,          			  /* used to get n and p type */
            ihh=1,       /* used in HH decouling to improve water suppression */
            t1_counter,  		        /* used for states tppi in t1 */
	    rTnum,			/* number of relaxation times, relaxT */
	    rTcounter;		    /* to obtain maximum relaxT, ie relaxTmax */

double      tau1,         				         /*  t1 delay */
	    lambda = 0.91/(4.0*getval("JNH")), 	   /* 1/4J H1 evolution delay */
	    tNH = 1.0/(4.0*getval("JNH")),	  /* 1/4J N15 evolution delay */
	    relaxT = getval("relaxT"),		     /* total relaxation time */
	    rTarray[1000], 	    /* to obtain maximum relaxT, ie relaxTmax */
            maxrelaxT = getval("maxrelaxT"),    /* maximum relaxT in all exps */
	    ncyc,			 /* number of pulsed cycles in relaxT */
            pwr_dly,                 /* power delay */
        
/* the sech/tanh pulse is automatically calculated by the macro "proteincal", */  
/* and is called directly from your shapelib.                  		      */
   pwClvl = getval("pwClvl"), 	  	        /* coarse power for C13 pulse */
   pwC = getval("pwC"),     	      /* C13 90 degree pulse length at pwClvl */
   rf0,            	          /* maximum fine power when using pwC pulses */
   rfst,	                           /* fine power for the stCall pulse */

   compH = getval("compH"),        /* adjustment for H1 amplifier compression */
   compN = getval("compN"),       /* adjustment for N15 amplifier compression */
   compC = getval("compC"),       /* adjustment for C13 amplifier compression */

	calH = getval("calH"), /* multiplier on a pw pulse for H1 calibration */
   	tpwrsf = getval("tpwrsf"),    /* fine power adustment for soft pulse  */
   	pwHs = getval("pwHs"),	        /* H1 90 degree pulse length at tpwrs */
   	pwHH = 0.0,                     /* pwHH = pwHs for HH h**o-decoupling */
   	tpwrs,	  	              /* power for the pwHs ("H2Osinc") pulse */

	pwNlvl = getval("pwNlvl"),	              /* power for N15 pulses */
        pwN = getval("pwN"),          /* N15 90 degree pulse length at pwNlvl */
	calN = getval("calN"),   /* multiplier on a pwN pulse for calibration */
	slNlvl,					   /* power for N15 spin lock */
        slNrf = 1500.0,        /* RF field in Hz for N15 spin lock at 600 MHz */

	sw1 = getval("sw1"),

	gt1 = getval("gt1"),  		       /* coherence pathway gradients */
        gzcal = getval("gzcal"),               /* dac to G/cm conversion      */
	gzlvl1 = getval("gzlvl1"),
	gzlvl2 = getval("gzlvl2"),
        BPpwrlimits,                        /*  =0 for no limit, =1 for limit */

	gt0 = getval("gt0"),				   /* other gradients */
	gt3 = getval("gt3"),
	gt4 = getval("gt4"),
	gt5 = getval("gt5"),
	gstab = getval("gstab"),
	gzlvl0 = getval("gzlvl0"),
	gzlvl3 = getval("gzlvl3"),
	gzlvl4 = getval("gzlvl4"),
	gzlvl5 = getval("gzlvl5");

    P_getreal(GLOBAL,"BPpwrlimits",&BPpwrlimits,1);

    getstr("f1180",f1180);
    getstr("mag_flg",mag_flg);
    getstr("C13refoc",C13refoc);
    getstr("NH2only",NH2only);
    getstr("T1",T1);
    getstr("T1rho",T1rho);
    getstr("T2",T2);
    getstr("TROSY",TROSY);
    getstr("Hdecflg", Hdecflg);
    getstr("Cdecflg", Cdecflg);

/*   LOAD PHASE TABLE    */
	
        settable(t3,2,phi3);
	settable(t4,1,phx);
   if (TROSY[A]=='y')
       {settable(t1,1,ph_x);
	settable(t9,1,phx);
 	settable(t10,1,phy);
	settable(t11,1,phx);
	settable(t12,2,recT);}
    else
       {settable(t1,1,phx);
	settable(t9,8,phi9);
 	settable(t10,1,phx);
	settable(t11,1,phy);
	settable(t12,4,rec);}



/*   INITIALIZE VARIABLES   */

/* maximum fine power for pwC pulses (and initialize rfst) */
	rf0 = 4095.0;    rfst=0.0;

/* 180 degree adiabatic C13 pulse from 0 to 200 ppm */
     if (C13refoc[A]=='y')
       {rfst = (compC*4095.0*pwC*4000.0*sqrt((30.0*sfrq/600.0+7.0)/0.35));   
	rfst = (int) (rfst + 0.5);
	if ( 1.0/(4000.0*sqrt((30.0*sfrq/600.0+7.0)/0.35)) < pwC )
           { text_error( " Not enough C13 RF. pwC must be %f usec or less.\n", 
	    (1.0e6/(4000.0*sqrt((30.0*sfrq/600.0+7.0)/0.35))) ); psg_abort(1); }}

/* selective H20 one-lobe sinc pulse */
    if(pwHs > 1e-6)
      tpwrs = tpwr - 20.0*log10(pwHs/(compH*pw*1.69));  /* needs 1.69 times more */
    else                    	                    /* power than a square pulse */
      tpwrs = 0.0;
    tpwrs = (int) (tpwrs);    
    if (tpwrsf<4095.0) tpwrs = tpwrs + 6.0;
    if (tpwrsf < 4095.0) 
    {
      tpwrs = tpwrs + 6.0;   
      pwr_dly = POWER_DELAY + PWRF_DELAY;
    }
    else pwr_dly = POWER_DELAY;

/* power level for N15 spinlock (90 degree pulse length calculated first) */
	slNlvl = 1/(4.0*slNrf*sfrq/600.0) ;
	slNlvl = pwNlvl - 20.0*log10(slNlvl/(pwN*compN));
	slNlvl = (int) (slNlvl + 0.5);

/* use 1/8J times for relaxation measurements of NH2 groups */
  if ( (NH2only[A]=='y') && ((T1[A]=='y') || (T1rho[A]=='y') || (T2[A]=='y')) )	
     {  tNH = tNH/2.0;  }

/* reset calH and calN for 2D if inadvertently left at 2.0 */
  if (ni>1.0) {calH=1.0; calN=1.0;}

/* make shapes and set up parameters for HH h**o-decoupling */
    if(Cdecflg[0] == 'y') makeCdec();
    if(Hdecflg[0] == 'y') makeHHdec();
    if(Hdecflg[0] != 'n')
    { 
      pwHH = pwHs; 
      pwHs = 0.0; 
    }


/* CHECK VALIDITY OF PARAMETER RANGES */

  if ((TROSY[A]=='y') && (gt1 < -2.0e-4 + pwHs + 1.0e-4 + 2.0*POWER_DELAY))
  { text_error( " gt1 is too small. Make gt1 equal to %f or more.\n",    
    (-2.0e-4 + pwHs + 1.0e-4 + 2.0*POWER_DELAY) ); psg_abort(1); }

  if((dm[A] == 'y' || dm[B] == 'y' || dm[C] == 'y' ))
  { text_error("incorrect dec1 decoupler flags! Should be 'nnn' "); psg_abort(1); }

  if((dm2[A] == 'y' || dm2[B] == 'y'))
  { text_error("incorrect dec2 decoupler flags! Should be 'nny' "); psg_abort(1); }

  if( dpwr2 > 50 )
  { text_error("don't fry the probe, DPWR2 too large!  ");   	    psg_abort(1); }

  if( pw > 50.0e-6 )
  { text_error("dont fry the probe, pw too high ! ");               psg_abort(1); } 
  
  if( pwN > 100.0e-6 )
  { text_error("dont fry the probe, pwN too high ! ");              psg_abort(1); }



/*  RELAXATION TIMES AND FLAGS */  

/* evaluate maximum relaxT, relaxTmax chosen by the user */
  rTnum = getarray("relaxT", rTarray);
  relaxTmax = rTarray[0];
  for (rTcounter=1; rTcounter<rTnum; rTcounter++)
      if (relaxTmax < rTarray[rTcounter]) relaxTmax = rTarray[rTcounter];


/* compare relaxTmax with maxrelaxT */
  if (maxrelaxT > relaxTmax)  relaxTmax = maxrelaxT; 


if ( ((T1rho[A]=='y') || (T2[A]=='y')) && (relaxTmax > d1) )
{ text_error("Maximum relaxation time, relaxT, is greater than d1 ! "); psg_abort(1);}

if ( ((T1[A]=='y') && (T1rho[A]=='y'))   ||   ((T1[A]=='y') && (T2[A]=='y')) ||
    ((T1rho[A]=='y') && (T2[A]=='y')) )
{ text_error("Choose only one relaxation measurement ! ");          psg_abort(1); } 


if ( ((T1[A]=='y') || (T1rho[A]=='y')) && 
       ((relaxT*100.0 - (int)(relaxT*100.0+1.0e-4)) > 1.0e-6) )
 { text_error("Relaxation time, relaxT, must be zero or multiple of 10msec"); psg_abort(1);}
 

 if ( (T2[A]=='y') && 
           (((relaxT+0.01)*50.0 - (int)((relaxT+0.01)*50.0+1.0e-4)) > 1.0e-6) )
{ text_error("Relaxation time, relaxT, must be odd multiple of 10msec"); psg_abort(1);}

if ( ((T1rho[A]=='y') || (T2[A]=='y'))  &&  (relaxTmax > 0.25) && (ix==1) ) 
{ printf("WARNING, sample heating will result for relaxT>0.25sec"); }

if ( ((T1rho[A]=='y') ||  (T2[A]=='y'))  &&  (relaxTmax > 0.5) ) 
{ text_error("relaxT greater than 0.5 seconds will heat sample"); psg_abort(1);}


if ( ((NH2only[A]=='y') || (T1[A]=='y') || (T1rho[A]=='y') || (T2[A]=='y'))
   &&  (TROSY[A]=='y') ) 
{ text_error("TROSY not implemented with NH2 spectrum, or relaxation exps."); psg_abort(1);} 


if ((TROSY[A]=='y') && (dm2[C] == 'y'))
{ text_error("Choose either TROSY='n' or dm2='n' ! ");              psg_abort(1); }
/* PHASES AND INCREMENTED TIMES */

/*  Phase incrementation for hypercomplex 2D data, States-Haberkorn element */

    if (TROSY[A]=='y')
	 {  if (phase1 == 2)   				      icosel = -1;
            else 	  {  tsadd(t4,2,4);  tsadd(t10,2,4);  icosel = +1;  }
	 }
    else {  if (phase1 == 2)  {tsadd(t10,2,4); icosel = +1;}
            else 			       icosel = -1;    
	 }

    if(Hdecflg[0] != 'n') ihh = icosel;

/*  Set up f1180  */
   
    tau1 = d2;
    if((f1180[A] == 'y') && (ni > 1.0)) 
	{ tau1 += ( 1.0 / (2.0*sw1) ); if(tau1 < 0.2e-6) tau1 = 0.0; }
    tau1 = tau1/2.0;



/* Calculate modifications to phases for States-TPPI acquisition          */

   if( ix == 1) d2_init = d2;
   t1_counter = (int) ( (d2-d2_init)*sw1 + 0.5 );
   if(t1_counter % 2) 
	{ tsadd(t3,2,4); tsadd(t12,2,4); }



/*  Correct inverted signals for NH2 only spectra  */

   if ((NH2only[A]=='y') && (T1[A]=='n')  &&  (T1rho[A]=='n')  && (T2[A]=='n'))
      { tsadd(t3,2,4); }



/* BEGIN PULSE SEQUENCE */

status(A);

	obspower(tpwr);
	decpower(pwClvl);
	decpwrf(rf0);
 	dec2power(pwNlvl);
	txphase(zero);
        decphase(zero);
        dec2phase(zero);
        if(Hdecflg[0] != 'n')
        {
          delay(5.0e-5);
          rgpulse(pw,zero,rof1,0.0);                 
          rgpulse(pw,one,0.0,rof1);                 
          zgradpulse(1.5*gzlvl0, 0.5e-3);
          delay(5.0e-4);
          rgpulse(pw,zero,rof1,0.0);                 
          rgpulse(pw,one,0.0,rof1);                 
          zgradpulse(-gzlvl0, 0.5e-3);
        }
        
	delay(d1);

 
/*  xxxxxxxxxxxxxxxxx  CONSTANT SAMPLE HEATING FROM N15 RF xxxxxxxxxxxxxxxxx  */

 if  (T1rho[A]=='y')
 	{dec2power(slNlvl);
         dec2rgpulse(relaxTmax-relaxT, zero, 0.0, 0.0);
    	 dec2power(pwNlvl);}
	
 if  (T2[A]=='y')      
 	{ncyc = 8.0*100.0*(relaxTmax - relaxT);
         if (BPpwrlimits > 0.5)
          {
           dec2power(pwNlvl-3.0);    /* reduce for probe protection */
           pwN=pwN*compN*1.4;
          }
    	 if (ncyc > 0)
       	    {initval(ncyc,v1);
             loop(v1,v2);
       	     delay(0.625e-3 - pwN);
      	     dec2rgpulse(2*pwN, zero, 0.0, 0.0);
      	     delay(0.625e-3 - pwN);
            endloop(v2);}
         if (BPpwrlimits > 0.5)
          {
           dec2power(pwNlvl);         /* restore normal value */
           pwN=getval("pwN");
          }
 	}
/*  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  */
        rcvroff();
	if (TROSY[A]=='n')   
	dec2rgpulse(pwN, zero, 0.0, 0.0);   /*destroy N15 magnetization*/
	zgradpulse(gzlvl0, 0.5e-3);
	delay(1.0e-4);
	if (TROSY[A]=='n')    dec2rgpulse(pwN, one, 0.0, 0.0);
	zgradpulse(0.7*gzlvl0, 0.5e-3);
	decpwrf(rfst);
	txphase(t1);
	delay(5.0e-4);

      if ( dm3[B] == 'y' )     /* begins optional 2H decoupling */
        {
          lk_hold();
          dec3rgpulse(1/dmf3,one,10.0e-6,2.0e-6);
          dec3unblank();
          dec3phase(zero);
          delay(2.0e-6);
          setstatus(DEC3ch, TRUE, 'w', FALSE, dmf3);
        }

   	rgpulse(calH*pw,t1,0.0,0.0);                 /* 1H pulse excitation */

	txphase(zero);
   	dec2phase(zero);
	zgradpulse(gzlvl0, gt0);
	delay(lambda - gt0 - pwHH);
	
	if(Hdecflg[0] != 'n')
	{
	  obspower(tpwrs);
          if (tpwrsf<4095.0) obspwrf(tpwrsf); 
	  shaped_pulse("H2Osinc", pwHH, two, 5.0e-5, 0.0);
	  obspower(tpwr);
          if (tpwrsf<4095.0) obspwrf(4095.0);
   	  sim3pulse(2.0*pw, 0.0, 2.0*pwN, zero, zero, zero, 0.0, 0.0);
   	  obspower(tpwrs);
          if (tpwrsf<4095.0) obspwrf(tpwrsf);
   	  shaped_pulse("H2Osinc", pwHH, two, 5.0e-5, 0.0);
   	  obspower(tpwr);
          if (tpwrsf<4095.0) obspwrf(4095.0); 
   	}
   	else 
   	  sim3pulse(2.0*pw, 0.0, 2.0*pwN, zero, zero, zero, 0.0, 0.0);
   	
   	txphase(one);
	zgradpulse(gzlvl0, gt0);
	delay(lambda - gt0 - pwHH);        
 	rgpulse(pw, one, 0.0, 0.0);
	txphase(two);
        obspower(tpwrs);
        if (tpwrsf<4095.0) obspwrf(tpwrsf);
        shaped_pulse("H2Osinc", pwHs, two, 5.0e-5, 0.0);
	obspower(tpwr);
	if (tpwrsf<4095.0) obspwrf(4095.0);

        if (TROSY[A]=='y')
	  zgradpulse(ihh*gzlvl3, gt3);           
	else
	  zgradpulse(-ihh*gzlvl3, gt3);
	dec2phase(t3);
	delay(2.0e-4);
   	dec2rgpulse(calN*pwN, t3, 0.0, 0.0);
	txphase(zero);
	decphase(zero);

/*  xxxxxxxxxxxxxxxxxx    OPTIONS FOR N15 RELAXATION    xxxxxxxxxxxxxxxxxxxx  */

if ( (T1[A]=='y') || (T1rho[A]=='y') || (T2[A]=='y') )
   {
    dec2phase(one);
    zgradpulse(gzlvl4, gt4);				/* 2.0*GRADIENT_DELAY */
    delay(tNH - gt4 - 2.0*GRADIENT_DELAY);

    sim3pulse(2.0*pw, 0.0, 2.0*pwN, zero, zero, one, 0.0, 0.0);

    zgradpulse(gzlvl4, gt4);				/* 2.0*GRADIENT_DELAY */
    delay(tNH - gt4 - 2.0*GRADIENT_DELAY);
   }

		/*   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    */

if  (T1[A]=='y')
   {
    dec2rgpulse(pwN, one, 0.0, 0.0);
    dec2phase(three);

    zgradpulse(gzlvl0, gt0);				/* 2.0*GRADIENT_DELAY */
    delay(2.5e-3 - gt0 - 2.0*GRADIENT_DELAY - pw);
    rgpulse(2.0*pw, zero, 0.0, 0.0);
    delay(2.5e-3 - pw);

    ncyc = (100.0*relaxT);
    initval(ncyc,v4);
    if (ncyc > 0)
	{loop(v4,v5);

	 delay(2.5e-3 - pw);
    	 rgpulse(2.0*pw, two, 0.0, 0.0);
   	 delay(2.5e-3 - pw);

	 delay(2.5e-3 - pw);
    	 rgpulse(2.0*pw, zero, 0.0, 0.0);
   	 delay(2.5e-3 - pw);

	 endloop(v5);}

    dec2rgpulse(pwN, three, 0.0, 0.0);
   }

		/*   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    */

			     /* Theory suggests 8.0 is better than 2PI as RF  */
			     /* field multiplier and experiment confirms this.*/
if  (T1rho[A]=='y')          /* Shift evolution of 2.0*pwN/PI for one pulse   */
   {		             /* at end left unrefocused as for normal sequence*/
    delay(1.0/(8.0*slNrf) - pwN);
    decrgpulse(pwN, zero, 0.0, 0.0);
    dec2power(slNlvl);
           				   /* minimum 5ms spinlock to dephase */
    dec2rgpulse((2.5e-3-pw), zero, 0.0, 0.0);	         /*  spins not locked */
    sim3pulse(2.0*pw, 0.0, 2.0*pw, zero, zero, zero, 0.0, 0.0);
    dec2rgpulse((2.5e-3-pw), zero, 0.0, 0.0);

    ncyc = 100.0*relaxT;
    initval(ncyc,v4);	    if (ncyc > 0)
	  {loop(v4,v5);
           dec2rgpulse((2.5e-3-pw), zero, 0.0, 0.0);
   	   sim3pulse(2.0*pw, 0.0, 2.0*pw, two, zero, zero, 0.0, 0.0);
           dec2rgpulse((2.5e-3-pw), zero, 0.0, 0.0);
           dec2rgpulse((2.5e-3-pw), zero, 0.0, 0.0);
   	   sim3pulse(2.0*pw, 0.0, 2.0*pw, zero, zero, zero, 0.0, 0.0);
           dec2rgpulse((2.5e-3-pw), zero, 0.0, 0.0);
           endloop(v5);} 

    dec2power(pwNlvl);	
    decrgpulse(pwN, zero, 0.0, 0.0);
    delay(1.0/(8.0*slNrf) + 2.0*pwN/PI - pwN);
   }
		/*   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    */

if  (T2[A]=='y')
   {
    dec2phase(zero);
    initval(0.0,v3);   initval(180.0,v4);
    if (BPpwrlimits > 0.5)
     {
      dec2power(pwNlvl-3.0);    /* reduce for probe protection */
      pwN=pwN*compN*1.4;
     }

    ncyc = 100.0*relaxT;
    initval(ncyc,v5);

    loop(v5,v6);

      initval(3.0,v7);
      loop(v7,v8);
       	delay(0.625e-3 - pwN);
      	dec2rgpulse(2.0*pwN, zero, 0.0, 0.0);
      	delay(0.625e-3 - pwN);
      endloop(v8);

      delay(0.625e-3 - pwN - SAPS_DELAY);
      add(v4,v3,v3);  obsstepsize(1.0);  xmtrphase(v3);	   	/* SAPS_DELAY */
      dec2rgpulse(2.0*pwN, zero, 0.0, 0.0);
      delay(0.625e-3 - pwN - pw);

      rgpulse(2*pw, zero, 0.0, 0.0);

      delay(0.625e-3 - pwN - pw );
      dec2rgpulse(2.0*pwN, zero, 0.0, 0.0);
      xmtrphase(zero);						/* SAPS_DELAY */
      delay(0.625e-3 - pwN - SAPS_DELAY);
  
      initval(3.0,v9);
      loop(v9,v10);
      	delay(0.625e-3 - pwN);
      	dec2rgpulse(2.0*pwN, zero, 0.0, 0.0);
      	delay(0.625e-3 - pwN);
      endloop(v10);

    endloop(v6);
    if (BPpwrlimits > 0.5)
     {
      dec2power(pwNlvl);    /* restore normal value */
      pwN=getval("pwN");
     }
   }

/*  xxxxxxxxxxxxxxxxxx    OPTIONS FOR N15 EVOLUTION    xxxxxxxxxxxxxxxxxxxxx  */
	txphase(zero);
	dec2phase(t9);

if ( (NH2only[A]=='y') || (T1[A]=='y') || (T1rho[A]=='y') || (T2[A]=='y') )	
{      
    	delay(tau1);
         			  /* optional sech/tanh pulse in middle of t1 */
    	if (C13refoc[A]=='y') 				   /* WFG_START_DELAY */
           {decshaped_pulse("stC200", 1.0e-3, zero, 0.0, 0.0);
            delay(tNH - 1.0e-3 - WFG_START_DELAY - 2.0*pw);}
    	else
           {delay(tNH - 2.0*pw);}
    	rgpulse(2.0*pw, zero, 0.0, 0.0);
    	if (tNH < gt1 + 1.99e-4)  delay(gt1 + 1.99e-4 - tNH);

    	delay(tau1);

    	dec2rgpulse(2.0*pwN, t9, 0.0, 0.0);

        if (mag_flg[A] == 'y')  magradpulse(gzcal*gzlvl1, gt1);
        else  zgradpulse(gzlvl1, gt1);   	/* 2.0*GRADIENT_DELAY */
	txphase(t4);
    	dec2phase(t10);
   	if (tNH > gt1 + 1.99e-4)  delay(tNH - gt1 - 2.0*GRADIENT_DELAY);
   	else   delay(1.99e-4 - 2.0*GRADIENT_DELAY);
}

else if (TROSY[A]=='y')
{
  	if ( (C13refoc[A]=='y') && (tau1 > 0.5e-3 + WFG2_START_DELAY) )
           {delay(tau1 - 0.5e-3 - WFG2_START_DELAY);     /* WFG2_START_DELAY */
            decshaped_pulse("stC200", 1.0e-3, zero, 0.0, 0.0);
            delay(tau1 - 0.5e-3);}
	else    delay(2.0*tau1);

        if (mag_flg[A] == 'y')  magradpulse(gzcal*gzlvl1, gt1);
        else  zgradpulse(gzlvl1, gt1);   	/* 2.0*GRADIENT_DELAY */
	delay(2.0e-4 - 2.0*GRADIENT_DELAY);

	dec2rgpulse(2.0*pwN, t9, 0.0, 0.0);

	txphase(three);

        delay(gt1 + 2.0e-4 - pwHs - 1.0e-4 - 2.0*pwr_dly);
        obspower(tpwrs);
	if (tpwrsf<4095.0) obspwrf(tpwrsf);
        shaped_pulse("H2Osinc", pwHs, three, 5.0e-5, 0.0);
        obspower(tpwr);
	if (tpwrsf<4095.0) obspwrf(4095.0);

	txphase(t4);
	delay(5.0e-5);
}

else
{					  	    /* fully-coupled spectrum */
        if (dm2[C]=='n')  {rgpulse(2.0*pw, zero, 0.0, 0.0);  pw=0.0;}		

  	if ( (C13refoc[A]=='y') && (tau1 > 0.5e-3 + WFG2_START_DELAY) )
           {delay(tau1 - 0.5e-3 - WFG2_START_DELAY);     /* WFG2_START_DELAY */
            simshaped_pulse("", "stC200", 2.0*pw, 1.0e-3, zero, zero, 0.0, 0.0);
            delay(tau1 - 0.5e-3);
            delay(gt1 + 2.0e-4);}
	else
           {delay(tau1);
            rgpulse(2.0*pw, zero, 0.0, 0.0);
            delay(gt1 + 2.0e-4 - 2.0*pw);
            delay(tau1);} 
 
	pw=getval("pw");
	dec2rgpulse(2.0*pwN, t9, 0.0, 0.0);

        if (mag_flg[A] == 'y')  magradpulse(gzcal*gzlvl1, gt1);
        else  zgradpulse(gzlvl1, gt1);   	/* 2.0*GRADIENT_DELAY */
	txphase(t4);
	dec2phase(t10);
	delay(2.0e-4 - 2.0*GRADIENT_DELAY);
}

	if  (T1rho[A]=='y')   delay(POWER_DELAY); 


/*  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  */
	if (TROSY[A]=='y')  rgpulse(pw, t4, 0.0, 0.0);
	else                sim3pulse(pw, 0.0, pwN, t4, zero, t10, 0.0, 0.0);

	txphase(zero);
	dec2phase(zero);
	zgradpulse(gzlvl5, gt5);
	if (TROSY[A]=='y')   delay(lambda - 0.65*(pw + pwN) - gt5);
	else   delay(lambda - 1.3*pwN - gt5);

	sim3pulse(2.0*pw, 0.0, 2.0*pwN, zero, zero, zero, 0.0, 0.0);

	zgradpulse(gzlvl5, gt5);
	txphase(one);
	dec2phase(t11);
	delay(lambda - 1.3*pwN - gt5);

	sim3pulse(pw, 0.0, pwN, one, zero, t11, 0.0, 0.0);

	txphase(zero);
	dec2phase(zero);
	zgradpulse(1.5*gzlvl5, gt5);
	delay(lambda - 1.3*pwN - gt5);

        sim3pulse(2.0*pw, 0.0, 2.0*pwN, zero, zero, zero, 0.0, 0.0);

	dec2phase(t10);
	zgradpulse(1.5*gzlvl5, gt5);
	if (TROSY[A]=='y')   delay(lambda - 1.6*pwN - gt5);
	else   delay(lambda - 0.65*pwN - gt5);

	if (TROSY[A]=='y')   dec2rgpulse(pwN, t10, 0.0, 0.0); 
	else    	     rgpulse(pw, zero, 0.0, 0.0); 

	delay((gt1/10.0) + 1.0e-4 +gstab - 0.65*pw + 2.0*GRADIENT_DELAY + POWER_DELAY);

        if ( dm3[B] == 'y' )   /* turns off 2H decoupling  */
           {
           setstatus(DEC3ch, FALSE, 'c', FALSE, dmf3);
           dec3rgpulse(1/dmf3,three,2.0e-6,2.0e-6);
           dec3blank();
           lk_autotrig();   /* resumes lock pulsing */
           }

	rgpulse(2.0*pw, zero, 0.0, 0.0);

	dec2power(dpwr2);				       /* POWER_DELAY */
        if (mag_flg[A] == 'y')	  magradpulse(icosel*gzcal*gzlvl2, 0.1*gt1);
        else   zgradpulse(icosel*gzlvl2, 0.1*gt1);		/* 2.0*GRADIENT_DELAY */
        

        if(Cdecflg[0] == 'y')
        {
          delay(gstab-2.0*POWER_DELAY-PRG_START_DELAY+rof2);
          rcvron();
                           
          statusdelay(C,1.0e-4);		

          if (dm3[B] == 'y') 
          {
            delay(1/dmf3); 
            lk_sample();
          }
	  setreceiver(t12);
          pbox_decon(&Cdseq);
          
          if(Hdecflg[0] == 'y')
            homodec(&HHdseq);  
        }
        else
        {
          delay(gstab+rof2);
          rcvron();
                             
          statusdelay(C,1.0e-4);		

          if (dm3[B] == 'y') 
          {
            delay(1/dmf3); 
            lk_sample();
          }
	  setreceiver(t12);

          if(Hdecflg[0] == 'y')
            homodec(&HHdseq);        
        }
}		 
Exemple #8
0
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 */
/**************************************************************
    initparms_img()

    Read in all parameters used by the Imaging 
    SEQD applications package. Build the array 
    of slice positions used in multislice loops.
 *************************************************************/
void initparms_img()
{
    int k;                  /*index for loops*/

/*-------------------------------------------------------------
    INITIALIZE PARAMETERS
-------------------------------------------------------------*/

/*--------------------------------------
    RFPULSES
--------------------------------------*/
    p2 = getvalnwarn("p2");
    p3 = getvalnwarn("p3");
    p4 = getvalnwarn("p4");
    p5 = getvalnwarn("p5");
    pi = getvalnwarn("pi");
    psat = getvalnwarn("psat");
    pmt = getvalnwarn("pmt");
    pwx2 = getvalnwarn("pwx2");
    psl = getvalnwarn("psl");

    getstrnwarn("pwpat",pwpat);
    getstrnwarn("p1pat",p1pat);
    getstrnwarn("p2pat",p2pat);
    getstrnwarn("p3pat",p3pat);
    getstrnwarn("p4pat",p4pat);
    getstrnwarn("p5pat",p5pat);
    getstrnwarn("pipat",pipat);
    getstrnwarn("satpat",satpat);
    getstrnwarn("mtpat",mtpat);
    getstrnwarn("pslpat",pslpat);

    tpwr1 = getvalnwarn("tpwr1");
    tpwr2 = getvalnwarn("tpwr2");
    tpwr3 = getvalnwarn("tpwr3");
    tpwr4 = getvalnwarn("tpwr4");
    tpwr5 = getvalnwarn("tpwr5");
    tpwri = getvalnwarn("tpwri");
    mtpwr = getvalnwarn("mtpwr");
    pwxlvl2 = getvalnwarn("pwxlvl2");
    tpwrsl = getvalnwarn("tpwrsl");

/*--------------------------------------
    DECOUPLER PULSES
--------------------------------------*/
    getstrnwarn("decpat",decpat);
    getstrnwarn("decpat1",decpat1);
    getstrnwarn("decpat2",decpat2);
    getstrnwarn("decpat3",decpat3);
    getstrnwarn("decpat4",decpat4);
    getstrnwarn("decpat5",decpat5);

    dpwr = getvalnwarn("dpwr");
    dpwr1 = getvalnwarn("dpwr1");
    dpwr4 = getvalnwarn("dpwr4");
    dpwr5 = getvalnwarn("dpwr5");

/*--------------------------------------
    GRADIENTS
--------------------------------------*/
    gradunit = getvalnwarn("gradunit");
    gro = getvalnwarn("gro");
    gro2 = getvalnwarn("gro2");
    gro3 = getvalnwarn("gro3");
    gpe = getvalnwarn("gpe");
    gpe2 = getvalnwarn("gpe2");
    gpe3 = getvalnwarn("gpe3");
    gss = getvalnwarn("gss");
    gss2 = getvalnwarn("gss2");
    gss3 = getvalnwarn("gss3");
    gror = getvalnwarn("gror");
    gssr = getvalnwarn("gssr");
    grof = getvalnwarn("grof");
    gssf = getvalnwarn("gssf");
    g0 = getvalnwarn("g0");
    g1 = getvalnwarn("g1");
    g2 = getvalnwarn("g2");
    g3 = getvalnwarn("g3");
    g4 = getvalnwarn("g4");
    g5 = getvalnwarn("g5");
    g6 = getvalnwarn("g6");
    g7 = getvalnwarn("g7");
    g8 = getvalnwarn("g8");
    g9 = getvalnwarn("g9");
    gx = getvalnwarn("gx");
    gy = getvalnwarn("gy");
    gz = getvalnwarn("gz");
    gvox1 = getvalnwarn("gvox1");
    gvox2 = getvalnwarn("gvox2");
    gvox3 = getvalnwarn("gvox3");
    gdiff = getvalnwarn("gdiff");
    gflow = getvalnwarn("gflow");
    gspoil = getvalnwarn("gspoil");
    gspoil2 = getvalnwarn("gspoil2");
    gcrush = getvalnwarn("gcrush");
    gcrush2 = getvalnwarn("gcrush2");
    gtrim = getvalnwarn("gtrim");
    gtrim2 = getvalnwarn("gtrim2");
    gramp = getvalnwarn("gramp");
    gramp2 = getvalnwarn("gramp2");
    gxscale = getvalnwarn("gxscale");
    gyscale = getvalnwarn("gyscale");
    gzscale = getvalnwarn("gzscale");
    gpemult = getvalnwarn("gpemult");

    /* Get gmax or gxmax, gymax, gzmax */
    if ( P_getreal(CURRENT,"gxmax",&gxmax,1) < 0 )
    {
    	if ( P_getreal(CURRENT,"gmax",&gmax,1) < 0 )
    	{
		gmax = 0;
    	}
	gxmax = gmax;
    }
    if ( P_getreal(CURRENT,"gymax",&gymax,1) < 0 )
    {
    	if ( P_getreal(CURRENT,"gmax",&gmax,1) < 0 )
    	{
		gmax = 0;
	}
	gymax = gmax;
    }
    if ( P_getreal(CURRENT,"gzmax",&gzmax,1) < 0 )
    {
    	if ( P_getreal(CURRENT,"gmax",&gmax,1) < 0 )
    	{
		gmax = 0;
	}
	gzmax = gmax;
    }
    if (gxmax < gzmax)
	if (gxmax < gymax)
	   gmax = gxmax;
	else
	   gmax = gymax;
    else
	if (gxmax < gymax)
	   gmax = gxmax;
	else
	   gmax = gymax;

    /* --- Get gradient limit parameters --- */
    if ( P_getreal(CURRENT,"gtotlimit",&gtotlimit,1) < 0 )
	gtotlimit = gxmax + gymax + gzmax;
    if (gtotlimit <= 0.0) gtotlimit = gxmax + gymax + gzmax;

    if ( P_getreal(CURRENT,"gxlimit",&gxlimit,1) < 0 )
	gxlimit = gxmax;
    if (gxlimit <= 0.0) gxlimit = gxmax;

    if ( P_getreal(CURRENT,"gylimit",&gylimit,1) < 0 )
	gylimit = gymax;
    if (gylimit <= 0.0) gylimit = gymax;

    if ( P_getreal(CURRENT,"gzlimit",&gzlimit,1) < 0 )
	gzlimit = gzmax;
    if (gzlimit <= 0.0) gzlimit = gzmax;

    /* --- Get gradstepsz if Present --- */
    /* if gradstepsz is 32767 gradient waveshaping is being used  */
    if ( P_getreal(GLOBAL,"gradstepsz",&gradstepsz,1) >= 0 )
    {
	if (gradstepsz < 1.0)
	{
	    if ((anygradcrwg) || (anygradwg) || (anypfga) || (anypfgw))
		gradstepsz = 32767.0;
	    else
		gradstepsz = 2047.0;
	}
    }
    else
    {
	if ((anygradcrwg) || (anygradwg) || (anypfga) || (anypfgw))
	    gradstepsz = 32767.0;
	else
	    gradstepsz = 2047.0;
    }

    getstrnwarn("gpatup",gpatup);
    getstrnwarn("gpatdown",gpatdown);
    getstrnwarn("gropat",gropat);
    getstrnwarn("gpepat",gpepat);
    getstrnwarn("gsspat",gsspat);
    getstrnwarn("gpat",gpat);
    getstrnwarn("gpat1",gpat1);
    getstrnwarn("gpat2",gpat2);
    getstrnwarn("gpat3",gpat3);
    getstrnwarn("gpat4",gpat4);
    getstrnwarn("gpat5",gpat5);

/*--------------------------------------
    DELAYS
--------------------------------------*/
    tr = getvalnwarn("tr");
    te = getvalnwarn("te");
    ti = getvalnwarn("ti");
    tm = getvalnwarn("tm");
    at = getvalnwarn("at");
    tpe = getvalnwarn("tpe");
    tpe2 = getvalnwarn("tpe2");
    tpe3 = getvalnwarn("tpe3");
    tcrush = getvalnwarn("tcrush");
    tdiff = getvalnwarn("tdiff");
    tdelta = getvalnwarn("tdelta");
    tDELTA = getvalnwarn("tDELTA");
    tflow = getvalnwarn("tflow");
    tspoil = getvalnwarn("tspoil");
    hold = getvalnwarn("hold");
    trise = getvalnwarn("trise");
    if (trise > 10e-3) abort_message("trise: %5.0f usec is excessive!",trise*1e6);

/*--------------------------------------
    FREQUENCIES
--------------------------------------*/
    resto = getvalnwarn("resto");
    wsfrq = getvalnwarn("wsfrq");
    chessfrq = getvalnwarn("chessfrq");
    mtfrq = getvalnwarn("mtfrq");

/*--------------------------------------
    PHYSICAL POSITIONS AND FOV
--------------------------------------*/
    fovunit = getvalnwarn("fovunit");
    pro = getvalnwarn("pro");
    ppe = getvalnwarn("ppe");
    ppe2 = getvalnwarn("ppe2");
    ppe3 = getvalnwarn("ppe3");
    pos1 = getvalnwarn("pos1");
    pos2 = getvalnwarn("pos2");
    pos3 = getvalnwarn("pos3");
    lro = getvalnwarn("lro");
    lpe = getvalnwarn("lpe");
    lpe2 = getvalnwarn("lpe2");
    lpe3 = getvalnwarn("lpe3");
    lss = getvalnwarn("lss");

/*--------------------------------------
    PHYSICAL SIZES
--------------------------------------*/
    thkunit = getvalnwarn("thkunit");
    vox1 = getvalnwarn("vox1");
    vox2 = getvalnwarn("vox2");
    vox3 = getvalnwarn("vox3");
    thk = getvalnwarn("thk");

/*--------------------------------------
    BANDWIDTHS
--------------------------------------*/
    sw1 = getvalnwarn("sw1");
    sw2 = getvalnwarn("sw2");
    sw3 = getvalnwarn("sw3");

/*--------------------------------------
    ORIENTATION PARAMETERS
--------------------------------------*/
    getstrnwarn("orient",orient);
    getstrnwarn("vorient",vorient);
    getstrnwarn("dorient",dorient);
    getstrnwarn("sorient",sorient);
    getstrnwarn("orient2",orient2);
        
    psi = getvalnwarn("psi");
    phi = getvalnwarn("phi");
    theta = getvalnwarn("theta");
    vpsi = getvalnwarn("vpsi");
    vphi = getvalnwarn("vphi");
    vtheta = getvalnwarn("vtheta");
    dpsi = getvalnwarn("dpsi");
    dphi = getvalnwarn("dphi");
    dtheta = getvalnwarn("dtheta");
    spsi = getvalnwarn("spsi");
    sphi = getvalnwarn("sphi");
    stheta = getvalnwarn("stheta");

    offsetx = getvalnwarn("offsetx");
    offsety = getvalnwarn("offsety");
    offsetz = getvalnwarn("offsetz");
    gxdelay = getvalnwarn("gxdelay");
    gydelay = getvalnwarn("gydelay");
    gzdelay = getvalnwarn("gzdelay");

/*--------------------------------------
    COUNTS AND FLAGS
--------------------------------------*/
    nD = getvalnwarn("nD");
    ns = getvalnwarn("ns");
    ne = getvalnwarn("ne");
    ni = getvalnwarn("ni");
    nv = getvalnwarn("nv");
    nv2 = getvalnwarn("nv2");
    nv3 = getvalnwarn("nv3");
    ssc = getvalnwarn("ssc");
    ticks = getvalnwarn("ticks");
        
    getstrnwarn("ir",ir);
    getstrnwarn("ws",ws);
    getstrnwarn("mt",mt);
    getstrnwarn("pilot",pilot);
    getstrnwarn("seqcon",seqcon);
    getstrnwarn("petable",petable);
    getstrnwarn("acqtype",acqtype);
    getstrnwarn("exptype",exptype);
    getstrnwarn("apptype",apptype);
    getstrnwarn("seqfil",seqfil);
    getstrnwarn("rfspoil",rfspoil);
    getstrnwarn("verbose",verbose);

/*--------------------------------------
    Miscellaneous
--------------------------------------*/
    rfphase = getvalnwarn("rfphase");
    B0 = getvalnwarn("B0");
    gpropdelay = getvalnwarn("gpropdelay");
    kzero = getvalnwarn("kzero");
    aqtm = getvalnwarn("aqtm");
    getstrnwarn("volumercv",volumercv);


/*--------------------------------------
    Build slice position array
--------------------------------------*/
    if (ns > MAXSLICE) {
        text_error("ns exceeds maximum limit.\n");
        psg_abort(1);
    }

    for (k = 0; k < MAXSLICE; k++) {
        pss[k] = 0.0;
    }

    if (seqcon[1] == 's')
	pss[0] = getval("pss");
    else if (seqcon[1] == 'c')
    	getarray("pss",pss);
    else
	pss[0] = getvalnwarn("pss");	/* get it anyway but with no warning */


/*--------------------------------------
    Old SISCO Imaging Parameters
--------------------------------------*/
    slcto = getvalnwarn("slcto");    /* slice selection offset */
    delto = getvalnwarn("delto");    /* slice spacing frequency */
    tox = getvalnwarn("tox");
    toy = getvalnwarn("toy");
    toz = getvalnwarn("toz");
    griserate = getvalnwarn("griserate");

}
Exemple #10
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);
}
Exemple #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();
}