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
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
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
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
58int XLALSetupFstatDemod( void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs );
59int XLALGetFstatTiming_Demod( const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel );
60void *XLALFstatInputTimeslice_Demod( const void *method_data, const UINT4 iStart[PULSAR_MAX_DETECTORS], const UINT4 iEnd[PULSAR_MAX_DETECTORS] );
61void XLALDestroyFstatInputTimeslice_Demod( void *method_data );
62
63int XLALSetupFstatResampGeneric( void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs );
64int XLALExtractResampledTimeseries_ResampGeneric( MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, void *method_data );
65int XLALGetFstatTiming_ResampGeneric( const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel );
66
67#ifdef LALPULSAR_CUDA_ENABLED
68int XLALSetupFstatResampCUDA( void **method_data, FstatCommon *common, FstatMethodFuncs *funcs, MultiSFTVector *multiSFTs, const FstatOptionalArgs *optArgs );
69int XLALExtractResampledTimeseries_ResampCUDA( MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_a, MultiCOMPLEX8TimeSeries **multiTimeSeries_SRC_b, void *method_data );
70int XLALGetFstatTiming_ResampCUDA( const void *method_data, FstatTimingGeneric *timingGeneric, FstatTimingModel *timingModel );
71#endif
72
73static int XLALSelectBestFstatMethod( FstatMethodType *method );
75
76// ---------- Constant variable definitions ---------- //
77
78static 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
104static 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///
163REAL8 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///
203int 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 );
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///
231XLALCreateFstatInputVector( 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///
251void
252XLALDestroyFstatInputVector( 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///
276XLALCreateFstatAtomVector( 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///
296void
297XLALDestroyFstatAtomVector( 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///
317XLALCreateMultiFstatAtomVector( 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///
337void
338XLALDestroyMultiFstatAtomVector( 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///
358FstatInput *
359XLALCreateFstatInput( 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 {
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
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;
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///
650int 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///
671const CHAR *
672XLALGetFstatInputMethodName( 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///
686const MultiLALDetector *
687XLALGetFstatInputDetectors( 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///
701XLALGetFstatInputTimestamps( 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///
716XLALGetFstatInputNoiseWeights( 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///
746XLALGetFstatInputDetectorStates( 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///
759int
760XLALComputeFstat( 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///
884void
885XLALDestroyFstatInput( 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 ) );
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///
933void
934XLALDestroyFstatResults( 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///
976REAL4
977XLALComputeFstatFromFaFb( 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///
993REAL4
994XLALComputeFstatFromAtoms( 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 */
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///
1051static int
1053{
1054 switch ( *method ) {
1055
1056 case FMETHOD_DEMOD_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///
1084int
1086{
1087 switch ( method ) {
1088
1090 case FMETHOD_DEMOD_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
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
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///
1134const 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///
1146const 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.
1189int
1190XLALGetFstatTiming( 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 ) {
1198 case FMETHOD_DEMOD_OPTC:
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
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
1224int
1225XLALAppendFstatTiming2File( const FstatInput *input, FILE *fp, BOOLEAN printHeader )
1226{
1227 XLAL_CHECK( input != NULL, XLAL_EINVAL );
1228 XLAL_CHECK( fp != NULL, XLAL_EINVAL );
1229
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///
1269int
1270XLALExtractResampledTimeseries( 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
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///
1307int
1308XLALFstatInputTimeslice( 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
1438static 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:111
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:123
@ FMETHOD_DEMOD_SSE
Demod: SSE hotloop with precalc divisors, uses fixed
Definition: ComputeFstat.h:120
@ FMETHOD_DEMOD_OPTC
Demod: gptimized C hotloop using Akos' algorithm, only works for
Definition: ComputeFstat.h:118
@ FMETHOD_DEMOD_BEST
Demod: best guess of the fastest available hotloop
Definition: ComputeFstat.h:121
@ FMETHOD_RESAMP_BEST
Resamp: best guess of the fastest available implementation
Definition: ComputeFstat.h:125
@ FMETHOD_DEMOD_GENERIC
Demod: generic C hotloop, works for any number of Dirichlet kernel terms
Definition: ComputeFstat.h:117
@ FMETHOD_RESAMP_CUDA
Resamp: CUDA resampling
Definition: ComputeFstat.h:124
@ FMETHOD_DEMOD_ALTIVEC
Demod: Altivec hotloop variant, uses fixed
Definition: ComputeFstat.h:119
@ 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:103
@ 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:162
COMPLEX8 Fa_alpha
.
Definition: ComputeFstat.h:167
REAL4 b2_alpha
Antenna-pattern factor .
Definition: ComputeFstat.h:165
REAL4 ab_alpha
Antenna-pattern factor .
Definition: ComputeFstat.h:166
COMPLEX8 Fb_alpha
.
Definition: ComputeFstat.h:168
REAL4 a2_alpha
Antenna-pattern factor .
Definition: ComputeFstat.h:164
A vector of -statistic 'atoms', i.e.
Definition: ComputeFstat.h:175
FstatAtom * data
Array of FstatAtom pointers of given length.
Definition: ComputeFstat.h:180
UINT4 length
Number of per-SFT 'atoms'.
Definition: ComputeFstat.h:179
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: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
FstatInput * prevInput
An FstatInput structure from a previous call to XLALCreateFstatInput(); may contain common workspace ...
Definition: ComputeFstat.h:146
REAL8 allowedMismatchFromSFTLength
Optional override for XLALFstatCheckSFTLengthMismatch().
Definition: ComputeFstat.h:149
REAL8 sourceDeltaT
Optional source-frame sampling period for XLALCWMakeFakeData(); if zero, use the previous internal de...
Definition: ComputeFstat.h:150
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
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_CUDA
If whatWasComputed & FSTATQ_2F_CUDA is true, the multi-detector values as for twoF,...
Definition: ComputeFstat.h:248
COMPLEX8 * FaPerDet[PULSAR_MAX_DETECTORS]
If whatWasComputed & FSTATQ_PARTS_PER_DET is true, the and values computed at numFreqBins frequenci...
Definition: ComputeFstat.h:287
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
COMPLEX8 * FbPerDet[PULSAR_MAX_DETECTORS]
Definition: ComputeFstat.h:288
MultiFstatAtomVector ** multiFatoms
If whatWasComputed & FSTATQ_ATOMS_PER_DET is true, the per-SFT -statistic multi-atoms computed at nu...
Definition: ComputeFstat.h:297
Generic F-stat timing coefficients (times in seconds) [see https://dcc.ligo.org/LIGO-T1600531-v4 for ...
Definition: ComputeFstat.h:316
const char * help
Definition: ComputeFstat.h:324
Struct to carry the -statistic method-specific timing model in terms of a list of variable names and...
Definition: ComputeFstat.h:335
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:187
FstatAtomVector ** data
Array of FstatAtomVector pointers, one for each detector X.
Definition: ComputeFstat.h:192
UINT4 length
Number of detectors.
Definition: ComputeFstat.h:191
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, ... ] where fkdot = d^kFreq/dt^k.
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