Public Access
script for release added, pyrefly checks are fixed for now
This commit is contained in:
1 parent
428af30c30
commit
dda8ae7df0
6 files changed
+179
-89
No files matched your search
@@ -22,13 +22,25 @@ jobs:
|
||||
- name: Install Node.js and git
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get -y install nodejs git lsb-release jq
|
||||
apt-get -y install nodejs git lsb-release jq devscripts
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
github-server-url: https://gitea.pkm.physik.tu-darmstadt.de
|
||||
|
||||
- name: Set package version from release tag
|
||||
if: startsWith(gitea.ref, 'refs/tags/v')
|
||||
env:
|
||||
TAG: ${{ gitea.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${TAG#v}"
|
||||
if [ "$(dpkg-parsechangelog --show-field Version)" != "$VERSION" ]; then
|
||||
dch --newversion "$VERSION" --distribution stable --force-distribution --noquery "Release $TAG"
|
||||
fi
|
||||
sed -i -E "s/^(__version__ = \")([^\"]+)(\")$/\1${VERSION}\3/" src/damaris/__init__.py
|
||||
|
||||
- name: Install build dependencies
|
||||
run: bash requirements.debian
|
||||
|
||||
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 VERSION (for example: 0.30)"
|
||||
}
|
||||
|
||||
if [[ ${1:-} == "-h" || ${1:-} == "--help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $# -ne 1 || ! $1 =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
version=$1
|
||||
tag="v$version"
|
||||
root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
cd "$root"
|
||||
|
||||
if [[ -n $(git status --porcelain) ]]; then
|
||||
echo "Release requires a clean working tree." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
|
||||
echo "Tag $tag already exists." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command -v dch >/dev/null || { echo "Install devscripts to use dch." >&2; exit 1; }
|
||||
command -v dpkg-parsechangelog >/dev/null || { echo "Install dpkg-dev to use dpkg-parsechangelog." >&2; exit 1; }
|
||||
|
||||
current_version=$(dpkg-parsechangelog --show-field Version)
|
||||
if [[ $current_version == "$version" ]]; then
|
||||
echo "debian/changelog already has version $version." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dch --newversion "$version" --distribution stable --force-distribution
|
||||
sed -i "s/^__version__ = .*/__version__ = \"$version\"/" src/damaris/__init__.py
|
||||
|
||||
if [[ $(dpkg-parsechangelog --show-field Version) != "$version" ]] ||
|
||||
[[ $(sed -n 's/^__version__ = "\([^"]*\)"$/\1/p' src/damaris/__init__.py) != "$version" ]]; then
|
||||
echo "Release version did not update consistently; inspect the changelog and package version." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "About to commit the version bump and create tag $tag."
|
||||
read -r -p "Continue? [y/N] " answer
|
||||
if [[ ! $answer =~ ^[Yy]$ ]]; then
|
||||
echo "Release preparation stopped; version and changelog edits were kept."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git add debian/changelog src/damaris/__init__.py
|
||||
git commit -m "Release $tag"
|
||||
git tag -a "$tag" -m "Release $tag"
|
||||
|
||||
echo "Created local release tag $tag. Push the commit and tag to start the package workflow."
|
||||
echo " git push origin HEAD"
|
||||
echo " git push origin $tag"
|
||||
@@ -12,13 +12,14 @@ import numpy
|
||||
import sys
|
||||
import datetime
|
||||
import tables
|
||||
from typing import IO
|
||||
from typing import IO, Any, Literal, cast
|
||||
from scipy.signal import filtfilt, remez
|
||||
|
||||
_XArray = numpy.ndarray | list
|
||||
_YChannels = list[numpy.ndarray]
|
||||
_IndexList = list[tuple[int, int]]
|
||||
_Description = dict[str, str]
|
||||
_CompressionLibrary = Literal["blosc", "blosc2", "bzip2", "lzo", "zlib"]
|
||||
#############################################################################
|
||||
# #
|
||||
# Name: Class ADC_Result #
|
||||
@@ -377,13 +378,14 @@ class ADC_Result(MeasurementData, Resultable, Drawable, DamarisFFT, Signalpath):
|
||||
|
||||
def write_to_hdf(self, hdffile: tables.File, where: str, name: str, title: str, complib: str | None = None, complevel: int | None = None) -> None:
|
||||
accu_group=hdffile.create_group(where=where,name=name,title=title)
|
||||
accu_group._v_attrs.damaris_type="ADC_Result"
|
||||
attrs = cast(Any, accu_group._v_attrs)
|
||||
attrs.damaris_type="ADC_Result"
|
||||
if self.contains_data():
|
||||
self.lock.acquire()
|
||||
try:
|
||||
# save time stamps
|
||||
if "job_date" in dir(self) and self.job_date is not None:
|
||||
accu_group._v_attrs.time="%04d%02d%02d %02d:%02d:%02d.%03d"%(self.job_date.year,
|
||||
attrs.time="%04d%02d%02d %02d:%02d:%02d.%03d"%(self.job_date.year,
|
||||
self.job_date.month,
|
||||
self.job_date.day,
|
||||
self.job_date.hour,
|
||||
@@ -393,15 +395,17 @@ class ADC_Result(MeasurementData, Resultable, Drawable, DamarisFFT, Signalpath):
|
||||
|
||||
if self.description is not None:
|
||||
for (key,value) in self.description.items():
|
||||
accu_group._v_attrs.__setattr__("description_"+key,str(value))
|
||||
accu_group._v_attrs.__setattr__("sampling_rate",self.sampling_rate)
|
||||
attrs.__setattr__("description_"+key,str(value))
|
||||
attrs.__setattr__("sampling_rate",self.sampling_rate)
|
||||
|
||||
# save interval information
|
||||
filter=None
|
||||
if complib is not None:
|
||||
if complevel is None:
|
||||
complevel=9
|
||||
filter=tables.Filters(complevel=complevel,complib=complib,shuffle=1)
|
||||
filter=tables.Filters(complevel=complevel,
|
||||
complib=cast(_CompressionLibrary, complib),
|
||||
shuffle=True)
|
||||
|
||||
index_table=hdffile.create_table(where=accu_group,
|
||||
name="indices",
|
||||
@@ -414,7 +418,7 @@ class ADC_Result(MeasurementData, Resultable, Drawable, DamarisFFT, Signalpath):
|
||||
expectedrows=len(self.index))
|
||||
index_table.flavor="numpy"
|
||||
# save channel data
|
||||
new_row=index_table.row
|
||||
new_row = cast(Any, index_table.row)
|
||||
for i in range(len(self.index)):
|
||||
new_row["start"]=self.index[i][0]
|
||||
new_row["dwelltime"]=1.0/self.sampling_rate
|
||||
@@ -436,27 +440,14 @@ class ADC_Result(MeasurementData, Resultable, Drawable, DamarisFFT, Signalpath):
|
||||
# save data
|
||||
time_slice_data=None
|
||||
if filter is not None:
|
||||
chunkshape = numpy.shape(timedata)
|
||||
if len(chunkshape) <= 1:
|
||||
chunkshape = (min(chunkshape[0],1024*8),)
|
||||
else:
|
||||
chunkshape = (min(chunkshape[0],1024*8), chunkshape[1])
|
||||
if tables.__version__[0]=="1":
|
||||
time_slice_data=hdffile.create_carray(accu_group,
|
||||
name="adc_data",
|
||||
shape=timedata.shape,
|
||||
atom=tables.Int16Atom(shape=chunkshape,
|
||||
flavor="numpy"),
|
||||
filters=filter,
|
||||
title="adc data")
|
||||
else:
|
||||
time_slice_data=hdffile.create_carray(accu_group,
|
||||
name="adc_data",
|
||||
shape=timedata.shape,
|
||||
chunkshape=chunkshape,
|
||||
atom=tables.Int16Atom(),
|
||||
filters=filter,
|
||||
title="adc data")
|
||||
chunkshape = (min(timedata.shape[0], 1024 * 8), timedata.shape[1])
|
||||
time_slice_data=hdffile.create_carray(accu_group,
|
||||
name="adc_data",
|
||||
shape=timedata.shape,
|
||||
chunkshape=chunkshape,
|
||||
atom=tables.Int16Atom(),
|
||||
filters=filter,
|
||||
title="adc data")
|
||||
time_slice_data[:]=timedata
|
||||
else:
|
||||
time_slice_data=hdffile.create_array(accu_group,
|
||||
@@ -684,7 +675,8 @@ def read_from_hdf(hdf_node: object) -> ADC_Result | None:
|
||||
if not isinstance(hdf_node, tables.Group):
|
||||
return None
|
||||
|
||||
if hdf_node._v_attrs.damaris_type!="ADC_Result":
|
||||
attrs = cast(Any, hdf_node._v_attrs)
|
||||
if attrs.damaris_type!="ADC_Result":
|
||||
return None
|
||||
|
||||
if not (hdf_node.__contains__("indices") and hdf_node.__contains__("adc_data")):
|
||||
@@ -696,12 +688,12 @@ def read_from_hdf(hdf_node: object) -> ADC_Result | None:
|
||||
adc.set_title(hdf_node._v_title)
|
||||
# populate description dictionary
|
||||
adc.description={}
|
||||
for attrname in hdf_node._v_attrs._v_attrnamesuser:
|
||||
for attrname in attrs._v_attrnamesuser:
|
||||
if attrname.startswith("description_"):
|
||||
adc.description[attrname[12:]]=hdf_node._v_attrs.__getattr__(attrname)
|
||||
adc.description[attrname[12:]]=attrs.__getattr__(attrname)
|
||||
|
||||
if "time" in dir(hdf_node._v_attrs):
|
||||
timestring=hdf_node._v_attrs.__getattr__("time")
|
||||
if "time" in dir(attrs):
|
||||
timestring=attrs.__getattr__("time")
|
||||
adc.job_date=datetime.datetime(int(timestring[:4]), # year
|
||||
int(timestring[4:6]), # month
|
||||
int(timestring[6:8]), # day
|
||||
|
||||
@@ -26,12 +26,13 @@ import datetime # added by Oleg Petrov
|
||||
import ctypes # added by Oleg Petrov
|
||||
import struct # added by Oleg Petrov
|
||||
import os # added by Oleg Petrov
|
||||
from typing import IO
|
||||
from typing import IO, Any, Literal, cast
|
||||
|
||||
_XArray = numpy.ndarray | list
|
||||
_YChannels = list[numpy.ndarray]
|
||||
_IndexList = list[tuple[int, int]]
|
||||
_Description = dict[str, str]
|
||||
_CompressionLibrary = Literal["blosc", "blosc2", "bzip2", "lzo", "zlib"]
|
||||
|
||||
|
||||
class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath):
|
||||
@@ -307,7 +308,7 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
for i in range(len(xdata)):
|
||||
dest.write("%e"%xdata[i])
|
||||
for j in range(ch_no):
|
||||
if self.use_error:
|
||||
if self.use_error and yerr is not None:
|
||||
dest.write("%s%e%s%e"%(delimiter, ydata[j][i], delimiter, yerr[j][i]))
|
||||
else:
|
||||
dest.write("%s%e"%(delimiter,ydata[j][i]))
|
||||
@@ -358,7 +359,7 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
self.lock.release()
|
||||
|
||||
# ------------- added by Oleg Petrov, 10 Sep 2013 -----------------------
|
||||
def write_to_tecmag(self, destination = sys.stdout, nrecords: int = 1,\
|
||||
def write_to_tecmag(self, destination: str | IO[bytes] = sys.stdout.buffer, nrecords: int = 1,\
|
||||
frequency: float = 100.,\
|
||||
last_delay: float = 1.,\
|
||||
receiver_phase: float = 0.,\
|
||||
@@ -388,8 +389,8 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
else:
|
||||
record = (self.job_id/self.n)%nrecords + 1
|
||||
|
||||
the_destination=destination
|
||||
if type(destination) in (str,):
|
||||
the_destination: IO[bytes] | None = None
|
||||
if isinstance(destination, str):
|
||||
if record == 1 and os.path.exists(destination):
|
||||
os.rename(destination, os.path.dirname(destination)+'/~'+os.path.basename(destination))
|
||||
|
||||
@@ -420,7 +421,10 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
data = data.flatten()
|
||||
|
||||
if record == 1:
|
||||
the_destination=open(destination, "wb")
|
||||
if isinstance(destination, str):
|
||||
the_destination = open(destination, "wb")
|
||||
else:
|
||||
the_destination = destination
|
||||
|
||||
# allocate space for all records in advance:
|
||||
buff = ctypes.create_string_buffer(1056+data_offset+2068)
|
||||
@@ -481,20 +485,24 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
struct.pack_into('4s', buff, 1056+data_offset+2060, 'PSEQ') # 'PSEQ' tag 658476
|
||||
struct.pack_into('?', buff, 1056+data_offset+2064, False) # BOOLean 658480
|
||||
|
||||
the_destination.write(buff)
|
||||
the_destination.write(buff.raw)
|
||||
|
||||
else:
|
||||
the_destination=open(destination, "rb+")
|
||||
if isinstance(destination, str):
|
||||
the_destination = open(destination, "rb+")
|
||||
else:
|
||||
the_destination = destination
|
||||
buff = ctypes.create_string_buffer(4*2*npts[0])
|
||||
struct.pack_into('%sf' % (2*npts[0]), buff, 0, *data)
|
||||
|
||||
the_destination.seek(1056+4*2*npts[0]*(record-1))
|
||||
the_destination.write(buff)
|
||||
the_destination.write(buff.raw)
|
||||
|
||||
the_destination = None
|
||||
ydata=None
|
||||
|
||||
finally:
|
||||
if isinstance(destination, str) and the_destination is not None:
|
||||
the_destination.close()
|
||||
self.lock.release()
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
@@ -518,25 +526,28 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
:param complevel: compression level.
|
||||
"""
|
||||
accu_group=hdffile.create_group(where=where,name=name,title=title)
|
||||
accu_group._v_attrs.damaris_type="Accumulation"
|
||||
attrs = cast(Any, accu_group._v_attrs)
|
||||
attrs.damaris_type="Accumulation"
|
||||
if self.contains_data():
|
||||
self.lock.acquire()
|
||||
try:
|
||||
# save time stamps
|
||||
if self.time_period is not None and len(self.time_period)>0:
|
||||
accu_group._v_attrs.earliest_time = self.time_period[0].isoformat(sep=' ', timespec='milliseconds')
|
||||
accu_group._v_attrs.oldest_time = self.time_period[1].isoformat(sep=' ', timespec='milliseconds')
|
||||
attrs.earliest_time = self.time_period[0].isoformat(sep=' ', timespec='milliseconds')
|
||||
attrs.oldest_time = self.time_period[1].isoformat(sep=' ', timespec='milliseconds')
|
||||
if self.common_descriptions is not None:
|
||||
for (key,value) in self.common_descriptions.items():
|
||||
accu_group._v_attrs.__setattr__("description_"+key,str(value))
|
||||
accu_group._v_attrs.__setattr__("sampling_rate",self.sampling_rate)
|
||||
attrs.__setattr__("description_"+key,str(value))
|
||||
attrs.__setattr__("sampling_rate",self.sampling_rate)
|
||||
|
||||
|
||||
filter=None
|
||||
if complib is not None:
|
||||
if complevel is None:
|
||||
complevel=3
|
||||
filter=tables.Filters(complevel=complevel,complib=complib,shuffle=1)
|
||||
filter=tables.Filters(complevel=complevel,
|
||||
complib=cast(_CompressionLibrary, complib),
|
||||
shuffle=True)
|
||||
|
||||
# save interval information
|
||||
# start save index_table
|
||||
@@ -553,7 +564,7 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
expectedrows=len(self.index))
|
||||
index_table.flavor="numpy"
|
||||
# save interval data
|
||||
new_row=index_table.row
|
||||
new_row = cast(Any, index_table.row)
|
||||
for i in range(len(self.index)):
|
||||
new_row["start"]=self.index[i][0]
|
||||
new_row["dwelltime"]=1.0/self.sampling_rate
|
||||
@@ -574,7 +585,7 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
title="job_ids used for accumulation",
|
||||
filters=filter,
|
||||
expectedrows=len(self.job_ids))
|
||||
new_row=jobid_table.row
|
||||
new_row = cast(Any, jobid_table.row)
|
||||
for i,job_id in enumerate(self.job_ids):
|
||||
new_row["job_date"] = self.job_ids[job_id].isoformat(timespec='milliseconds')
|
||||
new_row["job_id"]=job_id
|
||||
@@ -595,27 +606,14 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
# save data
|
||||
time_slice_data=None
|
||||
if filter is not None:
|
||||
chunkshape=timedata.shape
|
||||
if len(chunkshape) <= 1:
|
||||
chunkshape = (min(chunkshape[0],1024*8),)
|
||||
else:
|
||||
chunkshape = (min(chunkshape[0],1024*8), chunkshape[1])
|
||||
if tables.__version__[0]=="1":
|
||||
time_slice_data=hdffile.create_carray(accu_group,
|
||||
name="accu_data",
|
||||
shape=timedata.shape,
|
||||
atom=tables.Float32Atom(shape=chunkshape,
|
||||
flavor="numpy"),
|
||||
filters=filter,
|
||||
title="accu data")
|
||||
else:
|
||||
time_slice_data=hdffile.create_carray(accu_group,
|
||||
name="accu_data",
|
||||
shape=timedata.shape,
|
||||
chunkshape=chunkshape,
|
||||
atom=tables.Float32Atom(),
|
||||
filters=filter,
|
||||
title="accu data")
|
||||
chunkshape = (min(timedata.shape[0], 1024 * 8), timedata.shape[1])
|
||||
time_slice_data=hdffile.create_carray(accu_group,
|
||||
name="accu_data",
|
||||
shape=timedata.shape,
|
||||
chunkshape=chunkshape,
|
||||
atom=tables.Float32Atom(),
|
||||
filters=filter,
|
||||
title="accu data")
|
||||
|
||||
time_slice_data[:]=timedata
|
||||
else:
|
||||
@@ -1111,7 +1109,8 @@ class Accumulation(MeasurementData, Errorable, Drawable, DamarisFFT, Signalpath)
|
||||
self.set_title(self.__title_pattern % self.n)
|
||||
if hasattr(other, "is_clipped"):
|
||||
self.is_clipped = other.is_clipped
|
||||
self.common_descriptions=other.common_descriptions.copy()
|
||||
self.common_descriptions = (other.common_descriptions.copy()
|
||||
if other.common_descriptions is not None else None)
|
||||
self.time_period=other.time_period[:] if other.time_period is not None else None
|
||||
self.job_id = other.job_id # added by Oleg Petrov
|
||||
self.job_ids.update(other.job_ids)
|
||||
@@ -1213,7 +1212,8 @@ def read_from_hdf(hdf_node: object) -> "Accumulation | None":
|
||||
if not isinstance(hdf_node, tables.Group):
|
||||
return None
|
||||
|
||||
if hdf_node._v_attrs.damaris_type!="Accumulation":
|
||||
attrs = cast(Any, hdf_node._v_attrs)
|
||||
if attrs.damaris_type!="Accumulation":
|
||||
return None
|
||||
|
||||
if not (hdf_node.__contains__("indices") and hdf_node.__contains__("accu_data")):
|
||||
@@ -1224,13 +1224,13 @@ def read_from_hdf(hdf_node: object) -> "Accumulation | None":
|
||||
|
||||
# populate description dictionary
|
||||
accu.common_descriptions={}
|
||||
for attrname in hdf_node._v_attrs._v_attrnamesuser:
|
||||
for attrname in attrs._v_attrnamesuser:
|
||||
if attrname.startswith("description_"):
|
||||
accu.common_descriptions[attrname[12:]]=hdf_node._v_attrs.__getattr__(attrname)
|
||||
accu.common_descriptions[attrname[12:]]=attrs.__getattr__(attrname)
|
||||
|
||||
earliest_time=None
|
||||
if "earliest_time" in dir(hdf_node._v_attrs):
|
||||
timestring=hdf_node._v_attrs.__getattr__("earliest_time")
|
||||
if "earliest_time" in dir(attrs):
|
||||
timestring=attrs.__getattr__("earliest_time")
|
||||
# Handle both formats: "20260705 19:13:59.162" and "2026-07-05 19:13:59.162"
|
||||
if '-' in timestring:
|
||||
# New format: "2026-07-05 19:13:59.162"
|
||||
@@ -1261,8 +1261,8 @@ def read_from_hdf(hdf_node: object) -> "Accumulation | None":
|
||||
)
|
||||
|
||||
oldest_time=None
|
||||
if "oldest_time" in dir(hdf_node._v_attrs):
|
||||
timestring=hdf_node._v_attrs.__getattr__("oldest_time")
|
||||
if "oldest_time" in dir(attrs):
|
||||
timestring=attrs.__getattr__("oldest_time")
|
||||
# Handle both formats: "20260705 19:13:59.162" and "2026-07-05 19:13:59.162"
|
||||
if '-' in timestring:
|
||||
# New format: "2026-07-05 19:13:59.162"
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
import tables
|
||||
import numpy
|
||||
import collections
|
||||
from typing import IO
|
||||
from typing import IO, Any, Literal, cast
|
||||
from . import Drawable
|
||||
|
||||
## provide gaussian statistics for a series of measured data points
|
||||
@@ -31,7 +31,10 @@ class AccumulatedValue:
|
||||
self.y2=self.y**2
|
||||
self.n=1
|
||||
elif mean_err is None:
|
||||
self.n=max(1, int(n))
|
||||
if n is None:
|
||||
self.n=1
|
||||
else:
|
||||
self.n=max(1, n)
|
||||
self.y=float(mean)*self.n
|
||||
self.y2=(float(mean)**2)*self.n
|
||||
elif n is None:
|
||||
@@ -240,7 +243,9 @@ class MeasurementResult(Drawable.Drawable, collections.UserDict):
|
||||
if complib is not None:
|
||||
if complevel is None:
|
||||
complevel=9
|
||||
filter=tables.Filters(complevel=complevel,complib=complib,shuffle=1)
|
||||
filter=tables.Filters(complevel=complevel,
|
||||
complib=cast(Literal["blosc", "blosc2", "bzip2", "lzo", "zlib"], complib),
|
||||
shuffle=True)
|
||||
|
||||
mr_table=hdffile.create_table(where=where,name=name,
|
||||
description=h5_table_format,
|
||||
@@ -248,11 +253,12 @@ class MeasurementResult(Drawable.Drawable, collections.UserDict):
|
||||
filters=filter,
|
||||
expectedrows=len(self))
|
||||
mr_table.flavor="numpy"
|
||||
mr_table.attrs.damaris_type="MeasurementResult"
|
||||
attrs = cast(Any, mr_table.attrs)
|
||||
attrs.damaris_type="MeasurementResult"
|
||||
self.lock.acquire()
|
||||
try:
|
||||
mr_table.attrs.quantity_name=self.quantity_name
|
||||
row=mr_table.row
|
||||
attrs.quantity_name=self.quantity_name
|
||||
row = cast(Any, mr_table.row)
|
||||
xdata=self.get_xdata()
|
||||
if xdata.shape[0]!=0:
|
||||
for x in xdata:
|
||||
@@ -276,10 +282,11 @@ def read_from_hdf(hdf_node: object) -> "MeasurementResult | None":
|
||||
if not isinstance(hdf_node, tables.Table):
|
||||
return None
|
||||
|
||||
if hdf_node._v_attrs.damaris_type!="MeasurementResult":
|
||||
attrs = cast(Any, hdf_node._v_attrs)
|
||||
if attrs.damaris_type!="MeasurementResult":
|
||||
return None
|
||||
|
||||
mr=MeasurementResult(hdf_node._v_attrs.quantity_name)
|
||||
mr=MeasurementResult(attrs.quantity_name)
|
||||
for r in hdf_node.iterrows():
|
||||
mr[r["x"]]=AccumulatedValue(r["y"],r["y_err"],r["n"])
|
||||
|
||||
|
||||
@@ -360,6 +360,20 @@ class TestAccumulation(unittest.TestCase):
|
||||
r *= 2
|
||||
np.testing.assert_array_equal(accu.y[0], np.array([10, 20, 30], dtype="float32"))
|
||||
|
||||
def test_empty_iadd_accumulation_without_common_descriptions(self):
|
||||
"""An accumulation without common descriptions can be copied in-place."""
|
||||
other = Accumulation(x=np.array([0.0, 1.0]),
|
||||
y=[np.array([10.0, 20.0])],
|
||||
n=1,
|
||||
index=[(0, 1)],
|
||||
sampl_freq=1000.0)
|
||||
accu = Accumulation()
|
||||
|
||||
accu += other
|
||||
|
||||
self.assertIsNone(accu.common_descriptions)
|
||||
np.testing.assert_array_equal(accu.y[0], other.y[0])
|
||||
|
||||
def test_accumulation_plus_accumulation_keeps_both_job_ids(self):
|
||||
"""accu1 + accu2 must keep the provenance of both operands."""
|
||||
adc1 = self.create_adc_result()
|
||||
|
||||
Reference in new issue
Block a user