Skip to content

Commit ee19525

Browse files
committed
Add pu00 utilities
1 parent ead5c24 commit ee19525

7 files changed

Lines changed: 220 additions & 18 deletions

File tree

python/src/streaming_data_types/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from streaming_data_types.run_stop_6s4t import deserialise_6s4t, serialise_6s4t
1818
from streaming_data_types.status_x5f2 import deserialise_x5f2, serialise_x5f2
1919
from streaming_data_types.units_un00 import serialise_un00, deserialise_un00
20+
from streaming_data_types.pulse_metadata_pu00 import serialise_pu00, deserialise_pu00
2021

2122
__version__ = version
2223

@@ -37,6 +38,7 @@
3738
"ad00": serialise_ad00,
3839
"da00": serialise_da00,
3940
"un00": serialise_un00,
41+
"pu00": serialise_pu00,
4042
}
4143

4244

@@ -56,4 +58,5 @@
5658
"ad00": deserialise_ad00,
5759
"da00": deserialise_da00,
5860
"un00": deserialise_un00,
61+
"pu00": deserialise_pu00,
5962
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# automatically generated by the FlatBuffers compiler, do not modify
2+
3+
# namespace:
4+
5+
import flatbuffers
6+
from flatbuffers.compat import import_numpy
7+
np = import_numpy()
8+
9+
class Pu00Message(object):
10+
__slots__ = ['_tab']
11+
12+
@classmethod
13+
def GetRootAs(cls, buf, offset=0):
14+
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
15+
x = Pu00Message()
16+
x.Init(buf, n + offset)
17+
return x
18+
19+
@classmethod
20+
def GetRootAsPu00Message(cls, buf, offset=0):
21+
"""This method is deprecated. Please switch to GetRootAs."""
22+
return cls.GetRootAs(buf, offset)
23+
@classmethod
24+
def Pu00MessageBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
25+
return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x70\x75\x30\x30", size_prefixed=size_prefixed)
26+
27+
# Pu00Message
28+
def Init(self, buf, pos):
29+
self._tab = flatbuffers.table.Table(buf, pos)
30+
31+
# Pu00Message
32+
def SourceName(self):
33+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
34+
if o != 0:
35+
return self._tab.String(o + self._tab.Pos)
36+
return None
37+
38+
# Pu00Message
39+
def MessageId(self):
40+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
41+
if o != 0:
42+
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
43+
return 0
44+
45+
# Pu00Message
46+
def ReferenceTime(self):
47+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
48+
if o != 0:
49+
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
50+
return 0
51+
52+
# Pu00Message
53+
def Vetos(self):
54+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
55+
if o != 0:
56+
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
57+
return None
58+
59+
# Pu00Message
60+
def PeriodNumber(self):
61+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
62+
if o != 0:
63+
return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
64+
return None
65+
66+
# Pu00Message
67+
def ProtonCharge(self):
68+
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
69+
if o != 0:
70+
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
71+
return None
72+
73+
def Pu00MessageStart(builder):
74+
builder.StartObject(6)
75+
76+
def Start(builder):
77+
Pu00MessageStart(builder)
78+
79+
def Pu00MessageAddSourceName(builder, sourceName):
80+
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(sourceName), 0)
81+
82+
def AddSourceName(builder, sourceName):
83+
Pu00MessageAddSourceName(builder, sourceName)
84+
85+
def Pu00MessageAddMessageId(builder, messageId):
86+
builder.PrependInt64Slot(1, messageId, 0)
87+
88+
def AddMessageId(builder, messageId):
89+
Pu00MessageAddMessageId(builder, messageId)
90+
91+
def Pu00MessageAddReferenceTime(builder, referenceTime):
92+
builder.PrependInt64Slot(2, referenceTime, 0)
93+
94+
def AddReferenceTime(builder, referenceTime):
95+
Pu00MessageAddReferenceTime(builder, referenceTime)
96+
97+
def Pu00MessageAddVetos(builder, vetos):
98+
builder.PrependUint32Slot(3, vetos, None)
99+
100+
def AddVetos(builder, vetos):
101+
Pu00MessageAddVetos(builder, vetos)
102+
103+
def Pu00MessageAddPeriodNumber(builder, periodNumber):
104+
builder.PrependUint32Slot(4, periodNumber, None)
105+
106+
def AddPeriodNumber(builder, periodNumber):
107+
Pu00MessageAddPeriodNumber(builder, periodNumber)
108+
109+
def Pu00MessageAddProtonCharge(builder, protonCharge):
110+
builder.PrependFloat32Slot(5, protonCharge, None)
111+
112+
def AddProtonCharge(builder, protonCharge):
113+
Pu00MessageAddProtonCharge(builder, protonCharge)
114+
115+
def Pu00MessageEnd(builder):
116+
return builder.EndObject()
117+
118+
def End(builder):
119+
return Pu00MessageEnd(builder)

