ATLAS Offline Software
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 
19 #include "v40_write_ROBFragment.h"
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 
28 static const unsigned int ROB_HEADER = 0;
29 static const unsigned int ROB_STATUS = 1;
30 static const unsigned int ROB_CHECKSUM_TYPE = 2;
31 static const unsigned int ROD_HEADER = 3;
32 static const unsigned int ROD_STATUS = 4;
33 static const unsigned int ROD_DATA = 5;
34 static const unsigned int ROD_TRAILER = 6;
35 static 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
62  set(m_node[ROB_HEADER], m_header, 6, &m_node[ROB_STATUS]);
63  set(m_node[ROB_STATUS], &eformat::DEFAULT_STATUS, 1,
64  &m_node[ROB_CHECKSUM_TYPE]);
65  set(m_node[ROB_CHECKSUM_TYPE], &m_header[6], 1, &m_node[ROD_HEADER]);
66  if (m_rod_trailer[2] == eformat::STATUS_FRONT) {
67  set(m_node[ROD_HEADER], m_rod_header, 9, &m_node[ROD_STATUS]);
68  set(m_node[ROD_STATUS], &eformat::DEFAULT_STATUS, 1, &m_node[ROD_DATA]);
69  set(m_node[ROD_DATA], 0, 0, &m_node[ROD_TRAILER]);
70  }
71  else {
72  set(m_node[ROD_HEADER], m_rod_header, 9, &m_node[ROD_DATA]);
73  set(m_node[ROD_DATA], 0, 0, &m_node[ROD_STATUS]);
74  set(m_node[ROD_STATUS], &eformat::DEFAULT_STATUS, 1, &m_node[ROD_TRAILER]);
75  }
76  set(m_node[ROD_TRAILER], m_rod_trailer, 3, 0);
77 
78  //optional checksum stuff (trailer), for the initialization, it remains
79  //disconnected from the rest of the fragment.
80  m_checksum = 0;
81  set(m_node[ROB_CHECKSUM], &m_checksum, 1, 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();
94  rob_source_id(source_id);
95  rod_source_id(source_id);
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 
134 {
135  initialize();
136 }
137 
140 {
141  *this = other;
142 }
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));
150  status_position(rod[size_word-1]);
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);
165  v40::ROBFragment read(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 
183 {
184 }
185 
186 offline_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 
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],
277  m_node[ROB_HEADER].base[1]-m_node[ROB_HEADER].base[5]+n);
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],
293  m_node[ROB_HEADER].base[1]-m_node[ROD_TRAILER].base[0]+n);
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) {
308  m_node[ROD_HEADER].next = &m_node[ROD_STATUS];
309  m_node[ROD_STATUS].next = &m_node[ROD_DATA];
310  m_node[ROD_DATA].next = &m_node[ROD_TRAILER];
311  }
312  else {
313  m_node[ROD_HEADER].next = &m_node[ROD_DATA];
314  m_node[ROD_DATA].next = &m_node[ROD_STATUS];
315  m_node[ROD_STATUS].next = &m_node[ROD_TRAILER];
316  }
317 }
318 
320 {
321  if (m_parent) m_parent->size_change(m_node[ROB_HEADER].base[1],
322  m_node[ROB_HEADER].base[1]-m_node[ROD_TRAILER].base[1]+n);
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 
352 const 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());
364  m_node[ROD_TRAILER].next = &m_node[ROB_CHECKSUM];
365  }
366  return m_node;
367 }
368 
read
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)
Definition: openCoraCool.cxx:569
offline_eformat::v40_write::ROBFragment::status
const uint32_t * status(void) const
Returns a pointer to the first status word to be used by this fragment.
Definition: v40_write_ROBFragment.h:201
base
std::string base
Definition: hcg.cxx:78
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
offline_eformat::v40_write::ROBFragment::rod_data
const uint32_t * rod_data(void) const
Returns a pointer to the first of the data words at the ROD fragment.
Definition: v40_write_ROBFragment.h:285
v40_write_FullEventFragment.h
offline_eformat::v40::ROBFragment
Describes how to access the contents of a subdetector fragment, as prescribed by the event format not...
Definition: v40_ROBFragment.h:35
offline_eformat::v40_write::ROBFragment::m_rod_header
uint32_t m_rod_header[9]
The ROD Header.
Definition: v40_write_ROBFragment.h:526
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
initialize
void initialize()
Definition: run_EoverP.cxx:894
offline_eformat::v40_write::ROBFragment::checksum_type
uint32_t checksum_type(void) const
Returns the check sum type for this fragment.
Definition: v40_write_ROBFragment.h:342
offline_eformat::v40_write::ROBFragment::m_next
v40_write::ROBFragment * m_next
Next sibling.
Definition: v40_write_ROBFragment.h:531
offline_eformat::v40_write::ROBFragment::status_position
uint32_t status_position(void) const
Returns the current status position.
Definition: v40_write_ROBFragment.h:250
offline_eformat::v40_write::ROBFragment::m_rod_trailer
uint32_t m_rod_trailer[3]
The ROD trailer.
Definition: v40_write_ROBFragment.h:527
beamspotman.n
n
Definition: beamspotman.py:731
v40_ROBFragment.h
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
RunTileMonitoring.rod
rod
Definition: RunTileMonitoring.py:134
offline_eformat::v40_write::ROBFragment::~ROBFragment
virtual ~ROBFragment()
Base destructor.
Definition: v40_write_ROBFragment.cxx:182
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
offline_eformat::v40_write::ROBFragment::m_parent
v40_write::FullEventFragment * m_parent
My parent.
Definition: v40_write_ROBFragment.h:530
offline_eformat::v40_write::ROBFragment::m_checksum
uint32_t m_checksum
The ROB trailer.
Definition: v40_write_ROBFragment.h:528
offline_eformat::v40_write::ROBFragment::m_node
eformat::write::node_t m_node[8]
Node representation.
Definition: v40_write_ROBFragment.h:529
python.PyAthena.v
v
Definition: PyAthena.py:157
get_generator_info.version
version
Definition: get_generator_info.py:33
offline_eformat::v40_write::ROBFragment::ROBFragment
ROBFragment()
Builds a new "empty" ROB fragment, otherwise invalid.
Definition: v40_write_ROBFragment.cxx:133
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
offline_eformat::v40_write::ROBFragment
Defines a helper class to aid the creation of ROB fragments.
Definition: v40_write_ROBFragment.h:35
offline_eformat::v40_write::ROBFragment::initialize
void initialize(void)
Initializes the internal fields of this ROB fragment with the standard values.
Definition: v40_write_ROBFragment.cxx:37
offline_eformat::v40_write::ROBFragment::rod_bind
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 ...
Definition: v40_write_ROBFragment.cxx:352
merge.status
status
Definition: merge.py:17
offline_eformat::v40_write::ROBFragment::bind
eformat::write::node_t * bind(void)
Outputs a concatenation of eformat::write::node making up a list with the contents of this ROB fragme...
Definition: v40_write_ROBFragment.cxx:358
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
offline_eformat::v40_write::ROBFragment::rod_status
const uint32_t * rod_status(void) const
Returns a pointer to the first ROD status word to be used by this fragment.
Definition: v40_write_ROBFragment.h:237
checker_macros.h
Define macros for attributes used to control the static checker.
offline_eformat::v40_write::ROBFragment::m_header
uint32_t m_header[7]
The ROB Header.
Definition: v40_write_ROBFragment.h:525
offline_eformat::v40_write::ROBFragment::copy_header
void copy_header(const uint32_t *other)
Copies the header (meta data information) from another ROBFragment.
Definition: v40_write_ROBFragment.cxx:195
v40_write_ROBFragment.h