Example #1
0
/* Parse command line, sanity check arguments, and return a newly
 * allocated GSParams object */
static GSParams *parse_args(ssize_t argc, char **argv) {
    ssize_t i;
    GSParams *params;
    params = (GSParams *) XLALMalloc(sizeof(GSParams));
    memset(params, 0, sizeof(GSParams));

    /* Set default values to the arguments */
    params->waveFlags = XLALSimInspiralCreateWaveformFlags();
    params->nonGRparams = NULL;
    params->approximant = TaylorT1;
    params->domain = LAL_SIM_DOMAIN_TIME;
    params->phaseO = 7;
    params->ampO = 0;
    params->phiRef = 0.;
    params->deltaT = 1./4096.;
    params->deltaF = 0.125;
    params->m1 = 10. * LAL_MSUN_SI;
    params->m2 = 1.4 * LAL_MSUN_SI;
    params->f_min = 40.;
    params->fRef = 0.;
    params->f_max = 0.; /* Generate as much as possible */
    params->distance = 100. * 1e6 * LAL_PC_SI;
    params->inclination = 0.;
    params->s1x = 0.;
    params->s1y = 0.;
    params->s1z = 0.;
    params->s2x = 0.;
    params->s2y = 0.;
    params->s2z = 0.;
    params->lambda1 = 0.;
    params->lambda2 = 0.;
    strncpy(params->outname, "simulation.dat", 256); /* output to this file */
    params->ampPhase = 0; /* output h+ and hx */
    params->verbose = 0; /* No verbosity */

    /* consume command line */
    for (i = 1; i < argc; ++i) {
        if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
            printf("%s", usage);
            XLALFree(params);
            exit(0);
        } else if (strcmp(argv[i], "--verbose") == 0) {
            params->verbose = 1;
        } else if (strcmp(argv[i], "--amp-phase") == 0) {
            params->ampPhase = 1;
        } else if ( ( i == argc ) || ( !argv[i+1] ) ) {
            XLALPrintError("Error: value required for option %s\n", argv[i]);
        } else if (strcmp(argv[i], "--approximant") == 0) {
            params->approximant = XLALSimInspiralGetApproximantFromString(argv[++i]);
            if ( (int) params->approximant == XLAL_FAILURE) {
                XLALPrintError("Error: invalid value %s for --interaction-flag\n", argv[i]);
                goto fail;
            }
        } else if (strcmp(argv[i], "--domain") == 0) {
            i++;
            if (strcmp(argv[i], "TD") == 0)
                params->domain = LAL_SIM_DOMAIN_TIME;
            else if (strcmp(argv[i], "FD") == 0)
                params->domain = LAL_SIM_DOMAIN_FREQUENCY;
            else {
                XLALPrintError("Error: Unknown domain\n");
                goto fail;
            }
        } else if (strcmp(argv[i], "--phase-order") == 0) {
            params->phaseO = atoi(argv[++i]);
        } else if (strcmp(argv[i], "--amp-order") == 0) {
            params->ampO = atoi(argv[++i]);
        } else if (strcmp(argv[i], "--phiRef") == 0) {
            params->phiRef = atof(argv[++i]);
        } else if (strcmp(argv[i], "--fRef") == 0) {
            params->fRef = atof(argv[++i]);
        } else if (strcmp(argv[i], "--sample-rate") == 0) {
            params->deltaT = 1./atof(argv[++i]);
        } else if (strcmp(argv[i], "--deltaF") == 0) {
            params->deltaF = atof(argv[++i]);
        } else if (strcmp(argv[i], "--m1") == 0) {
            params->m1 = atof(argv[++i]) * LAL_MSUN_SI;
        } else if (strcmp(argv[i], "--m2") == 0) {
            params->m2 = atof(argv[++i]) * LAL_MSUN_SI;
        } else if (strcmp(argv[i], "--spin1x") == 0) {
            params->s1x = atof(argv[++i]);
        } else if (strcmp(argv[i], "--spin1y") == 0) {
            params->s1y = atof(argv[++i]);
        } else if (strcmp(argv[i], "--spin1z") == 0) {
            params->s1z = atof(argv[++i]);
        } else if (strcmp(argv[i], "--spin2x") == 0) {
            params->s2x = atof(argv[++i]);
        } else if (strcmp(argv[i], "--spin2y") == 0) {
            params->s2y = atof(argv[++i]);
        } else if (strcmp(argv[i], "--spin2z") == 0) {
            params->s2z = atof(argv[++i]);
        } else if (strcmp(argv[i], "--tidal-lambda1") == 0) {
            params->lambda1 = atof(argv[++i]);
        } else if (strcmp(argv[i], "--tidal-lambda2") == 0) {
            params->lambda2 = atof(argv[++i]);
        } else if (strcmp(argv[i], "--spin-order") == 0) {
            XLALSimInspiralSetSpinOrder( params->waveFlags, atoi(argv[++i]) );
        } else if (strcmp(argv[i], "--tidal-order") == 0) {
            XLALSimInspiralSetTidalOrder( params->waveFlags, atoi(argv[++i]) );
        } else if (strcmp(argv[i], "--f-min") == 0) {
            params->f_min = atof(argv[++i]);
        } else if (strcmp(argv[i], "--f-max") == 0) {
            params->f_max = atof(argv[++i]);
        } else if (strcmp(argv[i], "--distance") == 0) {
            params->distance = atof(argv[++i]) * 1e6 * LAL_PC_SI;
        } else if (strcmp(argv[i], "--inclination") == 0) {
            params->inclination = atof(argv[++i]);
        } else if (strcmp(argv[i], "--axis") == 0) {
            XLALSimInspiralSetFrameAxis( params->waveFlags,
                                         XLALGetFrameAxisFromString(argv[++i]) );
            if ( (int) XLALSimInspiralGetFrameAxis(params->waveFlags)
                    == (int) XLAL_FAILURE) {
                XLALPrintError("Error: invalid value %s for --axis\n", argv[i]);
                goto fail;
            }
        } else if (strcmp(argv[i], "--modes") == 0) {
            XLALSimInspiralSetModesChoice( params->waveFlags,
                                           XLALGetHigherModesFromString(argv[++i]) );
            if ( (int) XLALSimInspiralGetModesChoice(params->waveFlags)
                    == (int) XLAL_FAILURE) {
                XLALPrintError("Error: invalid value %s for --modes\n", argv[i]);
                goto fail;
            }
        } else if (strcmp(argv[i], "--nonGRpar") == 0) {
            char name[100];
            strcpy(name,argv[++i]);
            if ( ( i == argc ) || ( !argv[i+1] ) ) {
                XLALPrintError("Error: 'name value' pair required for option %s\n", argv[i-1]);
            } else if (params->nonGRparams==NULL) {
                params->nonGRparams=XLALSimInspiralCreateTestGRParam(name,atof(argv[++i]));
            } else {
                XLALSimInspiralAddTestGRParam(&params->nonGRparams,name,atof(argv[++i]));
            }
        } else if (strcmp(argv[i], "--outname") == 0) {
            strncpy(params->outname, argv[++i], 256);
        } else {
            XLALPrintError("Error: invalid option: %s\n", argv[i]);
            goto fail;
        }
    }

    return params;

