Skip to content

Commit bba4b66

Browse files
committed
add logging and delay as metadata
1 parent e7b8deb commit bba4b66

File tree

5 files changed

+57
-22
lines changed

5 files changed

+57
-22
lines changed

src/specsanalyzer/convert.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
"""Specsanalyzer image conversion module"""
22
from __future__ import annotations
33

4+
import logging
5+
46
import numpy as np
57
from scipy.ndimage import map_coordinates
68

9+
# Configure logging
10+
logger = logging.getLogger("specsanalyzer.specsscan")
11+
712

813
def get_damatrix_from_calib2d(
914
lens_mode: str,
@@ -82,7 +87,7 @@ def get_damatrix_from_calib2d(
8287

8388
elif lens_mode in supported_space_modes:
8489
# use the mode defaults
85-
print("This is a spatial mode, using default " + lens_mode + " config")
90+
logger.info("This is a spatial mode, using default " + lens_mode + " config")
8691
rr_vec, da_matrix_full = get_rr_da(lens_mode, calib2d_dict)
8792
a_inner = da_matrix_full[0][0]
8893
da_matrix = da_matrix_full[1:][:]

src/specsanalyzer/core.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@
2020
from specsanalyzer.convert import physical_unit_data
2121
from specsanalyzer.img_tools import crop_xarray
2222
from specsanalyzer.img_tools import fourier_filter_2d
23+
from specsanalyzer.logging import set_verbosity
24+
from specsanalyzer.logging import setup_logging
2325

2426
package_dir = os.path.dirname(__file__)
2527

28+
# Configure logging
29+
logger = setup_logging("specsanalyzer")
30+
2631

2732
class SpecsAnalyzer:
2833
"""SpecsAnalyzer: A class to convert photoemission data from a SPECS Phoibos analyzer from
@@ -38,19 +43,22 @@ def __init__(
3843
self,
3944
metadata: dict[Any, Any] = {},
4045
config: dict[Any, Any] | str = {},
46+
verbose: bool = True,
4147
**kwds,
4248
):
4349
"""SpecsAnalyzer constructor.
4450
4551
Args:
4652
metadata (dict, optional): Metadata dictionary. Defaults to {}.
4753
config (dict | str, optional): Metadata dictionary or file path. Defaults to {}.
54+
verbose (bool, optional): Disable info logs if set to False.
4855
**kwds: Keyword arguments passed to ``parse_config``.
4956
"""
5057
self._config = parse_config(
5158
config,
5259
**kwds,
5360
)
61+
set_verbosity(logger, verbose)
5462
self.metadata = metadata
5563
self._data_array = None
5664
self.print_msg = True
@@ -286,7 +294,7 @@ def convert_image(
286294
ek_min = range_dict["ek_min"]
287295
ek_max = range_dict["ek_max"]
288296
if self.print_msg:
289-
print("Using saved crop parameters...")
297+
logger.info("Using saved crop parameters...")
290298
data_array = crop_xarray(data_array, ang_min, ang_max, ek_min, ek_max)
291299
except KeyError:
292300
try:
@@ -343,11 +351,13 @@ def convert_image(
343351
+ data_array.coords[data_array.dims[1]][0]
344352
)
345353
if self.print_msg:
346-
print("Cropping parameters not found, using cropping ranges from config...")
354+
logger.info(
355+
"Cropping parameters not found, using cropping ranges from config...",
356+
)
347357
data_array = crop_xarray(data_array, ang_min, ang_max, ek_min, ek_max)
348358
except KeyError:
349359
if self.print_msg:
350-
print(
360+
logger.warning(
351361
"Warning: Cropping parameters not found, "
352362
"use method crop_tool() after loading.",
353363
)
@@ -402,7 +412,7 @@ def crop_tool(
402412
try:
403413
mesh_obj = data_array.plot(ax=ax)
404414
except AttributeError:
405-
print("Load the scan first!")
415+
logger.info("Load the scan first!")
406416
raise
407417

408418
lineh1 = ax.axhline(y=data_array.Angle[0])
@@ -650,7 +660,7 @@ def fft_tool(
650660

651661
filtered = fourier_filter_2d(raw_image, peaks=fft_filter_peaks, ret="filtered")
652662
except IndexError:
653-
print("Load the scan first!")
663+
logger.warning("Load the scan first!")
654664
raise
655665

656666
fig = plt.figure()

src/specsscan/core.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from specsanalyzer.io import to_h5
2222
from specsanalyzer.io import to_nexus
2323
from specsanalyzer.io import to_tiff
24+
from specsanalyzer.logging import set_verbosity
2425
from specsanalyzer.logging import setup_logging
2526
from specsscan.helpers import get_coords
2627
from specsscan.helpers import get_scan_path
@@ -50,13 +51,15 @@ def __init__(
5051
self,
5152
metadata: dict = {},
5253
config: dict | str = {},
54+
verbose: bool = True,
5355
**kwds,
5456
):
5557
"""SpecsScan constructor.
5658
5759
Args:
5860
metadata (dict, optional): Metadata dictionary. Defaults to {}.
5961
config (Union[dict, str], optional): Metadata dictionary or file path. Defaults to {}.
62+
verbose (bool, optional): Disable info logs if set to False.
6063
**kwds: Keyword arguments passed to ``parse_config``.
6164
"""
6265
self._config = parse_config(
@@ -65,6 +68,8 @@ def __init__(
6568
**kwds,
6669
)
6770

71+
set_verbosity(logger, verbose)
72+
6873
self.metadata = metadata
6974

7075
self._scan_info: dict[Any, Any] = {}
@@ -75,12 +80,14 @@ def __init__(
7580
folder_config={},
7681
user_config={},
7782
system_config={},
83+
verbose=verbose,
7884
)
7985
except KeyError:
8086
self.spa = SpecsAnalyzer(
8187
folder_config={},
8288
user_config={},
8389
system_config={},
90+
verbose=verbose,
8491
)
8592

8693
self._result: xr.DataArray = None
@@ -242,10 +249,11 @@ def load_scan(
242249
k: coordinate_mapping[k] for k in coordinate_mapping.keys() if k in res_xarray.dims
243250
}
244251
depends_dict = {
245-
rename_dict[k]: coordinate_depends[k]
252+
rename_dict.get(k, k): coordinate_depends[k]
246253
for k in coordinate_depends.keys()
247254
if k in res_xarray.dims
248255
}
256+
249257
res_xarray = res_xarray.rename(rename_dict)
250258
for k, v in coordinate_mapping.items():
251259
if k in fast_axes:
@@ -260,6 +268,7 @@ def load_scan(
260268
"/entry/sample/transformations/sample_polar": "Polar",
261269
"/entry/sample/transformations/sample_tilt": "Tilt",
262270
"/entry/sample/transformations/sample_azimuth": "Azimuth",
271+
"/entry/instrument/beam_pump/pulse_delay": "delay",
263272
}
264273

265274
# store data for resolved axis coordinates

src/specsscan/helpers.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22
from __future__ import annotations
33

44
import datetime as dt
5+
import logging
56
from pathlib import Path
67
from typing import Any
78
from typing import Sequence
89

910
import numpy as np
1011
import pandas as pd
12+
import xarray as xr
1113
from tqdm.auto import tqdm
1214

1315
from specsanalyzer.config import complete_dictionary
1416
from specsscan.metadata import MetadataRetriever
1517

18+
# Configure logging
19+
logger = logging.getLogger("specsanalyzer.specsscan")
20+
1621

1722
def get_scan_path(path: Path | str, scan: int, basepath: Path | str) -> Path:
1823
"""Returns the path to the given scan.
@@ -123,7 +128,7 @@ def load_images(
123128
"load_scan method.",
124129
) from exc
125130

126-
print(f"Averaging over {avg_dim}...")
131+
logger.info(f"Averaging over {avg_dim}...")
127132
for dim in tqdm(raw_2d_sliced):
128133
avg_list = []
129134
for image in tqdm(dim, leave=False, disable=not tqdm_enable_nested):
@@ -210,14 +215,14 @@ def parse_lut_to_df(scan_path: Path) -> pd.DataFrame:
210215
df_lut.reset_index(inplace=True)
211216

212217
new_cols = df_lut.columns.to_list()[1:]
213-
new_cols[new_cols.index("delaystage")] = "Delay"
218+
new_cols[new_cols.index("delaystage")] = "DelayStage"
214219
new_cols.insert(3, "delay (fs)") # Create label to drop the column later
215220

216221
df_lut = df_lut.set_axis(new_cols, axis="columns")
217222
df_lut.drop(columns="delay (fs)", inplace=True)
218223

219224
except FileNotFoundError:
220-
print(
225+
logger.info(
221226
"LUT.txt not found. Storing metadata from info.txt",
222227
)
223228
return None
@@ -265,7 +270,7 @@ def get_coords(
265270
return (np.array([]), "")
266271

267272
if df_lut is not None:
268-
print("scanvector.txt not found. Obtaining coordinates from LUT")
273+
logger.info("scanvector.txt not found. Obtaining coordinates from LUT")
269274

270275
df_new: pd.DataFrame = df_lut.loc[:, df_lut.columns[2:]]
271276

@@ -276,13 +281,18 @@ def get_coords(
276281
raise FileNotFoundError("scanvector.txt file not found!") from exc
277282

278283
if scan_type == "delay":
279-
t_0 = scan_info["TimeZero"]
280-
coords -= t_0
281-
coords *= 2 / 3e11 * 1e15
284+
t0 = scan_info["TimeZero"]
285+
coords = mm_to_fs(coords, t0)
282286

283287
return coords, dim
284288

285289

290+
def mm_to_fs(delaystage: xr.DataArray | np.ndarray | float, t0: float) -> float:
291+
delay = delaystage - t0
292+
delay *= 2 / 2.99792458e11 * 1e15
293+
return delay
294+
295+
286296
def compare_coords(axis_data: np.ndarray) -> tuple[np.ndarray, int]:
287297
"""Identifies the most changing column in a given 2-D numpy array.
288298
@@ -338,6 +348,9 @@ def parse_info_to_dict(path: Path) -> dict:
338348
except FileNotFoundError as exc:
339349
raise FileNotFoundError("info.txt file not found.") from exc
340350

351+
if "DelayStage" in info_dict and "TimeZero" in info_dict:
352+
info_dict["delay"] = mm_to_fs(info_dict["DelayStage"], info_dict["TimeZero"])
353+
341354
return info_dict
342355

343356

@@ -377,7 +390,7 @@ def handle_meta(
377390
if metadata is None:
378391
metadata = {}
379392

380-
print("Gathering metadata from different locations")
393+
logger.info("Gathering metadata from different locations")
381394
# get metadata from LUT dataframe
382395
lut_meta = {}
383396
energy_scan_mode = "snapshot"
@@ -395,10 +408,10 @@ def handle_meta(
395408

396409
metadata["scan_info"] = complete_dictionary(
397410
metadata.get("scan_info", {}),
398-
complete_dictionary(lut_meta, scan_info),
411+
complete_dictionary(scan_info, lut_meta),
399412
) # merging dictionaries
400413

401-
print("Collecting time stamps...")
414+
logger.info("Collecting time stamps...")
402415
if "time" in metadata["scan_info"]:
403416
time_list = [metadata["scan_info"]["time"][0], metadata["scan_info"]["time"][-1]]
404417
elif "StartTime" in metadata["scan_info"]:
@@ -445,8 +458,6 @@ def handle_meta(
445458
metadata["scan_info"]["slow_axes"] = slow_axes
446459
metadata["scan_info"]["fast_axes"] = fast_axes
447460

448-
print("Done!")
449-
450461
return metadata
451462

452463

@@ -460,7 +471,7 @@ def find_scan(path: Path, scan: int) -> list[Path]:
460471
Returns:
461472
List[Path]: scan_path: Path object pointing to the scan folder
462473
"""
463-
print("Scan path not provided, searching directories...")
474+
logger.info("Scan path not provided, searching directories...")
464475
for file in path.iterdir():
465476
if file.is_dir():
466477
try:
@@ -474,7 +485,7 @@ def find_scan(path: Path, scan: int) -> list[Path]:
474485
file.glob(f"*/*/Raw Data/{scan}"),
475486
)
476487
if scan_path:
477-
print("Scan found at path:", scan_path[0])
488+
logger.info(f"Scan found at path: {scan_path[0]}")
478489
break
479490
else:
480491
scan_path = []

src/specsscan/metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def fetch_epics_metadata(self, ts_from: float, ts_to: float, metadata: dict) ->
9090
for key in list(metadata["scan_info"]):
9191
if key.lower() in replace_dict:
9292
metadata["scan_info"][replace_dict[key.lower()]] = metadata["scan_info"][key]
93-
metadata["scan_info"].pop(key)
93+
del metadata["scan_info"][key]
9494
epics_channels = replace_dict.values()
9595
except KeyError:
9696
epics_channels = []

0 commit comments

Comments
 (0)