GWOLLUM
4.2.0
Tools for gravitational-wave analyses
|
Compute the noise power spectral density. More...
#include <Spectrum.h>
Public Member Functions | |
bool | AddData (const unsigned int aDataSize, const double *aData, const unsigned int aDataStart=0) |
Loads a data vector and updates the current PSD. More... | |
double | GetAmplitude (const double aFrequency) |
Returns the current ASD value at a given frequency. More... | |
TGraph * | GetAmplitudePeriodogram (const unsigned int aParity, const unsigned int aIndex) |
Returns a copy of a given (amplitude) periodogram. More... | |
TGraph * | GetASD (const double aFrequencyMin, const double aFrequencyMax) |
Returns a copy of the current ASD as a TGraph between 2 frequencies. More... | |
TGraph * | GetASD (void) |
Returns a copy of the current ASD as a TGraph. More... | |
unsigned int | GetDataBufferLength (void) |
Returns the effective circular buffer length [s] used to compute the PSD. More... | |
unsigned int | GetNSubSegmentsMax (const unsigned int aParity) |
Returns the maximum number of sub-segments in the buffer. More... | |
TGraph * | GetPeriodogram (const unsigned int aParity, const unsigned int aIndex) |
Returns a copy of a given periodogram. More... | |
double | GetPower (const double aFrequency) |
Returns the current PSD value at a given frequency. More... | |
double | GetPower (const unsigned int aFrequencyIndex) |
Returns the current PSD value at a given frequency index. More... | |
TGraph * | GetPSD (const double aFrequencyMin, const double aFrequencyMax) |
Returns a copy of the current PSD as a TGraph between 2 frequencies. More... | |
TGraph * | GetPSD (void) |
Returns a copy of the current PSD as a TGraph. More... | |
double | GetSpectrumFrequency (const unsigned int aIndex) |
Returns the frequency of a given spectrum frequency index [Hz]. More... | |
unsigned int | GetSpectrumNyquist (void) |
Returns the Nyquist frequency of the spectrum [Hz]. More... | |
double | GetSpectrumResolution (void) |
Returns the frequency resolution of the spectrum [Hz]: \(\delta f\). More... | |
unsigned int | GetSpectrumSize (void) |
Returns the number of points in the spectrum: \(n\). More... | |
bool | LoadData (const unsigned int aDataSize, const double *aData, const unsigned int aDataStart=0) |
Loads a data vector and computes a new PSD. More... | |
void | Reset (void) |
Resets the current PSD and the periodogram circular buffer. More... | |
bool | WritePeriodogram (const string aOutFileName) |
Writes periodograms and the resulting PSD in a ROOT file. More... | |
Constructors and destructors | |
Spectrum (const unsigned int aSpectrumSize, const unsigned int aDataDuration, const unsigned int aDataSamplingFrequency, const unsigned int aVerbosity=0) | |
Constructor of the Spectrum class. More... | |
virtual | ~Spectrum (void) |
Destructor of the Spectrum class. More... | |
Private Member Functions | |
void | ComputeMedianMean (void) |
Computes median-mean PSD. More... | |
Private Attributes | |
fft * | fft_psd |
FFT plan to compute the PSD. More... | |
unsigned int | fVerbosity |
Verbosity level. More... | |
double * | HannWindow |
Hann window vector. More... | |
unsigned int | nSubSegments [2] |
Number of even/odd sub-subsegments. More... | |
double ** | periodogram [2] |
Buffer for periodograms. More... | |
unsigned int | sampling |
Data sampling frequency [Hz]. More... | |
unsigned int | write_index [2] |
Write index in the buffer. More... | |
Compute the noise power spectral density.
This class is designed to estimate the one-sided noise power spectral density of a given stretch of data (PSD). It uses the median-mean method described in gr-qc/0509116. This method can be represented by the diagram below:
The input data is divided into \(N_e\) "even" subsegments and \(N_o\) "odd" subsegments (Spectrum::Spectrum()) of duration \(T_s\). Odd and even subsegments overlap by 50%. The number of subsegments, \(N_e\) and \(N_o\), is given by the duration of the input data \(T\) and the requested frequency resolution for the PSD. The input data is sampled at a frequency \(f_s\); therefore the total number of data points is \(N = T\times f_s\). The PSD frequency resolution \(\delta f\) is defined by the number of points, \(n = f_s/(2\delta f)\), to cover frequencies from 0 Hz to the Nyquist frequency, \(f_s/2\). We have:
\[ \begin{cases} N_e = \lfloor{ \frac{T}{T_s} }\rfloor = \lfloor{ \frac{N}{2n} }\rfloor = \lfloor{ \frac{N\delta f}{f_s} } \rfloor \\ N_o = \lfloor{ \frac{T-T_s/2}{T_s} }\rfloor = \lfloor{ \frac{N-n}{2n} }\rfloor \end{cases} \]
Each subsegment \(d_i(t)\) is hann-windowed with \(w(t)\) and Fourier transformed: \(\widetilde{(wd_i)}(f)\). Then, periodograms \(P_i(f)\) are evaluated for each subsegment:
\[ P_i(f) = \frac{2}{T_s}\left| \widetilde{(wd_i)}(f)\right|^2 \]
A median PSD is computed using periodograms for odd and even subsegments separately and a median-to-mean correction factor is applied (medianbiasfactor()). The 2 PSDs are finally averaged into one.
In fact, a dynamical PSD estimation is implemented here. The number of even and odd sub-segments is defined and fixed in the constructor of this class (Spectrum::Spectrum()). This defines a circular buffer of periodograms. Then, segments of data are provided with the AddData() method. This segment of data is used to compute periodograms, fill the circular buffer, and update the PSD estimate.
Spectrum::Spectrum | ( | const unsigned int | aSpectrumSize, |
const unsigned int | aDataDuration, | ||
const unsigned int | aDataSamplingFrequency, | ||
const unsigned int | aVerbosity = 0 |
||
) |
Constructor of the Spectrum class.
It defines the data sizes and initiates the FFT plan (FFTW_MEASURE). The spectrum resolution is defined by the number of points used to compute the data spectrum: \(n\). A nominal duration over which the PSD is estimated must be given: \(T\). A circular buffer of sub-segments is defined and is used to apply the median-mean method.
[in] | aSpectrumSize | Number of points in the spectrum (one sided): \(n\). |
[in] | aDataDuration | Nominal data duration to estimate the PSD [s]: \(T\). |
[in] | aDataSamplingFrequency | Input data sampling frequency [Hz]: \(f_s\). |
[in] | aVerbosity | Verbosity level. |
|
virtual |
Destructor of the Spectrum class.
bool Spectrum::AddData | ( | const unsigned int | aDataSize, |
const double * | aData, | ||
const unsigned int | aDataStart = 0 |
||
) |
Loads a data vector and updates the current PSD.
The data 'aData' is used to update the current PSD. The user must specify the size of the input data. If the size of the input data is smaller than the size specified in the constructor, the circular buffer is updated with this new data set. The oldest periodograms in the buffer are removed. If the size of the input data is larger than the size specified in the constructor, only the end of the input data is considered.
The input data is broken into odd and even subsegments as described in this class introduction. The periodograms are computed and saved in the circular buffer. Finally, a new PSD is estimated.
[in] | aDataSize | Input vector size (number of points) starting at aDataStart. |
[in] | aData | Input time series. |
[in] | aDataStart | First data index to consider for the PSD estimation. |
|
private |
Computes median-mean PSD.
|
inline |
Returns the current ASD value at a given frequency.
The ASD value is the square root of the PSD returned with GetPower().
[in] | aFrequency | Frequency value [Hz]. |
TGraph * Spectrum::GetAmplitudePeriodogram | ( | const unsigned int | aParity, |
const unsigned int | aIndex | ||
) |
Returns a copy of a given (amplitude) periodogram.
[in] | aParity | 0 for even subsegments, 1 for odd subsegments. |
[in] | aIndex | Subsegment index. |
TGraph * Spectrum::GetASD | ( | const double | aFrequencyMin, |
const double | aFrequencyMax | ||
) |
Returns a copy of the current ASD as a TGraph between 2 frequencies.
[in] | aFrequencyMin | Minimum frequency value [Hz]. |
[in] | aFrequencyMax | Maximum frequency value [Hz]. |
TGraph * Spectrum::GetASD | ( | void | ) |
Returns a copy of the current ASD as a TGraph.
|
inline |
Returns the effective circular buffer length [s] used to compute the PSD.
|
inline |
Returns the maximum number of sub-segments in the buffer.
[in] | aParity | 0 for even subsegments, 1 for odd subsegments |
TGraph * Spectrum::GetPeriodogram | ( | const unsigned int | aParity, |
const unsigned int | aIndex | ||
) |
Returns a copy of a given periodogram.
[in] | aParity | 0 for even subsegments, 1 for odd subsegments. |
[in] | aIndex | Subsegment index. |
double Spectrum::GetPower | ( | const double | aFrequency | ) |
Returns the current PSD value at a given frequency.
The power value is computed by interpolating the PSD if the requested frequency is inside the PSD frequency range (0 to Nyquist). If it is outside this range, the PSD is extrapolated.
[in] | aFrequency | Frequency value [Hz]. |
|
inline |
Returns the current PSD value at a given frequency index.
aFrequencyIndex | Frequency index. |
TGraph * Spectrum::GetPSD | ( | const double | aFrequencyMin, |
const double | aFrequencyMax | ||
) |
Returns a copy of the current PSD as a TGraph between 2 frequencies.
[in] | aFrequencyMin | Minimum frequency value [Hz]. |
[in] | aFrequencyMax | Maximum frequency value [Hz]. |
TGraph * Spectrum::GetPSD | ( | void | ) |
Returns a copy of the current PSD as a TGraph.
|
inline |
Returns the frequency of a given spectrum frequency index [Hz].
[in] | aIndex | Frequency index (0=DC). |
|
inline |
Returns the Nyquist frequency of the spectrum [Hz].
|
inline |
Returns the frequency resolution of the spectrum [Hz]: \(\delta f\).
|
inline |
Returns the number of points in the spectrum: \(n\).
bool Spectrum::LoadData | ( | const unsigned int | aDataSize, |
const double * | aData, | ||
const unsigned int | aDataStart = 0 |
||
) |
Loads a data vector and computes a new PSD.
This function is the same as AddData() but the PSD circular buffer is flushed before loading the new data vector.
[in] | aDataSize | Input vector size (number of samples) starting at aDataStart |
[in] | aData | Input time series. |
[in] | aDataStart | First data index to consider for the PSD estimation. |
void Spectrum::Reset | ( | void | ) |
Resets the current PSD and the periodogram circular buffer.
The periodogram buffer is flushed. The current PSD is set to 0.
bool Spectrum::WritePeriodogram | ( | const string | aOutFileName | ) |
Writes periodograms and the resulting PSD in a ROOT file.
[in] | aOutFileName | ROOT output file name (use a ".root" extension). |
|
private |
FFT plan to compute the PSD.
|
private |
Verbosity level.
|
private |
Hann window vector.
|
private |
Number of even/odd sub-subsegments.
|
private |
Buffer for periodograms.
|
private |
Data sampling frequency [Hz].
|
private |
Write index in the buffer.