python/src/streaming_data_types/fbschemas/pulse_metadata_pu00/__init__.py

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from collections import namedtuple
2+
import flatbuffers
3+
4+
import streaming_data_types.fbschemas.pulse_metadata_pu00.Pu00Message as Pu00Message
5+
from streaming_data_types.utils import check_schema_identifier
6+
7+
FILE_IDENTIFIER = b"pu00"
8+
9+
PulseMetadata = namedtuple("PulseMetadata", ("source_name", "message_id", "timestamp_ns", "vetos", "period_number", "proton_charge"))
10+
11+
12+
def deserialise_pu00(buffer) -> PulseMetadata:
13+
check_schema_identifier(buffer, FILE_IDENTIFIER)
14+
pu00 = Pu00Message.Pu00Message.GetRootAsPu00Message(buffer, 0)
15+
16+
return PulseMetadata(
17+
source_name=pu00.SourceName().decode("utf-8"),
18+
message_id=pu00.MessageId(),
19+
timestamp_ns=pu00.ReferenceTime(),
20+
period_number=pu00.PeriodNumber(),
21+
proton_charge=pu00.ProtonCharge(),
22+
vetos=pu00.Vetos(),
23+
)
24+
25+
26+
def serialise_pu00(source_name: str, message_id: int, timestamp_ns: int, vetos: int | None, period_number: int | None, proton_charge: float | None) -> bytes:
27+
builder = flatbuffers.Builder(128)
28+
29+
source_offset = builder.CreateString(source_name)
30+
31+
Pu00Message.Pu00MessageStart(builder)
32+
Pu00Message.AddSourceName(builder, source_offset)
33+
Pu00Message.AddMessageId(builder, message_id)
34+
Pu00Message.AddReferenceTime(builder, timestamp_ns)
35+
if vetos is not None:
36+
Pu00Message.AddVetos(builder, vetos)
37+
if period_number is not None:
38+
Pu00Message.AddPeriodNumber(builder, period_number)
39+
if proton_charge is not None:
40+
Pu00Message.AddProtonCharge(builder, proton_charge)
41+
result = Pu00Message.Pu00MessageEnd(builder)
42+
43+
builder.Finish(result, file_identifier=FILE_IDENTIFIER)
44+
return bytes(builder.Output())

python/tests/test_pu00.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
3+
from streaming_data_types import DESERIALISERS, SERIALISERS
4+
from streaming_data_types.exceptions import WrongSchemaException
5+
from streaming_data_types.pulse_metadata_pu00 import deserialise_pu00, serialise_pu00
6+
7+
8+
class TestSerialisationPu00:
9+
def test_serialises_and_deserialises_pu00_message_correctly(self):
10+
"""
11+
Round-trip to check what we serialise is what we get back.
12+
"""
13+
buf = serialise_pu00("some_source", 123, 456, vetos=1, period_number=2, proton_charge=3.)
14+
entry = deserialise_pu00(buf)
15+
16+
assert entry.source_name == "some_source"
17+
assert entry.message_id == 123
18+
assert entry.timestamp_ns == 456
19+
assert entry.vetos == 1
20+
assert entry.period_number == 2
21+
assert entry.proton_charge == pytest.approx(3.)
22+
23+
def test_serialises_and_deserialises_un00_message_correctly_with_none(self):
24+
"""
25+
Round-trip to check what we serialise is what we get back with None specified as a unit.
26+
"""
27+
buf = serialise_pu00("some_source", 123, 456, None, None, None)
28+
entry = deserialise_pu00(buf)
29+
30+
assert entry.source_name == "some_source"
31+
assert entry.message_id == 123
32+
assert entry.timestamp_ns == 456
33+
assert entry.vetos is None
34+
assert entry.period_number is None
35+
assert entry.proton_charge is None
36+
37+
def test_if_buffer_has_wrong_id_then_throws(self):
38+
buf = serialise_pu00("some_source", 1234567890, 123, None, None, None)
39+
40+
# Manually hack the id
41+
buf = bytearray(buf)
42+
buf[4:8] = b"1234"
43+
44+
with pytest.raises(WrongSchemaException):
45+
deserialise_pu00(buf)
46+
47+
def test_schema_type_is_in_global_serialisers_list(self):
48+
assert "pu00" in SERIALISERS
49+
assert "pu00" in DESERIALISERS
Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,36 @@
11
#[path = "6s4t_run_stop.rs"]
22
pub mod run_stop_6s4t;
3-
43
#[path = "ad00_area_detector_array.rs"]
54
pub mod area_detector_array_ad00;
6-
75
#[path = "al00_alarm.rs"]
86
pub mod alarm_al00;
9-
107
#[path = "answ_action_response.rs"]
118
pub mod action_response_answ;
12-
139
#[path = "da00_dataarray.rs"]
1410
pub mod dataarray_da00;
15-
1611
#[path = "df12_det_spec_map.rs"]
1712
pub mod det_spec_map_df12;
18-
1913
#[path = "ep01_epics_connection.rs"]
2014
pub mod epics_connection_ep01;
21-
2215
#[path = "ev44_events.rs"]
2316
pub mod events_ev44;
24-
2517
#[path = "f144_logdata.rs"]
2618
pub mod logdata_f144;
27-
2819
#[path = "fc00_forwarder_config.rs"]
2920
pub mod forwarder_config_fc00;
30-
3121
#[path = "hs01_event_histogram.rs"]
3222
pub mod event_histogram_hs01;
33-
3423
#[path = "json_json.rs"]
3524
pub mod json_json;
36-
3725
#[path = "pl72_run_start.rs"]
3826
pub mod run_start_pl72;
39-
4027
#[path = "pu00_pulse_metadata.rs"]
4128
pub mod pulse_metadata_pu00;
42-
4329
#[path = "se00_data.rs"]
4430
pub mod data_se00;
45-
4631
#[path = "un00_units.rs"]
4732
pub mod units_un00;
48-
4933
#[path = "wrdn_finished_writing.rs"]
5034
pub mod finished_writing_wrdn;
51-
5235
#[path = "x5f2_status.rs"]
5336
pub mod status_x5f2;
54-

rust/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::flatbuffers_generated::forwarder_config_fc00::{
2121
};
2222
use crate::flatbuffers_generated::json_json::{JsonData, root_as_json_data};
2323
use crate::flatbuffers_generated::logdata_f144::{f144_LogData, root_as_f_144_log_data};
24+
use crate::flatbuffers_generated::pulse_metadata_pu00::{Pu00Message, root_as_pu_00_message};
2425
use crate::flatbuffers_generated::run_start_pl72::{RunStart, root_as_run_start};
2526
use crate::flatbuffers_generated::run_stop_6s4t::{RunStop, root_as_run_stop};
2627
use crate::flatbuffers_generated::status_x5f2::{Status, root_as_status};
@@ -37,6 +38,7 @@ pub mod flatbuffers_generated;
3738
#[derive(Debug, Clone, PartialEq)]
3839
pub enum DeserializedMessage<'a> {
3940
EventDataEv44(Event44Message<'a>),
41+
PulseMetadataPu00(Pu00Message<'a>),
4042
AreaDetectorAd00(ad00_ADArray<'a>),
4143
RunStartPl72(RunStart<'a>),
4244
RunStop6s4t(RunStop<'a>),
@@ -83,6 +85,9 @@ pub fn deserialize_message(data: &[u8]) -> Result<DeserializedMessage<'_>, Deser
8385
Some(b"ev44") => Ok(DeserializedMessage::EventDataEv44(
8486
root_as_event_44_message(data)?,
8587
)),
88+
Some(b"pu00") => Ok(DeserializedMessage::PulseMetadataPu00(
89+
root_as_pu_00_message(data)?,
90+
)),
8691
Some(b"ad00") => Ok(DeserializedMessage::AreaDetectorAd00(
8792
root_as_ad_00_adarray(data)?,
8893
)),

0 commit comments

Comments
 (0)