@@ -115,7 +115,21 @@ def _func_call(self) -> Callable:
115
115
116
116
@classmethod
117
117
def correct_bandpass (cls ):
118
- """ :class:`~nenupy.io.tf.TFTask` calling :func:`~nenupy.io.tf_utils.correct_bandpass` to correct the polyphase-filter bandpass reponse.
118
+ """ :class:`~nenupy.io.tf.TFTask` to correct for the sub-band bandpass response.
119
+
120
+ A Poly-Phase Filter is involved in the NenuFAR data acquisition pipeline to split the data stream into sub-bands.
121
+ The combination of the filter shape and a Fourier transform results in a non-flat response across each sub-band.
122
+ This :class:`~nenupy.io.tf.TFTask` calls the :func:`~nenupy.io.tf_utils.correct_bandpass` function.
123
+
124
+ Example
125
+ -------
126
+ .. code-block:: python
127
+ :emphasize-lines: 3
128
+
129
+ >>> from nenupy.io.tf import Spectra, TFTask, TFPipeline
130
+ >>> sp = Spectra("/my/file.spectra")
131
+ >>> sp.pipeline = TFPipeline(sp, TFTask.correct_bandpass())
132
+ >>> data = sp.get(...)
119
133
120
134
.. figure:: ./_images/io_images/tf_bandpass_correction.png
121
135
:width: 650
@@ -129,16 +143,28 @@ def wrapper_task(data, channels):
129
143
130
144
@classmethod
131
145
def flatten_subband (cls ):
132
- """_summary_
146
+ """ :class:`~nenupy.io.tf.TFTask` to flatten each sub-band bandpass.
147
+ Based on the temporal median over each suband, a linear correction is applied to flatten the signal.
148
+ This :class:`~nenupy.io.tf.TFTask` calls the :func:`~nenupy.io.tf_utils.flatten_subband` function.
149
+
150
+ Example
151
+ -------
152
+ .. code-block:: python
153
+ :emphasize-lines: 3
154
+
155
+ >>> from nenupy.io.tf import Spectra, TFTask, TFPipeline
156
+ >>> sp = Spectra("/my/file.spectra")
157
+ >>> sp.pipeline = TFPipeline(sp, TFTask.flatten_subband())
158
+ >>> data = sp.get(...)
133
159
134
160
.. figure:: ./_images/io_images/tf_sb_flatten.png
135
161
:width: 650
136
162
:align: center
137
163
138
164
Warning
139
165
-------
140
- This is a warning
141
-
166
+ This correction assumes that the signal's spectrum could be considered flat at the sub-band resolution.
167
+ The method is not recommended for data other than Stokes I.
142
168
143
169
"""
144
170
def wrapper_task (data , channels ):
@@ -169,6 +195,11 @@ def wrapper_task(data, channels, remove_channels):
169
195
170
196
@classmethod
171
197
def correct_polarization (cls ):
198
+ """_summary_
199
+
200
+ warning : needs to be done at the beginning.
201
+
202
+ """
172
203
def wrapper_task (
173
204
time_unix ,
174
205
frequency_hz ,
@@ -273,7 +304,32 @@ def wrapper_task(
273
304
274
305
@classmethod
275
306
def time_rebin (cls ):
276
- """_summary_
307
+ """ :class:`~nenupy.io.tf.TFTask` to re-bin the data in time.
308
+ The targetted time resolution is defined by the ``'rebin_dt'`` argument, set in :attr:`~nenupy.io.tf.TFPipeline.parameters`.
309
+ This :class:`~nenupy.io.tf.TFTask` calls the :func:`~nenupy.io.tf_utils.rebin_along_dimension` function.
310
+
311
+ Example
312
+ -------
313
+ .. code-block:: python
314
+
315
+ >>> from nenupy.io.tf import Spectra, TFTask, TFPipeline
316
+ >>> import astropy.units as u
317
+ >>> sp = Spectra("/my/file.spectra")
318
+ >>> sp.pipeline = TFPipeline(sp, TFTask.time_rebin())
319
+
320
+ Then, either perform a one_time application of the `rebin_dt` parameter (that is forgotten after the :meth:`~nenupy.io.tf.Spectra.get` call):
321
+
322
+ .. code-block:: python
323
+
324
+ >>> data = sp.get(..., rebin_dt=0.2*u.s,...)
325
+
326
+ Or, set it for further usage:
327
+
328
+ .. code-block:: python
329
+
330
+ >>> sp.pipeline.parameters["rebin_dt"] = 0.2*u.s
331
+ >>> data = sp.get(...)
332
+
277
333
278
334
.. figure:: ./_images/io_images/tf_time_rebin.png
279
335
:width: 650
@@ -652,7 +708,7 @@ class Spectra:
652
708
653
709
"""
654
710
655
- def __init__ (self , filename : str ):
711
+ def __init__ (self , filename : str , check_missing_data : bool = True ):
656
712
self .filename = filename
657
713
658
714
# Decode the main header and lazy load the data
@@ -664,7 +720,7 @@ def __init__(self, filename: str):
664
720
data = self ._lazy_load_data ()
665
721
666
722
# Compute the boolean mask of bad blocks
667
- bad_block_mask = self ._get_bad_data_mask (data )
723
+ bad_block_mask = self ._get_bad_data_mask (data , bypass_verification = ~ check_missing_data )
668
724
669
725
# Compute the main data block descriptors (time / frequency / beam)
670
726
subband_width_hz = SUBBAND_WIDTH .to_value (u .Hz )
@@ -915,12 +971,15 @@ def get(self, file_name: str = None, **pipeline_kwargs) -> SData:
915
971
else :
916
972
# Save the result of the pipeline in a file
917
973
# No security on the resulting data volume
974
+ log .info (f"Estimated data volume to store: { (data .nbytes * u .byte ).to (u .Gibyte ):.3f} ..." )
918
975
utils .store_dask_tf_data (
919
976
file_name = file_name ,
920
977
data = data ,
921
978
time = time ,
922
979
frequency = frequency ,
923
- polarization = ["XX" , "XY" , "YX" , "YY" ] if not self .pipeline .contains ("Compute Stokes parameters" ) else self .pipeline .parameters ["stokes" ]
980
+ polarization = ["XX" , "XY" , "YX" , "YY" ] if not self .pipeline .contains ("Compute Stokes parameters" ) else self .pipeline .parameters ["stokes" ],
981
+ mode = "w" if self .pipeline .parameters ["overwrite" ] else "auto" ,
982
+ beam = self .pipeline .parameters ["beam" ]
924
983
)
925
984
self .pipeline .parameters = parameters_copy # Reset the parameters
926
985
return
@@ -1159,9 +1218,13 @@ def _lazy_load_data(self) -> np.ndarray:
1159
1218
return tmp .view (np .dtype (global_struct ))
1160
1219
1161
1220
@staticmethod
1162
- def _get_bad_data_mask (data : np .ndarray ) -> np .ndarray :
1221
+ def _get_bad_data_mask (data : np .ndarray , bypass_verification : bool = False ) -> np .ndarray :
1163
1222
""" """
1164
1223
1224
+ if bypass_verification :
1225
+ log .info ("Skipping missing data verification..." )
1226
+ return np .zeros (data ["TIMESTAMP" ].size , dtype = bool )
1227
+
1165
1228
log .info ("Checking for missing data (can take up to 1 min)..." )
1166
1229
1167
1230
# Either the TIMESTAMP is set to 0, the first idx, or the SB number is negative
@@ -1278,4 +1341,3 @@ def _to_sdata(self, data: np.ndarray, time: Time, frequency: u.Quantity) -> SDat
1278
1341
freq = frequency ,
1279
1342
polar = self .pipeline .parameters ["stokes" ],
1280
1343
)
1281
-
0 commit comments