More checks on refMeas. Renamed method refMeas to getRefMeas. Added removeRefMeas. Stabilized API?

This commit is contained in:
Anne de Jong 2023-12-19 12:27:44 +01:00
parent 87283e4aba
commit 98d4e8dad2

View File

@ -372,7 +372,7 @@ class Measurement:
if ext != DOTMEXT:
newname = newname + DOTMEXT
newname_full = str(pathlib.Path(self.folder) / newname )
newname_full = str(pathlib.Path(self.folder) / newname)
os.rename(self.fn, newname_full)
def genNewUUID(self):
@ -388,7 +388,7 @@ class Measurement:
"""
return self._UUID
def refMeas(self, mtype: MeasurementType):
def getRefMeas(self, mtype: MeasurementType):
"""
Return corresponding reference measurement, if configured and can be found. If the reference
measurement is currently not open, it tries to open it by traversing other measurement
@ -402,30 +402,66 @@ class Measurement:
except KeyError:
raise ValueError(f"No reference measurement configured for '{self.name}'")
m = None
# Try to find it in the dictionary of of open measurements
if required_uuid in Measurement.uuid_s.keys():
m = Measurement.uuid_s[required_uuid]
logging.info(f'Returned reference measurement {m.name} from list of open measurements')
return m
# See if we can open it using its last stored file name
try:
m = Measurement(possible_name)
if m.UUID == required_uuid:
logging.info(f'Opened reference measurement {m.name} by name')
return m
except Exception as e:
logging.error(f'Could not find reference measurement using file name: {possible_name}')
# Not found in list of openend measurements. See if we can open it using its last stored file name we know of
if m is None:
try:
m = Measurement(possible_name)
if m.UUID == required_uuid:
logging.info(f'Opened reference measurement {m.name} by name')
except Exception as e:
logging.error(f'Could not find reference measurement using file name: {possible_name}')
# Last resort, see if we can find the measurement in the same folder
m = Measurement.fromFolderWithUUID(required_uuid, self.folder, skip=[self.name])
logging.info('Found reference measurement in folder with correct UUID. Updating name of reference measurement')
# Update the measurement file name in the list, such that next time it
# can be opened just by its name.
self.setRefMeas(m)
return m
raise RuntimeError("Could not find reference measurement")
# Last resort, see if we can find the right measurement in the same folder
if m is None:
try:
m = Measurement.fromFolderWithUUID(required_uuid, self.folder, skip=[self.name])
logging.info('Found reference measurement in folder with correct UUID. Updating name of reference measurement')
# Update the measurement file name in the list, such that next time it
# can be opened just by its name.
self.setRefMeas(m)
except:
logging.error("Could not find the reference measurement. Is it deleted?")
# Well, we found it. Now make sure the reference measurement actually has the right type (User could have marked it as a NotSpecific for example in the mean time).
if m is not None:
if m.measurementType() != mtype:
m.removeRefMeas(mtype)
raise RuntimeError(f"Reference measurement for {self.name} is not a proper reference (anymore).")
# Whow, we passed all security checks, here we go!
return m
else:
# Nope, not there.
raise RuntimeError(f"Could not find the reference measurement for '{self.name}'. Is it deleted?")
def removeRefMeas(self, mtype: MeasurementType):
"""
Remove an existing reference measurement of specified type from this measurement. Silently ignores this
action if no reference measurement of this type is configured.
"""
try:
del self._refMeas[mtype]
self.__storeReafMeas()
except KeyError:
pass
def __storeReafMeas(self):
"""
Internal method that syncs the dictionary of reference methods with the backing HDF5 file
"""
with self.file("r+") as f:
# Update attribute in file. Stored as a flat list of string tuples:
# [(ref_value1, uuid_1, name_1), (ref_value2, uuid_2, name_2), ...]
reflist = list((str(key.value), val1, val2) for key, (val1, val2) in self._refMeas.items())
# print(reflist)
f.attrs['refMeas'] = reflist
def setRefMeas(self, m: Measurement):
"""
@ -438,12 +474,7 @@ class Measurement:
raise ValueError('Measurement to be set as reference is not a reference measurement')
self._refMeas[mtype] = (m.UUID, m.name)
with self.file("r+") as f:
# Update attribute in file. Stored as a flat list of string tuples:
# [(ref_value1, uuid_1, name_1), (ref_value2, uuid_2, name_2), ...]
reflist = list((str(key.value), val1, val2) for key, (val1, val2) in self._refMeas.items())
# print(reflist)
f.attrs['refMeas'] = reflist
self.__storeReafMeas()
@staticmethod
def fromFolderWithUUID(uuid_str: str, folder: str='', skip=[]):
@ -657,13 +688,13 @@ class Measurement:
Nblock = block.shape[0]
sum_ += np.sum(block, axis=0)
N += Nblock
meansquare += np.sum(block**2, axis=0) / self.N
meansquare += np.sum(block ** 2, axis=0) / self.N
avg = sum_ / N
# In fact, this is not the complete RMS, as in includes the DC
# If p = p_dc + p_osc, then rms(p_osc) = sqrt(ms(p)-ms(p_dc))
if substract_average:
meansquare -= avg**2
meansquare -= avg ** 2
rms = np.sqrt(meansquare)
return rms
@ -768,7 +799,7 @@ class Measurement:
signal = self.data(channels)
# Estimate noise power in block
blocks = [signal[i * N : (i + 1) * N] for i in range(Nblocks)]
blocks = [signal[i * N: (i + 1) * N] for i in range(Nblocks)]
if noiseCorrection:
# The difference between the measured signal in the previous block and
@ -972,10 +1003,11 @@ class Measurement:
raise ValueError(f"File {fn} does not exist.")
if timestamp is None:
timestamp = os.path.getmtime(fn)
if mfn is None:
mfn = os.path.splitext(fn)[0] + ".h5"
mfn = os.path.splitext(fn)[0] + DOTMEXT
else:
mfn = os.path.splitext(mfn)[0] + ".h5"
mfn = os.path.splitext(mfn)[0] + DOTMEXT
dat = np.loadtxt(fn, skiprows=skiprows, delimiter=delimiter)
if firstcoltime: