Skip to content

Commit 756c125

Browse files
committed
NEW: change to kaitai lazy parsing of WDS (and images)
Raw Spectra data is loaded on-demand from files
1 parent dc05d98 commit 756c125

File tree

3 files changed

+97
-8
lines changed

3 files changed

+97
-8
lines changed

lib/parsers/cameca.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,29 @@ def __eq__(self, other):
9292
Cameca.ElementT = ElementT
9393

9494

95+
class LazyData(Cameca.LazyData):
96+
97+
def _read(self):
98+
seek_to_pos = self.offset + self.size
99+
self._root._io.seek(seek_to_pos)
100+
101+
@property
102+
def lazy_bytes(self):
103+
if not hasattr(self, "_m_lazy_bytes"):
104+
io_fn = self._root._io._io.name
105+
with open(io_fn, "rb") as fn:
106+
fn.seek(self.offset)
107+
self._m_lazy_bytes = fn.read(self.size)
108+
return self._m_lazy_bytes
109+
110+
@lazy_bytes.deleter
111+
def lazy_bytes(self):
112+
del self._m_bytes
113+
114+
115+
Cameca.LazyData = LazyData
116+
117+
95118
class WdsScanSignal(Cameca.WdsScanSignal):
96119
def __init__(self, *args, **kwargs):
97120
super().__init__(*args, **kwargs)
@@ -110,7 +133,8 @@ def y_cps(self):
110133
if self._y_recalc_cps is not None:
111134
return self._y_recalc_cps
112135
if self._y_orig_cps is None:
113-
self._y_orig_cps = np.frombuffer(self.data, dtype=np.float32)
136+
self._y_orig_cps = np.frombuffer(self.data.lazy_bytes,
137+
dtype=np.float32)
114138
return self._y_orig_cps
115139

116140
@cached_property

lib/parsers/cameca_ks/cameca.ksy

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ types:
644644
(dataset_type != dataset_type::line_stage) and
645645
(dataset_type != dataset_type::line_beam)
646646
- id: data
647-
size: frame_size
647+
type: lazy_data(_root._io.pos, frame_size)
648648
repeat: expr
649649
repeat-expr: n_of_frames
650650
doc: |
@@ -793,7 +793,7 @@ types:
793793
type: f4
794794
- id: enabled
795795
type: u4
796-
doc: use in calculations
796+
doc: is this item used in calculations
797797
- id: peak_raw_cts
798798
type: s4
799799
- id: bkgd_1_raw_cts
@@ -808,6 +808,10 @@ types:
808808
type: s4
809809
- id: reserved_4
810810
size-eos: true
811+
instances:
812+
net_intensity:
813+
value: (peak_cps - bkgd_inter_cps) / beam_current
814+
-webide-representation: '{net_intensity:str}'
811815

812816
wds_qti_signal:
813817
params:
@@ -912,7 +916,7 @@ types:
912916
- id: data_array_size
913917
type: u4
914918
- id: data
915-
size: data_array_size
919+
type: lazy_data(_root._io.pos, data_array_size)
916920
- id: not_re_flag
917921
type: u4
918922
- id: signal_name
@@ -1407,6 +1411,29 @@ types:
14071411
type: qti_wds_measurement_setups
14081412
if: wds_measurement_struct_type >= 19
14091413

1414+
lazy_data:
1415+
doc: |
1416+
its _read method needs to be reimplemented in target language
1417+
to seek in the stream by provided size by parameter instead
1418+
of reading into memory
1419+
params:
1420+
- id: offset
1421+
type: u4
1422+
- id: size
1423+
type: u4
1424+
instances:
1425+
lazy_bytes:
1426+
io: _root._io
1427+
pos: offset
1428+
size: size
1429+
doc: "lazily parsed bytes on-demand"
1430+
seq:
1431+
- id: parsed_bytes
1432+
size: size
1433+
doc: |
1434+
this needs to be get rid off in target language and replaced with
1435+
relative seek.
1436+
14101437
wds_scan_spect_setup:
14111438
seq:
14121439
- id: xtal
@@ -1568,7 +1595,7 @@ types:
15681595
unix_timestamp:
15691596
value: ms_filetime / 10000000. - 11644473600
15701597
doc: 'seconds since Jan 1 1970'
1571-
1598+
15721599
element_t:
15731600
seq:
15741601
- id: atomic_number

