26
26
27
27
__author__ = "Jérôme Kieffer"
28
28
__license__ = "MIT"
29
- __copyright__ = "2020, ESRF"
30
- __date__ = "15/01/2021 "
29
+ __copyright__ = "2020-2024 , ESRF"
30
+ __date__ = "16/04/2025 "
31
31
32
32
import io
33
33
import os
38
38
import posixpath
39
39
from collections import namedtuple , OrderedDict
40
40
import json
41
+ import zipfile
41
42
import copy
42
43
import pyFAI
43
44
from pyFAI .io import Nexus
@@ -78,6 +79,13 @@ def parse():
78
79
help = "extract every individual frame" ,
79
80
default = False ,
80
81
)
82
+ parser .add_argument (
83
+ "-z" ,
84
+ "--zip" ,
85
+ action = "store_true" ,
86
+ help = "extract every individual frame into a zip-file" ,
87
+ default = False ,
88
+ )
81
89
return parser .parse_args ()
82
90
83
91
@@ -87,11 +95,24 @@ def extract_averaged(filename):
87
95
results ["filename" ] = filename
88
96
# Missing: comment normalization
89
97
with Nexus (filename , "r" ) as nxsr :
90
- entry_grp = nxsr .get_entries ()[0 ]
98
+ default = nxsr .h5 .attrs .get ("default" )
99
+ if default and default in nxsr .h5 :
100
+ entry_grp = nxsr .h5 [default ]
101
+ else :
102
+ entry_grp = nxsr .get_entries ()[0 ]
91
103
results ["h5path" ] = entry_grp .name
92
- nxdata_grp = nxsr .h5 [entry_grp .attrs ["default" ]]
104
+ # program = entry_grp.get("program_name")
105
+ # if program == ""
106
+ default = entry_grp .attrs ["default" ]
107
+ if posixpath .split (default )[- 1 ] == "hplc" :
108
+ default = posixpath .join (posixpath .split (default )[0 ],"results" )
109
+ # print(default)
110
+ nxdata_grp = nxsr .h5 [default ]
93
111
signal = nxdata_grp .attrs ["signal" ]
94
112
axis = nxdata_grp .attrs ["axes" ]
113
+ if not isinstance (axis , (str ,bytes )):
114
+ logger .error (f"There are several curves if the dataset { default } from file { filename } , please use the option --all to extract them all" )
115
+ sys .exit (1 )
95
116
results ["I" ] = nxdata_grp [signal ][()]
96
117
results ["q" ] = nxdata_grp [axis ][()]
97
118
results ["std" ] = nxdata_grp ["errors" ][()]
@@ -102,15 +123,12 @@ def extract_averaged(filename):
102
123
results ["geometry" ] = json .loads (
103
124
integration_grp ["configuration/data" ][()]
104
125
)
105
- results ["polarization" ] = integration_grp [
106
- "configuration/polarization_factor"
107
- ][()]
126
+ results ["polarization" ] = integration_grp ["configuration/polarization_factor" ][()]
108
127
109
128
instrument_grps = nxsr .get_class (entry_grp , class_type = "NXinstrument" )
110
129
if instrument_grps :
111
- detector_grp = nxsr .get_class (
112
- instrument_grps [0 ], class_type = "NXdetector"
113
- )[0 ]
130
+ detector_grp = nxsr .get_class (instrument_grps [0 ],
131
+ class_type = "NXdetector" )[0 ]
114
132
results ["mask" ] = detector_grp ["pixel_mask" ].attrs ["filename" ]
115
133
sample_grp = nxsr .get_class (entry_grp , class_type = "NXsample" )[0 ]
116
134
results ["sample" ] = posixpath .split (sample_grp .name )[- 1 ]
@@ -119,52 +137,68 @@ def extract_averaged(filename):
119
137
results ["exposure temperature" ] = sample_grp ["temperature" ][()]
120
138
results ["concentration" ] = sample_grp ["concentration" ][()]
121
139
if "2_correlation_mapping" in entry_grp :
122
- results ["to_merge" ] = entry_grp [
123
- "2_correlation_mapping/results/to_merge"
124
- ][()]
140
+ results ["to_merge" ] = entry_grp ["2_correlation_mapping/results/to_merge" ][()]
125
141
return results
126
142
127
143
128
144
def extract_all (filename ):
129
- "return some infomations extracted from a HDF5 file for all individual frames"
145
+ """return some infomations extracted from a HDF5 file for all individual frames.
146
+ Supports HPLC and SC and freshly integrated blocks of frames"""
130
147
res = []
131
148
results = OrderedDict ()
132
149
results ["filename" ] = filename
133
150
with Nexus (filename , "r" ) as nxsr :
134
- entry_grp = nxsr .get_entries ()[0 ]
151
+ default = nxsr .h5 .attrs .get ("default" )
152
+ if default and default in nxsr .h5 :
153
+ entry_grp = nxsr .h5 [default ]
154
+ else :
155
+ entry_grp = nxsr .get_entries ()[0 ]
156
+ program = entry_grp .get ("program_name" )[()].decode () if "program_name" in entry_grp else None
157
+
158
+ if program == "bm29.hplc" :
159
+ target = "1_chromatogram"
160
+ elif program == "bm29.integratemultiframe" :
161
+ target = "1_integration"
162
+ elif program == "bm29.subtract" :
163
+ target = "3_azimuthal_integration"
164
+ else :
165
+ raise RuntimeError (f"Unable to read file written by { program } " )
166
+ target = posixpath .join (entry_grp .name , target , "results" )
135
167
results ["h5path" ] = entry_grp .name
136
- nxdata_grp = nxsr .h5 [entry_grp . name + "/1_integration/results" ]
168
+ nxdata_grp = nxsr .h5 [target ]
137
169
signal = nxdata_grp .attrs ["signal" ]
138
170
axis = nxdata_grp .attrs ["axes" ][1 ]
139
171
I = nxdata_grp [signal ][()]
140
172
results ["q" ] = nxdata_grp [axis ][()]
141
173
std = nxdata_grp ["errors" ][()]
142
- results ["unit" ] = pyFAI .units .to_unit (
143
- axis + "_" + nxdata_grp [axis ].attrs ["units" ]
144
- )
174
+ try :
175
+ results ["unit" ] = pyFAI .units .to_unit (axis + "_" + nxdata_grp [axis ].attrs ["units" ])
176
+ except KeyError :
177
+ logger .warning ("Unable to parse radial units" )
145
178
integration_grp = nxdata_grp .parent
146
- results ["geometry" ] = json .loads (
147
- integration_grp ["configuration/data" ][()]
148
- )
149
- results ["polarization" ] = integration_grp [
150
- "configuration/polarization_factor"
151
- ][()]
152
- instrument_grp = nxsr .get_class (entry_grp , class_type = "NXinstrument" )[
153
- 0
154
- ]
155
- detector_grp = nxsr .get_class (instrument_grp , class_type = "NXdetector" )[
156
- 0
157
- ]
158
- results ["mask" ] = detector_grp ["pixel_mask" ].attrs ["filename" ]
159
- sample_grp = nxsr .get_class (entry_grp , class_type = "NXsample" )[0 ]
160
- results ["sample" ] = posixpath .split (sample_grp .name )[- 1 ]
161
- results ["buffer" ] = sample_grp ["buffer" ][()]
162
- if "temperature_env" in sample_grp :
163
- results ["storage temperature" ] = sample_grp ["temperature_env" ][()]
164
- if "temperature" in sample_grp :
165
- results ["exposure temperature" ] = sample_grp ["temperature" ][()]
166
- if "concentration" in sample_grp :
167
- results ["concentration" ] = sample_grp ["concentration" ][()]
179
+ if "configuration/data" in integration_grp :
180
+ results ["geometry" ] = json .loads (integration_grp ["configuration/data" ][()])
181
+ else :
182
+ logger .warning ("Unable to parse AzimuthalIntegrator configuration" )
183
+ if "configuration/polarization_factor" in integration_grp :
184
+ results ["polarization" ] = integration_grp ["configuration/polarization_factor" ][()]
185
+ instrument_grp = nxsr .get_class (entry_grp , class_type = "NXinstrument" )
186
+ if instrument_grp :
187
+ detector_grp = nxsr .get_class (instrument_grp [0 ], class_type = "NXdetector" )
188
+ if detector_grp :
189
+ results ["mask" ] = detector_grp [0 ]["pixel_mask" ].attrs ["filename" ]
190
+ sample_grp = nxsr .get_class (entry_grp , class_type = "NXsample" )
191
+ if sample_grp :
192
+ sample_grp = sample_grp [0 ]
193
+ results ["sample" ] = posixpath .split (sample_grp .name )[- 1 ]
194
+ if "buffer" in sample_grp :
195
+ results ["buffer" ] = sample_grp ["buffer" ][()]
196
+ if "temperature_env" in sample_grp :
197
+ results ["storage temperature" ] = sample_grp ["temperature_env" ][()]
198
+ if "temperature" in sample_grp :
199
+ results ["exposure temperature" ] = sample_grp ["temperature" ][()]
200
+ if "concentration" in sample_grp :
201
+ results ["concentration" ] = sample_grp ["concentration" ][()]
168
202
# if "2_correlation_mapping" in entry_grp:
169
203
# results["to_merge"] = entry_grp["2_correlation_mapping/results/to_merge"][()]
170
204
for i , s in zip (I , std ):
@@ -326,15 +360,23 @@ def main():
326
360
input_len = len (files )
327
361
logger .debug ("%s input files" , input_len )
328
362
for src in files :
363
+ print (f"{ src } \t --> " , end = "" )
329
364
if args .all :
330
365
dest = os .path .splitext (src )[0 ] + "%04i.dat"
331
366
for idx , frame in enumerate (extract_all (src )):
332
367
print (src , " --> " , dest % idx )
333
368
write_ascii (frame , dest % idx )
369
+ print (dest )
370
+ elif args .zip :
371
+ dest = os .path .splitext (src )[0 ] + ".zip"
372
+ with zipfile .ZipFile (dest , "w" ) as z :
373
+ for idx , frame in enumerate (extract_all (src )):
374
+ z .writestr (f'frame_{ idx :04d} .dat' , write_ascii (frame ))
375
+ print (dest )
334
376
else :
335
377
dest = os .path .splitext (src )[0 ] + ".dat"
336
378
write_ascii (extract_averaged (src ), dest )
337
- print (src , " --> " , dest )
379
+ print (dest )
338
380
339
381
340
382
if __name__ == "__main__" :
0 commit comments