or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

astrophysics.mddetector.mdfrequencyseries.mdindex.mdplotting.mdsegments.mdsignal-processing.mdspectrogram.mdtimeseries.md

frequencyseries.mddocs/

0

# Frequency Domain Analysis

1

2

Spectral analysis tools for power spectral densities, amplitude spectral densities, and frequency-domain filtering. GWpy's FrequencySeries class provides comprehensive support for frequency-domain gravitational-wave data analysis and detector characterization.

3

4

## Capabilities

5

6

### FrequencySeries - Frequency Domain Data Class

7

8

Primary class for handling frequency-domain data including power spectral densities (PSDs), amplitude spectral densities (ASDs), and transfer functions.

9

10

```python { .api }

11

class FrequencySeries(Series):

12

def __init__(self, data, frequencies=None, f0=None, df=None,

13

unit=None, name=None, **kwargs):

14

"""

15

Create a new FrequencySeries.

16

17

Parameters:

18

- data: array-like, frequency series data values

19

- frequencies: array-like, frequency values for each sample

20

- f0: float, starting frequency (Hz)

21

- df: float, frequency spacing (Hz)

22

- unit: str or Unit, physical unit of the data

23

- name: str, name for this series

24

"""

25

26

@classmethod

27

def read(cls, source, format=None, **kwargs):

28

"""

29

Read FrequencySeries from file.

30

31

Parameters:

32

- source: str, path to data file

33

- format: str, file format ('txt', 'hdf5', 'ligolw')

34

35

Returns:

36

FrequencySeries object

37

"""

38

39

def plot(self, **kwargs):

40

"""

41

Create a plot of the frequency series.

42

43

Returns:

44

Plot object

45

"""

46

47

def zpk(self, zeros, poles, gain, **kwargs):

48

"""

49

Filter using zero-pole-gain representation.

50

51

Parameters:

52

- zeros: array-like, filter zeros

53

- poles: array-like, filter poles

54

- gain: float, filter gain

55

56

Returns:

57

Filtered FrequencySeries

58

"""

59

60

def crop(self, start=None, end=None, copy=True):

61

"""

62

Crop to specific frequency range.

63

64

Parameters:

65

- start: float, start frequency

66

- end: float, end frequency

67

- copy: bool, return copy or view

68

69

Returns:

70

Cropped FrequencySeries

71

"""

72

73

def interpolate(self, df, **kwargs):

74

"""

75

Interpolate to new frequency spacing.

76

77

Parameters:

78

- df: float, new frequency resolution

79

80

Returns:

81

Interpolated FrequencySeries

82

"""

83

84

def inject(self, other, **kwargs):

85

"""

86

Inject another frequency series.

87

88

Parameters:

89

- other: FrequencySeries, series to inject

90

91

Returns:

92

Combined FrequencySeries

93

"""

94

95

def write(self, target, format=None, **kwargs):

96

"""

97

Write FrequencySeries to file.

98

99

Parameters:

100

- target: str, output file path

101

- format: str, output format

102

"""

103

```

104

105

### SpectralVariance - 2D Spectral Variance Analysis

106

107

Two-dimensional histogram for analyzing spectral variance and identifying non-stationary noise sources.

108

109

```python { .api }

110

class SpectralVariance(Array2D):

111

def __init__(self, data, bins=None, **kwargs):

112

"""

113

2D histogram for spectral variance analysis.

114

115

Parameters:

116

- data: 2D array, spectral variance data

117

- bins: array-like, histogram bin edges

118

"""

119

120

@classmethod

121

def from_spectrogram(cls, spectrogram, **kwargs):

122

"""

123

Calculate spectral variance from spectrogram.

124

125

Parameters:

126

- spectrogram: Spectrogram, input data

127

128

Returns:

129

SpectralVariance object

130

"""

131

132

def plot(self, **kwargs):

133

"""

134

Plot the spectral variance.

135

136

Returns:

137

Plot object

138

"""

139

```

140

141

### Usage Examples

142

143

#### Power Spectral Density Analysis

144

145

