34 #include <gsl/gsl_blas.h>
35 #include <gsl/gsl_matrix.h>
36 #include <gsl/gsl_vector.h>
40 #include <lal/EPSearch.h>
41 #include <lal/FrequencySeries.h>
42 #include <lal/LALChisq.h>
43 #include <lal/LALDatatypes.h>
44 #include <lal/LALMalloc.h>
45 #include <lal/LALStdlib.h>
46 #include <lal/LIGOLwXMLArray.h>
47 #include <lal/LIGOMetadataTables.h>
48 #include <lal/LIGOMetadataUtils.h>
49 #include <lal/RealFFT.h>
50 #include <lal/SnglBurstUtils.h>
51 #include <lal/TimeFreqFFT.h>
52 #include <lal/TimeSeries.h>
53 #include <lal/Units.h>
54 #include <lal/XLALError.h>
55 #include <lal/Window.h>
58 static double min(
double a,
double b)
64 static double max(
double a,
double b)
79 typedef struct tagExcessPowerFilter {
85 typedef struct tagLALExcessPowerFilterBank {
100 double channel_bandwidth,
112 new = malloc(
sizeof(*
new));
113 basis_filters = calloc(n_channels,
sizeof(*basis_filters));
116 if(!
new || !basis_filters || !twice_channel_overlap || !unwhitened_cross) {
124 new->n_filters = n_channels;
125 new->basis_filters = basis_filters;
126 new->twice_channel_overlap = twice_channel_overlap;
127 new->unwhitened_cross = unwhitened_cross;
129 for(
i = 0;
i < n_channels;
i++) {
131 if(!basis_filters[
i].fseries) {
146 for(
i = 0;
i <
new->n_filters - 1;
i++) {
203 if(segment_length < 1) {
207 if(segment_shift < 1) {
216 if(target_length < segment_length)
223 segments = (target_length - segment_length) / segment_shift;
225 return segments * segment_shift + segment_length;
237 double fractional_tile_shift,
245 int max_tile_shift = fractional_tile_shift * max_tile_length;
251 if(window_length % 4 != 0) {
255 if(max_tile_length < 1) {
259 if(fractional_tile_shift <= 0) {
263 if(fmod(fractional_tile_shift * max_tile_length, 1) != 0) {
264 XLALPrintError(
"fractional_tile_shift * max_tile_length not an integer");
267 if(max_tile_shift < 1) {
296 *tiling_length = window_length - 2 * *window_pad;
298 if(*tiling_length <= 0) {
299 XLALPrintError(
"window_length too small for tiling, must be >= 2 * %d + %d", *window_pad, max_tile_length);
307 *window_pad = (window_length - *tiling_length) / 2;
308 if(*tiling_length + 2 * *window_pad != window_length) {
309 XLALPrintError(
"window_length does not permit equal padding before and after tiling");
318 *window_shift = *tiling_length - (max_tile_length - max_tile_shift);
319 if(*window_shift < 1) {
333 *psd_shift = *psd_length - (window_length - *window_shift);
338 }
else if(psd_shift) {
363 typedef struct tagREAL8TimeFrequencyPlaneTiles {
374 typedef struct tagREAL8TimeFrequencyPlane {
397 unsigned tseries_length,
398 double tseries_deltaT,
401 double tiling_fractional_stride,
402 double max_tile_bandwidth,
403 double max_tile_duration,
404 const REAL8FFTPlan *plan
408 gsl_matrix *channel_data;
418 const double fseries_deltaF = 1.0 / (tseries_length * tseries_deltaT);
424 const double deltaF = 1 / max_tile_duration * tiling_fractional_stride;
430 const int channels = round(bandwidth / deltaF);
436 const unsigned inv_fractional_stride = round(1.0 / tiling_fractional_stride);
442 const unsigned min_length = round((1 / max_tile_bandwidth) / tseries_deltaT);
443 const unsigned max_length = round(max_tile_duration / tseries_deltaT);
444 const unsigned min_channels = inv_fractional_stride;
445 const unsigned max_channels = round(max_tile_bandwidth / deltaF);
469 if(
XLALEPGetTimingParameters(tseries_length, max_tile_duration / tseries_deltaT, tiling_fractional_stride, NULL, NULL, &window_shift, &tiling_start, &tiling_length) < 0)
491 (inv_fractional_stride * tiling_fractional_stride != 1) ||
492 (fmod(max_tile_duration, tseries_deltaT) != 0) ||
493 (fmod(deltaF, fseries_deltaF) != 0) ||
494 (tseries_deltaT <= 0) ||
495 (channels * deltaF != bandwidth) ||
496 (min_length * tseries_deltaT != (1 / max_tile_bandwidth)) ||
497 (min_length % inv_fractional_stride != 0) ||
498 (tiling_length % max_length != 0) ||
499 (channels % max_channels != 0)) {
500 XLALPrintError(
"unable to construct time-frequency tiling from input parameters\n");
509 channel_data = gsl_matrix_alloc(tseries_length, channels);
518 if(!plane || !channel_data || !channel_buffer || !unwhitened_channel_buffer || !tukey || !correlation) {
521 gsl_matrix_free(channel_data);
533 plane->
name[0] =
'\0';
535 plane->
deltaT = tseries_deltaT;
605 const double flo =
max(filterseries->
f0, inputseries->
f0);
607 double complex *
output = outputseq->
data + (int) round((flo - inputseries->
f0) / inputseries->
deltaF);
608 double complex *last = outputseq->
data + (int) round((fhi - inputseries->
f0) / inputseries->
deltaF);
609 const double complex *input = inputseries->
data->
data + (int) round((flo - inputseries->
f0) / inputseries->
deltaF);
610 const double complex *filter = filterseries->
data->
data + (int) round((flo - filterseries->
f0) / filterseries->
deltaF);
617 memset(outputseq->
data, 0, outputseq->
length *
sizeof(*outputseq->
data));
622 *
output = *input * conj(*filter);
623 memset(last, 0, (outputseq->
length - (last - outputseq->
data)) *
sizeof(*outputseq->
data));
639 const REAL8FFTPlan *reverseplan
647 (fmod(plane->
flow - fseries->
f0, fseries->
deltaF) != 0.0))
651 if((plane->
flow < fseries->
f0) ||
664 FILE *f = fopen(
"sk.dat",
"a");
675 FILE *f = fopen(
"sksk.dat",
"a");
676 for(dk = 0; dk < 100; dk++) {
680 double dr = fseries->
data->
data[k].re;
681 double di = fseries->
data->
data[k].im;
682 double dkr = fseries->
data->
data[k + dk].re;
683 double dki = fseries->
data->
data[k + dk].im;
684 avg_r += dr * dkr + di * dki;
685 avg_i += di * dkr - dr * dki;
689 fprintf(f,
"%d %g %g\n", dk, avg_r, avg_i);
742 double mean_square = 0;
744 for(
i = channel;
i < channel + channels;
i++)
774 strncpy(event->ifo, plane->
name, 2);
775 event->ifo[2] =
'\0';
780 event->start_time = plane->
epoch;
782 event->duration = tile_length * plane->
deltaT;
783 event->peak_time =
event->start_time;
784 XLALGPSAdd(&event->peak_time, event->duration / 2);
785 event->bandwidth = bandwidth;
786 event->central_freq = f_centre;
788 event->amplitude = h_rss;
789 event->snr = E / d - 1;
791 event->confidence = confidence;
801 double confidence_threshold
804 gsl_vector filter_output = {
811 gsl_vector_view filter_output_view;
812 gsl_vector *channel_buffer;
813 gsl_vector *unwhitened_channel_buffer;
816 unsigned channel_end;
828 channel_buffer = gsl_vector_alloc(filter_output.size);
829 unwhitened_channel_buffer = gsl_vector_alloc(filter_output.size);
830 if(!channel_buffer || !unwhitened_channel_buffer) {
832 gsl_vector_free(channel_buffer);
833 if(unwhitened_channel_buffer)
834 gsl_vector_free(unwhitened_channel_buffer);
843 for(channels = plane->
tiles.
min_channels; channels <= plane->tiles.max_channels; channels *= 2) {
865 for(
i = channel;
i < channel_end - 1;
i++)
867 uwsample_rms = sqrt(uwsample_rms);
874 filter_output_view = gsl_vector_subvector_with_stride(&filter_output, 0, stride, filter_output.size / stride);
875 gsl_vector_set_zero(channel_buffer);
876 gsl_vector_set_zero(unwhitened_channel_buffer);
877 channel_buffer->size = unwhitened_channel_buffer->size = filter_output_view.vector.size;
878 for(
i = channel;
i < channel_end; filter_output_view.vector.data++,
i++) {
879 gsl_blas_daxpy(1.0 / sample_rms, &filter_output_view.vector, channel_buffer);
886 FILE *f = fopen(
"sj.dat",
"a");
887 for(
i = 0;
i < channel_buffer->size;
i++)
888 fprintf(f,
"%g\n", gsl_vector_get(unwhitened_channel_buffer,
i));
895 for(
i = 0;
i < channel_buffer->size;
i++) {
896 gsl_vector_set(channel_buffer,
i, pow(gsl_vector_get(channel_buffer,
i), 2));
897 gsl_vector_set(unwhitened_channel_buffer,
i, pow(gsl_vector_get(unwhitened_channel_buffer,
i), 2));
901 for(tile_dof = 2; tile_dof <= plane->
tiles.
max_length / stride; tile_dof *= 2) {
906 double sumsquares = 0;
907 double uwsumsquares = 0;
909 sumsquares += gsl_vector_get(channel_buffer,
i);
910 uwsumsquares += gsl_vector_get(unwhitened_channel_buffer,
i);
923 gsl_vector_free(channel_buffer);
924 gsl_vector_free(unwhitened_channel_buffer);
930 if((confidence >= confidence_threshold) && (uwsumsquares >= tile_dof)) {
934 h_rss = sqrt((uwsumsquares - tile_dof) * (stride * plane->
deltaT)) * strain_rms;
939 gsl_vector_free(channel_buffer);
940 gsl_vector_free(unwhitened_channel_buffer);
943 head->
next = oldhead;
951 gsl_vector_free(channel_buffer);
952 gsl_vector_free(unwhitened_channel_buffer);
975 double confidence_threshold,
976 double fractional_stride,
977 double maxTileBandwidth,
978 double maxTileDuration
1007 if(!fplan || !rplan || !psd || !fseries || !plane) {
1055 XLALPrintInfo(
"%s(): constructing channel filters\n", __func__);
1092 XLALPrintInfo(
"%s(): computing the Fourier transform\n", __func__);
1109 XLALPrintInfo(
"%s(): normalizing to the average spectrum\n", __func__);
1123 XLALPrintInfo(
"%s(): projecting data onto time-frequency plane\n", __func__);
1138 XLALPrintInfo(
"%s(): computing the excess power for each tile\n", __func__);
static SnglBurst * XLALComputeExcessPower(const REAL8TimeFrequencyPlane *plane, const LALExcessPowerFilterBank *filter_bank, SnglBurst *head, double confidence_threshold)
static SnglBurst * XLALTFTileToBurstEvent(const REAL8TimeFrequencyPlane *plane, double tile_start, double tile_length, double f_centre, double bandwidth, double h_rss, double E, double d, double confidence)
static double max(double a, double b)
static COMPLEX16Sequence * apply_filter(COMPLEX16Sequence *outputseq, const COMPLEX16FrequencySeries *inputseries, const COMPLEX16FrequencySeries *filterseries)
static void XLALDestroyExcessPowerFilterBank(LALExcessPowerFilterBank *bank)
Destroy and excess power filter bank.
static double compute_unwhitened_mean_square(const LALExcessPowerFilterBank *filter_bank, unsigned channel, unsigned channels)
static REAL8TimeFrequencyPlane * XLALCreateTFPlane(unsigned tseries_length, double tseries_deltaT, double flow, double bandwidth, double tiling_fractional_stride, double max_tile_bandwidth, double max_tile_duration, const REAL8FFTPlan *plan)
Create and initialize a time-frequency plane object.
static void XLALDestroyTFPlane(REAL8TimeFrequencyPlane *plane)
Free a time-frequency plane object.
static int XLALFreqSeriesToTFPlane(REAL8TimeFrequencyPlane *plane, const LALExcessPowerFilterBank *filter_bank, const COMPLEX16FrequencySeries *fseries, const REAL8FFTPlan *reverseplan)
static LALExcessPowerFilterBank * XLALCreateExcessPowerFilterBank(double filter_deltaF, double flow, double channel_bandwidth, int n_channels, const REAL8FrequencySeries *psd, const REAL8Sequence *two_point_spectral_correlation)
From the power spectral density function, generate the comb of channel filters for the time-frequency...
static double min(double a, double b)
int XLALWriteLIGOLwXMLArrayREAL8TimeSeries(LIGOLwXMLStream *xml, const char *comment, const REAL8TimeSeries *series)
int XLALWriteLIGOLwXMLArrayCOMPLEX16FrequencySeries(LIGOLwXMLStream *xml, const char *comment, const COMPLEX16FrequencySeries *series)
int XLALWriteLIGOLwXMLArrayREAL8FrequencySeries(LIGOLwXMLStream *xml, const char *comment, const REAL8FrequencySeries *series)
int XLALOverlappedSegmentsCommensurate(int target_length, int segment_length, int segment_shift)
Round target_length down so that an integer number of intervals of length segment_length,...
SnglBurst * XLALEPSearch(LIGOLwXMLStream *diagnostics, const REAL8TimeSeries *tseries, REAL8Window *window, double flow, double bandwidth, double confidence_threshold, double fractional_stride, double maxTileBandwidth, double maxTileDuration)
Generate a linked list of burst events from a time series.
int XLALEPGetTimingParameters(int window_length, int max_tile_length, double fractional_tile_shift, int *psd_length, int *psd_shift, int *window_shift, int *window_pad, int *tiling_length)
Compute and return the timing parameters for an excess power analysis.
COMPLEX16FrequencySeries * XLALCreateExcessPowerFilter(double channel_flow, double channel_width, const REAL8FrequencySeries *psd, const REAL8Sequence *correlation)
Generate the frequency domain channel filter function.
double XLALExcessPowerFilterInnerProduct(const COMPLEX16FrequencySeries *filter1, const COMPLEX16FrequencySeries *filter2, const REAL8Sequence *correlation, const REAL8FrequencySeries *psd)
Compute the magnitude of the inner product of two arbitrary channel filters.
REAL8FrequencySeries * XLALCreateREAL8FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8FrequencySeries(REAL8FrequencySeries *series)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
double XLALLogChisqCCDF(double chi2, double dof)
void * XLALMalloc(size_t n)
RandomParams * XLALCreateRandomParams(INT4 seed)
int XLALNormalDeviates(REAL4Vector *deviates, RandomParams *params)
int XLALREAL8ReverseFFT(REAL8Vector *output, const COMPLEX16Vector *input, const REAL8FFTPlan *plan)
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
REAL8 XLALREAL8SequenceSum(const REAL8Sequence *sequence, size_t first, size_t count)
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
void XLALDestroyCOMPLEX16Sequence(COMPLEX16Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
COMPLEX16Sequence * XLALCreateCOMPLEX16Sequence(size_t length)
REAL8Sequence * XLALREAL8WindowTwoPointSpectralCorrelation(const REAL8Window *window, const REAL8FFTPlan *plan)
int XLALREAL8AverageSpectrumMedian(REAL8FrequencySeries *spectrum, const REAL8TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL8Window *window, const REAL8FFTPlan *plan)
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *tser, const REAL8FFTPlan *plan)
COMPLEX16FrequencySeries * XLALWhitenCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *fseries, const REAL8FrequencySeries *psd)
REAL8TimeSeries * XLALCutREAL8TimeSeries(const REAL8TimeSeries *series, size_t first, size_t length)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
const LALUnit lalDimensionlessUnit
REAL8Window * XLALCreateRectangularREAL8Window(UINT4 length)
void XLALDestroyREAL8Window(REAL8Window *window)
REAL8Sequence * XLALUnitaryWindowREAL8Sequence(REAL8Sequence *sequence, const REAL8Window *window)
REAL8Window * XLALCreateTukeyREAL8Window(UINT4 length, REAL8 beta)
#define XLAL_ERROR_NULL(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int XLALPrintProgressBar(double)
static _LAL_INLINE_ int XLALIsREAL8FailNaN(REAL8 val)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
double unwhitened_rms
root mean square of the unwhitened time series corresponding to this filter
COMPLEX16FrequencySeries * fseries
REAL8Sequence * unwhitened_cross
the mean square cross terms for wide channels (indices same as for twice_channel_overlap)
REAL8Sequence * twice_channel_overlap
twice the inner product of filters for neighbouring channels; twice_channel_overlap[0] is twice the i...
ExcessPowerFilter * basis_filters
double flow
low frequency boundary of TF plane
double deltaT
time resolution of the plane
REAL8Sequence * unwhitened_channel_buffer
UNDOCUMENTED.
int window_shift
by how many samples a window's start should be shifted from the start of the window preceding it
LIGOTimeGPS epoch
epoch of data from which this was computed
REAL8Window * window
time-domain window applied to input time series for tapering edges to 0
char name[LALNameLength]
name of data from which this was computed
REAL8Sequence * two_point_spectral_correlation
two-point spectral correlation of the whitened frequency series, computed from the time-domain window...
REAL8TimeFrequencyPlaneTiles tiles
time-frequency plane's tiling information
double deltaF
TF plane's frequency resolution (channel spacing)
REAL8Sequence * channel_buffer
re-usable holding area for the data for a single channel
gsl_matrix * channel_data
channel data.
double fseries_deltaF
input frequency series' resolution
unsigned inv_fractional_stride
struct tagSnglBurst * next