|
15 | 15 | from pathlib import Path
|
16 | 16 |
|
17 | 17 | import dask.dataframe as dd
|
| 18 | +import h5py |
| 19 | +import numpy as np |
| 20 | +import scipy.interpolate as sint |
18 | 21 | from natsort import natsorted
|
19 | 22 |
|
20 | 23 | from sed.core.logging import set_verbosity
|
|
27 | 30 | logger = setup_logging("flash_loader")
|
28 | 31 |
|
29 | 32 |
|
| 33 | +def get_count_rate( |
| 34 | + h5file: h5py.File, |
| 35 | + ms_markers_key: str = "msMarkers", |
| 36 | +) -> tuple[np.ndarray, np.ndarray]: |
| 37 | + """Create count rate in the file from the msMarker column. |
| 38 | +
|
| 39 | + Args: |
| 40 | + h5file (h5py.File): The h5file from which to get the count rate. |
| 41 | + ms_markers_key (str, optional): The hdf5 path where the millisecond markers |
| 42 | + are stored. Defaults to "msMarkers". |
| 43 | +
|
| 44 | + Returns: |
| 45 | + tuple[np.ndarray, np.ndarray]: The count rate in Hz and the seconds into the |
| 46 | + scan. |
| 47 | + """ |
| 48 | + ms_markers = np.asarray(h5file[ms_markers_key]) |
| 49 | + secs = np.arange(0, len(ms_markers)) / 1000 |
| 50 | + msmarker_spline = sint.InterpolatedUnivariateSpline(secs, ms_markers, k=1) |
| 51 | + rate_spline = msmarker_spline.derivative() |
| 52 | + count_rate = rate_spline(secs) |
| 53 | + |
| 54 | + return (count_rate, secs) |
| 55 | + |
| 56 | + |
30 | 57 | class CFELLoader(BaseLoader):
|
31 | 58 | """
|
32 | 59 | The class generates multiindexed multidimensional pandas dataframes from the new FLASH
|
@@ -137,7 +164,7 @@ def _initialize_dirs(self) -> None:
|
137 | 164 | raw_dir = raw_paths[0].resolve()
|
138 | 165 |
|
139 | 166 | processed_dir = beamtime_dir.joinpath("processed")
|
140 |
| - meta_dir = beamtime_dir.joinpath("meta/fabtrack/") |
| 167 | + meta_dir = beamtime_dir.joinpath("meta/fabtrack/") # cspell:ignore fabtrack |
141 | 168 |
|
142 | 169 | processed_dir.mkdir(parents=True, exist_ok=True)
|
143 | 170 |
|
@@ -254,10 +281,61 @@ def parse_local_metadata(self) -> dict:
|
254 | 281 |
|
255 | 282 | def get_count_rate(
|
256 | 283 | self,
|
257 |
| - fids: Sequence[int] = None, # noqa: ARG002 |
258 |
| - **kwds, # noqa: ARG002 |
259 |
| - ): |
260 |
| - return None, None |
| 284 | + fids: Sequence[int] = None, |
| 285 | + **kwds, |
| 286 | + ) -> tuple[np.ndarray, np.ndarray]: |
| 287 | + """Create count rate from the msMarker column for the files specified in |
| 288 | + ``fids``. |
| 289 | +
|
| 290 | + Args: |
| 291 | + fids (Sequence[int], optional): fids (Sequence[int]): the file ids to |
| 292 | + include. Defaults to list of all file ids. |
| 293 | + kwds: Keyword arguments: |
| 294 | +
|
| 295 | + - **ms_markers_key**: HDF5 path of the ms-markers |
| 296 | +
|
| 297 | + Returns: |
| 298 | + tuple[np.ndarray, np.ndarray]: Arrays containing countrate and seconds |
| 299 | + into the scan. |
| 300 | + """ |
| 301 | + if fids is None: |
| 302 | + fids = range(0, len(self.files)) |
| 303 | + |
| 304 | + ms_markers_key = kwds.pop( |
| 305 | + "ms_markers_key", |
| 306 | + self._config.get("dataframe", {}).get( |
| 307 | + "ms_markers_key", |
| 308 | + "msMarkers", |
| 309 | + ), |
| 310 | + ) |
| 311 | + |
| 312 | + if len(kwds) > 0: |
| 313 | + raise TypeError(f"get_count_rate() got unexpected keyword arguments {kwds.keys()}.") |
| 314 | + |
| 315 | + secs_list = [] |
| 316 | + count_rate_list = [] |
| 317 | + accumulated_time = 0 |
| 318 | + for fid in fids: |
| 319 | + try: |
| 320 | + count_rate_, secs_ = get_count_rate( |
| 321 | + h5py.File(self.files[fid]), |
| 322 | + ms_markers_key=ms_markers_key, |
| 323 | + ) |
| 324 | + secs_list.append((accumulated_time + secs_).T) |
| 325 | + count_rate_list.append(count_rate_.T) |
| 326 | + accumulated_time += secs_[-1] |
| 327 | + except OSError as exc: |
| 328 | + if "Unable to synchronously open file" in str(exc): |
| 329 | + logger.warning( |
| 330 | + f"Unable to open file {fid}: {str(exc)}. " |
| 331 | + "Most likely the file is incomplete.", |
| 332 | + ) |
| 333 | + pass |
| 334 | + |
| 335 | + count_rate = np.concatenate(count_rate_list) |
| 336 | + secs = np.concatenate(secs_list) |
| 337 | + |
| 338 | + return count_rate, secs |
261 | 339 |
|
262 | 340 | def get_elapsed_time(self, fids: Sequence[int] = None, **kwds) -> float | list[float]: # type: ignore[override]
|
263 | 341 | """
|
|
0 commit comments