int main( int argc, char *argv[] )
{
  LALStatus             status = blank_status;
#if 0
  const INT4            S2StartTime = 729273613; /* Feb 14 2003 16:00:00 UTC */
  const INT4            S2StopTime  = 734367613; /* Apr 14 2003 15:00:00 UTC */
#endif
  /* command line options */
  LIGOTimeGPS   gpsStartTime = {S2StartTime, 0};
  LIGOTimeGPS   gpsEndTime   = {S2StopTime, 0};
  REAL8         meanTimeStep = 2630 / LAL_PI;
  REAL8         timeInterval = 0;
  UINT4         randSeed = 1;
  CHAR         *userTag = NULL;
  REAL4         minMass = 3.0;       /* minimum component mass */
  REAL4         maxMass = 20.0;      /* maximum component mass */
  REAL4         sumMaxMass = 0.0;    /* maximum total mass sum */
  UINT4         sumMaxMassUse=0;     /* flag indicating to use the sumMaxMass */
  REAL4         dmin = 1.0;          /* minimum distance from earth (kpc) */
  REAL4         dmax = 20000.0 ;     /* maximum distance from earth (kpc) */
  REAL4         fLower = 0;          /* default value for th lower cut off frequency */
/* REAL4         Rcore = 0.0; */
  UINT4         ddistr = 0, mdistr=0;

  /* program variables */
  RandomParams *randParams = NULL;
  REAL4  u, exponent, d2;
  REAL4  deltaM, mtotal;


  /* waveform */
  CHAR waveform[LIGOMETA_WAVEFORM_MAX];

#if 0
  int i, stat;

  double d, cosphi, sinphi;
#endif

/*  GalacticInspiralParamStruc galacticPar; */

  /* xml output data */
  CHAR                  fname[256];
  MetadataTable         proctable;
  MetadataTable         procparams;
  MetadataTable         injections;
  ProcessParamsTable   *this_proc_param;
  SimInspiralTable     *this_inj = NULL;
  LIGOLwXMLStream       xmlfp;
  UINT4                 outCompress = 0;

  /* getopt arguments */
  struct option long_options[] =
  {
    {"help",                    no_argument,       0,                'h'},
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"write-compress",          no_argument,       &outCompress,      1 },
    {"version",                 no_argument,       0,                'V'},
    {"f-lower",                        required_argument, 0,                'f'},
    {"gps-start-time",          required_argument, 0,                'a'},
    {"gps-end-time",            required_argument, 0,                'b'},
    {"time-step",               required_argument, 0,                't'},
    {"time-interval",           required_argument, 0,                'i'},
    {"seed",                    required_argument, 0,                's'},
    {"min-mass",                required_argument, 0,                'A'},
    {"max-mass",                required_argument, 0,                'B'},
    {"max-total-mass",          required_argument, 0,                'x'},
    {"min-distance",            required_argument, 0,                'p'},
    {"max-distance",            required_argument, 0,                'r'},
    {"d-distr",                 required_argument, 0,                'd'},
    {"m-distr",                 required_argument, 0,                'm'},
    {"waveform",                required_argument, 0,                'w'},
    {"user-tag",                required_argument, 0,                'Z'},
    {"userTag",                 required_argument, 0,                'Z'},
    {0, 0, 0, 0}
  };
  int c;

  /* set up inital debugging values */
  lal_errhandler = LAL_ERR_EXIT;


  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) 
    calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  if (strcmp(CVS_REVISION,"$Revi" "sion$"))
    {
      XLALPopulateProcessTable(proctable.processTable,
          PROGRAM_NAME, CVS_REVISION, CVS_SOURCE, CVS_DATE, 0);
    }
  else
    {
      XLALPopulateProcessTable(proctable.processTable,
          PROGRAM_NAME, lalappsGitCommitID,
          lalappsGitGitStatus,
          lalappsGitCommitDate, 0);
    }
  snprintf( proctable.processTable->comment, LIGOMETA_COMMENT_MAX, " " );
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) 
    calloc( 1, sizeof(ProcessParamsTable) );

  /* clear the waveform field */
  memset( waveform, 0, LIGOMETA_WAVEFORM_MAX * sizeof(CHAR) );
  

  /*
   *
   * parse command line arguments
   *
   */

     
  while ( 1 )
  {
    /* getopt_long stores long option here */
    int option_index = 0;
    long int gpsinput;
    size_t optarg_len;

    c = getopt_long_only( argc, argv, 
        "a:A:b:B:d:f:hi:m:p:q:r:s:t:vZ:w:", long_options, &option_index );

    /* detect the end of the options */
    if ( c == - 1 )
    {
      break;
    }

    switch ( c )
    {
      case 0:
        /* if this option set a flag, do nothing else now */
        if ( long_options[option_index].flag != 0 )
        {
          break;
        }
        else
        {
          fprintf( stderr, "error parsing option %s with argument %s\n",
              long_options[option_index].name, optarg );
          exit( 1 );
        }
        break;

      case 'a':
        gpsinput = atol( optarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsStartTime.gpsSeconds = gpsinput;

        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 'b':
        gpsinput = atol( optarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsEndTime.gpsSeconds = gpsinput;
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 'f':
        fLower = atof( optarg );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "float", 
              "%f", fLower );
        break;

      case 's':
        randSeed = atoi( optarg );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%d", randSeed );
        break;

      case 't':
        meanTimeStep = (REAL8) atof( optarg );
        if ( meanTimeStep <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time step must be > 0: (%e seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "float", 
              "%e", meanTimeStep );
        break;

      case 'i':
        timeInterval = atof( optarg );
        if ( timeInterval < 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time interval must be >= 0: (%e seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", timeInterval );
        break;

      case 'A':
        /* minimum component mass */
        minMass = (REAL4) atof( optarg );
        if ( minMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "miniumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, minMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", minMass );
        break;

      case 'B':
        /* maximum component mass */
        maxMass = (REAL4) atof( optarg );
        if ( maxMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "maxiumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, maxMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", maxMass );
        break;

    case 'x':
      /* maximum sum of components */
      sumMaxMass = (REAL4) atof( optarg );
      if ( sumMaxMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "sum of two component masses must be > 0: "
                   "(%f solar masses specified)\n",
                   long_options[option_index].name, sumMaxMass );
          exit( 1 );
        }
      sumMaxMassUse=1;
        this_proc_param = this_proc_param->next =
          next_process_param( long_options[option_index].name,
                              "float", "%e", sumMaxMass );
        break;

      case 'p':
        /* minimum distance from earth */
        dmin = (REAL4) atof( optarg );
        if ( dmin <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "minimum distance must be > 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, dmin );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", dmin );
        break;

      case 'r':
        /* max distance from earth */
        dmax = (REAL4) atof( optarg );
        if ( dmax <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "maximum distance must be greater than 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, dmax );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", dmax );
        break;

      case 'd':
        ddistr = (UINT4) atoi( optarg );
        if ( ddistr != 0 && ddistr != 1 && ddistr != 2)
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "DDISTR must be either 0 or 1 or 2\n",
              long_options[option_index].name);
          exit(1);
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "int", "%d", ddistr );

        break;

      case 'm':
        mdistr = (UINT4) atoi( optarg );
        if ( mdistr != 0 && mdistr != 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "MDISTR must be either 0 or 1\n",
              long_options[option_index].name);
          exit(1);
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "int", "%d", mdistr );

  
        break;

      case 'Z':
        /* create storage for the usertag */
        optarg_len = strlen( optarg ) + 1;
        userTag = (CHAR *) calloc( optarg_len, sizeof(CHAR) );
        memcpy( userTag, optarg, optarg_len );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "string", "%s", optarg );
        break;

      case 'w':
        snprintf( waveform, LIGOMETA_WAVEFORM_MAX, "%s", optarg);
        this_proc_param = this_proc_param->next =
          next_process_param( long_options[option_index].name, "string",
              "%s", optarg);
        break;

      case 'V':
        /* print version information and exit */
        fprintf( stdout, "Binary Black Hole INJection generation routine\n" 
            "Duncan A Brown and Eirini Messaritaki\n"
            "CVS Version: " CVS_ID_STRING "\n"
            "CVS Tag: " CVS_NAME_STRING "\n" );
        fprintf( stdout, lalappsGitID );
        exit( 0 );
        break;
        
      case 'h':
      case '?':
        fprintf( stderr, USAGE );
        exit( 0 );
        break;

      default:
        fprintf( stderr, "unknown error while parsing options\n" );
        fprintf( stderr, USAGE );
        exit( 1 );
    }
  }

  if ( optind < argc )
  {
    fprintf( stderr, "extraneous command line arguments:\n" );
    while ( optind < argc )
    {
      fprintf ( stderr, "%s\n", argv[optind++] );
    }
    exit( 1 );
  }


  if ( !*waveform )
  {
    /* use EOBtwoPN as the default waveform */
    snprintf( waveform, LIGOMETA_WAVEFORM_MAX, "EOBtwoPN");
  }

  if ( !fLower )
  {
    fprintf( stderr, "--f-lower must be specified and non-zero\n" );
    exit( 1 );
  }

  /*
   *
   * initialization
   *
   */


  /* initialize the random number generator */
  LAL_CALL( LALCreateRandomParams( &status, &randParams, randSeed ), &status );

  /* mass range, per component */
  deltaM = maxMass - minMass;

  /* null out the head of the linked list */
  injections.simInspiralTable = NULL;

  /* create the output file name */
  if ( userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml.gz",
        randSeed, userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( userTag && !outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml",
        randSeed, userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( !userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml.gz",
        randSeed, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml",
        randSeed, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }


  /*
   *
   * loop over duration of desired output times
   *
   */


  while ( XLALGPSCmp( &gpsStartTime, &gpsEndTime ) < 0 )
  {

    /* rho, z and lGal are the galactocentric galactic axial coordinates */
    /* r and phi are the geocentric galactic spherical coordinates       */
#if 0
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.lGal = LAL_TWOPI * u;
    
    galacticPar.z = r * sinphi ;
    galacticPar.rho = 0.0 - Rcore * cos(galacticPar.lGal) +
      sqrt( r * r - galacticPar.z * galacticPar.z - 
      Rcore * Rcore * sin(galacticPar.lGal) * sin(galacticPar.lGal) );
#endif

#if 0
    if ( vrbflg ) fprintf( stdout, "%e %e %e %e %e\n", 
        galacticPar.m1, galacticPar.m2,
        galacticPar.rho * cos( galacticPar.lGal ),
        galacticPar.rho * sin( galacticPar.lGal ),
        galacticPar.z );
#endif

    /* create the sim_inspiral table */
    if ( injections.simInspiralTable )
    {
      this_inj = this_inj->next = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }
    else
    {
      injections.simInspiralTable = this_inj = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }

    /* set the geocentric end time of the injection */
    /* XXX CHECK XXX */
    this_inj->geocent_end_time = gpsStartTime;
    if ( timeInterval )
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      XLALGPSAdd( &(this_inj->geocent_end_time), u * timeInterval );
    }

    /* set gmst */
    this_inj->end_time_gmst = fmod(XLALGreenwichMeanSiderealTime(
        &this_inj->geocent_end_time), LAL_TWOPI) * 24.0 / LAL_TWOPI; /* hours */
    if( XLAL_IS_REAL8_FAIL_NAN(this_inj->end_time_gmst) )
    {
      fprintf(stderr, "XLALGreenwichMeanSiderealTime() failed\n");
      exit(1);
    }
    /* XXX END CHECK XXX */

    /* populate the sim_inspiral table */

    if (mdistr == 1)
    /* uniformly distributed mass1 and uniformly distributed mass2 */
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->mass1 = minMass + u * deltaM;
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->mass2 = minMass + u * deltaM;
      mtotal = this_inj->mass1 + this_inj->mass2 ;
      this_inj->eta = this_inj->mass1 * this_inj->mass2 / ( mtotal * mtotal );
      this_inj->mchirp = (this_inj->mass1 + this_inj->mass2) * 
        pow(this_inj->eta, 0.6);
    }
    else if (mdistr == 0)
    /*uniformly distributed total mass */
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status);
      mtotal = 2.0 * minMass + u * 2.0 *deltaM ;

      if (sumMaxMassUse==1) {
        while (mtotal > sumMaxMass) {
          LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status);
          mtotal = 2.0 * minMass + u * 2.0 *deltaM ;          
        }
      }

      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->mass1 = minMass + u * deltaM;
      this_inj->mass2 = mtotal - this_inj->mass1;

      while (this_inj->mass1 >= mtotal || 
          this_inj->mass2 >= maxMass || this_inj->mass2 <= minMass )
      {
        LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
        this_inj->mass1 = minMass + u * deltaM;
        this_inj->mass2 = mtotal - this_inj->mass1;
      }
      this_inj->eta = this_inj->mass1 * this_inj->mass2 / ( mtotal * mtotal );
      this_inj->mchirp = (this_inj->mass1 + this_inj->mass2) * 
        pow(this_inj->eta, 0.6);

    }

     /* spatial distribution */

#if 0
     LAL_CALL( LALUniformDeviate( &status, &u, randParams ),
            &status );
     sinphi = 2.0 * u - 1.0;
     cosphi = sqrt( 1.0 - sinphi*sinphi );
#endif

     if (ddistr == 0)
     /* uniform distribution in distance */
     {
       REAL4 deltaD = dmax - dmin ;
       LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
       this_inj->distance = dmin + deltaD * u ;
      }
      else if (ddistr == 1)
      /* uniform distribution in log(distance) */
      {
        REAL4 lmin = log10(dmin);
        REAL4 lmax = log10(dmax);
        REAL4 deltaL = lmax - lmin;
        LAL_CALL(  LALUniformDeviate(&status,&u,randParams),&status );
        exponent = lmin + deltaL * u;
        this_inj->distance = pow(10.0,(REAL4) exponent);
      }
     else if (ddistr == 2)
     /* uniform volume distribution */
     {
       REAL4 d2min = pow(dmin,3.0) ;
       REAL4 d2max = pow(dmax,3.0) ;
       REAL4 deltad2 = d2max - d2min ;
       LAL_CALL(  LALUniformDeviate(&status,&u,randParams),&status );
       d2 = d2min + u * deltad2 ;
       this_inj->distance = pow(d2,1.0/3.0);
     }

     this_inj->distance = this_inj->distance / 1000.0; /*convert to Mpc */
       

      /* compute random longitude and latitude */
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->latitude = asin( 2.0 * u - 1.0 ) ;
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->longitude = LAL_TWOPI * u ;
     

#if 0
    LAL_CALL( LALGalacticInspiralParamsToSimInspiralTable( &status,
          this_inj, &galacticPar, randParams ), &status );
    if (vrbflg)
    { 
      fprintf( stdout, "%e\n",
      sqrt(galacticPar.z*galacticPar.z+galacticPar.rho*galacticPar.rho
          + Rcore*Rcore + 2.0*Rcore*galacticPar.rho*cos(galacticPar.lGal))-
      this_inj->distance*1000.0);
    }
#endif


    /* set the source and waveform fields */
    snprintf( this_inj->source, LIGOMETA_SOURCE_MAX, "???" );
    memcpy( this_inj->waveform, waveform, LIGOMETA_WAVEFORM_MAX *
        sizeof(CHAR));

    /* XXX CHECK XXX */
    /* compute random inclination, polarization and coalescence phase */
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    this_inj->inclination = acos( 2.0 * u - 1.0 );
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    this_inj->polarization = LAL_TWOPI * u ;
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    this_inj->coa_phase = LAL_TWOPI * u ;
    
    /* populate the site specific information */
    LAL_CALL(LALPopulateSimInspiralSiteInfo( &status, this_inj ), 
        &status);
    
    /* increment the injection time */
    XLALGPSAdd( &gpsStartTime, meanTimeStep );

    /* finally populate the flower */
    if (fLower > 0)         
    {
        this_inj->f_lower = fLower;
    }
    else
    {
        this_inj->f_lower = 0;
    }
    /* XXX END CHECK XXX */

  } /* end loop over injection times */

  /* destroy random parameters */
  LAL_CALL( LALDestroyRandomParams( &status, &randParams ), &status );


  /*
   *
   * write output to LIGO_LW XML file
   *
   */


  /* open the xml file */
  memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
  LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlfp, fname ), &status );

  /* write the process table */
  snprintf( proctable.processTable->ifos, LIGOMETA_IFOS_MAX, "H1H2L1" );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_table ), 
      &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, proctable, 
        process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  free( proctable.processTable );

  /* free the unused process param entry */
  this_proc_param = procparams.processParamsTable;
  procparams.processParamsTable = procparams.processParamsTable->next;
  free( this_proc_param );

  /* write the process params table */
  if ( procparams.processParamsTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_params_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, procparams, 
          process_params_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
    while( procparams.processParamsTable )
    {
      this_proc_param = procparams.processParamsTable;
      procparams.processParamsTable = this_proc_param->next;
      free( this_proc_param );
    }
  }

  /* write the sim_inspiral table */
  if ( injections.simInspiralTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, sim_inspiral_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, injections, 
          sim_inspiral_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  }
  while ( injections.simInspiralTable )
  {
    this_inj = injections.simInspiralTable;
    injections.simInspiralTable = injections.simInspiralTable->next;
    LALFree( this_inj );
  }

  /* close the injection file */
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlfp ), &status );

  /* check for memory leaks and exit */
  LALCheckMemoryLeaks();
  return 0;
}
示例#2
0
int main( void )
{
  static LALStatus      status;
  static INT4TimeSeries series;
  const UINT4   duration = 60;      /* duration of frame file */
  const INT4    seed = 10;          /* random number seed     */
  const REAL4   rate = 16384;       /* sample rate (Hz)       */
  const UINT4   npts = duration * rate; /* number of points       */
  FrOutPar      opar = { "F", "TEST", ADCDataChannel, 6, 0, 0 };
  RandomParams *rpar = NULL;
  UINT4 count = 0;
  UINT4 i;

  /* initialize */

  LALCreateRandomParams( &status, &rpar, seed );
  TESTSTATUS( &status );

  strncpy( series.name, CHANNEL, sizeof( series.name ) );
  series.epoch.gpsSeconds = 600000000;
  series.sampleUnits = lalADCCountUnit;
  series.deltaT = 1 / rate;
  LALI4CreateVector( &status, &series.data, npts );
  TESTSTATUS( &status );

  /* generate first frame file worth of data and write it */

  /*
  LALNormalDeviates( &status, series.data, rpar );
  TESTSTATUS( &status );
  */
  for ( i = 0; i < series.data->length; ++i )
  {
    INT8 ns;
    ns  = (INT8)1000000000 * (INT8)series.epoch.gpsSeconds;
    ns += (INT8)series.epoch.gpsNanoSeconds;
    ns += (INT8)( 1e9 * i * series.deltaT );
    ns %= (INT8)1000000000;
    series.data->data[i] = count++;
  }

  LALFrWriteINT4TimeSeries( &status, &series, &opar );
  TESTSTATUS( &status );

  /* generate second frame file worth of data and write it */

  series.epoch.gpsSeconds += duration;
  /*
  LALNormalDeviates( &status, series.data, rpar );
  TESTSTATUS( &status );
  */
  for ( i = 0; i < series.data->length; ++i )
  {
    INT8 ns;
    ns  = (INT8)1000000000 * (INT8)series.epoch.gpsSeconds;
    ns += (INT8)series.epoch.gpsNanoSeconds;
    ns += (INT8)( 1e9 * i * series.deltaT );
    ns %= (INT8)1000000000;
    series.data->data[i] = count++;
  }

  LALFrWriteINT4TimeSeries( &status, &series, &opar );
  TESTSTATUS( &status );

  /* generate third frame file worth of data and write it */

  series.epoch.gpsSeconds += duration;
  /*
  LALNormalDeviates( &status, series.data, rpar );
  TESTSTATUS( &status );
  */
  for ( i = 0; i < series.data->length; ++i )
  {
    INT8 ns;
    ns  = (INT8)1000000000 * (INT8)series.epoch.gpsSeconds;
    ns += (INT8)series.epoch.gpsNanoSeconds;
    ns += (INT8)( 1e9 * i * series.deltaT );
    ns %= (INT8)1000000000;
    series.data->data[i] = count++;
  }

  LALFrWriteINT4TimeSeries( &status, &series, &opar );
  TESTSTATUS( &status );

  //if ( XLALFrWriteINT4TimeSeries( &series, 7 ) < 0 )
    //return 1;

  /* cleanup */

  LALI4DestroyVector( &status, &series.data );
  TESTSTATUS( &status );

  LALDestroyRandomParams( &status, &rpar );
  TESTSTATUS( &status );

  LALCheckMemoryLeaks();
  return 0;
}
示例#3
0
/*============================================================
 * FUNCTION definitions
 *============================================================*/
