BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
util.cxx
Go to the documentation of this file.
1// Dear emacs, this is -*- c++ -*-
2
3/**
4 * @file util.cxx
5 * @author <a href="mailto:Andre.dos.Anjos@cern.ch>Andr Rabello dos
6 * ANJOS</a>
7 * $Author: maqm $
8 * $Revision: 1.2 $
9 * $Date: 2022/01/06 21:15:37 $
10 *
11 * @brief Implements a set of utilities common to many event operations.
12 */
13
14#include "eformat/util.h"
15#include "eformat/FullEventFragment.h"
16#include "eformat/ROBFragment.h"
17#include "eformat/ROSFragment.h"
18#include "eformat/SubDetectorFragment.h"
19#include "eformat/WrongMarkerIssue.h"
20#include "ers/StreamFactory.h"
21
22using namespace eformat;
23
24uint32_t* eformat::next_fragment( std::fstream& fs, uint32_t* addr, size_t size ) {
25 using namespace eformat;
26
27 off_t offset = fs.tellg();
28 ERS_DEBUG_3( "Current stream position is 0x%lx", offset );
29
30 uint32_t data[2];
31 if ( fs && fs.good() && !fs.eof() )
32 {
33 // soft check, so we don't make mistakes
34 fs.read( (char*)data, 8 );
35 if ( !fs.good() || fs.eof() ) return 0; // end-of-file
36 switch ( (HeaderMarker)data[0] )
37 {
38 case FULL_EVENT:
39 case SUB_DETECTOR:
40 case ROS:
41 case ROB:
42 case ROD: break;
43 default:
44 // stop!
45 std::cout << "Word at offset " << HEX( offset ) << " is not one of " << HEX( FULL_EVENT )
46 << ", " << HEX( SUB_DETECTOR ) << ", " << HEX( ROS ) << ", " << HEX( ROB )
47 << "or " << HEX( ROS ) << ". Stopping execution..." << std::endl;
48 return 0;
49 }
50 }
51 else return 0; // file is over
52
53 // data[1] is the fragment size, in words. Take it and read the fragment
54 ERS_DEBUG_3( "Resetting stream position to 0x%lx...", offset );
55 fs.seekg( offset );
56 if ( addr && ( size >= ( data[1] * 4 ) ) )
57 {
58 // space is preallocated and checked
59 ERS_DEBUG_3( "Reading fragment data..." );
60 fs.read( (char*)addr, data[1] * 4 );
61 ERS_DEBUG_2( "Size of fragment readout is %u bytes", 4 * data[1] );
62 ERS_DEBUG_3( "Stream position is 0x%lx", offset = fs.tellg() );
63 return addr;
64 }
65 else if ( addr )
66 {
67 std::cout << "The fragment at offset " << HEX( offset ) << " has " << data[1] * 4
68 << " bytes and you provided only " << size
69 << " bytes in your buffer. Stopping execution..." << std::endl;
70 return 0;
71 }
72
73 // if I get here, is because I have to allocate space myself
74 ERS_DEBUG_3( "Allocating fragment data storage of size %ud bytes", 4 * data[1] );
75 uint32_t* retval = new uint32_t[data[1]];
76 ERS_DEBUG_3( "Reading fragment data..." );
77 fs.read( (char*)retval, data[1] * 4 );
78 ERS_DEBUG_2( "Size of fragment readout is %u bytes", 4 * data[1] );
79 ERS_DEBUG_3( "Stream position is 0x%lx", offset = fs.tellg() );
80 return retval;
81}
82
83size_t eformat::find_rods( const uint32_t* block_start, size_t block_size,
84 const uint32_t** rod, uint32_t* rod_size, size_t max_count ) {
85 const uint32_t* block_end = block_start + block_size;
86 size_t counter = 0;
87 while ( block_end > block_start )
88 {
89 uint32_t curr_rod_size = 12; //< base size for a ROD as eformat 2.4
90 curr_rod_size += *( block_end - 3 ) + *( block_end - 2 ); // status and data sizes
91 block_end -= curr_rod_size;
92 if ( rod && counter < max_count )
93 {
94 if ( block_end[0] != eformat::ROD )
95 throw EFORMAT_WRONG_MARKER( block_end[0], eformat::ROD );
96 rod_size[counter] = curr_rod_size;
97 rod[counter] = block_end;
98 }
99 ++counter;
100 }
101 return counter;
102}
103
104size_t eformat::get_robs( const uint32_t* fragment, const uint32_t** rob, size_t max_count ) {
105 using namespace eformat;
106 ERS_DEBUG_1( "Getting all ROB's from 0x%x...", fragment[0] );
107
108 size_t counter = 0;
109 switch ( ( eformat::HeaderMarker )( fragment[0] ) )
110 {
111 case ROD: return 0;
112 case ROB: {
113 if ( max_count > 0 )
114 {
115 rob[0] = fragment;
116 ++counter;
117 }
118 else return 0; // not enough space
119 }
120 break;
121 case ROS: {
123 counter += ros.children( rob, max_count );
124 ERS_DEBUG_1( "ROS 0x%x contains %d ROB's", ros.source_id(), counter );
125 }
126 break;
127 case SUB_DETECTOR: {
129 const uint32_t* ros[256];
130 size_t ros_counter = sd.children( ros, 256 );
131 for ( size_t i = 0; i < ros_counter; ++i )
132 counter += get_robs( ros[i], &rob[counter], max_count - counter );
133 ERS_DEBUG_1( "Subdetector 0x%x contains %d ROB's", sd.source_id(), counter );
134 }
135 break;
136 case FULL_EVENT: {
138 const uint32_t* sd[64];
139 size_t sd_counter = fe.children( sd, 64 );
140 for ( size_t i = 0; i < sd_counter; ++i )
141 counter += get_robs( sd[i], &rob[counter], max_count - counter );
142 ERS_DEBUG_1( "Fullevent 0x%x contains %d ROB's", fe.source_id(), counter );
143 }
144 break;
145 }
146
147 return counter;
148}
#define fs
TTree * data
#define EFORMAT_WRONG_MARKER(current, expected)
#define ERS_DEBUG_1(...)
#define ERS_DEBUG_3(...)
#define ERS_DEBUG_2(...)
virtual uint32_t children(TPointer *p, size_t max) const
uint32_t * next_fragment(std::fstream &fs, uint32_t *addr=0, size_t size=0)
Definition util.cxx:24
size_t get_robs(const uint32_t *fragment, const uint32_t **rob, size_t max_count)
Definition util.cxx:104
size_t find_rods(const uint32_t *block_start, size_t block_size, const uint32_t **rod=0, uint32_t *rod_size=0, size_t max_count=0)
Definition util.cxx:83