int main(int argc, char *argv[]){

  static LALStatus  status;  

  static LALDetector          *detector;
  static LIGOTimeGPSVector    timeV;
  static REAL8Cart3CoorVector velV;
  static REAL8Vector          timeDiffV;
  static REAL8                foft;
  static HoughPulsarTemplate  pulsarTemplate;

  EphemerisData   *edat = NULL;
  CHAR  *uvar_earthEphemeris = NULL; 
  CHAR  *uvar_sunEphemeris = NULL;
  SFTVector  *inputSFTs  = NULL;  
  REAL8 *alphaVec=NULL;
  REAL8 *deltaVec=NULL;
  REAL8 *freqVec=NULL;
  REAL8 *spndnVec=NULL;

  /* pgV is vector of peakgrams and pg1 is onepeakgram */
  static UCHARPeakGram    *pg1, **pgV; 
  UINT4  msp; /*number of spin-down parameters */
  CHAR   *uvar_ifo = NULL;
  CHAR   *uvar_sftDir = NULL; /* the directory where the SFT  could be */
  CHAR   *uvar_fnameOut = NULL;               /* The output prefix filename */
  CHAR   *uvar_fnameIn = NULL;  
  INT4   numberCount, ind;
  UINT8  nTemplates;   
  UINT4   mObsCoh;
  REAL8  uvar_peakThreshold;
  REAL8  f_min, f_max, fWings, timeBase;
  INT4  uvar_blocksRngMed;
  UINT4  sftlength; 
  INT4   sftFminBin;
  UINT4 loopId, tempLoopId;
  FILE  *fpOut = NULL;
  CHAR *fnameLog=NULL;
  FILE *fpLog = NULL;
  CHAR *logstr=NULL;
  /*REAL8 asq, bsq;*/ /* square of amplitude modulation functions a and b */

  /******************************************************************/
  /*    Set up the default parameters.      */
  /* ****************************************************************/

  /* LAL error-handler */
  lal_errhandler = LAL_ERR_EXIT;
  
  msp = 1; /*only one spin-down */
 
  /* memory allocation for spindown */
  pulsarTemplate.spindown.length = msp;
  pulsarTemplate.spindown.data = NULL;
  pulsarTemplate.spindown.data = (REAL8 *)LALMalloc(msp*sizeof(REAL8));
 
 
  uvar_peakThreshold = THRESHOLD;

  uvar_earthEphemeris = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_earthEphemeris,EARTHEPHEMERIS);

  uvar_sunEphemeris = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_sunEphemeris,SUNEPHEMERIS);

  uvar_sftDir = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_sftDir,SFTDIRECTORY);

  uvar_fnameOut = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_fnameOut,VALIDATEOUT);

  uvar_fnameIn = (CHAR *)LALMalloc(1024*sizeof(CHAR));
  strcpy(uvar_fnameIn,VALIDATEIN);

  uvar_blocksRngMed = BLOCKSRNGMED;

  /* register user input variables */
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_ifo,            "ifo",            STRING, 'i', OPTIONAL, "Detector GEO(1) LLO(2) LHO(3)" ) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_earthEphemeris, "earthEphemeris", STRING, 'E', OPTIONAL, "Earth Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sunEphemeris,   "sunEphemeris",   STRING, 'S', OPTIONAL, "Sun Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sftDir,         "sftDir",         STRING, 'D', OPTIONAL, "SFT Directory") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fnameIn,        "fnameIn",        STRING, 'T', OPTIONAL, "Input template file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fnameOut,       "fnameOut",       STRING, 'o', OPTIONAL, "Output filename") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_blocksRngMed,   "blocksRngMed",   INT4,   'w', OPTIONAL, "RngMed block size") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_peakThreshold,  "peakThreshold",  REAL8,  't', OPTIONAL, "Peak selection threshold") == XLAL_SUCCESS, XLAL_EFUNC);

  /* read all command line variables */
  BOOLEAN should_exit = 0;
  XLAL_CHECK_MAIN( XLALUserVarReadAllInput(&should_exit, argc, argv, lalAppsVCSInfoList) == XLAL_SUCCESS, XLAL_EFUNC);
  if (should_exit)
    exit(1);
 
  /* open log file for writing */
  fnameLog = LALCalloc( (strlen(uvar_fnameOut) + strlen(".log") + 10),1);
  strcpy(fnameLog,uvar_fnameOut);
  strcat(fnameLog,".log");
  if ((fpLog = fopen(fnameLog, "w")) == NULL) {
    fprintf(stderr, "Unable to open file %s for writing\n", fnameLog);
    LALFree(fnameLog);
    exit(1);
  }
  
  /* get the log string */
  XLAL_CHECK_MAIN( ( logstr = XLALUserVarGetLog(UVAR_LOGFMT_CFGFILE) ) != NULL, XLAL_EFUNC);  

  fprintf( fpLog, "## Log file for HoughValidate\n\n");
  fprintf( fpLog, "# User Input:\n");
  fprintf( fpLog, "#-------------------------------------------\n");
  fprintf( fpLog, "%s", logstr);
  LALFree(logstr);

  /* append an ident-string defining the exact CVS-version of the code used */
  {
    CHAR command[1024] = "";
    fprintf (fpLog, "\n\n# CVS-versions of executable:\n");
    fprintf (fpLog, "# -----------------------------------------\n");
    fclose (fpLog);
    
    sprintf (command, "ident %s | sort -u >> %s", argv[0], fnameLog);
    /* we don't check this. If it fails, we assume that */
    /* one of the system-commands was not available, and */
    /* therefore the CVS-versions will not be logged */
    if ( system(command) ) fprintf (stderr, "\nsystem('%s') returned non-zero status!\n\n", command );

    LALFree(fnameLog);
  }

  /* open output file for writing */
  fpOut= fopen(uvar_fnameOut, "w");
  /*setlinebuf(fpOut);*/  /* line buffered on */  
  setvbuf(fpOut, (char *)NULL, _IOLBF, 0);

  /*****************************************************************/
  /* read template file */
  /*****************************************************************/
  {
    FILE  *fpIn = NULL;
    INT4   r;
    REAL8  temp1, temp2, temp3, temp4, temp5;
    UINT8  templateCounter; 
    
    fpIn = fopen(uvar_fnameIn, "r");
    if ( !fpIn )
      {
	fprintf(stderr, "Unable to fine file %s\n", uvar_fnameIn);
	return DRIVEHOUGHCOLOR_EFILE;
      }


    nTemplates = 0;
    do 
      {
	r=fscanf(fpIn,"%lf%lf%lf%lf%lf\n", &temp1, &temp2, &temp3, &temp4, &temp5);
	/* make sure the line has the right number of entries or is EOF */
	if (r==5) nTemplates++;
      } while ( r != EOF);
    rewind(fpIn);
    
    alphaVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));
    deltaVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));     
    freqVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));
    spndnVec = (REAL8 *)LALMalloc(nTemplates*sizeof(REAL8));     
    
    
    for (templateCounter = 0; templateCounter < nTemplates; templateCounter++)
      {
	r=fscanf(fpIn,"%lf%lf%lf%lf%lf\n", &temp1, alphaVec + templateCounter, deltaVec + templateCounter, 
		 freqVec + templateCounter,  spndnVec + templateCounter);
      }     
    fclose(fpIn);      
  }


  /**************************************************/
  /* read sfts */     
  /*************************************************/
  f_min = freqVec[0];     /* initial frequency to be analyzed */
  /* assume that the last frequency in the templates file is also the highest frequency */
  f_max = freqVec[nTemplates-1] ; 
  
  /* we need to add wings to fmin and fmax to account for 
     the Doppler shift, the size of the rngmed block size
     and also nfsizecylinder.  The block size and nfsizecylinder are
     specified in terms of frequency bins...this goes as one of the arguments of 
     LALReadSFTfiles */
  /* first correct for Doppler shift */
  fWings =  f_max * VTOT; 
  f_min -= fWings;    
  f_max += fWings; 
  
  /* create pattern to look for in SFT directory */   

  {
    CHAR *tempDir = NULL;
    SFTCatalog *catalog = NULL;
    static SFTConstraints constraints;

    /* set detector constraint */
    constraints.detector = NULL;
    if ( XLALUserVarWasSet( &uvar_ifo ) )    
      constraints.detector = XLALGetChannelPrefix ( uvar_ifo );

    /* get sft catalog */
    tempDir = (CHAR *)LALCalloc(512, sizeof(CHAR));
    strcpy(tempDir, uvar_sftDir);
    strcat(tempDir, "/*SFT*.*");
    XLAL_CHECK_MAIN( ( catalog = XLALSFTdataFind( tempDir, &constraints) ) != NULL, XLAL_EFUNC);
    
    detector = XLALGetSiteInfo( catalog->data[0].header.name);

    mObsCoh = catalog->length;
    timeBase = 1.0 / catalog->data->header.deltaF;

    XLAL_CHECK_MAIN( ( inputSFTs = XLALLoadSFTs ( catalog, f_min, f_max) ) != NULL, XLAL_EFUNC);

    XLAL_CHECK_MAIN( XLALNormalizeSFTVect( inputSFTs, uvar_blocksRngMed, 0.0 ) == XLAL_SUCCESS, XLAL_EFUNC);

    if ( XLALUserVarWasSet( &uvar_ifo ) )    
      LALFree( constraints.detector );
    LALFree( tempDir);
    XLALDestroySFTCatalog(catalog );  	

  }



  sftlength = inputSFTs->data->data->length;
  {
    INT4 tempFbin;
    sftFminBin = floor( (REAL4)(timeBase * inputSFTs->data->f0) + (REAL4)(0.5));
    tempFbin = floor( timeBase * inputSFTs->data->f0 + 0.5);

    if (tempFbin - sftFminBin)
      {
	fprintf(stderr, "Rounding error in calculating fminbin....be careful! \n");
      }
  }

  /* loop over sfts and select peaks */

  /* first the memory allocation for the peakgramvector */
  pgV = NULL;
  pgV = (UCHARPeakGram **)LALMalloc(mObsCoh*sizeof(UCHARPeakGram *));  

  /* memory for  peakgrams */
  for (tempLoopId=0; tempLoopId < mObsCoh; tempLoopId++)
    {
      pgV[tempLoopId] = (UCHARPeakGram *)LALMalloc(sizeof(UCHARPeakGram));
      pgV[tempLoopId]->length = sftlength; 
      pgV[tempLoopId]->data = NULL; 
      pgV[tempLoopId]->data = (UCHAR *)LALMalloc(sftlength* sizeof(UCHAR));
   
      LAL_CALL (SFTtoUCHARPeakGram( &status, pgV[tempLoopId], inputSFTs->data + tempLoopId, uvar_peakThreshold), &status);
    }


  /* having calculated the peakgrams we don't need the sfts anymore */
  XLALDestroySFTVector( inputSFTs);


  
  /* ****************************************************************/
  /* setting timestamps vector */
  /* ****************************************************************/
  timeV.length = mObsCoh;
  timeV.data = NULL;  
  timeV.data = (LIGOTimeGPS *)LALMalloc(mObsCoh*sizeof(LIGOTimeGPS));
  
  { 
    UINT4    j; 
    for (j=0; j < mObsCoh; j++){
      timeV.data[j].gpsSeconds = pgV[j]->epoch.gpsSeconds;
      timeV.data[j].gpsNanoSeconds = pgV[j]->epoch.gpsNanoSeconds;
    }    
  }
  
  /******************************************************************/
  /* compute the time difference relative to startTime for all SFTs */
  /******************************************************************/
  timeDiffV.length = mObsCoh;
  timeDiffV.data = NULL; 
  timeDiffV.data = (REAL8 *)LALMalloc(mObsCoh*sizeof(REAL8));
  
  {   
    REAL8   t0, ts, tn, midTimeBase;
    UINT4   j; 

    midTimeBase=0.5*timeBase;
    ts = timeV.data[0].gpsSeconds;
    tn = timeV.data[0].gpsNanoSeconds * 1.00E-9;
    t0=ts+tn;
    timeDiffV.data[0] = midTimeBase;

    for (j=1; j< mObsCoh; ++j){
      ts = timeV.data[j].gpsSeconds;
      tn = timeV.data[j].gpsNanoSeconds * 1.00E-9;  
      timeDiffV.data[j] = ts + tn -t0 + midTimeBase; 
    }  
  }

  /******************************************************************/
  /* compute detector velocity for those time stamps                */
  /******************************************************************/
  velV.length = mObsCoh;
  velV.data = NULL;
  velV.data = (REAL8Cart3Coor *)LALMalloc(mObsCoh*sizeof(REAL8Cart3Coor));
  
  {  
    VelocityPar   velPar;
    REAL8     vel[3]; 
    UINT4     j; 

    velPar.detector = *detector;
    velPar.tBase = timeBase;
    velPar.vTol = ACCURACY;
    velPar.edat = NULL;

    /* read in ephemeris data */
    XLAL_CHECK_MAIN( ( edat = XLALInitBarycenter( uvar_earthEphemeris, uvar_sunEphemeris ) ) != NULL, XLAL_EFUNC);
    velPar.edat = edat;

    /* now calculate average velocity */    
    for(j=0; j< velV.length; ++j){
      velPar.startTime.gpsSeconds     = timeV.data[j].gpsSeconds;
      velPar.startTime.gpsNanoSeconds = timeV.data[j].gpsNanoSeconds;
      
      LAL_CALL( LALAvgDetectorVel ( &status, vel, &velPar), &status );
      velV.data[j].x= vel[0];
      velV.data[j].y= vel[1];
      velV.data[j].z= vel[2];   
    }  
  }


  
  /* amplitude modulation stuff */
  {
    AMCoeffs XLAL_INIT_DECL(amc);
    AMCoeffsParams *amParams;
    EarthState earth;
    BarycenterInput baryinput;  /* Stores detector location and other barycentering data */

    /* detector location */
    baryinput.site.location[0] = detector->location[0]/LAL_C_SI;
    baryinput.site.location[1] = detector->location[1]/LAL_C_SI;
    baryinput.site.location[2] = detector->location[2]/LAL_C_SI;
    baryinput.dInv = 0.e0;
    /* alpha and delta must come from the skypatch */
    /* for now set it to something arbitrary */
    baryinput.alpha = 0.0;
    baryinput.delta = 0.0;

    /* Allocate space for amParams stucture */
    /* Here, amParams->das is the Detector and Source info */
    amParams = (AMCoeffsParams *)LALMalloc(sizeof(AMCoeffsParams));
    amParams->das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource));
    amParams->das->pSource = (LALSource *)LALMalloc(sizeof(LALSource));
    /* Fill up AMCoeffsParams structure */
    amParams->baryinput = &baryinput;
    amParams->earth = &earth; 
    amParams->edat = edat;
    amParams->das->pDetector = detector; 
    /* make sure alpha and delta are correct */
    amParams->das->pSource->equatorialCoords.latitude = baryinput.delta;
    amParams->das->pSource->equatorialCoords.longitude = baryinput.alpha;
    amParams->das->pSource->orientation = 0.0;
    amParams->das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL;
    amParams->polAngle = amParams->das->pSource->orientation ; /* These two have to be the same!!*/

    /* timeV is start time ---> change to mid time */    
    LAL_CALL (LALComputeAM(&status, &amc, timeV.data, amParams), &status); 

    /* calculate a^2 and b^2 */
    /* for (ii=0, asq=0.0, bsq=0.0; ii<mObsCoh; ii++) */
    /*       { */
    /* 	REAL8 *a, *b; */
    /*        	a = amc.a + ii; */
    /* 	b = amc.b + ii; */
    /* 	asq += (*a) * (*a); */
    /* 	bsq += (*b) * (*b); */
    /*       } */
    
    /* free amParams */
    LALFree(amParams->das->pSource);
    LALFree(amParams->das);
    LALFree(amParams);

  }

  /* loop over templates */    
  for(loopId=0; loopId < nTemplates; ++loopId){
    
    /* set template parameters */    
    pulsarTemplate.f0 = freqVec[loopId];
    pulsarTemplate.longitude = alphaVec[loopId];
    pulsarTemplate.latitude = deltaVec[loopId];
    pulsarTemplate.spindown.data[0] = spndnVec[loopId];
	   
 
    {
      REAL8   f0new, vcProdn, timeDiffN;
      REAL8   sourceDelta, sourceAlpha, cosDelta, factorialN;
      UINT4   j, i, f0newBin; 
      REAL8Cart3Coor       sourceLocation;
      
      sourceDelta = pulsarTemplate.latitude;
      sourceAlpha = pulsarTemplate.longitude;
      cosDelta = cos(sourceDelta);
      
      sourceLocation.x = cosDelta* cos(sourceAlpha);
      sourceLocation.y = cosDelta* sin(sourceAlpha);
      sourceLocation.z = sin(sourceDelta);      

      /* loop for all different time stamps,calculate frequency and produce number count*/ 
      /* first initialize number count */
      numberCount=0;
      for (j=0; j<mObsCoh; ++j)
	{  
	  /* calculate v/c.n */
	  vcProdn = velV.data[j].x * sourceLocation.x
	    + velV.data[j].y * sourceLocation.y
	    + velV.data[j].z * sourceLocation.z;

	  /* loop over spindown values to find f_0 */
	  f0new = pulsarTemplate.f0;
	  factorialN = 1.0;
	  timeDiffN = timeDiffV.data[j];	  
	  for (i=0; i<msp;++i)
	    { 
	      factorialN *=(i+1.0);
	      f0new += pulsarTemplate.spindown.data[i]*timeDiffN / factorialN;
	      timeDiffN *= timeDiffN;
	    }
	  
	  f0newBin = floor(f0new*timeBase + 0.5);
	  foft = f0newBin * (1.0 +vcProdn) / timeBase;    
	  
	  /* get the right peakgram */      
	  pg1 = pgV[j];
	  
	  /* calculate frequency bin for template */
	  ind =  floor( foft * timeBase + 0.5 ) - sftFminBin; 
	  
	  /* update the number count */
	  numberCount+=pg1->data[ind]; 
	}      
      
    } /* end of block calculating frequency path and number count */      
    

    /******************************************************************/
    /* printing result in the output file */
    /******************************************************************/
    
    fprintf(fpOut,"%d %f %f %f %g \n", 
	    numberCount, pulsarTemplate.longitude, pulsarTemplate.latitude, pulsarTemplate.f0,
	    pulsarTemplate.spindown.data[0] );
    
  } /* end of loop over templates */

  /******************************************************************/
  /* Closing files */
  /******************************************************************/  
  fclose(fpOut); 

  
  /******************************************************************/
  /* Free memory and exit */
  /******************************************************************/

  LALFree(alphaVec);
  LALFree(deltaVec);
  LALFree(freqVec);
  LALFree(spndnVec);
  

  for (tempLoopId = 0; tempLoopId < mObsCoh; tempLoopId++){
    pg1 = pgV[tempLoopId];  
    LALFree(pg1->data);
    LALFree(pg1);
  }
  LALFree(pgV);
  
  LALFree(timeV.data);
  LALFree(timeDiffV.data);
  LALFree(velV.data);
  
  LALFree(pulsarTemplate.spindown.data);
   
  XLALDestroyEphemerisData(edat);
  
  XLALDestroyUserVars();

  LALCheckMemoryLeaks();
    
  return DRIVEHOUGHCOLOR_ENORM;
}
Beispiel #2
0
/* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv------------------------------------ */
int main(int argc, char *argv[]){ 
  static LALStatus       status;  /* LALStatus pointer */ 
  static LineNoiseInfo   lines, lines2;
  static LineHarmonicsInfo harmonics; 
  
  INT4 nLines=0, count1, nHarmonicSets;
  INT4 j, r;
  FILE *fpNstar=NULL;
  FILE *fpOut=NULL;
  INT4 *nstarVec=NULL;
  REAL8 *freqVec=NULL;
  INT4 nstarNum=0, minBin, maxBin;
  REAL8 timeBase=1800.0, minFreq, maxFreq;
  INT4 flag= 0;
 
  /* user input variables */
  CHAR *uvar_nstarfile=NULL;
  CHAR *uvar_harmonicsfile=NULL;
  CHAR *uvar_cleannstar=NULL;

  /* set defaults */

  uvar_nstarfile = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_nstarfile, NSTARFILE);

  uvar_harmonicsfile = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_harmonicsfile, HARMONICSFILE);

  uvar_cleannstar = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_cleannstar, CLEANNSTARFILE);

  /* register user input variables */
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_nstarfile,     "nstarfile",      STRING, 'n', OPTIONAL, "File with max number counts") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_harmonicsfile, "harmonicsfile",  STRING, 'l', OPTIONAL, "File with line information") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_cleannstar,    "cleannstarfile", STRING, 'o', OPTIONAL, "Output file") == XLAL_SUCCESS, XLAL_EFUNC);


  /* read all command line variables */
  BOOLEAN should_exit = 0;
  XLAL_CHECK_MAIN( XLALUserVarReadAllInput(&should_exit, argc, argv) == XLAL_SUCCESS, XLAL_EFUNC);
  if (should_exit)
    exit(1);
  

  /* find number of harmonics */
  SUB( LALFindNumberHarmonics (&status, &harmonics, uvar_harmonicsfile), &status); 
  nHarmonicSets = harmonics.nHarmonicSets; 

  /* convert harmonics to explicit lines */
  if (nHarmonicSets > 0)
    {
      harmonics.startFreq = (REAL8 *)LALMalloc(harmonics.nHarmonicSets * sizeof(REAL8));
      harmonics.gapFreq = (REAL8 *)LALMalloc(harmonics.nHarmonicSets * sizeof(REAL8));
      harmonics.numHarmonics = (INT4 *)LALMalloc(harmonics.nHarmonicSets * sizeof(INT4));
      harmonics.leftWing = (REAL8 *)LALMalloc(harmonics.nHarmonicSets * sizeof(REAL8));
      harmonics.rightWing = (REAL8 *)LALMalloc(harmonics.nHarmonicSets * sizeof(REAL8));
    

      SUB( LALReadHarmonicsInfo( &status, &harmonics, uvar_harmonicsfile ), &status);
      
      nLines = 0;
      for (count1=0; count1 < nHarmonicSets; count1++)
	{
	  nLines += *(harmonics.numHarmonics + count1);
	}
      
      lines.nLines = nLines;
      lines.lineFreq = (REAL8 *)LALMalloc(nLines * sizeof(REAL8));
      lines.leftWing = (REAL8 *)LALMalloc(nLines * sizeof(REAL8));
      lines.rightWing = (REAL8 *)LALMalloc(nLines * sizeof(REAL8));

      SUB( LALHarmonics2Lines( &status, &lines, &harmonics), &status);
    }


  /* read file with nstar information */
  fpNstar = fopen( uvar_nstarfile, "r");
  if (fpNstar == NULL)
    {
      fprintf(stderr, "nstar file %s not found\n", uvar_nstarfile);
      exit(0);
    }
  /* first find number of nstar values */ 
  nstarNum = 0;
  do {
    REAL8 temp1, temp2, temp3, temp4, temp5;
    r=fscanf(fpNstar,"%lf%lf%lf%lf%lf\n", &temp1, &temp2, &temp3, &temp4, &temp5); 
    /* make sure the line has the right number of entries or is EOF */
    if (r==5) nstarNum++;
  } while ( r != EOF);
  rewind(fpNstar);

  /* allocate memory for vector of nstar and freqstar */
  nstarVec = (INT4 *)LALMalloc(nstarNum*sizeof(INT4));
  freqVec  = (REAL8 *)LALMalloc(nstarNum*sizeof(REAL8));

  /* read nstarfile again */
  for (j=0; j<nstarNum; j++)
    {
      REAL8 temp1, temp2, temp3, temp4, temp5;
      r=fscanf(fpNstar,"%lf%lf%lf%lf%lf\n", &temp1, &temp2, &temp3, &temp4, &temp5); 
      if (r==5)
	{
	  nstarVec[j] = temp1;
	  freqVec[j] = temp2;
	}
    }

  /* now we are done with nstarfile */
  fclose(fpNstar);

  /* calculate min and max frequency bins in nstarfile */
  /* this assumes frequencies are ordered */
  minBin = floor(freqVec[0]*timeBase + 0.5);
  maxBin = floor(freqVec[nstarNum-1]*timeBase + 0.5);
  minFreq = freqVec[0];
  maxFreq = freqVec[nstarNum-1];

  /* choose lines affecting frequency range */
  lines2.nLines = nLines;
  lines2.lineFreq = (REAL8 *)LALMalloc(nLines * sizeof(REAL8));
  lines2.leftWing = (REAL8 *)LALMalloc(nLines * sizeof(REAL8));
  lines2.rightWing = (REAL8 *)LALMalloc(nLines * sizeof(REAL8));

  SUB( LALChooseLines (&status, &lines2, &lines, minFreq, maxFreq), &status); 
  SUB( LALCheckLines (&status, &flag, &lines2, 202.0), &status); 


  /* clean the nstarVec */
  if ( nstarNum > 0 )
    {
      /* loop over lines and clean nstarVec*/
      for (j=0; j<nLines; j++)
	{
	  REAL8 lineFreq, leftWing, rightWing;
	  INT4 lineBin, leftWingBins, rightWingBins;
	  INT4 leftCount, rightCount;

          lineFreq = lines.lineFreq[j];
	  leftWing = lines.leftWing[j] + lineFreq*VTOT;
	  rightWing = lines.rightWing[j] + lineFreq*VTOT;

	  lineBin = floor( lineFreq*timeBase + 0.5);
	  leftWingBins = floor( leftWing*timeBase + 0.5);
	  rightWingBins = floor( rightWing*timeBase + 0.5);

	  if ( (lineBin >= minBin) && (lineBin <= maxBin) )
	    {
	      /* clean lineBin */
	      nstarVec[lineBin-minBin] = 0;

	      /* now go left */	      
	      for (leftCount=0; leftCount < leftWingBins; leftCount++)
		{
		  if (lineBin-minBin-leftCount > 0)
		    {
		      nstarVec[lineBin-minBin-leftCount-1] = 0;
		    } 
		} /* end of loop over leftwing */

	      /* now go right */
	      for (rightCount = 0; rightCount < rightWingBins; rightCount++)
		{
		  if (maxBin - lineBin - rightCount > 0)
		    {
		      nstarVec[lineBin-minBin+rightCount+1]=0;
		    }
		} /* end of loop over rightwing */

	    } /* end of if statement */
	} /* end of loop over lines */
    } /* end of cleaning */
  

  /* now write the result */
  fpOut = fopen(uvar_cleannstar, "w");
  if (fpOut == NULL)
    {
      fprintf(stderr, "unable to open file %s for writing \n", uvar_cleannstar);
      exit(0);
    }
  for (j=0; j<nstarNum; j++)
    {
      fprintf(fpOut, "%d  %f \n", nstarVec[j], freqVec[j]);
    }
  fclose(fpOut);

  /* Free memory */
  LALFree(nstarVec);
  LALFree(freqVec);


  if (nLines > 0)
    {
      LALFree(lines.lineFreq);
      LALFree(lines.leftWing);
      LALFree(lines.rightWing);
   
      LALFree(lines2.lineFreq);
      LALFree(lines2.leftWing);
      LALFree(lines2.rightWing);

    }

  if (nHarmonicSets > 0)
    {
      LALFree(harmonics.startFreq);
      LALFree(harmonics.gapFreq);
      LALFree(harmonics.numHarmonics);
      LALFree(harmonics.leftWing);
      LALFree(harmonics.rightWing);
    }

  XLALDestroyUserVars();
  LALCheckMemoryLeaks(); 

  INFO( SFTCLEANC_MSGENORM );
  return SFTCLEANC_ENORM;
}
/**
 * register all our "user-variables"
 */