```python

146

from gwpy.timeseries import TimeSeries

147

from gwpy.frequencyseries import FrequencySeries

148

149

# Calculate PSD from time series

150

strain = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478)

151

psd = strain.psd(fftlength=4, overlap=2)

152

153

# Plot PSD

154

plot = psd.plot()

155

plot.set_xlabel('Frequency [Hz]')

156

plot.set_ylabel('Power Spectral Density [strain^2/Hz]')

157

plot.set_yscale('log')

158

plot.show()

159

160

# Read PSD from file

161

ref_psd = FrequencySeries.read('reference_psd.txt')

162

163

# Compare PSDs

164

ratio = psd / ref_psd

165

ratio.plot()

166

```

167

168

#### Amplitude Spectral Density

169

170

```python

171

# Calculate ASD (square root of PSD)

172

asd = strain.asd(fftlength=4)

173

174

# Plot with proper scaling

175

plot = asd.plot()

176

plot.set_xlabel('Frequency [Hz]')

177

plot.set_ylabel('Amplitude Spectral Density [strain/√Hz]')

178

plot.set_yscale('log')

179

plot.set_xlim(10, 2000)

180

plot.show()

181

```

182

183

#### Frequency Domain Filtering

184

185

```python

186

from scipy.signal import butter

187

188

# Design filter in zpk format

189

z, p, k = butter(8, [30, 400], btype='bandpass', fs=4096, output='zpk')

190

191

# Apply filter to frequency series data

192

filtered_psd = psd.zpk(z, p, k)

193

194

# Crop to analysis band

195

analysis_psd = psd.crop(20, 2000)

196

```

197

198

#### Working with Transfer Functions

199

200

```python

201

# Read calibration transfer function

202

cal_response = FrequencySeries.read('calibration_response.txt',

203

format='txt')

204

205

# Apply calibration correction

206

calibrated_psd = raw_psd * cal_response

207

208

# Plot magnitude and phase

209

fig, axes = plt.subplots(2, 1, sharex=True)

210

211

# Magnitude

212

axes[0].loglog(cal_response.frequencies, abs(cal_response))

213

axes[0].set_ylabel('Magnitude')

214

215

# Phase

216

axes[1].semilogx(cal_response.frequencies,

217

np.angle(cal_response, deg=True))

218

axes[1].set_ylabel('Phase [degrees]')

219

axes[1].set_xlabel('Frequency [Hz]')

220

```

221

222

#### Spectral Variance Analysis

223

224

```python

225

from gwpy.frequencyseries import SpectralVariance

226

227

# Calculate spectrogram first

228

spec = strain.spectrogram(stride=60, fftlength=4)

229

230

# Create spectral variance histogram

231

variance = SpectralVariance.from_spectrogram(spec,

232

bins=50,

233

low=1e-24,

234

high=1e-20)

235

236

# Plot spectral variance

237

plot = variance.plot()

238

plot.set_xlabel('Frequency [Hz]')

239

plot.set_ylabel('Amplitude Spectral Density [strain/√Hz]')

240

plot.show()

241

```

242

243

#### Noise Budget Analysis

244

245

```python

246

# Read multiple PSDs for noise budget

247

psds = {}

248

channels = ['H1:CAL-DELTAL_EXTERNAL_DQ',

249

'H1:ASC-AS_A_RF45_I_ERR_DQ',

250

'H1:LSC-DARM_IN1_DQ']

251

252

for channel in channels:

253

ts = TimeSeries.get(channel, start, end)

254

psds[channel] = ts.psd(fftlength=8)

255

256

# Plot noise budget

257

plot = FrequencySeries.plot(figsize=(12, 6))

258

for name, psd in psds.items():

259

plot.add_frequencyseries(psd, label=name)

260

261

plot.set_xlabel('Frequency [Hz]')

262

plot.set_ylabel('Power Spectral Density')

263

plot.set_yscale('log')

264

plot.legend()

265

plot.show()

266

```

267

268

#### Cross-Spectral Density

269

270

```python

271

# Calculate cross-spectral density between channels

272

witness = TimeSeries.get('H1:ASC-AS_A_RF45_I_ERR_DQ', start, end)

273

strain = TimeSeries.get('H1:DCS-CALIB_STRAIN_C02', start, end)

274

275

# Cross-spectral density

276

csd = strain.csd(witness, fftlength=4, overlap=2)

277

278

# Coherence calculation

279

coherence = strain.coherence(witness, fftlength=4, overlap=2)

280

281

# Plot coherence

282

plot = coherence.plot()

283

plot.set_xlabel('Frequency [Hz]')

284

plot.set_ylabel('Coherence')

285

plot.set_ylim(0, 1)

286

plot.show()

287

```