RawMicroSlice.cpp
Go to the documentation of this file.
1 #include "DAQDataFormats/RawMicroSlice.h"
2 #include "DAQDataFormats/DataFormatException.h"
3 
4 #include <boost/lexical_cast.hpp>
5 #include <assert.h>
6 namespace daqdataformats{
7 
8 //------------------------------------------------------------------------------
9 // Default constructor
10 RawMicroSlice::RawMicroSlice(const uint32_t size, const bool resize_buffer, const version_t version):
11  RawDAQData( 0
12  , (init_t) &RawMicroSlice::init
13  , (sizeofdata_t) &RawMicroSlice::getPredeterminedSize
14  , (setBufferSource_t)&RawMicroSlice::setBufferSource
15  , (print_t) &RawMicroSlice::printStandard
16  , (readData_t) &RawMicroSlice::readDataFromBuffer
17  )
18  , _Header (NULL)
19  , _TimingMarker (NULL)
20  , _FloatingNanoSlice (NULL)
21  , _HitProbability (0.0)
22  , _nanosliceVersion (rawdaqdataformat::DAQDATAFORMAT_UNKNOWN_VERSION)
23  , _microSliceHeaderVersion(version)
24 {
25 
26  /// Check if the size is legal
27  if (size < getPredeterminedSize()) {
28  std::string msg("An external input buffer was given to the ");
29  msg.append("RawMicroSlice constructor that was too small (size=");
30  msg.append(boost::lexical_cast<std::string>(size) + ", minimum size=");
31  msg.append(boost::lexical_cast<std::string>(getPredeterminedSize()) + ").");
33  }// end of checking if the size is legal
34 
35  /// Set the size of the Internal Buffer
36  if(resize_buffer){
38  }
39  else
41 
43 }
44 //------------------------------------------------------------------------------
46  RawDAQData(copy_in)
47  , _Header (NULL)
48  , _TimingMarker (NULL)
49  , _FloatingNanoSlice (NULL)
53 {
54  lastOperationsInDeepCopy(copy_in);
55 }
56 
57 //------------------------------------------------------------------------------
58 RawMicroSlice::RawMicroSlice(const void* microslice_buffer, const uint32_t size, const version_t microsliceheader_version):
59  RawDAQData( 0
65  )
66  , _Header (NULL)
67  , _TimingMarker (NULL)
68  , _FloatingNanoSlice (NULL)
69  , _HitProbability (0.0)
71  , _microSliceHeaderVersion(microsliceheader_version) ///< we'll figure it out in setBufferSource
72 {
73  /// Check if the size is legal
74  if (size < getPredeterminedSize()) {
75  std::string msg("An external input buffer was given to the ");
76  msg.append("RawMicroSlice constructor that was too small (size=");
77  msg.append(boost::lexical_cast<std::string>(size) + ", minimum size=");
78  msg.append(boost::lexical_cast<std::string>(getPredeterminedSize()) + ").");
80  }// end of checking if the size is legal
81 
82  /// In addition to standard shallow copy routine, set the maximum size
84 
85  RawDAQData::copy(microslice_buffer);
86 }
87 
88 
89 //------------------------------------------------------------------------------
90 // Destructor
93  if(_Header) delete _Header;
94  if(_TimingMarker) delete _TimingMarker;
95 }
96 
97 //------------------------------------------------------------------------------
99 {
101  std::string msg("Cannot set MicroSlice to version " + boost::lexical_cast<std::string>(version));
102  msg.append("\n It already has been set to " + boost::lexical_cast<std::string>(_microSliceHeaderVersion));
104  return false;
105  }
106 
108 
109  //if(_Buffer){
110  // setBufferSource(_Buffer);
111  //}
112 
113  if(_Header){
115  }
116 
117  return true;
118 }
119 
120 
121 //------------------------------------------------------------------------------
122 // Initialize a new MicroSlice (or reset it)
124 {
125 
126  /// This is needed for the formats with variable size
127  /// If buffer is internal, need to resize it
130  }
131 
132  // Initialize the header and timing marker
134  _Header->initSoft();
135  else
136  _Header->init();
137 
138  _TimingMarker->init();
139 }
140 
141 //------------------------------------------------------------------------------
142 // Method to Add a packed Nanoslice to the _Buffer
143 // If check_mc_flag = true, the method checks whether the nanoslice is MC generated
144 // and adds an appropriate flag to the MicroSlice Header.
145 void RawMicroSlice::addNanoSlice(const void* buffer, const bool check_mc_flag){
146 
147  /// Construct a temporary nanoslice with external buffer
148  const RawNanoSlice tmp_nanoslice(buffer);
149  /// This is its size
150  const uint32_t nanoslice_size = tmp_nanoslice.sizeofdata();
151 
152  /// Now add that much data to MicroSlice
153  addData(buffer, nanoslice_size, check_mc_flag);
154 }
155 
156 //------------------------------------------------------------------------------
157 // Method to Add data to the _Buffer
158 // If check_mc_flag = true, the method checks whether the nanoslice is MC generated
159 // and adds an appropriate flag to the MicroSlice Header.
160 void RawMicroSlice::addData(const void* buffer, const uint32_t nwords, const bool check_mc_flag){
161 
162  /// Add the data from buffer into the _Buffer
163  readDataGeneral(buffer, nwords);
164 
165  /// After Reading data, Buffer could have changed position
167 
168  /// Add byte count to the MicroSlice Header
169  _Header->addByteCount(nwords * sizeof(uint32_t));
170 
171  /// Check if the NanoSlice is the MC generated
172  /// If it is, set the appropriate MicroSlice MC flag
173  if(check_mc_flag){
175  const uint32_t FEBStatus = nano_header.getFEBStatus();
176  if(FEBStatus > 0x0000003F) setMonteCarloFlag(true);
177  }// end of checking mc flag
178 
179 }// end of addData
180 
181 
182 //------------------------------------------------------------------------------
183 // Method to generate a Microslice from scratch
184 void RawMicroSlice::generate(const version_t version_of_nanoslice){
185 
186  _nanosliceVersion = (version_t)version_of_nanoslice;
187 
188  /// Set the MC flag
189  setMonteCarloFlag(true);
190 
191  /// Generate the timing marker of the microslice
193 
194  // Loop over all the front end boards generating hits
195  // and writing them to the buffers
196  for(uint32_t boardID = 0; boardID < rawmicro::MAXIMUM_FRONTEND_BOARDS; ++boardID){
197 
198  /// Declare the front end boards simulators
199  FEBSimulator FrontEndBoard(boardID, _HitProbability, _nanosliceVersion);
200 
201  for(int pixelID = 0; pixelID < 32; ++pixelID){
202  /// Attempt to generate a nanoslice hit on a given pixel
203  FrontEndBoard.generateNanoSlice(pixelID);
204 
205  /// Check to see if it has nonzero data
206  if(FrontEndBoard.nonEmptyNanoSlice()){
207  // /Add the nanoslice from the FEB to the buffer
208  addNanoSlice(FrontEndBoard.getLastNanoSlice()->getBuffer());
209  } // endif NonEmptyNanoSlice
210  } // endfor pixelID
211  } // endfor boardID
212 }// end of RawMicroSlice::unpack()
213 
214 
215 //------------------------------------------------------------------------------
216 // Getters
218  return _Header;
219 } // Get MicroSlice Header pointer
220 daqdataformats::RawTimingMarker* RawMicroSlice::getTimingMarker() const { return _TimingMarker; } // Get Timing Marker pointer
223 {
224  return _Header->getDataPresent();
225 } // Get Method for Data present bit
227 {
228  return _Header->getMonteCarloFlag();
229 } // Get Method for SIM bit
231 {
232  return _Header->getByteCount();
233 } // Get Method for Byte Count
234 
235 uint32_t RawMicroSlice::getLowWord() const { return _TimingMarker->getLowWord();} // Get method for lower half of timing word
236 uint32_t RawMicroSlice::getHighWord() const { return _TimingMarker->getHighWord();} // Get method for upper half of timing word
237 uint64_t RawMicroSlice::getTime() const { return _TimingMarker->getTime();} // Get the time-stamp as a single 64-bit value */
239 
240 //------------------------------------------------------------------------------
242 
243  /// Could be zero nanoslices
244  if(!areThereNanoSlices())return 0;
245 
246  const uint32_t nanoslice_size = getNanoSliceSize();
247  if(nanoslice_size == 0){
248  std::string msg("From RawMicroSlice::getNumNanoSlices. NanoSLice size is zero.");
250  }// end of checking whether nanoslice size is zero
251 
252  return (sizeofdata() - rawmicro::PREDETERMINED_MICROSLICE_SIZE) / nanoslice_size;
253 }
254 
255 //------------------------------------------------------------------------------
256 // Sometimes we don't know the NanoSlice size yet,
257 // But we need to know if there are NanoSlices at all
259 
260 //------------------------------------------------------------------------------
261 //Setters
262 bool RawMicroSlice::setMonteCarloFlag (const bool mc_flag)
263 {
264  return _Header->setMonteCarloFlag(mc_flag);
265 }
266 bool RawMicroSlice::setLowWord (const uint32_t word) { return _TimingMarker->setLowWord (word);}
267 bool RawMicroSlice::setHighWord (const uint32_t word) { return _TimingMarker->setHighWord(word);}
268 bool RawMicroSlice::setTime (const uint64_t timestamp) { return _TimingMarker->setTime(timestamp);}
269 bool RawMicroSlice::setHitProbability (const float hit_prob) { _HitProbability = hit_prob; return true; }
270 
271 //------------------------------------------------------------------------------
273 
274  /// Could be zero nanoslices, then we don't know the nanoslice size
275  if(!areThereNanoSlices())return 0;
276 
277  /// If floating nanoslice is not set, set it to zeroth nanoslice
278  if(_FloatingNanoSlice == NULL && !setFloatingNanoSlice(0)) return 0;
279 
280  return _FloatingNanoSlice->sizeofdata();
281 }// end of getNanoSliceSize
282 
283 
284 //------------------------------------------------------------------------------
285 bool RawMicroSlice::setFloatingNanoSlice (const uint32_t inano) const {
286 
287  /// If there are no nanoslices, then can't the floating NanoSlice
288  if(!areThereNanoSlices())return false;
289 
290  /// Check whether NanoSlice is valid
291  /// If nanoslice is zero, then nothing to check
292  if(inano && inano >= getNumNanoSlices()){
293  //std::cout<<"Warning from RawMicroSlice::setFloatingNanoSlice : setting floating nanoslice to "<<inano
294  // <<"-th nanoslice, whereas only "<<this->getNumNanoSlices()<<"nanoslices are in the current MicroSlice."<<"\n";
295  return false;
296  }// end of checking whether NanoSlice is valid
297 
298  uint32_t* pointer = &RAWBUFF32[0] + rawmicro::PREDETERMINED_MICROSLICE_SIZE;
299 
300  /// counting nanoslices from zero
301  /// if inano is zero, then don't need to calculate NanoSlice size
302  if(inano) pointer += inano * getNanoSliceSize();
303 
304  /// See if we need to create a new Nanoslice or just set the pointer
305  if(_FloatingNanoSlice == NULL){
308  }
309  else{
310  _FloatingNanoSlice->setBufferSource(pointer);
311  }
312 
313  return true;
314 }
315 
316 //------------------------------------------------------------------------------
317 /// Setting Buffer, Header and Timing marker. Don't bother Floating NanoSlice
318 bool RawMicroSlice::setBufferSource(const void* pointer){
319 
320  _Buffer = (void*)pointer;
321 
323 
325  _microSliceHeaderVersion = daqdataformats::RawMicroSliceHeader::figureOutTheVersionStatic(pointer);
326  //assert(_microSliceHeaderVersion != rawdaqdataformat::DAQDATAFORMAT_UNKNOWN_VERSION);
327  if(_Header) {
329  }
330  }
331 
332  /// See if header and Timing marker are already constructed
333  if(_Header) {
334  _Header->setBufferSource(_Buffer);
335  const uint32_t* timing_marker_pointer = &RAWBUFF32[0] + _Header->sizeofdata();
336  return _TimingMarker->setBufferSource(timing_marker_pointer);
337  }
338 
339  uint32_t* timing_marker_pointer = &RAWBUFF32[0];
340 
342  timing_marker_pointer += _Header->sizeofdata();
343 
344  _TimingMarker = new RawTimingMarker(timing_marker_pointer);
345 
346  _function_sizeofdata = (sizeofdata_t) &RawMicroSlice::sizeofdata;
347 
348  return true;
349 }// end of setBufferSource1
350 
351 //------------------------------------------------------------------------------
352 // Print the MicroSlice structure
353 void RawMicroSlice::printStandard(std::ostream& os) const {
354 
355  const uint32_t size_of_data = sizeofdata();
356  os<<"----------MicroSlice----------------------------------------size="<<size_of_data<<std::endl;
357  printBuffer(os);
359  _Header->print(os);
360  }
361 
362  _TimingMarker->print(os);
363 
364 
365  const uint32_t num_nanoslices = getNumNanoSlices();
366 
367  os<<std::endl<<"----------NumNanoSlices-------="<<num_nanoslices<<std::endl;
368 
369  /// If number is nonzero, need to print them
370  if(num_nanoslices){
371  /// Get a copy of the MicroSlice this is so that we don't screw up the internal structure
372  const RawMicroSlice micro_copy(_Buffer, 3);
373 
374  for(uint32_t i = 0; i < num_nanoslices; ++i){
375  micro_copy.setFloatingNanoSlice(i);
376  micro_copy.getFloatingNanoSlice()->print(os);
377  }// end of loop over nanoslices
378  }// end of checking whether the number of nanoslices is non-zero
379 
380 
381 }// end of print1
382 
383 //------------------------------------------------------------------------------
384 // MicroSlice _Buffer size in words
386 {
387  return _Header->getMicroSliceSize();
388 }
389 
390 //------------------------------------------------------------------------------
391 // This is a general method to read the microslice from microslice_buffer to _Buffer
392 void* RawMicroSlice::readDataFromBuffer(const void* microslice_buffer)
393 {
394  /// Figure out version
396  setVersion(RawMicroSliceHeader::figureOutTheVersionStatic(microslice_buffer));
397  }
398 
399  /// First, read Header and Timing marker
400  void* microslice_buffer_new = readDataGeneral(microslice_buffer, rawmicro::PREDETERMINED_MICROSLICE_SIZE, 0);
401 
402  /// Now, read the rest of the the _Buffer
403  microslice_buffer_new = readDataGeneral(microslice_buffer_new
406  );
407  /// Check pointers after each read or resize buffer
409 
410  return microslice_buffer_new;
411 }
412 
413 //------------------------------------------------------------------------------
415 {
416 
417  /// Check if the file descriptor is invalid
418  if(fd < 0) return rds_error;
419 
420  char* current_buffer = (char*)_Buffer;
421 
422  /// Read the Header
423  ssize_t bytes_read = read(fd, current_buffer, (size_t)(RAWMICROSLICEHEADER_SIZE*sizeof(uint32_t)));
424  current_buffer += bytes_read;
425 
426  /// Figure out version
428  setVersion(RawMicroSliceHeader::figureOutTheVersionStatic(_Buffer));
429  }
430 
431  /// Check if the reading was OK
432  if (bytes_read == -1 || bytes_read == 0) return rds_error;
433 
434  /// Check if the reading was complete
435  if ((uint32_t)bytes_read != RAWMICROSLICEHEADER_SIZE*sizeof(uint32_t)) return rds_incomplete;
436 
437  /// After reading the header, now we know the whole MicroSlice size
438  /// In words
439  const uint32_t microslice_size = sizeofdata();
440  const uint32_t rest_of_microslice_size = microslice_size - RAWMICROSLICEHEADER_SIZE;
441 
442  /// Check whether we need to adjust the Internal Buffer size
444  resizeInternalBuffer(microslice_size);
445  }
446 
447  /// Read the rest of the MicroSlice
448  bytes_read = read(fd, current_buffer, (size_t)rest_of_microslice_size*sizeof(uint32_t));
449 
450  /// Check if the reading was OK
451  if (bytes_read == -1 || bytes_read == 0) return rds_error;
452 
453  /// Check if the reading was complete
454  if ((uint32_t)bytes_read != rest_of_microslice_size*sizeof(uint32_t)) return rds_incomplete;
455 
456  return rds_complete;
457 }
458 
459 }// end of namespace
uint32_t getLowWord() const
Get the byte count value of the header.
uint32_t getHighWord() const
! Get method for lower half of timing word
void * readDataGeneral(const void *buffer)
General ReadData method when the sizeofdata is known.
Definition: RawDAQData.cpp:186
#define GENERATE_DATAFORMAT_EXCEPTION(msg)
RawMicroSlice(const uint32_t buffersize=rawmicro::DEFAULT_MICROSLICE_SIZE, const bool resize_buffer=false, const version_t microsliceheader_version=rawdaqdataformat::DAQDATAFORMAT_UNKNOWN_VERSION)
If resize_buffer=true, then we resize the whole internal Buffer with zeros on the construction...
IMPLEMENT_MAIN_STANDARD IMPLEMENT_MAIN_setBufferSource daqdataformats::RawNanoSliceHeader * getHeader() const
Get the NanoSlice header pointer.
Definition: RawNanoSlice.h:57
#define sizeofdata_t
Definition: FunctionBind.h:30
bool setVersion(const version_t)
void generate(const version_t version_nanoslice=nanosliceheader::RAWNANOSLICE_DEFAULT_VERSION)
bool setBufferSource(const void *pointer)
Setting Buffer, Header and Timing marker. Don&#39;t bother Floating NanoSlice.
readDataStatus readData(const int file_descriptor)
Read Data From File Descriptor.
static const uint32_t PREDETERMINED_MICROSLICE_SIZE
Definition: RawMicroSlice.h:40
bool setLowWord(const uint32_t)
We are allowed to change the floating nanoslice, thus it&#39;s const.
bool setBufferSource(const void *)
We are not going to overload these funtions, so no need to declare them virtual.
Definition: RawDAQData.cpp:880
bool setLowWord(const uint32_t)
! Get the time-stamp as a single 64-bit value
void * _Buffer
All data formats need to have _Buffer and a Data structure. _Buffer will be common.
Definition: RawDAQData.h:276
version_t getVersion() const
Definition: RawMicroSlice.h:67
float getHitProbability() const
Get the time-stamp as a single 64-bit value.
uint32_t getNumNanoSlices() const
Get current Hit Probability (for a microslice generation)
static const uint32_t MAXIMUM_FRONTEND_BOARDS
Definition: RawMicroSlice.h:39
void addData(const void *buffer, const uint32_t nwords, const bool check_mc_flag=true)
virtual void copy(const RawDAQData &)
Deep copy from the DAQDataFormat.
Definition: RawDAQData.cpp:830
bool checkBufferInternalness()
If the buffer should be internal, check it&#39;s pointers and reassign them.
Definition: RawDAQData.cpp:612
bool _shouldBufferBeInternal
Auxillary variable that holds whether the buffer should be external or internal.
Definition: RawDAQData.h:286
::xsd::cxx::tree::buffer< char > buffer
Definition: Database.h:179
uint64_t getTime() const
Get method for upper half of timing word.
void lastOperationsInDeepCopy(const RawDAQData &copy_in)
Need to perform these operations in Deep Copy constructor.
Definition: RawDAQData.cpp:151
bool setHighWord(const uint32_t)
! Set method for lower half of timing word
bool setHighWord(const uint32_t)
Set method for lower half of timing word.
daqdataformats::RawMicroSliceHeader * _Header
MicroSlice Header.
void print(std::ostream &os=std::cout) const
Method for printing the content of the Buffer.
Definition: RawDAQData.cpp:500
uint32_t getPredeterminedSize() const
daqdataformats::RawTimingMarker * getTimingMarker() const
Get the MicroSlice Header.
void generateNanoSlice()
Generator methods produce a NanoSlice.
uint64_t getTime() const
! Get method for upper half of timing word
daqdataformats::RawTimingMarker * _TimingMarker
MicroSlice Timing Marker.
bool setFloatingNanoSlice(const uint32_t inano) const
Set the SIM flag.
float _HitProbability
Pixel Hit probability. Used when generating a MicroSlice.
bool setHitProbability(const float hit_prob)
daqdataformats::RawMicroSliceHeader * getHeader() const
void * readDataFromBuffer(const void *)
bool isInternalBuffer() const
Definition: RawDAQData.h:141
#define print_t
Definition: FunctionBind.h:31
void printBuffer(std::ostream &os=std::cout, const bool print_offset=true,const bool print_ascii=true,const bool print_buffer_address=false,const bool print_internal_buffer=false,const bool print_size_of_data=false,const std::string separation_between_lines="\n",const uint32_t cols=4) const
Definition: RawDAQData.cpp:330
bool setVersionSoft(const version_t)
Don&#39;t change the field.
void printStandard(std::ostream &os=std::cout) const
daqdataformats::RawNanoSlice * _FloatingNanoSlice
const XML_Char * version
Definition: expat.h:187
bool setTime(const uint64_t)
Set method for upper half of timing word.
uint32_t getByteCount() const
Get the Data Present bit of the Header.
Class to hold the MicroSlice data.
Definition: RawMicroSlice.h:48
#define setBufferSource_t
Definition: FunctionBind.h:33
Class to hold the timing markers used in the construction of Microslices in the DCMs.
#define RAWBUFF32
Definition: RawDAQData.h:16
#define readData_t
Definition: FunctionBind.h:32
int32_t version_t
Definition: RawDAQData.h:72
bool getMonteCarloFlag() const
Get the Data Present bit of the Header.
void addNanoSlice(const void *nanoslice_buffer, const bool check_mc_flag=true)
bool reserveInternalBuffer(const uint32_t size_of_data)
Reserve space for the internal buffer to some predetermined size.
Definition: RawDAQData.cpp:271
RawNanoSlice * getLastNanoSlice()
static const version_t DAQDATAFORMAT_UNKNOWN_VERSION
Definition: RawDAQData.h:81
Class to hold the data from the FEBs in correct formats.
uint32_t getNanoSliceSize() const
Getting a nanoslice size. It could be different for different versions.
uint32_t getHighWord() const
Get method for lower half of timing word.
void generate()
! Set the time-stamp as a single 64-bit value
#define init_t
Definition: FunctionBind.h:29
bool setMonteCarloFlag(const bool)
Get number of NanoSlices in the MicroSlice.
bool setTime(const uint64_t)
! Set method for upper half of timing word
bool getDataPresent() const
Get Floating NanoSlice.
static const uint32_t RAWMICROSLICEHEADER_SIZE
daqdataformats::RawNanoSlice * getFloatingNanoSlice() const
Get the MicroSlice Timing Marker.
bool resizeInternalBuffer(const uint32_t size_of_data)
Resize the internal buffer.
Definition: RawDAQData.cpp:292
enum BeamMode string