ComputeFStatistic_resamp.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Pinkesh Patel, Xavier Siemens
00003  * Copyright (C) 2007 Reinhard Prix, Iraj Gholami , Pinkesh Patel, Xavier Siemens
00004  * Copyright (C) 2005, 2006 Reinhard Prix, Iraj Gholami
00005  * Copyright (C) 2004 Reinhard Prix
00006  * Copyright (C) 2002, 2003, 2004 M.A. Papa, X. Siemens, Y. Itoh
00007  *
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; either version 2 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License
00019  *  along with with program; see the file COPYING. If not, write to the
00020  *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00021  *  MA  02111-1307  USA
00022  */
00023 
00024 /*********************************************************************************/
00025 /** \author P.Patel, X.Siemens, R. Prix, I. Gholami, Y. Ioth,M. Papa
00026  * \file
00027  * \brief
00028  * Calculate the F-statistic for a given parameter-space of pulsar GW signals.
00029  * Implements the so-called "F-statistic" as introduced in \ref JKS98.
00030  *
00031  *********************************************************************************/
00032 #include "config.h"
00033 
00034 /* System includes */
00035 #include <math.h>
00036 #include <stdio.h>
00037 #include <time.h>
00038 #ifdef HAVE_UNISTD_H
00039 #include <unistd.h>
00040 #endif
00041 
00042 
00043 int finite(double);
00044 
00045 /* LAL-includes */
00046 #include <lal/AVFactories.h>
00047 #include <lal/LALInitBarycenter.h>
00048 #include <lal/UserInput.h>
00049 #include <lal/SFTfileIO.h>
00050 #include <lal/ExtrapolatePulsarSpins.h>
00051 #include <lal/FrequencySeries.h>
00052 
00053 #include <lal/NormalizeSFTRngMed.h>
00054 #include <lal/ComputeFstat.h>
00055 #include <lal/LALHough.h>
00056 
00057 #include <lal/LogPrintf.h>
00058 #include <lal/DopplerFullScan.h>
00059 #include <lal/ComplexFFT.h>
00060 #include <lal/LALBarycenter.h>
00061 
00062 #include <lalapps.h>
00063 #include <lal/Window.h>
00064 #include <fftw3.h>
00065 #include <gsl/gsl_errno.h>
00066 #include <gsl/gsl_spline.h>
00067 #include <gsl/gsl_interp.h>
00068 
00069 /* local includes */
00070 
00071 #include "../HeapToplist.h"
00072 
00073 RCSID("$Id: ComputeFStatistic_resamp.c,v 1.30 2008/08/21 07:44:03 ppatel Exp $");
00074 NRCSID(TEMPORARY,"$Blah$");
00075 
00076 /*---------- DEFINES ----------*/
00077 
00078 #define MAXFILENAMELENGTH 256   /* Maximum # of characters of a SFT filename */
00079 
00080 #define EPHEM_YEARS  "00-04"    /**< default range: override with --ephemYear */
00081 
00082 #define TRUE (1==1)
00083 #define FALSE (1==0)
00084 
00085 /*----- SWITCHES -----*/
00086 #define NUM_SPINS 4             /* number of spin-values to consider: {f, fdot, f2dot, ... } */
00087 
00088 /*----- Error-codes -----*/
00089 #define COMPUTEFSTATISTIC_ENULL         1
00090 #define COMPUTEFSTATISTIC_ESYS          2
00091 #define COMPUTEFSTATISTIC_EINPUT        3
00092 #define COMPUTEFSTATISTIC_EMEM          4
00093 #define COMPUTEFSTATISTIC_ENONULL       5
00094 #define COMPUTEFSTATISTIC_EXLAL         6
00095 
00096 #define COMPUTEFSTATISTIC_MSGENULL      "Arguments contained an unexpected null pointer"
00097 #define COMPUTEFSTATISTIC_MSGESYS       "System call failed (probably file IO)"
00098 #define COMPUTEFSTATISTIC_MSGEINPUT     "Invalid input"
00099 #define COMPUTEFSTATISTIC_MSGEMEM       "Out of memory. Bad."
00100 #define COMPUTEFSTATISTIC_MSGENONULL    "Output pointer is non-NULL"
00101 #define COMPUTEFSTATISTIC_MSGEXLAL      "XLALFunction-call failed"
00102 
00103 /*----- Macros -----*/
00104 
00105 /* convert GPS-time to REAL8 */
00106 #define GPS2REAL8(gps) (1.0 * (gps).gpsSeconds + 1.e-9 * (gps).gpsNanoSeconds )
00107 #define SQ(x) ( (x) * (x) )
00108 
00109 #define MYMAX(x,y) ( (x) > (y) ? (x) : (y) )
00110 #define MYMIN(x,y) ( (x) < (y) ? (x) : (y) )
00111 
00112 #define LAL_INT4_MAX 2147483647
00113 
00114 /*---------- internal types ----------*/
00115 
00116 /** What info do we want to store in our toplist? */
00117 typedef struct {
00118   PulsarDopplerParams doppler;          /**< Doppler params of this 'candidate' */
00119   Fcomponents  Fstat;                   /**< the Fstat-value (plus Fa,Fb) for this candidate */
00120   CmplxAntennaPatternMatrix Mmunu;              /**< antenna-pattern matrix Mmunu = 0.5* Sinv*Tsft * [ Ad, Cd; Cd; Bd ] */
00121 } FstatCandidate;
00122 
00123 
00124 /** moving 'Scanline window' of candidates on the scan-line,
00125  * which is used to find local 1D maxima.
00126  */
00127 typedef struct
00128 {
00129   UINT4 length;
00130   FstatCandidate *window;               /**< array holding candidates */
00131   FstatCandidate *center;               /**< pointer to middle candidate in window */
00132 } scanlineWindow_t;
00133 
00134 /** Configuration settings required for and defining a coherent pulsar search.
00135  * These are 'pre-processed' settings, which have been derived from the user-input.
00136  */
00137 typedef struct {
00138   REAL8 Tsft;                               /**< length of one SFT in seconds */
00139   LIGOTimeGPS refTime;                      /**< reference-time for pulsar-parameters in SBB frame */
00140   /* -------------------- Resampling -------------------- */
00141   REAL8 FFTFreqBand;                        /**< treated outside of DopplerScan for resampling-technique */
00142   /* ---------------------------------------------------- */
00143   DopplerRegion searchRegion;               /**< parameter-space region (at *internalRefTime*) to search over */
00144   DopplerFullScanState *scanState;          /**< current state of the Doppler-scan */
00145   PulsarDopplerParams stepSizes;            /**< user-preferences on Doppler-param step-sizes */
00146   EphemerisData *ephemeris;                 /**< ephemeris data (from LALInitBarycenter()) */
00147   MultiSFTVector *multiSFTs;                /**< multi-IFO SFT-vectors */
00148   MultiDetectorStateSeries *multiDetStates; /**< pos, vel and LMSTs for detector at times t_i */
00149   MultiNoiseWeights *multiNoiseWeights;     /**< normalized noise-weights of those SFTs */
00150   ComputeFParams CFparams;                  /**< parameters for Fstat (e.g Dterms, SSB-prec,...) */
00151   CHAR *logstring;                          /**< log containing max-info on this search setup */
00152   toplist_t* FstatToplist;                  /**< sorted 'toplist' of the NumCandidatesToKeep loudest candidates */
00153   scanlineWindow_t *scanlineWindow;         /**< moving window of candidates on scanline to find local maxima */
00154 } ConfigVariables;
00155 
00156 LALUnit empty_Unit;
00157 
00158 /*---------- Global variables ----------*/
00159 extern UINT4 vrbflg;            /**< defined in lalapps.c */
00160 
00161 /* ----- Resampling Variables ----------*/
00162 REAL8 uvar_F;
00163 /*REAL8 uvar_Het;*/
00164 
00165 
00166 /* ----- User-variables: can be set from config-file or command-line */
00167 INT4 uvar_Dterms;
00168 CHAR *uvar_IFO;
00169 BOOLEAN uvar_SignalOnly;
00170 BOOLEAN uvar_UseNoiseWeights;
00171 REAL8 uvar_Freq;
00172 REAL8 uvar_FreqBand;
00173 /* REAL8 uvar_dFreq;   deactivated for resampling version */
00174 REAL8 uvar_Alpha;
00175 REAL8 uvar_dAlpha;
00176 REAL8 uvar_AlphaBand;
00177 REAL8 uvar_Delta;
00178 REAL8 uvar_dDelta;
00179 REAL8 uvar_DeltaBand;
00180 /* 1st spindown */
00181 REAL8 uvar_f1dot;
00182 REAL8 uvar_df1dot;
00183 REAL8 uvar_f1dotBand;
00184 /* 2nd spindown */
00185 REAL8 uvar_f2dot;
00186 REAL8 uvar_df2dot;
00187 REAL8 uvar_f2dotBand;
00188 /* 3rd spindown */
00189 REAL8 uvar_f3dot;
00190 REAL8 uvar_df3dot;
00191 REAL8 uvar_f3dotBand;
00192 /* --- */
00193 REAL8 uvar_TwoFthreshold;
00194 CHAR *uvar_ephemDir;
00195 CHAR *uvar_ephemYear;
00196 INT4  uvar_gridType;
00197 INT4  uvar_metricType;
00198 BOOLEAN uvar_projectMetric;
00199 REAL8 uvar_metricMismatch;
00200 CHAR *uvar_skyRegion;
00201 CHAR *uvar_DataFiles;
00202 BOOLEAN uvar_help;
00203 CHAR *uvar_outputLogfile;
00204 CHAR *uvar_outputFstat;
00205 CHAR *uvar_outputLoudest;
00206 
00207 INT4 uvar_NumCandidatesToKeep;
00208 INT4 uvar_clusterOnScanline;
00209 
00210 CHAR *uvar_gridFile;
00211 REAL8 uvar_dopplermax;
00212 INT4 uvar_RngMedWindow;
00213 REAL8 uvar_refTime;
00214 REAL8 uvar_internalRefTime;
00215 INT4 uvar_SSBprecision;
00216 
00217 INT4 uvar_minStartTime;
00218 INT4 uvar_maxEndTime;
00219 CHAR *uvar_workingDir;
00220 REAL8 uvar_timerCount;
00221 INT4 uvar_upsampleSFTs;
00222 
00223 REAL8 BaryRefTime;
00224 
00225 
00226 /* Defining a multi-IFO complex time series. Keeping the Real and Imaginary parts as seperate vectors, since it is necessary to interpolate them seperately */
00227 
00228 typedef struct
00229 {
00230   UINT4 length;                    /* Number of IFOs */
00231   REAL8Sequence** Real;           /* Real part of the time series */
00232   REAL8Sequence** Imag;           /* Imaginary part of the time series */
00233   REAL8 f_het;
00234   REAL8 deltaT;
00235   LIGOTimeGPS epoch; 
00236 }MultiCOMPLEX8TimeSeries;
00237 
00238 /* The Downsampled Time Series*/
00239 MultiCOMPLEX8TimeSeries* TSeries;
00240 REAL8 Fmin,Fmax;
00241 
00242 /* A container for fftw_complex vector data */
00243 typedef struct
00244 {
00245   UINT4 length;
00246   fftw_complex* data;
00247 }FFTWCOMPLEXSeries;
00248 
00249 typedef struct
00250 {
00251   UINT4 length;
00252   FFTWCOMPLEXSeries** data;
00253 }MultiFFTWCOMPLEXSeries;
00254 
00255 /* A buffer for resampling */
00256 typedef struct
00257 {
00258   const MultiDetectorStateSeries *multiDetStates;/**< buffer for each detStates (store pointer) and skypos */
00259   REAL8 Alpha, Delta;                           /**< skyposition of candidate */
00260   MultiSSBtimes *multiSSB;
00261   MultiSSBtimes *multiBinary;
00262   MultiAMCoeffs *multiAMcoef;
00263   MultiCmplxAMCoeffs *multiCmplxAMcoef;
00264   MultiFFTWCOMPLEXSeries *Saved_a,*Saved_b;      
00265 }ReSampBuffer;
00266 
00267 
00268 /* A contiguity structure required by the preprocessing function in order to store the information pertaining to the contiguity of SFTs and the gaps between them */
00269 
00270 typedef struct
00271 {
00272   UINT4  length;                    /* Number of Contiguous blocks */
00273   UINT4* NumContinuous;             /* Number of Contiguous SFTs in each block */
00274   REAL8* Gap;                       /* Gap between two Contiguous blocks in seconds */
00275 }Contiguity;
00276 
00277 
00278 /* ---------- local prototypes ---------- */
00279 /* Resampling prototypes (start) */
00280 
00281 LIGOTimeGPS REAL82GPS(REAL8 Time);
00282 void ComputeFStat_resamp (LALStatus *,REAL8FrequencySeries *fstatVector, const PulsarDopplerParams *doppler, const MultiSFTVector *multiSFTs, const MultiNoiseWeights *multiWeights, const MultiDetectorStateSeries *multiDetStates,const ComputeFParams *params, ReSampBuffer *Buffer,ConfigVariables* GV);
00283 void CalcTimeSeries(MultiSFTVector *multiSFTs);
00284 MultiCOMPLEX8TimeSeries* XLALCreateMultiCOMPLEX8TimeSeries(UINT4 i);
00285 void XLALDestroyMultiCOMPLEX8TimeSeries(MultiCOMPLEX8TimeSeries* T);
00286 void XLALDestroyReSampBuffer ( ReSampBuffer *cfb);
00287 void XLALDestroyMultiFFTWCOMPLEXSeries(MultiFFTWCOMPLEXSeries *X);
00288 void XLALDestroyMultiCOMPLEX8TimeSeries(MultiCOMPLEX8TimeSeries *T);
00289 void XLALDestroyFFTWCOMPLEXSeries(FFTWCOMPLEXSeries *X);
00290 void XLALDestroyREAL8Sequence(REAL8Sequence *X);
00291 void XLALDestroyMultiCmplxAMCoeffs(MultiCmplxAMCoeffs *X);
00292 REAL8Sequence* XLALCreateREAL8Sequence(UINT4 length);
00293 MultiFFTWCOMPLEXSeries *XLALCreateMultiFFTWCOMPLEXSeries(UINT4 length);
00294 FFTWCOMPLEXSeries *XLALCreateFFTWCOMPLEXSeries(UINT4 length);
00295 UINT4 factorial(UINT4 x);
00296 REAL8 magsquare(fftw_complex f);
00297 UINT4 Round(REAL8 X);
00298 INT4 CombineSFTs(FFTWCOMPLEXSeries *L,SFTVector *sft_vect,REAL8 FMIN,REAL8 FMAX,INT4 number,INT4 startindex);
00299 void ApplyWindow(REAL8Window *Win, FFTWCOMPLEXSeries *X);
00300 void Reshuffle(FFTWCOMPLEXSeries *X);
00301 void PrintL(FFTWCOMPLEXSeries* L,REAL8 min,REAL8 step);
00302 void ApplyHetCorrection(REAL8Sequence *BaryTimes, REAL8Sequence *DetectorTimes, REAL8 dt, REAL8Sequence *Real, REAL8Sequence *Imag, REAL8 TSFT);
00303 void ApplySpinDowns(REAL8 *SpinDowns, REAL8 dt, FFTWCOMPLEXSeries *FaIn, FFTWCOMPLEXSeries *FbIn,REAL8 StartTime, REAL8 BaryStartTime);
00304 void ApplyAandB(REAL8Sequence *FineBaryTimes,REAL8Sequence *BaryTimes,REAL8Sequence *a,REAL8Sequence *b,REAL8Sequence *Real,REAL8Sequence *Imag,FFTWCOMPLEXSeries *FaIn, FFTWCOMPLEXSeries *FbIn);
00305 double sinc(double t);
00306 void retband(REAL8 t0, REAL8 dt, REAL8* t,REAL8* x, REAL8* y,UINT4 n,UINT4 size, UINT4 terms);
00307 REAL8 strob(REAL8* Xdata, REAL8* Ydata, REAL8 X, UINT4 N1);
00308 REAL8Sequence* ResampleSeries(REAL8Sequence *X_Real,REAL8Sequence *X_Imag,REAL8Sequence *Y_Real,REAL8Sequence *Y_Imag,REAL8 dt,REAL8Vector *BaryTimes, REAL8Sequence *DetectorTimes,REAL8 TSFT);
00309 
00310 
00311 /* Resampling prototypes (end) */
00312 
00313 int main(int argc,char *argv[]);
00314 void initUserVars (LALStatus *);
00315 void InitFStat ( LALStatus *, ConfigVariables *cfg );
00316 void Freemem(LALStatus *,  ConfigVariables *cfg);
00317 
00318 void WriteFStatLog (LALStatus *, CHAR *argv[], const CHAR *log_fname);
00319 void checkUserInputConsistency (LALStatus *);
00320 int outputBeamTS( const CHAR *fname, const AMCoeffs *amcoe, const DetectorStateSeries *detStates );
00321 void InitEphemeris (LALStatus *, EphemerisData *edat, const CHAR *ephemDir, const CHAR *ephemYear, LIGOTimeGPS epoch, BOOLEAN isLISA);
00322 void getUnitWeights ( LALStatus *, MultiNoiseWeights **multiWeights, const MultiSFTVector *multiSFTs );
00323 
00324 int write_FstatCandidate_to_fp ( FILE *fp, const FstatCandidate *thisFCand );
00325 int write_PulsarCandidate_to_fp ( FILE *fp,  const PulsarCandidate *pulsarParams, const FstatCandidate *Fcand );
00326 
00327 int compareFstatCandidates ( const void *candA, const void *candB );
00328 void getLogString ( LALStatus *status, CHAR **logstr, const ConfigVariables *cfg );
00329 
00330 const char *va(const char *format, ...);        /* little var-arg string helper function */
00331 
00332 /* ---------- scanline window functions ---------- */
00333 scanlineWindow_t *XLALCreateScanlineWindow ( UINT4 windowWings );
00334 void XLALDestroyScanlineWindow ( scanlineWindow_t *scanlineWindow );
00335 int XLALAdvanceScanlineWindow ( const FstatCandidate *nextCand, scanlineWindow_t *scanWindow );
00336 BOOLEAN XLALCenterIsLocalMax ( const scanlineWindow_t *scanWindow );
00337 
00338 
00339 /*---------- empty initializers ---------- */
00340 static const ConfigVariables empty_ConfigVariables;
00341 static const FstatCandidate empty_FstatCandidate;
00342 static const ReSampBuffer empty_ReSampBuffer;
00343 
00344 /*----------------------------------------------------------------------*/
00345 /* Function definitions start here */
00346 /*----------------------------------------------------------------------*/
00347 
00348 /**
00349  * MAIN function of ComputeFStatistic code.
00350  * Calculate the F-statistic over a given portion of the parameter-space
00351  * and write a list of 'candidates' into a file(default: 'Fstats').
00352  */
00353 int main(int argc,char *argv[])
00354 {
00355   LALStatus status = blank_status;      /* initialize status */
00356   /*MultiCOMPLEX8TimeSeries* TSeries;*/
00357 
00358   FILE *fpFstat = NULL;
00359   ReSampBuffer Buffer = empty_ReSampBuffer;
00360   REAL8 numTemplates, templateCounter;
00361   REAL8 tickCounter;
00362   time_t clock0;
00363   REAL8FrequencySeries *fstatVector = NULL;
00364   PulsarDopplerParams dopplerpos = empty_PulsarDopplerParams;           /* current search-parameters */
00365   FstatCandidate loudestFCand = empty_FstatCandidate, thisFCand = empty_FstatCandidate;
00366   UINT4 k;
00367   ConfigVariables GV = empty_ConfigVariables;           /**< global container for various derived configuration settings */
00368 
00369   lalDebugLevel = 0;
00370   vrbflg = 1;   /* verbose error-messages */
00371 
00372   /* set LAL error-handler */
00373   lal_errhandler = LAL_ERR_EXIT;
00374 
00375   /* register all user-variable */
00376   LAL_CALL (LALGetDebugLevel(&status, argc, argv, 'v'), &status);
00377   LAL_CALL (initUserVars(&status), &status);
00378 
00379   /* do ALL cmdline and cfgfile handling */
00380   LAL_CALL (LALUserVarReadAllInput(&status, argc,argv), &status);
00381 
00382   if (uvar_help)        /* if help was requested, we're done here */
00383     exit (0);
00384 
00385   /* set log-level */
00386   LogSetLevel ( lalDebugLevel );
00387 
00388   /* keep a log-file recording all relevant parameters of this search-run */
00389   if ( uvar_outputLogfile ) {
00390     LAL_CALL (WriteFStatLog ( &status, argv, uvar_outputLogfile ), &status );
00391   }
00392 
00393   /* do some sanity checks on the user-input before we proceed */
00394   LAL_CALL ( checkUserInputConsistency(&status), &status);
00395 
00396   /* Initialization the common variables of the code, */
00397   /* like ephemeries data and template grids: */
00398   LAL_CALL ( InitFStat(&status, &GV), &status);
00399 
00400   /* if a complete output of the F-statistic file was requested,
00401    * we open and prepare the output-file here */
00402   if (uvar_outputFstat)
00403     {
00404       if ( (fpFstat = fopen (uvar_outputFstat, "wb")) == NULL)
00405         {
00406           LALPrintError ("\nError opening file '%s' for writing..\n\n", uvar_outputFstat);
00407           return (COMPUTEFSTATISTIC_ESYS);
00408         }
00409 
00410       fprintf (fpFstat, "%s", GV.logstring );
00411     } /* if outputFstat */
00412 
00413   /* count number of templates */
00414   numTemplates = XLALNumDopplerTemplates ( GV.scanState );
00415 
00416   /* prepare Fstat-vector over frequencies to hold output results */
00417   {
00418     REAL8 dFreq = 1.0 / GV.multiDetStates->Tspan;
00419     /*UINT4 numFreqBins = floor( GV.FFTFreqBand / dFreq +1e-6) + 1;
00420       REAL8 Freq0 = GV.searchRegion.fkdot[0];*/
00421     UINT4 numFreqBins = floor(uvar_FreqBand / dFreq + 1e-6);
00422     REAL8 Freq0 = uvar_Freq;
00423     fstatVector = XLALCreateREAL8FrequencySeries ("Fstat vector", &GV.searchRegion.refTime, Freq0, dFreq, &empty_Unit, numFreqBins );
00424     if ( fstatVector == NULL ) {
00425       fprintf ( stderr, "Oops, out of memory!\n");
00426       return  COMPUTEFSTATISTIC_EMEM;
00427     }
00428   } /* setup Fstat-vector */
00429 
00430   /*----------------------------------------------------------------------
00431    * main loop: demodulate data for each point in the sky-position grid
00432    * and for each value of the frequency-spindown
00433    */
00434   templateCounter = 0.0;
00435   tickCounter = 0;
00436   clock0 = time(NULL);
00437 
00438   /*Call the CalcTimeSeries Function Here*/
00439   LogPrintf (LOG_DEBUG, "Calculating Time Series.\n");
00440   CalcTimeSeries(GV.multiSFTs);
00441   fprintf(stderr, "\n WARNING!!! Only the middle half of the band you asked for or is usable. Rest of it is destroyed by Interpolation. Please ask for a larger band. In the future, this will be done automatically. \n"); 
00442   LogPrintf (LOG_DEBUG, "Done Calculating Time Series.\n");
00443 
00444   LogPrintf (LOG_DEBUG, "Starting Main Resampling Loop.\n");
00445   while ( XLALNextDopplerPos( &dopplerpos, GV.scanState ) == 0 )
00446     {
00447       /* main function call: compute F-statistic over frequency-band  */ 
00448       LAL_CALL( ComputeFStat_resamp ( &status, fstatVector, &dopplerpos, GV.multiSFTs, GV.multiNoiseWeights,GV.multiDetStates, &GV.CFparams, &Buffer, &GV), &status );
00449 
00450       /* Progress meter */
00451       templateCounter += 1.0;
00452       if ( lalDebugLevel && ( ++tickCounter > uvar_timerCount) )
00453         {
00454           REAL8 diffSec = time(NULL) - clock0 ;  /* seconds since start of loop*/
00455           REAL8 taup = diffSec / templateCounter ;
00456           REAL8 timeLeft = (numTemplates - templateCounter) *  taup;
00457           tickCounter = 0.0;
00458           LogPrintf (LOG_DEBUG, "Progress: %g/%g = %.2f %% done, Estimated time left: %.0f s\n",
00459                      templateCounter, numTemplates, templateCounter/numTemplates * 100.0, timeLeft);
00460         }
00461 
00462       for ( k=0; k < fstatVector->data->length; k++)
00463         {
00464       
00465           REAL8 thisF = fstatVector->data->data[k];
00466           /*REAL8 thisFreq = fstatVector->f0 + k * fstatVector->deltaF;*/
00467           REAL8 thisFreq = uvar_Freq + k* fstatVector->deltaF;
00468           /*fprintf(stderr,"f0 = %f , deltaF = %f\n",fstatVector->f0,fstatVector->deltaF);*/
00469           /* sanity check on the result */
00470           if ( !finite ( thisF ) )
00471             {
00472               LogPrintf(LOG_CRITICAL, "non-finite F = %.16g\n", thisF );
00473               LogPrintf (LOG_CRITICAL, "[Alpha,Delta] = [%.16g,%.16g],\nfkdot=[%.16g,%.16g,%.16g,%16.g]\n",
00474                          dopplerpos.Alpha, dopplerpos.Delta,
00475                          thisFreq, dopplerpos.fkdot[1], dopplerpos.fkdot[2], dopplerpos.fkdot[3] );
00476           return -1;
00477             }
00478 
00479           /* propagate fkdot from internalRefTime back to refTime for outputting results */
00480           /* FIXE: only do this for candidates we're going to write out */
00481           dopplerpos.fkdot[0] = thisFreq;
00482           /*LAL_CALL ( LALExtrapolatePulsarSpins ( &status, dopplerpos.fkdot, GV.refTime, dopplerpos.fkdot, GV.searchRegion.refTime ), &status );*/
00483           dopplerpos.refTime = GV.refTime;
00484 
00485           /* correct normalization in --SignalOnly case:
00486            * we didn't normalize data by 1/sqrt(Tsft * 0.5 * Sh) in terms of
00487            * the single-sided PSD Sh: the SignalOnly case is characterized by
00488            * setting Sh->1, so we need to divide Fa,Fb by sqrt(0.5*Tsft) and F by (0.5*Tsft)
00489            */
00490           if ( uvar_SignalOnly )
00491             {
00492               REAL8 norm = 1.0 / sqrt( 0.5 * GV.Tsft );
00493               thisF *= norm * norm;
00494               thisF += 2;               /* compute E[2F]:= 4 + SNR^2 */
00495             }
00496           thisFCand.Fstat.F = thisF;
00497           thisFCand.doppler = dopplerpos;
00498 
00499           /* push new value onto scan-line buffer */
00500           XLALAdvanceScanlineWindow ( &thisFCand, GV.scanlineWindow );
00501 
00502           /* two types of threshold: fixed (TwoFThreshold) and dynamic (NumCandidatesToKeep) */
00503           if ( XLALCenterIsLocalMax ( GV.scanlineWindow )                                       /* must be 1D local maximum */
00504                && (2.0 * GV.scanlineWindow->center->Fstat.F >= uvar_TwoFthreshold) )    /* fixed threshold */
00505             {
00506               FstatCandidate *writeCand = GV.scanlineWindow->center;
00507 
00508               /* insert this into toplist if requested */
00509               if ( GV.FstatToplist  )                   /* dynamic threshold */
00510                 {
00511                   if ( insert_into_toplist(GV.FstatToplist, (void*)writeCand ) )
00512                     LogPrintf ( LOG_DETAIL, "Added new candidate into toplist: 2F = %f\n", 2.0 * writeCand->Fstat.F );
00513                   else
00514                     LogPrintf ( LOG_DETAIL, "NOT added the candidate into toplist: 2F = %f\n", 2 * writeCand->Fstat.F );
00515                 }
00516               else if ( fpFstat )                               /* no toplist :write out immediately */
00517                 {
00518                   if ( write_FstatCandidate_to_fp ( fpFstat, writeCand ) != 0 )
00519                     {
00520                       LogPrintf (LOG_CRITICAL, "Failed to write candidate to file.\n");
00521                       return -1;
00522                     }
00523                 } /* if outputFstat */
00524 
00525             } /* if 2F > threshold */
00526 
00527           /* separately keep track of loudest candidate (for --outputLoudest) */
00528           if ( thisFCand.Fstat.F > loudestFCand.Fstat.F )
00529             loudestFCand = thisFCand;
00530 
00531         } /* inner loop about frequency-bins from resampling frequ-band */
00532 
00533     } /* while more Doppler positions to scan */
00534 
00535   /* ----- if using toplist: sort and write it out to file now ----- */
00536   if ( fpFstat && GV.FstatToplist )
00537     {
00538       UINT4 el;
00539 
00540       /* sort toplist */
00541       LogPrintf ( LOG_DEBUG, "Sorting toplist ... ");
00542       qsort_toplist ( GV.FstatToplist, compareFstatCandidates );
00543       LogPrintfVerbatim ( LOG_DEBUG, "done.\n");
00544 
00545       for ( el=0; el < GV.FstatToplist->elems; el ++ )
00546         {
00547           const FstatCandidate *candi;
00548           if ( ( candi = (const FstatCandidate *) toplist_elem ( GV.FstatToplist, el )) == NULL ) {
00549             LogPrintf ( LOG_CRITICAL, "Internal consistency problems with toplist: contains fewer elements than expected!\n");
00550             return -1;
00551           }
00552           if ( write_FstatCandidate_to_fp ( fpFstat, candi ) != 0 )
00553             {
00554               LogPrintf (LOG_CRITICAL, "Failed to write candidate to file.\n");
00555               return -1;
00556             }
00557         } /* for el < elems in toplist */
00558 
00559     } /* if fpFstat && toplist */
00560 
00561   XLALDestroyMultiCOMPLEX8TimeSeries(TSeries);
00562 
00563   if ( fpFstat )
00564     {
00565       fprintf (fpFstat, "%%DONE\n");
00566       fclose (fpFstat);
00567       fpFstat = NULL;
00568     }
00569 
00570   /* ----- estimate amplitude-parameters for the loudest canidate and output into separate file ----- */
00571   if ( uvar_outputLoudest )
00572     {
00573       FILE *fpLoudest;
00574       PulsarCandidate pulsarParams = empty_PulsarCandidate;
00575       pulsarParams.Doppler = loudestFCand.doppler;
00576 
00577       LAL_CALL(LALEstimatePulsarAmplitudeParams (&status, &pulsarParams, &loudestFCand.Fstat, &GV.searchRegion.refTime, &loudestFCand.Mmunu ),
00578                &status );
00579 
00580       if ( (fpLoudest = fopen (uvar_outputLoudest, "wb")) == NULL)
00581         {
00582           LALPrintError ("\nError opening file '%s' for writing..\n\n", uvar_outputLoudest);
00583           return COMPUTEFSTATISTIC_ESYS;
00584         }
00585 
00586       /* write header with run-info */
00587       fprintf (fpLoudest, "%s", GV.logstring );
00588 
00589       /* write this 'candidate' to disc */
00590       if ( write_PulsarCandidate_to_fp ( fpLoudest,  &pulsarParams, &loudestFCand) != XLAL_SUCCESS )
00591         {
00592           LogPrintf(LOG_CRITICAL, "call to write_PulsarCandidate_to_fp() failed!\n");
00593           return COMPUTEFSTATISTIC_ESYS;
00594         }
00595 
00596       fclose (fpLoudest);
00597 
00598       gsl_matrix_free ( pulsarParams.AmpFisherMatrix );
00599 
00600     } /* write loudest candidate to file */
00601 
00602   LogPrintf (LOG_DEBUG, "Search finished.\n");
00603 
00604   /* Free memory */
00605   LogPrintf (