CMS 3D CMS Logo

FileReaderDCC.cc
Go to the documentation of this file.
1 #include "FileReaderDCC.h"
2 #include <cerrno> // errno
3 #include <cstdlib> // exit
4 #include <cstring> // bzero, memcpy
5 #include <fcntl.h> // open
6 #include <iostream> // cerr
7 #include <sys/stat.h> // open
8 #include <sys/types.h> // open
9 #include <unistd.h> // read, close
10 
11 #ifndef O_LARGEFILE //for OSX
12 #define O_LARGEFILE 0
13 #endif
14 
16  if (sizeof(unsigned long long) != 8 || sizeof(unsigned short) != 2)
17  throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2"));
18  raw_event = new unsigned short[200000 * 40];
19  end = (file_buffer_end = file_buffer + sizeof(file_buffer) / sizeof(unsigned long long));
20  bzero(raw_event, sizeof(unsigned short) * 200000 * 40);
21  bzero(file_buffer, sizeof(file_buffer));
22  word_0 = 0;
23  word_1 = 0;
24  word_2 = 0;
25  eventStatus = 0;
28  acceptCriteria = 0x3F; // Everything
29  fd = 0;
30 }
31 
33  if (fd)
34  close(fd);
35 }
36 
37 int FileReaderDCC::open(const char *filename) {
38  if (fd)
39  close(fd);
40  fd = ::open(filename, O_RDONLY | O_LARGEFILE);
41  if (fd == -1)
42  throw(std::runtime_error(std::string("Error opening ").append(filename).append(" data file.")));
43  return fd;
44 }
45 
46 size_t FileReaderDCC::read(const unsigned short *&buf) {
47  // Check for ubnormal situation
49  throw(std::runtime_error("Error of reading"));
50  if (!fd)
51  throw(std::runtime_error("Open some file first"));
52 
53  unsigned long long *start = end;
54  unsigned short *event = raw_event;
55 
56  eventStatus = 0;
57  size_t dccWordCount = 0;
58  end = nullptr;
59 
60  while (!end && dccWordCount < 50000 * 40) {
61  unsigned long long *dccWord = start;
62  unsigned long long preHeader = 0;
63 
64  // Did we reach end of current buffer and want to read next block?
65  // If it was first time and we don't have file buffer then we won't get inside
66  while (dccWord < file_buffer_end && dccWordCount < 50000) {
67  word_0 = word_1; // delay by 2 DCC words
68  word_1 = word_2; // delay by 1 DCC word
69  word_2 = *dccWord; // current DCC word
70  if ((word_1 & 0xF0000000000000FFLL) == 0x500000000000005FLL && // let's call this a preHeader
71  (word_2 & 0xFF000000000000FFLL) == 0xD900000000000017LL) // and this is a header
72  {
73  if (eventStatus & Header) // Second header
74  {
75  word_2 = word_1; // Fall back to get rigth preHeader next time
76  end = dccWord; // Even if we end with preHeader of next evet put it to the end of this event too
77  break;
78  }
79  if (dccWordCount > 1) // Extra words between trailer and header
80  {
81  if ((word_0 & 0xFFFFFFFFFFFF0000LL) == 0xFFFFFFFFFFFF0000LL)
82  eventStatus |= FFFF;
83  word_2 = word_1; // Fall back to get rigth preHeader next time
84  end = dccWord;
85  break;
86  }
88  if (event == raw_event)
89  preHeader = word_1; // If preHeader not yet in event then put it there
90  start = dccWord;
91  }
92  if ((word_1 & 0xFF00000000000000LL) == 0xEF00000000000000LL &&
93  (word_2 & 0xFF0000000000000FLL) == 0xAF00000000000007LL) {
95  end = ++dccWord;
96  break;
97  }
98  // Increase counters by one DCC word
99  dccWord++;
100  dccWordCount++;
101  }
102 
103  // If have DCC Header
104  if (preHeader) {
105  // Need to account first word of DCC Header
106  memcpy(event, &preHeader, sizeof(preHeader));
107  event += sizeof(preHeader) / sizeof(unsigned short);
108  }
109 
110  // Take care of the rest
111  memcpy(event, start, (dccWord - start) * sizeof(unsigned long long));
112  event += (dccWord - start) * sizeof(unsigned long long) / sizeof(unsigned short);
113 
114  // If reach max length
115  if (dccWordCount == 50000 * 40) {
116  end = dccWord;
117  break;
118  }
119 
120  if (!end) {
121  // Need to read next block for the rest of this event
122  ssize_t length = ::read(fd, file_buffer, sizeof(file_buffer));
123  if (length == -1)
124  throw(std::runtime_error("Error of reading"));
125  if (length == 0) {
127  end = (file_buffer_end = file_buffer + sizeof(file_buffer) / sizeof(unsigned long long));
128  break;
129  }
130  file_buffer_end = file_buffer + length / sizeof(unsigned long long);
131 
132  // Will start from the beginning of new buffer next time we read it
133  start = file_buffer;
134  }
135  }
136 
137  if (!end)
139  if (!(eventStatus & Header) && !(eventStatus & Trailer) && !(eventStatus & FFFF))
140  eventStatus |= Unknown;
141 
142  buf = (const unsigned short *)raw_event;
143  return (eventStatus & FFFF ? event - raw_event - 4 : event - raw_event);
144 }
145 
146 size_t FileReaderDCC::next(const unsigned short *&buf) {
147  size_t size = 0;
148  do {
149  if ((size = read(buf)) == 0)
150  break;
153  return size;
154 }
size
Write out results.
size_t read(const unsigned short *&buf)
Definition: start.py:1
int open(const char *filename)
virtual ~FileReaderDCC(void)
unsigned long long word_0
Definition: FileReaderDCC.h:11
unsigned int acceptCriteria
Definition: FileReaderDCC.h:28
unsigned int rejectCriteria
Definition: FileReaderDCC.h:28
#define O_LARGEFILE
unsigned long long * file_buffer_end
Definition: FileReaderDCC.h:14
unsigned long long word_1
Definition: FileReaderDCC.h:11
unsigned long long file_buffer[4000]
Definition: FileReaderDCC.h:12
size_t next(const unsigned short *&buf)
unsigned long long word_2
Definition: FileReaderDCC.h:11
unsigned long long * end
Definition: FileReaderDCC.h:14
unsigned int eventStatus
Definition: FileReaderDCC.h:28
unsigned int selectCriteria
Definition: FileReaderDCC.h:28
unsigned short * raw_event
Definition: FileReaderDCC.h:9
Definition: event.py:1