lib/parsers/cameca_ks/cameca.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ def _read(self):
625625

626626
self.data = [None] * (self.n_of_frames)
627627
for i in range(self.n_of_frames):
628-
self.data[i] = self._io.read_bytes(self.frame_size)
628+
self.data[i] = self._root.LazyData(self._root._io.pos(), self.frame_size, self._io, self, self._root)
629629

630630
self.reserved_0 = self._io.read_bytes(56)
631631
self.lut_name = self._root.CSharpString(self._io, self, self._root)
@@ -680,6 +680,36 @@ def _read(self):
680680
self.user_comment = (self._io.read_bytes_full()).decode(u"CP1252")
681681

682682

683+
class LazyData(KaitaiStruct):
684+
"""its _read method needs to be reimplemented in target language
685+
to seek in the stream by provided size by parameter instead
686+
of reading into memory
687+
"""
688+
def __init__(self, offset, size, _io, _parent=None, _root=None):
689+
self._io = _io
690+
self._parent = _parent
691+
self._root = _root if _root else self
692+
self.offset = offset
693+
self.size = size
694+
self._read()
695+
696+
def _read(self):
697+
self.parsed_bytes = self._io.read_bytes(self.size)
698+
699+
@property
700+
def lazy_bytes(self):
701+
"""lazily parsed bytes on-demand."""
702+
if hasattr(self, '_m_lazy_bytes'):
703+
return self._m_lazy_bytes if hasattr(self, '_m_lazy_bytes') else None
704+
705+
io = self._root._io
706+
_pos = io.pos()
707+
io.seek(self.offset)
708+
self._m_lazy_bytes = io.read_bytes(self.size)
709+
io.seek(_pos)
710+
return self._m_lazy_bytes if hasattr(self, '_m_lazy_bytes') else None
711+
712+
683713
class QtiDataItem(KaitaiStruct):
684714
def __init__(self, _io, _parent=None, _root=None):
685715
self._io = _io
@@ -1124,6 +1154,14 @@ def _read(self):
11241154
self.reserved_3 = self._io.read_s4le()
11251155
self.reserved_4 = self._io.read_bytes_full()
11261156

1157+
@property
1158+
def net_intensity(self):
1159+
if hasattr(self, '_m_net_intensity'):
1160+
return self._m_net_intensity if hasattr(self, '_m_net_intensity') else None
1161+
1162+
self._m_net_intensity = ((self.peak_cps - self.bkgd_inter_cps) / self.beam_current)
1163+
return self._m_net_intensity if hasattr(self, '_m_net_intensity') else None
1164+
11271165

11281166
class XtalT(KaitaiStruct):
11291167
def __init__(self, _io, _parent=None, _root=None):
@@ -1141,7 +1179,7 @@ def rev_name(self):
11411179
return self._m_rev_name if hasattr(self, '_m_rev_name') else None
11421180

11431181
_pos = self._io.pos()
1144-
self._io.seek((0 if self.first_byte > 0x20 else 1))
1182+
self._io.seek((0 if self.first_byte > 32 else 1))
11451183
self._m_rev_name = (self._io.read_bytes_full()).decode(u"CP1252")
11461184
self._io.seek(_pos)
11471185
return self._m_rev_name if hasattr(self, '_m_rev_name') else None
@@ -1517,7 +1555,7 @@ def _read(self):
15171555
self.dwell_time = self._io.read_f4le()
15181556
self.beam_size = self._io.read_u4le()
15191557
self.data_array_size = self._io.read_u4le()
1520-
self.data = self._io.read_bytes(self.data_array_size)
1558+
self.data = self._root.LazyData(self._root._io.pos(), self.data_array_size, self._io, self, self._root)
15211559
self.not_re_flag = self._io.read_u4le()
15221560
self.signal_name = self._root.CSharpString(self._io, self, self._root)
15231561
self.reserved_0 = self._io.read_bytes(4)

0 commit comments

Comments
 (0)