int
main(int argc, char *argv[])
{
  static LALStatus       status;  /* LALStatus pointer */
  UserVariables_t XLAL_INIT_DECL(uvar);
  ConfigVariables_t XLAL_INIT_DECL(cfg);

  UINT4 k, numBins, numIFOs, maxNumSFTs, X, alpha;
  REAL8 Freq0, dFreq, normPSD;
  UINT4 finalBinSize, finalBinStep, finalNumBins;

  REAL8Vector *overSFTs = NULL; /* one frequency bin over SFTs */
  REAL8Vector *overIFOs = NULL; /* one frequency bin over IFOs */
  REAL8Vector *finalPSD = NULL; /* math. operation PSD over SFTs and IFOs */
  REAL8Vector *finalNormSFT = NULL; /* normalised SFT power */

  vrbflg = 1;	/* verbose error-messages */

  /* set LAL error-handler */
  lal_errhandler = LAL_ERR_EXIT;

  /* register and read user variables */
  if (initUserVars(argc, argv, &uvar) != XLAL_SUCCESS)
    return EXIT_FAILURE;

  MultiSFTVector *inputSFTs = NULL;
  if ( ( inputSFTs = XLALReadSFTs ( &cfg, &uvar ) ) == NULL )
    {
      XLALPrintError ("Call to XLALReadSFTs() failed with xlalErrno = %d\n", xlalErrno );
      return EXIT_FAILURE;
    }

  /* clean sfts if required */
  if ( XLALUserVarWasSet( &uvar.linefiles ) )
    {
      RandomParams *randPar=NULL;
      FILE *fpRand=NULL;
      INT4 seed, ranCount;

      if ( (fpRand = fopen("/dev/urandom", "r")) == NULL ) {
	fprintf(stderr,"Error in opening /dev/urandom" );
	return EXIT_FAILURE;
      }

      if ( (ranCount = fread(&seed, sizeof(seed), 1, fpRand)) != 1 ) {
	fprintf(stderr,"Error in getting random seed" );
	return EXIT_FAILURE;
      }

      LAL_CALL ( LALCreateRandomParams (&status, &randPar, seed), &status );

      LAL_CALL( LALRemoveKnownLinesInMultiSFTVector ( &status, inputSFTs, uvar.maxBinsClean, uvar.blocksRngMed, uvar.linefiles, randPar), &status);
      LAL_CALL ( LALDestroyRandomParams (&status, &randPar), &status);
      fclose(fpRand);
    } /* end cleaning */

  LogPrintf (LOG_DEBUG, "Computing spectrogram and PSD ... ");

  /* get power running-median rngmed[ |data|^2 ] from SFTs */
  MultiPSDVector *multiPSD = NULL;
  XLAL_CHECK_MAIN( ( multiPSD = XLALNormalizeMultiSFTVect ( inputSFTs, uvar.blocksRngMed, NULL ) ) != NULL, XLAL_EFUNC);
  /* restrict this PSD to just the "physical" band if requested using {--Freq, --FreqBand} */
  if ( ( XLALCropMultiPSDandSFTVectors ( multiPSD, inputSFTs, cfg.firstBin, cfg.lastBin )) != XLAL_SUCCESS ) {
    XLALPrintError ("%s: XLALCropMultiPSDandSFTVectors (inputPSD, inputSFTs, %d, %d) failed with xlalErrno = %d\n", __func__, cfg.firstBin, cfg.lastBin, xlalErrno );
    return EXIT_FAILURE;
  }

  /* start frequency and frequency spacing */
  Freq0 = multiPSD->data[0]->data[0].f0;
  dFreq = multiPSD->data[0]->data[0].deltaF;

  /* number of raw bins in final PSD */
  numBins = multiPSD->data[0]->data[0].data->length;
  if ( (finalPSD = XLALCreateREAL8Vector ( numBins )) == NULL ) {
    LogPrintf (LOG_CRITICAL, "Out of memory!\n");
    return EXIT_FAILURE;
  }

  /* number of IFOs */
  numIFOs = multiPSD->length;
  if ( (overIFOs = XLALCreateREAL8Vector ( numIFOs )) == NULL ) {
    LogPrintf (LOG_CRITICAL, "Out of memory!\n");
    return EXIT_FAILURE;
  }

  /* maximum number of SFTs */
  maxNumSFTs = 0;
  for (X = 0; X < numIFOs; ++X) {
    maxNumSFTs = GSL_MAX(maxNumSFTs, multiPSD->data[X]->length);
  }
  if ( (overSFTs = XLALCreateREAL8Vector ( maxNumSFTs )) == NULL ) {
    LogPrintf (LOG_CRITICAL, "Out of memory!\n");
    return EXIT_FAILURE;
  }

  /* normalize rngmd(power) to get proper *single-sided* PSD: Sn = (2/Tsft) rngmed[|data|^2]] */
  normPSD = 2.0 * dFreq;

  /* loop over frequency bins in final PSD */
  for (k = 0; k < numBins; ++k) {

    /* loop over IFOs */
    for (X = 0; X < numIFOs; ++X) {

      /* number of SFTs for this IFO */
      UINT4 numSFTs = multiPSD->data[X]->length;

      /* copy PSD frequency bins and normalise multiPSD for later use */
      for (alpha = 0; alpha < numSFTs; ++alpha) {
	multiPSD->data[X]->data[alpha].data->data[k] *= normPSD;
	overSFTs->data[alpha] = multiPSD->data[X]->data[alpha].data->data[k];
      }

      /* compute math. operation over SFTs for this IFO */
      overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.PSDmthopSFTs);
      if ( isnan( overIFOs->data[X] ) )
        XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X );

    } /* for IFOs X */

    /* compute math. operation over IFOs for this frequency */
    finalPSD->data[k] = math_op(overIFOs->data, numIFOs, uvar.PSDmthopIFOs);
    if ( isnan ( finalPSD->data[k] ) )
      XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in finalPSD->data[k=%d] = NAN ... exiting\n", k );

  } /* for freq bins k */
  LogPrintfVerbatim ( LOG_DEBUG, "done.\n");

  /* compute normalised SFT power */
  if (uvar.outputNormSFT) {
    LogPrintf (LOG_DEBUG, "Computing normalised SFT power ... ");

    if ( (finalNormSFT = XLALCreateREAL8Vector ( numBins )) == NULL ) {
      LogPrintf (LOG_CRITICAL, "Out of memory!\n");
      return EXIT_FAILURE;
    }

    /* loop over frequency bins in SFTs */
    for (k = 0; k < numBins; ++k) {

      /* loop over IFOs */
      for (X = 0; X < numIFOs; ++X) {

	/* number of SFTs for this IFO */
	UINT4 numSFTs = inputSFTs->data[X]->length;

	/* compute SFT power */
	for (alpha = 0; alpha < numSFTs; ++alpha) {
	  COMPLEX8 bin = inputSFTs->data[X]->data[alpha].data->data[k];
	  overSFTs->data[alpha] = crealf(bin)*crealf(bin) + cimagf(bin)*cimagf(bin);
	}

	/* compute math. operation over SFTs for this IFO */
	overIFOs->data[X] = math_op(overSFTs->data, numSFTs, uvar.nSFTmthopSFTs);
	if ( isnan ( overIFOs->data[X] ))
          XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in overIFOs->data[X=%d] = NAN ... exiting\n", X );

      } /* over IFOs */

      /* compute math. operation over IFOs for this frequency */
      finalNormSFT->data[k] = math_op(overIFOs->data, numIFOs, uvar.nSFTmthopIFOs);
      if ( isnan( finalNormSFT->data[k] ) )
        XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in bin finalNormSFT->data[k=%d] = NAN ... exiting\n", k );

    } /* over freq bins */
    LogPrintfVerbatim ( LOG_DEBUG, "done.\n");
  }

  /* output spectrograms */
  if ( uvar.outputSpectBname ) {
    LAL_CALL ( LALfwriteSpectrograms ( &status, uvar.outputSpectBname, multiPSD ), &status );
  }

  /* ---------- if user requested it, output complete MultiPSDVector over IFOs X, timestamps and freq-bins into ASCI file(s) */
  if ( uvar.dumpMultiPSDVector ) {
    if ( XLALDumpMultiPSDVector ( uvar.outputPSD, multiPSD ) != XLAL_SUCCESS ) {
      XLALPrintError ("%s: XLALDumpMultiPSDVector() failed, xlalErrnor = %d\n", __func__, xlalErrno );
      return EXIT_FAILURE;
    }
  } /* if uvar.dumpMultiPSDVector */

  /* ----- if requested, compute data-quality factor 'Q' -------------------- */
  if ( uvar.outputQ )
    {
      REAL8FrequencySeries *Q;
      if ( (Q = XLALComputeSegmentDataQ ( multiPSD, cfg.dataSegment )) == NULL ) {
        XLALPrintError ("%s: XLALComputeSegmentDataQ() failed with xlalErrno = %d\n", __func__, xlalErrno );
        return EXIT_FAILURE;
      }
      if ( XLAL_SUCCESS != XLALWriteREAL8FrequencySeries_to_file ( Q, uvar.outputQ ) ) {
        return EXIT_FAILURE;
      }
      XLALDestroyREAL8FrequencySeries ( Q );
    } /* if outputQ */

  /* ---------- BINNING if requested ---------- */
  /* work out bin size */
  if (XLALUserVarWasSet(&uvar.binSize)) {
    finalBinSize = uvar.binSize;
  }
  else if (XLALUserVarWasSet(&uvar.binSizeHz)) {
    finalBinSize = (UINT4)floor(uvar.binSizeHz / dFreq + 0.5); /* round to nearest bin */
  }
  else {
    finalBinSize = 1;
  }

  /* work out bin step */
  if (XLALUserVarWasSet(&uvar.binStep)) {
    finalBinStep = uvar.binStep;
  }
  else if (XLALUserVarWasSet(&uvar.binStepHz)) {
    finalBinStep = (UINT4)floor(uvar.binStepHz / dFreq + 0.5); /* round to nearest bin */
  }
  else {
    finalBinStep = finalBinSize;
  }

  /* work out total number of bins */
  finalNumBins = (UINT4)floor((numBins - finalBinSize) / finalBinStep) + 1;

  /* write final PSD to file */
  if (XLALUserVarWasSet(&uvar.outputPSD)) {

    FILE *fpOut = NULL;

    if ((fpOut = fopen(uvar.outputPSD, "wb")) == NULL) {
      LogPrintf ( LOG_CRITICAL, "Unable to open output file %s for writing...exiting \n", uvar.outputPSD );
      return EXIT_FAILURE;
    }

    /* write header info in comments */
    if ( XLAL_SUCCESS != XLALOutputVersionString ( fpOut, 0 ) )
      XLAL_ERROR ( XLAL_EFUNC );

    /* write the command-line */
    for (int a = 0; a < argc; a++)
      fprintf(fpOut,"%%%% argv[%d]: '%s'\n", a, argv[a]);

    /* write column headings */
    fprintf(fpOut,"%%%% columns:\n%%%% FreqBinStart");
    if (uvar.outFreqBinEnd)
      fprintf(fpOut," FreqBinEnd");
    fprintf(fpOut," PSD");
    if (uvar.outputNormSFT)
      fprintf(fpOut," normSFTpower");
    fprintf(fpOut,"\n");

    LogPrintf(LOG_DEBUG, "Printing PSD to file ... ");
    for (k = 0; k < finalNumBins; ++k) {
      UINT4 b = k * finalBinStep;

      REAL8 f0 = Freq0 + b * dFreq;
      REAL8 f1 = f0 + finalBinStep * dFreq;
      fprintf(fpOut, "%f", f0);
      if (uvar.outFreqBinEnd)
	fprintf(fpOut, "   %f", f1);

      REAL8 psd = math_op(&(finalPSD->data[b]), finalBinSize, uvar.PSDmthopBins);
      if ( isnan ( psd ))
        XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in psd[k=%d] = NAN ... exiting\n", k );

      fprintf(fpOut, "   %e", psd);

      if (uvar.outputNormSFT) {
	REAL8 nsft = math_op(&(finalNormSFT->data[b]), finalBinSize, uvar.nSFTmthopBins);
	if ( isnan ( nsft ))
          XLAL_ERROR ( EXIT_FAILURE, "Found Not-A-Number in nsft[k=%d] = NAN ... exiting\n", k );

	fprintf(fpOut, "   %f", nsft);
      }

      fprintf(fpOut, "\n");
    } // k < finalNumBins
    LogPrintfVerbatim ( LOG_DEBUG, "done.\n");

    fclose(fpOut);

  }

  /* we are now done with the psd */
  XLALDestroyMultiPSDVector  ( multiPSD);
  XLALDestroyMultiSFTVector  ( inputSFTs);

  XLALDestroyUserVars();

  XLALDestroyREAL8Vector ( overSFTs );
  XLALDestroyREAL8Vector ( overIFOs );
  XLALDestroyREAL8Vector ( finalPSD );
  XLALDestroyREAL8Vector ( finalNormSFT );

  LALCheckMemoryLeaks();

  return EXIT_SUCCESS;

} /* main() */
示例#4
0
int
main(int argc, char **argv)
{
  /* Command-line parsing variables. */
  int arg;                   /* command-line argument counter */
  static LALStatus stat;     /* status structure */
  CHAR *sourcefile = NULL;   /* name of sourcefile */
  CHAR *respfile = NULL;     /* name of respfile */
  CHAR *infile = NULL;       /* name of infile */
  CHAR *outfile = NULL;      /* name of outfile */
  INT4 seed = 0;             /* random number seed */
  INT4 sec = SEC;            /* ouput epoch.gpsSeconds */
  INT4 nsec = NSEC;          /* ouput epoch.gpsNanoSeconds */
  INT4 npt = NPT;            /* number of output points */
  REAL8 dt = DT;             /* output sampling interval */
  REAL4 sigma = SIGMA;       /* noise amplitude */

  /* File reading variables. */
  FILE *fp = NULL; /* generic file pointer */
  BOOLEAN ok = 1;  /* whether input format is correct */
  UINT4 i;         /* generic index over file lines */
  INT8 epoch;      /* epoch stored as an INT8 */

  /* Other global variables. */
  RandomParams *params = NULL; /* parameters of pseudorandom sequence */
  DetectorResponse detector;   /* the detector in question */
  INT2TimeSeries output;       /* detector ACD output */


  /*******************************************************************
   * PARSE ARGUMENTS (arg stores the current position)               *
   *******************************************************************/

  /* Exit gracefully if no arguments were given.
  if ( argc <= 1 ) {
    INFO( "No testing done." );
    return 0;
  } */

  arg = 1;
  while ( arg < argc ) {
    /* Parse source file option. */
    if ( !strcmp( argv[arg], "-s" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	sourcefile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse response file option. */
    else if ( !strcmp( argv[arg], "-r" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	respfile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse input file option. */
    else if ( !strcmp( argv[arg], "-i" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	infile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse noise output option. */
    else if ( !strcmp( argv[arg], "-n" ) ) {
      if ( argc > arg + 5 ) {
	arg++;
	sec = atoi( argv[arg++] );
	nsec = atoi( argv[arg++] );
	npt = atoi( argv[arg++] );
	dt = atof( argv[arg++] );
	sigma = atof( argv[arg++] );
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse output file option. */
    else if ( !strcmp( argv[arg], "-o" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	outfile = argv[arg++];
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse debug level option. */
    else if ( !strcmp( argv[arg], "-d" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Parse random seed option. */
    else if ( !strcmp( argv[arg], "-e" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	seed = atoi( argv[arg++] );
      }else{
	ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return BASICINJECTTESTC_EARG;
      }
    }
    /* Check for unrecognized options. */
    else if ( argv[arg][0] == '-' ) {
      ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
      LALPrintError( USAGE, *argv );
      return BASICINJECTTESTC_EARG;
    }
  } /* End of argument parsing loop. */

  /* Check for redundant or bad argument values. */
  CHECKVAL( npt, 0, 2147483647 );
  CHECKVAL( dt, 0, LAL_REAL4_MAX );


  /*******************************************************************
   * SETUP                                                           *
   *******************************************************************/

  /* Set up output, detector, and random parameter structures. */
  output.data = NULL;
  detector.transfer = (COMPLEX8FrequencySeries *)
    LALMalloc( sizeof(COMPLEX8FrequencySeries) );
  if ( !(detector.transfer) ) {
    ERROR( BASICINJECTTESTC_EMEM, BASICINJECTTESTC_MSGEMEM, 0 );
    return BASICINJECTTESTC_EMEM;
  }
  detector.transfer->data = NULL;
  detector.site = NULL;
  SUB( LALCreateRandomParams( &stat, &params, seed ), &stat );

  /* Set up units. */
  output.sampleUnits = lalADCCountUnit;
  if (XLALUnitDivide( &(detector.transfer->sampleUnits),
                      &lalADCCountUnit, &lalStrainUnit ) == NULL) {
    return LAL_EXLAL;
  }

  /* Read response function. */
  if ( respfile ) {
    REAL4VectorSequence *resp = NULL; /* response as vector sequence */
    COMPLEX8Vector *response = NULL;  /* response as complex vector */
    COMPLEX8Vector *unity = NULL;     /* vector of complex 1's */

    if ( ( fp = fopen( respfile, "r" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     respfile );
      return BASICINJECTTESTC_EFILE;
    }

    /* Read header. */
    ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 );
    I8ToLIGOTimeGPS( &( detector.transfer->epoch ), epoch );
    ok &= ( fscanf( fp, "# f0 = %lf\n", &( detector.transfer->f0 ) )
	    == 1 );
    ok &= ( fscanf( fp, "# deltaF = %lf\n",
		    &( detector.transfer->deltaF ) ) == 1 );
    if ( !ok ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     respfile );
      return BASICINJECTTESTC_EINPUT;
    }

    /* Read and convert body to a COMPLEX8Vector. */
    SUB( LALSReadVectorSequence( &stat, &resp, fp ), &stat );
    fclose( fp );
    if ( resp->vectorLength != 2 ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     respfile );
      return BASICINJECTTESTC_EINPUT;
    }
    SUB( LALCCreateVector( &stat, &response, resp->length ), &stat );
    memcpy( response->data, resp->data, 2*resp->length*sizeof(REAL4) );
    SUB( LALSDestroyVectorSequence( &stat, &resp ), &stat );

    /* Convert response function to a transfer function. */
    SUB( LALCCreateVector( &stat, &unity, response->length ), &stat );
    for ( i = 0; i < response->length; i++ ) {
      unity->data[i] = 1.0;
    }
    SUB( LALCCreateVector( &stat, &( detector.transfer->data ),
			   response->length ), &stat );
    SUB( LALCCVectorDivide( &stat, detector.transfer->data, unity,
			    response ), &stat );
    SUB( LALCDestroyVector( &stat, &response ), &stat );
    SUB( LALCDestroyVector( &stat, &unity ), &stat );
  }

  /* No response file, so generate a unit response. */
  else {
    I8ToLIGOTimeGPS( &( detector.transfer->epoch ), EPOCH );
    detector.transfer->f0 = 0.0;
    detector.transfer->deltaF = 1.5*FSTOP;
    SUB( LALCCreateVector( &stat, &( detector.transfer->data ), 2 ),
	 &stat );
    detector.transfer->data->data[0] = 1.0;
    detector.transfer->data->data[1] = 1.0;
  }


  /* Read input data. */
  if ( infile ) {
    REAL4VectorSequence *input = NULL; /* input as vector sequence */
    if ( ( fp = fopen( infile, "r" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     infile );
      return BASICINJECTTESTC_EFILE;
    }

    /* Read header. */
    ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 );
    I8ToLIGOTimeGPS( &( output.epoch ), epoch );
    ok &= ( fscanf( fp, "# deltaT = %lf\n", &( output.deltaT ) )
	    == 1 );
    if ( !ok ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     infile );
      return BASICINJECTTESTC_EINPUT;
    }

    /* Read and convert body. */
    SUB( LALSReadVectorSequence( &stat, &input, fp ), &stat );
    fclose( fp );
    if ( input->vectorLength != 1 ) {
      ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
	     infile );
      return BASICINJECTTESTC_EINPUT;
    }
    SUB( LALI2CreateVector( &stat, &( output.data ), input->length ),
	 &stat );
    for ( i = 0; i < input->length; i++ )
      output.data->data[i] = (INT2)( input->data[i] );
    SUB( LALSDestroyVectorSequence( &stat, &input ), &stat );
  }

  /* No input file, so generate one randomly. */
  else {
    output.epoch.gpsSeconds = sec;
    output.epoch.gpsNanoSeconds = nsec;
    output.deltaT = dt;
    SUB( LALI2CreateVector( &stat, &( output.data ), npt ), &stat );
    if ( sigma == 0 ) {
      memset( output.data->data, 0, npt*sizeof(INT2) );
    } else {
      REAL4Vector *deviates = NULL; /* unit Gaussian deviates */
      SUB( LALSCreateVector( &stat, &deviates, npt ), &stat );
      SUB( LALNormalDeviates( &stat, deviates, params ), &stat );
      for ( i = 0; i < (UINT4)( npt ); i++ )
	output.data->data[i] = (INT2)
	  floor( sigma*deviates->data[i] + 0.5 );
      SUB( LALSDestroyVector( &stat, &deviates ), &stat );
    }
  }


  /*******************************************************************
   * INJECTION                                                       *
   *******************************************************************/

  /* Open sourcefile. */
  if ( sourcefile ) {
    if ( ( fp = fopen( sourcefile, "r" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     sourcefile );
      return BASICINJECTTESTC_EFILE;
    }
  }

  /* For each line in the sourcefile... */
  while ( ok ) {
    PPNParamStruc ppnParams;       /* wave generation parameters */
    REAL4 m1, m2, dist, inc, phic; /* unconverted parameters */
    CoherentGW waveform;           /* amplitude and phase structure */
    REAL4TimeSeries signalvec;     /* GW signal */
    REAL8 time;                    /* length of GW signal */
    CHAR timeCode;                 /* code for signal time alignment */
    CHAR message[MSGLEN];          /* warning/info messages */

    /* Read and convert input line. */
    if ( sourcefile ) {
      ok &= ( fscanf( fp, "%c %" LAL_INT8_FORMAT " %f %f %f %f %f\n", &timeCode,
		      &epoch, &m1, &m2, &dist, &inc, &phic ) == 7 );
      ppnParams.mTot = m1 + m2;
      ppnParams.eta = m1*m2/( ppnParams.mTot*ppnParams.mTot );
      ppnParams.d = dist*LAL_PC_SI*1000.0;
      ppnParams.inc = inc*LAL_PI/180.0;
      ppnParams.phi = phic*LAL_PI/180.0;
    } else {
      timeCode = 'i';
      ppnParams.mTot = M1 + M2;
      ppnParams.eta = M1*M2/( ppnParams.mTot*ppnParams.mTot );
      ppnParams.d = DIST;
      ppnParams.inc = INC;
      ppnParams.phi = PHIC;
      epoch = EPOCH;
    }

    if ( ok ) {
      /* Set up other parameter structures. */
      ppnParams.epoch.gpsSeconds = ppnParams.epoch.gpsNanoSeconds = 0;
      ppnParams.position.latitude = ppnParams.position.longitude = 0.0;
      ppnParams.position.system = COORDINATESYSTEM_EQUATORIAL;
      ppnParams.psi = 0.0;
      ppnParams.fStartIn = FSTART;
      ppnParams.fStopIn = FSTOP;
      ppnParams.lengthIn = 0;
      ppnParams.ppn = NULL;
      ppnParams.deltaT = DELTAT;
      memset( &waveform, 0, sizeof(CoherentGW) );

      /* Generate waveform at zero epoch. */
      SUB( LALGeneratePPNInspiral( &stat, &waveform, &ppnParams ),
	   &stat );
      snprintf( message, MSGLEN, "%d: %s", ppnParams.termCode,
		   ppnParams.termDescription );
      INFO( message );
      if ( ppnParams.dfdt > 2.0 ) {
	snprintf( message, MSGLEN,
		     "Waveform sampling interval is too large:\n"
		     "\tmaximum df*dt = %f", ppnParams.dfdt );
	WARNING( message );
      }

      /* Compute epoch for waveform. */
      time = waveform.a->data->length*DELTAT;
      if ( timeCode == 'f' )
	epoch -= (INT8)( 1000000000.0*time );
      else if ( timeCode == 'c' )
	epoch -= (INT8)( 1000000000.0*ppnParams.tc );
      I8ToLIGOTimeGPS( &( waveform.a->epoch ), epoch );
      waveform.f->epoch = waveform.phi->epoch = waveform.a->epoch;

      /* Generate and inject signal. */
      signalvec.epoch = waveform.a->epoch;
      signalvec.epoch.gpsSeconds -= 1;
      signalvec.deltaT = output.deltaT/4.0;
      signalvec.f0 = 0;
      signalvec.data = NULL;
      time = ( time + 2.0 )/signalvec.deltaT;
      SUB( LALSCreateVector( &stat, &( signalvec.data ), (UINT4)time ),
	   &stat );
      SUB( LALSimulateCoherentGW( &stat, &signalvec, &waveform,
				  &detector ), &stat );
      SUB( LALSI2InjectTimeSeries( &stat, &output, &signalvec, params ),
	   &stat );
      SUB( LALSDestroyVectorSequence( &stat, &( waveform.a->data ) ),
	   &stat );
      SUB( LALSDestroyVector( &stat, &( waveform.f->data ) ), &stat );
      SUB( LALDDestroyVector( &stat, &( waveform.phi->data ) ), &stat );
      LALFree( waveform.a );
      LALFree( waveform.f );
      LALFree( waveform.phi );
      SUB( LALSDestroyVector( &stat, &( signalvec.data ) ), &stat );
    }

    /* If there is no source file, inject only one source. */
    if ( !sourcefile )
      ok = 0;
  }

  /* Input file is exhausted (or has a badly-formatted line ). */
  if ( sourcefile )
    fclose( fp );


  /*******************************************************************
   * CLEANUP                                                         *
   *******************************************************************/

  /* Print output file. */
  if ( outfile ) {
    if ( ( fp = fopen( outfile, "w" ) ) == NULL ) {
      ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
	     outfile );
      return BASICINJECTTESTC_EFILE;
    }
    epoch = 1000000000LL*(INT8)( output.epoch.gpsSeconds );
    epoch += (INT8)( output.epoch.gpsNanoSeconds );
    fprintf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", epoch );
    fprintf( fp, "# deltaT = %23.16e\n", output.deltaT );
    for ( i = 0; i < output.data->length; i++ )
      fprintf( fp, "%8.1f\n", (REAL4)( output.data->data[i] ) );
    fclose( fp );
  }

  /* Destroy remaining memory. */
  SUB( LALDestroyRandomParams( &stat, &params ), &stat );
  SUB( LALI2DestroyVector( &stat, &( output.data ) ), &stat );
  SUB( LALCDestroyVector( &stat, &( detector.transfer->data ) ),
       &stat );
  LALFree( detector.transfer );

  /* Done! */
  LALCheckMemoryLeaks();
  INFO( BASICINJECTTESTC_MSGENORM );
  return BASICINJECTTESTC_ENORM;
}
int
main( int argc, char **argv )
{
  int arg;                      /* command-line argument counter */
  BOOLEAN xyz = 0;              /* whether -x, -y, or -z options were given */
  INT4 verbosity = 0;           /* verbosity level */
  REAL8 x_1 = 0.0, x_2 = 0.0, dx; /* range and increment in x */
  REAL8 y_1 = 0.0, y_2 = 0.0, dy; /* range and increment in y */
  REAL8 z_1 = 0.0, z_2 = 0.0, dz; /* range and increment in z */
  INT4 nx = 1, ny = 1, nz = 1;  /* number of steps in each direction */
  INT4 i, j, k;                 /* index in each direction */
  REAL8 x, y, z, ddx, ddy, ddz; /* position and error in each direction */
  REAL8 ddr, ddmax = 0.0;       /* overall and maximum position error */
  static LALStatus stat;        /* status structure */
  EarthPosition earth;          /* terrestrial coordinates */


  /*******************************************************************
   * PARSE ARGUMENTS (arg stores the current position)               *
   *******************************************************************/

  arg = 1;
  while ( arg < argc ) {

    /* Parse range options. */
    if ( !strcmp( argv[arg], "-x" ) ) {
      if ( argc > arg + 3 ) {
	arg++;
	xyz = 1;
	x_1 = atof( argv[arg++] );
	x_2 = atof( argv[arg++] );
	nx = atoi( argv[arg++] );
      } else {
	ERROR( GEOCENTRICGEODETICTESTC_EARG,
	       GEOCENTRICGEODETICTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return GEOCENTRICGEODETICTESTC_EARG;
      }
    } else if ( !strcmp( argv[arg], "-y" ) ) {
      if ( argc > arg + 3 ) {
	arg++;
	xyz = 1;
	y_1 = atof( argv[arg++] );
	y_2 = atof( argv[arg++] );
	ny = atoi( argv[arg++] );
      } else {
	ERROR( GEOCENTRICGEODETICTESTC_EARG,
	       GEOCENTRICGEODETICTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return GEOCENTRICGEODETICTESTC_EARG;
      }
    } else if ( !strcmp( argv[arg], "-z" ) ) {
      if ( argc > arg + 3 ) {
	arg++;
	xyz = 1;
	z_1 = atof( argv[arg++] );
	z_2 = atof( argv[arg++] );
	nz = atoi( argv[arg++] );
      } else {
	ERROR( GEOCENTRICGEODETICTESTC_EARG,
	       GEOCENTRICGEODETICTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return GEOCENTRICGEODETICTESTC_EARG;
      }
    }

    /* Parse verbosity option. */
    else if ( !strcmp( argv[arg], "-v" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	verbosity = atoi( argv[arg++] );
      } else {
	ERROR( GEOCENTRICGEODETICTESTC_EARG,
	       GEOCENTRICGEODETICTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return GEOCENTRICGEODETICTESTC_EARG;
      }
    }

    /* Parse debug level option. */
    else if ( !strcmp( argv[arg], "-d" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
      } else {
	ERROR( GEOCENTRICGEODETICTESTC_EARG,
	       GEOCENTRICGEODETICTESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return GEOCENTRICGEODETICTESTC_EARG;
      }
    }

    /* Check for unrecognized options. */
    else if ( argv[arg][0] == '-' ) {
      ERROR( GEOCENTRICGEODETICTESTC_EARG,
	     GEOCENTRICGEODETICTESTC_MSGEARG, 0 );
      LALPrintError( USAGE, *argv );
      return GEOCENTRICGEODETICTESTC_EARG;
    }
  } /* End of argument parsing loop. */

  /*******************************************************************
   * SET PARAMETERS                                                  *
   *******************************************************************/

  /* If none of -x, -y, -z were given, generate a random position. */
  if ( !xyz ) {
    REAL4 lon, coslat, sinlat, rad; /* polar coordinates */
    RandomParams *rparams = NULL;   /* pseudorandom sequence parameters */
    SUB( LALCreateRandomParams( &stat, &rparams, 0 ), &stat );
    SUB( LALUniformDeviate( &stat, &lon, rparams ), &stat );
    lon *= LAL_TWOPI;
    SUB( LALUniformDeviate( &stat, &sinlat, rparams ), &stat );
    coslat = sqrt( 1.0 - sinlat*sinlat );
    SUB( LALUniformDeviate( &stat, &rad, rparams ), &stat );
    rad = 1.5*rad + 0.5;
    x_1 = x_2 = rad*coslat*cos( lon );
    y_1 = y_2 = rad*coslat*sin( lon );
    z_1 = z_2 = rad*sinlat;
    SUB( LALDestroyRandomParams( &stat, &rparams ), &stat );
  }

  /* Compute stepsizes. */
  dx = dy = dz = 0.0;
  if ( nx > 1 )
    dx = ( x_2 - x_1 )/( nx - 1.0 );
  if ( ny > 1 )
    dy = ( y_2 - y_1 )/( ny - 1.0 );
  if ( nz > 1 )
    dz = ( z_2 - z_1 )/( nz - 1.0 );

  /*******************************************************************
   * PERFORM TEST                                                    *
   *******************************************************************/

  /* Loop over each direction. */
  for ( i = 0; i < nx; i++ ) {
    x = LAL_REARTH_SI*( x_1 + i*dx );
    for ( j = 0; j < ny; j++ ) {
      y = LAL_REARTH_SI*( y_1 + j*dy );
      for ( k = 0; k < nz; k++ ) {
	z = LAL_REARTH_SI*( z_1 + k*dz );

	/* Do transformation. */
	earth.x = x;
	earth.y = y;
	earth.z = z;
	SUB( LALGeocentricToGeodetic( &stat, &earth ), &stat );
 	SUB( LALGeodeticToGeocentric( &stat, &earth ), &stat );

	/* Compute difference. */
	ddx = x - earth.x;
	ddy = y - earth.y;
	ddz = z - earth.z;
	ddr = sqrt( ddx*ddx + ddy*ddy + ddz*ddz );
	if ( ddr > ddmax )
	  ddmax = ddr;
	if ( verbosity == 1 )
	  fprintf( stdout, "%+23.16e\n", ddr );
	else if ( verbosity == 2 )
	  fprintf( stdout, "%+23.16e %+23.16e\n", earth.elevation, ddr );
	else if ( verbosity == 3 )
	  fprintf( stdout, "%+23.16e %+23.16e %+23.16e %+23.16e\n",
		   x, y, z, ddr );
	else if ( verbosity == 4 )
	  fprintf( stdout, "%+23.16e %+23.16e %+23.16e"
		   " %+23.16e %+23.16e %+23.16e %+23.16e\n", x, y, z,
		   earth.elevation, LAL_180_PI*earth.geodetic.latitude,
		   LAL_180_PI*earth.geodetic.longitude, ddr );
      }
    }
  }

  /* Print maximum. */
  fprintf( stdout, "Maximum error: %.16em\n", ddmax );
  if ( !xyz && ddmax > 1.0e-6 ) {
    ERROR( GEOCENTRICGEODETICTESTC_ETEST,
	   GEOCENTRICGEODETICTESTC_MSGETEST, 0 );
    return GEOCENTRICGEODETICTESTC_ETEST;
  }
  LALCheckMemoryLeaks();
  INFO( GEOCENTRICGEODETICTESTC_MSGENORM );
  return GEOCENTRICGEODETICTESTC_ENORM;
}
void LALRandomInspiralSignal
(
 LALStatus              *status,
 REAL4Vector            *signalvec,
 RandomInspiralSignalIn *randIn
 )
{

    REAL8                   maxTemp; /* temporary variable */
    INT4                    iMax;    /* temporary index    */
    UINT4                   indice;
    REAL8                   epsilon1, epsilon2, norm;
    REAL4Vector             noisy, buff;
    AddVectorsIn            addIn;
    INT4                    valid;
    static RandomParams     *randomparams;
    InspiralWaveNormaliseIn normin;

    INITSTATUS(status);
    ATTATCHSTATUSPTR(status);

    ASSERT (signalvec->data,  status, LALNOISEMODELSH_ENULL, LALNOISEMODELSH_MSGENULL);
    ASSERT (randIn->psd.data,  status, LALNOISEMODELSH_ENULL, LALNOISEMODELSH_MSGENULL);
    ASSERT (randIn->mMin > 0, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);
    ASSERT (randIn->MMax > 2*randIn->mMin, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);
    ASSERT (randIn->type >= 0, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);
    ASSERT (randIn->type <= 2, status, LALNOISEMODELSH_ESIZE, LALNOISEMODELSH_MSGESIZE);

    buff.length = signalvec->length;
    if (!(buff.data = (REAL4*) LALCalloc(buff.length, sizeof(REAL4)) )) {
        ABORT (status, LALNOISEMODELSH_EMEM, LALNOISEMODELSH_MSGEMEM);
    }

    /* Use the seed to initialize random(). */
    srandom(randIn->useed);
    /* use the random number so generated as the next seed */
    randIn->useed = random();

    /* we need random parameters only if we need to generate a signal (i.e. type 0/2) */
    if (randIn->type==0 || randIn->type==2)
    {
        valid = 0;
        /* Keep generating random parameters until they
         * are located within the specified region */
        while (!valid)
        {
            epsilon1 = (float) random()/(float)RAND_MAX;
            epsilon2 = (float) random()/(float)RAND_MAX;
            switch (randIn->param.massChoice)
            {

                case bhns:
                    ASSERT(randIn->mMin<=3 && randIn->mMax>=3, status, 10,
                            "if massChoice is set to bhns, mass1 must be <= 3 "
                            "solar mass and mass2 >= 3 solar mass\n");
                    randIn->param.mass1 = randIn->mMin +
                            (3 - randIn->mMin) * epsilon1;
                    randIn->param.mass2 = 3  +
                            (randIn->mMax - 3) * epsilon2;
                    randIn->param.massChoice=m1Andm2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice=bhns;
                    break;

                case m1Andm2:
                    /*
                     * restriction is on the minimum and maximum individual
                     * masses of the two component stars.
                     */
                    randIn->param.mass1 = randIn->mMin +
                            (randIn->mMax - randIn->mMin) * epsilon1;
                    randIn->param.mass2 = randIn->mMin  +
                            (randIn->mMax - randIn->mMin) * epsilon2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case minmaxTotalMass:
                    /*
                     * restriction is on the min and max Total mass. Should be
                     * check carefully. Right now, I think that it is almost
                     * uniformly distributed in total mass but seem to drop at
                     * very high mass. I'm not sure about the etaMin either. I
                     * might remove this code anyway soon. This is for a quick
                     * test for Craig Robinson and the high mass CBC search
                     * */
                    {
                     REAL8 etaMin ;
                     randIn->param.totalMass = randIn->MMin + (randIn->MMax - randIn->MMin)*epsilon1 ;

                    if (randIn->param.totalMass < (randIn->mMin+ randIn->mMax)) {
                      etaMin = (randIn->mMin / randIn->param.totalMass);
                      etaMin = etaMin - etaMin *etaMin;
                    }
                    else {
                      etaMin = (randIn->mMax / randIn->param.totalMass);
                      etaMin = etaMin - etaMin *etaMin;
                    }
                    randIn->param.eta = etaMin + epsilon2 * (.25 - etaMin);

                    }
                    randIn->param.massChoice = totalMassAndEta;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = minmaxTotalMass;
                    break;


                case totalMassAndEta:
                    /*
                     * restriction is on the total mass of the binary
                     * and the minimum mass of the component stars
                     */


                    randIn->param.mass1 = randIn->mMin
                            + (randIn->MMax - 2.*randIn->mMin) * epsilon1;
                    randIn->param.mass2 = randIn->mMin
                            + (randIn->MMax - randIn->param.mass1 - randIn->mMin) * epsilon2;
                    randIn->param.totalMass = randIn->param.mass1 + randIn->param.mass2 ;
                    randIn->param.eta = (randIn->param.mass1*randIn->param.mass2) / pow(randIn->param.totalMass,2.L);
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case totalMassUAndEta:
                    /*
                     * restriction is on the total mass of the binary
                     * and the etaMin which depends on max total mass.
                     */
                    {
                        REAL4 etaMin;

                        randIn->param.totalMass =  2*randIn->mMin  +  epsilon1 * (randIn->MMax - 2 * randIn->mMin) ;

                        if (randIn->param.totalMass < (randIn->mMin+ randIn->mMax)) {
                            etaMin = (randIn->mMin / randIn->param.totalMass);
                            etaMin = etaMin - etaMin *etaMin;
                        }
                        else {
                            etaMin = (randIn->mMax / randIn->param.totalMass);
                            etaMin = etaMin - etaMin *etaMin;
                        }
                        randIn->param.eta = etaMin + epsilon2 * (.25 - etaMin);

                        LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                        CHECKSTATUSPTR(status);
                    }
                    break;

                case fixedMasses: /* the user has already given individual masses*/
                    randIn->param.massChoice = m1Andm2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedMasses;
                    break;

                case fixedPsi: /* the user has already given psi0/psi3*/
                    randIn->param.massChoice = psi0Andpsi3;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedPsi;
                    break;

                case fixedTau: /* the user has already given tau0/tau3*/
                    randIn->param.massChoice = t03;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedTau;
                    break;

                case t02:
                    /* chirptimes t0 and t2 are required in a specified range */
                    randIn->param.t0 = randIn->t0Min +
                            (randIn->t0Max - randIn->t0Min)*epsilon1;
                    randIn->param.t2 = randIn->tnMin +
                            (randIn->tnMax - randIn->tnMin)*epsilon2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case t03:
                    /* chirptimes t0 and t3 are required in a specified range */
                    randIn->param.t0 = randIn->t0Min +
                            (randIn->t0Max - randIn->t0Min)*epsilon1;
                    randIn->param.t3 = randIn->tnMin +
                            (randIn->tnMax - randIn->tnMin)*epsilon2;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case psi0Andpsi3:
                    /* BCV parameters are required in a specified range */
                    randIn->param.psi0 = randIn->psi0Min +
                            (randIn->psi0Max - randIn->psi0Min)*epsilon1;
                    randIn->param.psi3 = randIn->psi3Min +
                            (randIn->psi3Max - randIn->psi3Min)*epsilon2;
                    break;

                case massesAndSpin:
                    /* masses, spin parameters and sky position needs to be set */

                    /* Set the random masses first */
                    randIn->param.mass1 = randIn->mMin +
                            (randIn->mMax - randIn->mMin) * epsilon1;
                    randIn->param.mass2 = randIn->mMin  +
                            (randIn->mMax - randIn->mMin) * epsilon2;

                    /* Set the random spin parameters */
                    GenerateRandomSpinTaylorParameters ( status->statusPtr, randIn );
                    CHECKSTATUSPTR(status);

                    /* Set the random sky position and polarisation angle */
                    GenerateRandomSkyPositionAndPolarisation ( status->statusPtr,randIn );
                    CHECKSTATUSPTR(status);

                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    break;

                case t04:
                default:
                    /* if the choice of parameters is wrong abort the run */
                    ABORT (status, LALNOISEMODELSH_ECHOICE, LALNOISEMODELSH_MSGECHOICE);
                    break;
            }


            /* Validate the random parameters generated above */
            switch (randIn->param.massChoice)
            {
                case bhns:
                    valid=1;
                    break;
                case minmaxTotalMass:
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax &&
                            (randIn->param.eta > randIn->etaMin) &&
                            (randIn->param.mass1+randIn->param.mass2) < randIn->MMax  &&
                            (randIn->param.mass1+randIn->param.mass2) > randIn->MMin
                       )
                    {
                        valid = 1;
                    }
                     break;

                case fixedMasses:
                case fixedTau:
                  valid = 1;
                  break;
                case m1Andm2:
                case t03:
                case t02:
                    /*
                     * The following imposes a range in which min and
                     * max of component masses are restricted.
                     */
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax &&
                            randIn->param.eta <= 0.25 &&
                            randIn->param.eta >= randIn->etaMin
                       )
                    {
                        valid = 1;
                    }
                    break;

                case totalMassAndEta:
                case totalMassUAndEta:

                    /*
                     * The following imposes a range in which min of
                     * component masses and max total mass are restricted.
                     */
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.totalMass <= randIn->MMax &&
                            randIn->param.eta <= 0.25 &&
                            randIn->param.eta >= randIn->etaMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax
                       )

                    {
                        valid = 1;
                    }
                    break;
                case fixedPsi:
                    randIn->param.massChoice = psi0Andpsi3;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    randIn->param.massChoice = fixedPsi;
                    valid = 1;
                case psi0Andpsi3:
                    /*
                     * the following makes sure that the BCV has
                     * a well defined end-frequency
                     */
                    randIn->param.massChoice = psi0Andpsi3;
                    LALInspiralParameterCalc(status->statusPtr, &(randIn->param));
                    CHECKSTATUSPTR(status);
                    valid = 1;
                    /*	       if (randIn->param.totalMass > 0.)
                               {
                               REAL8 fLR, fLSO, fend;
                               epsilon1 = (float) random()/(float)RAND_MAX;
                               fLR = 1.L/(LAL_PI * pow (3.L,1.5) * randIn->param.totalMass * LAL_MTSUN_SI);
                               fLSO = 1.L/(LAL_PI * pow (6.L,1.5) * randIn->param.totalMass * LAL_MTSUN_SI);
                               fend = fLSO + (fLR - fLSO) * epsilon1;
                               if (fend > randIn->param.tSampling/2. || fend < randIn->param.fLower) break;
                               randIn->param.fFinal = fend;
                               valid = 1;
                               }*/
                    break;

                case massesAndSpin:
                    if (
                            randIn->param.mass1 >= randIn->mMin &&
                            randIn->param.mass2 >= randIn->mMin &&
                            randIn->param.mass1 <= randIn->mMax &&
                            randIn->param.mass2 <= randIn->mMax &&
                            randIn->param.eta <= 0.25
                       )
                    {
                        valid = 1;
                    }
                    break;

                case t04:
                default:
                    ABORT (status, LALNOISEMODELSH_ECHOICE, LALNOISEMODELSH_MSGECHOICE);
                    break;
            }
        }
    }


    /* set up the structure for normalising the signal */
    normin.psd          = &(randIn->psd);
    normin.df           = randIn->param.tSampling / (REAL8) signalvec->length;
    normin.fCutoff      = randIn->param.fCutoff;
    normin.samplingRate = randIn->param.tSampling;

    switch (randIn->type)
    {
        case 0:

            /* First deal with the signal only case:
             * if the signal is generated in the Fourier domain no
             * need for Fourier transform
             */
            if (randIn->param.approximant == BCV ||
                    randIn->param.approximant == BCVSpin  ||
                    randIn->param.approximant == TaylorF1 ||
                    randIn->param.approximant == TaylorF2 ||
                    randIn->param.approximant == PadeF1)
            {
                LALInspiralWave(status->statusPtr, signalvec, &randIn->param);
                CHECKSTATUSPTR(status);
            }
            else /* Else - generate a time domain waveform */
            {
                /* Note that LALInspiralWave generates only the plus
                 * polarisation of the GW in the time/frequency domain.
                 * For SpinTaylor we need both plus and
                 * the cross polarisations - therefore for this case, we
                 * treat the waveform generation differently. For all other
                 * timedomain approximants, we recourse to calling
                 * LALInspiralWave () function.
                 */
                if (randIn->param.approximant == SpinTaylor)
                {
                    randIn->param.fFinal=0;
                    GenerateTimeDomainWaveformForInjection (status->statusPtr, &buff, &randIn->param);
                    CHECKSTATUSPTR(status);
                }
                else
                {
                    /* force to compute fFinal is it really necessary  ? */
                    randIn->param.fFinal=0;
                    LALInspiralWave(status->statusPtr, &buff, &randIn->param);
                    CHECKSTATUSPTR(status);
                }

                /* Once the time domain waveform has been generated, take its
                 * Fourier transform [i.e buff (t) ---> signal (f)].
                 */
                if (XLALREAL4VectorFFT(signalvec, &buff, randIn->fwdp) != 0)
                  ABORTXLAL(status);

            } /* End of else if time domain waveform */

            /* we might want to know where is the signalvec injected*/
            maxTemp  = 0;
            iMax     = 0;
            for ( indice = 0 ; indice< signalvec->length; indice++)
            {
                if (fabs(signalvec->data[indice]) > maxTemp){
                    iMax = indice;
                    maxTemp = fabs(signalvec->data[indice]);
                }
            }
            randIn->coalescenceTime = iMax;

            normin.fCutoff = randIn->param.fFinal;
            LALInspiralWaveNormaliseLSO(status->statusPtr, signalvec, &norm, &normin);
            CHECKSTATUSPTR(status);
            break;

        case 1:
            /*
             * next deal with the noise only case:
             */
            /*
                Old method of generating Gaussian noise
                LALGaussianNoise(status->statusPtr, &buff, &randIn->useed);
                */
            /*LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);*/
            LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);
            CHECKSTATUSPTR(status);
            LALNormalDeviates(status->statusPtr, &buff, randomparams);
            CHECKSTATUSPTR(status);
            LALDestroyRandomParams(status->statusPtr, &randomparams);
            CHECKSTATUSPTR(status);
            if (XLALREAL4VectorFFT(signalvec, &buff, randIn->fwdp) != 0)
              ABORTXLAL(status);
            LALColoredNoise(status->statusPtr, signalvec, randIn->psd);
            CHECKSTATUSPTR(status);

            /* multiply the noise vector by the correct normalisation factor */
            {
                double a2 = randIn->NoiseAmp * sqrt (randIn->param.tSampling)/2.L;
                UINT4 i;
                for (i=0; i<signalvec->length; i++) signalvec->data[i] *= a2;
            }
            break;

        default:
            /*
             * finally deal with the noise+signal only case:
             */
            noisy.length = signalvec->length;
            if (!(noisy.data = (REAL4*) LALMalloc(sizeof(REAL4)*noisy.length)))
            {
                if (buff.data != NULL) LALFree(buff.data);
                buff.data = NULL;
                ABORT (status, LALNOISEMODELSH_EMEM, LALNOISEMODELSH_MSGEMEM);
            }
            /*LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);*/
            LALCreateRandomParams(status->statusPtr, &randomparams, randIn->useed);
            CHECKSTATUSPTR(status);
            LALNormalDeviates(status->statusPtr, &buff, randomparams);
            CHECKSTATUSPTR(status);
            LALDestroyRandomParams(status->statusPtr, &randomparams);
            CHECKSTATUSPTR(status);
            if (XLALREAL4VectorFFT(&noisy, &buff, randIn->fwdp) != 0)
              ABORTXLAL(status);
            LALColoredNoise(status->statusPtr, &noisy, randIn->psd);
            CHECKSTATUSPTR(status);

            if (randIn->param.approximant == BCV ||
                    randIn->param.approximant == BCVSpin  ||
                    randIn->param.approximant == TaylorF1 ||
                    randIn->param.approximant == TaylorF2 ||
                    randIn->param.approximant == PadeF1)
            {
                LALInspiralWave(status->statusPtr, &buff, &randIn->param);
                CHECKSTATUSPTR(status);
            }
            else
            {
                LALInspiralWave(status->statusPtr, signalvec, &randIn->param);
                CHECKSTATUSPTR(status);


                /* Now convert from time domain signal(t) ---> frequency
                 * domain waveform buff(f) i.e signal(t) -> buff(f)*/
                if (XLALREAL4VectorFFT(&buff, signalvec, randIn->fwdp) != 0)
                  ABORTXLAL(status);

            }

            /* we might want to know where is the signal injected*/
            maxTemp  = 0;
            iMax     = 0;
            for ( indice = 0 ; indice< signalvec->length; indice++)
            {
                if (fabs(signalvec->data[indice]) > maxTemp){
                    iMax = indice;
                    maxTemp = fabs(signalvec->data[indice]);
                }
            }
            randIn->coalescenceTime = iMax;

            normin.fCutoff = randIn->param.fFinal;
            LALInspiralWaveNormaliseLSO(status->statusPtr, &buff, &norm, &normin);
            CHECKSTATUSPTR(status);

            addIn.v1 = &buff;
            addIn.a1 = randIn->SignalAmp;
            addIn.v2 = &noisy;
            /* After experimenting we found that the following factor SamplingRate*sqrt(2)
             * is needed for noise amplitude to get the output of the signalless correlation
             * equal to unity; the proof of this is still needed
             */
            addIn.a2 = randIn->NoiseAmp * sqrt (randIn->param.tSampling)/2.L;
            LALAddVectors(status->statusPtr, signalvec, addIn);
            CHECKSTATUSPTR(status);
            if (noisy.data != NULL) LALFree(noisy.data);
            break;
    }

    /* Hash out signal for all frequencies less than or equal to the
     * lower cut-off frequency.
     */


    if (buff.data != NULL) LALFree(buff.data);

    DETATCHSTATUSPTR(status);
    RETURN(status);
}
示例#7
0
int main ( int argc, char *argv[] )
{
  /* lal function variables */
  LALStatus             status = blank_status;

  /* templates */
  RandomParams         *randParams = NULL;
  InspiralTemplate      newTmplt;
  SnglInspiralTable    *thisTmplt  = NULL;

  /* output data */
  MetadataTable         templateBank;
  MetadataTable         proctable;
  MetadataTable         procparams;
  MetadataTable         searchsummvars;
  SearchSummvarsTable  *this_search_summvar = NULL;
  ProcessParamsTable   *this_proc_param = NULL;
  LIGOLwXMLStream       results;

  /* counters and other variables */
  INT4 i;
  CHAR  fname[256];


  /*
   *
   * initialization
   *
   */


  /* set up inital debugging values */
  lal_errhandler = LAL_ERR_EXIT;

  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *)
    calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME, lalAppsVCSIdentInfo.vcsId,
      lalAppsVCSIdentInfo.vcsStatus, lalAppsVCSIdentInfo.vcsDate, 0);
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *)
    calloc( 1, sizeof(ProcessParamsTable) );

  /* call the argument parse and check function */
  arg_parse_check( argc, argv, procparams );

  /* can use LALMalloc() / LALCalloc() from here */


  /*
   *
   * create the radom number seed
   *
   */


  /* store the seed in the search summvars table */
  this_search_summvar = searchsummvars.searchSummvarsTable =
    (SearchSummvarsTable *) LALCalloc( 1, sizeof(SearchSummvarsTable) );
  snprintf( this_search_summvar->name,
      LIGOMETA_NAME_MAX, "template bank simulation seed" );

  if ( randSeedType == urandom )
  {
    FILE   *fpRand = NULL;
    INT4    randByte;

    if ( vrbflg )
      fprintf( stdout, "obtaining random seed from /dev/urandom: " );

    randomSeed = 0;
    fpRand = fopen( "/dev/urandom", "r" );
    if ( fpRand )
    {
      for ( randByte = 0; randByte < 4 ; ++randByte )
      {
        INT4 tmpSeed = (INT4) fgetc( fpRand );
        randomSeed += tmpSeed << ( randByte * 8 );
      }
      fclose( fpRand );
    }
    else
    {
      perror( "error obtaining random seed from /dev/urandom" );
      exit( 1 );
    }
  }
  else if ( randSeedType == user )
  {
    if ( vrbflg )
      fprintf( stdout, "using user specified random seed: " );
  }

  this_search_summvar->value = randomSeed;
  snprintf( this_search_summvar->string, LIGOMETA_STRING_MAX,
      "%d", randomSeed );
  if ( vrbflg ) fprintf( stdout, "%d\n", randomSeed );

  /* create the tmplt bank random parameter structure */
  LAL_CALL( LALCreateRandomParams( &status, &randParams, randomSeed ),
      &status );


  /*
   *
   * create a random template bank
   *
   */


  /* make sure the pointer to the first template is null */
  templateBank.snglInspiralTable = NULL;

  for ( i = 0; i < numTmplts; ++i )
  {
    memset( &newTmplt, 0, sizeof(InspiralTemplate) );
    newTmplt.massChoice = m1Andm2;
    newTmplt.order = LAL_PNORDER_TWO;
    newTmplt.fLower = fLow;

    /* set up the injection masses */
    if ( maxMass == minMass )
    {
      newTmplt.mass1 = (REAL8) maxMass;
      newTmplt.mass2 = (REAL8) maxMass;
    }
    else
    {
      REAL4 mass;
      /* generate random parameters for the injection */
      LAL_CALL( LALUniformDeviate( &status, &mass, randParams ), &status );
      newTmplt.mass1 = (maxMass - minMass) * mass;
      newTmplt.mass1 += minMass;

      LAL_CALL( LALUniformDeviate( &status, &mass, randParams ), &status );
      newTmplt.mass2 = (maxMass - minMass) * mass;
      newTmplt.mass2 += minMass;
    }

    LAL_CALL( LALInspiralParameterCalc( &status, &newTmplt ), &status );

    if ( ! templateBank.snglInspiralTable )
    {
      thisTmplt = templateBank.snglInspiralTable =
        (SnglInspiralTable *) LALCalloc(1, sizeof(SnglInspiralTable));
    }
    else
    {
      thisTmplt = thisTmplt->next =
        (SnglInspiralTable *) LALCalloc(1, sizeof(SnglInspiralTable));
    }

    thisTmplt->mass1 = newTmplt.mass1;
    thisTmplt->mass2 = newTmplt.mass2;
    thisTmplt->mchirp = newTmplt.chirpMass;
    thisTmplt->eta = newTmplt.eta;
    thisTmplt->tau0 = newTmplt.t0;
    thisTmplt->tau2 = newTmplt.t2;
    thisTmplt->tau3 = newTmplt.t3;
    thisTmplt->tau4 = newTmplt.t4;
    thisTmplt->tau5 = newTmplt.t5;
    thisTmplt->ttotal = newTmplt.tC;
    thisTmplt->psi0 = newTmplt.psi0;
    thisTmplt->psi3 = newTmplt.psi3;
    thisTmplt->f_final = newTmplt.fFinal;
    thisTmplt->eta = newTmplt.eta;
    thisTmplt->beta = newTmplt.beta;
    snprintf( thisTmplt->ifo, LIGOMETA_IFO_MAX, "P1" );
    snprintf( thisTmplt->search, LIGOMETA_SEARCH_MAX, "randombank" );
    snprintf( thisTmplt->channel, LIGOMETA_CHANNEL_MAX, "SIM-BANK" );
  }


  /*
   *
   * write the output data
   *
   */

  /* open the output xml file */
  memset( &results, 0, sizeof(LIGOLwXMLStream) );
  if ( userTag && !outCompress )
  {
    snprintf( fname, sizeof(fname), "P1-TMPLTBANK_%s-%d-%d.xml",
        userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "P1-TMPLTBANK_%s-%d-%d.xml.gz",
        userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( !userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "P1-TMPLTBANK-%d-%d.xml.gz",
        gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else
  {
    snprintf( fname, sizeof(fname), "P1-TMPLTBANK-%d-%d.xml",
        gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  LAL_CALL( LALOpenLIGOLwXMLFile( &status, &results, fname ), &status );

  /* write the process table */
  snprintf( proctable.processTable->ifos, LIGOMETA_IFO_MAX, "P1" );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &results, process_table ),
      &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &results, proctable,
        process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &results ), &status );
  free( proctable.processTable );

  /* erase the first empty process params entry */
  {
    ProcessParamsTable *emptyPPtable = procparams.processParamsTable;
    procparams.processParamsTable = procparams.processParamsTable->next;
    free( emptyPPtable );
  }

  /* write the process params table */
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &results, process_params_table ),
      &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &results, procparams,
        process_params_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &results ), &status );
  while( procparams.processParamsTable )
  {
    this_proc_param = procparams.processParamsTable;
    procparams.processParamsTable = this_proc_param->next;
    free( this_proc_param );
  }

  /* write the search summvars table */
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &results,
        search_summvars_table ), &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &results, searchsummvars,
        search_summvars_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &results ), &status );
  while( searchsummvars.searchSummvarsTable )
  {
    this_search_summvar = searchsummvars.searchSummvarsTable;
    searchsummvars.searchSummvarsTable = this_search_summvar->next;
    LALFree( this_search_summvar );
  }

  /* write the template bank to the file */
  if ( templateBank.snglInspiralTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &results, sngl_inspiral_table ),
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &results, templateBank,
          sngl_inspiral_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &results ), &status );
  }
  while ( templateBank.snglInspiralTable )
  {
    thisTmplt = templateBank.snglInspiralTable;
    templateBank.snglInspiralTable = templateBank.snglInspiralTable->next;
    LALFree( thisTmplt );
  }

  /* close the output xml file */
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &results ), &status );

  /* free the rest of the memory, check for memory leaks and exit */
  LAL_CALL( LALDestroyRandomParams( &status, &randParams ), &status );
  LALCheckMemoryLeaks();
  exit( 0 );
}
示例#8
0
int main(void)
{
  static LALStatus      status;
  LALDetector           detector;
  LALSource             pulsar;
  CoarseFitOutput       output;
  CoarseFitInput        input;
  CoarseFitParams       params;
  LIGOTimeGPS           tgps[FITTOPULSARTEST_LENGTH];
  REAL4                 cosIota;
  REAL4                 phase;
  REAL4                 psi;
  REAL4                 h0;
  REAL4                 cos2phase, sin2phase;
  static RandomParams   *randomParams;
  static REAL4Vector    *noise;
  INT4                  seed = 0;
  LALDetAndSource       detAndSource;
  LALDetAMResponseSeries        pResponseSeries = {NULL,NULL,NULL};
  REAL4TimeSeries               Fp, Fc, Fs;
  LALTimeIntervalAndNSample     time_info;
  UINT4                         i;


  /* Allocate memory */
  input.B = NULL;
  input.var = NULL;

  LALZCreateVector( &status, &input.B, FITTOPULSARTEST_LENGTH);
  LALZCreateVector( &status, &input.var, FITTOPULSARTEST_LENGTH);

  noise = NULL;
  LALCreateVector( &status, &noise, FITTOPULSARTEST_LENGTH);
  LALCreateRandomParams( &status, &randomParams, seed);

  Fp.data = NULL;
  Fc.data = NULL;
  Fs.data = NULL;

  pResponseSeries.pPlus   = &(Fp);
  pResponseSeries.pCross  = &(Fc);
  pResponseSeries.pScalar = &(Fs);

  LALSCreateVector(&status, &(pResponseSeries.pPlus->data), 1);
  LALSCreateVector(&status, &(pResponseSeries.pCross->data), 1);
  LALSCreateVector(&status, &(pResponseSeries.pScalar->data), 1);

  input.t = tgps;
  /******** GENERATE FAKE INPUT **********/

  time_info.epoch.gpsSeconds     = FITTOPULSARTEST_T0;
  time_info.epoch.gpsNanoSeconds = 0;
  time_info.deltaT               = 60;
  time_info.nSample              = FITTOPULSARTEST_LENGTH;

  cosIota = 0.5;
  psi = 0.1;
  phase = 0.4;
  h0 = 5.0;

  cos2phase = cos(2.0*phase);
  sin2phase = sin(2.0*phase);

  detector = lalCachedDetectors[LALDetectorIndexGEO600DIFF];     /* use GEO 600 detector for tests */
  pulsar.equatorialCoords.longitude = 1.4653;                   /* right ascention of pulsar */
  pulsar.equatorialCoords.latitude = -1.2095;                   /* declination of pulsar */
  pulsar.equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; /* coordinate system */
  pulsar.orientation = psi;                                     /* polarization angle */
  strcpy(pulsar.name, "fakepulsar");                            /* name of pulsar */

  detAndSource.pDetector = &detector;
  detAndSource.pSource = &pulsar;

  LALNormalDeviates( &status, noise, randomParams );

  LALComputeDetAMResponseSeries(&status, &pResponseSeries, &detAndSource, &time_info);

  for (i = 0;i < FITTOPULSARTEST_LENGTH; i++)
  {
    input.t[i].gpsSeconds = FITTOPULSARTEST_T0 + 60*i;
    input.t[i].gpsNanoSeconds = 0;

    input.B->data[i] = crect( pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*cos2phase + 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*sin2phase, pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*sin2phase - 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*cos2phase );
    input.var->data[i] = crect( noise->data[FITTOPULSARTEST_LENGTH-i-1]*noise->data[FITTOPULSARTEST_LENGTH-i-1], noise->data[i]*noise->data[i] );
  }

  input.B->length = FITTOPULSARTEST_LENGTH;
  input.var->length = FITTOPULSARTEST_LENGTH;

  /*******  TEST RESPONSE TO VALID DATA  ************/
/* Test that valid data generate the correct answers */
  params.detector = detector;
  params.pulsarSrc = pulsar;

  params.meshH0[0] = 4.0;
  params.meshH0[1] = 0.2;
  params.meshH0[2] = 10;

  params.meshCosIota[0] = 0.0;
  params.meshCosIota[1] =  0.1;
  params.meshCosIota[2] =  10;

  params.meshPhase[0] = 0.0;
  params.meshPhase[1] = 0.1;
  params.meshPhase[2] = 10;

  params.meshPsi[0] =  0.0;
  params.meshPsi[1] =  0.1;
  params.meshPsi[2] =  10;

  output.mChiSquare = NULL;
  LALDCreateVector( &status, &output.mChiSquare,params.meshH0[2]*params.meshCosIota[2]*params.meshPhase[2]*params.meshPsi[2]);


  LALCoarseFitToPulsar(&status,&output, &input, &params);

  if(status.statusCode)
  {
    printf("Unexpectedly got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    return FITTOPULSARTESTC_EFLS;
  }


  if(output.phase > phase + params.meshPhase[2] || output.phase < phase - params.meshPhase[2])
  {
    printf("Got incorrect phase %f when expecting %f \n",
            output.phase, phase);
    return FITTOPULSARTESTC_EFLS;
  }

  if(output.cosIota > cosIota + params.meshCosIota[2] || output.cosIota < cosIota - params.meshCosIota[2])
  {
    printf("Got incorrect cosIota %f when expecting %f \n",
            output.cosIota, cosIota);
    return FITTOPULSARTESTC_EFLS;
  }

    if(output.psi > psi + params.meshPsi[2] || output.psi < psi - params.meshPsi[2])
  {
    printf("Got incorrect psi %f when expecting %f \n",
            output.psi, psi);
    return FITTOPULSARTESTC_EFLS;
  }

  /*******  TEST RESPONSE OF LALCoarseFitToPulsar TO INVALID DATA  ************/

#ifndef LAL_NDEBUG
if ( ! lalNoDebug ) {

 /* Test that all the error conditions are correctly detected by the function */

 LALCoarseFitToPulsar(&status, NULL, &input, &params);

  if (status.statusCode != FITTOPULSARH_ENULLOUTPUT
       || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLOUTPUT))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT);
    return FITTOPULSARTESTC_ECHK;
  }

 LALCoarseFitToPulsar(&status, &output, NULL, &params);

  if (status.statusCode != FITTOPULSARH_ENULLINPUT
       || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLINPUT))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT);
    return FITTOPULSARTESTC_ECHK;
  }

 LALCoarseFitToPulsar(&status, &output, &input, NULL);

  if (status.statusCode != FITTOPULSARH_ENULLPARAMS
       || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLPARAMS))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS);
    return FITTOPULSARTESTC_ECHK;
  }

  /* try having two input vectors of different length */
  input.var->length = 1;
  LALCoarseFitToPulsar(&status, &output, &input, &params);

  if (status.statusCode != FITTOPULSARH_EVECSIZE
       || strcmp(status.statusDescription, FITTOPULSARH_MSGEVECSIZE))
  {
    printf( "Got error code %d and message %s\n",
            status.statusCode, status.statusDescription);
    printf( "Expected error code %d and message %s\n",
            FITTOPULSARH_EVECSIZE, FITTOPULSARH_MSGEVECSIZE);
    return FITTOPULSARTESTC_ECHK;
  }

  input.var->length = FITTOPULSARTEST_LENGTH;

} /* if ( ! lalNoDebug ) */
#endif /* LAL_NDEBUG */

  /*******  CLEAN UP  ************/

  LALZDestroyVector(&status, &input.B);
  LALZDestroyVector(&status, &input.var);
  LALDestroyVector(&status, &noise);
  LALDDestroyVector(&status, &output.mChiSquare);
  LALDestroyRandomParams(&status, &randomParams);
  LALSDestroyVector(&status, &(pResponseSeries.pPlus->data));
  LALSDestroyVector(&status, &(pResponseSeries.pCross->data));
  LALSDestroyVector(&status, &(pResponseSeries.pScalar->data));

  LALCheckMemoryLeaks();

  return FITTOPULSARTESTC_ENOM;
}
int main(int argc, char *argv[]){

  /* LALStatus pointer */
  static LALStatus  status;  
  
  /* time and velocity  */
  static LIGOTimeGPSVector    timeV;
  static REAL8Cart3CoorVector velV;
  static REAL8Vector          timeDiffV;
  LIGOTimeGPS firstTimeStamp;

  /* standard pulsar sft types */ 
  MultiSFTVector *inputSFTs = NULL;
  UINT4 binsSFT;
  UINT4 sftFminBin;
  UINT4 numsft;

  INT4 k;
  FILE *fp=NULL;

  /* information about all the ifos */
  MultiDetectorStateSeries *mdetStates = NULL;
  UINT4 numifo;

  /* vector of weights */
  REAL8Vector weightsV;

  /* ephemeris */
  EphemerisData    *edat=NULL;

  static UCHARPeakGram       pg1;
  static HoughTemplate  pulsarTemplate;
  static REAL8Vector  foft; 

  /* miscellaneous */
  UINT4  mObsCoh;
  REAL8  timeBase, deltaF;
  REAL8  numberCount;

  /* Chi2Test parameters */
  HoughParamsTest chi2Params;
  REAL8Vector numberCountV;  /* Vector with the number count of each block inside */
  REAL8  numberCountTotal;   /* Sum over all the numberCounts */
  REAL8  chi2;

  /* sft constraint variables */
  LIGOTimeGPS startTimeGPS, endTimeGPS;
  LIGOTimeGPSVector *inputTimeStampsVector=NULL;


  REAL8  alphaPeak, meanN, sigmaN;

  /* user input variables */
  BOOLEAN  uvar_help, uvar_weighAM, uvar_weighNoise;
  INT4     uvar_blocksRngMed, uvar_nfSizeCylinder, uvar_maxBinsClean;
  REAL8    uvar_startTime, uvar_endTime;
  REAL8    uvar_fStart, uvar_peakThreshold, uvar_fSearchBand;
  REAL8    uvar_Alpha, uvar_Delta, uvar_Freq, uvar_fdot;
  REAL8    uvar_AlphaWeight, uvar_DeltaWeight;
  CHAR     *uvar_earthEphemeris=NULL;
  CHAR     *uvar_sunEphemeris=NULL;
  CHAR     *uvar_sftDir=NULL;
  CHAR     *uvar_timeStampsFile=NULL;
  CHAR     *uvar_outfile=NULL;
  LALStringVector *uvar_linefiles=NULL;
  INT4     uvar_p;


  /* Set up the default parameters */  

  /* LAL error-handler */
  lal_errhandler = LAL_ERR_EXIT;
    
  uvar_help = FALSE;
  uvar_weighAM = TRUE;
  uvar_weighNoise = TRUE;
  uvar_blocksRngMed = BLOCKSRNGMED;
  uvar_nfSizeCylinder = NFSIZE;
  uvar_fStart = F0;
  uvar_fSearchBand = FBAND;
  uvar_peakThreshold = THRESHOLD;
  uvar_maxBinsClean = 100;
  uvar_startTime= 0;
  uvar_endTime = LAL_INT4_MAX;

  uvar_Alpha = 1.0;
  uvar_Delta = 1.0;
  uvar_Freq = 310.0;
  uvar_fdot = 0.0;

  uvar_AlphaWeight = uvar_Alpha;
  uvar_DeltaWeight = uvar_Delta;

  uvar_p = NBLOCKSTEST;
  chi2Params.length=uvar_p;
  chi2Params.numberSFTp=NULL;
  chi2Params.sumWeight=NULL;
  chi2Params.sumWeightSquare=NULL;

  uvar_outfile = (CHAR *)LALCalloc( MAXFILENAMELENGTH , sizeof(CHAR));
  strcpy(uvar_outfile, "./tempout");

  uvar_earthEphemeris = (CHAR *)LALCalloc( MAXFILENAMELENGTH , sizeof(CHAR));
  strcpy(uvar_earthEphemeris,EARTHEPHEMERIS);

  uvar_sunEphemeris = (CHAR *)LALCalloc( MAXFILENAMELENGTH , sizeof(CHAR));
  strcpy(uvar_sunEphemeris,SUNEPHEMERIS);


  uvar_sftDir = (CHAR *)LALCalloc( MAXFILENAMELENGTH , sizeof(CHAR));
  strcpy(uvar_sftDir,SFTDIRECTORY);


  /* register user input variables */
  LAL_CALL( LALRegisterBOOLUserVar(   &status, "help",            'h', UVAR_HELP,     "Print this message",                    &uvar_help),            &status);  
  LAL_CALL( LALRegisterREALUserVar(   &status, "fStart",          'f', UVAR_OPTIONAL, "Start search frequency",                &uvar_fStart),              &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "fSearchBand",     'b', UVAR_OPTIONAL, "Search frequency band",                 &uvar_fSearchBand),     &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "startTime",        0,  UVAR_OPTIONAL, "GPS start time of observation",         &uvar_startTime),        &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "endTime",          0,  UVAR_OPTIONAL, "GPS end time of observation",           &uvar_endTime),          &status);
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "timeStampsFile",   0,  UVAR_OPTIONAL, "Input time-stamps file",                &uvar_timeStampsFile),   &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "peakThreshold",    0,  UVAR_OPTIONAL, "Peak selection threshold",              &uvar_peakThreshold),   &status);
  LAL_CALL( LALRegisterBOOLUserVar(   &status, "weighAM",          0,  UVAR_OPTIONAL, "Use amplitude modulation weights",      &uvar_weighAM),         &status);  
  LAL_CALL( LALRegisterBOOLUserVar(   &status, "weighNoise",       0,  UVAR_OPTIONAL, "Use SFT noise weights",                 &uvar_weighNoise),      &status);  
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "earthEphemeris",  'E', UVAR_OPTIONAL, "Earth Ephemeris file",                  &uvar_earthEphemeris),  &status);
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "sunEphemeris",    'S', UVAR_OPTIONAL, "Sun Ephemeris file",                    &uvar_sunEphemeris),    &status);
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "sftDir",          'D', UVAR_REQUIRED, "SFT filename pattern",                  &uvar_sftDir),          &status);
  LAL_CALL( LALRegisterLISTUserVar(   &status, "linefiles",        0,  UVAR_OPTIONAL, "Comma separated List of linefiles (filenames must contain IFO name)",  
	      &uvar_linefiles),       &status);

  LAL_CALL( LALRegisterREALUserVar(   &status, "Alpha",            0,  UVAR_OPTIONAL, "Sky location (longitude)",               &uvar_Alpha),              &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "Delta",            0,  UVAR_OPTIONAL, "Sky location (latitude)",                &uvar_Delta),              &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "Freq",             0,  UVAR_OPTIONAL, "Template frequency",                     &uvar_Freq),               &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "fdot",             0,  UVAR_OPTIONAL, "First spindown",                         &uvar_fdot),               &status);

  LAL_CALL( LALRegisterREALUserVar(   &status, "AlphaWeight",      0,  UVAR_OPTIONAL, "sky Alpha for weight calculation",       &uvar_AlphaWeight),        &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "DeltaWeight",      0,  UVAR_OPTIONAL, "sky Delta for weight calculation",       &uvar_DeltaWeight),        &status);

  LAL_CALL( LALRegisterINTUserVar(    &status, "nfSizeCylinder",   0,  UVAR_OPTIONAL, "Size of cylinder of PHMDs",             &uvar_nfSizeCylinder),  &status);

  LAL_CALL( LALRegisterINTUserVar(    &status, "blocksRngMed",     0,  UVAR_OPTIONAL, "Running Median block size",             &uvar_blocksRngMed),    &status);
  LAL_CALL( LALRegisterINTUserVar(    &status, "maxBinsClean",     0,  UVAR_OPTIONAL, "Maximum number of bins in cleaning",    &uvar_maxBinsClean),    &status);
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "outfile",          0,  UVAR_OPTIONAL, "output file name",                      &uvar_outfile),         &status);

  LAL_CALL( LALRegisterINTUserVar(    &status, "pdatablock",     'p',  UVAR_OPTIONAL, "Number of data blocks for veto tests",  &uvar_p),               &status);


  /* read all command line variables */
  LAL_CALL( LALUserVarReadAllInput(&status, argc, argv), &status);

  /* exit if help was required */
  if (uvar_help)
    exit(0); 

  /* very basic consistency checks on user input */
  if ( uvar_fStart < 0 ) {
    fprintf(stderr, "start frequency must be positive\n");
    exit(1);
  }

  if ( uvar_fSearchBand < 0 ) {
    fprintf(stderr, "search frequency band must be positive\n");
    exit(1);
  }
 
  if ( uvar_peakThreshold < 0 ) {
    fprintf(stderr, "peak selection threshold must be positive\n");
    exit(1);
  }


  /***** start main calculations *****/

  chi2Params.length=uvar_p;
  chi2Params.numberSFTp = (UINT4 *)LALMalloc( uvar_p*sizeof(UINT4));
  chi2Params.sumWeight = (REAL8 *)LALMalloc( uvar_p*sizeof(REAL8));
  chi2Params.sumWeightSquare = (REAL8 *)LALMalloc( uvar_p*sizeof(REAL8));


  /* read sft Files and set up weights */
  {
    /* new SFT I/O data types */
    SFTCatalog *catalog = NULL;
    static SFTConstraints constraints;

    REAL8 doppWings, f_min, f_max;

    /* set detector constraint */
    constraints.detector = NULL;

    if ( LALUserVarWasSet( &uvar_startTime ) ) {
      XLALGPSSetREAL8(&startTimeGPS, uvar_startTime);
      constraints.minStartTime = &startTimeGPS;
    }

    if ( LALUserVarWasSet( &uvar_endTime ) ) {
      XLALGPSSetREAL8(&endTimeGPS, uvar_endTime);
      constraints.maxEndTime = &endTimeGPS;
    }

    if ( LALUserVarWasSet( &uvar_timeStampsFile ) ) {
      LAL_CALL ( LALReadTimestampsFile ( &status, &inputTimeStampsVector, uvar_timeStampsFile), &status);
      constraints.timestamps = inputTimeStampsVector;
    }
    
    /* get sft catalog */
    LAL_CALL( LALSFTdataFind( &status, &catalog, uvar_sftDir, &constraints), &status);
    if ( (catalog == NULL) || (catalog->length == 0) ) {
      fprintf (stderr,"Unable to match any SFTs with pattern '%s'\n", uvar_sftDir );
      exit(1);
    }

    /* now we can free the inputTimeStampsVector */
    if ( LALUserVarWasSet( &uvar_timeStampsFile ) ) {
      LALDestroyTimestampVector ( &status, &inputTimeStampsVector);
    }

    /* get some sft parameters */
    mObsCoh = catalog->length; /* number of sfts */
    deltaF = catalog->data->header.deltaF;  /* frequency resolution */
    timeBase= 1.0/deltaF; /* coherent integration time */
    // unused: UINT8 f0Bin = floor( uvar_fStart * timeBase + 0.5); /* initial search frequency */
    // unused: INT4 length =  uvar_fSearchBand * timeBase; /* total number of search bins - 1 */
    
    /* catalog is ordered in time so we can get start, end time and tObs*/
    firstTimeStamp = catalog->data[0].header.epoch;
    // unused: LIGOTimeGPS lastTimeStamp = catalog->data[mObsCoh - 1].header.epoch;

    /* allocate memory for velocity vector */
    velV.length = mObsCoh;
    velV.data = NULL;
    velV.data = (REAL8Cart3Coor *)LALCalloc(mObsCoh, sizeof(REAL8Cart3Coor));

    /* allocate memory for timestamps vector */
    timeV.length = mObsCoh;
    timeV.data = NULL;
    timeV.data = (LIGOTimeGPS *)LALCalloc( mObsCoh, sizeof(LIGOTimeGPS));

    /* allocate memory for vector of time differences from start */
    timeDiffV.length = mObsCoh;
    timeDiffV.data = NULL; 
    timeDiffV.data = (REAL8 *)LALCalloc(mObsCoh, sizeof(REAL8));
  
    /* add wings for Doppler modulation and running median block size*/
    doppWings = (uvar_fStart + uvar_fSearchBand) * VTOT;    
    f_min = uvar_fStart - doppWings - (uvar_blocksRngMed + uvar_nfSizeCylinder) * deltaF;
    f_max = uvar_fStart + uvar_fSearchBand + doppWings + (uvar_blocksRngMed + uvar_nfSizeCylinder) * deltaF;

    /* read sft files making sure to add extra bins for running median */
    /* read the sfts */
    LAL_CALL( LALLoadMultiSFTs ( &status, &inputSFTs, catalog, f_min, f_max), &status);


    /* clean sfts if required */
    if ( LALUserVarWasSet( &uvar_linefiles ) )
      {
	RandomParams *randPar=NULL;
	FILE *fpRand=NULL;
	INT4 seed, ranCount;  

	if ( (fpRand = fopen("/dev/urandom", "r")) == NULL ) {
	  fprintf(stderr,"Error in opening /dev/urandom" ); 
	  exit(1);
	} 

	if ( (ranCount = fread(&seed, sizeof(seed), 1, fpRand)) != 1 ) {
	  fprintf(stderr,"Error in getting random seed" );
	  exit(1);
	}

	LAL_CALL ( LALCreateRandomParams (&status, &randPar, seed), &status );

	LAL_CALL( LALRemoveKnownLinesInMultiSFTVector ( &status, inputSFTs, uvar_maxBinsClean, uvar_blocksRngMed, uvar_linefiles, randPar), &status);

	LAL_CALL ( LALDestroyRandomParams (&status, &randPar), &status);
	fclose(fpRand);
      } /* end cleaning */


    /* SFT info -- assume all SFTs have same length */
    numifo = inputSFTs->length;
    binsSFT = inputSFTs->data[0]->data->data->length;
    sftFminBin = (INT4) floor(inputSFTs->data[0]->data[0].f0 * timeBase + 0.5);    


    LAL_CALL( LALDestroySFTCatalog( &status, &catalog ), &status);  	

  } /* end of sft reading block */



  /* get detector velocities weights vector, and timestamps */
  { 
    MultiNoiseWeights *multweight = NULL;    
    MultiPSDVector *multPSD = NULL;  
    UINT4 iIFO, iSFT, j;

    /*  get ephemeris  */
    edat = (EphemerisData *)LALCalloc(1, sizeof(EphemerisData));
    (*edat).ephiles.earthEphemeris = uvar_earthEphemeris;
    (*edat).ephiles.sunEphemeris = uvar_sunEphemeris;
    LAL_CALL( LALInitBarycenter( &status, edat), &status);


    /* normalize sfts */
    LAL_CALL( LALNormalizeMultiSFTVect (&status, &multPSD, inputSFTs, uvar_blocksRngMed), &status);

    /* set up weights */
    weightsV.length = mObsCoh;
    weightsV.data = (REAL8 *)LALCalloc(1, mObsCoh * sizeof(REAL8));

    /* initialize all weights to unity */
    LAL_CALL( LALHOUGHInitializeWeights( &status, &weightsV), &status);
   
    /* compute multi noise weights if required */
    if ( uvar_weighNoise ) {
      LAL_CALL ( LALComputeMultiNoiseWeights ( &status, &multweight, multPSD, uvar_blocksRngMed, 0), &status);
    }
    
    /* we are now done with the psd */
    LAL_CALL ( LALDestroyMultiPSDVector  ( &status, &multPSD), &status);

    /* get information about all detectors including velocity and timestamps */
    /* note that this function returns the velocity at the 
       mid-time of the SFTs -- should not make any difference */
    LAL_CALL ( LALGetMultiDetectorStates ( &status, &mdetStates, inputSFTs, edat), &status);


    /* copy the timestamps, weights, and velocity vector */
    for (j = 0, iIFO = 0; iIFO < numifo; iIFO++ ) {

      numsft = mdetStates->data[iIFO]->length;
      
      for ( iSFT = 0; iSFT < numsft; iSFT++, j++) {

	velV.data[j].x = mdetStates->data[iIFO]->data[iSFT].vDetector[0];
	velV.data[j].y = mdetStates->data[iIFO]->data[iSFT].vDetector[1];
	velV.data[j].z = mdetStates->data[iIFO]->data[iSFT].vDetector[2];

	if ( uvar_weighNoise )
	  weightsV.data[j] = multweight->data[iIFO]->data[iSFT];

	/* mid time of sfts */
	timeV.data[j] = mdetStates->data[iIFO]->data[iSFT].tGPS;

      } /* loop over SFTs */

    } /* loop over IFOs */

    if ( uvar_weighNoise ) {
      LAL_CALL( LALHOUGHNormalizeWeights( &status, &weightsV), &status);
    }

    /* compute the time difference relative to startTime for all SFTs */
    for(j = 0; j < mObsCoh; j++)
      timeDiffV.data[j] = XLALGPSDiff( timeV.data + j, &firstTimeStamp );

    if ( uvar_weighNoise ) {    
      LAL_CALL ( LALDestroyMultiNoiseWeights ( &status, &multweight), &status);
    }

  } /* end block for noise weights, velocity and time */
  

  
  /* calculate amplitude modulation weights if required */
  if (uvar_weighAM) 
    {
      MultiAMCoeffs *multiAMcoef = NULL;
      UINT4 iIFO, iSFT;
      SkyPosition skypos;      

      /* get the amplitude modulation coefficients */
      skypos.longitude = uvar_AlphaWeight;
      skypos.latitude = uvar_DeltaWeight;
      skypos.system = COORDINATESYSTEM_EQUATORIAL;
      LAL_CALL ( LALGetMultiAMCoeffs ( &status, &multiAMcoef, mdetStates, skypos), &status);
      
      /* loop over the weights and multiply them by the appropriate
	 AM coefficients */
      for ( k = 0, iIFO = 0; iIFO < numifo; iIFO++) {
	
	numsft = mdetStates->data[iIFO]->length;
	
	for ( iSFT = 0; iSFT < numsft; iSFT++, k++) {	  
	  
	  REAL8 a, b;
	  
	  a = multiAMcoef->data[iIFO]->a->data[iSFT];
	  b = multiAMcoef->data[iIFO]->b->data[iSFT];    
	  weightsV.data[k] *= (a*a + b*b);
	} /* loop over SFTs */
      } /* loop over IFOs */
      
      LAL_CALL( LALHOUGHNormalizeWeights( &status, &weightsV), &status);
      
      XLALDestroyMultiAMCoeffs ( multiAMcoef );
    } /* end AM weights calculation */


  /* misc. memory allocations */

  /* memory for one spindown */  
  pulsarTemplate.spindown.length = 1; 
  pulsarTemplate.spindown.data = NULL; 
  pulsarTemplate.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));

  /* copy template parameters */
  pulsarTemplate.spindown.data[0] = uvar_fdot;
  pulsarTemplate.f0 = uvar_Freq;
  pulsarTemplate.latitude = uvar_Delta;
  pulsarTemplate.longitude = uvar_Alpha;

  /* memory for f(t) vector */
  foft.length = mObsCoh;
  foft.data = NULL;
  foft.data = (REAL8 *)LALMalloc(mObsCoh*sizeof(REAL8));

  /* memory for peakgram */
  pg1.length = binsSFT;
  pg1.data = NULL;
  pg1.data = (UCHAR *)LALCalloc( binsSFT, sizeof(UCHAR));
 
  /* memory for number Count Vector */
  numberCountV.length = uvar_p;
  numberCountV.data = NULL;
  numberCountV.data = (REAL8 *)LALMalloc( uvar_p*sizeof(REAL8));

  /* block for calculating peakgram and number count */  
  {
    UINT4 iIFO, iSFT, ii, numberSFTp;
    INT4 ind;
    REAL8 sumWeightSquare;
    SFTtype  *sft;        
  
    /* compute mean and sigma for noise only */    
    /* first calculate the sum of the weights squared */
    sumWeightSquare = 0.0;
    for ( k = 0; k < (INT4)mObsCoh; k++)
      sumWeightSquare += weightsV.data[k] * weightsV.data[k];
    
    /* probability of selecting a peak expected mean and standard deviation for noise only */
    alphaPeak = exp( - uvar_peakThreshold);
    meanN = mObsCoh* alphaPeak; 
    sigmaN = sqrt(sumWeightSquare * alphaPeak * (1.0 - alphaPeak));
        
 
   /* the received frequency as a function of time  */
   LAL_CALL( ComputeFoft(&status, &foft, &pulsarTemplate, &timeDiffV, &velV, timeBase), &status);   
   
   LAL_CALL(SplitSFTs(&status, &weightsV, &chi2Params), &status);
   
   /* loop over SFT, generate peakgram and get number count */
   UINT4 j;
   j=0;
   iIFO=0;
   iSFT=0;
   
   numsft = mdetStates->data[iIFO]->length;
  
     
      for (k=0 ; k<uvar_p ; k++ ){
       
         numberSFTp=chi2Params.numberSFTp[k];
         numberCount = 0;

         for (ii=0 ; (ii < numberSFTp)&&(iIFO<numifo) ; ii++) {
	   
	    sft = inputSFTs->data[iIFO]->data + iSFT;

            LAL_CALL (SFTtoUCHARPeakGram( &status, &pg1, sft, uvar_peakThreshold), &status);	    

            ind = floor( foft.data[j]*timeBase - sftFminBin + 0.5); 
            
	    numberCount += pg1.data[ind]*weightsV.data[j];
	    
	    j++;

	    iSFT++;

	    if (iSFT >= numsft){
		
		iIFO++;
		iSFT=0;
		if (iIFO<numifo){
		numsft = mdetStates->data[iIFO]->length;
		}
	    }

         } /* loop over SFTs */
       
         numberCountV.data[k]=numberCount;
       	  
      } /* loop over blocks */
  
  }
  
