ATLAS Offline Software
Loading...
Searching...
No Matches
v40_write_ROBFragment.cxx
Go to the documentation of this file.
1//Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5*/
6
7
17
20#include "eformat/HeaderMarker.h"
21#include "v40_ROBFragment.h"
22#include "eformat/Status.h"
23#include "eformat/Issue.h"
24#include "eformat/checksum.h"
26#include <cstring>
27
28static const unsigned int ROB_HEADER = 0;
29static const unsigned int ROB_STATUS = 1;
30static const unsigned int ROB_CHECKSUM_TYPE = 2;
31static const unsigned int ROD_HEADER = 3;
32static const unsigned int ROD_STATUS = 4;
33static const unsigned int ROD_DATA = 5;
34static const unsigned int ROD_TRAILER = 6;
35static const unsigned int ROB_CHECKSUM = 7;
36
38 m_parent = 0;
39 m_next = 0;
40 m_header[0] = eformat::ROB; //marker
41 m_header[1] = 21;
42 m_header[2] = 8; //this header size + status size
43 eformat::helper::Version version(0, eformat::MAJOR_V40_VERSION);
44 m_header[3] = version.code(); //format version
45 m_header[4] = 0; //source identifier of the ROB fragment
46 m_header[5] = 1; //number of status
47 m_header[6] = eformat::NO_CHECKSUM; //check sum
48 m_rod_header[0] = eformat::ROD; //ROD marker
49 m_rod_header[1] = 9; //ROD header size
50 m_rod_header[2] = eformat::DEFAULT_ROD_VERSION; //format version
51 m_rod_header[3] = 0; //source identifier of the ROD fragment
52 m_rod_header[4] = 0; //run number
53 m_rod_header[5] = 0; //LVL1 identifier
54 m_rod_header[6] = 0; //bunch crossing identifier
55 m_rod_header[7] = 0; //LVL1 type
56 m_rod_header[8] = 0; //detector event type
57 m_rod_trailer[0] = 1; //number of status in the ROD
58 m_rod_trailer[1] = 0; //number of data words in the ROD
59 m_rod_trailer[2] = eformat::STATUS_FRONT; //status block position
60
61 //now initialize pages
63 set(m_node[ROB_STATUS], &eformat::DEFAULT_STATUS, 1,
66 if (m_rod_trailer[2] == eformat::STATUS_FRONT) {
68 set(m_node[ROD_STATUS], &eformat::DEFAULT_STATUS, 1, &m_node[ROD_DATA]);
70 }
71 else {
74 set(m_node[ROD_STATUS], &eformat::DEFAULT_STATUS, 1, &m_node[ROD_TRAILER]);
75 }
77
78 //optional checksum stuff (trailer), for the initialization, it remains
79 //disconnected from the rest of the fragment.
80 m_checksum = 0;
82}
83
85(uint32_t source_id,
86 uint32_t run_no,
87 uint32_t lvl1_id,
88 uint32_t bc_id,
89 uint32_t lvl1_type,
90 uint32_t detev_type,
91 uint32_t ndata, const uint32_t* data, uint32_t status_position)
92{
93 initialize();
96 rod_run_no(run_no);
97 rod_lvl1_id(lvl1_id);
98 rod_bc_id(bc_id);
99 rod_lvl1_type(lvl1_type);
100 rod_detev_type(detev_type);
101
102 //now initialize pages
103 this->status_position(status_position);
104 status(1, &eformat::DEFAULT_STATUS);
105 rod_data(ndata, data);
106}
107
109(uint32_t rob_source_id,
110 uint32_t rod_source_id,
111 uint32_t run_no,
112 uint32_t lvl1_id,
113 uint32_t bc_id,
114 uint32_t lvl1_type,
115 uint32_t detev_type,
116 uint32_t ndata, const uint32_t* data, uint32_t status_position)
117{
118 initialize();
119 this->rob_source_id(rob_source_id);
120 this->rod_source_id(rod_source_id);
121 rod_run_no(run_no);
122 rod_lvl1_id(lvl1_id);
123 rod_bc_id(bc_id);
124 rod_lvl1_type(lvl1_type);
125 rod_detev_type(detev_type);
126
127 //now initialize pages
128 this->status_position(status_position);
129 status(1, &eformat::DEFAULT_STATUS);
130 rod_data(ndata, data);
131}
132
137
143
145 uint32_t size_word)
146{
147 initialize();
148 status(1, &eformat::DEFAULT_STATUS);
149 memcpy(m_rod_header, rod, 9*sizeof(uint32_t));
151 rod_data(rod[size_word-2],
152 status_position()?&rod[9]:&rod[9+rod[size_word-3]]);
153 rod_status(rod[size_word-3],
154 status_position()?&rod[9+rod[size_word-2]]:&rod[9]);
155 //make sure the ROD version is correct
156 m_rod_header[2] = eformat::DEFAULT_ROD_VERSION | (0xffff & m_rod_header[2]);
157
158 rob_source_id(rod_source_id()); //copies ROD source identifier
159}
160
162{
163 initialize();
164 copy_header(rob);
166 const uint32_t* tmp;
167
168 //cares about the data section of the ROD fragment.
169 if (read.check_rod_noex()) {
170 read.rod_data(tmp);
171 rod_data(read.rod_ndata(), tmp);
172 }
173 else if (read.payload_size_word() >= 9) {
174 read.rod_start(tmp);
175 rod_data(read.payload_size_word()-9, tmp+9);
176 }
177 else { //there is not even data here
178 rod_data(0, 0);
179 }
180}
181
185
186offline_eformat::v40_write::ROBFragment& offline_eformat::v40_write::ROBFragment::operator=
188{
189 initialize();
190 copy_header(other);
191 rod_data(other.rod_ndata(), other.rod_data());
192 return *this;
193}
194
196 v40::ROBFragment read(other);
197 if (!read.check_rob_noex()) { //gives us a reasonable start up scenario
198 throw EFORMAT_UNSUPPORTED_OPERATION("operate on corrupted", eformat::ROB);
199 }
200 eformat::helper::Version robver(read.version());
201 minor_version(robver.minor_version());
202 rob_source_id(read.source_id());
203 const uint32_t* tmp;
204 read.status(tmp);
205 status(read.nstatus(), tmp);
206 const uint32_t* rod;
207 read.rod_start(rod);
208 uint32_t rod_size = read.payload_size_word();
209
210 if (rod_size >= 9) {
211 memcpy(m_rod_header, rod, 9*sizeof(uint32_t));
212 }
213 else {
214 //we have less than 9 words!
215 uint32_t size_diff = 9 - rod_size;
216 memcpy(m_rod_header, rod, rod_size*sizeof(uint32_t));
217 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
218 m_node[ROB_HEADER].base[1] - size_diff);
219 m_node[ROD_HEADER].size_word = rod_size;
220 m_node[ROB_HEADER].base[1] -= size_diff; //total size should be reduced
221 }
222
223 if (read.check_rod_noex()) {
224 status_position(read.rod_status_position());
225 read.rod_status(tmp);
226 rod_status(read.rod_nstatus(), tmp);
227 }
228 else {
229 //this ROD is corrupted, so we should ignore its status words and the
230 //trailer as well. Just put out what is there as it was data.
231 rod_status(0, 0);
232 m_node[ROD_TRAILER].size_word = 0;
233 const uint32_t size_diff = 3;
234 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
235 m_node[ROB_HEADER].base[1] - size_diff);
236 m_node[ROB_HEADER].base[1] -= size_diff;
237 }
238 checksum_type(read.checksum_type()); //re-links node[6] => node[7] if nedeed
239}
240
243
244 minor_version(other.minor_version());
245 rob_source_id(other.source_id());
246 memcpy(reinterpret_cast<void*>(m_rod_header),
247 reinterpret_cast<const void*>(other.m_rod_header), 9*sizeof(uint32_t));
248
249 if (other.m_node[ROD_HEADER].size_word != 9) {
250 //probably a corrupted ROD in the other side, set the appropriate size for
251 //this header
252 uint32_t size_diff = 9 - other.m_node[ROD_HEADER].size_word;
253 m_node[ROD_HEADER].size_word = other.m_node[ROD_HEADER].size_word;
254 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
255 m_node[ROB_HEADER].base[1] - size_diff);
256 m_node[ROB_HEADER].base[1] -= size_diff;
257 }
258
259 status(other.nstatus(), other.status());
260 status_position(other.status_position());
261 rod_status(other.rod_nstatus(), other.rod_status());
262
263 if (other.m_node[ROD_TRAILER].size_word != 3) {
264 //probably a corrupted ROD in the other side, zero trailer!
265 uint32_t size_diff = 3 - other.m_node[ROD_TRAILER].size_word;
266 m_node[ROD_TRAILER].size_word = other.m_node[ROD_TRAILER].size_word;
267 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
268 m_node[ROB_HEADER].base[1] - size_diff);
269 m_node[ROB_HEADER].base[1] -= size_diff;
270 }
271 checksum_type(other.checksum_type()); //re-links node[6] => node[7] if nedeed
272}
273
275{
276 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
278 m_node[ROB_HEADER].base[1] -= m_node[ROB_HEADER].base[5]; //remove count from previous status
279 m_node[ROB_HEADER].base[2] -= m_node[ROB_HEADER].base[5]; //remove count from previous status
280 m_node[ROB_STATUS].size_word = m_node[ROB_HEADER].base[5] = n; //set new values
281 m_node[ROB_HEADER].base[1] += n;
282 m_node[ROB_HEADER].base[2] += n;
283 // FIXME: I'm assuming that these are ok.
284 // Probably can't avoid this as long as we're using node_t from eformat.
285 uint32_t* status_nc ATLAS_THREAD_SAFE = const_cast<uint32_t*>(status);
286 m_node[ROB_STATUS].base = status_nc;
287}
288
290 const uint32_t* status)
291{
292 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
294 m_node[ROB_HEADER].base[1] -= m_node[ROD_TRAILER].base[0]; //remove count from previous status
295 m_node[ROD_STATUS].size_word = m_node[ROD_TRAILER].base[0] = n; //set new values
296 m_node[ROB_HEADER].base[1] += n; //set ROB header's total fragment size
297 // FIXME: I'm assuming that these are ok.
298 // Probably can't avoid this as long as we're using node_t from eformat.
299 uint32_t* status_nc ATLAS_THREAD_SAFE = const_cast<uint32_t*>(status);
300 m_node[ROD_STATUS].base = status_nc;
301}
302
304{
305 if (v == m_node[ROD_TRAILER].base[2]) return; //do nothing in this case:)
306 m_node[ROD_TRAILER].base[2] = v;
307 if (m_node[ROD_TRAILER].base[2] == eformat::STATUS_FRONT) {
311 }
312 else {
316 }
317}
318
320{
321 if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
323
324 //remove count from previous data size
325 m_node[ROB_HEADER].base[1] -= m_node[ROD_TRAILER].base[1];
326 m_node[ROD_DATA].size_word = m_node[ROD_TRAILER].base[1] = n; //set new values
327 m_node[ROB_HEADER].base[1] += n; //set ROB header's total fragment size back
328 // FIXME: I'm assuming that these are ok.
329 // Probably can't avoid this as long as we're using node_t from eformat.
330 uint32_t* data_nc ATLAS_THREAD_SAFE = const_cast<uint32_t*>(data);
331 m_node[ROD_DATA].base = data_nc;
332}
333
335{
336 if (m_node[ROB_CHECKSUM_TYPE].base[0] == eformat::NO_CHECKSUM && s != eformat::NO_CHECKSUM) {
337 //Going from no checksum to having a checksum: update sizes
338 if (m_parent)
339 m_parent->size_change(m_node[ROB_HEADER].base[1], m_node[ROB_HEADER].base[1]+1);
340 m_node[ROB_HEADER].base[1] += 1;
341 }
342 else if (m_node[ROB_CHECKSUM_TYPE].base[0] != eformat::NO_CHECKSUM &&
343 s == eformat::NO_CHECKSUM) {
344 //Going from having a checksum to no checksum: update sizes
345 if (m_parent)
346 m_parent->size_change(m_node[ROB_HEADER].base[1], m_node[ROB_HEADER].base[1]-1);
347 m_node[ROB_HEADER].base[1] -= 1;
348 }
349 m_header[6] = m_node[ROB_CHECKSUM_TYPE].base[0] = s;
350}
351
352const eformat::write::node_t* offline_eformat::v40_write::ROBFragment::rod_bind(void)
353{
354 m_node[ROD_TRAILER].next = 0; //cuts off the checksum word
355 return &m_node[ROD_HEADER];
356}
357
359{
360 m_node[ROD_TRAILER].next = 0; //cuts off the checksum word
361 m_node[ROB_CHECKSUM].next = 0; //cuts off relation ships with other fragments
362 if (checksum_type() != eformat::NO_CHECKSUM) {
363 m_checksum = eformat::write::checksum(checksum_type(), rod_bind());
365 }
366 return m_node;
367}
368
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Describes how to access the contents of a subdetector fragment, as prescribed by the event format not...
Defines a helper class to aid the creation of ROB fragments.
void rod_bc_id(uint32_t s)
Changes the bunch crossing identifier in the ROD fragment.
void checksum_type(uint32_t s)
Changes the check sum type for this fragment.
v40_write::ROBFragment * m_next
Next sibling.
void rob_source_id(uint32_t s)
Changes the source identifier for only the ROB fragment.
eformat::write::node_t m_node[8]
Node representation.
void rod_lvl1_type(uint32_t s)
Changes the lvl1 trigger type in the ROD fragment.
const eformat::write::node_t * rod_bind(void)
Outputs a concatenation of eformat::write::node making up a list with the contents of the underlying ...
void initialize(void)
Initializes the internal fields of this ROB fragment with the standard values.
eformat::write::node_t * bind(void)
Outputs a concatenation of eformat::write::node making up a list with the contents of this ROB fragme...
void status(uint32_t n, const uint32_t *status)
Changes the number of status words and the status words themselves from the fragment.
void rod_detev_type(uint32_t s)
Changes the detector event type in the ROD fragment.
void rod_run_no(uint32_t s)
Changes the run number for the ROD fragment.
ROBFragment(uint32_t source_id, uint32_t run_no, uint32_t lvl1_id, uint32_t bc_id, uint32_t lvl1_type, uint32_t detev_type, uint32_t ndata, const uint32_t *data, uint32_t status_position)
Builds a new ROB fragment from scratch.
v40_write::FullEventFragment * m_parent
My parent.
void rod_lvl1_id(uint32_t s)
Changes the lvl1 identifier in the ROD fragment.
uint32_t size_word(void) const
Returns the total size for this fragment, in words.
void status_position(uint32_t v)
Changes the order of the status and data blocks in the ROD fragment.
void rod_source_id(uint32_t s)
Changes the source identifier for only the ROD fragment.
void rod_status(uint32_t n, const uint32_t *status)
Changes the number of status words and the status words themselves from the ROD fragment.
void copy_header(const uint32_t *other)
Copies the header (meta data information) from another ROBFragment.
void source_id(uint32_t s)
Changes the source identifier for both the ROB and the ROD fragments.
void minor_version(uint16_t v)
Changes the minor version number of the fragment.
void rod_data(uint32_t n, const uint32_t *data)
Changes the number of data words and the data words themselves from the ROD fragment.
STL class.
std::string base
Definition hcg.cxx:81
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)
void initialize()
static const unsigned int ROB_HEADER
static const unsigned int ROD_DATA
static const unsigned int ROB_CHECKSUM
static const unsigned int ROB_CHECKSUM_TYPE
static const unsigned int ROD_TRAILER
static const unsigned int ROB_STATUS
static const unsigned int ROD_HEADER
static const unsigned int ROD_STATUS