LALPulsar  6.1.0.1-b72065a
ComputeFstat.c
Go to the documentation of this file.
1 //
2 // Copyright (C) 2012--2015 Karl Wette
3 // Copyright (C) 2005--2007, 2010, 2014 Reinhard Prix
4 // Copyright (C) 2007 Chris Messenger
5 // Copyright (C) 2006 John T. Whelan, Badri Krishnan
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with with program; see the file COPYING. If not, write to the
19 // Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 // MA 02110-1301 USA
21 //
22 
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <gsl/gsl_math.h>
27 
28 #include "ComputeFstat_internal.h"
29 
30 #ifdef LALPULSAR_CUDA_ENABLED
31 #include <cuda.h>
32 #include <cuda_runtime_api.h>
33 #endif
34 
35 #include <lal/LALString.h>
36 #include <lal/LALSIMD.h>
37 #include <lal/NormalizeSFTRngMed.h>
38 #include <lal/ExtrapolatePulsarSpins.h>
39 #include <lal/VectorMath.h>
40 
41 // ---------- Internal struct definitions ---------- //
42 
43 // Internal definition of input data structure
44 struct tagFstatInput {
45  REAL8 Tsft; // Length of input SFTs (for maximum length checking)
46  REAL8 minFreqFull; // Minimum frequency loaded from input SFTs
47  REAL8 maxFreqFull; // Maximum frequency loaded from input SFTs
48  int singleFreqBin; // True if XLALComputeFstat() can only compute a single frequency bin, due to zero dFreq being passed to XLALCreateFstatInput()
49  FstatMethodType method; // Method to use for computing the F-statistic
50  FstatCommon common; // Common input data
51  int *workspace_refcount; // Reference counter for the shared workspace 'common.workspace'
52  FstatMethodFuncs method_funcs; // Function pointers for F-statistic method
53  void *method_data; // F-statistic method data
54 };
55 
56 // ---------- Internal prototypes ---------- //
57 
58 int XLALSetupFstatDemod( void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs );
59 int XLALGetFstatTiming_Demod( const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel );
60 void *XLALFstatInputTimeslice_Demod( const void *method_data, const UINT4 iStart[PULSAR_MAX_DETECTORS], const UINT4 iEnd[PULSAR_MAX_DETECTORS] );
61 void XLALDestroyFstatInputTimeslice_Demod( void *method_data );
62 
63 int XLALSetupFstatResampGeneric( void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs );
64 int XLALExtractResampledTimeseries_ResampGeneric( MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, void *method_data );
65 int XLALGetFstatTiming_ResampGeneric( const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel );
66 
67 #ifdef LALPULSAR_CUDA_ENABLED
68 int XLALSetupFstatResampCUDA( void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs );
69 int XLALExtractResampledTimeseries_ResampCUDA( MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, void *method_data );
70 int XLALGetFstatTiming_ResampCUDA( const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel );
71 #endif
72 
73 static int XLALSelectBestFstatMethod( FstatMethodType *method );
75 
76 // ---------- Constant variable definitions ---------- //
77 
78 static const char *const FstatMethodNames[FMETHOD_END] = {
79  [FMETHOD_DEMOD_GENERIC] = "DemodGeneric",
80  [FMETHOD_DEMOD_OPTC] = "DemodOptC",
81  [FMETHOD_DEMOD_ALTIVEC] = "DemodAltivec",
82  [FMETHOD_DEMOD_SSE] = "DemodSSE",
83  [FMETHOD_DEMOD_BEST] = "DemodBest",
84 
85  [FMETHOD_RESAMP_GENERIC] = "ResampGeneric",
86  [FMETHOD_RESAMP_CUDA] = "ResampCUDA",
87  [FMETHOD_RESAMP_BEST] = "ResampBest",
88 };
89 
91  .randSeed = 0,
92  .SSBprec = SSBPREC_RELATIVISTICOPT,
93  .Dterms = 8,
94  .runningMedianWindow = 101,
95  .FstatMethod = FMETHOD_DEMOD_BEST,
96  .injectSources = NULL,
97  .injectSqrtSX = NULL,
98  .assumeSqrtSX = NULL,
99  .prevInput = NULL,
100  .collectTiming = 0,
101  .resampFFTPowerOf2 = 1
102 };
103 
104 static const char FstatTimingGenericHelp[] =
105  "%%%% ----- Generic F-stat timing model (all times in seconds) [see https://dcc.ligo.org/LIGO-T1600531-v4 for details] -----\n"
106  "%%%% tauF_eff: effective total time per F-stat call to XLALComputeFstat() per detector per output frequency bin\n"
107  "%%%% tauF_core: core time per output frequency bin per detector, excluding time to compute the buffer\n"
108  "%%%% tauF_buffer: time per detector per frequency bin to re-compute all buffered quantities once\n"
109  "%%%% NFbin: (average over F-stat calls) number of F-stat output frequency bins\n"
110  "%%%% Ndet: number of detectors\n"
111  "%%%%\n"
112  "%%%% => generic F-stat timing:\n"
113  "%%%% tauF_eff = tauF_core + b * tauF_buffer\n"
114  "%%%% where 'b' denotes the fraction of times per call to XLALComputeFstat() the buffer needed to be recomputed\n"
115  "%%%%\n"
116  "%%%% NCalls: number of F-stat calls we average over\n"
117  "%%%% NBufferMisses: number of times the buffer needed to be recomputed\n"
118  "%%%% ==> b = NBufferMisses / NCalls\n"
119  "%%%% All timing numbers are averaged over repeated calls to XLALComputeFstat(for fixed-setup).\n"
120  "";
121 
122 
123 // ==================== Function definitions =================== //
124 
125 /// \addtogroup ComputeFstat_h
126 /// @{
127 
128 ///
129 /// Compute the maximum SFT length that can safely be used as input to XLALComputeFstat(), given
130 /// the desired range limits in search parameters.
131 ///
132 /// The \f$ \mathcal{F} \f$ -statistic algorithms implemented in this module assume that the input
133 /// SFTs supplied to XLALCreateFstatInput() are of such a length that, within the time span of
134 /// each SFT, the spectrum of any CW signal being searched for will be mostly contained within
135 /// one SFT bin:
136 /// * The \a Demod algorithm makes explicit use of this assumption in order to sum up only a few
137 /// bins in the Dirichlet kernel, thereby speeding up the computation.
138 /// * While the \a Resamp algorithm is in principle independent of the SFT length (as the data
139 /// are converted from SFTs back into a time series), in practise it makes use of this assumption
140 /// for convenience to linearly approximate the phase over the time span of a single SFT.
141 ///
142 /// In order for this assumption to be valid, the SFT bins must be of a certain minimum size, and
143 /// hence the time spans of the SFTs must be of a certain maximum length. This maximum length is
144 /// dependent upon the parameter space being searched: searches for isolated CW sources rarely
145 /// encounter this restriction by using standard 1800-second SFTs, but searches for CW sources in
146 /// binary systems typically must use shorter SFTs.
147 ///
148 /// An expression giving the maximum allowed SFT length is given by \cite LeaciPrix2015 , eq. (C2):
149 /// \f[
150 /// T_{\textrm{SFT-max}} = \sqrt{ \frac{
151 /// 6 \sqrt{ 5 \mu_{\textrm{SFT}} }
152 /// }{
153 /// \pi (a \sin\iota / c)_{\textrm{max}} f_{\textrm{max}} \Omega_{\textrm{max}}^2
154 /// } } \,,
155 /// \f]
156 /// This function computes this expression with a user-given acceptable
157 /// maximum mismatch \f$ \mu_{\textrm{SFT}} \f$ , and
158 /// \f$ (a \sin\iota / c)_{\textrm{max}} \f$ and \f$ \Omega_{\textrm{max}} \f$ set to either the binary
159 /// motion of the source, as specified by \p binaryMaxAsini and \p binaryMinPeriod, or the sidereal
160 /// motion of the Earth, i.e. with \f$ (a \sin\iota / c) \sim 0.02~\textrm{s} \f$ and
161 /// \f$ \Omega \sim 2\pi / 1~\textrm{day} \f$ .
162 ///
163 REAL8 XLALFstatMaximumSFTLength( const REAL8 maxFreq, /**< [in] Maximum signal frequency */
164  const REAL8 binaryMaxAsini, /**< [in] Maximum projected semi-major axis a*sini/c (= 0 for isolated sources) */
165  const REAL8 binaryMinPeriod, /**< [in] Minimum orbital period (s) */
166  const REAL8 mu_SFT /**< [in] Maximum allowed fractional mismatch */
167  )
168 {
169 
170  // Check input
171  XLAL_CHECK_REAL8( maxFreq > 0, XLAL_EINVAL );
172  XLAL_CHECK_REAL8( binaryMaxAsini >= 0, XLAL_EINVAL );
173  XLAL_CHECK_REAL8( ( binaryMaxAsini == 0 ) || ( binaryMinPeriod > 0 ), XLAL_EINVAL ); // if binary: P>0
174  XLAL_CHECK_REAL8( mu_SFT >= 0, XLAL_EINVAL );
175 
176  // Compute maximum allowed SFT length due to sidereal motion of the Earth
177  const REAL8 earthAsini = LAL_REARTH_SI / LAL_C_SI;
178  const REAL8 earthOmega = LAL_TWOPI / LAL_DAYSID_SI;
179  const REAL8 Tsft_max_earth = sqrt( ( 6.0 * sqrt( 5.0 * mu_SFT ) ) / ( LAL_PI * earthAsini * maxFreq * earthOmega * earthOmega ) );
180  if ( binaryMaxAsini == 0 ) {
181  return Tsft_max_earth;
182  }
183 
184  // Compute maximum allowed SFT length due to binary motion of the source
185  const REAL8 binaryMaxOmega = LAL_TWOPI / binaryMinPeriod;
186  const REAL8 Tsft_max_binary = sqrt( ( 6.0 * sqrt( 5.0 * mu_SFT ) ) / ( LAL_PI * binaryMaxAsini * maxFreq * binaryMaxOmega * binaryMaxOmega ) );
187 
188  // Compute maximum allowed SFT length
189  const REAL8 Tsft_max = GSL_MIN( Tsft_max_earth, Tsft_max_binary );
190 
191  return Tsft_max;
192 
193 } // XLALFstatMaximumSFTLength()
194 
195 ///
196 /// Check that the SFT length \f$ T_{\textrm{SFT}} \f$ does not exceed the result
197 /// of XLALFstatMaximumSFTLength(), in which case a large unexpected mismatch
198 /// would be produced.
199 /// See documentation of that function for parameter dependence.
200 /// If allowedMismatch==0, the default value is taken
201 /// from #DEFAULT_MAX_MISMATCH_FROM_SFT_LENGTH .
202 ///
203 int XLALFstatCheckSFTLengthMismatch( const REAL8 Tsft, /**< [in] actual SFT length */
204  const REAL8 maxFreq, /**< [in] Maximum signal frequency */
205  const REAL8 binaryMaxAsini, /**< [in] Maximum projected semi-major axis a*sini/c (= 0 for isolated sources) */
206  const REAL8 binaryMinPeriod, /**< [in] Minimum orbital period (s) */
207  const REAL8 allowedMismatch /**< [in] Maximum allowed fractional mismatch */
208  )
209 {
210 
211  // Use user-given maximum allowed mismatch, or fall back to hardcoded default
212  XLAL_CHECK_REAL8( allowedMismatch >= 0, XLAL_EINVAL );
214  if ( allowedMismatch > 0 ) {
215  mu_SFT = allowedMismatch;
216  }
217 
218  const REAL8 Tsft_max = XLALFstatMaximumSFTLength( maxFreq, binaryMaxAsini, binaryMinPeriod, mu_SFT );
219  XLAL_CHECK( !XLALIsREAL8FailNaN( Tsft_max ), XLAL_EINVAL );
220  XLAL_CHECK( Tsft < Tsft_max, XLAL_EINVAL, "Length of input SFTs (%g s) must be less than %g s for CW signal with frequency = %g, binary asini = %g, period = %g to stay below mismatch of %g.", Tsft, Tsft_max, maxFreq, binaryMaxAsini, binaryMinPeriod, mu_SFT );
221 
222  return XLAL_SUCCESS;
223 
224 } // XLALFstatCheckSFTLengthMismatch()
225 
226 ///
227 /// Create a \c FstatInputVector of the given length, for example for setting up
228 /// F-stat searches over several segments.
229 ///
231 XLALCreateFstatInputVector( const UINT4 length ///< [in] Length of the \c FstatInputVector.
232  )
233 {
234  // Allocate and initialise vector container
235  FstatInputVector *inputs;
236  XLAL_CHECK_NULL( ( inputs = XLALCalloc( 1, sizeof( *inputs ) ) ) != NULL, XLAL_ENOMEM );
237  inputs->length = length;
238 
239  // Allocate and initialise vector data
240  if ( inputs->length > 0 ) {
241  XLAL_CHECK_NULL( ( inputs->data = XLALCalloc( inputs->length, sizeof( inputs->data[0] ) ) ) != NULL, XLAL_ENOMEM );
242  }
243 
244  return inputs;
245 
246 } // XLALCreateFstatInputVector()
247 
248 ///
249 /// Free all memory associated with a \c FstatInputVector structure.
250 ///
251 void
252 XLALDestroyFstatInputVector( FstatInputVector *inputs ///< [in] \c FstatInputVector structure to be freed.
253  )
254 {
255  if ( inputs == NULL ) {
256  return;
257  }
258 
259  if ( inputs->data ) {
260  for ( UINT4 i = 0; i < inputs->length; ++i ) {
261  XLALDestroyFstatInput( inputs->data[i] );
262  }
263  XLALFree( inputs->data );
264  }
265 
266  XLALFree( inputs );
267 
268  return;
269 
270 } // XLALDestroyFstatInputVector()
271 
272 ///
273 /// Create a \c FstatAtomVector of the given length.
274 ///
276 XLALCreateFstatAtomVector( const UINT4 length ///< [in] Length of the \c FstatAtomVector.
277  )
278 {
279  // Allocate and initialise vector container
280  FstatAtomVector *atoms;
281  XLAL_CHECK_NULL( ( atoms = XLALCalloc( 1, sizeof( *atoms ) ) ) != NULL, XLAL_ENOMEM );
282  atoms->length = length;
283 
284  // Allocate and initialise vector data
285  if ( atoms->length > 0 ) {
286  XLAL_CHECK_NULL( ( atoms->data = XLALCalloc( atoms->length, sizeof( atoms->data[0] ) ) ) != NULL, XLAL_ENOMEM );
287  }
288 
289  return atoms;
290 
291 } // XLALCreateFstatAtomVector()
292 
293 ///
294 /// Free all memory associated with a \c FstatAtomVector structure.
295 ///
296 void
297 XLALDestroyFstatAtomVector( FstatAtomVector *atoms ///< [in] \c FstatAtomVector structure to be freed.
298  )
299 {
300  if ( atoms == NULL ) {
301  return;
302  }
303 
304  if ( atoms->data ) {
305  XLALFree( atoms->data );
306  }
307  XLALFree( atoms );
308 
309  return;
310 
311 } // XLALDestroyFstatAtomVector()
312 
313 ///
314 /// Create a \c MultiFstatAtomVector of the given length.
315 ///
317 XLALCreateMultiFstatAtomVector( const UINT4 length ///< [in] Length of the \c MultiFstatAtomVector.
318  )
319 {
320  // Allocate and initialise vector container
321  MultiFstatAtomVector *multiAtoms;
322  XLAL_CHECK_NULL( ( multiAtoms = XLALCalloc( 1, sizeof( *multiAtoms ) ) ) != NULL, XLAL_ENOMEM );
323  multiAtoms->length = length;
324 
325  // Allocate and initialise vector data
326  if ( multiAtoms->length > 0 ) {
327  XLAL_CHECK_NULL( ( multiAtoms->data = XLALCalloc( multiAtoms->length, sizeof( multiAtoms->data[0] ) ) ) != NULL, XLAL_ENOMEM );
328  }
329 
330  return multiAtoms;
331 
332 } // XLALCreateMultiFstatAtomVector()
333 
334 ///
335 /// Free all memory associated with a \c MultiFstatAtomVector structure.
336 ///
337 void
338 XLALDestroyMultiFstatAtomVector( MultiFstatAtomVector *multiAtoms ///< [in] \c MultiFstatAtomVector structure to be freed.
339  )
340 {
341  if ( multiAtoms == NULL ) {
342  return;
343  }
344 
345  for ( UINT4 X = 0; X < multiAtoms->length; ++X ) {
346  XLALDestroyFstatAtomVector( multiAtoms->data[X] );
347  }
348  XLALFree( multiAtoms->data );
349  XLALFree( multiAtoms );
350 
351  return;
352 
353 } // XLALDestroyMultiFstatAtomVector()
354 
355 ///
356 /// Create a fully-setup \c FstatInput structure for computing the \f$ \mathcal{F} \f$ -statistic using XLALComputeFstat().
357 ///
358 FstatInput *
359 XLALCreateFstatInput( const SFTCatalog *SFTcatalog, /**< [in] Catalog of SFTs to either load from files, or generate in memory.
360  The \c locator field of each \c SFTDescriptor must be \c !=NULL for SFT loading, and \c ==NULL for SFT generation. **/
361  const REAL8 minCoverFreq, ///< [in] Minimum instantaneous frequency which will be covered over the SFT time span.
362  const REAL8 maxCoverFreq, ///< [in] Maximum instantaneous frequency which will be covered over the SFT time span.
363  const REAL8 dFreq, ///< [in] Requested spacing of \f$ \mathcal{F} \f$ -statistic frequency bins. May be zero \e only for single-frequency searches.
364  const EphemerisData *ephemerides, ///< [in] Ephemerides for the time-span of the SFTs.
365  const FstatOptionalArgs *optionalArgs ///< [in] Optional 'advanced-level' and method-specific extra arguments; NULL: use defaults from FstatOptionalArgsDefaults.
366  )
367 {
368  // Check catalog
369  XLAL_CHECK_NULL( SFTcatalog != NULL, XLAL_EINVAL );
370  XLAL_CHECK_NULL( SFTcatalog->length > 0, XLAL_EINVAL );
371  XLAL_CHECK_NULL( SFTcatalog->data != NULL, XLAL_EINVAL );
372  for ( UINT4 i = 1; i < SFTcatalog->length; ++i ) {
373  XLAL_CHECK_NULL( ( SFTcatalog->data[0].locator == NULL ) == ( SFTcatalog->data[i].locator == NULL ), XLAL_EINVAL,
374  "All 'locator' fields of SFTDescriptors in 'SFTcatalog' must be either NULL or !NULL." );
375  }
376 
377  // Check remaining required parameters
378  XLAL_CHECK_NULL( isfinite( minCoverFreq ) && ( minCoverFreq > 0 ) && isfinite( maxCoverFreq ) && ( maxCoverFreq > 0 ), XLAL_EINVAL, "Check failed: minCoverFreq=%f and maxCoverFreq=%f must be finite and positive!", minCoverFreq, maxCoverFreq );
379  XLAL_CHECK_NULL( maxCoverFreq > minCoverFreq, XLAL_EINVAL, "Check failed: maxCoverFreq>minCoverFreq (%f<=%f)!", maxCoverFreq, minCoverFreq );
381  XLAL_CHECK_NULL( dFreq >= 0, XLAL_EINVAL );
382 
383  // Create local copy of optional arguments, or use defaults if not given
384  FstatOptionalArgs optArgs;
385  if ( optionalArgs != NULL ) {
386  optArgs = *optionalArgs;
387  } else {
388  optArgs = FstatOptionalArgsDefaults;
389  }
390 
391  // Check optional arguments sanity
392  XLAL_CHECK_NULL( ( optArgs.injectSources == NULL ) || ( ( optArgs.injectSources->length > 0 ) && ( optArgs.injectSources->data != NULL ) ), XLAL_EINVAL );
393  XLAL_CHECK_NULL( ( optArgs.injectSqrtSX == NULL ) || ( optArgs.injectSqrtSX->length > 0 ), XLAL_EINVAL );
394  XLAL_CHECK_NULL( ( optArgs.assumeSqrtSX == NULL ) || ( optArgs.assumeSqrtSX->length > 0 ), XLAL_EINVAL );
396 
397  // Check optional Fstat method type argument
398  XLAL_CHECK_NULL( ( FMETHOD_START < optArgs.FstatMethod ) && ( optArgs.FstatMethod < FMETHOD_END ), XLAL_EINVAL );
401 
402  //
403  // Parse which F-statistic method to use, and set these variables:
404  // - extraBinsMethod: any extra SFT frequency bins required by the method
405  // - setupFuncMethod: method setup function, called at end of XLALCreateFstatInput()
406  //
407  int extraBinsMethod = 0;
408  int ( *setupFuncMethod )( void **, FstatCommon *, FstatMethodFuncs *, MultiSFTVector *, const FstatOptionalArgs * );
409  switch ( optArgs.FstatMethod ) {
410 
411  case FMETHOD_DEMOD_GENERIC: // Demod: generic C hotloop
412  XLAL_CHECK_NULL( optArgs.Dterms > 0, XLAL_EINVAL );
413  extraBinsMethod = optArgs.Dterms;
414  setupFuncMethod = XLALSetupFstatDemod;
415  break;
416 
417  case FMETHOD_DEMOD_OPTC: // Demod: gptimized C hotloop using Akos' algorithm
418  XLAL_CHECK_NULL( optArgs.Dterms <= 20, XLAL_EINVAL, "Selected Hotloop variant 'OptC' only works for Dterms <= 20, got %d\n", optArgs.Dterms );
419  extraBinsMethod = optArgs.Dterms;
420  setupFuncMethod = XLALSetupFstatDemod;
421  break;
422 
423  case FMETHOD_DEMOD_ALTIVEC: // Demod: Altivec hotloop variant
424  XLAL_CHECK_NULL( optArgs.Dterms == 8, XLAL_EINVAL, "Selected Hotloop variant 'Altivec' only works for Dterms == 8, got %d\n", optArgs.Dterms );
425  extraBinsMethod = optArgs.Dterms;
426  setupFuncMethod = XLALSetupFstatDemod;
427  break;
428 
429  case FMETHOD_DEMOD_SSE: // Demod: SSE hotloop with precalc divisors
430  XLAL_CHECK_NULL( optArgs.Dterms == 8, XLAL_EINVAL, "Selected Hotloop variant 'SSE' only works for Dterms == 8, got %d\n", optArgs.Dterms );
431  extraBinsMethod = optArgs.Dterms;
432  setupFuncMethod = XLALSetupFstatDemod;
433  break;
434 
435  case FMETHOD_RESAMP_CUDA: // Resamp: CUDA implementation
436 #ifdef LALPULSAR_CUDA_ENABLED
437  extraBinsMethod = 8; // use 8 extra bins to give better agreement with Demod(w Dterms=8) near the boundaries
438  setupFuncMethod = XLALSetupFstatResampCUDA;
439 #else
440  XLAL_ERROR_NULL( XLAL_EFAILED, "Unexpected selection of unavailable optArgs.FstatMethod='%d'\n", optArgs.FstatMethod );
441 #endif
442  break;
443 
444  case FMETHOD_RESAMP_GENERIC: // Resamp: generic implementation
445  extraBinsMethod = 8; // use 8 extra bins to give better agreement with Demod(w Dterms=8) near the boundaries
446  setupFuncMethod = XLALSetupFstatResampGeneric;
447  break;
448 
449  default:
450  XLAL_ERROR_NULL( XLAL_EFAILED, "Missing switch case for optArgs.FstatMethod='%d'\n", optArgs.FstatMethod );
451  }
452  XLAL_CHECK_NULL( extraBinsMethod >= 0, XLAL_EFAILED );
453  XLAL_CHECK_NULL( setupFuncMethod != NULL, XLAL_EFAILED );
454 
455  // Determine whether to load and/or generate SFTs
456  const BOOLEAN loadSFTs = ( SFTcatalog->data[0].locator != NULL );
457  const BOOLEAN generateSFTs = ( optArgs.injectSources != NULL ) || ( optArgs.injectSqrtSX != NULL );
458  XLAL_CHECK_NULL( loadSFTs || generateSFTs, XLAL_EINVAL, "Can neither load nor generate SFTs with given parameters" );
459 
460  // Create top-level input data struct
461  FstatInput *input;
462  XLAL_CHECK_NULL( ( input = XLALCalloc( 1, sizeof( *input ) ) ) != NULL, XLAL_ENOMEM );
463  input->method = optArgs.FstatMethod;
464  FstatCommon *common = &input->common; // handy shortcut
465 
466  // Determine whether we can re-used workspace from a previous call to XLALCreateFstatInput()
467  if ( optArgs.prevInput != NULL ) {
468 
469  // Check that F-stat method being used agrees with 'prevInput'
470  XLAL_CHECK_NULL( optArgs.prevInput->method == input->method, XLAL_EFAILED, "Cannot use workspace from 'prevInput' with different FstatMethod '%d'!='%d'", optArgs.prevInput->method, input->method );
471 
472  // Get pointers to workspace and workspace reference counter in 'prevInput'
473  common->workspace = optArgs.prevInput->common.workspace;
474  input->workspace_refcount = optArgs.prevInput->workspace_refcount;
475 
476  // Increment reference count
477  ++( *input->workspace_refcount );
478  XLALPrintInfo( "%s: re-using workspace from 'optionalArgs.prevInput', reference count = %i\n", __func__, *input->workspace_refcount );
479 
480  } else {
481 
482  // Workspace must be allocated by method setup function
483  common->workspace = NULL;
484 
485  // Allocate memory for reference counter; when reference count reaches 0, memory must be destroyed
486  XLAL_CHECK_NULL( ( input->workspace_refcount = XLALCalloc( 1, sizeof( *input->workspace_refcount ) ) ) != NULL, XLAL_ENOMEM );
487 
488  // Initialise reference counter to 1
489  ( *input->workspace_refcount ) = 1;
490  XLALPrintInfo( "%s: allocating new workspace, reference count = %i\n", __func__, *input->workspace_refcount );
491 
492  }
493 
494  // Determine the length of an SFT
495  input->Tsft = 1.0 / SFTcatalog->data[0].header.deltaF;
496 
498 
499  // Compute the mid-time and time-span of the SFTs
500  double Tspan = 0;
501  {
502  const LIGOTimeGPS startTime = SFTcatalog->data[0].header.epoch;
503  const LIGOTimeGPS endTime = SFTcatalog->data[SFTcatalog->length - 1].header.epoch;
504  common->midTime = startTime;
505  Tspan = input->Tsft + XLALGPSDiff( &endTime, &startTime );
506  XLALGPSAdd( &common->midTime, 0.5 * Tspan );
507  }
508 
509  // Determine the frequency spacing: if dFreq==0, default to 1.0/Tspan and set singleFreqBin==true
510  input->singleFreqBin = ( dFreq == 0 );
511  common->dFreq = input->singleFreqBin ? 1.0 / Tspan : dFreq;
512 
513  // Determine the frequency band required by each method 'minFreqMethod',
514  // as well as the frequency band required to load or generate initial SFTs for 'minFreqFull'
515  // the difference being that for noise-floor estimation, we need extra frequency-bands for the
516  // running median
517  REAL8 minFreqMethod, maxFreqMethod;
518  {
519  // Number of extra frequency bins required by: F-stat method, and running median
520  int extraBinsFull = extraBinsMethod + optArgs.runningMedianWindow / 2 + 1; // NOTE: running-median window needed irrespective of assumeSqrtSX!
521 
522  // Extend frequency range by number of extra bins times SFT bin width
523  const REAL8 extraFreqMethod = extraBinsMethod / input->Tsft;
524  minFreqMethod = minCoverFreq - extraFreqMethod;
525  maxFreqMethod = maxCoverFreq + extraFreqMethod;
526 
527  const REAL8 extraFreqFull = extraBinsFull / input->Tsft;
528  input->minFreqFull = minCoverFreq - extraFreqFull;
529  input->maxFreqFull = maxCoverFreq + extraFreqFull;
530 
531  } // end: block to determine frequency-bins range
532 
533  // Load SFTs, if required, and extract detectors and timestamps
534  MultiSFTVector *multiSFTs = NULL;
535  if ( loadSFTs ) {
536  // Load all SFTs at once
537  XLAL_CHECK_NULL( ( multiSFTs = XLALLoadMultiSFTs( SFTcatalog, input->minFreqFull, input->maxFreqFull ) ) != NULL, XLAL_EFUNC );
538 
539  // Extract detectors and timestamps from SFTs
542 
543  } else {
544  // Create a multi-view of SFT catalog
545  MultiSFTCatalogView *multiSFTcatalog;
546  XLAL_CHECK_NULL( ( multiSFTcatalog = XLALGetMultiSFTCatalogView( SFTcatalog ) ) != NULL, XLAL_EFUNC );
547 
548  // Extract detectors and timestamps from multi-view of SFT catalog
550  XLAL_CHECK_NULL( ( common->multiTimestamps = XLALTimestampsFromMultiSFTCatalogView( multiSFTcatalog ) ) != NULL, XLAL_EFUNC );
551 
552  // Cleanup
553  XLALDestroyMultiSFTCatalogView( multiSFTcatalog );
554  } // end: if !loadSFTs
555 
556  // Check length of multi-noise floor arrays
557  XLAL_CHECK_NULL( ( optArgs.injectSqrtSX == NULL ) || ( optArgs.injectSqrtSX->length == common->detectors.length ), XLAL_EINVAL );
558  XLAL_CHECK_NULL( ( optArgs.assumeSqrtSX == NULL ) || ( optArgs.assumeSqrtSX->length == common->detectors.length ), XLAL_EINVAL );
559 
560  // Generate SFTs with injections and noise, if required
561  if ( generateSFTs ) {
562  // Initialise parameters struct for XLALCWMakeFakeMultiData()
563  CWMFDataParams XLAL_INIT_DECL( MFDparams );
564  if ( multiSFTs != NULL ) {
565  const SFTtype *sft = &multiSFTs->data[0]->data[0];
566  MFDparams.fMin = sft->f0;
567  MFDparams.Band = sft->data->length * sft->deltaF;
568  } else {
569  MFDparams.fMin = input->minFreqFull;
570  MFDparams.Band = input->maxFreqFull - input->minFreqFull;
571  }
572  MFDparams.multiIFO = common->detectors;
573  MFDparams.multiTimestamps = common->multiTimestamps;
574  MFDparams.randSeed = optArgs.randSeed;
575  MFDparams.sourceDeltaT = optArgs.sourceDeltaT;
576 
577  // Set noise floors if sqrtSX is given; otherwise noise floors are zero
578  if ( optArgs.injectSqrtSX != NULL ) {
579  MFDparams.multiNoiseFloor = *( optArgs.injectSqrtSX );
580  } else {
581  MFDparams.multiNoiseFloor.length = common->detectors.length;
582  }
583 
584  // Generate SFTs with injections
585  MultiSFTVector *fakeMultiSFTs = NULL;
586  XLAL_CHECK_NULL( XLALCWMakeFakeMultiData( &fakeMultiSFTs, NULL, optArgs.injectSources, &MFDparams, ephemerides ) == XLAL_SUCCESS, XLAL_EFUNC );
587 
588  // If SFTs were loaded, add generated SFTs to then, otherwise just used generated SFTs
589  if ( multiSFTs != NULL ) {
591  XLALDestroyMultiSFTVector( fakeMultiSFTs );
592  } else {
593  multiSFTs = fakeMultiSFTs;
594  }
595 
596  } // if generateSFTs
597 
598  // Check that no single-SFT input vectors are given to avoid returning singular results
599  for ( UINT4 X = 0; X < common->detectors.length; ++X ) {
600  XLAL_CHECK_NULL( multiSFTs->data[X]->length > 1, XLAL_EINVAL, "Need more than 1 SFTs per Detector!\n" );
601  }
602 
603  // Normalise SFTs using either running median or assumed PSDs
604  MultiPSDVector *runningMedian;
605  XLAL_CHECK_NULL( ( runningMedian = XLALNormalizeMultiSFTVect( multiSFTs, optArgs.runningMedianWindow, optArgs.assumeSqrtSX ) ) != NULL, XLAL_EFUNC );
606 
607  // Calculate SFT noise weights from PSD
608  XLAL_CHECK_NULL( ( common->multiNoiseWeights = XLALComputeMultiNoiseWeights( runningMedian, optArgs.runningMedianWindow, 0 ) ) != NULL, XLAL_EFUNC );
609 
610  // for use within this modul: remove the normalization from the noise-weights: the normalisation factor is saved separately
611  // in the struct, and this allows us to use and extract subsets of the noise-weights without having to re-normalize them
612  for ( UINT4 X = 0; X < common->detectors.length; ++X ) {
614  }
615  common->multiNoiseWeights->isNotNormalized = ( 1 == 1 );
616 
617  // at this point we're done with running-median noise estimation and can 'trim' the SFTs back to
618  // the width actually required by the Fstat-methods *methods*.
619  // NOTE: this is especially relevant for resampling, where the frequency-band determines the sampling
620  // rate, and the number of samples that need to be FFT'ed
621  XLAL_CHECK_NULL( XLALMultiSFTVectorResizeBand( multiSFTs, minFreqMethod, maxFreqMethod - minFreqMethod ) == XLAL_SUCCESS, XLAL_EFUNC );
622 
623  // Get detector states, with a timestamp shift of Tsft/2
624  const REAL8 tOffset = 0.5 * input->Tsft;
625  XLAL_CHECK_NULL( ( common->multiDetectorStates = XLALGetMultiDetectorStates( common->multiTimestamps, &common->detectors, ephemerides, tOffset ) ) != NULL, XLAL_EFUNC );
626 
627  // Save ephemerides and SSB precision
628  common->ephemerides = ephemerides;
629  common->SSBprec = optArgs.SSBprec;
630 
631  // Call the appropriate method function to setup their input data structures
632  // - The method input data structures are expected to take ownership of the
633  // SFTs, which is why 'input->common' does not retain a pointer to them
634  FstatMethodFuncs *funcs = &input->method_funcs;
635  XLAL_CHECK_NULL( ( setupFuncMethod )( &input->method_data, common, funcs, multiSFTs, &optArgs ) == XLAL_SUCCESS, XLAL_EFUNC );
636 
637  // If setup function allocated a workspace, check that it also supplied a destructor function
638  XLAL_CHECK_NULL( common->workspace == NULL || funcs->workspace_destroy_func != NULL, XLAL_EFAILED );
639 
640  // Cleanup
641  XLALDestroyMultiPSDVector( runningMedian );
642 
643  return input;
644 
645 } // XLALCreateFstatInput()
646 
647 ///
648 /// Returns the frequency band loaded from input SFTs
649 ///
650 int XLALGetFstatInputSFTBand( const FstatInput *input, ///< [in] \c FstatInput structure.
651  REAL8 *minFreqFull, ///< [out] Minimum frequency loaded from input SFTs
652  REAL8 *maxFreqFull ///< [out] Maximum frequency loaded from input SFTs
653  )
654 {
655 
656  // Check input
657  XLAL_CHECK( input != NULL, XLAL_EINVAL );
658  XLAL_CHECK( minFreqFull != NULL, XLAL_EINVAL );
659  XLAL_CHECK( maxFreqFull != NULL, XLAL_EINVAL );
660 
661  *minFreqFull = input->minFreqFull;
662  *maxFreqFull = input->maxFreqFull;
663 
664  return XLAL_SUCCESS;
665 
666 }
667 
668 ///
669 /// Returns the human-readable name of the \f$ \mathcal{F} \f$ -statistic method being used by a \c FstatInput structure.
670 ///
671 const CHAR *
672 XLALGetFstatInputMethodName( const FstatInput *input ///< [in] \c FstatInput structure.
673  )
674 {
675  // Check input
676  XLAL_CHECK_NULL( input != NULL, XLAL_EINVAL );
677  XLAL_CHECK_NULL( FstatMethodNames[input->method] != NULL, XLAL_EFAULT );
678 
679  return FstatMethodNames[input->method];
680 
681 } // XLALGetFstatMethodName()
682 
683 ///
684 /// Returns the detector information stored in a \c FstatInput structure.
685 ///
686 const MultiLALDetector *
687 XLALGetFstatInputDetectors( const FstatInput *input ///< [in] \c FstatInput structure.
688  )
689 {
690  // Check input
691  XLAL_CHECK_NULL( input != NULL, XLAL_EINVAL );
692 
693  return &input->common.detectors;
694 
695 } // XLALGetFstatInputDetectors()
696 
697 ///
698 /// Returns the SFT timestamps stored in a \c FstatInput structure.
699 ///
701 XLALGetFstatInputTimestamps( const FstatInput *input ///< [in] \c FstatInput structure.
702  )
703 {
704  // Check input
705  XLAL_CHECK_NULL( input != NULL, XLAL_EINVAL );
706 
707  return input->common.multiTimestamps;
708 
709 } // XLALGetFstatInputTimestamps()
710 
711 ///
712 /// Returns the multi-detector noise weights stored in a \c FstatInput structure.
713 /// Note: the returned object is allocated here and needs to be free'ed by caller.
714 ///
716 XLALGetFstatInputNoiseWeights( const FstatInput *input ///< [in] \c FstatInput structure.
717  )
718 {
719  // Check input
720  XLAL_CHECK_NULL( input != NULL, XLAL_EINVAL );
721 
722  // copy and rescale data to a new allocated MultiNoiseWeights structure
723  UINT4 numIFOs = input->common.multiNoiseWeights->length;
724  MultiNoiseWeights *ret = NULL;
725  XLAL_CHECK_NULL( ( ret = XLALCalloc( 1, sizeof( *ret ) ) ) != NULL, XLAL_ENOMEM );
726  XLAL_CHECK_NULL( ( ret->data = XLALCalloc( numIFOs, sizeof( ret->data[0] ) ) ) != NULL, XLAL_ENOMEM );
727  ret->length = numIFOs;
728  ret->Sinv_Tsft = input->common.multiNoiseWeights->Sinv_Tsft;
729  REAL8 ooSinv_Tsft = 1.0 / input->common.multiNoiseWeights->Sinv_Tsft;
730  for ( UINT4 X = 0; X < numIFOs; X++ ) {
731  UINT4 length = input->common.multiNoiseWeights->data[X]->length;
732  XLAL_CHECK_NULL( ( ret->data[X] = XLALCreateREAL8Vector( length ) ) != NULL, XLAL_EFUNC );
733  // ComputeFstat stores *un-normalized* weights internally, so re-normalize them for returning them
734  XLAL_CHECK_NULL( input->common.multiNoiseWeights->isNotNormalized, XLAL_EERR, "BUG: noise weights stored in FstatInput must be unnormalized!\n" );
735  XLAL_CHECK_NULL( XLALVectorScaleREAL8( ret->data[X]->data, ooSinv_Tsft, input->common.multiNoiseWeights->data[X]->data, length ) == XLAL_SUCCESS, XLAL_EFUNC );
736  }
737 
738  return ret;
739 
740 } // XLALGetFstatInputNoiseWeights()
741 
742 ///
743 /// Returns the multi-detector state series stored in a \c FstatInput structure.
744 ///
746 XLALGetFstatInputDetectorStates( const FstatInput *input ///< [in] \c FstatInput structure.
747  )
748 {
749  // Check input
750  XLAL_CHECK_NULL( input != NULL, XLAL_EINVAL );
751 
752  return input->common.multiDetectorStates;
753 
754 } // XLALGetFstatInputDetectorStates()
755 
756 ///
757 /// Compute the \f$ \mathcal{F} \f$ -statistic over a band of frequencies.
758 ///
759 int
760 XLALComputeFstat( FstatResults **Fstats, ///< [in/out] Address of a pointer to a \c FstatResults results structure; if \c NULL, allocate here.
761  FstatInput *input, ///< [in] Input data structure created by one of the setup functions.
762  const PulsarDopplerParams *doppler, ///< [in] Doppler parameters, including starting frequency, at which to compute \f$ 2\mathcal{F} \f$
763  const UINT4 numFreqBins, ///< [in] Number of frequencies at which the \f$ 2\mathcal{F} \f$ are to be computed. Must be 1 if XLALCreateFstatInput() was passed zero \c dFreq.
764  const FstatQuantities whatToCompute ///< [in] Bit-field of which \f$ \mathcal{F} \f$ -statistic quantities to compute.
765  )
766 {
767  // Check input
768  XLAL_CHECK( Fstats != NULL, XLAL_EINVAL );
769  XLAL_CHECK( input != NULL, XLAL_EINVAL );
770  XLAL_CHECK( doppler != NULL, XLAL_EINVAL );
771  XLAL_CHECK( doppler->asini >= 0, XLAL_EINVAL );
772  XLAL_CHECK( numFreqBins > 0, XLAL_EINVAL );
773  XLAL_CHECK( !input->singleFreqBin || numFreqBins == 1, XLAL_EINVAL, "numFreqBins must be 1 if XLALCreateFstatInput() was passed zero dFreq" );
774  XLAL_CHECK( whatToCompute < FSTATQ_LAST, XLAL_EINVAL );
775 
776  // Check that SFT length is within allowed maximum
777  {
778  const REAL8 maxFreq = doppler->fkdot[0] + input->common.dFreq * numFreqBins;
779  XLAL_CHECK( XLALFstatCheckSFTLengthMismatch( input->Tsft, maxFreq, doppler->asini, doppler->period, input->common.allowedMismatchFromSFTLength ) == XLAL_SUCCESS, XLAL_EFUNC );
780  }
781 
782  // Allocate results struct, if needed
783  if ( ( *Fstats ) == NULL ) {
784  XLAL_CHECK( ( ( *Fstats ) = XLALCalloc( 1, sizeof( **Fstats ) ) ) != NULL, XLAL_ENOMEM );
785  }
786 
787  // Get constant pointer to common input data
788  const FstatCommon *common = &input->common;
789  const UINT4 numDetectors = common->detectors.length;
790 
791  // Enlarge result arrays if they are too small
792  const BOOLEAN moreFreqBins = ( numFreqBins > ( *Fstats )->internalalloclen );
793  const BOOLEAN moreDetectors = ( numDetectors > ( *Fstats )->numDetectors );
794  if ( moreFreqBins || moreDetectors ) {
795  // Enlarge multi-detector 2F array
796  if ( ( whatToCompute & FSTATQ_2F ) && moreFreqBins ) {
797  ( *Fstats )->twoF = XLALRealloc( ( *Fstats )->twoF, numFreqBins * sizeof( ( *Fstats )->twoF[0] ) );
798  XLAL_CHECK( ( *Fstats )->twoF != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->twoF to length %u", numFreqBins );
799  }
800 #ifndef LALPULSAR_CUDA_ENABLED
801  XLAL_CHECK( ( *Fstats )->twoF_CUDA == NULL, XLAL_EINVAL, "CUDA not enabled" );
802 #endif
803 
804  // Enlarge multi-detector Fa & Fb array
805  if ( ( whatToCompute & FSTATQ_FAFB ) && moreFreqBins ) {
806  ( *Fstats )->Fa = XLALRealloc( ( *Fstats )->Fa, numFreqBins * sizeof( ( *Fstats )->Fa[0] ) );
807  XLAL_CHECK( ( *Fstats )->Fa != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->Fa to length %u", numFreqBins );
808  ( *Fstats )->Fb = XLALRealloc( ( *Fstats )->Fb, numFreqBins * sizeof( ( *Fstats )->Fb[0] ) );
809  XLAL_CHECK( ( *Fstats )->Fb != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->Fb to length %u", numFreqBins );
810  }
811 
812  // Enlarge 2F per detector arrays
813  if ( ( whatToCompute & FSTATQ_2F_PER_DET ) && ( moreFreqBins || moreDetectors ) ) {
814  for ( UINT4 X = 0; X < numDetectors; ++X ) {
815  ( *Fstats )->twoFPerDet[X] = XLALRealloc( ( *Fstats )->twoFPerDet[X], numFreqBins * sizeof( ( *Fstats )->twoFPerDet[X][0] ) );
816  XLAL_CHECK( ( *Fstats )->twoFPerDet[X] != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->twoFPerDet[%u] to length %u", X, numFreqBins );
817  }
818  }
819 
820  // Enlarge Fa & Fb per detector arrays
821  if ( ( whatToCompute & FSTATQ_FAFB_PER_DET ) && ( moreFreqBins || moreDetectors ) ) {
822  for ( UINT4 X = 0; X < numDetectors; ++X ) {
823  ( *Fstats )->FaPerDet[X] = XLALRealloc( ( *Fstats )->FaPerDet[X], numFreqBins * sizeof( ( *Fstats )->FaPerDet[X][0] ) );
824  XLAL_CHECK( ( *Fstats )->FaPerDet[X] != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->FaPerDet[%u] to length %u", X, numFreqBins );
825  ( *Fstats )->FbPerDet[X] = XLALRealloc( ( *Fstats )->FbPerDet[X], numFreqBins * sizeof( ( *Fstats )->FbPerDet[X][0] ) );
826  XLAL_CHECK( ( *Fstats )->FbPerDet[X] != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->FbPerDet[%u] to length %u", X, numFreqBins );
827  }
828  }
829 
830  // Enlarge F-atoms per detector arrays, and initialise to NULL
831  if ( ( whatToCompute & FSTATQ_ATOMS_PER_DET ) && moreFreqBins ) {
832  UINT4 kPrev = 0;
833  if ( ( *Fstats )->multiFatoms != NULL ) {
834  kPrev = ( *Fstats )->internalalloclen; // leave previously-used frequency-bins untouched
835  }
836 
837  ( *Fstats )->multiFatoms = XLALRealloc( ( *Fstats )->multiFatoms, numFreqBins * sizeof( ( *Fstats )->multiFatoms[0] ) );
838  XLAL_CHECK( ( *Fstats )->multiFatoms != NULL, XLAL_EINVAL, "Failed to (re)allocate (*Fstats)->multiFatoms to length %u", numFreqBins );
839 
840  for ( UINT4 k = kPrev; k < numFreqBins; ++k ) {
841  ( *Fstats )->multiFatoms[k] = NULL;
842  }
843 
844  } // if Atoms_per_det to enlarge
845 
846  // Update allocated length of arrays
847  ( *Fstats )->internalalloclen = numFreqBins;
848 
849  } // if (moreFreqBins || moreDetectors)
850 
851  // Extrapolate parameters in 'doppler' to SFT mid-time
852  PulsarDopplerParams midDoppler = ( *doppler );
853  {
854  const REAL8 dtau = XLALGPSDiff( &common->midTime, &doppler->refTime );
855  XLAL_CHECK( XLALExtrapolatePulsarSpins( midDoppler.fkdot, midDoppler.fkdot, dtau ) == XLAL_SUCCESS, XLAL_EFUNC );
856  }
857  midDoppler.refTime = common->midTime;
858 
859  // Initialise result struct parameters
860  ( *Fstats )->doppler = midDoppler;
861  ( *Fstats )->dFreq = input->singleFreqBin ? 0 : common->dFreq;
862  ( *Fstats )->numFreqBins = numFreqBins;
863  ( *Fstats )->numDetectors = numDetectors;
864  XLAL_INIT_MEM( ( *Fstats )->detectorNames );
865  for ( UINT4 X = 0; X < numDetectors; ++X ) {
866  strncpy( ( *Fstats )->detectorNames[X], common->detectors.sites[X].frDetector.prefix, 2 );
867  }
868  ( *Fstats )->whatWasComputed = whatToCompute;
869 
870  // Call the appropriate method function to compute the F-statistic
871  XLAL_CHECK( ( input->method_funcs.compute_func )( *Fstats, common, input->method_data ) == XLAL_SUCCESS, XLAL_EFUNC );
872 
873  ( *Fstats )->doppler = ( *doppler );
874  // Record the internal reference time used, which is required to compute a correct global signal phase
875  ( *Fstats )->refTimePhase = midDoppler.refTime;
876 
877  return XLAL_SUCCESS;
878 
879 } // XLALComputeFstat()
880 
881 ///
882 /// Free all memory associated with a \c FstatInput structure.
883 ///
884 void
885 XLALDestroyFstatInput( FstatInput *input ///< [in] \c FstatInput structure to be freed.
886  )
887 {
888  if ( input == NULL ) {
889  return;
890  }
891  if ( input->common.isTimeslice ) {
893  "Something is wrong: 'isTimeslice==TRUE' for non-LALDemod F-stat method '%s' is not supported!\n", XLALGetFstatInputMethodName( input ) );
894  XLALDestroyFstatInputTimeslice_common( &input->common );
895  XLALDestroyFstatInputTimeslice_Demod( input->method_data );
896  XLALFree( input );
897  return;
898  }
899 
900  XLALDestroyMultiTimestamps( input->common.multiTimestamps );
901  XLALDestroyMultiNoiseWeights( input->common.multiNoiseWeights );
902  XLALDestroyMultiDetectorStateSeries( input->common.multiDetectorStates );
903 
904  // Release a reference to 'common.workspace'; if there are no more outstanding references ...
905  if ( --( *input->workspace_refcount ) == 0 ) {
906  XLALPrintInfo( "%s: workspace reference count = %i, freeing workspace\n", __func__, *input->workspace_refcount );
907 
908  // If allocated, free method-specific workspace using destructor function
909  if ( input->common.workspace != NULL ) {
910  ( input->method_funcs.workspace_destroy_func )( input->common.workspace );
911  }
912 
913  // Free memory for workspace reference count
914  XLALFree( input->workspace_refcount );
915 
916  } else {
917  XLALPrintInfo( "%s: workspace reference count = %i\n", __func__, *input->workspace_refcount );
918  }
919 
920  if ( input->method_data != NULL ) {
921  // Free method-specific data using destructor function
922  ( input->method_funcs.method_data_destroy_func )( input->method_data );
923  }
924 
925  XLALFree( input );
926 
927  return;
928 } // XLALDestroyFstatInput()
929 
930 ///
931 /// Free all memory associated with a \c FstatResults structure.
932 ///
933 void
934 XLALDestroyFstatResults( FstatResults *Fstats ///< [in] \c FstatResults structure to be freed.
935  )
936 {
937  if ( Fstats == NULL ) {
938  return;
939  }
940 
941  XLALFree( Fstats->twoF );
942 #ifdef LALPULSAR_CUDA_ENABLED
943  if ( Fstats->twoF_CUDA != NULL ) {
944  cudaFree( Fstats->twoF_CUDA );
945  }
946 #endif
947  XLALFree( Fstats->Fa );
948  XLALFree( Fstats->Fb );
949  for ( UINT4 X = 0; X < PULSAR_MAX_DETECTORS; ++X ) {
950  XLALFree( Fstats->twoFPerDet[X] );
951  XLALFree( Fstats->FaPerDet[X] );
952  XLALFree( Fstats->FbPerDet[X] );
953  }
954  if ( Fstats->multiFatoms != NULL ) {
955  for ( UINT4 n = 0; n < Fstats->internalalloclen; ++n ) {
957  }
958  XLALFree( Fstats->multiFatoms );
959  }
960 
961  XLALFree( Fstats );
962 
963  return;
964 } // XLALDestroyFstatResults()
965 
966 
967 /// Compute the \f$ \mathcal{F} \f$ -statistic from the complex \f$ F_a \f$ and \f$ F_b \f$ components
968 /// and the antenna pattern matrix.
969 ///
970 /// Note for developers:
971 /// This is just a wrapper to the internal function
972 /// compute_fstat_from_fa_fb()
973 /// so that it can be re-used externally.
974 /// Inside this module, better use that function directly!
975 ///
976 REAL4
977 XLALComputeFstatFromFaFb( COMPLEX8 Fa, ///< [in] F-stat component \f$ F_a \f$
978  COMPLEX8 Fb, ///< [in] F-stat component \f$ F_b \f$
979  REAL4 A, ///< [in] antenna pattern matrix component
980  REAL4 B, ///< [in] antenna pattern matrix component
981  REAL4 C, ///< [in] antenna pattern matrix component
982  REAL4 E, ///< [in] antenna pattern matrix component
983  REAL4 Dinv ///< [in] inverse determinant
984  )
985 {
986  return compute_fstat_from_fa_fb( Fa, Fb, A, B, C, E, Dinv );
987 } // XLALComputeFstatFromFaFb()
988 
989 
990 ///
991 /// Compute single-or multi-IFO Fstat '2F' from multi-IFO 'atoms'
992 ///
993 REAL4
994 XLALComputeFstatFromAtoms( const MultiFstatAtomVector *multiFstatAtoms, ///< [in] Multi-detector atoms
995  const INT4 X ///< [in] Detector number, give -1 for multi-Fstat
996  )
997 {
998  // ----- check input parameters and report errors
999  XLAL_CHECK_REAL4( multiFstatAtoms && multiFstatAtoms->data && multiFstatAtoms->data[0]->data, XLAL_EINVAL, "Empty pointer as input parameter." );
1000  XLAL_CHECK_REAL4( multiFstatAtoms->length > 0, XLAL_EBADLEN, "Input MultiFstatAtomVector has zero length. (i.e., no detectors)" );
1001  XLAL_CHECK_REAL4( X >= -1, XLAL_EDOM, "Invalid detector number X=%d. Only nonnegative numbers, or -1 for multi-F, are allowed.", X );
1002  XLAL_CHECK_REAL4( ( X < 0 ) || ( ( UINT4 )( X ) <= multiFstatAtoms->length - 1 ), XLAL_EDOM, "Requested X=%d, but FstatAtoms only have length %d.", X, multiFstatAtoms->length );
1003 
1004  // internal detector index Y to do both single- and multi-F case
1005  UINT4 Y, Ystart, Yend;
1006  if ( X == -1 ) { /* loop through all detectors to get multi-Fstat */
1007  Ystart = 0;
1008  Yend = multiFstatAtoms->length - 1;
1009  } else { /* just compute single-Fstat for 1 IFO */
1010  Ystart = X;
1011  Yend = X;
1012  }
1013 
1014  // set up temporary Fatoms and matrix elements for summations
1015  REAL4 mmatrixA = 0.0, mmatrixB = 0.0, mmatrixC = 0.0;
1016  REAL4 twoF = 0.0;
1017  COMPLEX8 Fa, Fb;
1018  Fa = 0.0;
1019  Fb = 0.0;
1020 
1021  for ( Y = Ystart; Y <= Yend; Y++ ) { /* loop through detectors */
1022  UINT4 alpha, numSFTs;
1023  numSFTs = multiFstatAtoms->data[Y]->length;
1024  XLAL_CHECK_REAL4( numSFTs > 0, XLAL_EDOM, "Input FstatAtomVector has zero length. (i.e., no timestamps for detector X=%d)", Y );
1025 
1026  for ( alpha = 0; alpha < numSFTs; alpha++ ) { /* loop through SFTs */
1027  FstatAtom *thisAtom = &multiFstatAtoms->data[Y]->data[alpha];
1028  /* sum up matrix elements and Fa, Fb */
1029  mmatrixA += thisAtom->a2_alpha;
1030  mmatrixB += thisAtom->b2_alpha;
1031  mmatrixC += thisAtom->ab_alpha;
1032  Fa += thisAtom->Fa_alpha;
1033  Fb += thisAtom->Fb_alpha;
1034  } /* loop through SFTs */
1035 
1036  } // loop through detectors
1037 
1038  // compute determinant and final Fstat (not twoF!)
1039  REAL4 D = XLALComputeAntennaPatternSqrtDeterminant( mmatrixA, mmatrixB, mmatrixC, 0 );
1040  REAL4 Dinv = 1.0f / D;
1041 
1042  twoF = compute_fstat_from_fa_fb( Fa, Fb, mmatrixA, mmatrixB, mmatrixC, 0, Dinv );
1043 
1044  return twoF;
1045 
1046 } // XLALComputeFstatFromAtoms()
1047 
1048 ///
1049 /// If user asks for a 'best' \c FstatMethodType, find and select it
1050 ///
1051 static int
1053 {
1054  switch ( *method ) {
1055 
1056  case FMETHOD_DEMOD_BEST:
1057  case FMETHOD_RESAMP_BEST:
1058  // If user asks for a 'best' method:
1059  // Decrement the current method, then check for the first available Fstat method. This assumes the FstatMethodType enum is ordered as follows:
1060  // FMETHOD_..._GENERIC, (must **always** avaiable)
1061  // FMETHOD_..._OPTIMISED, (always avaiable)
1062  // FMETHOD_..._SUPERFAST (not always available; requires special hardware)
1063  // FMETHOD_..._BEST (must **always** avaiable)
1064  XLALPrintInfo( "%s: trying to find best available Fstat method for '%s'\n", __func__, FstatMethodNames[*method] );
1065  while ( !XLALFstatMethodIsAvailable( --( *method ) ) ) {
1066  XLAL_CHECK( FMETHOD_START < *method, XLAL_EFAILED );
1067  XLALPrintInfo( "%s: Fstat method '%s' is unavailable\n", __func__, FstatMethodNames[*method] );
1068  }
1069  XLALPrintInfo( "%s: Fstat method '%s' is available; selected as best method\n", __func__, FstatMethodNames[*method] );
1070  break;
1071 
1072  default:
1073  // If user asks for a specific method:
1074  // Check that method is available
1075  XLAL_CHECK( XLALFstatMethodIsAvailable( *method ), XLAL_EINVAL, "Fstat method '%s' is unavailable", FstatMethodNames[*method] );
1076  break;
1077  }
1078  return XLAL_SUCCESS;
1079 }
1080 
1081 ///
1082 /// Return true if given \c FstatMethodType corresponds to a valid and *available* Fstat method, false otherwise
1083 ///
1084 int
1086 {
1087  switch ( method ) {
1088 
1089  case FMETHOD_DEMOD_GENERIC:
1090  case FMETHOD_DEMOD_BEST:
1092  case FMETHOD_RESAMP_BEST:
1093  // 'Generic' and 'Best' methods must **always** be available
1094  return 1;
1095 
1096  case FMETHOD_DEMOD_OPTC:
1097  // This method is always avalable
1098  return 1;
1099 
1100  case FMETHOD_DEMOD_ALTIVEC:
1101  // This method is available only if compiled with Altivec support
1102 #ifdef HAVE_ALTIVEC
1103  return 1;
1104 #else
1105  return 0;
1106 #endif
1107 
1108  case FMETHOD_DEMOD_SSE:
1109  // This method is available only if compiled with SSE support,
1110  // and SSE is available on the current execution machine
1111 #ifdef HAVE_SSE_COMPILER
1112  return LAL_HAVE_SSE_RUNTIME();
1113 #else
1114  return 0;
1115 #endif
1116 
1117  case FMETHOD_RESAMP_CUDA:
1118  // This medthod is available only if compiled with CUDA support
1119 #ifdef LALPULSAR_CUDA_ENABLED
1120  return 1;
1121 #else
1122  return 0;
1123 #endif
1124 
1125  default:
1126  return 0;
1127 
1128  }
1129 } // XLALFstatMethodIsAvailable()
1130 
1131 ///
1132 /// Return pointer to a static string giving the name of the \c FstatMethodType \p method
1133 ///
1134 const CHAR *
1136 {
1137  XLAL_CHECK_NULL( method < XLAL_NUM_ELEM( FstatMethodNames ) && FstatMethodNames[method] != NULL,
1138  XLAL_EINVAL, "FstatMethodType = %i is invalid", method );
1139  return FstatMethodNames[method];
1140 }
1141 
1142 ///
1143 /// Return pointer to a static array of all (available) \c FstatMethodType choices.
1144 /// This data is used by the UserInput module to parse a user enumeration.
1145 ///
1146 const UserChoices *
1148 {
1149  static int firstCall = 1;
1150  static UserChoices choices;
1151  if ( firstCall ) {
1153  size_t i = 0;
1154  for ( FstatMethodType m = FMETHOD_START + 1; m < FMETHOD_END; m++ ) {
1155  if ( ! XLALFstatMethodIsAvailable( m ) ) {
1156  continue;
1157  }
1158  FstatMethodType bm = m;
1160  if ( bm == m ) {
1161  // add an Fstat method
1162  choices[i].name = FstatMethodNames[m];
1163  choices[i].val = m;
1164  i++;
1165  } else {
1166  // add a "best" Fstat method twice, so that:
1167  // - name of "best" method will appear as equal to the actual method it selects,
1168  // in the help string, e.g. "...|DemodSuperFast=DemodBest|..."
1169  // - FMETHOD_..._BEST will print as "...Best" in e.g. help default argument, log output
1170  choices[i].name = FstatMethodNames[m];
1171  choices[i].val = bm;
1172  i++;
1173  choices[i].name = FstatMethodNames[m];
1174  choices[i].val = m;
1175  i++;
1176  }
1177  } // for m < FMETHOD_LAST
1178 
1179  firstCall = 0;
1180 
1181  } // if firstCall
1182 
1183  return ( const UserChoices * ) &choices;
1184 } // XLALFstatMethodChoices()
1185 
1186 /// Return measured values and details about generic F-statistic timing and method-specific timing model,
1187 // including static pointers to help-string documenting the generic F-stat timing, and the method-specific timing model.
1188 /// See also https://dcc.ligo.org/LIGO-T1600531-v4 for details about the timing model.
1189 int
1190 XLALGetFstatTiming( const FstatInput *input, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel )
1191 {
1192  XLAL_CHECK( input != NULL, XLAL_EINVAL );
1193  XLAL_CHECK( timingGeneric != NULL, XLAL_EINVAL );
1194  XLAL_CHECK( timingModel != NULL, XLAL_EINVAL );
1195 
1196  switch ( input->method ) {
1197  case FMETHOD_DEMOD_GENERIC:
1198  case FMETHOD_DEMOD_OPTC:
1199  case FMETHOD_DEMOD_ALTIVEC:
1200  case FMETHOD_DEMOD_SSE:
1201  XLAL_CHECK( XLALGetFstatTiming_Demod( input->method_data, timingGeneric, timingModel ) == XLAL_SUCCESS, XLAL_EFUNC );
1202  break;
1203 
1205  XLAL_CHECK( XLALGetFstatTiming_ResampGeneric( input->method_data, timingGeneric, timingModel ) == XLAL_SUCCESS, XLAL_EFUNC );
1206  break;
1207 
1208 #ifdef LALPULSAR_CUDA_ENABLED
1209  case FMETHOD_RESAMP_CUDA:
1210  XLAL_CHECK( XLALGetFstatTiming_ResampCUDA( input->method_data, timingGeneric, timingModel ) == XLAL_SUCCESS, XLAL_EFUNC );
1211  break;
1212 #endif
1213 
1214  default:
1215  XLAL_ERROR( XLAL_EINVAL, "Unsupported F-stat method '%s'\n", FstatMethodNames [ input->method ] );
1216  }
1217 
1218  timingGeneric->help = FstatTimingGenericHelp; // set static help-string pointer (not used or set otherwise)
1219 
1220  return XLAL_SUCCESS;
1221 
1222 } // XLALGetFstatTiming()
1223 
1224 int
1225 XLALAppendFstatTiming2File( const FstatInput *input, FILE *fp, BOOLEAN printHeader )
1226 {
1227  XLAL_CHECK( input != NULL, XLAL_EINVAL );
1228  XLAL_CHECK( fp != NULL, XLAL_EINVAL );
1229 
1231  FstatTimingModel XLAL_INIT_DECL( tiModel );
1232  XLAL_CHECK( XLALGetFstatTiming( input, &tiGen, &tiModel ) == XLAL_SUCCESS, XLAL_EFUNC );
1233 
1234  if ( printHeader ) {
1235  fprintf( fp, "%s\n", tiGen.help );
1236  fprintf( fp, "%s\n", tiModel.help );
1237  // generic F-stat timing header line
1238  fprintf( fp, "%%%%%8s %10s %4s %10s %10s %11s %10s ", "NCalls", "NFbin", "Ndet", "tauF_eff", "tauF_core", "tauF_buffer", "b" );
1239  // method-specific F-stat timing model header line
1240  fprintf( fp, "|" );
1241  for ( UINT4 i = 0; i < tiModel.numVariables; i ++ ) {
1242  fprintf( fp, " %13s", tiModel.names[i] );
1243  }
1244  fprintf( fp, "\n" );
1245  } // if (printHeader)
1246 
1247  // generic F-stat timing values
1248  fprintf( fp, "%10.0f %10d %4d %10.2e %10.2e %11.2e %10.2e ",
1249  tiGen.NCalls, tiGen.NFbin, tiGen.Ndet, tiGen.tauF_eff, tiGen.tauF_core, tiGen.tauF_buffer, tiGen.NBufferMisses / tiGen.NCalls );
1250 
1251  // method-specific F-stat timing model values
1252  fprintf( fp, " " ); // for '|'
1253  for ( UINT4 i = 0; i < tiModel.numVariables; i ++ ) {
1254  fprintf( fp, " %13g", tiModel.values[i] );
1255  }
1256  fprintf( fp, "\n" );
1257 
1258  return XLAL_SUCCESS;
1259 
1260 } // AppendFstatTiming2File()
1261 
1262 ///
1263 /// Extracts the resampled timeseries from a given FstatInput structure (must have been initialized previously by XLALCreateFstatInput() and a call to XLALComputeFstat()).
1264 ///
1265 /// \note This function only returns a pointer to the time-series that are still part of the FstatInput structure, and will by managed by F-statistic API calls.
1266 /// Therefore do *not* free the resampled timeseries with XLALDestroyMultiCOMPLEX8TimeSeries(), only
1267 /// free the complete Fstat input structure with XLALDestroyFstatInputVector() at the end once its no longer needed.
1268 ///
1269 int
1270 XLALExtractResampledTimeseries( MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, ///< [out] \c multi-detector SRC-frame timeseries, multiplied by AM function a(t).
1271  MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, ///< [out] \c multi-detector SRC-frame timeseries, multiplied by AM function b(t).
1272  FstatInput *input ///< [in] \c FstatInput structure.
1273  )
1274 {
1275  XLAL_CHECK( input != NULL, XLAL_EINVAL );
1276  XLAL_CHECK( ( multiTimeSeries_SRC_a != NULL ) && ( multiTimeSeries_SRC_b != NULL ), XLAL_EINVAL );
1277 
1278  switch ( input->method ) {
1280  XLAL_CHECK( XLALExtractResampledTimeseries_ResampGeneric( multiTimeSeries_SRC_a, multiTimeSeries_SRC_b, input->method_data ) == XLAL_SUCCESS, XLAL_EFUNC );
1281  break;
1282 
1283 #ifdef LALPULSAR_CUDA_ENABLED
1284  case FMETHOD_RESAMP_CUDA:
1285  XLAL_CHECK( XLALExtractResampledTimeseries_ResampCUDA( multiTimeSeries_SRC_a, multiTimeSeries_SRC_b, input->method_data ) == XLAL_SUCCESS, XLAL_EFUNC );
1286  break;
1287 #endif
1288 
1289  default:
1290  XLAL_ERROR( XLAL_EINVAL, "%s() only works for resampling-Fstat methods, not with '%s'\n", __func__, FstatMethodNames [ input->method ] );
1291  }
1292 
1293  return XLAL_SUCCESS;
1294 } // XLALExtractResampledTimeseries()
1295 
1296 ///
1297 /// Create and return an FstatInput 'timeslice' for given input FstatInput object [must be using LALDemod Fstat method!]
1298 /// which covers only the time interval ['minStartGPS','maxStartGPS'), using conventions of XLALCWGPSinRange().
1299 ///
1300 /// The returned FstatInput structure is equivalent to one that would have been produced for the given time-interval
1301 /// in the first place, except that it uses "containers" and references the data in the original FstatInput object.
1302 /// A special flag is set in the FstatInput object to notify the destructor to only free the data-containers.
1303 ///
1304 /// Note: if a timeslice is empty for any detector, the corresponding timeseries 'container' will be allocated and
1305 /// will have length==0 and data==NULL.
1306 ///
1307 int
1308 XLALFstatInputTimeslice( FstatInput **slice, ///< [out] Address of a pointer to a \c FstatInput structure
1309  const FstatInput *input, ///< [in] Input data structure
1310  const LIGOTimeGPS *minStartGPS, ///< [in] Minimum starting GPS time
1311  const LIGOTimeGPS *maxStartGPS ///< [in] Maximum starting GPS time
1312  )
1313 {
1314  XLAL_CHECK( input != NULL, XLAL_EINVAL );
1315  XLAL_CHECK( slice != NULL && ( *slice ) == NULL, XLAL_EINVAL );
1316  XLAL_CHECK( minStartGPS != NULL, XLAL_EINVAL );
1317  XLAL_CHECK( maxStartGPS != NULL, XLAL_EINVAL );
1318  XLAL_CHECK( XLALGPSCmp( minStartGPS, maxStartGPS ) < 1, XLAL_EINVAL, "minStartGPS (%"LAL_GPS_FORMAT") is greater than maxStartGPS (%"LAL_GPS_FORMAT")\n",
1319  LAL_GPS_PRINT( *minStartGPS ), LAL_GPS_PRINT( *maxStartGPS ) );
1320 
1321  // only supported for 'LALDemod' Fstat methods
1322  XLAL_CHECK( input->method < FMETHOD_RESAMP_GENERIC, XLAL_EINVAL, "This function is not avavible for the chosen FstatMethod '%s'!", XLALGetFstatInputMethodName( input ) );
1323 
1324  const FstatCommon *common = &( input->common );
1325  UINT4 numIFOs = common->detectors.length;
1326 
1327  // ---------- Find start- and end- indices of the requested timeslice for all detectors
1328  const MultiLIGOTimeGPSVector *mTS = common->multiTimestamps;
1331  for ( UINT4 X = 0; X < numIFOs; X ++ ) {
1332  XLAL_CHECK( XLALFindTimesliceBounds( &( iStart[X] ), &( iEnd[X] ), input->common.multiTimestamps->data[X], minStartGPS, maxStartGPS ) == XLAL_SUCCESS, XLAL_EFUNC );
1333  }
1334 
1335  // ----- prepare new top-level 'containers' for the timeslices in the 'common' part of FstatInput:
1337  XLAL_CHECK( ( multiTimestamps = XLALCalloc( 1, sizeof( *multiTimestamps ) ) ) != NULL, XLAL_ENOMEM );
1338  XLAL_CHECK( ( multiTimestamps->data = XLALCalloc( numIFOs, sizeof( *multiTimestamps->data ) ) ) != NULL, XLAL_ENOMEM );
1339  multiTimestamps->length = numIFOs;
1340 
1341  MultiNoiseWeights *multiNoiseWeights = NULL;
1342  XLAL_CHECK( ( multiNoiseWeights = XLALCalloc( 1, sizeof( *multiNoiseWeights ) ) ) != NULL, XLAL_ENOMEM );
1343  XLAL_CHECK( ( multiNoiseWeights->data = XLALCalloc( numIFOs, sizeof( *multiNoiseWeights->data ) ) ) != NULL, XLAL_ENOMEM );
1344  multiNoiseWeights->length = numIFOs;
1345 
1346  MultiDetectorStateSeries *multiDetectorStates = NULL;
1347  XLAL_CHECK( ( multiDetectorStates = XLALCalloc( 1, sizeof( *multiDetectorStates ) ) ) != NULL, XLAL_ENOMEM );
1348  XLAL_CHECK( ( multiDetectorStates->data = XLALCalloc( numIFOs, sizeof( *multiDetectorStates->data ) ) ) != NULL, XLAL_ENOMEM );
1349  multiDetectorStates->length = numIFOs;
1350 
1351  // determine earliest and latest SFT times of timeslice over all IFOs, in order to correctly set 'FstatCommon->midTime' value
1352  LIGOTimeGPS earliest_time = {LAL_INT4_MAX, 0};
1353  LIGOTimeGPS latest_time = {0, 0};
1354 
1355  // for updating noise-normalization factor Sinv_Tsft over timesclie
1356  UINT4 numSFTsSlice = 0;
1357  REAL8 sumWeightsSlice = 0;
1358 
1359  // ----- loop over detectors, create per-detector containers and set them to the requested timeslice
1360  for ( UINT4 X = 0; X < numIFOs; X ++ ) {
1361  // prepare multiTimestamps
1362  XLAL_CHECK( ( multiTimestamps->data[X] = XLALCalloc( 1, sizeof( *multiTimestamps->data[X] ) ) ) != NULL, XLAL_EFUNC );
1363  multiTimestamps->data[X]->deltaT = common->multiTimestamps->data[X]->deltaT;
1364 
1365  // prepare multiNoiseWeights
1366  multiNoiseWeights->data[X] = NULL;
1367  XLAL_CHECK( ( multiNoiseWeights->data[X] = XLALCalloc( 1, sizeof( *multiNoiseWeights->data[X] ) ) ) != NULL, XLAL_EFUNC );
1368 
1369  // prepare multiDetectorStates, copy struct values
1370  XLAL_CHECK( ( multiDetectorStates->data[X] = XLALCalloc( 1, sizeof( *multiDetectorStates->data[X] ) ) ) != NULL, XLAL_EFUNC );
1371  multiDetectorStates->data[X]->detector = common->multiDetectorStates->data[X]->detector;
1372  multiDetectorStates->data[X]->system = common->multiDetectorStates->data[X]->system;
1373  multiDetectorStates->data[X]->deltaT = common->multiDetectorStates->data[X]->deltaT;
1374 
1375  //---- set the timeslices
1376  if ( iStart[X] > iEnd[X] ) {
1377  continue; // empty slice
1378  }
1379 
1380  UINT4 sliceLength = iEnd[X] - iStart[X] + 1; // guaranteed >= 1
1381 
1382  // slice multiTimestamps
1383  multiTimestamps->data[X]->length = sliceLength;
1384  multiTimestamps->data[X]->data = &( mTS->data[X]->data[iStart[X]] );
1385 
1386  // keep track of earliest and latest SFT times included in timeslice (for computing 'midTime')
1387  if ( ( XLALGPSCmp( &( multiTimestamps->data[X]->data[0] ), &earliest_time ) == -1 ) ) {
1388  earliest_time = multiTimestamps->data[X]->data[0];
1389  }
1390  if ( XLALGPSCmp( &( multiTimestamps->data[X]->data[sliceLength - 1] ), &latest_time ) == 1 ) {
1391  latest_time = multiTimestamps->data[X]->data[sliceLength - 1];
1392  }
1393 
1394  // slice multiNoiseWeights
1395  multiNoiseWeights->data[X]->length = sliceLength;
1396  multiNoiseWeights->data[X]->data = &( common->multiNoiseWeights->data[X]->data[iStart[X]] );
1397 
1398  // sum the weights for updating the overall noise-normalisation factor Sinv_Tsft
1399  numSFTsSlice += sliceLength;
1400  for ( UINT4 alpha = 0; alpha < sliceLength; alpha++ ) {
1401  sumWeightsSlice += multiNoiseWeights->data[X]->data[alpha];
1402  }
1403 
1404  // slice multiDetectorStates
1405  multiDetectorStates->data[X]->length = sliceLength;
1406  multiDetectorStates->data[X]->data = &( common->multiDetectorStates->data[X]->data[iStart[X]] );
1407 
1408  } // for X < numIFOs
1409 
1410  // calculate new data midTime for timeslice
1411  XLALGPSAdd( &latest_time, multiDetectorStates->data[0]->deltaT );
1412  REAL8 TspanSlice = XLALGPSDiff( &latest_time, &earliest_time );
1413  LIGOTimeGPS midTimeSlice = earliest_time;
1414  XLALGPSAdd( &midTimeSlice, 0.5 * TspanSlice );
1415 
1416  // update noise-weight normalisation factor
1417  multiNoiseWeights->Sinv_Tsft = sumWeightsSlice / numSFTsSlice ;
1418  multiNoiseWeights->isNotNormalized = ( 1 == 1 );
1419 
1420  // allocate memory and copy the orginal FstatInput struct
1421  XLAL_CHECK( ( ( *slice ) = XLALCalloc( 1, sizeof( *input ) ) ) != NULL, XLAL_ENOMEM );
1422  memcpy( ( *slice ), input, sizeof( *input ) );
1423 
1424  ( *slice )->common.isTimeslice = ( 1 == 1 ); // This is a timeslice
1425  ( *slice )->common.midTime = midTimeSlice;
1426  ( *slice )->common.multiTimestamps = multiTimestamps;
1427  ( *slice )->common.multiDetectorStates = multiDetectorStates;
1428  ( *slice )->common.multiNoiseWeights = multiNoiseWeights;
1429 
1430  ( *slice )->method_data = XLALFstatInputTimeslice_Demod( input->method_data, iStart, iEnd );
1431  XLAL_CHECK( ( *slice )->method_data != NULL, XLAL_EFUNC );
1432 
1433  return XLAL_SUCCESS;
1434 
1435 } // XLALFstatInputTimeslice()
1436 
1437 
1438 static void
1440 {
1441  if ( !common ) {
1442  return;
1443  }
1444 
1445  for ( UINT4 X = 0; X < common->multiTimestamps->length; X ++ ) {
1446  XLALFree( common->multiTimestamps->data[X] );
1447  XLALFree( common->multiDetectorStates->data[X] );
1448  XLALFree( common->multiNoiseWeights->data[X] );
1449  }
1450 
1451  XLALFree( common->multiTimestamps->data );
1452  XLALFree( common->multiDetectorStates->data );
1453  XLALFree( common->multiNoiseWeights->data );
1454  XLALFree( common->multiTimestamps );
1455  XLALFree( common->multiNoiseWeights );
1456  XLALFree( common->multiDetectorStates );
1457 
1458  return;
1459 
1460 } // XLALDestroyFstatInputTimeslice_common()
1461 
1462 /// @}
static const char FstatTimingGenericHelp[]
Definition: ComputeFstat.c:104
static const char *const FstatMethodNames[FMETHOD_END]
Definition: ComputeFstat.c:78
static REAL4 compute_fstat_from_fa_fb(COMPLEX8 Fa, COMPLEX8 Fb, REAL4 A, REAL4 B, REAL4 C, REAL4 E, REAL4 Dinv)
#define __func__
log an I/O error, i.e.
#define LAL_INT4_MAX
int k
#define D(j)
UINT2 A
Definition: SFTnaming.c:46
UINT2 B
Definition: SFTnaming.c:47
#define fprintf
int XLALCWMakeFakeMultiData(MultiSFTVector **multiSFTs, MultiREAL8TimeSeries **multiTseries, const PulsarParamsVector *injectionSources, const CWMFDataParams *dataParams, const EphemerisData *edat)
Generate fake 'CW' data, returned either as SFTVector or REAL4Timeseries or both, for given CW-signal...
void * XLALFstatInputTimeslice_Demod(const void *method_data, const UINT4 iStart[PULSAR_MAX_DETECTORS], const UINT4 iEnd[PULSAR_MAX_DETECTORS])
int XLALSetupFstatDemod(void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs)
int XLALGetFstatTiming_Demod(const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel)
void XLALDestroyFstatInputTimeslice_Demod(void *method_data)
Free all memory not needed by the orginal FstatInput structure.
int XLALExtractResampledTimeseries_ResampCUDA(MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, void *method_data)
int XLALSetupFstatResampCUDA(void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs)
int XLALGetFstatTiming_ResampCUDA(const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel)
int XLALExtractResampledTimeseries_ResampGeneric(MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, void *method_data)
int XLALGetFstatTiming_ResampGeneric(const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel)
int XLALSetupFstatResampGeneric(void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs)
FstatAtomVector * XLALCreateFstatAtomVector(const UINT4 length)
Create a FstatAtomVector of the given length.
Definition: ComputeFstat.c:276
static int XLALSelectBestFstatMethod(FstatMethodType *method)
If user asks for a 'best' FstatMethodType, find and select it.
const MultiLIGOTimeGPSVector * XLALGetFstatInputTimestamps(const FstatInput *input)
Returns the SFT timestamps stored in a FstatInput structure.
Definition: ComputeFstat.c:701
FstatMethodType
Different methods available to compute the -statistic, falling into two broad classes:
Definition: ComputeFstat.h:110
const MultiLALDetector * XLALGetFstatInputDetectors(const FstatInput *input)
Returns the detector information stored in a FstatInput structure.
Definition: ComputeFstat.c:687
static void XLALDestroyFstatInputTimeslice_common(FstatCommon *common)
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 MultiDetectorStateSeries * XLALGetFstatInputDetectorStates(const FstatInput *input)
Returns the multi-detector state series stored in a FstatInput structure.
Definition: ComputeFstat.c:746
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 XLALDestroyFstatInputVector(FstatInputVector *inputs)
Free all memory associated with a FstatInputVector structure.
Definition: ComputeFstat.c:252
int XLALFstatInputTimeslice(FstatInput **slice, const FstatInput *input, const LIGOTimeGPS *minStartGPS, const LIGOTimeGPS *maxStartGPS)
Create and return an FstatInput 'timeslice' for given input FstatInput object [must be using LALDemod...
int XLALGetFstatInputSFTBand(const FstatInput *input, REAL8 *minFreqFull, REAL8 *maxFreqFull)
Returns the frequency band loaded from input SFTs.
Definition: ComputeFstat.c:650
MultiNoiseWeights * XLALGetFstatInputNoiseWeights(const FstatInput *input)
Returns the multi-detector noise weights stored in a FstatInput structure.
Definition: ComputeFstat.c:716
int XLALExtractResampledTimeseries(MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, FstatInput *input)
Extracts the resampled timeseries from a given FstatInput structure (must have been initialized previ...
int XLALGetFstatTiming(const FstatInput *input, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel)
Return measured values and details about generic F-statistic timing and method-specific timing model,...
REAL4 XLALComputeFstatFromAtoms(const MultiFstatAtomVector *multiFstatAtoms, const INT4 X)
Compute single-or multi-IFO Fstat '2F' from multi-IFO 'atoms'.
Definition: ComputeFstat.c:994
REAL8 XLALFstatMaximumSFTLength(const REAL8 maxFreq, const REAL8 binaryMaxAsini, const REAL8 binaryMinPeriod, const REAL8 mu_SFT)
Compute the maximum SFT length that can safely be used as input to XLALComputeFstat(),...
Definition: ComputeFstat.c:163
const CHAR * XLALFstatMethodName(FstatMethodType method)
Return pointer to a static string giving the name of the FstatMethodType method.
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)
FstatInputVector * XLALCreateFstatInputVector(const UINT4 length)
Create a FstatInputVector of the given length, for example for setting up F-stat searches over severa...
Definition: ComputeFstat.c:231
REAL4 XLALComputeFstatFromFaFb(COMPLEX8 Fa, COMPLEX8 Fb, REAL4 A, REAL4 B, REAL4 C, REAL4 E, REAL4 Dinv)
Compute the -statistic from the complex and components and the antenna pattern matrix.
Definition: ComputeFstat.c:977
FstatQuantities
Bit-field of -statistic quantities which can be computed by XLALComputeFstat().
Definition: ComputeFstat.h:94
void XLALDestroyFstatAtomVector(FstatAtomVector *atoms)
Free all memory associated with a FstatAtomVector structure.
Definition: ComputeFstat.c:297
#define DEFAULT_MAX_MISMATCH_FROM_SFT_LENGTH
default maximum allowed F-stat mismatch from SFTs being too long, to be used in XLALFstatCheckSFTLeng...
Definition: ComputeFstat.h:70
void XLALDestroyMultiFstatAtomVector(MultiFstatAtomVector *multiAtoms)
Free all memory associated with a MultiFstatAtomVector structure.
Definition: ComputeFstat.c:338
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
int XLALFstatMethodIsAvailable(FstatMethodType method)
Return true if given FstatMethodType corresponds to a valid and available Fstat method,...
MultiFstatAtomVector * XLALCreateMultiFstatAtomVector(const UINT4 length)
Create a MultiFstatAtomVector of the given length.
Definition: ComputeFstat.c:317
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:122
@ FMETHOD_DEMOD_SSE
Demod: SSE hotloop with precalc divisors, uses fixed
Definition: ComputeFstat.h:119
@ FMETHOD_DEMOD_OPTC
Demod: gptimized C hotloop using Akos' algorithm, only works for
Definition: ComputeFstat.h:117
@ FMETHOD_DEMOD_BEST
Demod: best guess of the fastest available hotloop
Definition: ComputeFstat.h:120
@ FMETHOD_RESAMP_BEST
Resamp: best guess of the fastest available implementation
Definition: ComputeFstat.h:124
@ FMETHOD_DEMOD_GENERIC
Demod: generic C hotloop, works for any number of Dirichlet kernel terms
Definition: ComputeFstat.h:116
@ FMETHOD_RESAMP_CUDA
Resamp: CUDA resampling
Definition: ComputeFstat.h:123
@ FMETHOD_DEMOD_ALTIVEC
Demod: Altivec hotloop variant, uses fixed
Definition: ComputeFstat.h:118
@ FSTATQ_2F
Compute multi-detector .
Definition: ComputeFstat.h:96
@ FSTATQ_FAFB_PER_DET
Compute and for each detector.
Definition: ComputeFstat.h:99
@ FSTATQ_FAFB
Compute multi-detector and .
Definition: ComputeFstat.h:97
@ FSTATQ_LAST
Definition: ComputeFstat.h:102
@ 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
#define LAL_GPS_FORMAT
#define LAL_GPS_PRINT(gps)
void XLALDestroyMultiDetectorStateSeries(MultiDetectorStateSeries *mdetStates)
Helper function to get rid of a multi-IFO DetectorStateSeries Note, this is "NULL-robust" in the sens...
int XLALMultiLALDetectorFromMultiSFTs(MultiLALDetector *multiIFO, const MultiSFTVector *multiSFTs)
Extract multi detector-info from a given multi SFTCatalog view.
MultiDetectorStateSeries * XLALGetMultiDetectorStates(const MultiLIGOTimeGPSVector *multiTS, const MultiLALDetector *multiIFO, const EphemerisData *edat, REAL8 tOffset)
Get the detector-time series for the given MultiLIGOTimeGPSVector.
int XLALMultiLALDetectorFromMultiSFTCatalogView(MultiLALDetector *multiIFO, const MultiSFTCatalogView *multiView)
Extract multi detector-info from a given multi SFTCatalog view.
int XLALExtrapolatePulsarSpins(PulsarSpins fkdot1, const PulsarSpins fkdot0, REAL8 dtau)
Extrapolate the Pulsar spin-parameters (fkdot0) from the initial reference-epoch to the new referen...
REAL4 XLALComputeAntennaPatternSqrtDeterminant(REAL4 A, REAL4 B, REAL4 C, REAL4 E)
Compute (sqrt of) determinant of the antenna-pattern matrix Mmunu = [ A, C, 0, -E; C B E,...
Definition: LALComputeAM.c:544
#define LAL_DAYSID_SI
#define LAL_PI
#define LAL_TWOPI
unsigned char BOOLEAN
#define XLAL_NUM_ELEM(x)
#define XLAL_INIT_MEM(x)
double REAL8
#define XLAL_INIT_DECL(var,...)
char CHAR
uint32_t UINT4
float complex COMPLEX8
int32_t INT4
float REAL4
void * XLALCalloc(size_t m, size_t n)
void * XLALRealloc(void *p, size_t n)
void XLALFree(void *p)
#define LAL_HAVE_SSE_RUNTIME()
MultiPSDVector * XLALNormalizeMultiSFTVect(MultiSFTVector *multsft, UINT4 blockSize, const MultiNoiseFloor *assumeSqrtSX)
Function for normalizing a multi vector of SFTs in a multi IFO search and returns the running-median ...
void XLALDestroyMultiPSDVector(MultiPSDVector *multvect)
Destroy a multi PSD-vector.
Definition: PSDutils.c:102
MultiNoiseWeights * XLALComputeMultiNoiseWeights(const MultiPSDVector *rngmed, UINT4 blocksRngMed, UINT4 excludePercentile)
Computes weight factors arising from MultiSFTs with different noise floors.
Definition: PSDutils.c:285
void XLALDestroyMultiNoiseWeights(MultiNoiseWeights *weights)
Destroy a MultiNoiseWeights object.
Definition: PSDutils.c:172
#define PULSAR_MAX_DETECTORS
maximal number of detectors we can handle (for static arrays of detector quantities)
static const INT4 m
MultiSFTVector * XLALLoadMultiSFTs(const SFTCatalog *inputCatalog, REAL8 fMin, REAL8 fMax)
Function to load a catalog of SFTs from possibly different detectors.
Definition: SFTfileIO.c:416
void XLALDestroyMultiSFTCatalogView(MultiSFTCatalogView *multiView)
Destroys a MultiSFTCatalogView, without freeing the original catalog that the 'view' was referring to...
Definition: SFTcatalog.c:496
void XLALDestroyMultiSFTVector(MultiSFTVector *multvect)
Destroy a multi SFT-vector.
Definition: SFTtypes.c:424
MultiSFTCatalogView * XLALGetMultiSFTCatalogView(const SFTCatalog *catalog)
Return a MultiSFTCatalogView generated from an input SFTCatalog.
Definition: SFTcatalog.c:380
int XLALMultiSFTVectorResizeBand(MultiSFTVector *multiSFTs, REAL8 f0, REAL8 Band)
Resize the frequency-band of a given multi-SFT vector to [f0, f0+Band].
Definition: SFTtypes.c:946
int XLALFindTimesliceBounds(UINT4 *iStart, UINT4 *iEnd, const LIGOTimeGPSVector *timestamps, const LIGOTimeGPS *minStartGPS, const LIGOTimeGPS *maxStartGPS)
MultiLIGOTimeGPSVector * XLALTimestampsFromMultiSFTCatalogView(const MultiSFTCatalogView *multiView)
Given a multi-SFTCatalogView, return a MultiLIGOTimeGPSVector holding the SFT timestamps.
MultiLIGOTimeGPSVector * XLALExtractMultiTimestampsFromSFTs(const MultiSFTVector *multiSFTs)
Given a multi-SFT vector, return a MultiLIGOTimeGPSVector holding the SFT timestamps.
int XLALMultiSFTVectorAdd(MultiSFTVector *a, const MultiSFTVector *b)
Adds SFT-data from MultiSFTvector 'b' to elements of MultiSFTVector 'a'.
Definition: SFTtypes.c:842
void XLALDestroyMultiTimestamps(MultiLIGOTimeGPSVector *multiTS)
Destroy a MultiLIGOTimeGPSVector timestamps vector.
@ SSBPREC_LAST
end marker
Definition: SSBtimes.h:50
@ SSBPREC_RELATIVISTICOPT
optimized relativistic, numerically equivalent to SSBPREC_RELATIVISTIC, but faster
Definition: SSBtimes.h:48
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
int XLALVectorScaleREAL8(REAL8 *out, REAL8 scalar, const REAL8 *in, const UINT4 len)
#define XLAL_ERROR_NULL(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_VOID(assertion,...)
#define XLAL_CHECK_REAL4(assertion,...)
#define XLAL_CHECK_REAL8(assertion,...)
#define XLAL_CHECK_NULL(assertion,...)
static _LAL_INLINE_ int XLALIsREAL8FailNaN(REAL8 val)
XLAL_EBADLEN
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EFUNC
XLAL_EERR
XLAL_EDOM
XLAL_EINVAL
XLAL_EFAILED
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
int XLALGPSCmp(const LIGOTimeGPS *t0, const LIGOTimeGPS *t1)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
n
double alpha
size_t numDetectors
COMPLEX8Sequence * data
Struct controlling all the aspects of the fake data (time-series + SFTs) to be produced by XLALCWMake...
REAL8 deltaT
timespan centered on each timestamp (e.g.
CoordinateSystem system
The coordinate system used for detector's position/velocity and detector-tensor.
DetectorState * data
array of DetectorState entries
UINT4 length
total number of entries
LALDetector detector
detector-info corresponding to this timeseries
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
An -statistic 'atom', i.e.
Definition: ComputeFstat.h:161
COMPLEX8 Fa_alpha
.
Definition: ComputeFstat.h:166
REAL4 b2_alpha
Antenna-pattern factor .
Definition: ComputeFstat.h:164
REAL4 ab_alpha
Antenna-pattern factor .
Definition: ComputeFstat.h:165
COMPLEX8 Fb_alpha
.
Definition: ComputeFstat.h:167
REAL4 a2_alpha
Antenna-pattern factor .
Definition: ComputeFstat.h:163
A vector of -statistic 'atoms', i.e.
Definition: ComputeFstat.h:174
FstatAtom * data
Array of FstatAtom pointers of given length.
Definition: ComputeFstat.h:179
UINT4 length
Number of per-SFT 'atoms'.
Definition: ComputeFstat.h:178
MultiDetectorStateSeries * multiDetectorStates
const EphemerisData * ephemerides
SSBprecision SSBprec
REAL8 allowedMismatchFromSFTLength
MultiLALDetector detectors
MultiLIGOTimeGPSVector * multiTimestamps
LIGOTimeGPS midTime
MultiNoiseWeights * multiNoiseWeights
A vector of XLALComputeFstat() input data structures, for e.g.
Definition: ComputeFstat.h:82
FstatInput ** data
Pointer to the data array.
Definition: ComputeFstat.h:87
UINT4 length
Number of elements in array.
Definition: ComputeFstat.h:86
void(* workspace_destroy_func)(void *)
Struct of optional 'advanced level' and (potentially method-specific) arguments to be passed to the ...
Definition: ComputeFstat.h:136
UINT4 randSeed
Random-number seed value used in case of fake Gaussian noise generation (injectSqrtSX)
Definition: ComputeFstat.h:137
MultiNoiseFloor * injectSqrtSX
Single-sided PSD values for fake Gaussian noise to be added to SFT data.
Definition: ComputeFstat.h:143
PulsarParamsVector * injectSources
Vector of parameters of CW signals to simulate and inject.
Definition: ComputeFstat.h:142
UINT4 runningMedianWindow
If SFT noise weights are calculated from the SFTs, the running median window length to use.
Definition: ComputeFstat.h:140
MultiNoiseFloor * assumeSqrtSX
Single-sided PSD values to be used for computing SFT noise weights instead of from a running median o...
Definition: ComputeFstat.h:144
FstatInput * prevInput
An FstatInput structure from a previous call to XLALCreateFstatInput(); may contain common workspace ...
Definition: ComputeFstat.h:145
REAL8 allowedMismatchFromSFTLength
Optional override for XLALFstatCheckSFTLengthMismatch().
Definition: ComputeFstat.h:148
REAL8 sourceDeltaT
Optional source-frame sampling period for XLALCWMakeFakeData(); if zero, use the previous internal de...
Definition: ComputeFstat.h:149
UINT4 Dterms
Number of Dirichlet kernel terms, used by some Demod methods; see FstatMethodType.
Definition: ComputeFstat.h:139
FstatMethodType FstatMethod
Method to use for computing the -statistic.
Definition: ComputeFstat.h:141
SSBprecision SSBprec
Barycentric transformation precision.
Definition: ComputeFstat.h:138
XLALComputeFstat() computed results structure.
Definition: ComputeFstat.h:201
COMPLEX8 * Fb
Definition: ComputeFstat.h:259
REAL4 * twoFPerDet[PULSAR_MAX_DETECTORS]
If whatWasComputed & FSTATQ_2F_PER_DET is true, the values computed at numFreqBins frequencies space...
Definition: ComputeFstat.h:268
REAL4 * twoF_CUDA
If whatWasComputed & FSTATQ_2F_CUDA is true, the multi-detector values as for twoF,...
Definition: ComputeFstat.h:247
COMPLEX8 * FaPerDet[PULSAR_MAX_DETECTORS]
If whatWasComputed & FSTATQ_PARTS_PER_DET is true, the and values computed at numFreqBins frequenci...
Definition: ComputeFstat.h:278
REAL4 * twoF
If whatWasComputed & FSTATQ_2F is true, the multi-detector values computed at numFreqBins frequencie...
Definition: ComputeFstat.h:241
COMPLEX8 * Fa
If whatWasComputed & FSTATQ_PARTS is true, the multi-detector and computed at numFreqBins frequenci...
Definition: ComputeFstat.h:258
COMPLEX8 * FbPerDet[PULSAR_MAX_DETECTORS]
Definition: ComputeFstat.h:279
MultiFstatAtomVector ** multiFatoms
If whatWasComputed & FSTATQ_ATOMS_PER_DET is true, the per-SFT -statistic multi-atoms computed at nu...
Definition: ComputeFstat.h:288
Generic F-stat timing coefficients (times in seconds) [see https://dcc.ligo.org/LIGO-T1600531-v4 for ...
Definition: ComputeFstat.h:307
const char * help
Definition: ComputeFstat.h:315
Struct to carry the -statistic method-specific timing model in terms of a list of variable names and...
Definition: ComputeFstat.h:326
LALFrDetector frDetector
CHAR prefix[3]
REAL8 deltaT
'length' of each timestamp (e.g.
Definition: SFTfileIO.h:194
LIGOTimeGPS * data
array of timestamps
Definition: SFTfileIO.h:193
Multi-IFO container for COMPLEX8 resampled timeseries.
Definition: LFTandTSutils.h:52
Multi-IFO time-series of DetectorStates.
UINT4 length
number of detectors
DetectorStateSeries ** data
vector of pointers to DetectorStateSeries
A multi-detector vector of FstatAtomVector.
Definition: ComputeFstat.h:186
FstatAtomVector ** data
Array of FstatAtomVector pointers, one for each detector X.
Definition: ComputeFstat.h:191
UINT4 length
Number of detectors.
Definition: ComputeFstat.h:190
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
UINT4 length
number of detectors
One noise-weight (number) per SFT (therefore indexed over IFOs and SFTs.
Definition: PSDutils.h:71
REAL8 Sinv_Tsft
normalization factor used: (using single-sided PSD!)
Definition: PSDutils.h:77
UINT4 length
number of detectors
Definition: PSDutils.h:75
REAL8Vector ** data
weights-vector for each detector
Definition: PSDutils.h:76
BOOLEAN isNotNormalized
if true: weights are saved unnormalized (divide by Sinv_Tsft to get normalized version).
Definition: PSDutils.h:78
A collection of PSD vectors – one for each IFO in a multi-IFO search.
Definition: PSDutils.h:62
A multi-SFT-catalogue "view": a multi-IFO vector of SFT-catalogs.
Definition: SFTfileIO.h:255
A collection of SFT vectors – one for each IFO in a multi-IFO search.
Definition: SFTfileIO.h:179
Type containing the 'Doppler-parameters' affecting the time-evolution of the phase.
REAL8 period
Binary: orbital period (sec)
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ...
LIGOTimeGPS refTime
Reference time of pulsar parameters (in SSB!)
REAL8 asini
Binary: projected, normalized orbital semi-major axis (s).
PulsarParams * data
array of pulsar-signal parameters
UINT4 length
number of pulsar-signals
REAL8 * 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
SFTtype header
SFT-header info.
Definition: SFTfileIO.h:228
struct tagSFTLocator * locator
internal description of where to find this SFT [opaque!]
Definition: SFTfileIO.h:227
XLALComputeFstat() input data structure.
Definition: ComputeFstat.c:44
void * method_data
Definition: ComputeFstat.c:53
REAL8 minFreqFull
Definition: ComputeFstat.c:46
int * workspace_refcount
Definition: ComputeFstat.c:51
FstatMethodType method
Definition: ComputeFstat.c:49
FstatMethodFuncs method_funcs
Definition: ComputeFstat.c:52
FstatCommon common
Definition: ComputeFstat.c:50
REAL8 maxFreqFull
Definition: ComputeFstat.c:47