/* Chi2 Test */
  {
      REAL8   eta;                /* Auxiliar variable */ 
      REAL8   nj, sumWeightj, sumWeightSquarej;
                     

      numberCountTotal=0;
      chi2=0;
 
      for(k=0; k<uvar_p ; k++){
	  numberCountTotal += numberCountV.data[k];
      }
      
      eta=numberCountTotal/mObsCoh;
      INT4 j;
      for(j=0 ; j<(uvar_p) ; j++){
	  
	  nj=numberCountV.data[j];
	  sumWeightj=chi2Params.sumWeight[j];
	  sumWeightSquarej=chi2Params.sumWeightSquare[j];
	  
	  chi2 += (nj-sumWeightj*eta)*(nj-sumWeightj*eta)/(sumWeightSquarej*eta*(1-eta));
      }
   }


  
   
    fp = fopen(uvar_outfile , "w");
    setvbuf(fp, (char *)NULL, _IOLBF, 0);
    fprintf(fp, "%g  %g  %g  %g %g  %g  %g  %g \n", (numberCountTotal - meanN)/sigmaN, meanN ,sigmaN, chi2, uvar_Freq, uvar_Alpha, uvar_Delta, uvar_fdot);
/*    fprintf(stdout, "%g  %g  %g  %g %g  %g  %g  %g \n", (numberCountTotal - meanN)/sigmaN, meanN ,sigmaN, chi2, uvar_Freq, uvar_Alpha, uvar_Delta, uvar_fdot);*/
    fclose(fp);
  


  /* free memory */
  LALFree(pulsarTemplate.spindown.data);  
  LALFree(timeV.data);
  LALFree(timeDiffV.data);
  LALFree(foft.data);
  LALFree(velV.data);

  LALFree(weightsV.data);

  XLALDestroyMultiDetectorStateSeries ( mdetStates );

  LALFree(edat->ephemE);
  LALFree(edat->ephemS);
  LALFree(edat);

  LAL_CALL (LALDestroyMultiSFTVector(&status, &inputSFTs), &status );
  LALFree(pg1.data);
  
  LALFree(numberCountV.data);

  LALFree(chi2Params.numberSFTp);
  LALFree(chi2Params.sumWeight);
  LALFree(chi2Params.sumWeightSquare);

  LAL_CALL (LALDestroyUserVars(&status), &status);

  LALCheckMemoryLeaks();

  if ( lalDebugLevel )
    REPORTSTATUS ( &status);

  return status.statusCode;
}
示例#10
0
int main(int argc, char *argv[]){ 

  static LALStatus       status;  /* LALStatus pointer */ 

  static MultiSFTVector  *inputSFTs = NULL;
  static SFTCatalog *catalog = NULL;
  static SFTCatalog thisCatalog;
  static SFTConstraints constraints;


  /* 09/09/05 gam; randPar now a parameter for LALCleanCOMPLEX8SFT */
  FILE *fp=NULL;   
  INT4 seed, ranCount;
  RandomParams *randPar=NULL; 
  UINT4 k, j;  

  /* user input variables */
  BOOLEAN uvar_help;
  LALStringVector *uvar_linefiles=NULL; /* files with harmonics info */
  CHAR *uvar_sftDir;    /* directory for unclean sfts */
  CHAR *uvar_outDir;   /* directory for cleaned sfts */
  REAL8 uvar_fMin, uvar_fMax;
  INT4  uvar_window, uvar_maxBins;

  /* set defaults */

  uvar_help = FALSE;
  uvar_sftDir = (CHAR *)LALMalloc(256 * sizeof(CHAR));
  strcpy(uvar_sftDir, INPUTSFTDIR);

  uvar_outDir = (CHAR *)LALMalloc(256 * sizeof(CHAR));
  strcpy(uvar_outDir, OUTPUTSFTDIR);

  uvar_fMin = STARTFREQ;
  uvar_fMax = ENDFREQ;  
  uvar_window = WINDOWSIZE;
  uvar_maxBins = MAXBINS;

  /* register user input variables */
  LAL_CALL( LALRegisterBOOLUserVar(   &status, "help",     'h',UVAR_HELP,     "Print this message",     &uvar_help),   &status);  
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "sftDir",   'i',UVAR_OPTIONAL, "Input SFT file pattern", &uvar_sftDir), &status);
  LAL_CALL( LALRegisterSTRINGUserVar( &status, "outDir",   'o',UVAR_OPTIONAL, "Output SFT Directory",   &uvar_outDir), &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "fMin",      0, UVAR_OPTIONAL, "start Frequency",        &uvar_fMin),   &status);
  LAL_CALL( LALRegisterREALUserVar(   &status, "fMax",      0, UVAR_OPTIONAL, "Max Frequency Band",     &uvar_fMax),   &status);
  LAL_CALL( LALRegisterINTUserVar(    &status, "window",   'w',UVAR_OPTIONAL, "Window size",            &uvar_window), &status);
  LAL_CALL( LALRegisterINTUserVar(    &status, "maxBins",  'm',UVAR_OPTIONAL, "Max. bins to clean",     &uvar_maxBins),&status);
  LAL_CALL( LALRegisterLISTUserVar(   &status, "linefiles", 0, UVAR_OPTIONAL, "List of linefiles (filenames must contain IFO name)", &uvar_linefiles),  &status);



  /* read all command line variables */
  LAL_CALL( LALUserVarReadAllInput(&status, argc, argv), &status);

  /* exit if help was required */
  if (uvar_help)
    exit(0); 
  
  /* set detector constraint */
  constraints.detector = NULL;

  /* get sft catalog */
  LAL_CALL( LALSFTdataFind( &status, &catalog, uvar_sftDir, &constraints), &status);
  if ( (catalog == NULL) || (catalog->length == 0) ) {
    fprintf (stderr,"Unable to match any SFTs with pattern '%s'\n", uvar_sftDir );
    exit(1);
  }
  thisCatalog.length = 1;
  fprintf(stdout, "%d\n",catalog->length);

  /* get a new seed value, and use it to create a new random parameter structure */
  fp=fopen("/dev/urandom", "r");
  if (!fp) 
    { 
      fprintf(stderr,"Error in opening /dev/urandom \n"); 
      exit(1); 
    } 
  ranCount = fread(&seed, sizeof(seed), 1, fp);
  fclose(fp);
  if (!(ranCount==1)) 
    { 
      fprintf(stderr,"Error in reading random seed \n"); 
      exit(1); 
    } 
  LAL_CALL ( LALCreateRandomParams (&status, &randPar, seed), &status );
  
  /* loop over sfts and clean them -- load one sft at a time */
  for (j=0; j<catalog->length; j++) {

    thisCatalog.data = catalog->data + j;
  
    /* read the sfts */
    LAL_CALL( LALLoadMultiSFTs ( &status, &inputSFTs, &thisCatalog, uvar_fMin, uvar_fMax), &status);    
    
    /* clean  lines */
    if ( LALUserVarWasSet( &uvar_linefiles ) ) {
      LAL_CALL( LALRemoveKnownLinesInMultiSFTVector ( &status, inputSFTs, uvar_maxBins, 
						      uvar_window, uvar_linefiles, randPar), &status);
    }
    
    /* write output */
    for (k = 0; k < inputSFTs->length; k++) {
      LAL_CALL( LALWriteSFTVector2Dir ( &status, inputSFTs->data[k], uvar_outDir, "cleaned", "cleaned"), &status);
    }

    LAL_CALL( LALDestroyMultiSFTVector(&status, &inputSFTs), &status );

  } /* end loop over sfts */

  /* Free memory */
  LAL_CALL( LALDestroySFTCatalog( &status, &catalog ), &status);
  LAL_CALL( LALDestroyUserVars(&status), &status);
  LAL_CALL( LALDestroyRandomParams (&status, &randPar), &status);

  LALCheckMemoryLeaks(); 

  return 0;
}
示例#11
0
int main( void )
{
  UINT4 resamplefac = 4;
  UINT4 seglen = 64 * 1024; /* after resampling */
  UINT4 numovrlpseg = 10; /* after resampling */
  UINT4 stride = seglen / 2; /* after resampling */
  UINT4 reclen = numovrlpseg * stride + stride; /* after resampling */
  /* UINT4 numovrlpseg = 8; */ /* after resampling */
  /* UINT4 stride = seglen; */ /* after resampling */
  /* UINT4 reclen = numovrlpseg * stride; */ /* after resampling */

  static LALStatus status;

  static AverageSpectrumParams  specpar;
  static REAL4FrequencySeries   fseries;
  static REAL4TimeSeries        tseries;
  static RandomParams          *randpar;
  static ResampleTSParams       resamplepar;
  static PassBandParamStruc     highpasspar;
  REAL8 avg;
  UINT4 j;
  UINT4 k;
  FILE *fp;


  /* allocate memory for time and frequency series */
  tseries.deltaT = 0.1;
  LALCreateVector( &status, &tseries.data, reclen * resamplefac );
  TESTSTATUS( &status );
  LALCreateVector( &status, &fseries.data, seglen / 2 + 1 );
  TESTSTATUS( &status );

  for ( j = 0; j < tseries.data->length; ++j )
    tseries.data->data[j] = sin( 0.1 * j );
  /*
  memset( tseries.data->data, 0,
      tseries.data->length * sizeof( *tseries.data->data ) );
  tseries.data->data[seglen/2-1] = 1;
  tseries.data->data[seglen/2] = 1;
  tseries.data->data[seglen/2+1] = 1;
  */
  /* create white Gaussian noise */
  LALCreateRandomParams( &status, &randpar, 0 );
  TESTSTATUS( &status );
  LALNormalDeviates( &status, tseries.data, randpar );
  TESTSTATUS( &status );
  LALDestroyRandomParams( &status, &randpar );
  TESTSTATUS( &status );

  /* resample */
  resamplepar.deltaT = resamplefac * tseries.deltaT;
  resamplepar.filterType = defaultButterworth;
  LALResampleREAL4TimeSeries( &status, &tseries, &resamplepar );
  TESTSTATUS( &status );

  /* do some simple colouring: high-pass filter */
  highpasspar.nMax = 4;
  highpasspar.f1   = -1;
  highpasspar.a1   = -1;
  highpasspar.f2   = 0.1 / tseries.deltaT; /* ~20% of Nyquist */
  highpasspar.a2   = 0.9; /* this means 10% attenuation at f2 */
  LALDButterworthREAL4TimeSeries( &status, &tseries, &highpasspar );
  TESTSTATUS( &status );

  specpar.method  = useMean;
  specpar.overlap = seglen - stride;

  LALCreateForwardRealFFTPlan( &status, &specpar.plan, seglen, 0 );
  TESTSTATUS( &status );
  specpar.window = XLALCreateRectangularREAL4Window(seglen);

  /* compute spectrum */
  LALREAL4AverageSpectrum( &status, &fseries, &tseries, &specpar );
  TESTSTATUS( &status );

  /* output results */
  fp = fopen( "out1.dat", "w" );
  for ( k = 0; k < fseries.data->length; ++k )
    fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] );
  fclose( fp );

  /* compute average */
  avg = 0;
  for ( k = 1; k < fseries.data->length - 1; ++k )
    avg += fseries.data->data[k];
  avg /= ( fseries.data->length - 2 );
  printf( "lal mean:\t%g\n", avg );

  /* use the xlal function */
  XLALREAL4AverageSpectrumWelch( &fseries, &tseries, seglen, stride,
      specpar.window, specpar.plan );
  if ( xlalErrno )
  {
    XLAL_PERROR();
    exit( 1 );
  }

  /* output results */
  fp = fopen( "out2.dat", "w" );
  for ( k = 0; k < fseries.data->length; ++k )
    fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] );
  fclose( fp );

  /* compute average */
  avg = 0;
  for ( k = 1; k < fseries.data->length - 1; ++k )
    avg += fseries.data->data[k];
  avg /= ( fseries.data->length - 2 );
  printf( "xlal mean:\t%g\n", avg );

  /* median-mean method */
  XLALREAL4AverageSpectrumMedianMean( &fseries, &tseries, seglen, stride,
      specpar.window, specpar.plan );
  if ( xlalErrno )
  {
    XLAL_PERROR();
    exit( 1 );
  }

  /* output results */
  fp = fopen( "out3.dat", "w" );
  for ( k = 0; k < fseries.data->length; ++k )
    fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] );
  fclose( fp );

  /* compute average */
  avg = 0;
  for ( k = 1; k < fseries.data->length - 1; ++k )
    avg += fseries.data->data[k];
  avg /= ( fseries.data->length - 2 );
  printf( "med mean:\t%g\n", avg );

  /* median method */
  XLALREAL4AverageSpectrumMedian( &fseries, &tseries, seglen, stride,
      specpar.window, specpar.plan );
  if ( xlalErrno )
  {
    XLAL_PERROR();
    exit( 1 );
  }

  /* output results */
  fp = fopen( "out4.dat", "w" );
  for ( k = 0; k < fseries.data->length; ++k )
    fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] );
  fclose( fp );

  /* compute average */
  avg = 0;
  for ( k = 1; k < fseries.data->length - 1; ++k )
    avg += fseries.data->data[k];
  avg /= ( fseries.data->length - 2 );
  printf( "median:\t\t%g\n", avg );

  /* cleanup */
  XLALDestroyREAL4Window( specpar.window );
  LALDestroyRealFFTPlan( &status, &specpar.plan );
  TESTSTATUS( &status );
  LALDestroyVector( &status, &fseries.data );
  TESTSTATUS( &status );
  LALDestroyVector( &status, &tseries.data );
  TESTSTATUS( &status );

  /* exit */
  LALCheckMemoryLeaks();
  return 0;
}
示例#12
0
文件: minj.c 项目: Solaro/lalsuite
int main( int argc, char *argv[] )
{
  LALStatus             status = blank_status;
  const INT4            S2StartTime = 729273613; /* Feb 14 2003 16:00:00 UTC */
  const INT4            S2StopTime  = 734367613; /* Apr 14 2003 15:00:00 UTC */

  /* command line options */
  LIGOTimeGPS   gpsStartTime = {S2StartTime, 0};
  LIGOTimeGPS   gpsEndTime   = {S2StopTime, 0};
  REAL8         meanTimeStep = 2630 / LAL_PI;
  REAL8         timeInterval = 0;
  UINT4         randSeed = 1;
  CHAR         *userTag = NULL;
  REAL4         minMass = 0.1;
  REAL4         maxMass = 1.0;
  REAL4         r_core = 5.0;     /* kpc core radius */
  REAL4         r_max = 50.0;     /* kpc halo radius */
  REAL4         q = 1.0;          /* flatten halo */

  /* program variables */
  RandomParams *randParams = NULL;
  REAL4  u;
  REAL4  deltaM;

  int i, stat;
  const int maxIter = 1000;
  const double tol = 1e-6;
  const gsl_root_fsolver_type *solver_type;
  gsl_root_fsolver *solver;
  gsl_function pdf;

  struct halo_pdf_params pdf_params;

  double r_lo, r_hi, r;
  double cosphi, sinphi;
  double pdf_norm;

  GalacticInspiralParamStruc galacticPar;

  /* xml output data */
  CHAR                  fname[256];
  MetadataTable         proctable;
  MetadataTable         procparams;
  MetadataTable         injections;
  ProcessParamsTable   *this_proc_param;
  SimInspiralTable     *this_inj = NULL;
  LIGOLwXMLStream       xmlfp;
  UINT4                 outCompress = 0;

  /* LALgetopt arguments */
  struct LALoption long_options[] =
  {
    {"help",                    no_argument,       0,                'h'},
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"write-compress",          no_argument,       &outCompress,      1 },
    {"gps-start-time",          required_argument, 0,                'a'},
    {"gps-end-time",            required_argument, 0,                'b'},
    {"time-step",               required_argument, 0,                't'},
    {"time-interval",                required_argument, 0,                     'i'},
    {"seed",                    required_argument, 0,                's'},
    {"minimum-mass",            required_argument, 0,                'A'},
    {"maximum-mass",            required_argument, 0,                'B'},
    {"core-radius",             required_argument, 0,                'p'},
    {"flatten-halo",            required_argument, 0,                'q'},
    {"halo-radius",             required_argument, 0,                'r'},
    {"user-tag",                required_argument, 0,                'Z'},
    {"userTag",                 required_argument, 0,                'Z'},
    {0, 0, 0, 0}
  };
  int c;

  /* set up inital debugging values */
  lal_errhandler = LAL_ERR_EXIT;

  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) 
    calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  if (strcmp(CVS_REVISION,"$Revi" "sion$"))
    {
      XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME,
          CVS_REVISION, CVS_SOURCE, CVS_DATE, 0);
    }
  else
    {
      XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME,
          lalappsGitCommitID, lalappsGitGitStatus, lalappsGitCommitDate, 0);
    }
  snprintf( proctable.processTable->comment, LIGOMETA_COMMENT_MAX, " " );
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) 
    calloc( 1, sizeof(ProcessParamsTable) );
  

  /*
   *
   * parse command line arguments
   *
   */

     
  while ( 1 )
  {
    /* LALgetopt_long stores long option here */
    int option_index = 0;
    long int gpsinput;
    size_t LALoptarg_len;

    c = LALgetopt_long_only( argc, argv,
        "a:A:b:B:hi:p:q:r:s:t:vZ:", long_options, &option_index );

    /* detect the end of the options */
    if ( c == - 1 )
    {
      break;
    }

    switch ( c )
    {
      case 0:
        /* if this option set a flag, do nothing else now */
        if ( long_options[option_index].flag != 0 )
        {
          break;
        }
        else
        {
          fprintf( stderr, "error parsing option %s with argument %s\n",
              long_options[option_index].name, LALoptarg );
          exit( 1 );
        }
        break;

      case 'a':
        gpsinput = atol( LALoptarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsStartTime.gpsSeconds = gpsinput;

        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 'b':
        gpsinput = atol( LALoptarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsEndTime.gpsSeconds = gpsinput;
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 's':
        randSeed = atoi( LALoptarg );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%d", randSeed );
        break;

      case 't':
        meanTimeStep = (REAL8) atof( LALoptarg );
        if ( meanTimeStep <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time step must be > 0: (%le seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "float", 
              "%le", meanTimeStep );
        break;

      case 'i':
        timeInterval = atof( LALoptarg );
        if ( timeInterval < 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time interval must be >= 0: (%le seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%le", timeInterval );
        break;

      case 'A':
        minMass = (REAL4) atof( LALoptarg );
        if ( minMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "miniumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, minMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", minMass );
        break;

      case 'B':
        maxMass = (REAL4) atof( LALoptarg );
        if ( maxMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "maxiumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, maxMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", maxMass );
        break;

      case 'p':
        /* core-radius */
        r_core = (REAL4) atof( LALoptarg );
        if ( r_core <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "galactic core radius must be > 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, r_core );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", r_core );
        break;

      case 'q':
        /* flatten-halo */
        q = (REAL4) atof( LALoptarg );
        if ( q <= 0 || q > 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "halo flattening parameter must be in range (0,1]: "
              "(%f specified)\n",
              long_options[option_index].name, q );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", q );
        break;

      case 'r':
        /* max halo radius */
        r_max = (REAL4) atof( LALoptarg );
        if ( r_max <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "halo radius must be greater than 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, r_max );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", r_max );
        break;

      case 'Z':
        /* create storage for the usertag */
        LALoptarg_len = strlen( LALoptarg ) + 1;
        userTag = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR) );
        memcpy( userTag, LALoptarg, LALoptarg_len );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "string", "%s", LALoptarg );
        break;

      case 'v':
        vrbflg = 1;
        break;

      case 'h':
        fprintf( stderr, USAGE );
        exit( 0 );
        break;

      case '?':
        fprintf( stderr, USAGE );
        exit( 1 );
        break;

      default:
        fprintf( stderr, "unknown error while parsing options\n" );
        fprintf( stderr, USAGE );
        exit( 1 );
    }
  }

  if ( LALoptind < argc )
  {
    fprintf( stderr, "extraneous command line arguments:\n" );
    while ( LALoptind < argc )
    {
      fprintf ( stderr, "%s\n", argv[LALoptind++] );
    }
    exit( 1 );
  }


  /*
   *
   * initialization
   *
   */


  /* initialize the random number generator */
  LAL_CALL( LALCreateRandomParams( &status, &randParams, randSeed ), &status );

  /* initialize the gsl solver with the spatial pdf */
  pdf.function = &halo_pdf;
  pdf.params   = &pdf_params;
  solver_type = gsl_root_fsolver_bisection;
  solver = gsl_root_fsolver_alloc( solver_type );
  pdf_params.a = r_core;

  /* normalization for the spatial pdf */
  pdf_norm = r_max - r_core * atan2( r_max, r_core );

  /* mass range */
  deltaM = maxMass - minMass;

  /* null out the head of the linked list */
  injections.simInspiralTable = NULL;

  /* create the output file name */
  if ( userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml.gz",
        randSeed, userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( userTag && !outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml", 
        randSeed, userTag, gpsStartTime.gpsSeconds, 
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( !userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml.gz",
        randSeed, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml", 
        randSeed, gpsStartTime.gpsSeconds, 
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }


  /*
   *
   * loop over duration of desired output times
   *
   */


  while ( XLALGPSCmp( &gpsStartTime, &gpsEndTime ) < 0 )
  {
    /* uniformly distributed masses */
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.m1 = minMass + u * deltaM;
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.m2 = minMass + u * deltaM;
    
    /* spatial distribution */
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    pdf_params.u = u * pdf_norm;

    r_lo = 0.0;
    r_hi = r_max;
    gsl_root_fsolver_set( solver, &pdf, r_lo, r_hi );

    for ( i = 0; i < maxIter; ++i )
    {
      gsl_root_fsolver_iterate( solver );
      r = gsl_root_fsolver_root( solver );
      r_lo = gsl_root_fsolver_x_lower( solver );
      r_hi = gsl_root_fsolver_x_upper( solver );
      stat = gsl_root_test_interval( r_lo, r_hi, 0, tol );
      if ( stat == GSL_SUCCESS )
        break;
    }

    if ( stat != GSL_SUCCESS )
    {
      fprintf( stderr, "could not find root after %d iterations\n", maxIter );
      exit( 1 );
    }

    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    sinphi = 2.0 * u - 1.0;
    cosphi = sqrt( 1.0 - sinphi*sinphi );
    
    galacticPar.rho = r * cosphi;
    galacticPar.z   = q * r * sinphi;

    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.lGal = LAL_TWOPI * u;    

    if ( vrbflg ) fprintf( stdout, "%e %e %e %e %e\n", 
        galacticPar.m1, galacticPar.m2,
        galacticPar.rho * cos( galacticPar.lGal ),
        galacticPar.rho * sin( galacticPar.lGal ),
        galacticPar.z );

    /* create the sim_inspiral table */
    if ( injections.simInspiralTable )
    {
      this_inj = this_inj->next = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }
    else
    {
      injections.simInspiralTable = this_inj = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }

    /* set the geocentric end time of the injection */
    galacticPar.geocentEndTime = gpsStartTime;
    if ( timeInterval )
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      XLALGPSAdd( &(galacticPar.geocentEndTime), u * timeInterval );
    }

    /* populate the sim_inspiral table */
    LAL_CALL( LALGalacticInspiralParamsToSimInspiralTable( &status,
          this_inj, &galacticPar, randParams ), &status );

    /* set the source and waveform fields */
    snprintf( this_inj->source, LIGOMETA_SOURCE_MAX, "MW" );
    snprintf( this_inj->waveform, LIGOMETA_WAVEFORM_MAX, 
        "GeneratePPNtwoPN" );

    /* increment the injection time */
    XLALGPSAdd( &gpsStartTime, meanTimeStep );
  } /* end loop over injection times */

  /* destroy random parameters */
  LAL_CALL( LALDestroyRandomParams( &status, &randParams ), &status );


  /*
   *
   * write output to LIGO_LW XML file
   *
   */


  /* open the xml file */
  memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
  LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlfp, fname ), &status );

  /* write the process table */
  snprintf( proctable.processTable->ifos, LIGOMETA_IFOS_MAX, "H1H2L1" );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_table ), 
      &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, proctable, 
        process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  free( proctable.processTable );

  /* free the unused process param entry */
  this_proc_param = procparams.processParamsTable;
  procparams.processParamsTable = procparams.processParamsTable->next;
  free( this_proc_param );

  /* write the process params table */
  if ( procparams.processParamsTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_params_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, procparams, 
          process_params_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
    while( procparams.processParamsTable )
    {
      this_proc_param = procparams.processParamsTable;
      procparams.processParamsTable = this_proc_param->next;
      free( this_proc_param );
    }
  }

  /* write the sim_inspiral table */
  if ( injections.simInspiralTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, sim_inspiral_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, injections, 
          sim_inspiral_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  }
  while ( injections.simInspiralTable )
  {
    this_inj = injections.simInspiralTable;
    injections.simInspiralTable = injections.simInspiralTable->next;
    LALFree( this_inj );
  }

  /* close the injection file */
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlfp ), &status );

  /* check for memory leaks and exit */
  LALCheckMemoryLeaks();
  return 0;
}
/* void RunGeneratePulsarSignalTest(LALStatus *status, int argc, char **argv) */ /* 02/02/05 gam */
void RunGeneratePulsarSignalTest(LALStatus *status)
{
  INT4    i, j, k;         /* all purpose indices */
  INT4    iSky = 0;        /* for loop over sky positions */
  INT4    jDeriv = 0;      /* for loop over spindowns */
  INT4    testNumber = 0;  /* which test is being run */

  /* The input and output structs used by the functions being tested */
  PulsarSignalParams *pPulsarSignalParams = NULL;
  REAL4TimeSeries *signalvec = NULL;
  SFTParams *pSFTParams = NULL;
  SkyConstAndZeroPsiAMResponse *pSkyConstAndZeroPsiAMResponse;
  SFTandSignalParams *pSFTandSignalParams;
  SFTVector *outputSFTs = NULL;
  SFTVector *fastOutputSFTs = NULL;
  REAL4 renorm; /* to renormalize SFTs to account for different effective sample rates */

  /* containers for detector and ephemeris data */
  LALDetector cachedDetector;
  CHAR IFO[6] = "LHO";
  EphemerisData *edat = NULL;

  char earthFile[] = TEST_DATA_DIR "earth00-19-DE405.dat.gz";
  char sunFile[]   = TEST_DATA_DIR "sun00-19-DE405.dat.gz";

  /* containers for sky position and spindown data */
  REAL8 **skyPosData;
  REAL8 **freqDerivData;
  INT4 numSkyPosTotal = 8;
  INT4 numSpinDown = 1;
  INT4 numFreqDerivTotal = 2;
  INT4 numFreqDerivIncludingNoSpinDown; /* set below */
  INT4 iFreq = 0;
  REAL8 cosTmpDEC;
  REAL8 tmpDeltaRA;
  REAL8 DeltaRA = 0.01;
  REAL8 DeltaDec = 0.01;
  REAL8 DeltaFDeriv1 = -1.0e-10;
  REAL8 DeltaFDeriv2 = 0.0;
  REAL8 DeltaFDeriv3 = 0.0;
  REAL8 DeltaFDeriv4 = 0.0;
  REAL8 DeltaFDeriv5 = 0.0;

  /* containers for number of SFTs, times to generate SFTs, reference time, and gap */
  INT4 numSFTs = 4;
  REAL8 f0SFT = 943.12;
  REAL8 bandSFT = 0.5;
  UINT4 gpsStartTimeSec = 765432109; /* GPS start time of data requested seconds; example = Apr 08 2004 04:01:36 UTC */
  UINT4 gpsStartTimeNan = 0;          /* GPS start time of data requested nanoseconds */
  LIGOTimeGPSVector *timeStamps;
  LIGOTimeGPS GPSin;   /* holder for reference-time for pulsar parameters at the detector; will convert to SSB! */
  REAL8 sftGap = 73.0; /* extra artificial gap between SFTs */
  REAL8 tSFT   = 1800.0;
  REAL8 duration = tSFT + (numSFTs - 1)*(tSFT + sftGap);
  INT4 nBinsSFT = (INT4)(bandSFT*tSFT + 0.5);

  /* additional parameters that determine what signals to test; note f0SGNL and bandSGNL must be compatible with f0SFT and bandSFT */
  REAL8 f0SGNL = f0SFT + bandSFT/2.0;
  REAL8 dfSGNL = 1.0/tSFT;
  REAL8 bandSGNL = 0.005;
  INT4  nBinsSGNL = (INT4)(bandSGNL*tSFT + 0.5);
  INT4  nsamples = 18000; /* nsamples from SFT header; 2 x this would be the effective number of time samples used to create an SFT from raw data */
  INT4  Dterms = 3;       /* 09/07/05 gam; use Dterms to fill in SFT bins with fake data as per LALDemod else fill in bin with zero */
  REAL8 h_0 = 7.0e-22;    /* Source amplitude; use arbitrary small number for default */
  REAL8 cosIota;        /* cosine of inclination angle iota of the source */

  /* variables for comparing differences */
  REAL4 maxDiffSFTMod, diffAtMaxPower;
  REAL4 overallMaxDiffSFTMod;
  REAL4 maxMod, fastMaxMod;
  INT4  jMaxMod, jFastMaxMod;
  REAL4 tmpDiffSFTMod, sftMod, fastSFTMod;
  REAL4 smallMod = 1.e-30;
  REAL4 epsDiffMod;
  REAL4 epsBinErrorRate;   /* 10/12/04 gam; Allowed bin error rate */
  INT4  binErrorCount = 0; /* 10/12/04 gam; Count number of bin errors  */

  /* randval is always set to a default value or given a random value to generate certain signal parameters or mismatch */
  REAL4 randval;
  #ifdef INCLUDE_RANDVAL_MISMATCH
   INT4 seed=0;
   INT4 rndCount;
   RandomParams *randPar=NULL;
   FILE *fpRandom;
  #endif

  INITSTATUS(status);
  ATTATCHSTATUSPTR(status);

  /* generate timeStamps */
  timeStamps = (LIGOTimeGPSVector *)LALMalloc(sizeof(LIGOTimeGPSVector));
  timeStamps->data =(LIGOTimeGPS *)LALMalloc (numSFTs*sizeof(LIGOTimeGPS));
  timeStamps->length = numSFTs;
  for (i = 0; i < numSFTs; i++) {
      timeStamps->data[i].gpsSeconds = gpsStartTimeSec + (UINT4)(i*(tSFT + sftGap));
      timeStamps->data[i].gpsNanoSeconds = 0;
  } /* for i < numSFTs */

  /* generate skyPosData */
  skyPosData=(REAL8 **)LALMalloc(numSkyPosTotal*sizeof(REAL8 *));
  for(iSky=0;iSky<numSkyPosTotal;iSky++)
  {
        skyPosData[iSky] = (REAL8 *)LALMalloc(2*sizeof(REAL8));
        /* Try fairly random sky positions skyPosData[iSky][0] = RA, skyPosData[iSky][1] = DEC */
        if (iSky == 0) {
          skyPosData[iSky][0] = 0.02*LAL_TWOPI;
          skyPosData[iSky][1] = 0.03*LAL_PI/2.0;
        } else if (iSky == 1) {
          skyPosData[iSky][0] = 0.23*LAL_TWOPI;
          skyPosData[iSky][1] = -0.57*LAL_PI/2.0;
        } else if (iSky == 2) {
          skyPosData[iSky][0] = 0.47*LAL_TWOPI;
          skyPosData[iSky][1] = 0.86*LAL_PI/2.0;
        } else if (iSky == 3) {
          skyPosData[iSky][0] = 0.38*LAL_TWOPI;
          skyPosData[iSky][1] = -0.07*LAL_PI/2.0;
        } else if (iSky == 4) {
          skyPosData[iSky][0] = 0.65*LAL_TWOPI;
          skyPosData[iSky][1] = 0.99*LAL_PI/2.0;
        } else if (iSky == 5) {
          skyPosData[iSky][0] = 0.72*LAL_TWOPI;
          skyPosData[iSky][1] = -0.99*LAL_PI/2.0;
        } else if (iSky == 6) {
          skyPosData[iSky][0] = 0.81*LAL_TWOPI;
          skyPosData[iSky][1] = 0.19*LAL_PI/2.0;
        } else if (iSky == 7) {
          skyPosData[iSky][0] = 0.99*LAL_TWOPI;
          skyPosData[iSky][1] = 0.01*LAL_PI/2.0;
        } else {
          skyPosData[iSky][0] = 0.0;
          skyPosData[iSky][1] = 0.0;
        } /* END if (k == 0) ELSE ... */
  } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */

  freqDerivData = NULL; /* 02/02/05 gam */
  if (numSpinDown > 0) {
    freqDerivData=(REAL8 **)LALMalloc(numFreqDerivTotal*sizeof(REAL8 *));
    for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) {
        freqDerivData[jDeriv] = (REAL8 *)LALMalloc(numSpinDown*sizeof(REAL8));
        if (jDeriv == 0) {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 0.0;
          }
        } else if (jDeriv == 1) {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 1.e-9; /* REALLY THIS IS ONLY GOOD FOR numSpinDown = 1; */
          }
        } else {
          for(k=0;k<numSpinDown;k++) {
            freqDerivData[jDeriv][k] = 0.0;
          }
        } /* END if (k == 0) ELSE ... */
    } /* END for(jDeriv=0;jDeriv<numFreqDerivTotal;jDeriv++) */
    numFreqDerivIncludingNoSpinDown = numFreqDerivTotal;
  } else {
    numFreqDerivIncludingNoSpinDown = 1;  /* Even if numSpinDown = 0 still need to count case of zero spindown. */
  }  /* END if (numSpinDown > 0) ELSE ... */

  /* Initialize ephemeris data */
  XLAL_CHECK_LAL (status, ( edat = XLALInitBarycenter( earthFile, sunFile ) ) != NULL, XLAL_EFUNC);

  /* Allocate memory for PulsarSignalParams and initialize */
  pPulsarSignalParams = (PulsarSignalParams *)LALMalloc(sizeof(PulsarSignalParams));
  pPulsarSignalParams->pulsar.position.system = COORDINATESYSTEM_EQUATORIAL;
  pPulsarSignalParams->pulsar.spindown = NULL;
  if (numSpinDown > 0) {
    LALDCreateVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown),((UINT4)numSpinDown));
    CHECKSTATUSPTR (status);
  }
  pPulsarSignalParams->orbit.asini = 0 /* isolated pulsar */;
  pPulsarSignalParams->transfer = NULL;
  pPulsarSignalParams->dtDelayBy2 = 0;
  pPulsarSignalParams->dtPolBy2 = 0;
  /* Set up pulsar site */
  if (strstr(IFO, "LHO")) {
       cachedDetector = lalCachedDetectors[LALDetectorIndexLHODIFF];
  } else if (strstr(IFO, "LLO")) {
       cachedDetector = lalCachedDetectors[LALDetectorIndexLLODIFF];
  } else if (strstr(IFO, "GEO")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexGEO600DIFF];
  } else if (strstr(IFO, "VIRGO")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexVIRGODIFF];
  } else if (strstr(IFO, "TAMA")) {
      cachedDetector = lalCachedDetectors[LALDetectorIndexTAMA300DIFF];
  } else {
      /* "Invalid or null IFO" */
      ABORT( status, GENERATEPULSARSIGNALTESTC_EIFO, GENERATEPULSARSIGNALTESTC_MSGEIFO);
  }
  pPulsarSignalParams->site = &cachedDetector;
  pPulsarSignalParams->ephemerides = edat;
  pPulsarSignalParams->startTimeGPS.gpsSeconds = (INT4)gpsStartTimeSec;
  pPulsarSignalParams->startTimeGPS.gpsNanoSeconds = (INT4)gpsStartTimeNan;
  pPulsarSignalParams->duration = (UINT4)duration;
  pPulsarSignalParams->samplingRate = (REAL8)ceil(2.0*bandSFT); /* Make sampleRate an integer so that T*samplingRate = integer for integer T */
  pPulsarSignalParams->fHeterodyne = f0SFT;

  GPSin.gpsSeconds = timeStamps->data[0].gpsSeconds;
  GPSin.gpsNanoSeconds = timeStamps->data[0].gpsNanoSeconds;

  /* Allocate memory for SFTParams and initialize */
  pSFTParams = (SFTParams *)LALCalloc(1, sizeof(SFTParams));
  pSFTParams->Tsft = tSFT;
  pSFTParams->timestamps = timeStamps;
  pSFTParams->noiseSFTs = NULL;

  #ifdef INCLUDE_RANDVAL_MISMATCH
    /* Initial seed and randPar to use LALUniformDeviate to generate random mismatch during Monte Carlo. */
    fpRandom = fopen("/dev/urandom","r");
    rndCount = fread(&seed, sizeof(INT4),1, fpRandom);
    fclose(fpRandom);
    /* seed = 1234; */ /* Test value */
    LALCreateRandomParams(status->statusPtr, &randPar, seed);
    CHECKSTATUSPTR (status);
  #endif

  /* allocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */
  pSkyConstAndZeroPsiAMResponse = (SkyConstAndZeroPsiAMResponse *)LALMalloc(sizeof(SkyConstAndZeroPsiAMResponse));
  pSkyConstAndZeroPsiAMResponse->skyConst = (REAL8 *)LALMalloc((2*numSpinDown*(numSFTs+1)+2*numSFTs+3)*sizeof(REAL8));
  pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4));
  pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi = (REAL4 *)LALMalloc(numSFTs*sizeof(REAL4));
  pSFTandSignalParams = (SFTandSignalParams *)LALMalloc(sizeof(SFTandSignalParams));
  /* create lookup table (LUT) values for doing trig */
  /* pSFTandSignalParams->resTrig = 64; */ /* length sinVal and cosVal; resolution of trig functions = 2pi/resTrig */
  /* pSFTandSignalParams->resTrig = 128; */ /* 10/08/04 gam; length sinVal and cosVal; domain = -2pi to 2pi inclusive; resolution = 4pi/resTrig */
  pSFTandSignalParams->resTrig = 0; /* 10/12/04 gam; turn off using LUTs since this is more typical. */
  /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */
  if (pSFTandSignalParams->resTrig > 0) {
    pSFTandSignalParams->trigArg = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    pSFTandSignalParams->sinVal  = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    pSFTandSignalParams->cosVal  = (REAL8 *)LALMalloc((pSFTandSignalParams->resTrig+1)*sizeof(REAL8));
    for (k=0; k<=pSFTandSignalParams->resTrig; k++) {
       /* pSFTandSignalParams->trigArg[k]= ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig); */ /* 10/08/04 gam */
       pSFTandSignalParams->trigArg[k]= -1.0*((REAL8)LAL_TWOPI) + 2.0 * ((REAL8)LAL_TWOPI) * ((REAL8)k) / ((REAL8)pSFTandSignalParams->resTrig);
       pSFTandSignalParams->sinVal[k]=sin( pSFTandSignalParams->trigArg[k] );
       pSFTandSignalParams->cosVal[k]=cos( pSFTandSignalParams->trigArg[k] );
    }
  }
  pSFTandSignalParams->pSigParams = pPulsarSignalParams;
  pSFTandSignalParams->pSFTParams = pSFTParams;
  pSFTandSignalParams->nSamples = nsamples;
  pSFTandSignalParams->Dterms = Dterms;  /* 09/07/05 gam */

  /* ********************************************************/
  /*                                                       */
  /* START SECTION: LOOP OVER SKY POSITIONS                */
  /*                                                       */
  /* ********************************************************/
  for(iSky=0;iSky<numSkyPosTotal;iSky++) {

    /* set source sky position declination (DEC) */
    randval = 0.5; /* Gives default value */
    #ifdef INCLUDE_SEQUENTIAL_MISMATCH
      randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
    #endif
    #ifdef INCLUDE_RANDVAL_MISMATCH
       LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
    #endif
    pPulsarSignalParams->pulsar.position.latitude = skyPosData[iSky][1] + (((REAL8)randval) - 0.5)*DeltaDec;
    cosTmpDEC = cos(skyPosData[iSky][1]);
    if (cosTmpDEC != 0.0) {
          tmpDeltaRA = DeltaRA/cosTmpDEC;
    } else {
          tmpDeltaRA = 0.0; /* We are at a celestial pole */
    }

    /* set source sky position right ascension (RA) */
    randval = 0.5; /* Gives default value */
    #ifdef INCLUDE_SEQUENTIAL_MISMATCH
      randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
    #endif
    #ifdef INCLUDE_RANDVAL_MISMATCH
      LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
    #endif
    pPulsarSignalParams->pulsar.position.longitude = skyPosData[iSky][0] + (((REAL8)randval) - 0.5)*tmpDeltaRA;

    /* Find reference time in SSB for this sky positions */
    int ret = XLALConvertGPS2SSB ( &(pPulsarSignalParams->pulsar.refTime), GPSin, pPulsarSignalParams );
    if ( ret != XLAL_SUCCESS ) {
      XLALPrintError ("XLALConvertGPS2SSB() failed with xlalErrno = %d\n", xlalErrno );
      ABORTXLAL (status);
    }

    /* one per sky position fill in SkyConstAndZeroPsiAMResponse for use with LALFastGeneratePulsarSFTs */
    LALComputeSkyAndZeroPsiAMResponse (status->statusPtr, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams);
    CHECKSTATUSPTR (status);

    /* ********************************************************/
    /*                                                       */
    /* START SECTION: LOOP OVER SPINDOWN                     */
    /*                                                       */
    /* ********************************************************/
    for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) {
     /* source spindown parameters */
     if (numSpinDown > 0) {
       for(k=0;k<numSpinDown;k++) {
         randval = 0.5; /* Gives default value */
         #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            if (freqDerivData[jDeriv][k] < 0.0) {
               randval = ( (REAL4)(iSky) )/( (REAL4)(numSkyPosTotal) );
            } else {
               randval = 0.5; /* If derivative is not negative (i.e., it is zero) then do not add in mismatch; keep it zero. */
            }
         #endif
         #ifdef INCLUDE_RANDVAL_MISMATCH
           LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
         #endif
         if (k == 0) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv1;
         } else if (k == 1) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv2;
         } else if (k == 2) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv3;
         } else if (k == 3) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv4;
         } else if (k == 4) {
          pPulsarSignalParams->pulsar.spindown->data[k] = freqDerivData[jDeriv][k] + (((REAL8)randval) - 0.5)*DeltaFDeriv5;
         } /* END if (k == 0) ELSE ... */
       }
     }

     /* ***************************************************/
     /*                                                  */
     /* START SECTION: LOOP OVER FREQUENCIES             */
     /*                                                  */
     /* ***************************************************/
     for(iFreq=0;iFreq<nBinsSGNL;iFreq++) {

       /* set source orientation psi */
       randval = 0.5; /* Gives default value */
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.psi = (randval - 0.5) * ((REAL4)LAL_PI_2);

       /* set angle between source spin axis and direction from source to SSB, cosIota */
       randval = 1.0; /* Gives default value */
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       cosIota = 2.0*((REAL8)randval) - 1.0;

       /* h_0 is fixed above; get A_+ and A_x from h_0 and cosIota */
       pPulsarSignalParams->pulsar.aPlus = (REAL4)(0.5*h_0*(1.0 + cosIota*cosIota));
       pPulsarSignalParams->pulsar.aCross = (REAL4)(h_0*cosIota);

       /* get random value for phi0 */
       randval = 0.125; /* Gives default value pi/4*/
       #ifdef INCLUDE_SEQUENTIAL_MISMATCH
            randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #endif
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.phi0 = ((REAL8)randval) * ((REAL8)LAL_TWOPI);

       /* randval steps through various mismatches to frequencies centered on a bin */
       /* Note that iFreq = nBinsSGNL/2 gives randval = 0.5 gives no mismatch from frequency centered on a bin */
       randval = ( (REAL4)(iFreq) )/( (REAL4)(nBinsSGNL) );
       #ifdef INCLUDE_RANDVAL_MISMATCH
          LALUniformDeviate(status->statusPtr, &randval, randPar); CHECKSTATUSPTR (status);
       #endif
       pPulsarSignalParams->pulsar.f0 = f0SGNL + iFreq*dfSGNL + (((REAL8)randval) - 0.5)*dfSGNL;

       testNumber++; /* Update count of which test we about to do. */

       /* FIRST: Use LALGeneratePulsarSignal and LALSignalToSFTs to generate outputSFTs */
       signalvec = NULL;
       LALGeneratePulsarSignal(status->statusPtr, &signalvec, pPulsarSignalParams);
       CHECKSTATUSPTR (status);
       outputSFTs = NULL;
       LALSignalToSFTs(status->statusPtr, &outputSFTs, signalvec, pSFTParams);
       CHECKSTATUSPTR (status);

       #ifdef PRINT_OUTPUTSFT
           if (testNumber == TESTNUMBER_TO_PRINT) {
              i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */
              fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0);
              fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross);
              fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi);
              fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0);
              fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0);
              fprintf(stdout,"outputSFTs->data[%i].data->length = %i \n",i,outputSFTs->data[i].data->length);
              renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1));
              for(j=0;j<nBinsSFT;j++) {
                /* fprintf(stdout,"%i %g %g \n", j, renorm*outputSFTs->data[i].data->data[j].re, renorm*outputSFTs->data[i].data->data[j].im); */
                fprintf(stdout,"%i %g \n",j,renorm*renorm*outputSFTs->data[i].data->data[j].re*outputSFTs->data[i].data->data[j].re + renorm*renorm*outputSFTs->data[i].data->data[j].im*outputSFTs->data[i].data->data[j].im);
                fflush(stdout);
              }
           }
       #endif

       /* SECOND: Use LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs to generate outputSFTs */
       LALFastGeneratePulsarSFTs (status->statusPtr, &fastOutputSFTs, pSkyConstAndZeroPsiAMResponse, pSFTandSignalParams);
       CHECKSTATUSPTR (status);

       #ifdef PRINT_FASTOUTPUTSFT
          if (testNumber == TESTNUMBER_TO_PRINT) {
            REAL4  fPlus;
            REAL4  fCross;
            i=SFTINDEX_TO_PRINT; /* index of which outputSFT to output */
            fPlus = pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) + pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi);
            fCross = pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi[i]*cos(2.0*pPulsarSignalParams->pulsar.psi) - pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi[i]*sin(2.0*pPulsarSignalParams->pulsar.psi);
            fprintf(stdout,"iFreq = %i, inject h_0 = %23.10e \n",iFreq,h_0);
            fprintf(stdout,"iFreq = %i, inject cosIota = %23.10e, A_+ = %23.10e, A_x = %23.10e \n",iFreq,cosIota,pPulsarSignalParams->pulsar.aPlus,pPulsarSignalParams->pulsar.aCross);
            fprintf(stdout,"iFreq = %i, inject psi = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.psi);
            fprintf(stdout,"iFreq = %i, fPlus, fCross = %23.10e,  %23.10e \n",iFreq,fPlus,fCross);
            fprintf(stdout,"iFreq = %i, inject phi0 = %23.10e \n",iFreq,pPulsarSignalParams->pulsar.phi0);
            fprintf(stdout,"iFreq = %i, search f0 = %23.10e, inject f0 = %23.10e \n",iFreq,f0SGNL + iFreq*dfSGNL,pPulsarSignalParams->pulsar.f0);
            fprintf(stdout,"fastOutputSFTs->data[%i].data->length = %i \n",i,fastOutputSFTs->data[i].data->length);
            fflush(stdout);
            for(j=0;j<nBinsSFT;j++) {
               /* fprintf(stdout,"%i %g %g \n",j,fastOutputSFTs->data[i].data->data[j].re,fastOutputSFTs->data[i].data->data[j].im); */
               fprintf(stdout,"%i %g \n",j,fastOutputSFTs->data[i].data->data[j].re*fastOutputSFTs->data[i].data->data[j].re + fastOutputSFTs->data[i].data->data[j].im*fastOutputSFTs->data[i].data->data[j].im);
               fflush(stdout);
            }
          }
       #endif

       /* find maximum difference in power */
       epsDiffMod = 0.20; /* maximum allowed percent difference */ /* 10/12/04 gam */
       overallMaxDiffSFTMod = 0.0;
       for (i = 0; i < numSFTs; i++) {
          renorm = ((REAL4)nsamples)/((REAL4)(outputSFTs->data[i].data->length - 1));
          maxDiffSFTMod = 0.0;
          diffAtMaxPower = 0.0;
          maxMod = 0.0;
          fastMaxMod = 0.0;
          jMaxMod = -1;
          jFastMaxMod = -1;
          /* Since doppler shifts can move the signal by an unknown number of bins search the whole band for max modulus: */
          for(j=0;j<nBinsSFT;j++) {
               sftMod = renorm*renorm*crealf(outputSFTs->data[i].data->data[j])*crealf(outputSFTs->data[i].data->data[j]) + renorm*renorm*cimagf(outputSFTs->data[i].data->data[j])*cimagf(outputSFTs->data[i].data->data[j]);
               sftMod = sqrt(sftMod);
               fastSFTMod = crealf(fastOutputSFTs->data[i].data->data[j])*crealf(fastOutputSFTs->data[i].data->data[j]) + cimagf(fastOutputSFTs->data[i].data->data[j])*cimagf(fastOutputSFTs->data[i].data->data[j]);
               fastSFTMod = sqrt(fastSFTMod);
               if (fabs(sftMod) > smallMod) {
                   tmpDiffSFTMod = fabs((sftMod - fastSFTMod)/sftMod);
                   if (tmpDiffSFTMod > maxDiffSFTMod) {
                       maxDiffSFTMod = tmpDiffSFTMod;
                   }
                   if (tmpDiffSFTMod > overallMaxDiffSFTMod) {
                       overallMaxDiffSFTMod = tmpDiffSFTMod;
                   }
                   if (sftMod > maxMod) {
                       maxMod = sftMod;
                       jMaxMod = j;
                   }
                   if (fastSFTMod > fastMaxMod) {
                       fastMaxMod = fastSFTMod;
                       jFastMaxMod = j;
                   }
               }
          }
          if (fabs(maxMod) > smallMod) {
             diffAtMaxPower = fabs((maxMod - fastMaxMod)/maxMod);
          }
          #ifdef PRINT_MAXSFTPOWER
            fprintf(stdout,"maxSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxMod,maxMod);
            fprintf(stdout,"maxFastSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jFastMaxMod,fastMaxMod);
            fflush(stdout);
          #endif
          #ifdef PRINT_MAXDIFFSFTPOWER
            fprintf(stdout,"maxDiffSFTMod, testNumber %i, SFT %i, bin %i = %g \n",testNumber,i,jMaxDiff,maxDiffSFTMod);
            fflush(stdout);
          #endif
          #ifdef PRINT_DIFFATMAXPOWER
            fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower);
            fflush(stdout);
          #endif
          #ifdef PRINT_ERRORATMAXPOWER
            if (diffAtMaxPower > epsDiffMod) {
              fprintf(stdout,"diffAtMaxPower, testNumber %i, SFT %i, bins %i and %i = %g exceeded epsDiffMod = %g \n",testNumber,i,jMaxMod,jFastMaxMod,diffAtMaxPower,epsDiffMod);
              fflush(stdout);
              /* break; */ /* only report 1 error per test */
            }
            if (jMaxMod != jFastMaxMod) {
              fprintf(stdout,"MaxPower occurred in different bins: testNumber %i, SFT %i, bins %i and %i\n",testNumber,i,jMaxMod,jFastMaxMod);
              fflush(stdout);
              /* break; */ /* only report 1 error per test */
            }
          #endif
          if (jMaxMod != jFastMaxMod) {
              binErrorCount++; /* 10/12/04 gam; count up bin errors; if too ABORT at bottom of code */
          }
          if ( diffAtMaxPower > epsDiffMod ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EMOD, GENERATEPULSARSIGNALTESTC_MSGEMOD);
          }
          /* 10/12/04 gam; turn on test above and add test below */
          if ( fabs(((REAL8)(jMaxMod - jFastMaxMod))) >  1.1 ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EBIN,   GENERATEPULSARSIGNALTESTC_MSGEBIN);
          }
       } /* END for(i = 0; i < numSFTs; i++) */
       #ifdef PRINT_OVERALLMAXDIFFSFTPOWER
         fprintf(stdout,"overallMaxDiffSFTMod, testNumber = %i, SFT %i, bin %i = %g \n",testNumber,iOverallMaxDiffSFTMod,jOverallMaxDiff,overallMaxDiffSFTMod);
         fflush(stdout);
       #endif

       /* 09/07/05 gam; Initialize fastOutputSFTs since only 2*Dterms bins are changed by LALFastGeneratePulsarSFTs */
       for (i = 0; i < numSFTs; i++) {
          for(j=0;j<nBinsSFT;j++) {
             fastOutputSFTs->data[i].data->data[j] = 0.0;
          }
       }

       XLALDestroySFTVector( outputSFTs);

       LALFree(signalvec->data->data);
       LALFree(signalvec->data);
       LALFree(signalvec);

     } /* END for(iFreq=0;iFreq<nBinsSGNL;iFreq++) */
     /* ***************************************************/
     /*                                                  */
     /* END SECTION: LOOP OVER FREQUENCIES               */
     /*                                                  */
     /* ***************************************************/
   } /* END for(jDeriv=0;jDeriv<numFreqDerivIncludingNoSpinDown;jDeriv++) */
  /* ********************************************************/
  /*                                                       */
  /* END SECTION: LOOP OVER SPINDOWN                       */
  /*                                                       */
  /* ********************************************************/

  } /* END for(iSky=0;iSky<numSkyPosTotal;iSky++) */
  /* ********************************************************/
  /*                                                       */
  /* END SECTION: LOOP OVER SKY POSITIONS                  */
  /*                                                       */
  /* ********************************************************/

  /* 10/12/04 gam; check if too many bin errors */
  epsBinErrorRate = 0.20;  /* 10/12/04 gam; maximum allowed bin errors */
  if ( (((REAL4)binErrorCount)/((REAL4)testNumber)) > epsBinErrorRate ) {
            ABORT( status, GENERATEPULSARSIGNALTESTC_EBINS, GENERATEPULSARSIGNALTESTC_MSGEBINS);
  }

  #ifdef INCLUDE_RANDVAL_MISMATCH
    LALDestroyRandomParams(status->statusPtr, &randPar);
    CHECKSTATUSPTR (status);
  #endif

  /* fprintf(stdout,"Total number of tests completed = %i. \n", testNumber);
  fflush(stdout); */

  LALFree(pSFTParams);
  if (numSpinDown > 0) {
    LALDDestroyVector(status->statusPtr, &(pPulsarSignalParams->pulsar.spindown));
    CHECKSTATUSPTR (status);
  }
  LALFree(pPulsarSignalParams);

  /* deallocate memory for structs needed by LALComputeSkyAndZeroPsiAMResponse and LALFastGeneratePulsarSFTs */
  XLALDestroySFTVector( fastOutputSFTs);
  LALFree(pSkyConstAndZeroPsiAMResponse->fCrossZeroPsi);
  LALFree(pSkyConstAndZeroPsiAMResponse->fPlusZeroPsi);
  LALFree(pSkyConstAndZeroPsiAMResponse->skyConst);
  LALFree(pSkyConstAndZeroPsiAMResponse);
  /* 02/02/05 gam; if NOT pSFTandSignalParams->resTrig > 0 should not create trigArg etc... */
  if (pSFTandSignalParams->resTrig > 0) {
    LALFree(pSFTandSignalParams->trigArg);
    LALFree(pSFTandSignalParams->sinVal);
    LALFree(pSFTandSignalParams->cosVal);
  }
  LALFree(pSFTandSignalParams);

  /* deallocate skyPosData */
  for(i=0;i<numSkyPosTotal;i++)
  {
      LALFree(skyPosData[i]);
  }
  LALFree(skyPosData);

  if (numSpinDown > 0) {
    /* deallocate freqDerivData */
    for(i=0;i<numFreqDerivTotal;i++)
    {
        LALFree(freqDerivData[i]);
    }
    LALFree(freqDerivData);
  }

  LALFree(timeStamps->data);
  LALFree(timeStamps);

  XLALDestroyEphemerisData(edat);

  CHECKSTATUSPTR (status);
  DETATCHSTATUSPTR (status);
}
示例#14
0
int
main( int argc, char **argv )
{
  static LALStatus stat;       /* status structure */
  int arg;                     /* command-line argument counter */
  UINT4 n = SIZE, i, j;        /* array size and indecies */
  CHAR *infile = NULL;         /* input filename */
  CHAR *outfile = NULL;        /* output filename */
  BOOLEAN timing = 0;          /* whether -t option was given */
  BOOLEAN single = 0;          /* whether -s option was given */
  BOOLEAN invert = 0;          /* whether -v option was given */
  REAL4 sDet = 0.0;            /* determinant if -s option is given */
  REAL8 dDet = 0.0;            /* determinant if -s option isn't given */
  REAL4Array *sMatrix = NULL;  /* matrix if -s option is given */
  REAL8Array *dMatrix = NULL;  /* matrix if -s option is not given */
  REAL4Array *sInverse = NULL; /* inverse if -s option is given */
  REAL8Array *dInverse = NULL; /* inverse if -s option isn't given */
  UINT4Vector dimLength;       /* dimensions used to create matrix */
  UINT4 dims[2];               /* dimLength.data array */
  clock_t start = 0, stop = 0; /* start and stop times for timing */
  FILE *fp = NULL;             /* input/output file pointer */


  /*******************************************************************
   * PARSE ARGUMENTS (arg stores the current position)               *
   *******************************************************************/

  arg = 1;
  while ( arg < argc ) {

    /* Parse matrix size option. */
    if ( !strcmp( argv[arg], "-n" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	n = atoi( argv[arg++] );
      } else {
	ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return DETINVERSETESTC_EARG;
      }
    }

    /* Parse input option. */
    else if ( !strcmp( argv[arg], "-i" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	infile = argv[arg++];
      } else {
	ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return DETINVERSETESTC_EARG;
      }
    }

    /* Parse output option. */
    else if ( !strcmp( argv[arg], "-o" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
	outfile = argv[arg++];
      } else {
	ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return DETINVERSETESTC_EARG;
      }
    }

    /* Parse inversion, single-precision, and timing options. */
    else if ( !strcmp( argv[arg], "-v" ) ) {
      arg++;
      invert = 1;
    }
    else if ( !strcmp( argv[arg], "-s" ) ) {
      arg++;
      single = 1;
    }
    else if ( !strcmp( argv[arg], "-t" ) ) {
      arg++;
      timing = 1;
    }

    /* Parse debug level option. */
    else if ( !strcmp( argv[arg], "-d" ) ) {
      if ( argc > arg + 1 ) {
	arg++;
      }else{
	ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
        LALPrintError( USAGE, *argv );
        return DETINVERSETESTC_EARG;
      }
    }

    /* Check for unrecognized options. */
    else {
      ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
      LALPrintError( USAGE, *argv );
      return DETINVERSETESTC_EARG;
    }
  } /* End of argument parsing loop. */


  /*******************************************************************
   * GET INPUT MATRIX                                                *
   *******************************************************************/

  /* Set up array creation vector. */
  dimLength.length = 2;
  dimLength.data = dims;

  /* Read input matrix file. */
  if ( infile ) {

    /* Open input file. */
    if ( !strcmp( infile, "stdin" ) )
      fp = stdin;
    else if ( !( fp = fopen( infile, "r" ) ) ) {
      ERROR( DETINVERSETESTC_EFILE, "- " DETINVERSETESTC_MSGEFILE, infile );
      return DETINVERSETESTC_EFILE;
    }

    /* Single-precision mode: */
    if ( single ) {
      REAL4Vector *vec = NULL; /* parsed input line */

      /* Read first non-comment line and create array. */
      do {
	SUB( LALSReadVector( &stat, &vec, fp, 0 ), &stat );
      } while ( ( n = vec->length ) == 0 );
      dimLength.data[0] = dimLength.data[1] = n;
      SUB( LALSCreateArray( &stat, &sMatrix, &dimLength ), &stat );
      for ( j = 0; j < n; j++ )
	sMatrix->data[j] = vec->data[j];
      SUB( LALSDestroyVector( &stat, &vec ), &stat );

      /* Read remaining lines. */
      for ( i = 1; i < n; i++ ) {
	SUB( LALSReadVector( &stat, &vec, fp, 1 ), &stat );
	if ( vec->length != n ) {
	  ERROR( DETINVERSETESTC_EFMT, DETINVERSETESTC_MSGEFMT, 0 );
	  return DETINVERSETESTC_EFMT;
	}
	for ( j = 0; j < n; j++ )
	  sMatrix->data[i*n+j] = vec->data[j];
	SUB( LALSDestroyVector( &stat, &vec ), &stat );
      }
    }

    /* Double-precision mode: */
    else {
      REAL8Vector *vec = NULL; /* parsed input line */

      /* Read first non-comment line and create array. */
      do {
	SUB( LALDReadVector( &stat, &vec, fp, 0 ), &stat );
      } while ( ( n = vec->length ) == 0 );
      dimLength.data[0] = dimLength.data[1] = n;
      SUB( LALDCreateArray( &stat, &dMatrix, &dimLength ), &stat );
      for ( j = 0; j < n; j++ )
	dMatrix->data[j] = vec->data[j];
      SUB( LALDDestroyVector( &stat, &vec ), &stat );

      /* Read remaining lines. */
      for ( i = 1; i < n; i++ ) {
	SUB( LALDReadVector( &stat, &vec, fp, 1 ), &stat );
	if ( vec->length != n ) {
	  ERROR( DETINVERSETESTC_EFMT, DETINVERSETESTC_MSGEFMT, 0 );
	  return DETINVERSETESTC_EFMT;
	}
	for ( j = 0; j < n; j++ )
	  dMatrix->data[i*n+j] = vec->data[j];
	SUB( LALDDestroyVector( &stat, &vec ), &stat );
      }
    }
  }

  /* Generate random matrix. */
  else {
    RandomParams *params = NULL;
    SUB( LALCreateRandomParams( &stat, &params, 0 ), &stat );
    dimLength.data[0] = dimLength.data[1] = n;

    /* Single-precision mode: */
    if ( single ) {
      SUB( LALSCreateArray( &stat, &sMatrix, &dimLength ), &stat );
      for ( i = 0; i < n; i++ ) {
	REAL4 x;
	for ( j = 0; j < n; j++ ) {
	  SUB( LALUniformDeviate( &stat, &x, params ), &stat );
	  sMatrix->data[i*n+j] = 2.0*x - 1.0;
	}
      }
    }

    /* Double-precision mode: */
    else {
      SUB( LALDCreateArray( &stat, &dMatrix, &dimLength ), &stat );
      for ( i = 0; i < n; i++ ) {
	REAL4 x;
	for ( j = 0; j < n; j++ ) {
	  SUB( LALUniformDeviate( &stat, &x, params ), &stat );
	  dMatrix->data[i*n+j] = 2.0*(REAL8)( x ) - 1.0;
	}
      }
    }

    SUB( LALDestroyRandomParams( &stat, &params ), &stat );
  }

  /* Write input matrix to output file. */
  if ( outfile ) {

    /* Open output file. */
    if ( !strcmp( outfile, "stdout" ) )
      fp = stdout;
    else if ( !strcmp( outfile, "stderr" ) )
      fp = stderr;
    else if ( !( fp = fopen( outfile, "r" ) ) ) {
      ERROR( DETINVERSETESTC_EFILE, "- " DETINVERSETESTC_MSGEFILE, outfile );
      return DETINVERSETESTC_EFILE;
    }

    /* Single-precision mode: */
    if ( single ) {
      for ( i = 0; i < n; i++ ) {
	fprintf( fp, "%16.9e", sMatrix->data[i*n] );
	for ( j = 1; j < n; j++ )
	  fprintf( fp, " %16.9e", sMatrix->data[i*n+j] );
	fprintf( fp, "\n" );
      }
    }

    /* Double-precision mode: */
    else {
      for ( i = 0; i < n; i++ ) {
	fprintf( fp, "%25.17e", dMatrix->data[i*n] );
	for ( j = 1; j < n; j++ )
	  fprintf( fp, " %25.17e", dMatrix->data[i*n+j] );
	fprintf( fp, "\n" );
      }
    }
  }


  /*******************************************************************
   * COMPUTE INVERSE                                                 *
   *******************************************************************/

  if ( timing )
    start = clock();

  /* Single-precision mode: */
  if ( single ) {
    if ( invert ) {
      SUB( LALSCreateArray( &stat, &sInverse, &dimLength ), &stat );
      SUB( LALSMatrixInverse( &stat, &sDet, sMatrix, sInverse ),
	   &stat );
    }
  }

  /* Double-precision mode: */
  else {
    if ( invert ) {
      SUB( LALDCreateArray( &stat, &dInverse, &dimLength ), &stat );
      SUB( LALDMatrixInverse( &stat, &dDet, dMatrix, dInverse ),
	   &stat );
    } else {
      SUB( LALDMatrixDeterminant( &stat, &dDet, dMatrix ), &stat );
    }
  }

  if ( timing ) {
    stop = clock();
    fprintf( stderr, "Elapsed time: %.2f s\n",
	     (double)( stop - start )/CLOCKS_PER_SEC );
  }

  /* Write output. */
  if ( outfile ) {

    /* Write determinant. */
    fprintf( fp, "\n" );
    if ( single )
      fprintf( fp, "%16.9e\n", sDet );
    else
      fprintf( fp, "%25.17e\n", dDet );

    /* Write inverse. */
    if ( invert ) {
      fprintf( fp, "\n" );
      if ( single ) {
	for ( i = 0; i < n; i++ ) {
	  fprintf( fp, "%16.9e", sInverse->data[i*n] );
	  for ( j = 1; j < n; j++ )
	    fprintf( fp, " %16.9e", sInverse->data[i*n+j] );
	  fprintf( fp, "\n" );
	}
      } else {
	for ( i = 0; i < n; i++ ) {
	  fprintf( fp, "%25.17e", dInverse->data[i*n] );
	  for ( j = 1; j < n; j++ )
	    fprintf( fp, " %25.17e", dInverse->data[i*n+j] );
	  fprintf( fp, "\n" );
	}
      }
    }

    /* Finished output. */
    if ( fp != stdout && fp != stderr )
      fclose( fp );
  }

  /* Clean up and exit. */
  if ( single ) {
    SUB( LALSDestroyArray( &stat, &sMatrix ), &stat );
    if ( invert ) {
      SUB( LALSDestroyArray( &stat, &sInverse ), &stat );
    }
  } else {
    SUB( LALDDestroyArray( &stat, &dMatrix ), &stat );
    if ( invert ) {
      SUB( LALDDestroyArray( &stat, &dInverse ), &stat );
    }
  }
  LALCheckMemoryLeaks();
  INFO( DETINVERSETESTC_MSGENORM );
  return DETINVERSETESTC_ENORM;
}