fail:
    printf("%s", usage);
    XLALFree(params);
    exit(1);
}
int main(void) {
	static LALStatus    mystatus;

	/* variables for timing purposes */
	clock_t start, diff;
	int msec;

	REAL4TimeSeries *h_plus;
	REAL4TimeSeries *h_cross;
	REAL8TimeSeries *hplus;
	REAL8TimeSeries *hcross;
	InspiralTemplate params;

	FILE *outputfile;
	INT4 i,length;
	REAL8 dt, m, m1, m2, nu, lambda1, lambda2;
	LIGOTimeGPS tc = LIGOTIMEGPSZERO;

	memset( &mystatus, 0, sizeof(LALStatus) );
	memset( &params, 0, sizeof(InspiralTemplate) );

	m1 = 5.;
	m2 = 5.;
	m = m1 + m2;
	nu = m1 * m2 / m / m;

	lambda1 = 0.;
	lambda2 = 0.;
	LALSimInspiralWaveformFlags *waveFlags;
	waveFlags = XLALSimInspiralCreateWaveformFlags();

	params.approximant = TaylorT4;
	params.order = LAL_PNORDER_THREE_POINT_FIVE;
	params.ampOrder = LAL_PNORDER_NEWTONIAN;
	params.mass1 = m1;
	params.mass2 = m2;
	params.totalMass = m;
	params.eta = nu;
	params.tSampling = 4096;
	params.fCutoff = 2047.;
	params.fLower = 40.;
	params.distance = 1e6 * LAL_PC_SI;
	params.ieta = 1;

	dt = 1. / params.tSampling;

	start = clock();
	length = XLALSimInspiralTaylorT4PNRestricted(&hplus, &hcross, 0., dt, params.mass1*LAL_MSUN_SI, params.mass2*LAL_MSUN_SI, params.fLower, 0., params.distance, lambda1, lambda2, XLALSimInspiralGetTidalOrder(waveFlags), 0, 7);
	diff = clock() - start;
	msec = diff * 1000 / CLOCKS_PER_SEC;
	printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000);

	fprintf(stderr, "length = %i\n", length);
	fprintf(stderr, "T = %f\n", (float) length * dt);

	outputfile = fopen("T4wave1.dat","w");

	length = hplus->data->length;

	for(i = 0; i < length; i++) {
		fprintf(outputfile,"%e\t%e\t%e\n",
			i*dt,
			hplus->data->data[i],
			hcross->data->data[i]);
	}

	fclose(outputfile);
	fprintf(stdout,"waveform saved in T4wave1.dat\n" );

	start = clock();
	h_plus = XLALCreateREAL4TimeSeries("", &tc, 0.0, dt, &lalDimensionlessUnit, 4096*3);
	h_cross = XLALCreateREAL4TimeSeries("", &tc, 0.0, dt, &lalDimensionlessUnit, 4096*3);

	fprintf(stderr, "Lower cut-off frequency used will be %fHz\n", params.fLower);

	/* --- now we can call the injection function --- */
	LALTaylorT4WaveformTemplates(&mystatus, h_plus->data, h_cross->data, &params);
	diff = clock() - start;
	msec = diff * 1000 / CLOCKS_PER_SEC;
	printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000);

	if ( mystatus.statusCode )
	{
		fprintf( stderr, "LALInspiralTaylorT4Test: error generating waveform\n" );
		exit( 1 );
	}

	/* --- and finally save in a file --- */

	outputfile = fopen("T4wave2.dat","w");

	length = h_plus->data->length;

	for(i = 0; i < length; i++) {
		fprintf(outputfile,"%e\t%e\t%e\n",
			i*dt,
			h_plus->data->data[i],
			h_cross->data->data[i]);
	}

	fclose(outputfile);
	fprintf(stdout,"waveform saved in T4wave2.dat\n" );
	return 0;
}
REAL8 calculate_lalsim_snr(SimInspiralTable *inj, char *IFOname, REAL8FrequencySeries *psd, REAL8 start_freq)
{
  /* Calculate and return the single IFO SNR
   *
   * Required options:
   *
   * inj:     SimInspiralTable entry for which the SNR has to be calculated
   * IFOname: The canonical name (e.g. H1, L1, V1) name of the IFO for which the SNR must be calculated
   * PSD:     PSD curve to be used for the overlap integrap
   * start_freq: lower cutoff of the overlap integral
   *
   * */

  int ret=0;
  INT4 errnum=0;
  UINT4 j=0;
  /* Fill detector site info */
  LALDetector*  detector=NULL;
  detector=calloc(1,sizeof(LALDetector));
  if(!strcmp(IFOname,"H1"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLHODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"H2"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLHODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"LLO")||!strcmp(IFOname,"L1"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexLLODIFF],sizeof(LALDetector));
  if(!strcmp(IFOname,"V1")||!strcmp(IFOname,"VIRGO"))
    memcpy(detector,&lalCachedDetectors[LALDetectorIndexVIRGODIFF],sizeof(LALDetector));

  Approximant approx=TaylorF2;
  approx=XLALGetApproximantFromString(inj->waveform);
  LALSimulationDomain modelDomain;

  if(XLALSimInspiralImplementedFDApproximants(approx)) modelDomain = LAL_SIM_DOMAIN_FREQUENCY;
  else if(XLALSimInspiralImplementedTDApproximants(approx)) modelDomain = LAL_SIM_DOMAIN_TIME;
  else
  {
      fprintf(stderr,"ERROR. Unknown approximant number %i. Unable to choose time or frequency domain model.",approx);
      exit(1);
  }

  REAL8 m1,m2, s1x,s1y,s1z,s2x,s2y,s2z,phi0,f_min,f_max,iota,polarization,

  /* No tidal PN terms until injtable is able to get them */
  lambda1=0.0,lambda2=0.0;

  LALSimInspiralWaveformFlags *waveFlags= XLALSimInspiralCreateWaveformFlags();

  /* Spin and tidal interactions at the highest level (default) until injtable stores them.
   * When spinO and tideO are added to injtable we can un-comment those lines and should be ok
   *
  int spinO = inj->spinO;
  int tideO = inj->tideO;
  XLALSimInspiralSetSpinOrder(waveFlags, *(LALSimInspiralSpinOrder*) spinO);
  XLALSimInspiralSetTidalOrder(waveFlags, *(LALSimInspiralTidalOrder*) tideO);
  */

  /* When nonGR terms stored in the table, we can add them here. (If they are only phase deformations, they won't change the SNR though) */
  LALSimInspiralTestGRParam *nonGRparams=NULL;
  /* Linked list of non-GR parameters. Pass in NULL (or None in python) for standard GR waveforms */

  LALPNOrder  order;   /* Phase order of the model   */
  INT4        amporder=0;
  order = XLALGetOrderFromString(inj->waveform);
  amporder = inj->amp_order;
  /* Read parameters */
  m1=inj->mass1*LAL_MSUN_SI;
  m2=inj->mass2*LAL_MSUN_SI;
  s1x=inj->spin1x;
  s1y=inj->spin1y;
  s1z=inj->spin1z;
  s2x=inj->spin2x;
  s2y=inj->spin2y;
  s2z=inj->spin2z;
  iota=inj->inclination;
  f_min=start_freq;
  phi0=inj->coa_phase;
  polarization=inj->polarization;
  REAL8 latitude=inj->latitude;
  REAL8 longitude=inj->longitude;

  LIGOTimeGPS epoch;
  memcpy(&epoch,&(inj->geocent_end_time),sizeof(LIGOTimeGPS));

  /* Hardcoded values of srate and segment length. If changed here they must also be changed in inspinj.c */
  REAL8 srate=4096.0;
  const CHAR *WF=inj->waveform;
  /* Increase srate for EOB WFs */
  if (strstr(WF,"EOB"))
    srate=8192.0;
  REAL8 segment=64.0;

  f_max=(srate/2.0-(1.0/segment));
  size_t seglen=(size_t) segment*srate;
  REAL8 deltaF=1.0/segment;
  REAL8 deltaT=1.0/srate;

  /* Frequency domain h+ and hx. They are going to be filled either by a FD WF or by the FFT of a TD WF*/
  COMPLEX16FrequencySeries *freqHplus;
  COMPLEX16FrequencySeries *freqHcross;
  freqHplus=  XLALCreateCOMPLEX16FrequencySeries("fhplus",
    &epoch,
    0.0,
    deltaF,
    &lalDimensionlessUnit,
    seglen/2+1
  );

  freqHcross=XLALCreateCOMPLEX16FrequencySeries("fhcross",
    &epoch,
    0.0,
    deltaF,
    &lalDimensionlessUnit,
    seglen/2+1
  );

  /* If the approximant is on the FD call XLALSimInspiralChooseFDWaveform */
  if (modelDomain == LAL_SIM_DOMAIN_FREQUENCY)
  {

    COMPLEX16FrequencySeries *hptilde=NULL;
    COMPLEX16FrequencySeries *hctilde=NULL;
    XLAL_TRY(ret=XLALSimInspiralChooseFDWaveform(&hptilde,&hctilde, phi0, deltaF, m1, m2,
      s1x, s1y, s1z, s2x, s2y, s2z, f_min, 0.0, 0.0, LAL_PC_SI * 1.0e6,
      iota, lambda1, lambda2, waveFlags, nonGRparams,
      amporder, order, approx),errnum
    );

    if(!hptilde|| hptilde->data==NULL || hptilde->data->data==NULL ||!hctilde|| hctilde->data==NULL || hctilde->data->data==NULL)
    {
      XLALPrintError(" ERROR in XLALSimInspiralChooseFDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum );
      exit(1);
    }

    COMPLEX16 *dataPtr = hptilde->data->data;
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      if(j < hptilde->data->length)
      {
        freqHplus->data->data[j] = dataPtr[j];
      }
      else
      {
        freqHplus->data->data[j]=0.0 + I*0.0;
      }
    }
    dataPtr = hctilde->data->data;
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      if(j < hctilde->data->length)
      {
        freqHcross->data->data[j] = dataPtr[j];
      }
      else
      {
        freqHcross->data->data[j]=0.0+0.0*I;
      }
    }
    /* Clean */
    if(hptilde) XLALDestroyCOMPLEX16FrequencySeries(hptilde);
    if(hctilde) XLALDestroyCOMPLEX16FrequencySeries(hctilde);

  }
  else
  {

    /* Otherwise use XLALSimInspiralChooseTDWaveform */
    REAL8FFTPlan *timeToFreqFFTPlan = XLALCreateForwardREAL8FFTPlan((UINT4) seglen, 0 );
    REAL8TimeSeries *hplus=NULL;
    REAL8TimeSeries *hcross=NULL;
    REAL8TimeSeries *timeHplus=NULL;
    REAL8TimeSeries *timeHcross=NULL;
    REAL8 padding =0.4;//seconds
    REAL8Window *window=XLALCreateTukeyREAL8Window(seglen,(REAL8)2.0*padding*srate/(REAL8)seglen);
    REAL4 WinNorm = sqrt(window->sumofsquares/window->data->length);
    timeHcross=XLALCreateREAL8TimeSeries("timeModelhCross",
      &epoch,
      0.0,
      deltaT,
      &lalStrainUnit,
      seglen
    );
    timeHplus=XLALCreateREAL8TimeSeries("timeModelhplus",
      &epoch,
      0.0,
      deltaT,
      &lalStrainUnit,
      seglen
    );
    for (j=0;j<(UINT4) timeHcross->data->length;++j)
      timeHcross->data->data[j]=0.0;
    for (j=0;j<(UINT4) timeHplus->data->length;++j)
      timeHplus->data->data[j]=0.0;
    XLAL_TRY(ret=XLALSimInspiralChooseTDWaveform(&hplus, &hcross, phi0, deltaT,
        m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, f_min, 0., LAL_PC_SI*1.0e6,
        iota, lambda1, lambda2, waveFlags, nonGRparams, amporder, order, approx),
        errnum);

    if (ret == XLAL_FAILURE || hplus == NULL || hcross == NULL)
    {
      XLALPrintError(" ERROR in XLALSimInspiralChooseTDWaveform(): error generating waveform. errnum=%d. Exiting...\n",errnum );
      exit(1);
    }

    XLALSimAddInjectionREAL8TimeSeries(timeHplus, hplus, NULL);
    XLALSimAddInjectionREAL8TimeSeries(timeHcross, hcross, NULL);
    for (j=0; j<(UINT4) timeHplus->data->length; ++j)
      timeHplus->data->data[j]*=window->data->data[j];
    for (j=0; j<(UINT4) timeHcross->data->length; ++j)
      timeHcross->data->data[j]*=window->data->data[j];
      
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      freqHplus->data->data[j]=0.0+I*0.0;
      freqHcross->data->data[j]=0.0+I*0.0;
    }

    /* FFT into freqHplus and freqHcross */
    XLALREAL8TimeFreqFFT(freqHplus,timeHplus,timeToFreqFFTPlan);
    XLALREAL8TimeFreqFFT(freqHcross,timeHcross,timeToFreqFFTPlan);
    for (j=0; j<(UINT4) freqHplus->data->length; ++j)
    {
      freqHplus->data->data[j]/=WinNorm;
      freqHcross->data->data[j]/=WinNorm;
    }
    /* Clean... */
    if ( hplus ) XLALDestroyREAL8TimeSeries(hplus);
    if ( hcross ) XLALDestroyREAL8TimeSeries(hcross);
    if ( timeHplus ) XLALDestroyREAL8TimeSeries(timeHplus);
    if ( timeHcross ) XLALDestroyREAL8TimeSeries(timeHcross);
    if (timeToFreqFFTPlan) LALFree(timeToFreqFFTPlan);
    if (window) XLALDestroyREAL8Window(window);
  }

  /* The WF has been generated and is in freqHplus/cross. Now project into the IFO frame */
  double Fplus, Fcross;
  double FplusScaled, FcrossScaled;
  double HSquared;
  double GPSdouble=(REAL8) inj->geocent_end_time.gpsSeconds+ (REAL8) inj->geocent_end_time.gpsNanoSeconds*1.0e-9;
  double gmst;
  LIGOTimeGPS GPSlal;
  XLALGPSSetREAL8(&GPSlal, GPSdouble);
  gmst=XLALGreenwichMeanSiderealTime(&GPSlal);

  /* Fill Fplus and Fcross*/
  XLALComputeDetAMResponse(&Fplus, &Fcross, (const REAL4 (*)[3])detector->response,longitude, latitude, polarization, gmst);
  /* And take the distance into account */
  FplusScaled  = Fplus  / (inj->distance);
  FcrossScaled = Fcross / (inj->distance);

  REAL8 timedelay = XLALTimeDelayFromEarthCenter(detector->location,longitude, latitude, &GPSlal);
  REAL8 timeshift =  timedelay;
  REAL8 twopit    = LAL_TWOPI * timeshift;

  UINT4 lower = (UINT4)ceil(f_min / deltaF);
  UINT4 upper = (UINT4)floor(f_max / deltaF);
  REAL8 re = cos(twopit*deltaF*lower);
  REAL8 im = -sin(twopit*deltaF*lower);

  /* Incremental values, using cos(theta) - 1 = -2*sin(theta/2)^2 */
  REAL8 dim = -sin(twopit*deltaF);
  REAL8 dre = -2.0*sin(0.5*twopit*deltaF)*sin(0.5*twopit*deltaF);
  REAL8 TwoDeltaToverN = 2.0 *deltaT / ((double) seglen);

  REAL8 plainTemplateReal,  plainTemplateImag,templateReal,templateImag;
  REAL8 newRe, newIm,temp;
  REAL8 this_snr=0.0;
  for (j=lower; j<=(UINT4) upper; ++j)
  {
    /* derive template (involving location/orientation parameters) from given plus/cross waveforms: */
    plainTemplateReal = FplusScaled * creal(freqHplus->data->data[j])
                        +  FcrossScaled *creal(freqHcross->data->data[j]);
    plainTemplateImag = FplusScaled * cimag(freqHplus->data->data[j])
                        +  FcrossScaled * cimag(freqHcross->data->data[j]);

    /* do time-shifting...             */
    /* (also un-do 1/deltaT scaling): */
    templateReal = (plainTemplateReal*re - plainTemplateImag*im) / deltaT;
    templateImag = (plainTemplateReal*im + plainTemplateImag*re) / deltaT;
    HSquared  = templateReal*templateReal + templateImag*templateImag ;
    temp = ((TwoDeltaToverN * HSquared) / psd->data->data[j]);
    this_snr  += temp;
    /* Now update re and im for the next iteration. */
    newRe = re + re*dre - im*dim;
    newIm = im + re*dim + im*dre;

    re = newRe;
    im = newIm;
  }

  /* Clean */
  if (freqHcross) XLALDestroyCOMPLEX16FrequencySeries(freqHcross);
  if (freqHplus) XLALDestroyCOMPLEX16FrequencySeries(freqHplus);
  if (waveFlags) XLALSimInspiralDestroyWaveformFlags(waveFlags);
  if (nonGRparams) XLALSimInspiralDestroyTestGRParam(nonGRparams);
  if (detector) free(detector);

  return sqrt(this_snr*2.0);

}