From 2f190f45d6d8fcb505df6bf696f7c7513bec3523 Mon Sep 17 00:00:00 2001 From: Frederik <47137695+fgjorup@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:39:10 +0100 Subject: [PATCH] Update unit references to use NXdata for datasets, include optional attribute reading --- GSASII/imports/G2pwd_HDF5.py | 46 ++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/GSASII/imports/G2pwd_HDF5.py b/GSASII/imports/G2pwd_HDF5.py index d2f38210..b92f2af1 100644 --- a/GSASII/imports/G2pwd_HDF5.py +++ b/GSASII/imports/G2pwd_HDF5.py @@ -54,7 +54,8 @@ def ContentsValidator(self, filename): if definition == 'NXazint1d': fileItems = { 'I':('NXdata','I'), - 'unit':('NXparameters','unit'), + 'unit':('NXdata','radial_axis','units'), + # 'unit':('NXparameters','unit'), } buffer = {} if not self.readInNeXus(filename,buffer,fileItems,'NXazint1d-validate'): @@ -67,7 +68,7 @@ def ContentsValidator(self, filename): if definition == 'NXazint2d': fileItems = { 'I':('NXdata','I'), - 'unit':('NXparameters','unit'), + 'unit':('NXdata','radial_axis','units'), 'azimuthal_axis':('NXdata','azimuthal_axis'), } buffer = {} @@ -176,6 +177,7 @@ def readNXazint1d(self, filename, fpbuffer={}, entry=None): see https://nxazint-hdf5-nexus-3229ecbd09ba8a773fbbd8beb72cace6216dfd5063e1.gitlab-pages.esrf.fr/classes/contributed_definitions/NXazint1d.html ''' + # key: (NeXus section, dataset name, optional attribute name) fileItems = { # arrays 'radial_axis':('NXdata','radial_axis'), @@ -186,9 +188,13 @@ def readNXazint1d(self, filename, fpbuffer={}, entry=None): 'polarization_factor':('NXparameters','polarization_factor'), # strings 'instrument/name':('NXinstrument','name'), - 'unit':('NXparameters','unit'), + 'unit':('NXdata','radial_axis','units'), + # 'unit':('NXparameters','unit'), 'sample/name':('NXsample','name'), 'source/name':('NXsource','name'), + # bools + 'polarization_applied':('NXentry', 'polarization_applied'), + } # test if we have what we need in the buffer and if not read it in if not self.readInNeXus(filename,fpbuffer,fileItems,'NXazint1d',entry): return False @@ -207,6 +213,10 @@ def readNXazint1d(self, filename, fpbuffer={}, entry=None): self.powderentry[2] = self.blknum # bank number self.idstring = f'#{self.blknum} {os.path.split(filename)[1][:60]}' self.instdict['wave'] = fpbuffer['wavelength'] + # if the data are already corrected for polarization, set the polarization factor + # to 0.5 (unpolarized) + if fpbuffer['polarization_applied']: + self.instdict['Polariz.'] = [0.5,0.5,False] # if not, are there more [selected] images that after this to be read? self.repeat = False if self.blknum < self.numbanks-1: @@ -232,6 +242,7 @@ def readNXazint2d(self, filename, fpbuffer={}, entry=None): see https://nxazint-hdf5-nexus-3229ecbd09ba8a773fbbd8beb72cace6216dfd5063e1.gitlab-pages.esrf.fr/classes/contributed_definitions/NXazint2d.html ''' self.comments = [] + # key: (NeXus section, dataset name, optional attribute name) fileItems = { # arrays 'radial_axis':('NXdata','radial_axis'), @@ -243,15 +254,19 @@ def readNXazint2d(self, filename, fpbuffer={}, entry=None): 'polarization_factor':('NXparameters','polarization_factor'), # strings 'instrument/name':('NXinstrument','name'), - 'unit':('NXparameters','unit'), - 'azimuth_bins':('NXparameters','azimuth_bins'), + # 'azimuth_bins':('NXparameters','azimuth_bins'), 'sample/name':('NXsample','name'), 'source/name':('NXsource','name'), + # bools + 'polarization_applied':('NXentry', 'polarization_applied'), + # from attributes + 'unit':('NXdata','radial_axis','units'), } # test if we have what we need in the buffer and if not read it in if not self.readInNeXus(filename,fpbuffer,fileItems,'NXazint2d',entry): return False # now pull the selected dataset from the buffer - self.numazimuth = fpbuffer['azimuth_bins'] + self.numazimuth = fpbuffer['azimuthal_axis'].size + # self.numazimuth = fpbuffer['azimuth_bins'] self.numbanks = self.numparams * self.numazimuth # group by parametric variable numScan = self.blknum // self.numazimuth @@ -271,6 +286,10 @@ def readNXazint2d(self, filename, fpbuffer={}, entry=None): self.powderentry[2] = self.blknum # bank number self.idstring = f'#{numScan} Azm={self.Sample["Azimuth"]} {os.path.split(filename)[1][:60]}' self.instdict['wave'] = fpbuffer['wavelength'] + # if the data are already corrected for polarization, set the polarization factor + # to 0.5 (unpolarized) + if fpbuffer['polarization_applied']: + self.instdict['Polariz.'] = [0.5,0.5,False] # if not, are there more [selected] images that after this to be read? self.repeat = False if self.blknum < self.numbanks-1: @@ -318,11 +337,18 @@ def readInNeXus(self,filename,fpbuffer,fileItems,fmt,entry=None): if nexusDict[loc[0]] is None: fpbuffer[k] = None continue - key = '/'.join((nexusDict[loc[0]],)+loc[1:]) + key = '/'.join((nexusDict[loc[0]],)+loc[1:2]) savedKeys.append(key) if key not in fp: fpbuffer[k] = None continue + # check if the value should be read from a dataset attribute rather + # than the dataset itself + if len(loc) > 2: # attribute + val = fp[key].attrs[loc[2]] + val = val.decode() if isinstance(val, bytes) else val + fpbuffer[k] = val + continue val = fp[key] if val.shape: fpbuffer[k] = np.array(val) @@ -332,9 +358,9 @@ def readInNeXus(self,filename,fpbuffer,fileItems,fmt,entry=None): elif 'int' in str(val.dtype): fpbuffer[k] = int(val[()]) else: - fpbuffer[k] = val[()].decode() + fpbuffer[k] = val[()].decode() if isinstance(val[()], bytes) else val[()] self.comments.append(f'{k}={fpbuffer[k]}') - if fpbuffer['unit'] != '2th': + if fpbuffer['unit'] not in ['degrees','deg','2th', '2theta']: print(f'{fmt} HDF5 file has units',fpbuffer['unit']) self.errors = f'{fmt} only can be read with 2theta units' return False @@ -379,7 +405,7 @@ def readInNeXus(self,filename,fpbuffer,fileItems,fmt,entry=None): else: self.blknum = min(self.selections) return True - + def FillInParametics(self,fpbuffer,count): '''put changing parametric variables into the top of the comments '''