void
InitUserVars (LALStatus *status, struct CommandLineArgsTag *CLA)
{

  INITSTATUS(status);
  ATTATCHSTATUSPTR (status);

  /* Initialize default values */
  CLA->Tsft=1800;
  CLA->nTsft=0;            
  CLA->timestamps=NULL;
  CLA->gpsStart=-1;
  CLA->sqrtSh=1.0;
  
  /** Default year-span of ephemeris-files to be used */
  CLA->ephemEarth = XLALStringDuplicate("earth00-19-DE405.dat.gz");
  CLA->ephemSun = XLALStringDuplicate("sun00-19-DE405.dat.gz");
  
  /* ---------- register all our user-variable ---------- */
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->Alpha),      "Alpha",          REAL8,  'a', OPTIONAL,  "Sky position Alpha (equatorial coordinates) in radians") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->Alpha),      "longitude",      REAL8,  0,   DEVELOPER, "[DEPRECATED] Use --Alpha instead!") == XLAL_SUCCESS, XLAL_EFUNC);

  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->Delta),      "Delta",          REAL8,  'd', OPTIONAL,  "Sky position Delta (equatorial coordinates) in radians") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->Delta),      "latitude",       REAL8,  0,   DEVELOPER, "[DEPRECATED] Use --Delta instead!") == XLAL_SUCCESS, XLAL_EFUNC);
 
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->phi0),       "phi0",           REAL8,  'Q', OPTIONAL,  "Phi_0: Initial phase in radians") == XLAL_SUCCESS, XLAL_EFUNC);

  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->psi),        "psi",            REAL8,  'Y', OPTIONAL,  "Polarisation in radians") == XLAL_SUCCESS, XLAL_EFUNC);

  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->cosi),       "cosi",           REAL8,  'i', OPTIONAL,  "Cos(iota)") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->cosiota),    "cosiota",        REAL8,  0,   DEVELOPER, "[DEPRECATED] Use --cosi instead") == XLAL_SUCCESS, XLAL_EFUNC);

  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->h0),         "h0",             REAL8,  's', OPTIONAL,  "Strain amplitude h_0") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->sqrtSh),     "sqrtSh",         REAL8,  'N', OPTIONAL,  "Noise floor: one-sided sqrt(Sh) in 1/sqrt(Hz)") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->timestamps), "timestampsFile", STRING, 'T', OPTIONAL,  "Name of timestamps file") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->gpsStart),   "startTime",      INT4,   'S', OPTIONAL,  "GPS start time of continuous observation") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->Tsft),       "Tsft",           REAL8,  't', OPTIONAL,  "Length of an SFT in seconds") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->nTsft),      "nTsft",          INT4,   'n', OPTIONAL,  "Number of SFTs") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->IFO),        "IFO",            STRING, 'D', OPTIONAL,  "Detector: H1, H2, L1, G1, ... ") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->detector),   "detector",       STRING, 0,   DEVELOPER, "[DEPRECATED] Use --IFO instead!") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->ephemEarth), "ephemEarth",     STRING, 0,   OPTIONAL,  "Earth ephemeris file to use") == XLAL_SUCCESS, XLAL_EFUNC);

  XLAL_CHECK_LAL( status, XLALRegisterNamedUvar(&(CLA->ephemSun),   "ephemSun",       STRING, 0,   OPTIONAL,  "Sun ephemeris file to use") == XLAL_SUCCESS, XLAL_EFUNC);

  /* ----- added for mfd_v4 compatibility ---------- */
  XLAL_CHECK_LAL ( status, XLALRegisterNamedUvar(&(CLA->duration),  "duration",       REAL8, 0,    OPTIONAL,  "Duration of requested signal in seconds") == XLAL_SUCCESS, XLAL_EFUNC);
  
  XLAL_CHECK_LAL ( status, XLALRegisterNamedUvar(&(CLA->aPlus),     "aPlus",          REAL8, 0,    OPTIONAL,  "Plus polarization amplitude aPlus") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_LAL ( status, XLALRegisterNamedUvar(&(CLA->aCross),    "aCross",         REAL8, 0,    OPTIONAL,  "Cross polarization amplitude aCross") == XLAL_SUCCESS, XLAL_EFUNC);


  DETATCHSTATUSPTR (status);
  RETURN(status);
} /* InitUserVars() */
int main( int argc, char *argv[]){

  static LALStatus            status;  
  static LALDetector          detector;
  static LIGOTimeGPSVector    timeV;
  static REAL8Cart3CoorVector velV;
  static REAL8Vector          timeDiffV;
  static REAL8Vector          foft;
  static PulsarSignalParams  params;
  static SFTParams sftParams;

  static UCHARPeakGram     pg1;
  static COMPLEX8SFTData1  sft1;
  static REAL8PeriodoPSD   periPSD;

  REAL4TimeSeries   *signalTseries = NULL;
  SFTVector    *inputSFTs  = NULL;  
  SFTVector    *outputSFTs = NULL;
  /* data about injected signal */
  static PulsarData           pulsarInject;

  /* the template */
  static HoughTemplate  pulsarTemplate, pulsarTemplate1;

  /*FILE  *fpOUT = NULL;  output file pointer */
  FILE  *fpLog = NULL; /* log file pointer */
  CHAR  *logstr=NULL; /* log string containing user input variables */
  CHAR  *fnamelog=NULL; /* name of log file */
  INT4  nfSizeCylinder;
  
  EphemerisData   *edat = NULL;

  INT4   mObsCoh, numberCount;
  REAL8  sftBand;  
  REAL8  timeBase, deltaF, normalizeThr, threshold;
  UINT4  sftlength; 
  INT4   sftFminBin;
  REAL8  fHeterodyne;
  REAL8  tSamplingRate;


  /* grid spacings */
  REAL8 deltaTheta;
  INT4 mmP, mmT; /* for loop over mismatched templates */

  /* user input variables */
  INT4 uvar_ifo, uvar_blocksRngMed;
  REAL8 uvar_peakThreshold;
  REAL8 uvar_alpha, uvar_delta, uvar_h0, uvar_f0;
  REAL8 uvar_psi, uvar_phi0, uvar_fdot, uvar_cosiota;
  CHAR *uvar_earthEphemeris=NULL;
  CHAR *uvar_sunEphemeris=NULL;
  CHAR *uvar_sftDir=NULL;
  CHAR *uvar_fnameout=NULL;

  /*  set up the default parameters  */

  nfSizeCylinder = NFSIZE;

  /* set other user input variables */
  uvar_peakThreshold = THRESHOLD;
  uvar_ifo = IFO;
  uvar_blocksRngMed = BLOCKSRNGMED;

  /* set default pulsar parameters */
  uvar_h0 = H0;
  uvar_alpha = ALPHA;
  uvar_delta = DELTA;
  uvar_f0 =  F0;
  uvar_fdot = FDOT;
  uvar_psi = PSI;
  uvar_cosiota = COSIOTA;
  uvar_phi0 = PHI0;

  /* now set the default filenames */
  uvar_earthEphemeris = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_earthEphemeris,EARTHEPHEMERIS);

  uvar_sunEphemeris = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_sunEphemeris,SUNEPHEMERIS);

  uvar_sftDir = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_sftDir,SFTDIRECTORY);

  uvar_fnameout = (CHAR *)LALMalloc(512*sizeof(CHAR));
  strcpy(uvar_fnameout, FILEOUT);

  /* register user input variables */
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_ifo,            "ifo",            INT4,   'i', OPTIONAL, "Detector GEO(1) LLO(2) LHO(3)" ) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_blocksRngMed,   "blocksRngMed",   INT4,   'w', OPTIONAL, "RngMed block size") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_peakThreshold,  "peakThreshold",  REAL8,  't', OPTIONAL, "Peak selection threshold") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_earthEphemeris, "earthEphemeris", STRING, 'E', OPTIONAL, "Earth Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sunEphemeris,   "sunEphemeris",   STRING, 'S', OPTIONAL, "Sun Ephemeris file") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_sftDir,         "sftDir",         STRING, 'D', OPTIONAL, "SFT Directory") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fnameout,       "fnameout",       STRING, 'o', OPTIONAL, "Output file prefix") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_alpha,          "alpha",          REAL8,  'r', OPTIONAL, "Right ascension") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_delta,          "delta",          REAL8,  'l', OPTIONAL, "Declination") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_h0,             "h0",             REAL8,  'm', OPTIONAL, "h0 to inject") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_f0,             "f0",             REAL8,  'f', OPTIONAL, "Start search frequency") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_psi,            "psi",            REAL8,  'p', OPTIONAL, "Polarization angle") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_phi0,           "phi0",           REAL8,  'P', OPTIONAL, "Initial phase") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_cosiota,        "cosiota",        REAL8,  'c', OPTIONAL, "Cosine of iota") == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN( XLALRegisterNamedUvar( &uvar_fdot,           "fdot",           REAL8,  'd', OPTIONAL, "Spindown parameter") == XLAL_SUCCESS, XLAL_EFUNC);

  /* read all command line variables */
  BOOLEAN should_exit = 0;
  XLAL_CHECK_MAIN( XLALUserVarReadAllInput(&should_exit, argc, argv, lalAppsVCSInfoList) == XLAL_SUCCESS, XLAL_EFUNC);
  if (should_exit)
    exit(1);
  
  /* write the log file */
  fnamelog = (CHAR *)LALMalloc( 512*sizeof(CHAR));
  strcpy(fnamelog, uvar_fnameout);
  strcat(fnamelog, "_log");
  /* open the log file for writing */
  if ((fpLog = fopen(fnamelog, "w")) == NULL) {
    fprintf(stderr, "Unable to open file %s for writing\n", fnamelog);
    LALFree(fnamelog);
    exit(1);
  }

  /* get the log string */
  XLAL_CHECK_MAIN( ( logstr = XLALUserVarGetLog(UVAR_LOGFMT_CFGFILE) ) != NULL, XLAL_EFUNC);  

  fprintf( fpLog, "## Log file for HoughMismatch\n\n");
  fprintf( fpLog, "# User Input:\n");
  fprintf( fpLog, "#-------------------------------------------\n");
  fprintf( fpLog, "%s", logstr);
  LALFree(logstr);

  /* append an ident-string defining the exact CVS-version of the code used */
  {
    CHAR command[1024] = "";
    fprintf (fpLog, "\n\n# CVS-versions of executable:\n");
    fprintf (fpLog, "# -----------------------------------------\n");
    fclose (fpLog);
    
    sprintf (command, "ident %s | sort -u >> %s", argv[0], fnamelog);
    /* we don't check this. If it fails, we assume that */
    /* one of the system-commands was not available, and */
    /* therefore the CVS-versions will not be logged */
    if ( system(command) ) fprintf (stderr, "\nsystem('%s') returned non-zero status!\n\n", command );

    LALFree(fnamelog); 
  }

  /* set peak selection threshold */
  SUB( LALRngMedBias( &status, &normalizeThr, uvar_blocksRngMed ), &status ); 
  threshold = uvar_peakThreshold/normalizeThr; 

  /* set detector */
  if (uvar_ifo ==1) detector=lalCachedDetectors[LALDetectorIndexGEO600DIFF];
  if (uvar_ifo ==2) detector=lalCachedDetectors[LALDetectorIndexLLODIFF];
  if (uvar_ifo ==3) detector=lalCachedDetectors[LALDetectorIndexLHODIFF];


  /* copy user input values */
  pulsarInject.f0 = uvar_f0;
  pulsarInject.latitude = uvar_delta;
  pulsarInject.longitude = uvar_alpha;
  pulsarInject.aPlus = 0.5 * uvar_h0 * ( 1.0 + uvar_cosiota * uvar_cosiota );
  pulsarInject.aCross = uvar_h0 * uvar_cosiota;
  pulsarInject.psi = uvar_psi;
  pulsarInject.phi0 = uvar_phi0;
  pulsarInject.spindown.length = 1;
  pulsarInject.spindown.data = NULL;
  pulsarInject.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));
  pulsarInject.spindown.data[0] = uvar_fdot;

  /* copy these values also to the pulsar template */
  /* template is complately matched at this point */
  pulsarTemplate.f0 = uvar_f0;
  pulsarTemplate.latitude = uvar_delta;
  pulsarTemplate.longitude = uvar_alpha;
  pulsarTemplate.spindown.length = 1;
  pulsarTemplate.spindown.data = NULL;
  pulsarTemplate.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));
  pulsarTemplate.spindown.data[0] = uvar_fdot;

  /* allocate memory for mismatched spindown template */
  pulsarTemplate1.spindown.length = 1;
  pulsarTemplate1.spindown.data = NULL;
  pulsarTemplate1.spindown.data = (REAL8 *)LALMalloc(sizeof(REAL8));

  /* read sfts */
  {
    CHAR *tempDir;
    tempDir = (CHAR *)LALMalloc(512*sizeof(CHAR));
    strcpy(tempDir, uvar_sftDir);
    strcat(tempDir, "/*SFT*.*"); 
    sftBand = 0.5; 
    SUB( LALReadSFTfiles ( &status, &inputSFTs, uvar_f0 - sftBand, uvar_f0 + sftBand, nfSizeCylinder + uvar_blocksRngMed , tempDir), &status);
    LALFree(tempDir);
  }


  /* get sft parameters */
  mObsCoh = inputSFTs->length;
  sftlength = inputSFTs->data->data->length;
  deltaF = inputSFTs->data->deltaF;
  timeBase = 1.0/deltaF;
  sftFminBin = floor( timeBase * inputSFTs->data->f0 + 0.5);
  fHeterodyne = sftFminBin*deltaF;
  tSamplingRate = 2.0*deltaF*(sftlength -1.);

  /* create timestamp vector */
  timeV.length = mObsCoh;
  timeV.data = NULL;  
  timeV.data = (LIGOTimeGPS *)LALMalloc(mObsCoh*sizeof(LIGOTimeGPS));

  /* read timestamps */
  { 
    INT4    i; 
    SFTtype  *sft= NULL; 
    
    sft = inputSFTs->data;
    for (i=0; i < mObsCoh; i++){
      timeV.data[i].gpsSeconds = sft->epoch.gpsSeconds;
      timeV.data[i].gpsNanoSeconds = sft->epoch.gpsNanoSeconds;
      ++sft;
    }    
  }

  /* compute the time difference relative to startTime for all SFT */
  timeDiffV.length = mObsCoh;
  timeDiffV.data = NULL; 
  timeDiffV.data = (REAL8 *)LALMalloc(mObsCoh*sizeof(REAL8));

  {   
    REAL8   t0, ts, tn, midTimeBase;
    INT4   j; 

    midTimeBase=0.5*timeBase;
    ts = timeV.data[0].gpsSeconds;
    tn = timeV.data[0].gpsNanoSeconds * 1.00E-9;
    t0=ts+tn;
    timeDiffV.data[0] = midTimeBase;

    for (j=1; j< mObsCoh; ++j){
      ts = timeV.data[j].gpsSeconds;
      tn = timeV.data[j].gpsNanoSeconds * 1.00E-9;  
      timeDiffV.data[j] = ts+tn -t0+midTimeBase; 
    }  
  }

  /* compute detector velocity for those time stamps  */ 
  velV.length = mObsCoh; 
  velV.data = NULL;
  velV.data = (REAL8Cart3Coor *)LALMalloc(mObsCoh*sizeof(REAL8Cart3Coor));
  
  {  
    VelocityPar   velPar;
    REAL8     vel[3]; 
    UINT4     j; 

    velPar.detector = detector;
    velPar.tBase = timeBase;
    velPar.vTol = 0.0; /* irrelevant */
    velPar.edat = NULL;

    /* read in ephemeris data */
    XLAL_CHECK_MAIN( ( edat = XLALInitBarycenter( uvar_earthEphemeris, uvar_sunEphemeris ) ) != NULL, XLAL_EFUNC);
    velPar.edat = edat;

    /* calculate detector velocity */    
    for(j=0; j< velV.length; ++j){
      velPar.startTime.gpsSeconds     = timeV.data[j].gpsSeconds;
      velPar.startTime.gpsNanoSeconds = timeV.data[j].gpsNanoSeconds;
      
      SUB( LALAvgDetectorVel ( &status, vel, &velPar), &status );
      velV.data[j].x= vel[0];
      velV.data[j].y= vel[1];
      velV.data[j].z= vel[2];   
    }  
  }

  /* set grid spacings */
  {
    deltaTheta = 1.0 / ( VTOT * uvar_f0 * timeBase );
    /* currently unused: REAL8 deltaFdot = deltaF / timeBase; */
  }

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

  /* allocate memory for Hough peripsd structure */
  periPSD.periodogram.length = sftlength;
  periPSD.periodogram.data = NULL;
  periPSD.periodogram.data = (REAL8 *)LALMalloc(sftlength* sizeof(REAL8));
  periPSD.psd.length = sftlength;
  periPSD.psd.data = NULL;
  periPSD.psd.data = (REAL8 *)LALMalloc(sftlength* sizeof(REAL8));

  /* allocate memory for peakgram */
  pg1.length = sftlength;
  pg1.data = NULL;
  pg1.data = (UCHAR *)LALMalloc(sftlength* sizeof(UCHAR));

  /* generate signal and add to input sfts */  
  /* parameters for output sfts */
  sftParams.Tsft = timeBase;
  sftParams.timestamps = &(timeV);
  sftParams.noiseSFTs = inputSFTs;  
  
  /* signal generation parameters */
  params.orbit.asini = 0 /* isolated pulsar */;
  /* params.transferFunction = NULL; */
  params.site = &(detector);
  params.ephemerides = edat;
  params.startTimeGPS.gpsSeconds = timeV.data[0].gpsSeconds;   /* start time of output time series */
  params.startTimeGPS.gpsNanoSeconds = timeV.data[0].gpsNanoSeconds;   /* start time of output time series */
  params.duration = timeDiffV.data[mObsCoh-1] + 0.5 * timeBase; /* length of time series in seconds */
  params.samplingRate = tSamplingRate;
  params.fHeterodyne = fHeterodyne;
  /* reference time for frequency and spindown is first timestamp */
  params.pulsar.refTime.gpsSeconds = timeV.data[0].gpsSeconds; 
  params.pulsar.refTime.gpsNanoSeconds = timeV.data[0].gpsNanoSeconds;

  params.pulsar.position.longitude = pulsarInject.longitude;
  params.pulsar.position.latitude = pulsarInject.latitude ;
  params.pulsar.position.system = COORDINATESYSTEM_EQUATORIAL; 
  params.pulsar.psi = pulsarInject.psi;
  params.pulsar.aPlus = pulsarInject.aPlus;
  params.pulsar.aCross = pulsarInject.aCross;
  params.pulsar.phi0 = pulsarInject.phi0;
  params.pulsar.f0 = pulsarInject.f0;
  params.pulsar.spindown = &pulsarInject.spindown ;

  SUB( LALGeneratePulsarSignal(&status, &signalTseries, &params ), &status);
  SUB( LALSignalToSFTs(&status, &outputSFTs, signalTseries, &sftParams), &status); 

  
  /* fill in elements of sft structure sft1 used in peak selection */
  sft1.length = sftlength;
  sft1.fminBinIndex = sftFminBin;
  sft1.timeBase = timeBase;

  /* loop over mismatched templates */
  for (mmT = -2; mmT <= 2; mmT++)
    { 
      for (mmP = -2; mmP <= 2; mmP++)
	{
	  INT4 mmFactor;
	  
	  /* displace the template */
	  mmFactor = 1.0;
	  pulsarTemplate1.f0 = pulsarTemplate.f0 /*+ mmFactor * mm * deltaF*/; 
	  pulsarTemplate1.latitude = pulsarTemplate.latitude + mmFactor * mmT * deltaTheta;
	  pulsarTemplate1.longitude = pulsarTemplate.longitude + mmFactor * mmP * deltaTheta;
	  pulsarTemplate1.spindown.data[0] = pulsarTemplate.spindown.data[0] /*+ mmFactor * mm * deltaFdot*/;
	  
	  numberCount = 0;
	  /* now calculate the number count for the template */
          INT4 j;
	  for (j=0; j < mObsCoh; j++)  
	    {
	      INT4 ind;
	      
	      sft1.epoch.gpsSeconds = timeV.data[j].gpsSeconds;
	      sft1.epoch.gpsNanoSeconds = timeV.data[j].gpsNanoSeconds;
	      sft1.data = outputSFTs->data[j].data->data;
	      
	      SUB( COMPLEX8SFT2Periodogram1(&status, &periPSD.periodogram, &sft1), &status );	
	      
	      SUB( LALPeriodo2PSDrng( &status, 
				      &periPSD.psd, &periPSD.periodogram, &uvar_blocksRngMed), &status );	
	      
	      SUB( LALSelectPeakColorNoise(&status,&pg1,&threshold,&periPSD), &status); 	 
	      
	      SUB( ComputeFoft(&status, &foft, &pulsarTemplate1, &timeDiffV, &velV, timeBase), &status);
	      
	      ind = floor( foft.data[j]*timeBase - sftFminBin + 0.5); 
	      
	      numberCount += pg1.data[ind]; 
	    } 
	  /* print the number count */
	  fprintf(stdout, "%d    %d    %d\n", mmT, mmP, numberCount);
	}
    }
  
  /* free structures created by signal generation routines */
  LALFree(signalTseries->data->data);
  LALFree(signalTseries->data);
  LALFree(signalTseries);
  signalTseries =NULL;
  XLALDestroySFTVector( outputSFTs);

  /* destroy input sfts */
  XLALDestroySFTVector( inputSFTs);

  /* free other structures */
  LALFree(foft.data);  
  LALFree(pulsarInject.spindown.data);
  LALFree(pulsarTemplate.spindown.data);
  LALFree(pulsarTemplate1.spindown.data);
  LALFree(timeV.data);
  LALFree(timeDiffV.data);
  LALFree(velV.data);
  XLALDestroyEphemerisData(edat);
  LALFree(periPSD.periodogram.data);
  LALFree(periPSD.psd.data);

  LALFree(pg1.data);

  XLALDestroyUserVars();  
  LALCheckMemoryLeaks();
  
  INFO( DRIVEHOUGHCOLOR_MSGENORM );
  return DRIVEHOUGHCOLOR_ENORM;
}