diff --git a/maxwell_integrate_to_h5.py b/maxwell_integrate_to_h5.py index 5976eb6b493599d384070890ba8fca50520ced97..dc5b14caec94065f03f9bc82a847262e667c40f5 100644 --- a/maxwell_integrate_to_h5.py +++ b/maxwell_integrate_to_h5.py @@ -136,44 +136,117 @@ def integrate_ims_in_dir(path_im, path_int, dtype_im=".tif", dtype_int=".dat"): print(f"File {output_file} already exists. Removing it to create a new one.") os.remove(output_file) - with h5py.File(output_file, "w") as f: - # Top-level NXroot - nxroot = f.create_group(subdir_name) - nxroot.attrs["NX_class"] = np.string_("NXroot") - nxroot.attrs["default"] = np.string_("1.1") + + with h5py.File(output_file, "w") as h5: + entry = h5.create_group(f"/{subdir_name}") + entry.attrs["NX_class"] = "NXentry" + entry.attrs["default"] = "last_plot" # reference to the last spectrum for idx, result in enumerate(results_data, start=1): - entry_name = f"{idx}.1" - entry = nxroot.create_group(entry_name) - entry.attrs["NX_class"] = np.string_("NXentry") - entry.attrs["default"] = np.string_("plotdata") - - # Create full measurement group - meas = entry.create_group("measurement") - meas.attrs["NX_class"] = np.string_("NXcollection") - meas.attrs["filename"] = np.string_(result["filename"]) - - meas.create_dataset("q", data=result["q"]) - meas.create_dataset("I", data=result["I"]) - meas.create_dataset("dI", data=result["dI"]) - - # Create plotdata group with proper NXdata spec - plot = entry.create_group("plotdata") - plot.attrs["NX_class"] = np.string_("NXdata") - plot.attrs["signal"] = np.string_("I") - plot.attrs["axes"] = np.string_("q") - plot.attrs["title"] = np.string_(result["filename"]) - - plot.create_dataset("q", data=result["q"]) - dset_I = plot.create_dataset("I", data=result["I"]) - dset_I.attrs["long_name"] = np.string_(result["filename"]) - plot["I"].attrs["long_name"] = "Intensity" - plot["q"].attrs["long_name"] = "Ang^-1" - - plot.create_dataset("dI", data=result["dI"]) - plot["dI"].attrs["long_name"] = np.string_("Uncertainty in I") + scan_name = f"{idx:03d}" # e.g., '001' + scan_group = entry.create_group(scan_name) + + # Instrument / Detector group + detector = scan_group.create_group("instrument/detector") + detector.attrs["NX_class"] = "NXdetector" + chunk_size = min(len(result["I"]), 1000) + + detector.create_dataset("q", data=np.asarray(result["q"], dtype=np.float64), chunks=(chunk_size,)) + detector.create_dataset("I", data=np.asarray(result["I"], dtype=np.float64), chunks=(chunk_size,)) + detector.create_dataset("dI", data=np.asarray(result["dI"], dtype=np.float64), chunks=(chunk_size,)) + + # Add interpretation info (optional for PyMca) + detector["I"].attrs["interpretation"] = "spectrum" + + # Measurement group (holds soft links) + meas = scan_group.create_group("measurement") + meas.attrs["NX_class"] = "NXdata" + meas.attrs["signal"] = "I" + meas.attrs["axes"] = "q" + meas.attrs["filename"] = result["filename"] + + meas["I"] = h5py.SoftLink(f"/{subdir_name}/{scan_name}/instrument/detector/I") + meas["q"] = h5py.SoftLink(f"/{subdir_name}/{scan_name}/instrument/detector/q") + meas["dI"] = h5py.SoftLink(f"/{subdir_name}/{scan_name}/instrument/detector/dI") + + # Optional display-friendly names + meas["I"].attrs["long_name"] = "Intensity" + meas["q"].attrs["long_name"] = "Q [1/A]" + + # For PyMca auto-plot: + scan_group.attrs["default"] = "measurement" + # Optional global default plot group + if idx == len(results_data): # mark the last one as global default + entry["last_plot"] = h5py.SoftLink(f"/{subdir_name}/{scan_name}/measurement") + # Title or metadata + entry["title"] = "Collected Q-I scans" + + h5.flush() + + # h5 = h5py.File(output_file, "w") + # h5["/entry/instrument/q/data"] = result["q"] + # h5["/entry/instrument/I/data"] = result["I"] + # h5["/entry/instrument/dI/data"] = result["dI"] + + # h5["/entry/title"] = subdir_name + # h5["/entry"].attrs["NX_class"] = u"NXentry" + # h5["/entry/instrument"].attrs["NX_class"] = u"NXinstrument" + # h5["/entry/instrument/q/"].attrs["NX_class"] = u"NXdetector" + # h5["/entry/instrument/I/"].attrs["NX_class"] = u"NXdetector" + # h5["/entry/instrument/dI/"].attrs["NX_class"] = u"NXdetector" + + # h5["/entry/instrument/q/data"].attrs["interpretation"] = u"Dataset" + # h5["/entry/instrument/I/data"].attrs["interpretation"] = u"Dataset" + # h5["/entry/instrument/dI/data"].attrs["interpretation"] = u"Dataset" + + # h5["/entry/measurement/q"] = h5py.SoftLink("/entry/instrument/q/data") + # h5["/entry/measurement/I"] = h5py.SoftLink("/entry/instrument/I/data") + # h5["/entry/measurement/dI"] = h5py.SoftLink("/entry/instrument/dI/data") + # h5["/entry/measurement"].attrs["NX_class"] = u"NXcollection" + # h5["/entry/measurement"].attrs["signal"] = u"I" + # h5["/entry"].attrs["default"] = u"measurement" + + # # Top-level NXroot + # nxroot = f.create_group(subdir_name) + # nxroot.attrs["NX_class"] = np.string_("NXroot") + # nxroot.attrs["default"] = np.string_("1.1") + + # for idx, result in enumerate(results_data, start=1): + # entry_name = f"{idx}.1" + # entry = nxroot.create_group(entry_name) + # entry.attrs["NX_class"] = np.string_("NXentry") + # entry.attrs["default"] = np.string_("plotdata") + + # # Create full measurement group + # meas = entry.create_group("measurement") + # meas.attrs["NX_class"] = np.string_("NXcollection") + # meas.attrs["filename"] = np.string_(result["filename"]) + + # meas.create_dataset("q", data=result["q"]) + # meas.create_dataset("I", data=result["I"]) + # meas.create_dataset("dI", data=result["dI"]) + + # # Create plotdata group with proper NXdata spec + # plot = entry.create_group("plotdata") + # plot.attrs["NX_class"] = np.string_("NXdata") + # plot.attrs["signal"] = np.string_("I") + # plot.attrs["axes"] = np.string_("q") + # plot.attrs["title"] = np.string_(result["filename"]) + + # plot.create_dataset("q", data=result["q"]) + # dset_I = plot.create_dataset("I", data=result["I"]) + # dset_I.attrs["long_name"] = np.string_(result["filename"]) + # plot["I"].attrs["long_name"] = "Intensity" + # plot["q"].attrs["long_name"] = "Ang^-1" + + # plot.create_dataset("dI", data=result["dI"]) + # plot["dI"].attrs["long_name"] = np.string_("Uncertainty in I") + + + h5.flush() + h5.close() print(f"✅ HDF5 file '{output_file}' created with {len(results_data)} spectra.") # # Sort results_data by filename # def natural_sort_key(item):