30#include <lal/LogPrintf.h>
31#include <lal/SFTfileIO.h>
33#include <lal/LALDatatypes.h>
34#include <lal/LALStdio.h>
35#include <lal/UserInput.h>
36#include <lal/LALPulsarVCSInfo.h>
41#define POWER(x) (((REAL8)crealf(x)*(REAL8)crealf(x)) + ((REAL8)cimagf(x)*(REAL8)cimagf(x)))
56int main(
int argc,
char **argv )
58 lalUserVarHelpBrief =
"Arithmetic and noise-weighted averge spectrum and persistency from SFTs for Fscan";
59 lalUserVarHelpDescription =
"Provide SFTs to this program for computing arithmetic and noise-weighted average spectra and persistency of frequency bins above background, optionally track frequency bins above threshold or specific frequency bins, saved as ASCII data files for use by Fscan";
61 FILE *SPECOUT = NULL, *WTOUT = NULL, *LINEOUT = NULL;
67 REAL8Vector *timeavg = NULL, *timeavgwt = NULL, *sumweight = NULL, *persistency = NULL;
69 CHAR outbase[256], outfile0[512], outfile1[512], outfile2[512];
71 CHAR *SFTpatt = NULL, *
IFO = NULL, *outputDir = NULL, *outputBname = NULL, *
header = NULL;
72 INT4 startGPS = 0, endGPS = 0, blocksRngMean = 21;
73 REAL8 f_min = 0.0,
f_max = 0.0, timebaseline = 0, persistSNRthresh = 3.0, auto_track;
77 INT4 persistAvgSeconds = 0;
79 REAL8Vector *this_epoch_avg = NULL, *this_epoch_avg_wt = NULL, *new_epoch_avg = NULL, *new_epoch_wt = NULL;
89 " - '<SFT file>;<SFT file>;...', where <SFT file> may contain wildcards\n - 'list:<file containing list of SFT files>'" ) ==
XLAL_SUCCESS,
XLAL_EFUNC );
102 XLAL_CHECK_MAIN(
XLALRegisterNamedUvar( &line_freq,
"lineFreq", STRINGVector, 0, OPTIONAL,
"CSV list of line frequencies (e.g., --lineFreq=21.5,22.0). If set, then an output file with all GPS start times of SFTs with float values of number of standard deviations above the mean (>0 indicates above mean). Be careful that the CSV list of values are interpreted as floating point values" ) ==
XLAL_SUCCESS,
XLAL_EFUNC );
113 printf(
"Starting spec_avg_long...\n" );
117 INT4 nside = ( blocksRngMean - 1 ) / 2;
125 XLAL_CHECK_MAIN( persistAvgOpt > 0 && persistAvgOpt < 4,
XLAL_EINVAL,
"--persistAvgOption can only take a value of 1, 2, or 3" );
128 persistAvgSeconds = timebaseline;
140 constraints.maxStartTime = &endTime;
141 constraints.detector =
IFO;
143 printf(
"Calling XLALSFTdataFind with SFTpatt=%s\n", SFTpatt );
151 if ( allow_skipping ) {
169 snprintf( outbase,
sizeof( outbase ),
"%s/%s", outputDir, outputBname );
171 snprintf( outbase,
sizeof( outbase ),
"%s/spec_%.2f_%.2f_%s_%d_%d", outputDir,
f_min,
f_max, constraints.detector,
startTime.gpsSeconds, endTime.
gpsSeconds );
174 snprintf( outfile0,
sizeof( outfile0 ),
"%s.txt", outbase );
175 snprintf( outfile1,
sizeof( outfile1 ),
"%s_PWA.txt", outbase );
176 snprintf( outfile2,
sizeof( outfile2 ),
"%s_line_times.csv", outbase );
178 UINT4 epoch_index = 0;
180 printf(
"Looping over SFTs to compute average spectra\n" );
182 fprintf( stderr,
"Extracting SFT %d...\n",
j );
200 if ( line_freq != NULL ) {
209 memset( persistency->data, 0,
sizeof(
REAL8 )*persistency->length );
215 memset( new_epoch_avg->data, 0,
sizeof(
REAL8 )*new_epoch_avg->length );
220 XLAL_CHECK_MAIN( epoch_avg->
data != NULL,
XLAL_ENOMEM,
"Persistency calculation failed to allocate epoch_avg. Try using a longer epoch averaging with the -E flag or longer -T" );
227 REAL8 thisavepower = 0.;
229 for (
INT4 ii = -nside; ii <= nside; ii++ ) {
236 thisavepower /=
count;
237 REAL8 weight = 1. / thisavepower;
241 timeavg->
data[
i] = thispower;
242 timeavgwt->data[
i] = thispower * weight;
243 sumweight->data[
i] = weight;
245 this_epoch_avg->
data[
i] = thispower * weight;
246 this_epoch_avg_wt->data[
i] = weight;
248 timeavg->
data[
i] += thispower;
249 timeavgwt->data[
i] += thispower * weight;
250 sumweight->data[
i] += weight;
255 this_epoch_avg->
data[
i] += thispower * weight;
256 this_epoch_avg_wt->data[
i] += weight;
258 new_epoch_avg->data[
i] = thispower * weight;
259 new_epoch_wt->data[
i] = weight;
266 if ( new_epoch_avg->data[0] != 0.0 ) {
269 this_epoch_avg->
data[
i] *= 2.0 / this_epoch_avg_wt->data[
i] / timebaseline;
273 memcpy( &( epoch_avg->
data[epoch_index * this_epoch_avg->
length] ), this_epoch_avg->
data,
sizeof(
REAL8 )*this_epoch_avg->
length );
277 memcpy( this_epoch_avg->
data, new_epoch_avg->data,
sizeof(
REAL8 )*new_epoch_avg->length );
278 memcpy( this_epoch_avg_wt->data, new_epoch_wt->data,
sizeof(
REAL8 )*new_epoch_wt->length );
281 memset( new_epoch_avg->data, 0,
sizeof(
REAL8 )*new_epoch_avg->length );
284 if (
j == catalog->
length - 1 ) {
286 this_epoch_avg->
data[
i] = 2.*this_epoch_avg->
data[
i] / this_epoch_avg_wt->data[
i] / timebaseline;
289 memcpy( &( epoch_avg->
data[epoch_index * this_epoch_avg->
length] ), this_epoch_avg->
data,
sizeof(
REAL8 )*this_epoch_avg->
length );
319 if ( ( epoch_avg->
data[
j * epoch_avg->
vectorLength +
i] - mean ) / std > persistSNRthresh ) {
320 persistency->data[
i] += 1.0;
326 for (
UINT4 i = 0;
i < persistency->length;
i++ ) {
327 persistency->data[
i] /= (
REAL8 )epoch_gps_times->
length;
331 if ( freq_vect != NULL ) {
342 if ( freq_vect != NULL ) {
380 SPECOUT = fopen( outfile0,
"w" );
382 XLAL_CHECK_MAIN( SPECOUT != NULL,
XLAL_EIO,
"Failed to open '%s' for writing: %s", outfile0, strerror( fopenerr ) );
383 WTOUT = fopen( outfile1,
"w" );
385 XLAL_CHECK_MAIN( WTOUT != NULL,
XLAL_EIO,
"Failed to open '%s' for writing: %s", outfile1, strerror( fopenerr ) );
394 REAL8 PSDWT = 2.*timeavgwt->data[
i] / sumweight->data[
i] / timebaseline;
395 REAL8 AMPPSD = pow( PSD, 0.5 );
396 REAL8 AMPPSDWT = pow( PSDWT, 0.5 );
397 REAL8 persist = persistency->data[
i];
398 fprintf( SPECOUT,
"%16.8f %g %g %g %g %g\n",
f, PSD, AMPPSD, PSDWT, AMPPSDWT, persist );
400 REAL8 PWA_TAVGWT = timeavgwt->data[
i];
401 REAL8 PWA_SUMWT = sumweight->data[
i];
402 fprintf( WTOUT,
"%16.8f %g %g\n",
f, PWA_TAVGWT, PWA_SUMWT );
408 if ( freq_vect != NULL ) {
410 LINEOUT = fopen( outfile2,
"w" );
412 XLAL_CHECK_MAIN( LINEOUT != NULL,
XLAL_EIO,
"Failed to open '%s' for writing: %s", outfile2, strerror( fopenerr ) );
417 fprintf( LINEOUT,
"# GPS Epoch (len = %d s)", persistAvgSeconds );
419 fprintf( LINEOUT,
"# GPS Epoch (option = %d)", persistAvgOpt );
439 fprintf( stderr,
"Destroying Variables\n" );
449 fprintf( stderr,
"Done Destroying Variables\n" );
450 fprintf( stderr,
"end of spec_avg_long\n" );
463 UINT4 epoch_index = 0;
475 if ( ( persistAvgOptWasSet &&
XLALGPSDiff( &test_epoch, &
epoch ) != 0 ) || ( !persistAvgOptWasSet &&
XLALGPSDiff( &test_epoch, &
epoch ) >= persistAvgSeconds ) ) {
494 if ( ( persistAvgOptWasSet &&
XLALGPSDiff( &test_epoch, &epoch_gps_times->
data[epoch_index - 1] ) != 0 ) || ( !persistAvgOptWasSet &&
XLALGPSDiff( &test_epoch, &epoch_gps_times->
data[epoch_index - 1] ) >= persistAvgSeconds ) ) {
501 return epoch_gps_times;
518 if ( persistAvgOptWasSet && persistAvgOpt == 1 ) {
519 utc->tm_sec = utc->tm_min = utc->tm_hour = 0;
521 }
else if ( persistAvgOptWasSet && persistAvgOpt == 2 ) {
522 utc->tm_sec = utc->tm_min = utc->tm_hour = 0;
524 }
else if ( persistAvgOptWasSet && persistAvgOpt == 3 ) {
525 utc->tm_sec = utc->tm_min = utc->tm_hour = 0;
548 UINT4 removeLength = 0;
549 for (
UINT4 i = 0;
i < ( *line_freq )->length;
i++ ) {
559 if ( removeLength > 0 ) {
562 if ( valid->
data[
i] == 1 ) {
565 fprintf( stderr,
"NOTE: requested frequency to monitor %s Hz is outside of requested band and will not be included in output\n", ( *line_freq )->data[
i] );
569 *line_freq = new_line_freq;
582 freq_vect->
data[
i] = atof( line_freq->
data[
i] );
592 memcpy(
win->data, input->
data,
sizeof(
REAL8 )*blocksRngMean );
600 memmove(
win->data, &
win->data[1],
sizeof(
REAL8 ) * ( blocksRngMean - 1 ) );
601 win->data[
win->length - 1] = input->
data[
i + ( blocksRngMean - 1 )];
615 memcpy(
win->data, &input->
data[
i],
sizeof(
REAL8 )*blocksRngMean );
635 *mean = means->
data[0];
636 *std = stds->
data[0];
637 }
else if ( idx >= means->
length ) {
641 *mean = means->
data[idx - nside];
642 *std = stds->
data[idx - nside];
const LALVCSInfoList lalPulsarVCSInfoList
NULL-terminated list of VCS and build information for LALPulsar and its dependencies
SFTVector * extract_one_sft(const SFTCatalog *full_catalog, const LIGOTimeGPS starttime, const REAL8 f_min, const REAL8 f_max)
REAL8VectorSequence * XLALCreateREAL8VectorSequence(UINT4 length, UINT4 veclen)
void XLALDestroyREAL8VectorSequence(REAL8VectorSequence *vecseq)
#define XLAL_INIT_DECL(var,...)
char char * XLALStringDuplicate(const char *s)
void LogPrintf(LogLevel_t, const char *format,...) _LAL_GCC_PRINTF_FORMAT_(2
void XLALDestroySFTVector(SFTVector *vect)
XLAL interface to destroy an SFTVector.
void XLALDestroySFTCatalog(SFTCatalog *catalog)
Free an 'SFT-catalogue'.
LIGOTimeGPSVector * XLALCreateTimestampVector(UINT4 len)
Allocate a LIGOTimeGPSVector.
SFTCatalog * XLALSFTdataFind(const CHAR *file_pattern, const SFTConstraints *constraints)
Find the list of SFTs matching the file_pattern and satisfying the given constraints,...
void XLALDestroyTimestampVector(LIGOTimeGPSVector *vect)
De-allocate a LIGOTimeGPSVector.
void XLALDestroyStringVector(LALStringVector *vect)
LALStringVector * XLALAppendString2Vector(LALStringVector *vect, const CHAR *string)
REAL8Vector * XLALResizeREAL8Vector(REAL8Vector *vector, UINT4 length)
void XLALDestroyUINT4Vector(UINT4Vector *vector)
INT4Vector * XLALCreateINT4Vector(UINT4 length)
void XLALDestroyINT4Vector(INT4Vector *vector)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
UINT4Vector * XLALCreateUINT4Vector(UINT4 length)
INT4 XLALUTCToGPS(const struct tm *utc)
struct tm * XLALFillUTC(struct tm *utc)
struct tm * XLALGPSToUTC(struct tm *utc, INT4 gpssec)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_MAIN(assertion,...)
#define XLAL_ERROR_MAIN(...)
#define XLAL_TRY(statement, errnum)
#define XLAL_CHECK_NULL(assertion,...)
int XLALGPSCmp(const LIGOTimeGPS *t0, const LIGOTimeGPS *t1)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
REAL8Vector * line_freq_str2dbl(const LALStringVector *line_freq)
int set_sft_avg_epoch(struct tm *utc, LIGOTimeGPS *epoch_start, const LIGOTimeGPS first_sft_epoch, const INT4 persistAvgOpt, const BOOLEAN persistAvgOptWasSet)
int main(int argc, char **argv)
int rngstd(const REAL8Vector *input, const REAL8Vector *means, const REAL8Vector *output, const INT4 blocksRngMean)
int validate_line_freq(LALStringVector **line_freq, const REAL8 f0, const REAL8 deltaF, const UINT4 numBins)
int rngmean(const REAL8Vector *input, const REAL8Vector *output, const INT4 blocksRngMean)
LIGOTimeGPSVector * setup_epochs(const SFTCatalog *catalog, const INT4 persistAvgOpt, const BOOLEAN persistAvgOptWasSet, const INT4 persistAvgSeconds)
int select_mean_std_from_vect(REAL8 *mean, REAL8 *std, const REAL8Vector *means, const REAL8Vector *stds, const UINT4 idx, const UINT4 nside)
A vector of COMPLEX8FrequencySeries.
COMPLEX8FrequencySeries * data
Pointer to the data array.
UINT4 length
Number of elements in array.
A vector of 'timestamps' of type LIGOTimeGPS.
LIGOTimeGPS * data
array of timestamps
UINT4 length
number of timestamps
An "SFT-catalogue": a vector of SFTdescriptors, as returned by XLALSFTdataFind()
SFTDescriptor * data
array of data-entries describing matched SFTs
UINT4 length
number of SFTs in catalog
'Constraints' for SFT-matching: which detector, within which time-stretch and which timestamps exactl...
SFTtype header
SFT-header info.