Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ComputeFstatistic_v2.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 David Keitel, Santiago Caride, Reinhard Prix
3 * Copyright (C) 2008, 2013 Karl Wette
4 * Copyright (C) 2007 Chris Messenger
5 * Copyright (C) 2004, 2007, 2010 Reinhard Prix
6 * Copyright (C) 2005, 2006 Reinhard Prix, Iraj Gholami
7 * Copyright (C) 2002, 2003, 2004 M.A. Papa, X. Siemens, Y. Itoh
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with with program; see the file COPYING. If not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301 USA
23 */
24
25/*********************************************************************************/
26/**
27 * \defgroup lalpulsar_bin_Fstatistic Fstatistic Search Applications
28 * \ingroup lalpulsar_bin_Apps
29 */
30
31/**
32 * \author R. Prix, I. Gholami, Y. Ioth, Papa, X. Siemens, C. Messenger, K. Wette
33 * \file
34 * \ingroup lalpulsar_bin_Fstatistic
35 * \brief
36 * Calculate the F-statistic for a given parameter-space of pulsar GW signals.
37 * Implements the so-called "F-statistic" as introduced in \cite JKS98 .
38 *
39 * This code is a descendant of an earlier implementation 'ComputeFStatistic.[ch]'
40 * by Bruce Allen, Bernd Machenschalk, David Hammer, Jolien Creighton, Maria Alessandra Papa,
41 * Reinhard Prix, Xavier Siemens, Scott Koranda, Yousuke Itoh
42 *
43 */
44#include "config.h"
45
46#include <math.h>
47#include <stdio.h>
48#include <strings.h>
49#ifdef HAVE_UNISTD_H
50#include <unistd.h>
51#endif
52
53#include <gsl/gsl_math.h>
54
55#include <lal/LALString.h>
56#include <lal/AVFactories.h>
57#include <lal/LALInitBarycenter.h>
58#include <lal/UserInput.h>
59#include <lal/TranslateAngles.h>
60#include <lal/TranslateMJD.h>
61#include <lal/SFTfileIO.h>
62#include <lal/ExtrapolatePulsarSpins.h>
63#include <lal/FstatisticTools.h>
64#include <lal/NormalizeSFTRngMed.h>
65#include <lal/ComputeFstat.h>
66#include <lal/LALHough.h>
67#include <lal/LogPrintf.h>
68#include <lal/DopplerFullScan.h>
69#include <lal/BinaryPulsarTiming.h>
70#include <lal/TransientCW_utils.h>
71#include <lal/LineRobustStats.h>
72#include <lal/HeapToplist.h>
73#include <lal/LALPulsarVCSInfo.h>
74
75/*---------- DEFINES ----------*/
76
77#define TRUE (1==1)
78#define FALSE (1==0)
79#define SQ(x) ( (x) * (x) )
80
81/*----- SWITCHES -----*/
82/*----- Macros -----*/
83
84/** convert GPS-time to REAL8 */
85#define MYMAX(x,y) ( (x) > (y) ? (x) : (y) )
86#define MYMIN(x,y) ( (x) < (y) ? (x) : (y) )
87
88// NOTE: LAL's nan is more portable than either of libc or gsl !
89#define LAL_NAN XLALREAL4FailNaN()
90/*---------- internal types ----------*/
91
92/** What info do we want to store in our toplist? */
93typedef struct {
94 PulsarDopplerParams doppler; /**< Doppler params of this 'candidate' */
95 REAL4 twoF; /**< F-statistic value */
96 UINT4 numDetectors; /**< number of detectors = effective vector length. numDetectors=0 should make all code ignore the FX field. */
97 REAL4 twoFX[PULSAR_MAX_DETECTORS]; /**< vector of single-detector F-statistic values (array of fixed size) */
98 LIGOTimeGPS FaFb_refTime; /**< reference time of Fa and Fb */
99 COMPLEX16 Fa; /**< complex amplitude Fa */
100 COMPLEX16 Fb; /**< complex amplitude Fb */
101 AntennaPatternMatrix Mmunu; /**< antenna-pattern matrix Mmunu = (h_mu|h_nu) */
102 REAL4 log10BSGL; /**< Line-robust statistic \f$ \log_{10}B_{\mathrm{SGL}} \f$ */
104
105/**
106 * moving 'Scanline window' of candidates on the scan-line,
107 * which is used to find local 1D maxima.
108 */
109typedef struct {
111 FstatCandidate *window; /**< array holding candidates */
112 FstatCandidate *center; /**< pointer to middle candidate in window */
114
115/**
116 * Struct holding various timing measurements and relevant search parameters.
117 * This is used to fit timing-models with measured times to predict search run-times
118 */
119typedef struct {
120 UINT4 NSFTs; /**< total number of SFTs */
121 UINT4 NFreq; /**< number of frequency bins */
122 REAL8 tauFstat; /**< time to compute one Fstatistic over full data-duration (NSFT atoms) [in seconds]*/
123 REAL8 tauTemplate; /**< total loop time per template, includes candidate-handling (transient stats, toplist etc) */
124 REAL8 tauF0; /**< Demod timing constant = time per template per SFT */
125
126 /* ----- transient-specific timings */
127 UINT4 tauMin; /**< shortest transient timescale [s] */
128 UINT4 tauMax; /**< longest transient timescale [s] */
129 UINT4 NStart; /**< number of transient start-time steps in FstatMap matrix */
130 UINT4 NTau; /**< number of transient timescale steps in FstatMap matrix */
131 REAL8 tauTransFstatMap; /**< time to compute transient-search Fstatistic-map over {t0, tau} [s] */
132 REAL8 tauTransMarg; /**< time to marginalize the Fstat-map to compute transient-search Bayes [s] */
133
135
136/**
137 * Enum for which statistic is used to "rank" significance of candidates
138 */
139typedef enum {
140 RANKBY_2F = 0, /**< rank candidates by F-statistic */
141 RANKBY_NC = 1, /**< HierarchSearchGCT also has RANKBY_NC = 1, not applicable here */
142 RANKBY_BSGL = 2 /**< rank candidates by BSGListic */
144
145
146/**
147 * Configuration settings required for and defining a coherent pulsar search.
148 * These are 'pre-processed' settings, which have been derived from the user-input.
149 */
150typedef struct {
151 LIGOTimeGPS startTime; /**< starting timestamp of SFTs */
152 REAL8 Tspan; /**< time spanned by all SFTs */
153 REAL8 Alpha; /**< sky position alpha in radians */
154 REAL8 Delta; /**< sky position delta in radians */
155 REAL8 Tsft; /**< length of one SFT in seconds */
156 DopplerRegion searchRegion; /**< parameter-space region to search over */
157 DopplerFullScanState *scanState; /**< current state of the Doppler-scan */
158 PulsarDopplerParams stepSizes; /**< user-preferences on Doppler-param step-sizes */
159 EphemerisData *ephemeris; /**< ephemeris data (from XLALInitBarycenter()) */
160 UINT4 NSFTs; /**< total number of all SFTs used */
161 UINT4Vector *numSFTsPerDet; /**< number of SFTs per detector, for log strings, etc. */
162 LALStringVector *detectorIDs; /**< detector ID names, for column headings string */
163 FstatInput *Fstat_in; /**< Fstat input data struct */
164 FstatQuantities Fstat_what; /**< Fstat quantities to compute */
165 toplist_t *FstatToplist; /**< sorted 'toplist' of the NumCandidatesToKeep loudest candidates */
166 scanlineWindow_t *scanlineWindow; /**< moving window of candidates on scanline to find local maxima */
167 CHAR *VCSInfoString; /**< Git version string */
168 CHAR *logstring; /**< log containing max-info on the whole search setup */
169 transientWindowRange_t transientWindowRange; /**< search range parameters for transient window */
170 BSGLSetup *BSGLsetup; /**< pre-computed setup for line-robust statistic */
171 RankingStat_t RankingStatistic; /**< rank candidates according to F or BSGL */
175 PulsarParamsVector *injectionSources; /**< Source parameters to inject: comma-separated list of file-patterns and/or direct config-strings ('{...}') */
176 MultiLIGOTimeGPSVector *multiTimestamps; /**< a vector of timestamps (only set if provided from dedicated time stamp files) */
177 MultiLALDetector multiIFO; /**< detectors to generate data for (if provided by user and not via noise files) */
178 BOOLEAN runSearch; /**< whether to actually perform the search, or just generate a grid and/or count templates */
180
181
182/* ----- User-variables: can be set from config-file or command-line */
183typedef struct {
184 INT4 Dterms; /**< number of terms in LALDemod Dirichlet kernel is Dterms+1 */
185
186 LALStringVector *assumeSqrtSX;/**< Assume stationary Gaussian noise with detector noise-floors sqrt{SX}" */
187 BOOLEAN UseNoiseWeights; /**< use SFT-specific noise-weights for each segment in Fstat-computation */
188
189 REAL8 Freq; /**< start-frequency of search */
190 REAL8 FreqBand; /**< Frequency-band to search over */
191 REAL8 dFreq; /**< user-specifyable Frequency stepsize */
192
193 REAL8 Alpha; /**< equatorial right-ascension in rad */
194 REAL8 dAlpha;
195 REAL8 AlphaBand;
196
197 REAL8 Delta; /**< equatorial declination in rad */
198 REAL8 dDelta;
199 REAL8 DeltaBand;
200
201 REAL8 f1dot; /**< 1st spindown dFreq/dt */
202 REAL8 df1dot;
203 REAL8 f1dotBand;
204
205 REAL8 f2dot; /**< 2nd spindown d^2Freq/dt^2 */
206 REAL8 df2dot;
207 REAL8 f2dotBand;
208
209 REAL8 f3dot; /**< 3rd spindown d^3Freq/dt^3 */
210 REAL8 df3dot;
211 REAL8 f3dotBand;
212
213 /* orbital parameters */
214 REAL8 orbitPeriod; /**< binary-system orbital period in s */
215 REAL8 dorbitPeriod;
216 REAL8 orbitPeriodBand;
217 REAL8 orbitasini; /**< amplitude of radial motion */
218 REAL8 dorbitasini;
219 REAL8 orbitasiniBand;
220 LIGOTimeGPS orbitTp; /**< epoch of periapse passage */
221 REAL8 dorbitTp;
222 REAL8 orbitTpBand;
223 REAL8 orbitArgp; /**< angle of periapse */
224 REAL8 dorbitArgp;
225 REAL8 orbitArgpBand;
226 REAL8 orbitEcc; /**< orbital eccentricity */
227 REAL8 dorbitEcc;
228 REAL8 orbitEccBand;
229
230 /* extra parameters for --gridType==GRID_SPINDOWN_SQUARE */
231 BOOLEAN strictSpindownBounds; /**< suppress spindown grid points outside the [fkdot,fkdotBand] ranges? */
232
233 /* extra parameters for --gridType=GRID_SPINDOWN_AGEBRK parameter space */
234 REAL8 spindownAge; /**< spindown age of the object */
235 REAL8 minBraking; /**< minimum braking index */
236 REAL8 maxBraking; /**< maximum braking index */
237
238 /* --- */
239 REAL8 TwoFthreshold; /**< output threshold on 2F */
240 CHAR *ephemEarth; /**< Earth ephemeris file to use */
241 CHAR *ephemSun; /**< Sun ephemeris file to use */
242
243 INT4 gridType; /**< type of template grid in parameter space */
244 INT4 metricType; /**< type of metric to use in metric template grids */
245 BOOLEAN projectMetric; /**< should we use frequency-projected metric? */
246 REAL8 metricMismatch; /**< maximal *nominal* metric mismatch *per* dimension */
247 CHAR *skyRegion; /**< list of skypositions defining a search-polygon */
248 CHAR *DataFiles; /**< glob-pattern for SFT data-files to use */
249
250 CHAR *outputLogfile; /**< write a log-file */
251 CHAR *outputFstat; /**< filename to output Fstatistic in */
252 CHAR *outputLoudest; /**< filename for loudest F-candidate plus parameter estimation */
253
254 CHAR *outputFstatHist; /**< output discrete histogram of all Fstatistic values */
255 REAL8 FstatHistBin; /**< width of an Fstatistic histogram bin */
256
257 BOOLEAN countTemplates; /**< just count templates (if supported) instead of search */
258 CHAR *outputGrid; /**< filename to output grid points in */
259
260 INT4 NumCandidatesToKeep; /**< maximal number of toplist candidates to output */
261 REAL8 FracCandidatesToKeep; /**< fractional number of candidates to output in toplist */
262 INT4 clusterOnScanline; /**< number of points on "scanline" to use for 1-D local maxima finding */
263
264 CHAR *gridFile; /**< read template grid from this file */
265
266 INT4 RngMedWindow; /**< running-median window for noise floor estimation */
267 LIGOTimeGPS refTime; /**< reference-time for definition of pulsar-parameters [GPS] */
268
269 int SSBprecision; /**< full relativistic timing or Newtonian */
270
271 LIGOTimeGPS minStartTime; /**< Only use SFTs with timestamps starting from (including) this epoch (format 'xx.yy[GPS]' or 'xx.yyMJD') */
272 LIGOTimeGPS maxStartTime; /**< Only use SFTs with timestamps up to (excluding) this epoch (format 'xx.yy[GPS]' or 'xx.yyMJD') */
273 CHAR *workingDir; /**< directory to use for output files */
274 REAL8 timerCount; /**< output progress-meter every timerCount seconds */
275
276 CHAR *outputFstatAtoms; /**< output per-SFT, per-IFO 'atoms', ie quantities required to compute F-stat */
277
278 BOOLEAN outputSingleFstats; /**< in multi-detector case, also output single-detector F-stats */
279 CHAR *RankingStatistic; /**< rank candidates according to F-stat or BSGL */
280
281 BOOLEAN computeBSGL; /**< get single-IFO F-stats and compute line-robust statistic */
282 BOOLEAN BSGLlogcorr; /**< BSGL: compute log-correction (slower) or not (faster) */
283 REAL8 Fstar0; /**< BSGL: transition-scale parameter 'Fstar0', see documentation for XLALCreateBSGLSetup() for details */
284 LALStringVector *oLGX; /**< BSGL: prior per-detector line-vs-Gauss odds 'oLGX', see XLALCreateBSGLSetup() for details */
285 REAL8 BSGLthreshold; /**< output threshold on BSGL */
286
287 CHAR *outputTransientStats; /**< output file for transient B-stat values */
288 CHAR *outputTransientStatsAll; /**< output file for transient Fstat map F(t0,tau) for each candidate */
289 CHAR *transient_WindowType; /**< name of transient window ('none', 'rect', 'exp',...) */
290 LIGOTimeGPS transient_t0Epoch; /**< earliest GPS start-time for transient window search, in seconds */
291 UINT4 transient_t0Offset; /**< earliest start-time for transient window search, as offset in seconds from dataStartGPS */
292 UINT4 transient_t0Band; /**< Range of GPS start-times to search in transient search, in seconds */
293 INT4 transient_dt0; /**< Step-size for search/marginalization over transient-window start-time, in seconds */
294 UINT4 transient_tau; /**< smallest transient window length for marginalization, in seconds */
295 UINT4 transient_tauBand; /**< Range of transient-window timescales to search, in seconds */
296 INT4 transient_dtau; /**< Step-size for search/marginalization over transient-window timescale, in seconds */
297 BOOLEAN transient_useFReg; /**< FALSE: use 'standard' e^F for marginalization, TRUE: use e^FReg = (1/D)*e^F */
298
299 CHAR *outputTiming; /**< output timing measurements and parameters into this file [append!]*/
300 CHAR *outputFstatTiming; /**< output F-statistic timing measurements and parameters into this file [append!]*/
301
302 int FstatMethod; //!< select which method/algorithm to use to compute the F-statistic
303
304 BOOLEAN resampFFTPowerOf2; //!< in Resamp: enforce FFT length to be a power of two (by rounding up)
305 REAL8 allowedMismatchFromSFTLength; /**< maximum allowed mismatch from SFTs being too long */
306
307 LALStringVector *injectionSources; /**< Source parameters to inject: comma-separated list of file-patterns and/or direct config-strings ('{...}') */
308 LALStringVector *injectSqrtSX; /**< Add Gaussian noise: list of respective detectors' noise-floors sqrt{Sn}" */
309 LALStringVector *IFOs; /**< list of detector-names "H1,H2,L1,.." or single detector */
310 LALStringVector *timestampsFiles; /**< Names of numDet timestamps files */
311 REAL8 Tsft; /**< length of one SFT in seconds, used in combination with timestamps files (otherwise taken from SFT files) */
312 INT4 randSeed; /**< allow user to specify random-number seed for reproducible noise-realizations */
313
315
316/*---------- Global variables ----------*/
317extern int vrbflg; /**< defined in lal/lib/std/LALError.c */
318
319/* ---------- local prototypes ---------- */
320int main( int argc, char *argv[] );
321int initUserVars( UserInput_t *uvar );
322int InitFstat( ConfigVariables *cfg, const UserInput_t *uvar );
323void Freemem( ConfigVariables *cfg );
324
325int checkUserInputConsistency( const UserInput_t *uvar );
326int outputBeamTS( const CHAR *fname, const AMCoeffs *amcoe, const DetectorStateSeries *detStates );
328
329int write_FstatCandidate_to_fp( FILE *fp, const FstatCandidate *thisFCand, const BOOLEAN output_stats, const BOOLEAN output_orbit );
330int write_PulsarCandidate_to_fp( FILE *fp, const PulsarCandidate *pulsarParams, const FstatCandidate *Fcand );
331
332int compareFstatCandidates( const void *candA, const void *candB );
333int compareFstatCandidates_BSGL( const void *candA, const void *candB );
334
335int WriteFstatLog( const CHAR *log_fname, const CHAR *logstr );
337
338int write_TimingInfo( const CHAR *timingFile, const timingInfo_t *ti, const ConfigVariables *cfg );
339
340gsl_vector_int *resize_histogram( gsl_vector_int *old_hist, size_t size );
341
342/* ---------- scanline window functions ---------- */
344void XLALDestroyScanlineWindow( scanlineWindow_t *scanlineWindow );
345int XLALAdvanceScanlineWindow( const FstatCandidate *nextCand, scanlineWindow_t *scanWindow );
346BOOLEAN XLALCenterIsLocalMax( const scanlineWindow_t *scanWindow, const UINT4 sortingStatistic );
347
348/* ----- which timing function to use ----- */
349#define GETTIME XLALGetCPUTime
350
351/*----------------------------------------------------------------------*/
352/* Function definitions start here */
353/*----------------------------------------------------------------------*/
354
355/**
356 * MAIN function of ComputeFstatistic code.
357 * Calculate the F-statistic over a given portion of the parameter-space
358 * and write a list of 'candidates' into a file(default: 'Fstats').
359 */
360int main( int argc, char *argv[] )
361{
362 FILE *fpFstat = NULL;
363 LALFILE *fpTransientStats = NULL, *fpTransientStatsAll = NULL;
364 REAL8 numTemplates, templateCounter;
365 time_t clock0;
367 FstatCandidate XLAL_INIT_DECL( loudestFCand );
368 FstatCandidate XLAL_INIT_DECL( thisFCand );
369 gsl_vector_int *Fstat_histogram = NULL;
370
373
374 vrbflg = 1; /* verbose error-messages */
375
376 /* set LAL error-handler */
378
379 /* register all user-variable */
381
383
384 /* do ALL cmdline and cfgfile handling */
385 BOOLEAN should_exit = 0;
387 if ( should_exit ) {
388 exit( 1 );
389 }
390
391 /* do some sanity checks on the user-input before we proceed */
393
394 /* Initialization the common variables of the code, */
395 /* like ephemeries data and template grids: */
397
398 /* ----- produce a log-string describing the specific run setup ----- */
399 BOOLEAN logstrVerbose = TRUE;
400 XLAL_CHECK_MAIN( ( GV.logstring = XLALGetLogString( &GV, logstrVerbose ) ) != NULL, XLAL_EFUNC );
402
403 /* keep a log-file recording all relevant parameters of this search-run */
404 if ( uvar.outputLogfile ) {
405 XLAL_CHECK_MAIN( WriteFstatLog( uvar.outputLogfile, GV.logstring ) == XLAL_SUCCESS, XLAL_EFUNC );
406 }
407
408 /* count number of binary orbit parameters (done early to be able to prepare output file headers) */
409 const UINT4 n_orbitasini = 1 + ( XLALUserVarWasSet( &uvar.dorbitasini ) ? ( UINT4 ) floor( uvar.orbitasiniBand / uvar.dorbitasini ) : 0 );
410 const UINT4 n_orbitPeriod = 1 + ( XLALUserVarWasSet( &uvar.dorbitPeriod ) ? ( UINT4 ) floor( uvar.orbitPeriodBand / uvar.dorbitPeriod ) : 0 );
411 const UINT4 n_orbitTp = 1 + ( XLALUserVarWasSet( &uvar.dorbitTp ) ? ( UINT4 ) floor( uvar.orbitTpBand / uvar.dorbitTp ) : 0 );
412 const UINT4 n_orbitArgp = 1 + ( XLALUserVarWasSet( &uvar.dorbitArgp ) ? ( UINT4 ) floor( uvar.orbitArgpBand / uvar.dorbitArgp ) : 0 );
413 const UINT4 n_orbitEcc = 1 + ( XLALUserVarWasSet( &uvar.dorbitEcc ) ? ( UINT4 ) floor( uvar.orbitEccBand / uvar.dorbitEcc ) : 0 );
414 const UINT4 n_orbit = n_orbitasini * n_orbitPeriod * n_orbitTp * n_orbitArgp * n_orbitEcc;
415
416 /* if a complete output of the F-statistic results, or a grid output file, was requested,
417 * we open and prepare the output-file here */
418 if ( ( uvar.outputFstat && GV.runSearch ) || uvar.outputGrid ) {
419 if ( uvar.outputGrid ) {
420 XLAL_CHECK_MAIN( ( fpFstat = fopen( uvar.outputGrid, "wb" ) ) != NULL, XLAL_ESYS, "\nError opening file '%s' for writing..\n\n", uvar.outputGrid );
421 } else {
422 XLAL_CHECK_MAIN( ( fpFstat = fopen( uvar.outputFstat, "wb" ) ) != NULL, XLAL_ESYS, "\nError opening file '%s' for writing..\n\n", uvar.outputFstat );
423 }
424 fprintf( fpFstat, "%s", GV.logstring );
425
426 /* assemble column headings string */
427 char column_headings_string[1024];
428 XLAL_INIT_MEM( column_headings_string );
429 strcat( column_headings_string, "freq alpha delta f1dot f2dot f3dot" );
430 if ( !uvar.outputGrid ) {
431 strcat( column_headings_string, " 2F" );
432 if ( uvar.computeBSGL ) {
433 strcat( column_headings_string, " log10BSGL" );
434 }
435 if ( uvar.outputSingleFstats || uvar.computeBSGL ) {
437 for ( UINT4 X = 0; X < numDetectors ; X ++ ) {
438 char headingX[7];
439 snprintf( headingX, sizeof( headingX ), " 2F_%s", GV.detectorIDs->data[X] );
440 strcat( column_headings_string, headingX );
441 } /* for X < numDet */
442 }
443 }
444 if ( n_orbit > 1 ) {
445 strcat( column_headings_string, " asini period tp argp ecc" );
446 }
447 fprintf( fpFstat, "%%%% columns:\n%%%% %s\n", column_headings_string );
448
449 } /* if ( ( uvar.outputFstat && GV.runSearch ) || uvar.outputGrid ) */
450
451 /* count number of templates */
452 numTemplates = XLALNumDopplerTemplates( GV.scanState );
453 numTemplates *= n_orbit;
454 if ( uvar.countTemplates ) {
455 printf( "%%%% Number of templates: %0.0f\n", numTemplates );
456 }
457
458 if ( uvar.outputGrid ) { /* alternative to main search loop: loop through the same grid but only write out the parameters, no F-stats */
459 while ( XLALNextDopplerPos( &dopplerpos, GV.scanState ) == 0 ) {
460 for ( UINT4 i_orbitasini = 0; i_orbitasini < n_orbitasini; ++i_orbitasini ) {
461 for ( UINT4 i_orbitPeriod = 0; i_orbitPeriod < n_orbitPeriod; ++i_orbitPeriod ) {
462 for ( UINT4 i_orbitTp = 0; i_orbitTp < n_orbitTp; ++i_orbitTp ) {
463 for ( UINT4 i_orbitArgp = 0; i_orbitArgp < n_orbitArgp; ++i_orbitArgp ) {
464 for ( UINT4 i_orbitEcc = 0; i_orbitEcc < n_orbitEcc; ++i_orbitEcc ) {
465 dopplerpos.asini = uvar.orbitasini + i_orbitasini * uvar.dorbitasini;
466 dopplerpos.period = uvar.orbitPeriod + i_orbitPeriod * uvar.dorbitPeriod;
467 dopplerpos.tp = uvar.orbitTp;
468 XLALGPSAdd( &dopplerpos.tp, i_orbitTp * uvar.dorbitTp );
469 dopplerpos.argp = uvar.orbitArgp + i_orbitArgp * uvar.dorbitArgp;
470 dopplerpos.ecc = uvar.orbitEcc + i_orbitEcc * uvar.dorbitEcc;
471 for ( UINT4 iFreq = 0; iFreq < GV.numFreqBins_FBand; iFreq ++ ) {
472 /* collect data on current 'Fstat-candidate' */
473 thisFCand.doppler = dopplerpos; // use 'original' dopplerpos @ refTime !
474 thisFCand.doppler.fkdot[0] += iFreq * GV.dFreq; // this only does something for the resampling post-loop over frequency-bins, 0 otherwise ...
475 if ( fpFstat ) { /* no search, no toplist: write out grid point immediately */
476 if ( write_FstatCandidate_to_fp( fpFstat, &thisFCand, 0, n_orbit > 1 ) != 0 ) {
477 LogPrintf( LOG_CRITICAL, "Failed to write candidate to file.\n" );
478 return -1;
479 }
480 }
481 }
482 }
483 }
484 }
485 }
486 }
487 } /* while more Doppler positions to scan */
488 } /* if ( uvar.outputGrid ) */
489
490 if ( uvar.outputTransientStats && GV.runSearch ) {
491 XLAL_CHECK_MAIN( ( fpTransientStats = XLALFileOpen( uvar.outputTransientStats, "wb" ) ) != NULL, XLAL_ESYS, "\nError opening file '%s' for writing..\n\n", uvar.outputTransientStats );
492 XLALFilePrintf( fpTransientStats, "%s", GV.logstring ); /* write search log comment */
493 XLAL_CHECK_MAIN( write_transientCandidate_to_fp( fpTransientStats, NULL, 's' ) == XLAL_SUCCESS, XLAL_EFUNC ); /* write header-line comment */
494 }
495
496 if ( uvar.outputTransientStatsAll && GV.runSearch ) {
497 XLAL_CHECK_MAIN( ( fpTransientStatsAll = XLALFileOpen( uvar.outputTransientStatsAll, "wb" ) ) != NULL, XLAL_ESYS, "\nError opening file '%s' for writing..\n\n", uvar.outputTransientStatsAll );
498 XLALFilePrintf( fpTransientStatsAll, "%s", GV.logstring ); /* write search log comment */
499 XLAL_CHECK_MAIN( write_transientCandidateAll_to_fp( fpTransientStatsAll, NULL ) == XLAL_SUCCESS, XLAL_EFUNC ); /* write header-line comment */
500 }
501
502 /* start Fstatistic histogram with a single empty bin */
503 if ( uvar.outputFstatHist && GV.runSearch ) {
504 XLAL_CHECK_MAIN( ( Fstat_histogram = gsl_vector_int_alloc( 1 ) ) != NULL, XLAL_ENOMEM );
505 gsl_vector_int_set_zero( Fstat_histogram );
506 }
507
508 /*----------------------------------------------------------------------
509 * main loop: demodulate data for each point in the sky-position grid
510 * and for each value of the frequency-spindown
511 */
512 templateCounter = 0.0;
513 clock0 = GETTIME();
514
515 // ----- prepare timing info
516 REAL8 tic0, tic, toc, timeOfLastProgressUpdate = 0; // high-precision timing counters
517 timingInfo_t XLAL_INIT_DECL( timing ); // timings of Fstatistic computation, transient Fstat-map, transient Bayes factor
518
519 // pointer to Fstat results structure, will be allocated by XLALComputeFstat()
520 FstatResults *Fstat_res = NULL;
521
522 while ( GV.runSearch && ( XLALNextDopplerPos( &dopplerpos, GV.scanState ) == 0 ) ) {
523
524 for ( UINT4 i_orbitasini = 0; i_orbitasini < n_orbitasini; ++i_orbitasini ) {
525 for ( UINT4 i_orbitPeriod = 0; i_orbitPeriod < n_orbitPeriod; ++i_orbitPeriod ) {
526 for ( UINT4 i_orbitTp = 0; i_orbitTp < n_orbitTp; ++i_orbitTp ) {
527 for ( UINT4 i_orbitArgp = 0; i_orbitArgp < n_orbitArgp; ++i_orbitArgp ) {
528 for ( UINT4 i_orbitEcc = 0; i_orbitEcc < n_orbitEcc; ++i_orbitEcc ) {
529
530 dopplerpos.asini = uvar.orbitasini + i_orbitasini * uvar.dorbitasini;
531 dopplerpos.period = uvar.orbitPeriod + i_orbitPeriod * uvar.dorbitPeriod;
532 dopplerpos.tp = uvar.orbitTp;
533 XLALGPSAdd( &dopplerpos.tp, i_orbitTp * uvar.dorbitTp );
534 dopplerpos.argp = uvar.orbitArgp + i_orbitArgp * uvar.dorbitArgp;
535 dopplerpos.ecc = uvar.orbitEcc + i_orbitEcc * uvar.dorbitEcc;
536
537 tic0 = tic = GETTIME();
538
539 /* main function call: compute F-statistic for this template */
541
542 toc = GETTIME();
543 timing.tauFstat += ( toc - tic ); // pure Fstat-calculation time
544
545 /* Progress meter */
546 templateCounter += 1.0;
547 if ( LogLevel() >= LOG_NORMAL && ( ( toc - timeOfLastProgressUpdate ) > uvar.timerCount ) ) {
548 REAL8 diffSec = GETTIME() - clock0 ; /* seconds since start of loop*/
549 REAL8 taup = diffSec / templateCounter ;
550 REAL8 timeLeft = ( numTemplates - templateCounter ) * taup;
551 LogPrintf( LOG_NORMAL, "Progress: %g/%g = %.2f %% done, Estimated time left: %.0f s\n",
552 templateCounter, numTemplates, templateCounter / numTemplates * 100.0, timeLeft );
553 timeOfLastProgressUpdate = toc;
554 }
555
556 // here we use Santiago's trick to hack the resampling Fstat(f) into the single-F rest of the
557 // main-loop: we simply loop the remaining body over all frequency-bins in the Fstat-vector,
558 // this way nothing needs to be changed! in the non-resampling case, this loop iterates only
559 // once, so nothing is changed ...
560 for ( UINT4 iFreq = 0; iFreq < GV.numFreqBins_FBand; iFreq ++ ) {
561
562 /* collect data on current 'Fstat-candidate' */
563 thisFCand.doppler = dopplerpos; // use 'original' dopplerpos @ refTime !
564 thisFCand.doppler.fkdot[0] += iFreq * GV.dFreq; // this only does something for the resampling post-loop over frequency-bins, 0 otherwise ...
565 thisFCand.twoF = Fstat_res->twoF[iFreq];
567 thisFCand.numDetectors = Fstat_res->numDetectors;
568 for ( UINT4 X = 0; X < thisFCand.numDetectors; ++X ) {
569 thisFCand.twoFX[X] = Fstat_res->twoFPerDet[X][iFreq];
570 }
571 } else {
572 thisFCand.numDetectors = 0;
573 }
574 if ( GV.Fstat_what & FSTATQ_FAFB ) {
575 thisFCand.FaFb_refTime = Fstat_res->refTimePhase; // 'internal' reference time, used only for global phase estimate
576 thisFCand.Fa = Fstat_res->Fa[iFreq];
577 thisFCand.Fb = Fstat_res->Fb[iFreq];
578 } else {
579 thisFCand.Fa = thisFCand.Fb = crect( LAL_NAN, LAL_NAN );
580 }
581 thisFCand.Mmunu = Fstat_res->Mmunu;
582 MultiFstatAtomVector *thisFAtoms = NULL;
584 thisFAtoms = Fstat_res->multiFatoms[iFreq];
585 }
586
587 /* sanity check on the result */
588 if ( !isfinite( thisFCand.twoF ) ) {
589 LogPrintf( LOG_CRITICAL, "non-finite 2F = %.16g, Fa=(%.16g,%.16g), Fb=(%.16g,%.16g)\n",
590 thisFCand.twoF, creal( thisFCand.Fa ), cimag( thisFCand.Fa ), creal( thisFCand.Fb ), cimag( thisFCand.Fb ) );
591 LogPrintf( LOG_CRITICAL, "[Alpha,Delta] = [%.16g,%.16g],\nfkdot=[%.16g,%.16g,%.16g,%16.g]\n",
592 thisFCand.doppler.Alpha, thisFCand.doppler.Delta,
593 thisFCand.doppler.fkdot[0], thisFCand.doppler.fkdot[1], thisFCand.doppler.fkdot[2], thisFCand.doppler.fkdot[3] );
594 if ( thisFCand.doppler.asini > 0 ) {
595 LogPrintf( LOG_CRITICAL, "tp = {%d s, %d ns}, argp = %f, asini = %f, ecc = %f, period = %f\n",
596 thisFCand.doppler.tp.gpsSeconds, thisFCand.doppler.tp.gpsNanoSeconds,
597 thisFCand.doppler.argp, thisFCand.doppler.asini,
598 thisFCand.doppler.ecc, thisFCand.doppler.period );
599 }
600 return -1;
601 }
602
603 if ( uvar.computeBSGL ) {
604 thisFCand.log10BSGL = XLALComputeBSGL( thisFCand.twoF, thisFCand.twoFX, GV.BSGLsetup );
605 XLAL_CHECK_MAIN( xlalErrno == 0, XLAL_EFUNC, "XLALComputeBSGL() failed with errno=%d\n", xlalErrno );
606 } else {
607 thisFCand.log10BSGL = LAL_NAN; /* in non-BSGL case, block field with NAN, needed for output checking in write_PulsarCandidate_to_fp() */
608 }
609
610 /* push new value onto scan-line buffer */
612
613 /* two types of threshold: fixed (TwoF- and/or BSGL-threshold) and dynamic (NumCandidatesToKeep) */
614 BOOLEAN is1DlocalMax = FALSE;
615 if ( XLALCenterIsLocalMax( GV.scanlineWindow, GV.RankingStatistic ) ) { /* must be 1D local maximum */
616 is1DlocalMax = TRUE;
617 }
618 BOOLEAN isOver2FThreshold = FALSE; /* will always be checked, so start at 'FALSE' */
619 if ( GV.scanlineWindow->center->twoF >= uvar.TwoFthreshold ) { /* fixed 2F threshold */
620 isOver2FThreshold = TRUE;
621 }
622 BOOLEAN isOverBSGLthreshold = TRUE; /* will not be checked in non-BSGL case, so start at 'TRUE' */
623 if ( uvar.computeBSGL && ( GV.scanlineWindow->center->log10BSGL < uvar.BSGLthreshold ) ) { /* fixed threshold on log10BSGL */
624 isOverBSGLthreshold = FALSE;
625 }
626 if ( is1DlocalMax && isOver2FThreshold && isOverBSGLthreshold ) {
628
629 /* insert this into toplist if requested */
630 if ( GV.FstatToplist ) { /* dynamic threshold */
631 if ( insert_into_toplist( GV.FstatToplist, ( void * )writeCand ) ) {
632 LogPrintf( LOG_DEBUG, "Added new candidate into toplist: 2F = %f", writeCand->twoF );
633 if ( uvar.computeBSGL ) {
634 LogPrintfVerbatim( LOG_DEBUG, ", 2F_H1 = %f, 2F_L1 = %f, log10BSGL = %f", writeCand->twoFX[0], writeCand->twoFX[1], writeCand->log10BSGL );
635 }
636 } else {
637 LogPrintf( LOG_DEBUG, "NOT added the candidate into toplist: 2F = %f", writeCand->twoF );
638 if ( uvar.computeBSGL ) {
639 LogPrintfVerbatim( LOG_DEBUG, ", 2F_H1 = %f, 2F_L1 = %f, log10BSGL = %f", writeCand->twoFX[0], writeCand->twoFX[1], writeCand->log10BSGL );
640 }
641 }
643 } else if ( fpFstat ) { /* no toplist :write out immediately */
644 if ( write_FstatCandidate_to_fp( fpFstat, writeCand, 1, n_orbit > 1 ) != 0 ) {
645 LogPrintf( LOG_CRITICAL, "Failed to write candidate to file.\n" );
646 return -1;
647 }
648 } /* if outputFstat */
649
650 } /* if candidate is local maximum and over threshold */
651
652 /* separately keep track of loudest candidate (for --outputLoudest) */
653 switch ( GV.RankingStatistic ) {
654 case RANKBY_2F:
655 if ( thisFCand.twoF > loudestFCand.twoF ) {
656 loudestFCand = thisFCand;
657 }
658 break;
659 case RANKBY_BSGL:
660 if ( thisFCand.log10BSGL > loudestFCand.log10BSGL ) {
661 loudestFCand = thisFCand;
662 }
663 break;
664 default:
665 XLAL_ERROR_MAIN( XLAL_EINVAL, "Invalid ranking statistic '%d', supported are 'F=0', and 'BSGL=2'\n", GV.RankingStatistic );
666 break;
667 }
668
669 /* add Fstatistic to histogram if needed */
670 if ( uvar.outputFstatHist ) {
671
672 /* compute bin */
673 const size_t bin = thisFCand.twoF / uvar.FstatHistBin;
674
675 /* resize histogram vector if needed */
676 if ( !Fstat_histogram || bin >= Fstat_histogram->size ) {
677 XLAL_CHECK_MAIN( ( Fstat_histogram = resize_histogram( Fstat_histogram, bin + 1 ) ) != NULL, XLAL_EFUNC, "\nCouldn't (re)allocate 'Fstat_histogram'\n" );
678 }
679
680 /* add to bin */
681 gsl_vector_int_set( Fstat_histogram, bin,
682 gsl_vector_int_get( Fstat_histogram, bin ) + 1 );
683
684 }
685
686
687 /* ----- output F-stat atoms into files: one file per Doppler-position ---------- */
688 /* F-stat 'atoms' = per-SFT components {a,b,Fa,Fb}_alpha) */
689 if ( uvar.outputFstatAtoms ) {
690 LALFILE *fpFstatAtoms = NULL;
691 CHAR *fnameAtoms = NULL;
692 CHAR *dopplerName;
693 UINT4 len;
694
695 XLAL_CHECK_MAIN( ( dopplerName = XLALPulsarDopplerParams2String( &dopplerpos ) ) != NULL, XLAL_EFUNC );
696 len = strlen( uvar.outputFstatAtoms ) + strlen( dopplerName ) + 10;
697 XLAL_CHECK_MAIN( ( fnameAtoms = LALMalloc( len ) ) != NULL, XLAL_ENOMEM, "Failed to LALMalloc(%d)\n", len );
698 sprintf( fnameAtoms, "%s_%s.dat", uvar.outputFstatAtoms, dopplerName );
699
700 XLAL_CHECK_MAIN( ( fpFstatAtoms = XLALFileOpen( fnameAtoms, "wb" ) ) != NULL, XLAL_ESYS, "Error opening file '%s' for writing..\n\n", fnameAtoms );
701 XLALFree( fnameAtoms );
702 XLALFree( dopplerName );
703
704 XLALFilePrintf( fpFstatAtoms, "%s", GV.logstring );
705
706 XLAL_CHECK_MAIN( write_MultiFstatAtoms_to_fp( fpFstatAtoms, thisFAtoms ) == XLAL_SUCCESS, XLAL_EFUNC );
707 XLALFileClose( fpFstatAtoms );
708
709 } /* if outputFstatAtoms */
710
711 /* ----- compute transient-CW statistics if their output was requested ----- */
712 if ( fpTransientStats || fpTransientStatsAll ) {
713 transientCandidate_t XLAL_INIT_DECL( transientCand );
714
715 /* compute Fstat map F_mn over {t0, tau} */
716 tic = GETTIME();
717 XLAL_CHECK_MAIN( ( transientCand.FstatMap = XLALComputeTransientFstatMap( thisFAtoms, GV.transientWindowRange, uvar.transient_useFReg ) ) != NULL, XLAL_EFUNC );
718 toc = GETTIME();
719 timing.tauTransFstatMap += ( toc - tic ); // time to compute transient Fstat-map
720
721 /* compute marginalized Bayes factor */
722 tic = GETTIME();
723 transientCand.logBstat = XLALComputeTransientBstat( GV.transientWindowRange, transientCand.FstatMap );
724 XLAL_CHECK_MAIN( xlalErrno == 0, XLAL_EFUNC, "XLALComputeTransientBstat() failed with xlalErrno = %d\n", xlalErrno );
725 toc = GETTIME();
726 timing.tauTransMarg += ( toc - tic );
727
728 /* ----- compute parameter posteriors for {t0, tau} */
729 pdf1D_t *pdf_t0 = NULL;
730 pdf1D_t *pdf_tau = NULL;
731
732 XLAL_CHECK_MAIN( ( pdf_t0 = XLALComputeTransientPosterior_t0( GV.transientWindowRange, transientCand.FstatMap ) ) != NULL, XLAL_EFUNC );
733 XLAL_CHECK_MAIN( ( pdf_tau = XLALComputeTransientPosterior_tau( GV.transientWindowRange, transientCand.FstatMap ) ) != NULL, XLAL_EFUNC );
734
735 if ( fpTransientStats ) {
736 /* get maximum-posterior estimate (MP) from the modes of these pdfs */
737 transientCand.t0_MP = XLALFindModeOfPDF1D( pdf_t0 );
738 XLAL_CHECK_MAIN( xlalErrno == 0, XLAL_EFUNC, "mode-estimation failed for pdf_t0. xlalErrno = %d\n", xlalErrno );
739 transientCand.tau_MP = XLALFindModeOfPDF1D( pdf_tau );
740 XLAL_CHECK_MAIN( xlalErrno == 0, XLAL_EFUNC, "mode-estimation failed for pdf_tau. xlalErrno = %d\n", xlalErrno );
741 }
742
743 /* record timing-relevant transient search params */
744 timing.tauMin = GV.transientWindowRange.tau;
745 timing.tauMax = timing.tauMin + GV.transientWindowRange.tauBand;
746 timing.NStart = transientCand.FstatMap->F_mn->size1;
747 timing.NTau = transientCand.FstatMap->F_mn->size2;
748
749 /* add meta-info on current transient-CW candidate */
750 transientCand.doppler = dopplerpos;
751 transientCand.windowRange = GV.transientWindowRange;
752
753 if ( fpTransientStats ) {
754 /* output everything into stats-file (one line per candidate) */
755 XLAL_CHECK_MAIN( write_transientCandidate_to_fp( fpTransientStats, &transientCand, 's' ) == XLAL_SUCCESS, XLAL_EFUNC );
756 }
757
758 if ( fpTransientStatsAll ) {
759 /* output everything into stats-file (one block for the whole (t0,tau) grid per candidate) */
760 XLAL_CHECK_MAIN( write_transientCandidateAll_to_fp( fpTransientStatsAll, &transientCand ) == XLAL_SUCCESS, XLAL_EFUNC );
761 }
762
763 /* free dynamically allocated F-stat map */
764 XLALDestroyTransientFstatMap( transientCand.FstatMap );
765 XLALDestroyPDF1D( pdf_t0 );
766 XLALDestroyPDF1D( pdf_tau );
767
768 } /* if ( fpTransientStats || fpTransientStatsAll ) */
769
770 } // for ( iFreq < numFreqBins_FBand )
771
772 /* now measure total loop time per template */
773 toc = GETTIME();
774 timing.tauTemplate += ( toc - tic0 );
775
776 }
777 }
778 }
779 }
780 }
781
782 } /* while more Doppler positions to scan */
783
784
785 /* if requested: output timings into timing-file */
786 if ( uvar.outputTiming && GV.runSearch ) {
787 REAL8 num_templates = numTemplates * GV.numFreqBins_FBand; // 'templates' now refers to number of 'frequency-bands' in resampling case
788
789 timing.NSFTs = GV.NSFTs;
790 if ( uvar.gridType == GRID_SPINDOWN_SQUARE || uvar.gridType == GRID_SPINDOWN_AGEBRK ) {
791 /* In this case, dFreq is not meaningful,
792 * but we can get the number of points from the lattice tiling code.
793 * The number of frequency points covered is dimension 2 of the lattice.
794 * (0 and 1 are sky locations which are not tiled.)
795 */
796 timing.NFreq = XLALNumDopplerPointsAtDimension( GV.scanState, 2 );
797 } else {
798 timing.NFreq = ( UINT4 )( 1 + floor( GV.searchRegion.fkdotBand[0] / GV.dFreq ) );
799 }
800
801 // compute averages:
802 timing.tauFstat /= num_templates;
803 timing.tauTemplate /= num_templates;
804 timing.tauF0 = timing.tauFstat / timing.NSFTs;
805 timing.tauTransFstatMap /= num_templates;
806 timing.tauTransMarg /= num_templates;
807
808 XLAL_CHECK_MAIN( write_TimingInfo( uvar.outputTiming, &timing, &GV ) == XLAL_SUCCESS, XLAL_EFUNC );
809
810 } /* if timing output requested */
811
812 /* if requested: output F-statistic timings into F-statistic-timing-file */
813 if ( uvar.outputFstatTiming && GV.runSearch ) {
814
815 FILE *fp;
816 if ( ( fp = fopen( uvar.outputFstatTiming, "rb" ) ) != NULL ) {
817 fclose( fp );
818 XLAL_CHECK( ( fp = fopen( uvar.outputFstatTiming, "ab" ) ), XLAL_ESYS, "Failed to open existing timing-file '%s' for appending\n", uvar.outputFstatTiming );
820 } else {
821 XLAL_CHECK( ( fp = fopen( uvar.outputFstatTiming, "wb" ) ), XLAL_ESYS, "Failed to open new timing-file '%s' for writing\n", uvar.outputFstatTiming );
823 }
824 fclose( fp );
825
826 } /* if timing output requested */
827
828 /* ----- if using toplist: sort and write it out to file now ----- */
829 if ( fpFstat && GV.FstatToplist && GV.runSearch ) {
830 UINT4 el;
831
832 /* sort toplist */
833 LogPrintf( LOG_NORMAL, "Sorting toplist ... " );
834 if ( GV.RankingStatistic == RANKBY_2F ) {
836 } else if ( GV.RankingStatistic == RANKBY_BSGL ) {
838 } else {
839 XLAL_ERROR( XLAL_EINVAL, "Ranking statistic '%d' undefined here, allowed are 'F=0' and 'BSGL=2'\n", GV.RankingStatistic );
840 }
841 LogPrintfVerbatim( LOG_NORMAL, "done.\n" );
842
843 for ( el = 0; el < GV.FstatToplist->elems; el ++ ) {
844 const FstatCandidate *candi;
845 if ( ( candi = ( const FstatCandidate * ) toplist_elem( GV.FstatToplist, el ) ) == NULL ) {
846 LogPrintf( LOG_CRITICAL, "Internal consistency problems with toplist: contains fewer elements than expected!\n" );
847 return -1;
848 }
849 if ( write_FstatCandidate_to_fp( fpFstat, candi, 1, n_orbit > 1 ) != 0 ) {
850 LogPrintf( LOG_CRITICAL, "Failed to write candidate to file.\n" );
851 return -1;
852 }
853 } /* for el < elems in toplist */
854
855 } /* if fpFstat && toplist */
856
857 if ( fpFstat ) {
858 fprintf( fpFstat, "%%DONE\n" );
859 fclose( fpFstat );
860 fpFstat = NULL;
861 }
862 XLALFileClose( fpTransientStats );
863 XLALFileClose( fpTransientStatsAll );
864
865 /* ----- estimate amplitude-parameters for the loudest canidate and output into separate file ----- */
866 if ( uvar.outputLoudest && GV.runSearch ) {
867 FILE *fpLoudest;
868 PulsarCandidate XLAL_INIT_DECL( pulsarParams );
869 pulsarParams.Doppler = loudestFCand.doppler;
870
871 XLAL_CHECK_MAIN( XLALEstimatePulsarAmplitudeParams( &pulsarParams, &loudestFCand.FaFb_refTime, loudestFCand.Fa, loudestFCand.Fb, &loudestFCand.Mmunu ) == XLAL_SUCCESS, XLAL_EFUNC );
872
873 XLAL_CHECK_MAIN( ( fpLoudest = fopen( uvar.outputLoudest, "wb" ) ) != NULL, XLAL_ESYS, "Error opening file '%s' for writing..\n\n", uvar.outputLoudest );
874
875 /* write header with run-info */
876 fprintf( fpLoudest, "%s", GV.logstring );
877
878 /* write this 'candidate' to disc */
879 XLAL_CHECK_MAIN( write_PulsarCandidate_to_fp( fpLoudest, &pulsarParams, &loudestFCand ) == XLAL_SUCCESS, XLAL_EFUNC );
880 fclose( fpLoudest );
881
882 gsl_matrix_free( pulsarParams.AmpFisherMatrix );
883
884 } /* write loudest candidate to file */
885
886 LogPrintf( LOG_NORMAL, "Search finished.\n" );
887
888 /* write out the Fstatistic histogram */
889 if ( uvar.outputFstatHist && GV.runSearch ) {
890
891 size_t i = 0;
892 FILE *fpFstatHist = fopen( uvar.outputFstatHist, "wb" );
893
894 XLAL_CHECK_MAIN( fpFstatHist != NULL, XLAL_ESYS, "\nError opening file '%s' for writing..\n\n", uvar.outputFstat );
895 fprintf( fpFstatHist, "%s", GV.logstring );
896
897 for ( i = 0; i < Fstat_histogram->size; ++i )
898 fprintf( fpFstatHist, "%0.3f %0.3f %i\n",
899 uvar.FstatHistBin * i,
900 uvar.FstatHistBin * ( i + 1 ),
901 gsl_vector_int_get( Fstat_histogram, i ) );
902
903 fprintf( fpFstatHist, "%%DONE\n" );
904 fclose( fpFstatHist );
905
906 }
907
908 /* Free memory */
910 XLALDestroyFstatResults( Fstat_res );
911
912 Freemem( &GV );
913
914 if ( Fstat_histogram ) {
915 gsl_vector_int_free( Fstat_histogram );
916 }
917
918 /* did we forget anything ? */
920
921 return 0;
922
923} /* main() */
924
925
926/**
927 * Register all our "user-variables" that can be specified from cmd-line and/or config-file.
928 * Here we set defaults for some user-variables and register them with the UserInput module.
929 */
930int
932{
933 XLAL_CHECK( uvar != NULL, XLAL_EINVAL );
934
935 /* set a few defaults */
936 uvar->FreqBand = 0.0;
937 uvar->Alpha = 0.0;
938 uvar->Delta = 0.0;
939 uvar->AlphaBand = 0;
940 uvar->DeltaBand = 0;
941 uvar->skyRegion = NULL;
942 uvar->Dterms = FstatOptionalArgsDefaults.Dterms;
943
944 uvar->ephemEarth = XLALStringDuplicate( "earth00-40-DE405.dat.gz" );
945 uvar->ephemSun = XLALStringDuplicate( "sun00-40-DE405.dat.gz" );
946
947 uvar->assumeSqrtSX = NULL;
948 uvar->UseNoiseWeights = TRUE;
949
950 /* default step-sizes for GRID_FLAT */
951 uvar->dAlpha = 0.001;
952 uvar->dDelta = 0.001;
953 uvar->dFreq = 0.0; /* zero indicates 'not set by user==> i.e. use canonical default */
954 uvar->df1dot = 0.0;
955 uvar->df2dot = 0.0;
956 uvar->df3dot = 0.0;
957
958 /* define default orbital semi-major axis */
959 uvar->orbitasini = 0 /* isolated pulsar */;
960
961 uvar->TwoFthreshold = 0.0;
962 uvar->NumCandidatesToKeep = 0;
963 uvar->FracCandidatesToKeep = 0.0;
964 uvar->clusterOnScanline = 0;
965
966 uvar->metricType = LAL_PMETRIC_NONE;
967 uvar->projectMetric = TRUE;
968 uvar->gridType = GRID_FLAT;
969
970 uvar->metricMismatch = 0.02;
971
972 uvar->outputLogfile = NULL;
973 uvar->outputFstat = NULL;
974 uvar->outputLoudest = NULL;
975
976 uvar->outputFstatHist = NULL;
977 uvar->FstatHistBin = 0.1;
978
979 uvar->countTemplates = FALSE;
980
981 uvar->gridFile = NULL;
982
984
985 uvar->SSBprecision = FstatOptionalArgsDefaults.SSBprec;
986
987 uvar->minStartTime.gpsSeconds = 0;
988 uvar->maxStartTime.gpsSeconds = LAL_INT4_MAX;
989
990 uvar->workingDir = XLALStringDuplicate( "." );
991
992 uvar->timerCount = 10; /* output a timer/progress count every N seconds */
993
994 uvar->strictSpindownBounds = FALSE;
995
996 uvar->spindownAge = 0.0;
997 uvar->minBraking = 0.0;
998 uvar->maxBraking = 0.0;
999
1000 uvar->FstatMethod = FstatOptionalArgsDefaults.FstatMethod;
1001
1002 uvar->outputSingleFstats = FALSE;
1003 uvar->RankingStatistic = XLALStringDuplicate( "F" );
1004
1005 uvar->computeBSGL = FALSE;
1006 uvar->BSGLlogcorr = TRUE;
1007 uvar->Fstar0 = 0.0;
1008 uvar->oLGX = NULL; /* NULL is intepreted as oLGX[X] = 1.0/Ndet for all X */
1009 uvar->BSGLthreshold = - LAL_REAL8_MAX;
1010
1011 uvar->transient_WindowType = XLALStringDuplicate( "none" );
1012 uvar->transient_useFReg = 0;
1013 uvar->resampFFTPowerOf2 = FstatOptionalArgsDefaults.resampFFTPowerOf2;
1014 uvar->allowedMismatchFromSFTLength = 0;
1015 uvar->injectionSources = NULL;
1016 uvar->injectSqrtSX = NULL;
1017 uvar->IFOs = NULL;
1018 uvar->timestampsFiles = NULL;
1019
1020 uvar->Tsft = 1800.0;
1021
1022 /* ---------- register all user-variables ---------- */
1023 XLALRegisterUvarMember( Alpha, RAJ, 'a', OPTIONAL, "Sky: equatorial J2000 right ascension (in radians or hours:minutes:seconds)" );
1024 XLALRegisterUvarMember( Delta, DECJ, 'd', OPTIONAL, "Sky: equatorial J2000 declination (in radians or degrees:minutes:seconds)" );
1025 XLALRegisterUvarMember( skyRegion, STRING, 'R', OPTIONAL, "ALTERNATIVE: Sky-region polygon '(Alpha1,Delta1),(Alpha2,Delta2),...' or 'allsky'" );
1026
1027 XLALRegisterUvarMember( Freq, REAL8, 'f', OPTIONAL, "Starting search frequency Freq in Hz" );
1028 XLALRegisterUvarMember( f1dot, REAL8, 's', OPTIONAL, "First spindown parameter f1dot = dFreq/dt" );
1029 XLALRegisterUvarMember( f2dot, REAL8, 0, OPTIONAL, "Second spindown parameter f2dot = d^2Freq/dt^2" );
1030 XLALRegisterUvarMember( f3dot, REAL8, 0, OPTIONAL, "Third spindown parameter f3dot = d^3Freq/dt^3" );
1031
1032 XLALRegisterUvarMember( AlphaBand, RAJ, 'z', OPTIONAL, "Sky: search band from Alpha to Alpha+AlphaBand (in radians or h:m:s)" );
1033 XLALRegisterUvarMember( DeltaBand, DECJ, 'c', OPTIONAL, "Sky: search band from Delta to Delta+DeltaBand (in radians or d:m:s)" );
1034 XLALRegisterUvarMember( FreqBand, REAL8, 'b', OPTIONAL, "Search band in frequency in Hz" );
1035 XLALRegisterUvarMember( f1dotBand, REAL8, 'm', OPTIONAL, "Search band in f1dot in Hz/s" );
1036 XLALRegisterUvarMember( f2dotBand, REAL8, 0, OPTIONAL, "Search band in f2dot in Hz/s^2" );
1037 XLALRegisterUvarMember( f3dotBand, REAL8, 0, OPTIONAL, "Search band in f3dot in Hz/s^3" );
1038
1039 XLALRegisterUvarMember( dAlpha, RAJ, 'l', OPTIONAL, "Sky: stepsize in Alpha (in radians or h:m:s)" );
1040 XLALRegisterUvarMember( dDelta, DECJ, 'g', OPTIONAL, "Sky: stepsize in Delta (in radians or d:m:s)" );
1041 XLALRegisterUvarMember( dFreq, REAL8, 'r', OPTIONAL, "Stepsize for frequency in Hz" );
1042 XLALRegisterUvarMember( df1dot, REAL8, 'e', OPTIONAL, "Stepsize for f1dot in Hz/s" );
1043 XLALRegisterUvarMember( df2dot, REAL8, 0, OPTIONAL, "Stepsize for f2dot in Hz/s^2" );
1044 XLALRegisterUvarMember( df3dot, REAL8, 0, OPTIONAL, "Stepsize for f3dot in Hz/s^3" );
1045
1046 XLALRegisterUvarMember( orbitasini, REAL8, 0, OPTIONAL, "Binary Orbit: Projected semi-major axis in light-seconds [Default: 0.0]" );
1047 XLALRegisterUvarMember( orbitPeriod, REAL8, 0, OPTIONAL, "Binary Orbit: Period in seconds" );
1048 XLALRegisterUvarMember( orbitTp, EPOCH, 0, OPTIONAL, "Binary Orbit: (true) epoch of periapsis: use 'xx.yy[GPS|MJD]' format." );
1049 XLALRegisterUvarMember( orbitArgp, REAL8, 0, OPTIONAL, "Binary Orbit: Orbital argument of periapse in radians" );
1050 XLALRegisterUvarMember( orbitEcc, REAL8, 0, OPTIONAL, "Binary Orbit: Orbital eccentricity" );
1051
1052 XLALRegisterUvarMember( orbitasiniBand, REAL8, 0, OPTIONAL, "Binary Orbit: Band in Projected semi-major axis in light-seconds [Default: 0.0]" );
1053 XLALRegisterUvarMember( orbitPeriodBand, REAL8, 0, OPTIONAL, "Binary Orbit: Band in Period in seconds" );
1054 XLALRegisterUvarMember( orbitTpBand, REAL8, 0, OPTIONAL, "Binary Orbit: Band in (true) epoch of periapsis: use 'xx.yy[GPS|MJD]' format." );
1055 XLALRegisterUvarMember( orbitArgpBand, REAL8, 0, OPTIONAL, "Binary Orbit: Band in Orbital argument of periapse in radians" );
1056 XLALRegisterUvarMember( orbitEccBand, REAL8, 0, OPTIONAL, "Binary Orbit: Band in Orbital eccentricity" );
1057
1058 XLALRegisterUvarMember( dorbitasini, REAL8, 0, OPTIONAL, "Binary Orbit: Spacing in Projected semi-major axis in light-seconds [Default: 0.0]" );
1059 XLALRegisterUvarMember( dorbitPeriod, REAL8, 0, OPTIONAL, "Binary Orbit: Spacing in Period in seconds" );
1060 XLALRegisterUvarMember( dorbitTp, REAL8, 0, OPTIONAL, "Binary Orbit: Spacing in (true) epoch of periapsis: use 'xx.yy[GPS|MJD]' format." );
1061 XLALRegisterUvarMember( dorbitArgp, REAL8, 0, OPTIONAL, "Binary Orbit: Spacing in Orbital argument of periapse in radians" );
1062 XLALRegisterUvarMember( dorbitEcc, REAL8, 0, OPTIONAL, "Binary Orbit: Spacing in Orbital eccentricity" );
1063
1064 XLALRegisterUvarMember( DataFiles, STRING, 'D', OPTIONAL, "File-pattern specifying (also multi-IFO) input SFT-files. Possibilities are:\n"
1065 " - '<SFT file>;<SFT file>;...', where <SFT file> may contain wildcards\n - 'list:<file containing list of SFT files>'" );
1066
1067 XLALRegisterUvarMember( assumeSqrtSX, STRINGVector, 0, OPTIONAL, "Don't estimate noise-floors but assume (stationary) per-IFO sqrt{SX} (if single value: use for all IFOs).\nNote that, unlike the historic --SignalOnly flag, this option will not lead to explicitly adding a +4 'correction' for noiseless SFTs to the output F-statistic." );
1068
1069 XLALRegisterUvarMember( TwoFthreshold, REAL8, 'F', OPTIONAL, "Set the threshold for selection of 2F" );
1070 XLALRegisterUvarMember( gridType, INT4, 0, OPTIONAL, "Grid: 0=flat, 1=isotropic, 2=metric, 3=skygrid-file, 6=grid-file, 8=spin-square, 9=spin-age-brk" );
1071 XLALRegisterUvarMember( metricType, INT4, 'M', OPTIONAL, "Metric: 0=none,1=Ptole-analytic,2=Ptole-numeric, 3=exact" );
1072 XLALRegisterUvarMember( metricMismatch, REAL8, 'X', OPTIONAL, "Maximal allowed mismatch for metric tiling" );
1073 XLALRegisterUvarMember( outputLogfile, STRING, 0, OPTIONAL, "Name of log-file identifying the code + search performed" );
1074 XLALRegisterUvarMember( gridFile, STRING, 0, OPTIONAL, "Load grid from this file: sky-grid or full-grid depending on --gridType." );
1075 XLALRegisterUvarMember( refTime, EPOCH, 0, OPTIONAL, "Reference SSB epoch for pulsar-parameters: use 'xx.yy[GPS|MJD]' format [Default: startTime]" );
1076
1077 XLALRegisterUvarMember( outputFstat, STRING, 0, OPTIONAL, "Output-file for F-statistic field over the parameter-space" );
1078 XLALRegisterUvarMember( outputLoudest, STRING, 0, OPTIONAL, "Loudest F-statistic candidate + estimated MLE amplitudes" );
1079
1080 XLALRegisterUvarMember( outputFstatHist, STRING, 0, OPTIONAL, "Output-file for a discrete histogram of all Fstatistic values" );
1081 XLALRegisterUvarMember( FstatHistBin, REAL8, 0, OPTIONAL, "Width of an Fstatistic histogram bin" );
1082
1083 XLALRegisterUvarMember( NumCandidatesToKeep, INT4, 0, OPTIONAL, "Number of Fstat 'candidates' to keep. (0 = All)" );
1084 XLALRegisterUvarMember( FracCandidatesToKeep, REAL8, 0, OPTIONAL, "Fraction of Fstat 'candidates' to keep." );
1085 XLALRegisterUvarMember( clusterOnScanline, INT4, 0, OPTIONAL, "Neighbors on each side for finding 1D local maxima on scanline" );
1086
1087 XLALRegisterUvarMember( minStartTime, EPOCH, 0, OPTIONAL, "Only use SFTs with timestamps starting from (including) this epoch (format 'xx.yy[GPS|MJD]') " );
1088 XLALRegisterUvarMember( maxStartTime, EPOCH, 0, OPTIONAL, "Only use SFTs with timestamps up to (excluding) this epoch (format 'xx.yy[GPS|MJD]')" );
1089
1090 XLALRegisterUvarMember( outputFstatAtoms, STRING, 0, OPTIONAL, "Output filename *base* for F-statistic 'atoms' {a,b,Fa,Fb}_alpha. One file per doppler-point." );
1091 XLALRegisterUvarMember( outputSingleFstats, BOOLEAN, 0, OPTIONAL, "In multi-detector case, also output single-detector F-stats?" );
1092 XLALRegisterUvarMember( RankingStatistic, STRING, 0, DEVELOPER, "Rank toplist candidates according to 'F' or 'BSGL' statistic" );
1093
1094 // ----- Line robust stats parameters ----------
1095 XLALRegisterUvarMember( computeBSGL, BOOLEAN, 0, OPTIONAL, "Compute and output line-robust statistic BSGL " );
1096 XLALRegisterUvarMember( Fstar0, REAL8, 0, OPTIONAL, "BSGL: transition-scale parameter 'Fstar0'" );
1097 XLALRegisterUvarMember( oLGX, STRINGVector, 0, OPTIONAL, "BSGL: prior per-detector line-vs-Gauss odds 'oLGX' (Defaults to oLGX=1/Ndet)" );
1098 XLALRegisterUvarMember( BSGLlogcorr, BOOLEAN, 0, DEVELOPER, "BSGL: include log-correction terms (slower) or not (faster)" );
1099 XLALRegisterUvarMember( BSGLthreshold, REAL8, 0, OPTIONAL, "BSGL threshold for candidate output" );
1100 // --------------------------------------------
1101
1102 XLALRegisterUvarMember( outputTransientStats, STRING, 0, OPTIONAL, "TransientCW: Output filename for transient-CW statistics." );
1103 XLALRegisterUvarMember( outputTransientStatsAll, STRING, 0, DEVELOPER, "TransientCW: Output filename for transient-CW statistics -- including the whole (t0,tau) grid for each candidate -- WARNING: CAN BE HUGE!." );
1104 XLALRegisterUvarMember( transient_WindowType, STRING, 0, OPTIONAL, "TransientCW: Type of transient signal window to use. ('none', 'rect', 'exp')." );
1105 XLALRegisterUvarMember( transient_t0Epoch, EPOCH, 0, OPTIONAL, "TransientCW: Earliest start-time for transient window search, in seconds (format 'xx.yy[GPS|MJD]')" );
1106 XLALRegisterUvarMember( transient_t0Offset, UINT4, 0, OPTIONAL, "TransientCW: Earliest start-time for transient window search, as offset in seconds from dataStartGPS" );
1107 XLALRegisterUvarMember( transient_t0Band, UINT4, 0, OPTIONAL, "TransientCW: Range of GPS start-times to search in transient search, in seconds" );
1108 XLALRegisterUvarMember( transient_dt0, INT4, 0, OPTIONAL, "TransientCW: Step-size in transient-CW start-time in seconds [Default:Tsft]" );
1109 XLALRegisterUvarMember( transient_tau, UINT4, 0, OPTIONAL, "TransientCW: Minimal transient-CW duration timescale, in seconds" );
1110 XLALRegisterUvarMember( transient_tauBand, UINT4, 0, OPTIONAL, "TransientCW: Range of transient-CW duration timescales to search, in seconds" );
1111 XLALRegisterUvarMember( transient_dtau, INT4, 0, OPTIONAL, "TransientCW: Step-size in transient-CW duration timescale, in seconds [Default:Tsft]" );
1112
1113 XLALRegisterUvarAuxDataMember( FstatMethod, UserEnum, XLALFstatMethodChoices(), 0, OPTIONAL, "F-statistic method to use" );
1114
1115 XLALRegisterUvarMember( countTemplates, BOOLEAN, 0, OPTIONAL, "Count number of templates (if supported) instead of search" );
1116 XLALRegisterUvarMember( outputGrid, STRING, 0, OPTIONAL, "Output-file for parameter-space grid (without running a search!)" );
1117
1118 /* ----- more experimental/expert options ----- */
1119 XLALRegisterUvarMember( UseNoiseWeights, BOOLEAN, 'W', DEVELOPER, "Use per-SFT noise weights" );
1120 XLALRegisterUvarMember( ephemEarth, STRING, 0, DEVELOPER, "Earth ephemeris file to use" );
1121 XLALRegisterUvarMember( ephemSun, STRING, 0, DEVELOPER, "Sun ephemeris file to use" );
1122
1123 XLALRegisterUvarAuxDataMember( SSBprecision, UserEnum, &SSBprecisionChoices, 0, DEVELOPER, "Precision to use for time-transformation to SSB" );
1124
1125 XLALRegisterUvarMember( RngMedWindow, INT4, 'k', DEVELOPER, "Running-Median window size" );
1126 XLALRegisterUvarMember( Dterms, INT4, 't', DEVELOPER, "Number of kernel terms (single-sided) to use in\na) Dirichlet kernel if FstatMethod=Demod*\nb) sinc-interpolation kernel if FstatMethod=Resamp*" );
1127
1128 XLALRegisterUvarMember( workingDir, STRING, 'w', DEVELOPER, "Directory to use as work directory." );
1129 XLALRegisterUvarMember( timerCount, REAL8, 0, DEVELOPER, "N: Output progress/timer info every N seconds" );
1130
1131 XLALRegisterUvarMember( projectMetric, BOOLEAN, 0, DEVELOPER, "Use projected metric on Freq=const subspact" );
1132
1133 XLALRegisterUvarMember( strictSpindownBounds, BOOLEAN, 0, DEVELOPER, "suppress spindown grid points outside the [fkdot,fkdotBand] ranges? (only supported for --gridType=8)" );
1134
1135 XLALRegisterUvarMember( spindownAge, REAL8, 0, DEVELOPER, "Spindown age for --gridType=9" );
1136 XLALRegisterUvarMember( minBraking, REAL8, 0, DEVELOPER, "Minimum braking index for --gridType=9" );
1137 XLALRegisterUvarMember( maxBraking, REAL8, 0, DEVELOPER, "Maximum braking index for --gridType=9" );
1138
1139 XLALRegisterUvarMember( transient_useFReg, BOOLEAN, 0, DEVELOPER, "FALSE: use 'standard' e^F for marginalization, if TRUE: use e^FReg = (1/D)*e^F (BAD)" );
1140
1141 XLALRegisterUvarMember( outputTiming, STRING, 0, DEVELOPER, "Append timing measurements and parameters into this file" );
1142 XLALRegisterUvarMember( outputFstatTiming, STRING, 0, DEVELOPER, "Append F-statistic timing measurements and parameters into this file" );
1143
1144 XLALRegisterUvarMember( resampFFTPowerOf2, BOOLEAN, 0, DEVELOPER, "For Resampling methods: enforce FFT length to be a power of two (by rounding up)" );
1145
1146 XLALRegisterUvarMember( allowedMismatchFromSFTLength, REAL8, 0, DEVELOPER, "Maximum allowed mismatch from SFTs being too long [Default: what's hardcoded in XLALFstatMaximumSFTLength]" );
1147
1148 /* inject signals into the data being analyzed */
1149 XLALRegisterUvarMember( injectionSources, STRINGVector, 0, DEVELOPER, "%s", InjectionSourcesHelpString );
1150 XLALRegisterUvarMember( injectSqrtSX, STRINGVector, 0, DEVELOPER, "Generate Gaussian Noise SFTs on-the-fly: CSV list of detectors' noise-floors sqrt{Sn}" );
1151 XLALRegisterUvarMember( IFOs, STRINGVector, 0, DEVELOPER, "CSV list of detectors, eg. \"H1,H2,L1,G1, ...\", when no SFT files are specified" );
1152 XLALRegisterUvarMember( timestampsFiles, STRINGVector, 0, DEVELOPER,
1153 "Files containing timestamps for the generated SFTs when using "UVAR_STR( injectSqrtSX ) ". "
1154 "Arguments correspond to the detectors given by " UVAR_STR( IFOs )
1155 "; for example, if " UVAR_STR( IFOs ) " is set to 'H1,L1', then an argument of "
1156 "'t1.txt,t2.txt' to this option will read H1 timestamps from the file 't1.txt', and L1 timestamps from the file 't2.txt'. "
1157 "The timebase of the generated SFTs is specified by " UVAR_STR( Tsft ) ". "
1158 );
1159 XLALRegisterUvarMember( Tsft, REAL8, 0, DEVELOPER, "Generate SFTs with this timebase (in seconds) instead of loading from files. Requires --injectSqrtSX, --IFOs, --timestampsFiles" );
1160 XLALRegisterUvarMember( randSeed, INT4, 0, DEVELOPER, "Specify random-number seed for reproducible noise (0 means use /dev/urandom for seeding)." );
1161
1162 return XLAL_SUCCESS;
1163
1164} /* initUserVars() */
1165
1166/** Initialized Fstat-code: handle user-input and set everything up.
1167 * NOTE: the logical *order* of things in here is very important, so be careful
1168 */
1169int
1171{
1172 XLAL_CHECK( ( cfg != NULL ) && ( uvar != NULL ), XLAL_EINVAL );
1173
1174 REAL8 fCoverMin, fCoverMax; /* covering frequency-band to read from SFTs */
1175 SFTCatalog *catalog = NULL;
1176 SFTConstraints XLAL_INIT_DECL( constraints );
1177 LIGOTimeGPS endTime;
1178 size_t toplist_length = uvar->NumCandidatesToKeep;
1179
1180 /* check compatibility of some output options */
1181 cfg->runSearch = !( uvar->countTemplates || uvar->outputGrid );
1182 XLAL_CHECK( cfg->runSearch || !( uvar->outputFstat || uvar->outputFstatAtoms || uvar->outputFstatHist || uvar->outputFstatTiming || uvar->outputLoudest || uvar->outputTransientStats || uvar->outputTransientStatsAll ), XLAL_EINVAL, "Invalid input: --countTemplates or --outputGrid means that no search is actually run, so we can't do any of --outputFstat --outputFstatAtoms --outputFstatHist --outputFstatTiming --outputLoudest --outputTransientStats --outputTransientStatsAll" );
1183
1184 /* set the current working directory */
1185 XLAL_CHECK( chdir( uvar->workingDir ) == 0, XLAL_EINVAL, "Unable to change directory to workinDir '%s'\n", uvar->workingDir );
1186
1187 /* ----- set computational parameters for F-statistic from User-input ----- */
1188 cfg->useResamp = ( uvar->FstatMethod >= FMETHOD_RESAMP_GENERIC ); // use resampling;
1189
1190 /* check that resampling is compatible with gridType */
1191 if ( cfg->useResamp && uvar->gridType > GRID_SKY_LAST /* end-marker for factored grid types */ ) {
1192 XLAL_ERROR( XLAL_EINVAL, "\nUse of resampling FstatMethod is incompatible with non-factored gridType=%i\n\n", uvar->gridType );
1193 }
1194
1195 /* if IFO string vector was passed by user, parse it for later use */
1196 if ( uvar->IFOs != NULL ) {
1198 }
1199
1200 LIGOTimeGPS minStartTime = uvar->minStartTime;
1201 LIGOTimeGPS maxStartTime = uvar->maxStartTime;
1202 constraints.minStartTime = &minStartTime;
1203 constraints.maxStartTime = &maxStartTime;
1204
1205 /* read timestamps if requested by the user */
1206 if ( uvar->timestampsFiles != NULL ) {
1207 XLAL_CHECK( ( cfg->multiTimestamps = XLALReadMultiTimestampsFilesConstrained( uvar->timestampsFiles, constraints.minStartTime, constraints.maxStartTime ) ) != NULL, XLAL_EFUNC );
1208 XLAL_CHECK( ( cfg->multiTimestamps->length > 0 ) && ( cfg->multiTimestamps->data != NULL ), XLAL_EINVAL, "Got empty timestamps-list from XLALReadMultiTimestampsFiles()\n" );
1209
1210 for ( UINT4 X = 0; X < cfg->multiTimestamps->length; X ++ ) {
1211 cfg->multiTimestamps->data[X]->deltaT = uvar->Tsft; // Tsft information not given by timestamps-file
1212 }
1213 }
1214
1215 /* get full SFT-catalog of all matching (multi-IFO) SFTs */
1216 /* DataFiles optional because of injectSqrtSX option, don't try to load if no files given **/
1217 if ( uvar->DataFiles != NULL ) {
1218 LogPrintf( LOG_NORMAL, "Finding all SFTs to load ... " );
1219 XLAL_CHECK( ( catalog = XLALSFTdataFind( uvar->DataFiles, &constraints ) ) != NULL, XLAL_EFUNC );
1220 LogPrintfVerbatim( LOG_NORMAL, "done. (found %d SFTs)\n", catalog->length );
1221 } else {
1222 /* Build a fake catalog with timestamps and IFOs given on the commandline instead of noise data files */
1223 /* the data missing in the locators then signal to the Fstat code that fake noise needs to be generated, */
1224 /* the noise level is passed from the sqrtSX option */
1225 XLAL_CHECK( ( catalog = XLALMultiAddToFakeSFTCatalog( NULL, uvar->IFOs, cfg-> multiTimestamps ) ) != NULL, XLAL_EFUNC );
1226 }
1227
1228 XLAL_CHECK( catalog->length > 0, XLAL_EINVAL, "\nSorry, didn't find any matching SFTs with pattern '%s'!\n\n", uvar->DataFiles );
1229
1230 /* deduce start- and end-time of the observation spanned by the data */
1231 UINT4 numSFTfiles = catalog->length;
1232
1233 cfg->Tsft = 1.0 / catalog->data[0].header.deltaF;
1234 cfg->startTime = catalog->data[0].header.epoch;
1235 endTime = catalog->data[numSFTfiles - 1].header.epoch;
1236 XLALGPSAdd( &endTime, cfg->Tsft ); /* add on Tsft to last SFT start-time */
1237
1238 // time spanned by the SFTs
1239 cfg->Tspan = XLALGPSDiff( &endTime, &cfg->startTime );
1240
1241 /* ----- load ephemeris-data ----- */
1242 XLAL_CHECK( ( cfg->ephemeris = XLALInitBarycenter( uvar->ephemEarth, uvar->ephemSun ) ) != NULL, XLAL_EFUNC );
1243
1244 /* ----- get reference-times (from user if given, use startTime otherwise): ----- */
1245 LIGOTimeGPS refTime;
1246 if ( XLALUserVarWasSet( &uvar->refTime ) ) {
1247 refTime = uvar->refTime;
1248 } else {
1249 refTime = cfg->startTime;
1250 }
1251
1252 /* define sky position variables from user input */
1253 cfg->Alpha = uvar->Alpha;
1254 cfg->Delta = uvar->Delta;
1255
1256
1257 REAL8 fMin, fMax, f1dotMin, f1dotMax, f2dotMin, f2dotMax, f3dotMin, f3dotMax;
1258 { /* ----- prepare spin-range at refTime (in *canonical format*, ie all Bands >= 0) ----- */
1259 fMin = MYMIN( uvar->Freq, uvar->Freq + uvar->FreqBand );
1260 fMax = MYMAX( uvar->Freq, uvar->Freq + uvar->FreqBand );
1261
1262 /* Specific to --gridType=GRID_SPINDOWN_AGEBRK parameter space */
1263 if ( uvar->gridType == GRID_SPINDOWN_AGEBRK ) {
1264
1265 /* Set the first and second spindown ranges to the maximum that will be
1266 * encountered by the age-braking index parameter space. These will *ONLY*
1267 * be used by older code to, e.g. load the correct band of SFTs, and
1268 * will *NOT* be used by the tiling code itself.
1269 * The formulas used here are, with age=a, min braking=n, max braking=N:
1270 *
1271 * -f0/((n-1)*a) <= f1 <= -f0/((N-1)*a)
1272 * n*(f1^2)/f0 <= f2 <= N*(f1^2)/f0
1273 *
1274 * f0/f1 are taken as the maximum/minimum value appropriate for getting the
1275 * maximum/minimum values of f1/f2 (note that f1 is strictly negative here).
1276 */
1277
1278 f1dotMin = -1.0 * fMax / ( ( uvar->minBraking - 1.0 ) * uvar->spindownAge );
1279 f1dotMax = -1.0 * fMin / ( ( uvar->maxBraking - 1.0 ) * uvar->spindownAge );
1280
1281 f2dotMin = uvar->minBraking * ( f1dotMax * f1dotMax ) / fMax;
1282 f2dotMax = uvar->maxBraking * ( f1dotMin * f1dotMin ) / fMin;
1283
1284 } else { /* Used for all other --gridTypes */
1285
1286 f1dotMin = MYMIN( uvar->f1dot, uvar->f1dot + uvar->f1dotBand );
1287 f1dotMax = MYMAX( uvar->f1dot, uvar->f1dot + uvar->f1dotBand );
1288
1289 f2dotMin = MYMIN( uvar->f2dot, uvar->f2dot + uvar->f2dotBand );
1290 f2dotMax = MYMAX( uvar->f2dot, uvar->f2dot + uvar->f2dotBand );
1291
1292 }
1293
1294 f3dotMin = MYMIN( uvar->f3dot, uvar->f3dot + uvar->f3dotBand );
1295 f3dotMax = MYMAX( uvar->f3dot, uvar->f3dot + uvar->f3dotBand );
1296
1297 } /* spin-range at refTime */
1298
1299
1300 { /* ----- set up Doppler region to scan ----- */
1301 BOOLEAN haveAlphaDelta = ( XLALUserVarWasSet( &uvar->Alpha ) && XLALUserVarWasSet( &uvar->Delta ) );
1302
1303 if ( uvar->skyRegion ) {
1304 XLAL_CHECK( ( cfg->searchRegion.skyRegionString = XLALCalloc( 1, strlen( uvar->skyRegion ) + 1 ) ) != NULL, XLAL_ENOMEM );
1305 strcpy( cfg->searchRegion.skyRegionString, uvar->skyRegion );
1306 } else if ( haveAlphaDelta ) { /* parse this into a sky-region */
1307 XLAL_CHECK( ( cfg->searchRegion.skyRegionString = XLALSkySquare2String( cfg->Alpha, cfg->Delta, uvar->AlphaBand, uvar->DeltaBand ) ) != NULL, XLAL_EFUNC );
1308 } else if ( !uvar->gridFile ) {
1309 XLAL_ERROR( XLAL_EINVAL, "\nCould not setup searchRegion, have neither skyRegion nor (Alpha, Delta) nor a gridFile!\n\n" );
1310 }
1311
1312 /* spin searchRegion defined by spin-range at reference-time */
1313 cfg->searchRegion.refTime = refTime;
1314
1315 cfg->searchRegion.fkdot[0] = fMin;
1316 cfg->searchRegion.fkdot[1] = f1dotMin;
1317 cfg->searchRegion.fkdot[2] = f2dotMin;
1318 cfg->searchRegion.fkdot[3] = f3dotMin;
1319
1320 cfg->searchRegion.fkdotBand[0] = fMax - fMin;
1321 cfg->searchRegion.fkdotBand[1] = f1dotMax - f1dotMin;
1322 cfg->searchRegion.fkdotBand[2] = f2dotMax - f2dotMin;
1323 cfg->searchRegion.fkdotBand[3] = f3dotMax - f3dotMin;
1324
1325 } /* get DopplerRegion */
1326
1327 /*read signal parameters to be injected, if requested by the user*/
1328 if ( uvar->injectionSources != NULL ) {
1329 XLAL_CHECK_MAIN( ( cfg->injectionSources = XLALPulsarParamsFromUserInput( uvar->injectionSources, NULL ) ) != NULL, XLAL_EFUNC );
1330 }
1331
1332 /* ----- set fixed grid step-sizes from user-input: only used for GRID_FLAT ----- */
1333 cfg->stepSizes.Alpha = uvar->dAlpha;
1334 cfg->stepSizes.Delta = uvar->dDelta;
1335 cfg->stepSizes.fkdot[0] = uvar->dFreq;
1336 cfg->stepSizes.fkdot[1] = uvar->df1dot;
1337 cfg->stepSizes.fkdot[2] = uvar->df2dot;
1338 cfg->stepSizes.fkdot[3] = uvar->df3dot;
1339
1340
1341 REAL8 tmpFreqBandRef = cfg->searchRegion.fkdotBand[0];
1342
1343 /* initialize full multi-dimensional Doppler-scanner */
1344 {
1345 DopplerFullScanInit scanInit; /* init-structure for DopperScanner */
1346
1347 scanInit.searchRegion = cfg->searchRegion;
1348 if ( cfg->useResamp ) { // in the resampling-case, temporarily take out frequency-dimension of the Doppler template bank
1349 scanInit.searchRegion.fkdotBand[0] = 0;
1350 }
1351
1352 scanInit.gridType = uvar->gridType;
1353 scanInit.gridFile = uvar->gridFile;
1354 scanInit.metricType = uvar->metricType;
1355 scanInit.projectMetric = uvar->projectMetric;
1356 scanInit.metricMismatch = uvar->metricMismatch;
1357 scanInit.stepSizes = cfg->stepSizes;
1358 scanInit.ephemeris = cfg->ephemeris; /* used by Ephemeris-based metric */
1359 scanInit.startTime = cfg->startTime;
1360 scanInit.Tspan = cfg->Tspan;
1361
1362 // just use first SFTs' IFO for metric (should be irrelevant)
1363 const LALDetector *detector;
1364 XLAL_CHECK( ( detector = XLALGetSiteInfo( catalog->data[0].header.name ) ) != NULL, XLAL_EFUNC );
1365 scanInit.Detector = detector;
1366
1367 /* Specific options for some gridTypes */
1368 if ( uvar->gridType == GRID_SPINDOWN_SQUARE ) {
1369 scanInit.extraArgs[0] = !uvar->strictSpindownBounds;
1370 } else if ( uvar->gridType == GRID_SPINDOWN_AGEBRK ) {
1371 scanInit.extraArgs[0] = uvar->spindownAge;
1372 scanInit.extraArgs[1] = uvar->minBraking;
1373 scanInit.extraArgs[2] = uvar->maxBraking;
1374 }
1375
1376 LogPrintf( LOG_NORMAL, "Setting up template grid ... " );
1377 XLAL_CHECK( ( cfg->scanState = XLALInitDopplerFullScan( &scanInit ) ) != NULL, XLAL_EFUNC );
1378 LogPrintfVerbatim( LOG_NORMAL, "template grid ready.\n" );
1380 }
1381
1382 /* maximum ranges of binary orbit parameters */
1383 const REAL8 binaryMaxAsini = MYMAX( uvar->orbitasini, uvar->orbitasini + uvar->orbitasiniBand );
1384 const REAL8 binaryMinPeriod = MYMIN( uvar->orbitPeriod, uvar->orbitPeriod + uvar->orbitPeriodBand );
1385 const REAL8 binaryMaxEcc = MYMAX( uvar->orbitEcc, uvar->orbitEcc + uvar->orbitEccBand );
1386
1387 { /* ----- What frequency-band do we need to read from the SFTs?
1388 * propagate spin-range from refTime to startTime and endTime of observation
1389 */
1390 PulsarSpinRange spinRangeRef; /* temporary only */
1391
1392 // extract spanned spin-range at reference-time from the template-bank
1394
1395 // in the resampling case, we need to restore the frequency-band info now, which we set to 0
1396 // before calling the DopplerInit template bank construction
1397 if ( cfg->useResamp ) {
1398 spinRangeRef.fkdotBand[0] = tmpFreqBandRef;
1399 }
1400
1401 // write this search spin-range@refTime back into 'cfg' struct for users' reference
1402 cfg->searchRegion.refTime = spinRangeRef.refTime;
1403 memcpy( cfg->searchRegion.fkdot, spinRangeRef.fkdot, sizeof( cfg->searchRegion.fkdot ) );
1404 memcpy( cfg->searchRegion.fkdotBand, spinRangeRef.fkdotBand, sizeof( cfg->searchRegion.fkdotBand ) );
1405
1406 // Compute covering frequency range, accounting for Doppler modulation due to the Earth and any binary companion */
1407 XLALCWSignalCoveringBand( &fCoverMin, &fCoverMax, &cfg->startTime, &endTime, &spinRangeRef, binaryMaxAsini, binaryMinPeriod, binaryMaxEcc );
1408
1409 } /* extrapolate spin-range */
1410
1411 /* check that SFT length is within allowed maximum */
1412 /* use fCoverMax here to work with loading grid from file (--gridType=6) */
1413 XLAL_CHECK( XLALFstatCheckSFTLengthMismatch( cfg->Tsft, fCoverMax, binaryMaxAsini, binaryMinPeriod, uvar->allowedMismatchFromSFTLength ) == XLAL_SUCCESS, XLAL_EFUNC, "Excessive mismatch would be incurred due to SFTs being too long for the current search setup. Please double-check your parameter ranges or provide shorter input SFTs. If you really know what you're doing, you could also consider using the --allowedMismatchFromSFTLength override." );
1414
1415 /* If requested, assume a certain PSD instead of estimating it from data.
1416 * NOTE that, unlike for the now removed --SignalOnly flag,
1417 * no extra +4 is added to the F-statistic output in this case.
1418 */
1419 MultiNoiseFloor s_assumeSqrtSX, *assumeSqrtSX;
1420 if ( uvar->assumeSqrtSX != NULL ) {
1421 XLAL_CHECK( XLALParseMultiNoiseFloor( &s_assumeSqrtSX, uvar->assumeSqrtSX, XLALCountIFOsInCatalog( catalog ) ) == XLAL_SUCCESS, XLAL_EFUNC );
1422 assumeSqrtSX = &s_assumeSqrtSX;
1423 } else {
1424 assumeSqrtSX = NULL;
1425 }
1426
1427 if ( XLALUserVarWasSet( &uvar->dFreq ) ) {
1428 cfg->dFreq = uvar->dFreq;
1429 } else {
1430 cfg->dFreq = 1.0 / ( 2 * cfg->Tspan );
1431 }
1432 if ( cfg->useResamp ) { // handle special resampling case, where we deal with a vector of F-stat values instead of one
1433 cfg->numFreqBins_FBand = ( UINT4 )( 1 + floor( cfg->searchRegion.fkdotBand[0] / cfg->dFreq ) );
1434 } else {
1435 cfg->numFreqBins_FBand = 1; // number of frequency-bins in the frequency-band used for resampling (1 if not using Resampling)
1436 }
1437
1438 MultiNoiseFloor *injectSqrtSX = NULL;
1439 MultiNoiseFloor s_injectSqrtSX;
1440
1441 if ( uvar->injectSqrtSX != NULL ) {
1442 XLAL_CHECK( XLALParseMultiNoiseFloor( &s_injectSqrtSX, uvar->injectSqrtSX, XLALCountIFOsInCatalog( catalog ) ) == XLAL_SUCCESS, XLAL_EFUNC );
1443 injectSqrtSX = &s_injectSqrtSX;
1444 }
1445
1447 optionalArgs.Dterms = uvar->Dterms;
1448 optionalArgs.SSBprec = uvar->SSBprecision;
1449 optionalArgs.runningMedianWindow = uvar->RngMedWindow;
1450 optionalArgs.injectSources = cfg->injectionSources;
1451 optionalArgs.injectSqrtSX = injectSqrtSX;
1452 optionalArgs.randSeed = uvar->randSeed;
1453 optionalArgs.assumeSqrtSX = assumeSqrtSX;
1454 optionalArgs.FstatMethod = uvar->FstatMethod;
1455 optionalArgs.resampFFTPowerOf2 = uvar->resampFFTPowerOf2;
1456 optionalArgs.collectTiming = XLALUserVarWasSet( &uvar->outputFstatTiming );
1457 optionalArgs.allowedMismatchFromSFTLength = uvar->allowedMismatchFromSFTLength;
1458
1459
1460 XLAL_CHECK( ( cfg->Fstat_in = XLALCreateFstatInput( catalog, fCoverMin, fCoverMax, cfg->dFreq, cfg->ephemeris, &optionalArgs ) ) != NULL, XLAL_EFUNC );
1461 XLALDestroySFTCatalog( catalog );
1462
1463 cfg->Fstat_what = FSTATQ_2F; // always calculate multi-detector 2F
1464 if ( XLALUserVarWasSet( &uvar->outputLoudest ) ) {
1465 cfg->Fstat_what |= FSTATQ_FAFB; // also calculate Fa,b parts for parameter estimation
1466 }
1467
1468 /* get SFT detectors and timestamps */
1469 const MultiLALDetector *multiIFO;
1470 XLAL_CHECK( ( multiIFO = XLALGetFstatInputDetectors( cfg->Fstat_in ) ) != NULL, XLAL_EFUNC );
1473
1474 /* count total number of SFTs loaded */
1475 cfg->NSFTs = 0;
1476 for ( UINT4 X = 0; X < multiTS->length; X++ ) {
1477 cfg->NSFTs += multiTS->data[X]->length;
1478 }
1479
1480 /* for column headings string, get number of detectors, detector name vector, and SFTs per detector vector */
1481 {
1482 const UINT4 numDetectors = multiIFO->length;
1484 cfg->detectorIDs = NULL;
1485 for ( UINT4 X = 0; X < numDetectors; X++ ) {
1486 cfg->numSFTsPerDet->data[X] = multiTS->data[X]->length;
1487 XLAL_CHECK( ( cfg->detectorIDs = XLALAppendString2Vector( cfg->detectorIDs, multiIFO->sites[X].frDetector.prefix ) ) != NULL, XLAL_EFUNC );
1488 } /* for X < numDetectors */
1489 }
1490
1491 /* ----- set up scanline-window if requested for 1D local-maximum clustering on scanline ----- */
1492 XLAL_CHECK( ( cfg->scanlineWindow = XLALCreateScanlineWindow( uvar->clusterOnScanline ) ) != NULL, XLAL_EFUNC );
1493
1494 /* set number of toplist candidates from fraction if asked to */
1495 if ( 0.0 < uvar->FracCandidatesToKeep && uvar->FracCandidatesToKeep <= 1.0 ) {
1496 if ( XLALNumDopplerTemplates( cfg->scanState ) <= 0.0 ) {
1497 XLAL_ERROR( XLAL_EINVAL, "Cannot use FracCandidatesToKeep because number of templates was counted to be zero!\n" );
1498 }
1499 toplist_length = ceil( XLALNumDopplerTemplates( cfg->scanState ) * uvar->FracCandidatesToKeep );
1500 }
1501
1502 /* ----- set up toplist if requested ----- */
1503 if ( toplist_length > 0 ) {
1504 if ( strcmp( uvar->RankingStatistic, "F" ) == 0 ) {
1506 } else if ( strcmp( uvar->RankingStatistic, "BSGL" ) == 0 ) {
1507 if ( !uvar->computeBSGL ) {
1508 XLAL_ERROR( XLAL_EINVAL, "\nERROR: Ranking by BSGL only possible if --computeBSGL given.\n\n" );
1509 }
1511 } else {
1512 XLAL_ERROR( XLAL_EINVAL, "\nERROR: Invalid value specified for candidate ranking - supported are 'F' and 'BSGL'.\n\n" );
1513 }
1514
1515 if ( cfg->RankingStatistic == RANKBY_BSGL ) {
1516 XLAL_CHECK( create_toplist( &( cfg->FstatToplist ), toplist_length, sizeof( FstatCandidate ), compareFstatCandidates_BSGL ) == 0, XLAL_EFUNC );
1517 } else { // rank by F-stat
1518 XLAL_CHECK( create_toplist( &( cfg->FstatToplist ), toplist_length, sizeof( FstatCandidate ), compareFstatCandidates ) == 0, XLAL_EFUNC );
1519 }
1520 } /* if toplist_length > 0 */
1521
1522
1523 /* ----- transient-window related parameters ----- */
1524 int twtype;
1525 XLAL_CHECK( ( twtype = XLALParseTransientWindowName( uvar->transient_WindowType ) ) >= 0, XLAL_EFUNC );
1526 cfg->transientWindowRange.type = twtype;
1527
1528 /* make sure user doesn't set window=none but sets window-parameters => indicates she didn't mean 'none' */
1530 && ( XLALUserVarWasSet( &uvar->transient_dt0 )
1531 || XLALUserVarWasSet( &uvar->transient_t0Epoch )
1532 || XLALUserVarWasSet( &uvar->transient_t0Offset )
1533 || XLALUserVarWasSet( &uvar->transient_t0Band )
1534 || XLALUserVarWasSet( &uvar->transient_tau )
1535 || XLALUserVarWasSet( &uvar->transient_tauBand )
1536 || XLALUserVarWasSet( &uvar->transient_dtau ) )
1537 ), XLAL_EINVAL, "ERROR: transientWindow->type == NONE, but window-parameters were set! Use a different window-type!" );
1538
1539 if ( XLALUserVarWasSet( &uvar->transient_t0Offset ) ) {
1540 XLAL_CHECK( !XLALUserVarWasSet( &uvar->transient_t0Epoch ), XLAL_EINVAL, "ERROR: only one of transient_t0Epoch, transient_t0Offset may be used!" );
1541 cfg->transientWindowRange.t0 = cfg->startTime.gpsSeconds + uvar->transient_t0Offset;
1542 } else if ( XLALUserVarWasSet( &uvar->transient_t0Epoch ) ) {
1543 cfg->transientWindowRange.t0 = uvar->transient_t0Epoch.gpsSeconds; /* just dropping ns part here */
1544 }
1545
1546 if ( XLALUserVarWasSet( &uvar->transient_t0Band ) ) {
1547 cfg->transientWindowRange.t0Band = uvar->transient_t0Band;
1548 }
1549
1550 if ( XLALUserVarWasSet( &uvar->transient_dt0 ) ) {
1551 cfg->transientWindowRange.dt0 = uvar->transient_dt0;
1552 } else {
1553 cfg->transientWindowRange.dt0 = cfg->Tsft;
1554 }
1555
1556 if ( XLALUserVarWasSet( &uvar->transient_tau ) ) {
1557 cfg->transientWindowRange.tau = uvar->transient_tau;
1558 }
1559
1560 if ( XLALUserVarWasSet( &uvar->transient_tauBand ) ) {
1561 cfg->transientWindowRange.tauBand = uvar->transient_tauBand;
1562 }
1563
1564 if ( XLALUserVarWasSet( &uvar->transient_dtau ) ) {
1565 cfg->transientWindowRange.dtau = uvar->transient_dtau;
1566 } else {
1567 cfg->transientWindowRange.dtau = cfg->Tsft;
1568 }
1569
1570 /* get atoms back from Fstat-computing, either if atoms-output or transient-Bstat output was requested */
1571 if ( ( uvar->outputFstatAtoms != NULL ) || ( uvar->outputTransientStats != NULL ) || ( uvar->outputTransientStatsAll != NULL ) ) {
1573 }
1574
1575 /* return single-IFO Fstat values for Line-robust statistic */
1576 if ( uvar->outputSingleFstats || uvar->computeBSGL ) {
1578 }
1579
1580 /* ---------- prepare Line-robust statistics parameters ---------- */
1581 if ( uvar->computeBSGL ) {
1582 UINT4 numDetectors = multiIFO->length;
1583 /* take BSGL user input and pre-compute the corresponding BSGLsetup */
1584 REAL4 *oLGX_p = NULL;
1586 if ( uvar->oLGX != NULL ) {
1587 if ( uvar->oLGX->length != numDetectors ) {
1588 XLAL_ERROR( XLAL_EINVAL, "Invalid input: length(oLGX) = %d differs from number of detectors (%d)'\n", uvar->oLGX->length, numDetectors );
1589 }
1590 XLAL_CHECK( XLALParseLinePriors( &oLGX[0], uvar->oLGX ) == XLAL_SUCCESS, XLAL_EFUNC );
1591 oLGX_p = &oLGX[0];
1592 } // if uvar->oLGX != NULL
1593
1594 XLAL_CHECK( ( cfg->BSGLsetup = XLALCreateBSGLSetup( numDetectors, uvar->Fstar0, oLGX_p, uvar->BSGLlogcorr, 1 ) ) != NULL, XLAL_EFUNC ); // coherent F-stat: NSeg=1
1595 } // if uvar_computeBSGL
1596
1597 return XLAL_SUCCESS;
1598
1599} /* InitFstat() */
1600
1601/**
1602 * Produce a log-string describing the present run-setup
1603 */
1604CHAR *
1606{
1607 XLAL_CHECK_NULL( cfg != NULL, XLAL_EINVAL );
1608
1609#define BUFLEN 1024
1610 CHAR buf[BUFLEN];
1611
1612 CHAR *logstr = NULL;
1613 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, "%% cmdline: " ) ) != NULL, XLAL_EFUNC );
1614 CHAR *cmdline;
1616 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, cmdline ) ) != NULL, XLAL_EFUNC );
1617 XLALFree( cmdline );
1618 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, "\n" ) ) != NULL, XLAL_EFUNC );
1619 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, cfg->VCSInfoString ) ) != NULL, XLAL_EFUNC );
1620
1621 if ( !verbose ) {
1622 /* don't include search details */
1623 return logstr;
1624 }
1625
1626 XLAL_CHECK_NULL( snprintf( buf, BUFLEN, "%%%% FstatMethod used: '%s'\n", XLALGetFstatInputMethodName( cfg->Fstat_in ) ) < BUFLEN, XLAL_EBADLEN );
1627 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, buf ) ) != NULL, XLAL_EFUNC );
1628
1629 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, "%% Started search: " ) ) != NULL, XLAL_EFUNC );
1630 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, LogGetTimestamp() ) ) != NULL, XLAL_EFUNC );
1631 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, "\n%% Loaded SFTs: [ " ) ) != NULL, XLAL_EFUNC );
1632
1634 for ( UINT4 X = 0; X < numDet; X ++ ) {
1635 XLAL_CHECK_NULL( snprintf( buf, BUFLEN, "%s:%d%s", cfg->detectorIDs->data[X], cfg->numSFTsPerDet->data[X], ( X < numDet - 1 ) ? ", " : " ]\n" ) < BUFLEN, XLAL_EBADLEN );
1636 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, buf ) ) != NULL, XLAL_EFUNC );
1637 }
1638 INT4 startTimeSeconds = cfg->startTime.gpsSeconds;
1639 struct tm startTimeUTC = *XLALGPSToUTC( &startTimeUTC, startTimeSeconds );
1640 {
1641 CHAR *startTimeUTCString = XLALStringDuplicate( asctime( &startTimeUTC ) );
1642 startTimeUTCString[strlen( startTimeUTCString ) - 1] = 0; // kill trailing newline
1643 XLAL_CHECK_NULL( snprintf( buf, BUFLEN, "%%%% GPS starttime = %d (%s GMT)\n", startTimeSeconds, startTimeUTCString ) < BUFLEN, XLAL_EBADLEN );
1644 XLALFree( startTimeUTCString );
1645 }
1646 char bufGPS[32];
1647 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, buf ) ) != NULL, XLAL_EFUNC );
1648 XLAL_CHECK_NULL( snprintf( buf, BUFLEN, "%%%% Total time spanned = %.0f s (%.2f hours)\n", cfg->Tspan, cfg->Tspan / 3600.0 ) < BUFLEN, XLAL_EBADLEN );
1649 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, buf ) ) != NULL, XLAL_EFUNC );
1650 XLAL_CHECK_NULL( snprintf( buf, BUFLEN, "%%%% Pulsar-params refTime = %s\n", XLALGPSToStr( bufGPS, &( cfg->searchRegion.refTime ) ) ) < BUFLEN, XLAL_EBADLEN );
1651 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, buf ) ) != NULL, XLAL_EFUNC );
1652 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, "%% Spin-range at refTime: fkdot = [ " ) ) != NULL, XLAL_EFUNC );
1653 for ( UINT4 k = 0; k < PULSAR_MAX_SPINS; k ++ ) {
1654 XLAL_CHECK_NULL( snprintf( buf, BUFLEN, "%.16g:%.16g%s", cfg->searchRegion.fkdot[k], cfg->searchRegion.fkdot[k] + cfg->searchRegion.fkdotBand[k],
1655 ( k < PULSAR_MAX_SPINS - 1 ) ? ", " : " ]\n" ) < BUFLEN, XLAL_EBADLEN );
1656 XLAL_CHECK_NULL( ( logstr = XLALStringAppend( logstr, buf ) ) != NULL, XLAL_EFUNC );
1657 }
1658
1659 /* return result */
1660 return logstr;
1661
1662} // XLALGetLogString()
1663
1664
1665
1666/***********************************************************************/
1667/**
1668 * Log the all relevant parameters of the present search-run to a log-file.
1669 * The name of the log-file is log_fname
1670 * <em>NOTE:</em> Currently this function only logs the user-input and code-versions.
1671 */
1672int
1673WriteFstatLog( const CHAR *log_fname, const CHAR *log_string )
1674{
1675 XLAL_CHECK( ( log_fname != NULL ) && ( log_string != NULL ), XLAL_EINVAL );
1676
1677 /* prepare log-file for writing */
1678 FILE *fplog;
1679 XLAL_CHECK( ( fplog = fopen( log_fname, "wb" ) ) != NULL, XLAL_ESYS, "Failed to open log-file '%s' for writing.\n\n", log_fname );
1680
1681 fprintf( fplog, "%%%% LOG-FILE for ComputeFstatistic run\n\n" );
1682 fprintf( fplog, "%s", log_string );
1683 fclose( fplog );
1684
1685 return XLAL_SUCCESS;
1686
1687} /* WriteFstatLog() */
1688
1689
1690/** Free all globally allocated memory. */
1691void
1693{
1694 if ( !cfg ) {
1695 return;
1696 }
1699
1701
1702 /* destroy FstatToplist if any */
1703 if ( cfg->FstatToplist ) {
1704 free_toplist( &( cfg->FstatToplist ) );
1705 }
1706
1707 if ( cfg->scanlineWindow ) {
1709 }
1710
1711 /* Free config-Variables and userInput stuff */
1713
1714 if ( cfg->searchRegion.skyRegionString ) {
1716 }
1717
1718 /* Free ephemeris data */
1720
1721 if ( cfg->VCSInfoString ) {
1722 XLALFree( cfg->VCSInfoString );
1723 }
1724 if ( cfg->logstring ) {
1725 XLALFree( cfg->logstring );
1726 }
1727
1728 XLALFree( cfg->BSGLsetup );
1729
1730 /* free source injection if any */
1731 if ( cfg->injectionSources ) {
1733 }
1734
1735 if ( cfg->multiTimestamps ) {
1737 }
1738
1739 return;
1740
1741} /* Freemem() */
1742
1743
1744/*----------------------------------------------------------------------*/
1745/**
1746 * Some general consistency-checks on user-input.
1747 * Throws an error plus prints error-message if problems are found.
1748 */
1749int
1751{
1752 XLAL_CHECK( uvar != NULL, XLAL_EINVAL );
1753
1754 /* check for negative stepsizes in Freq, Alpha, Delta */
1755 if ( XLALUserVarWasSet( &uvar->dAlpha ) && ( uvar->dAlpha < 0 ) ) {
1756 XLALPrintError( "\nNegative value of stepsize dAlpha not allowed!\n\n" );
1758 }
1759 if ( XLALUserVarWasSet( &uvar->dDelta ) && ( uvar->dDelta < 0 ) ) {
1760 XLALPrintError( "\nNegative value of stepsize dDelta not allowed!\n\n" );
1762 }
1763 if ( XLALUserVarWasSet( &uvar->dFreq ) && ( uvar->dFreq < 0 ) ) {
1764 XLALPrintError( "\nNegative value of stepsize dFreq not allowed!\n\n" );
1766 }
1767
1768 /* binary parameter checks */
1769 if ( XLALUserVarWasSet( &uvar->orbitPeriod ) && ( uvar->orbitPeriod <= 0 ) ) {
1770 XLALPrintError( "\nNegative or zero value of orbital period not allowed!\n\n" );
1772 }
1773 if ( XLALUserVarWasSet( &uvar->orbitasini ) && ( uvar->orbitasini < 0 ) ) {
1774 XLALPrintError( "\nNegative value of projected orbital semi-major axis not allowed!\n\n" );
1776 }
1777 if ( XLALUserVarWasSet( &uvar->orbitArgp ) && ( ( uvar->orbitArgp < 0 ) || ( uvar->orbitArgp >= LAL_TWOPI ) ) ) {
1778 XLALPrintError( "\nOrbital argument of periapse must lie in range [0 2*PI)!\n\n" );
1780 }
1781 if ( XLALUserVarWasSet( &uvar->orbitEcc ) && ( uvar->orbitEcc < 0 ) ) {
1782 XLALPrintError( "\nNegative value of orbital eccentricity not allowed!\n\n" );
1784 }
1785
1786 /* grid-related checks */
1787 {
1788 BOOLEAN haveAlphaBand = XLALUserVarWasSet( &uvar->AlphaBand );
1789 BOOLEAN haveDeltaBand = XLALUserVarWasSet( &uvar->DeltaBand );
1790 BOOLEAN haveSkyRegion, haveAlphaDelta, haveGridFile;
1791 BOOLEAN useSkyGridFile, useFullGridFile, haveMetric, useMetric;
1792
1793 haveSkyRegion = ( uvar->skyRegion != NULL );
1794 haveAlphaDelta = ( XLALUserVarWasSet( &uvar->Alpha ) && XLALUserVarWasSet( &uvar->Delta ) );
1795 haveGridFile = ( uvar->gridFile != NULL );
1796 useSkyGridFile = ( uvar->gridType == GRID_FILE_SKYGRID );
1797 useFullGridFile = ( uvar->gridType == GRID_FILE_FULLGRID );
1798 haveMetric = ( uvar->metricType > LAL_PMETRIC_NONE );
1799 useMetric = ( uvar->gridType == GRID_METRIC );
1800
1801 if ( !useFullGridFile && !useSkyGridFile && haveGridFile ) {
1802 XLALPrintError( "\nERROR: gridFile was specified but not needed for gridType=%d\n\n", uvar->gridType );
1804 }
1805 if ( useSkyGridFile && !haveGridFile ) {
1806 XLALPrintError( "\nERROR: gridType=SKY-FILE, but no --gridFile specified!\n\n" );
1808 }
1809 if ( useFullGridFile && !haveGridFile ) {
1810 XLALPrintError( "\nERROR: gridType=GRID-FILE, but no --gridFile specified!\n\n" );
1812 }
1813
1814 if ( ( haveAlphaBand && !haveDeltaBand ) || ( haveDeltaBand && !haveAlphaBand ) ) {
1815 XLALPrintError( "\nERROR: Need either BOTH (AlphaBand, DeltaBand) or NONE.\n\n" );
1817 }
1818
1819 if ( haveSkyRegion && haveAlphaDelta ) {
1820 XLALPrintError( "\nOverdetermined sky-region: only use EITHER (Alpha,Delta) OR skyRegion!\n\n" );
1822 }
1823 if ( !haveSkyRegion && !haveAlphaDelta && !useSkyGridFile && !useFullGridFile ) {
1824 XLALPrintError( "\nUnderdetermined sky-region: use one of (Alpha,Delta), skyRegion or a gridFile!\n\n" );
1826 }
1827
1828 if ( !useMetric && haveMetric ) {
1829 XLALPrintWarning( "\nWARNING: Metric was specified for non-metric grid... will be ignored!\n" );
1830 }
1831 if ( useMetric && !haveMetric ) {
1832 XLALPrintError( "\nERROR: metric grid-type selected, but no metricType selected\n\n" );
1834 }
1835
1836 /* Specific checks for --gridType=GRID_SPINDOWN_{SQUARE,AGEBRK} parameter spaces */
1837 if ( uvar->gridType == GRID_SPINDOWN_SQUARE || uvar->gridType == GRID_SPINDOWN_AGEBRK ) {
1838
1839 /* Check that no grid spacings were given */
1840 if ( uvar->dFreq != 0.0 || uvar->df1dot != 0.0 || uvar->df2dot != 0.0 || uvar->df3dot != 0.0 ) {
1841 XLALPrintError( "\nERROR: dFreq and df{1,2,3}dot cannot be used with gridType={8,9}\n\n" );
1843 }
1844
1845 }
1846
1847 if ( uvar->strictSpindownBounds && !( uvar->gridType == GRID_SPINDOWN_SQUARE ) ) {
1848 XLALPrintError( "\nERROR: strictSpindownBounds can only be used with gridType=8\n\n" );
1850 }
1851
1852 /* Specific checks for --gridType=GRID_SPINDOWN_AGEBRK parameter space */
1853 if ( uvar->gridType == GRID_SPINDOWN_AGEBRK ) {
1854
1855 /* Check that no third spindown range were given */
1856 if ( uvar->f3dot != 0.0 || uvar->f3dotBand != 0.0 ) {
1857 XLALPrintError( "\nERROR: f3dot and f3dotBand cannot be used with gridType=9\n\n" );
1859 }
1860
1861 /* Check age and braking indices */
1862 if ( uvar->spindownAge <= 0.0 ) {
1863 XLALPrintError( "\nERROR: spindownAge must be strictly positive with gridType=9\n\n" );
1865 }
1866 if ( uvar->minBraking <= 0.0 ) {
1867 XLALPrintError( "\nERROR: minBraking must be strictly positive with gridType=9\n\n" );
1869 }
1870 if ( uvar->maxBraking <= 0.0 ) {
1871 XLALPrintError( "\nERROR: minBraking must be strictly positive with gridType=9\n\n" );
1873 }
1874 if ( uvar->minBraking >= uvar->maxBraking ) {
1875 XLALPrintError( "\nERROR: minBraking must be strictly less than maxBraking with gridType=9\n\n" );
1877 }
1878
1879 /* Check that no first and second spindown ranges were given */
1880 if ( uvar->f1dot != 0.0 || uvar->f1dotBand != 0.0 ) {
1881 XLALPrintError( "\nERROR: f1dot and f1dotBand cannot be used with gridType=9\n\n" );
1883 }
1884 if ( uvar->f2dot != 0.0 || uvar->f2dotBand != 0.0 ) {
1885 XLALPrintError( "\nERROR: f2dot and f2dotBand cannot be used with gridType=9\n\n" );
1887 }
1888
1889 }
1890
1891 } /* Grid-related checks */
1892
1893 /* check NumCandidatesToKeep and FracCandidatesToKeep */
1894 if ( XLALUserVarWasSet( &uvar->NumCandidatesToKeep ) && XLALUserVarWasSet( &uvar->FracCandidatesToKeep ) ) {
1895 XLALPrintError( "\nERROR: NumCandidatesToKeep and FracCandidatesToKeep are mutually exclusive\n\n" );
1897 }
1898 if ( XLALUserVarWasSet( &uvar->FracCandidatesToKeep ) && ( uvar->FracCandidatesToKeep <= 0.0 || 1.0 < uvar->FracCandidatesToKeep ) ) {
1899 XLALPrintError( "\nERROR: FracCandidatesToKeep must be greater than 0.0 and less than or equal to 1.0\n\n" );
1901 }
1902
1903 /* check options for input data and injections */
1904 XLAL_CHECK( ( uvar->DataFiles == NULL ) ^ ( uvar->injectSqrtSX == NULL ), XLAL_EINVAL, "Must pass exactly one out of --DataFiles or --injectSqrtSX \n" );
1905 if ( uvar->DataFiles != NULL ) {
1906 XLAL_CHECK( !XLALUserVarWasSet( &uvar->Tsft ), XLAL_EINVAL, UVAR_STR( Tsft ) " can only be used for data generation with " UVAR_STR( injectSqrtSX )", not when loading existing " UVAR_STR( DataFiles ) "\n" );
1907 XLAL_CHECK( uvar->IFOs == NULL, XLAL_EINVAL, UVAR_STR( IFOs ) " can only be used for data generation with " UVAR_STR( injectSqrtSX ) ", not when loading existing " UVAR_STR( DataFiles ) "\n" );
1908 XLAL_CHECK( uvar->timestampsFiles == NULL, XLAL_EINVAL, UVAR_STR( timestampsFiles ) " can only be used for data generation with " UVAR_STR( injectSqrtSX ) ", not when loading existing " UVAR_STR( DataFiles ) "\n" );
1909 }
1910 if ( uvar->injectSqrtSX != NULL ) {
1911 XLAL_CHECK( uvar->timestampsFiles != NULL && uvar->IFOs != NULL, XLAL_EINVAL, "--injectSqrtSX requires --IFOs, --timestampsFiles \n" );
1912 }
1913
1914 return XLAL_SUCCESS;
1915
1916} /* checkUserInputConsistency() */
1917
1918/* debug-output a(t) and b(t) into given file.
1919 * return 0 = OK, -1 on error
1920 */
1921int
1922outputBeamTS( const CHAR *fname, const AMCoeffs *amcoe, const DetectorStateSeries *detStates )
1923{
1924 FILE *fp;
1925 UINT4 i, len;
1926
1927 if ( !fname || !amcoe || !amcoe->a || !amcoe->b || !detStates ) {
1928 return -1;
1929 }
1930
1931 len = amcoe->a->length;
1932 if ( ( len != amcoe->b->length ) || ( len != detStates->length ) ) {
1933 return -1;
1934 }
1935
1936 if ( ( fp = fopen( fname, "wb" ) ) == NULL ) {
1937 return -1;
1938 }
1939
1940 for ( i = 0; i < len; i ++ ) {
1941 INT4 ret;
1942 ret = fprintf( fp, "%9d %f %f %f \n",
1943 detStates->data[i].tGPS.gpsSeconds, detStates->data[i].LMST, amcoe->a->data[i], amcoe->b->data[i] );
1944 if ( ret < 0 ) {
1945 fprintf( fp, "ERROR\n" );
1946 fclose( fp );
1947 return -1;
1948 }
1949 }
1950
1951 fclose( fp );
1952 return 0;
1953} /* outputBeamTS() */
1954
1955/**
1956 * write full 'PulsarCandidate' (i.e. Doppler params + Amplitude params + error-bars + Fa,Fb, F, + A,B,C,D
1957 * RETURN 0 = OK, -1 = ERROR
1958 */
1959int
1960write_PulsarCandidate_to_fp( FILE *fp, const PulsarCandidate *pulsarParams, const FstatCandidate *Fcand )
1961{
1962 if ( !fp || !pulsarParams || !Fcand ) {
1963 return -1;
1964 }
1965
1966 fprintf( fp, "\n" );
1967 char bufGPS[32];
1968 fprintf( fp, "refTime = %s;\n", XLALGPSToStr( bufGPS, &pulsarParams->Doppler.refTime ) );
1969 fprintf( fp, "\n" );
1970
1971 /* Amplitude parameters with error-estimates */
1972 fprintf( fp, "aPlus = % .6g;\n", pulsarParams->Amp.aPlus );
1973 fprintf( fp, "daPlus = % .6g;\n", pulsarParams->dAmp.aPlus );
1974 fprintf( fp, "aCross = % .6g;\n", pulsarParams->Amp.aCross );
1975 fprintf( fp, "daCross = % .6g;\n", pulsarParams->dAmp.aCross );
1976 fprintf( fp, "phi0 = % .6g;\n", pulsarParams->Amp.phi0 );
1977 fprintf( fp, "dphi0 = % .6g;\n", pulsarParams->dAmp.phi0 );
1978 fprintf( fp, "psi = % .6g;\n", pulsarParams->Amp.psi );
1979 fprintf( fp, "dpsi = % .6g;\n", pulsarParams->dAmp.psi );
1980
1981 /* To allow arbitrary aPlus/aCross amplitudes, we have switched to output-variables A^\nu = (aPlus, aCross, phi0, psi)
1982 * and hence using a different Jacobian matrix. The dh0 and dcosi recovered below are only valid when GW is emitted at
1983 * twice the spin frequency, and are derived from dA+, dAx. Since both the current and original calculations ignore
1984 * off-diagonal items in computing the errors, the dh0 and dcosi below are expected to be slightly different from the
1985 * original estimate when the output-variables are B^\nu = (h0, cosi, phi0, psi). Since they are only used for sanity
1986 * checks, it should not impact any usage. */
1987 if ( fabs( pulsarParams->Amp.aPlus ) >= fabs( pulsarParams->Amp.aCross ) ) { /* Assume GW at twice the spin frequency only */
1988 REAL8 h0, dh0, cosi, dcosi;
1989 h0 = pulsarParams->Amp.aPlus + sqrt( SQ( pulsarParams->Amp.aPlus ) - SQ( pulsarParams->Amp.aCross ) );
1990 if ( h0 > 0 ) {
1991 cosi = pulsarParams->Amp.aCross / h0;
1992 } else {
1993 cosi = 0;
1994 }
1995 dh0 = ( pulsarParams->Amp.aPlus + pulsarParams->dAmp.aPlus ) + sqrt( SQ( pulsarParams->Amp.aPlus + pulsarParams->dAmp.aPlus ) - SQ( fabs( pulsarParams->Amp.aCross ) + pulsarParams->dAmp.aCross ) ) - h0;
1996 if ( ( h0 + dh0 ) > 0 ) {
1997 dcosi = fabs( ( fabs( pulsarParams->Amp.aCross ) + pulsarParams->dAmp.aCross ) / ( h0 + dh0 ) - fabs( cosi ) );
1998 } else {
1999 dcosi = 0;
2000 }
2001
2002 fprintf( fp, "h0 = % .6g;\n", h0 );
2003 fprintf( fp, "dh0 = % .6g;\n", dh0 );
2004 fprintf( fp, "cosi = % .6g;\n", cosi );
2005 fprintf( fp, "dcosi = % .6g;\n", dcosi );
2006 }
2007
2008 fprintf( fp, "\n" );
2009
2010 /* Doppler parameters */
2011 fprintf( fp, "Alpha = % .16g;\n", pulsarParams->Doppler.Alpha );
2012 fprintf( fp, "Delta = % .16g;\n", pulsarParams->Doppler.Delta );
2013 fprintf( fp, "Freq = % .16g;\n", pulsarParams->Doppler.fkdot[0] );
2014 fprintf( fp, "f1dot = % .16g;\n", pulsarParams->Doppler.fkdot[1] );
2015 fprintf( fp, "f2dot = % .16g;\n", pulsarParams->Doppler.fkdot[2] );
2016 fprintf( fp, "f3dot = % .16g;\n", pulsarParams->Doppler.fkdot[3] );
2017
2018 fprintf( fp, "\n" );
2019
2020 /* Binary parameters */
2021 if ( pulsarParams->Doppler.asini > 0 ) {
2022 fprintf( fp, "orbitPeriod = % .16g;\n", pulsarParams->Doppler.period );
2023 fprintf( fp, "orbitasini = % .16g;\n", pulsarParams->Doppler.asini );
2024 fprintf( fp, "orbitTp = %s;\n", XLALGPSToStr( bufGPS, &( pulsarParams->Doppler.tp ) ) );
2025 fprintf( fp, "orbitArgp = % .16g;\n", pulsarParams->Doppler.argp );
2026 fprintf( fp, "orbitEcc = % .16g;\n", pulsarParams->Doppler.ecc );
2027 }
2028
2029 /* Amplitude Modulation Coefficients */
2030 fprintf( fp, "Ad = % .6g;\n", Fcand->Mmunu.Ad );
2031 fprintf( fp, "Bd = % .6g;\n", Fcand->Mmunu.Bd );
2032 fprintf( fp, "Cd = % .6g;\n", Fcand->Mmunu.Cd );
2033 fprintf( fp, "Ed = % .6g;\n", Fcand->Mmunu.Ed );
2034 fprintf( fp, "Sinv_Tsft= % .6g;\n", Fcand->Mmunu.Sinv_Tsft );
2035 fprintf( fp, "\n" );
2036
2037 /* F-stat-values */
2038 fprintf( fp, "Fa = % .6g %+.6gi;\n", creal( Fcand->Fa ), cimag( Fcand->Fa ) );
2039 fprintf( fp, "Fb = % .6g %+.6gi;\n", creal( Fcand->Fb ), cimag( Fcand->Fb ) );
2040 fprintf( fp, "twoF = % .6g;\n", Fcand->twoF );
2041 /* single-IFO F-stat values, if present */
2042 UINT4 X, numDet = Fcand->numDetectors;
2043 for ( X = 0; X < numDet ; X ++ ) {
2044 fprintf( fp, "twoF%d = % .6g;\n", X, Fcand->twoFX[X] );
2045 }
2046 /* BSGL */
2047 if ( !XLALIsREAL4FailNaN( Fcand->log10BSGL ) ) { /* if --computeBSGL=FALSE, the log10BSGL field was initialised to NAN - do not output it */
2048 fprintf( fp, "log10BSGL = % .6g;\n", Fcand->log10BSGL );
2049 }
2050
2051 fprintf( fp, "\nAmpFisher = " );
2052 XLALfprintfGSLmatrix( fp, "%.9g", pulsarParams->AmpFisherMatrix );
2053
2054 return 0;
2055
2056} /* write_PulsarCandidate_to_fp() */
2057
2058/** comparison function for our candidates toplist */
2059int
2060compareFstatCandidates( const void *candA, const void *candB )
2061{
2062 REAL8 twoF1 = ( ( const FstatCandidate * )candA )->twoF;
2063 REAL8 twoF2 = ( ( const FstatCandidate * )candB )->twoF;
2064 if ( twoF1 < twoF2 ) {
2065 return 1;
2066 } else if ( twoF1 > twoF2 ) {
2067 return -1;
2068 } else {
2069 return 0;
2070 }
2071
2072} /* compareFstatCandidates() */
2073
2074/** comparison function for our candidates toplist with alternate sorting statistic BSGL=log10BSGL */
2075int
2076compareFstatCandidates_BSGL( const void *candA, const void *candB )
2077{
2078 REAL8 BSGL1 = ( ( const FstatCandidate * )candA )->log10BSGL;
2079 REAL8 BSGL2 = ( ( const FstatCandidate * )candB )->log10BSGL;
2080 if ( BSGL1 < BSGL2 ) {
2081 return 1;
2082 } else if ( BSGL1 > BSGL2 ) {
2083 return -1;
2084 } else {
2085 return 0;
2086 }
2087
2088} /* compareFstatCandidates_BSGL() */
2089
2090/**
2091 * write one 'FstatCandidate' (i.e. only Doppler-params + Fstat) into file 'fp'.
2092 * Return: 0 = OK, -1 = ERROR
2093 */
2094int
2095write_FstatCandidate_to_fp( FILE *fp, const FstatCandidate *thisFCand, const BOOLEAN output_stats, const BOOLEAN output_orbit )
2096{
2097
2098 if ( !fp || !thisFCand ) {
2099 return -1;
2100 }
2101
2102 /* write main Doppler parameters */
2103 fprintf( fp, "%.16g %.16g %.16g %.16g %.16g %.16g",
2104 thisFCand->doppler.fkdot[0], thisFCand->doppler.Alpha, thisFCand->doppler.Delta,
2105 thisFCand->doppler.fkdot[1], thisFCand->doppler.fkdot[2], thisFCand->doppler.fkdot[3] );
2106
2107 if ( output_stats ) {
2108 /* add extra output-field containing per-detector FX if non-NULL */
2109 char extraStatsStr[256] = ""; /* defaults to empty */
2110 char buf0[256];
2111 /* BSGL */
2112 if ( !XLALIsREAL4FailNaN( thisFCand->log10BSGL ) ) { /* if --computeBSGL=FALSE, the log10BSGL field was initialised to NAN - do not output it */
2113 snprintf( extraStatsStr, sizeof( extraStatsStr ), " %.9g", thisFCand->log10BSGL );
2114 }
2115 if ( thisFCand->numDetectors > 0 ) {
2116 for ( UINT4 X = 0; X < thisFCand->numDetectors; X ++ ) {
2117 snprintf( buf0, sizeof( buf0 ), " %.9g", thisFCand->twoFX[X] );
2118 UINT4 len1 = strlen( extraStatsStr ) + strlen( buf0 ) + 1;
2119 if ( len1 > sizeof( extraStatsStr ) ) {
2120 XLAL_ERROR( XLAL_EINVAL, "assembled output string too long! (%d > %zu)\n", len1, sizeof( extraStatsStr ) );
2121 break; /* we can't really terminate with error in this function, but at least we avoid crashing */
2122 }
2123 strcat( extraStatsStr, buf0 );
2124 } /* for X < numDet */
2125 } /* if FX */
2126 fprintf( fp, " %.9g%s", thisFCand->twoF, extraStatsStr );
2127 }
2128
2129 if ( output_orbit ) {
2130 fprintf( fp, " %.16g %.16g %.16g %.16g %.16g",
2131 thisFCand->doppler.asini, thisFCand->doppler.period,
2132 XLALGPSGetREAL8( &thisFCand->doppler.tp ),
2133 thisFCand->doppler.argp, thisFCand->doppler.ecc );
2134 }
2135
2136 fprintf( fp, "\n" );
2137
2138 return 0;
2139
2140} /* write_FstatCandidate_to_fp */
2141
2142/* --------------------------------------------------------------------------------
2143 * Scanline window functions
2144 * FIXME: should go into a separate file once implementation is settled down ...
2145 *
2146 * --------------------------------------------------------------------------------*/
2147
2148/**
2149 * Create a scanline window, with given windowWings >= 0.
2150 * Note: the actual window-size is 1 + 2 * windowWings
2151 */
2153XLALCreateScanlineWindow( UINT4 windowWings ) /**< number of neighbors on each side in scanlineWindow */
2154{
2155 scanlineWindow_t *ret = NULL;
2156 UINT4 windowLen = 1 + 2 * windowWings;
2157
2158 XLAL_CHECK_NULL( ( ret = LALCalloc( 1, sizeof( *ret ) ) ) != NULL, XLAL_ENOMEM );
2159 ret->length = windowLen;
2160
2161 XLAL_CHECK_NULL( ( ret->window = LALCalloc( windowLen, sizeof( ret->window[0] ) ) ) != NULL, XLAL_ENOMEM );
2162
2163 ret->center = &( ret->window[ windowWings ] ); /* points to central bin */
2164
2165 return ret;
2166
2167} /* XLALCreateScanlineWindow() */
2168
2169void
2171{
2172 if ( !scanlineWindow ) {
2173 return;
2174 }
2175
2176 if ( scanlineWindow->window ) {
2177 XLALFree( scanlineWindow->window );
2178 }
2179
2180 XLALFree( scanlineWindow );
2181
2182 return;
2183
2184} /* XLALDestroyScanlineWindow() */
2185
2186/**
2187 * Advance by pushing a new candidate into the scanline-window
2188 */
2189int
2191{
2192 UINT4 i;
2193
2194 if ( !nextCand || !scanWindow || !scanWindow->window ) {
2196 }
2197
2198 for ( i = 1; i < scanWindow->length; i ++ ) {
2199 scanWindow->window[i - 1] = scanWindow->window[i];
2200 }
2201
2202 scanWindow->window[ scanWindow->length - 1 ] = *nextCand; /* struct-copy */
2203
2204 return XLAL_SUCCESS;
2205
2206} /* XLALAdvanceScanlineWindow() */
2207
2208/**
2209 * check wether central candidate in Scanline-window is a local maximum
2210 */
2211BOOLEAN
2212XLALCenterIsLocalMax( const scanlineWindow_t *scanWindow, const UINT4 rankingStatistic )
2213{
2214
2215 if ( !scanWindow || !scanWindow->center ) {
2216 return FALSE;
2217 }
2218
2219 if ( rankingStatistic == RANKBY_2F ) { /* F-statistic */
2220
2221 REAL8 twoF0 = scanWindow->center->twoF;
2222
2223 for ( UINT4 i = 0; i < scanWindow->length; i ++ )
2224 if ( scanWindow->window[i].twoF > twoF0 ) {
2225 return FALSE;
2226 }
2227
2228 }
2229
2230 else if ( rankingStatistic == RANKBY_BSGL ) { /* line-robust statistic log10BSGL */
2231
2232 REAL8 BSGL0 = scanWindow->center->log10BSGL;
2233
2234 for ( UINT4 i = 0; i < scanWindow->length; i ++ )
2235 if ( scanWindow->window[i].log10BSGL > BSGL0 ) {
2236 return FALSE;
2237 }
2238
2239 } else {
2240 XLALPrintError( "Unsupported ranking statistic '%d' ! Supported: 'F=0' and 'BSGL=2'.\n", rankingStatistic );
2241 return FALSE;
2242 }
2243
2244 return TRUE;
2245
2246} /* XLALCenterIsLocalMax() */
2247
2248/**
2249 * Function to append one timing-info line to output file.
2250 *
2251 */
2252int
2253write_TimingInfo( const CHAR *fname, const timingInfo_t *ti, const ConfigVariables *cfg )
2254{
2255 XLAL_CHECK( ( fname != NULL ) && ( ti != NULL ), XLAL_EINVAL );
2256
2257 CHAR *logstr_short;
2258 BOOLEAN logstrVerbose = FALSE;
2259 XLAL_CHECK( ( logstr_short = XLALGetLogString( cfg, logstrVerbose ) ) != NULL, XLAL_EFUNC );
2260
2261 FILE *fp;
2262 if ( ( fp = fopen( fname, "rb" ) ) != NULL ) {
2263 fclose( fp );
2264 XLAL_CHECK( ( fp = fopen( fname, "ab" ) ), XLAL_ESYS, "Failed to open existing timing-file '%s' for appending\n", fname );
2265 } else {
2266 XLAL_CHECK( ( fp = fopen( fname, "wb" ) ), XLAL_ESYS, "Failed to open new timing-file '%s' for writing\n", fname );
2267 fprintf( fp, "%s", logstr_short );
2268 fprintf( fp, "%2s%6s %10s %10s %10s %10s %10s %10s %10s %10s %10s %16s %12s\n",
2269 "%%", "NSFTs", "NFreq", "tauF[s]", "tauFEff[s]", "tauF0[s]", "FstatMethod",
2270 "tauMin", "tauMax", "NStart", "NTau", "tauTransFstatMap", "tauTransMarg"
2271 );
2272 }
2273
2274 fprintf( fp, "%8d %10d %10.1e %10.1e %10.1e %10s %10d %10d %10d %10d %16.1e %12.1e\n",
2275 ti->NSFTs, ti->NFreq, ti->tauFstat, ti->tauTemplate, ti->tauF0, XLALGetFstatInputMethodName( cfg->Fstat_in ),
2276 ti->tauMin, ti->tauMax, ti->NStart, ti->NTau, ti->tauTransFstatMap, ti->tauTransMarg
2277 );
2278
2279 fclose( fp );
2280 XLALFree( logstr_short );
2281 return XLAL_SUCCESS;
2282
2283} /* write_TimingInfo() */
2284
2285/* Resize histogram */
2286gsl_vector_int *resize_histogram( gsl_vector_int *old_hist, size_t size )
2287{
2288 gsl_vector_int *new_hist = gsl_vector_int_alloc( size );
2289 XLAL_CHECK_NULL( new_hist != NULL, XLAL_ENOMEM );
2290 gsl_vector_int_set_zero( new_hist );
2291 if ( old_hist != NULL ) {
2292 gsl_vector_int_view old = gsl_vector_int_subvector( old_hist, 0, GSL_MIN( old_hist->size, size ) );
2293 gsl_vector_int_view new = gsl_vector_int_subvector( new_hist, 0, GSL_MIN( old_hist->size, size ) );
2294 gsl_vector_int_memcpy( &new.vector, &old.vector );
2295 gsl_vector_int_free( old_hist );
2296 }
2297 return new_hist;
2298}
#define MYMIN(x, y)
int main(int argc, char *argv[])
MAIN function of ComputeFstatistic code.
int initUserVars(UserInput_t *uvar)
Register all our "user-variables" that can be specified from cmd-line and/or config-file.
void Freemem(ConfigVariables *cfg)
Free all globally allocated memory.
int compareFstatCandidates(const void *candA, const void *candB)
comparison function for our candidates toplist
int outputBeamTS(const CHAR *fname, const AMCoeffs *amcoe, const DetectorStateSeries *detStates)
int write_PulsarCandidate_to_fp(FILE *fp, const PulsarCandidate *pulsarParams, const FstatCandidate *Fcand)
write full 'PulsarCandidate' (i.e.
RankingStat_t
Enum for which statistic is used to "rank" significance of candidates.
@ RANKBY_2F
rank candidates by F-statistic
@ RANKBY_BSGL
rank candidates by BSGListic
@ RANKBY_NC
HierarchSearchGCT also has RANKBY_NC = 1, not applicable here.
gsl_vector_int * resize_histogram(gsl_vector_int *old_hist, size_t size)
CHAR * XLALGetLogString(const ConfigVariables *cfg, const BOOLEAN verbose)
Produce a log-string describing the present run-setup.
#define MYMAX(x, y)
convert GPS-time to REAL8
int compareFstatCandidates_BSGL(const void *candA, const void *candB)
comparison function for our candidates toplist with alternate sorting statistic BSGL=log10BSGL
int XLALAdvanceScanlineWindow(const FstatCandidate *nextCand, scanlineWindow_t *scanWindow)
Advance by pushing a new candidate into the scanline-window.
int vrbflg
defined in lal/lib/std/LALError.c
#define TRUE
#define FALSE
#define GETTIME
void XLALDestroyScanlineWindow(scanlineWindow_t *scanlineWindow)
#define SQ(x)
int write_TimingInfo(const CHAR *timingFile, const timingInfo_t *ti, const ConfigVariables *cfg)
Function to append one timing-info line to output file.
int InitFstat(ConfigVariables *cfg, const UserInput_t *uvar)
Initialized Fstat-code: handle user-input and set everything up.
BOOLEAN XLALCenterIsLocalMax(const scanlineWindow_t *scanWindow, const UINT4 sortingStatistic)
check wether central candidate in Scanline-window is a local maximum
#define BUFLEN
int checkUserInputConsistency(const UserInput_t *uvar)
Some general consistency-checks on user-input.
int WriteFstatLog(const CHAR *log_fname, const CHAR *logstr)
Log the all relevant parameters of the present search-run to a log-file.
scanlineWindow_t * XLALCreateScanlineWindow(UINT4 windowWings)
Create a scanline window, with given windowWings >= 0.
#define LAL_NAN
MultiNoiseWeights * getUnitWeights(const MultiSFTVector *multiSFTs)
int write_FstatCandidate_to_fp(FILE *fp, const FstatCandidate *thisFCand, const BOOLEAN output_stats, const BOOLEAN output_orbit)
write one 'FstatCandidate' (i.e.
void XLALDestroyDopplerFullScan(DopplerFullScanState *scan)
Destroy the a full DopplerFullScanState structure.
REAL8 XLALNumDopplerTemplates(DopplerFullScanState *scan)
Return (and compute if not done so yet) the total number of Doppler templates of the DopplerScan scan...
UINT8 XLALNumDopplerPointsAtDimension(DopplerFullScanState *scan, const size_t dim)
Compute and return the total number of frequency and spindown points up to and along a certain dimens...
DopplerFullScanState * XLALInitDopplerFullScan(const DopplerFullScanInit *init)
Set up a full multi-dimensional grid-scan.
int XLALGetDopplerSpinRange(PulsarSpinRange *spinRange, const DopplerFullScanState *scan)
Return the spin-range spanned by the given template bank stored in the opaque DopplerFullScanState.
int XLALNextDopplerPos(PulsarDopplerParams *pos, DopplerFullScanState *scan)
Function to step through the full template grid point by point.
CHAR * XLALSkySquare2String(REAL8 Alpha, REAL8 Delta, REAL8 AlphaBand, REAL8 DeltaBand)
parse a 'classical' sky-square (Alpha, Delta, AlphaBand, DeltaBand) into a "SkyRegion"-string of the ...
Definition: DopplerScan.c:1295
@ GRID_METRIC
generate grid using a 2D sky-metric
Definition: DopplerScan.h:93
@ GRID_SPINDOWN_SQUARE
spindown tiling for a single sky position and square parameter space
Definition: DopplerScan.h:100
@ GRID_FLAT
"flat" sky-grid: fixed step-size (dAlpha,dDelta)
Definition: DopplerScan.h:91
@ GRID_FILE_SKYGRID
read skygrid from a file
Definition: DopplerScan.h:94
@ GRID_FILE_FULLGRID
load the full D-dim grid from a file
Definition: DopplerScan.h:98
@ GRID_SKY_LAST
end-marker for factored grid types
Definition: DopplerScan.h:96
@ GRID_SPINDOWN_AGEBRK
spindown tiling for a single sky position and non-square parameter space defined by spindown age and ...
Definition: DopplerScan.h:101
int create_toplist(toplist_t **list, size_t length, size_t size, int(*smaller)(const void *, const void *))
Definition: HeapToplist.c:101
void free_toplist(toplist_t **list)
Definition: HeapToplist.c:139
void qsort_toplist(toplist_t *list, int(*compare)(const void *, const void *))
Definition: HeapToplist.c:241
void * toplist_elem(toplist_t *list, size_t ind)
Definition: HeapToplist.c:185
int insert_into_toplist(toplist_t *list, void *element)
Definition: HeapToplist.c:151
#define LAL_INT4_MAX
lal_errhandler_t lal_errhandler
int LAL_ERR_EXIT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
int k
void LALCheckMemoryLeaks(void)
#define LALCalloc(m, n)
#define LALMalloc(n)
const LALVCSInfoList lalPulsarVCSInfoList
NULL-terminated list of VCS and build information for LALPulsar and its dependencies
ConfigVariables GV
global container for various derived configuration settings
Definition: PredictFstat.c:70
#define STRING(a)
REAL8 XLALFindModeOfPDF1D(const pdf1D_t *pdf)
Find the 'mode' of the probabilty distribution, ie.
void XLALDestroyPDF1D(pdf1D_t *pdf)
Destructor function for 1-D pdf.
#define fprintf
PulsarParamsVector * XLALPulsarParamsFromUserInput(const LALStringVector *UserInput, const LIGOTimeGPS *refTimeDef)
Function to determine the PulsarParamsVector input from a user-input defining CW sources.
const char *const InjectionSourcesHelpString
void XLALDestroyPulsarParamsVector(PulsarParamsVector *ppvect)
Destructor for PulsarParamsVector type.
const MultiLIGOTimeGPSVector * XLALGetFstatInputTimestamps(const FstatInput *input)
Returns the SFT timestamps stored in a FstatInput structure.
Definition: ComputeFstat.c:701
const MultiLALDetector * XLALGetFstatInputDetectors(const FstatInput *input)
Returns the detector information stored in a FstatInput structure.
Definition: ComputeFstat.c:687
const CHAR * XLALGetFstatInputMethodName(const FstatInput *input)
Returns the human-readable name of the -statistic method being used by a FstatInput structure.
Definition: ComputeFstat.c:672
const FstatOptionalArgs FstatOptionalArgsDefaults
Global initializer for setting FstatOptionalArgs to default values.
Definition: ComputeFstat.c:90
int XLALFstatCheckSFTLengthMismatch(const REAL8 Tsft, const REAL8 maxFreq, const REAL8 binaryMaxAsini, const REAL8 binaryMinPeriod, const REAL8 allowedMismatch)
Check that the SFT length does not exceed the result of XLALFstatMaximumSFTLength(),...
Definition: ComputeFstat.c:203
const UserChoices * XLALFstatMethodChoices(void)
Return pointer to a static array of all (available) FstatMethodType choices.
void XLALDestroyFstatInput(FstatInput *input)
Free all memory associated with a FstatInput structure.
Definition: ComputeFstat.c:885
int XLALAppendFstatTiming2File(const FstatInput *input, FILE *fp, BOOLEAN printHeader)
FstatQuantities
Bit-field of -statistic quantities which can be computed by XLALComputeFstat().
Definition: ComputeFstat.h:94
FstatInput * XLALCreateFstatInput(const SFTCatalog *SFTcatalog, const REAL8 minCoverFreq, const REAL8 maxCoverFreq, const REAL8 dFreq, const EphemerisData *ephemerides, const FstatOptionalArgs *optionalArgs)
Create a fully-setup FstatInput structure for computing the -statistic using XLALComputeFstat().
Definition: ComputeFstat.c:359
int XLALComputeFstat(FstatResults **Fstats, FstatInput *input, const PulsarDopplerParams *doppler, const UINT4 numFreqBins, const FstatQuantities whatToCompute)
Compute the -statistic over a band of frequencies.
Definition: ComputeFstat.c:760
void XLALDestroyFstatResults(FstatResults *Fstats)
Free all memory associated with a FstatResults structure.
Definition: ComputeFstat.c:934
@ FMETHOD_RESAMP_GENERIC
Resamp: generic implementation
Definition: ComputeFstat.h:123
@ FSTATQ_2F
Compute multi-detector .
Definition: ComputeFstat.h:96
@ FSTATQ_FAFB
Compute multi-detector and .
Definition: ComputeFstat.h:97
@ FSTATQ_ATOMS_PER_DET
Compute per-SFT -statistic atoms for each detector (Demod only).
Definition: ComputeFstat.h:100
@ FSTATQ_2F_PER_DET
Compute for each detector.
Definition: ComputeFstat.h:98
char * XLALGPSToStr(char *s, const LIGOTimeGPS *t)
int XLALParseMultiLALDetector(MultiLALDetector *detInfo, const LALStringVector *detNames)
Parse string-vectors (typically input by user) of N detector-names for detectors ,...
int XLALParseMultiNoiseFloor(MultiNoiseFloor *multiNoiseFloor, const LALStringVector *sqrtSX, UINT4 numDetectors)
Parse string-vectors (typically input by user) of N detector noise-floors for detectors ,...
int XLALCWSignalCoveringBand(REAL8 *minCoverFreq, REAL8 *maxCoverFreq, const LIGOTimeGPS *time1, const LIGOTimeGPS *time2, const PulsarSpinRange *spinRange, const REAL8 binaryMaxAsini, const REAL8 binaryMinPeriod, const REAL8 binaryMaxEcc)
Determines a frequency band which covers the frequency evolution of a band of CW signals between two ...
int XLALFileClose(LALFILE *file)
LALFILE * XLALFileOpen(const char *path, const char *mode)
int XLALFilePrintf(LALFILE *file, const char *fmt,...)
int XLALEstimatePulsarAmplitudeParams(PulsarCandidate *pulsarParams, const LIGOTimeGPS *FaFb_refTime, const COMPLEX8 Fa, const COMPLEX8 Fb, const AntennaPatternMatrix *Mmunu)
Estimate the amplitude parameters of a pulsar CW signal, given its phase parameters,...
EphemerisData * XLALInitBarycenter(const CHAR *earthEphemerisFile, const CHAR *sunEphemerisFile)
XLAL interface to reading ephemeris files 'earth' and 'sun', and return ephemeris-data in old backwar...
void XLALDestroyEphemerisData(EphemerisData *edat)
Destructor for EphemerisData struct, NULL robust.
#define LAL_TWOPI
#define LAL_REAL8_MAX
#define crect(re, im)
unsigned char BOOLEAN
#define XLAL_INIT_MEM(x)
double complex COMPLEX16
double REAL8
#define XLAL_INIT_DECL(var,...)
char CHAR
uint32_t UINT4
int32_t INT4
float REAL4
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
char char * XLALStringDuplicate(const char *s)
int char * XLALStringAppend(char *s, const char *append)
char * XLALVCSInfoString(const LALVCSInfoList vcs_list, const int verbose, const char *prefix)
BSGLSetup * XLALCreateBSGLSetup(const UINT4 numDetectors, const REAL4 Fstar0sc, const REAL4 oLGX[PULSAR_MAX_DETECTORS], const BOOLEAN useLogCorrection, const UINT4 numSegments)
REAL4 XLALComputeBSGL(const REAL4 twoF, const REAL4 twoFX[PULSAR_MAX_DETECTORS], const BSGLSetup *setup)
Single-bin wrapper of XLALVectorComputeBSGL(), provided for backwards compatibility.
int XLALParseLinePriors(REAL4 oLGX[PULSAR_MAX_DETECTORS], const LALStringVector *oLGX_string)
Parse string-vectors (typically input by user) of N per-detector line-to-Gaussian prior ratios to a ...
const char * LogGetTimestamp(void)
void void int XLALfprintfGSLmatrix(FILE *fp, const char *fmt, const gsl_matrix *gij) _LAL_GCC_VPRINTF_FORMAT_(2)
void void LogPrintfVerbatim(LogLevel_t, const char *format,...) _LAL_GCC_PRINTF_FORMAT_(2
LogLevel_t LogLevel(void)
void LogPrintf(LogLevel_t, const char *format,...) _LAL_GCC_PRINTF_FORMAT_(2
LOG_CRITICAL
LOG_DEBUG
LOG_NORMAL
@ LAL_PMETRIC_NONE
Definition: PtoleMetric.h:96
#define PULSAR_MAX_DETECTORS
maximal number of detectors we can handle (for static arrays of detector quantities)
#define PULSAR_MAX_SPINS
maximal number of spin-parameters (Freq + spindowns) we can handle
@ TRANSIENT_NONE
Note: in this case the window-parameters will be ignored, and treated as rect={data},...
const LALDetector * XLALGetSiteInfo(const CHAR *name)
Find the site geometry-information 'LALDetector' for given a detector name (or prefix).
Definition: SFTnaming.c:218
void XLALDestroySFTCatalog(SFTCatalog *catalog)
Free an 'SFT-catalogue'.
Definition: SFTcatalog.c:329
MultiLIGOTimeGPSVector * XLALReadMultiTimestampsFilesConstrained(const LALStringVector *fnames, const LIGOTimeGPS *minGPS, const LIGOTimeGPS *maxGPS)
Load several timestamps files, return a MultiLIGOTimeGPSVector struct, allocated here.
SFTCatalog * XLALMultiAddToFakeSFTCatalog(SFTCatalog *catalog, const LALStringVector *detectors, const MultiLIGOTimeGPSVector *timestamps)
Multi-detector and multi-timestamp wrapper of XLALAddToFakeSFTCatalog().
Definition: SFTcatalog.c:749
SFTCatalog * XLALSFTdataFind(const CHAR *file_pattern, const SFTConstraints *constraints)
Find the list of SFTs matching the file_pattern and satisfying the given constraints,...
Definition: SFTcatalog.c:71
void XLALDestroyMultiTimestamps(MultiLIGOTimeGPSVector *multiTS)
Destroy a MultiLIGOTimeGPSVector timestamps vector.
INT4 XLALCountIFOsInCatalog(const SFTCatalog *catalog)
Count the number of the unique IFOs in the given catalog.
Definition: SFTcatalog.c:582
SSBprecision
The precision in calculating the barycentric transformation.
Definition: SSBtimes.h:45
const UserChoices SSBprecisionChoices
Static array of all SSBprecision choices, for use by the UserInput module parsing routines.
Definition: SSBtimes.c:41
void XLALDestroyStringVector(LALStringVector *vect)
LALStringVector * XLALAppendString2Vector(LALStringVector *vect, const CHAR *string)
transientFstatMap_t * XLALComputeTransientFstatMap(const MultiFstatAtomVector *multiFstatAtoms, transientWindowRange_t windowRange, BOOLEAN useFReg)
Function to compute transient-window "F-statistic map" over start-time and timescale {t0,...
void XLALDestroyTransientFstatMap(transientFstatMap_t *FstatMap)
Standard destructor for transientFstatMap_t Fully NULL-robust as usual.
int XLALParseTransientWindowName(const char *windowName)
Parse a transient window name string into the corresponding transientWindowType.
int write_transientCandidate_to_fp(LALFILE *fp, const transientCandidate_t *thisCand, const char timeUnit)
Write one line for given transient CW candidate into output file.
int write_MultiFstatAtoms_to_fp(LALFILE *fp, const MultiFstatAtomVector *multiAtoms)
Write multi-IFO F-stat atoms 'multiAtoms' into output stream 'fstat'.
CHAR * XLALPulsarDopplerParams2String(const PulsarDopplerParams *par)
Turn pulsar doppler-params into a single string that can be used for filenames The format is tRefNNNN...
int write_transientCandidateAll_to_fp(LALFILE *fp, const transientCandidate_t *thisCand)
Write full set of t0 and tau grid points for given transient CW candidate into output file.
pdf1D_t * XLALComputeTransientPosterior_t0(transientWindowRange_t windowRange, const transientFstatMap_t *FstatMap)
Compute transient-CW posterior (normalized) on start-time t0, using given type and parameters of tran...
pdf1D_t * XLALComputeTransientPosterior_tau(transientWindowRange_t windowRange, const transientFstatMap_t *FstatMap)
Compute transient-CW posterior (normalized) on timescale tau, using given type and parameters of tran...
REAL8 XLALComputeTransientBstat(transientWindowRange_t windowRange, const transientFstatMap_t *FstatMap)
Compute transient-CW Bayes-factor B_SG = P(x|HypS)/P(x|HypG) (where HypG = Gaussian noise hypothesis)...
int XLALUserVarReadAllInput(BOOLEAN *should_exit, int argc, char *argv[], const LALVCSInfoList vcs_list)
void XLALDestroyUserVars(void)
#define XLALRegisterUvarMember(name, type, option, category,...)
#define UVAR_STR(n)
void CHAR * XLALUserVarGetLog(UserVarLogFormat format)
int XLALUserVarWasSet(const void *cvar)
#define XLALRegisterUvarAuxDataMember(name, type, cdata, option, category,...)
UVAR_LOGFMT_CMDLINE
void XLALDestroyUINT4Vector(UINT4Vector *vector)
UINT4Vector * XLALCreateUINT4Vector(UINT4 length)
struct tm * XLALGPSToUTC(struct tm *utc, INT4 gpssec)
#define xlalErrno
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_MAIN(assertion,...)
#define XLAL_ERROR_MAIN(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_CHECK_NULL(assertion,...)
static _LAL_INLINE_ int XLALIsREAL4FailNaN(REAL4 val)
XLAL_EBADLEN
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFUNC
XLAL_ESYS
XLAL_EINVAL
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
size
size_t numDetectors
This structure contains the per-SFT (weighted) antenna-pattern functions , with the SFT-index,...
Definition: LALComputeAM.h:63
REAL4Vector * b
(weighted) per-SFT antenna-pattern function
Definition: LALComputeAM.h:65
REAL4Vector * a
(weighted) per-SFT antenna-pattern function
Definition: LALComputeAM.h:64
Struct holding the "antenna-pattern" matrix , in terms of the multi-detector scalar product.
Definition: LALComputeAM.h:127
REAL8 Sinv_Tsft
normalization-factor (using single-sided PSD!)
Definition: LALComputeAM.h:133
CHAR name[LALNameLength]
Configuration settings required for and defining a coherent pulsar search.
scanlineWindow_t * scanlineWindow
moving window of candidates on scanline to find local maxima
MultiLALDetector multiIFO
detectors to generate data for (if provided by user and not via noise files)
LALStringVector * detectorIDs
detector ID names, for column headings string
RankingStat_t RankingStatistic
rank candidates according to F or BSGL
UINT4Vector * numSFTsPerDet
number of SFTs per detector, for log strings, etc.
FstatInput * Fstat_in
Fstat input data struct.
CHAR * VCSInfoString
Git version string.
REAL8 Tspan
time spanned by all SFTs
REAL8 Tsft
length of one SFT in seconds
BSGLSetup * BSGLsetup
pre-computed setup for line-robust statistic
PulsarParamsVector * injectionSources
Source parameters to inject: comma-separated list of file-patterns and/or direct config-strings ('{....
DopplerRegion searchRegion
parameter-space region to search over
toplist_t * FstatToplist
sorted 'toplist' of the NumCandidatesToKeep loudest candidates
REAL8 Alpha
sky position alpha in radians
EphemerisData * ephemeris
ephemeris data (from XLALInitBarycenter())
CHAR * logstring
log containing max-info on the whole search setup
DopplerFullScanState * scanState
current state of the Doppler-scan
UINT4 NSFTs
total number of all SFTs used
PulsarDopplerParams stepSizes
user-preferences on Doppler-param step-sizes
MultiLIGOTimeGPSVector * multiTimestamps
a vector of timestamps (only set if provided from dedicated time stamp files)
FstatQuantities Fstat_what
Fstat quantities to compute.
transientWindowRange_t transientWindowRange
search range parameters for transient window
REAL8 Delta
sky position delta in radians
LIGOTimeGPS startTime
starting timestamp of SFTs
BOOLEAN runSearch
whether to actually perform the search, or just generate a grid and/or count templates
LIGOTimeGPS tGPS
GPS timestamps corresponding to this entry.
REAL8 LMST
local mean sidereal time at the detector-location in radians
Timeseries of DetectorState's, representing the detector-info at different timestamps.
DetectorState * data
array of DetectorState entries
UINT4 length
total number of entries
Structure describing a region in paramter-space (a,d,f,f1dot,..).
LALPulsarMetricType metricType
which metric to use if GRID_METRIC
const CHAR * gridFile
filename for sky-grid or full-grid if GRID_FILE_SKYGRID or GRID_FILE_FULLGRID
REAL8 metricMismatch
for GRID_METRIC and GRID_ISOTROPIC
REAL8 extraArgs[3]
extra grid-specific setup arguments
const LALDetector * Detector
Current detector.
LIGOTimeGPS startTime
start-time of the observation
REAL8 Tspan
total time spanned by observation
DopplerRegion searchRegion
Doppler-space region to be covered + scanned.
BOOLEAN projectMetric
project metric on f=const subspace
PulsarDopplerParams stepSizes
user-settings for stepsizes if GRID_FLAT
const EphemerisData * ephemeris
ephemeris-data for numerical metrics
DopplerGridType gridType
which type of grid to generate
PulsarSpins fkdotBand
spin-intervals
Definition: DopplerScan.h:119
CHAR * skyRegionString
sky-region string '(a1,d1), (a2,d2), ..'
Definition: DopplerScan.h:116
LIGOTimeGPS refTime
Definition: DopplerScan.h:117
PulsarSpins fkdot
reference time of definition of Doppler parameters
Definition: DopplerScan.h:118
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
What info do we want to store in our toplist?
COMPLEX16 Fa
complex amplitude Fa
LIGOTimeGPS FaFb_refTime
reference time of Fa and Fb
AntennaPatternMatrix Mmunu
antenna-pattern matrix Mmunu = (h_mu|h_nu)
PulsarDopplerParams doppler
Doppler params of this 'candidate'.
COMPLEX16 Fb
complex amplitude Fb
REAL4 log10BSGL
Line-robust statistic .
UINT4 numDetectors
number of detectors = effective vector length.
REAL4 twoFX[PULSAR_MAX_DETECTORS]
vector of single-detector F-statistic values (array of fixed size)
REAL4 twoF
F-statistic value.
Struct of optional 'advanced level' and (potentially method-specific) arguments to be passed to the ...
Definition: ComputeFstat.h:137
UINT4 randSeed
Random-number seed value used in case of fake Gaussian noise generation (injectSqrtSX)
Definition: ComputeFstat.h:138
MultiNoiseFloor * injectSqrtSX
Single-sided PSD values for fake Gaussian noise to be added to SFT data.
Definition: ComputeFstat.h:144
PulsarParamsVector * injectSources
Vector of parameters of CW signals to simulate and inject.
Definition: ComputeFstat.h:143
UINT4 runningMedianWindow
If SFT noise weights are calculated from the SFTs, the running median window length to use.
Definition: ComputeFstat.h:141
MultiNoiseFloor * assumeSqrtSX
Single-sided PSD values to be used for computing SFT noise weights instead of from a running median o...
Definition: ComputeFstat.h:145
BOOLEAN resampFFTPowerOf2
Resamp: round up FFT lengths to next power of 2; see FstatMethodType.
Definition: ComputeFstat.h:148
REAL8 allowedMismatchFromSFTLength
Optional override for XLALFstatCheckSFTLengthMismatch().
Definition: ComputeFstat.h:149
BOOLEAN collectTiming
a flag to turn on/off the collection of F-stat-method-specific timing-data
Definition: ComputeFstat.h:147
UINT4 Dterms
Number of Dirichlet kernel terms, used by some Demod methods; see FstatMethodType.
Definition: ComputeFstat.h:140
FstatMethodType FstatMethod
Method to use for computing the -statistic.
Definition: ComputeFstat.h:142
SSBprecision SSBprec
Barycentric transformation precision.
Definition: ComputeFstat.h:139
XLALComputeFstat() computed results structure.
Definition: ComputeFstat.h:202
COMPLEX8 * Fb
Definition: ComputeFstat.h:260
AntennaPatternMatrix Mmunu
Antenna pattern matrix , used in computing .
Definition: ComputeFstat.h:228
UINT4 numDetectors
Number of detectors over which the were computed.
Definition: ComputeFstat.h:221
REAL4 * twoFPerDet[PULSAR_MAX_DETECTORS]
If whatWasComputed & FSTATQ_2F_PER_DET is true, the values computed at numFreqBins frequencies space...
Definition: ComputeFstat.h:277
REAL4 * twoF
If whatWasComputed & FSTATQ_2F is true, the multi-detector values computed at numFreqBins frequencie...
Definition: ComputeFstat.h:242
COMPLEX8 * Fa
If whatWasComputed & FSTATQ_PARTS is true, the multi-detector and computed at numFreqBins frequenci...
Definition: ComputeFstat.h:259
LIGOTimeGPS refTimePhase
For performance reasons the global phase of all returned 'Fa' and 'Fb' quantities (Fa,...
Definition: ComputeFstat.h:211
MultiFstatAtomVector ** multiFatoms
If whatWasComputed & FSTATQ_ATOMS_PER_DET is true, the per-SFT -statistic multi-atoms computed at nu...
Definition: ComputeFstat.h:297
LALFrDetector frDetector
CHAR prefix[3]
REAL8 deltaT
'length' of each timestamp (e.g.
Definition: SFTfileIO.h:194
A multi-detector vector of FstatAtomVector.
Definition: ComputeFstat.h:187
array of detectors definitions 'LALDetector'
UINT4 length
number of detectors
LALDetector sites[PULSAR_MAX_DETECTORS]
array of site information
A collection of (multi-IFO) LIGOTimeGPSVector time-stamps vectors.
Definition: SFTfileIO.h:198
UINT4 length
number of timestamps vectors or ifos
Definition: SFTfileIO.h:202
LIGOTimeGPSVector ** data
timestamps vector for each ifo
Definition: SFTfileIO.h:203
array of detector-specific 'noise floors' (ie PSD values), assumed constant over the frequency-band o...
One noise-weight (number) per SFT (therefore indexed over IFOs and SFTs.
Definition: PSDutils.h:71
A collection of SFT vectors – one for each IFO in a multi-IFO search.
Definition: SFTfileIO.h:179
REAL8 aCross
Signal amplitude (cross)
REAL8 psi
polarization angle psi
REAL8 aPlus
Signal amplitude (plus)
REAL8 phi0
initial signal-phase (at some reference time)
Type containing a "candidate": parameter-space point with estimated errors and Fstat-value/significan...
PulsarAmplitudeParams dAmp
amplitude-parameters and error-estimates
PulsarAmplitudeParams Amp
gsl_matrix * AmpFisherMatrix
Fisher-matrix of amplitude-subspace: has more info than dAmp!
PulsarDopplerParams Doppler
Type containing the 'Doppler-parameters' affecting the time-evolution of the phase.
REAL8 period
Binary: orbital period (sec)
LIGOTimeGPS tp
Binary: time of observed periapsis passage (in SSB)
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ... ] where fkdot = d^kFreq/dt^k.
REAL8 Delta
Sky position: DEC (latitude) in equatorial coords and radians.
LIGOTimeGPS refTime
Reference time of pulsar parameters (in SSB!)
REAL8 Alpha
Sky position: RA (longitude) in equatorial coords and radians.
REAL8 ecc
Binary: orbital eccentricity.
REAL8 asini
Binary: projected, normalized orbital semi-major axis (s).
REAL8 argp
Binary: argument of periapsis (radians)
Straightforward vector type of N PulsarParams structs.
Contains a "spin-range", ie spins and corresponding bands at a given (SSB) reference GPS-time .
PulsarSpins fkdot
Vector of spin-values .
LIGOTimeGPS refTime
SSB reference GPS-time at which spin-range is defined.
PulsarSpins fkdotBand
Vector of spin-bands , MUST be same length as fkdot.
REAL4 * data
An "SFT-catalogue": a vector of SFTdescriptors, as returned by XLALSFTdataFind()
Definition: SFTfileIO.h:238
SFTDescriptor * data
array of data-entries describing matched SFTs
Definition: SFTfileIO.h:243
UINT4 length
number of SFTs in catalog
Definition: SFTfileIO.h:242
'Constraints' for SFT-matching: which detector, within which time-stretch and which timestamps exactl...
Definition: SFTfileIO.h:212
SFTtype header
SFT-header info.
Definition: SFTfileIO.h:228
UINT4 * data
moving 'Scanline window' of candidates on the scan-line, which is used to find local 1D maxima.
FstatCandidate * window
array holding candidates
FstatCandidate * center
pointer to middle candidate in window
Struct holding various timing measurements and relevant search parameters.
UINT4 tauMin
shortest transient timescale [s]
UINT4 NSFTs
total number of SFTs
REAL8 tauF0
Demod timing constant = time per template per SFT.
UINT4 NTau
number of transient timescale steps in FstatMap matrix
UINT4 NFreq
number of frequency bins
REAL8 tauTransFstatMap
time to compute transient-search Fstatistic-map over {t0, tau} [s]
UINT4 tauMax
longest transient timescale [s]
UINT4 NStart
number of transient start-time steps in FstatMap matrix
REAL8 tauTemplate
total loop time per template, includes candidate-handling (transient stats, toplist etc)
REAL8 tauFstat
time to compute one Fstatistic over full data-duration (NSFT atoms) [in seconds]
REAL8 tauTransMarg
time to marginalize the Fstat-map to compute transient-search Bayes [s]
size_t elems
Definition: HeapToplist.h:37
Struct holding a transient CW candidate.
Struct defining a range of transient windows.
UINT4 tauBand
range of transient timescales tau to search, in seconds
UINT4 dtau
stepsize to search tau-range with, in seconds
UINT4 tau
shortest transient timescale tau in seconds
UINT4 t0
earliest GPS start-time 't0' in seconds
UINT4 dt0
stepsize to search t0-range with, in seconds
transientWindowType_t type
window-type: none, rectangular, exponential, ....
UINT4 t0Band
range of start-times 't0' to search, in seconds