Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JCLB.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 #include <limits>
5 #include <vector>
6 #include <map>
7 #include <algorithm>
8 
10 
14 
15 #include "JDAQ/JDAQTimesliceIO.hh"
16 
18 #include "JSupport/JSupport.hh"
19 #include "JSupport/JMeta.hh"
20 
21 #include "Jeep/JParser.hh"
22 #include "Jeep/JMessage.hh"
23 
24 
25 namespace {
26 
27  const uint32_t TDC = 1414808643; //!< TDC data type
28 
30 
31  typedef std::vector<char> buffer_type; //!< UDP packet
32  typedef std::vector<buffer_type> collection_type; //!< collection of UDP packets
33  typedef std::map<int, collection_type> timeslice_type; //!< module identifier -> collection of UDP packets
34 
35 
36  /**
37  * Auxiliary data structure to organise CLB data.
38  */
39  struct map_type :
40  public std::map<uint64_t, timeslice_type> // UTC time -> time slice data
41  {
42  /**
43  * Constructor.
44  *
45  * \param detector detector identifier
46  */
47  map_type(int detector) :
48  detector(detector),
49  frame_index(0)
50  {}
51 
52 
53  /**
54  * Convert first element in container and remove it.
55  *
56  * \return time slice
57  */
58  const JDAQTimeslice& pop()
59  {
60  using namespace std;
61  using namespace KM3NETDAQ;
62 
63  frame_index += 1;
64 
65  timeslice.clear();
66 
67  for (timeslice_type::iterator collection = this->begin()->second.begin(); collection != this->begin()->second.end(); ++collection) {
68 
69  sort(collection->second.begin(), collection->second.end(), compare);
70 
71  const CLBCommonHeader* header = (const CLBCommonHeader*) collection->second.rbegin()->data();
72 
73  const JDAQChronometer chronometer(detector,
74  header->runNumber(),
75  frame_index,
76  JDAQUTCExtended(header->timeStamp().sec(), header->timeStamp().tics()));
77 
78  if (timeslice.empty()) {
79  timeslice = JDAQTimeslice(chronometer);
80  }
81 
82  const uint32_t number_of_packets = collection->second.size();
83  const uint32_t sequence_number = header->udpSequenceNumber();
84 
85  const JDAQFrameStatus status(DAQ_UDP_RECEIVED_PACKETS.write(number_of_packets) | //
86  DAQ_UDP_SEQUENCE_NUMBER .write(sequence_number), // DAQ status
87  DAQ_WHITE_RABBIT.write(1), // TDC status
88  DAQ_UDP_TRAILER .write(sequence_number + 1 == number_of_packets)); // FIFO status
89 
90  JDAQSuperFrame frame(JDAQSuperFrameHeader(chronometer, collection->first, status));
91 
92  for (collection_type::const_iterator i = collection->second.begin(); i != collection->second.end(); ++i) {
93 
94  const size_t size = (i->size() - sizeof(CLBCommonHeader)) / sizeof(JDAQHit);
95  const JDAQHit* data = (const JDAQHit*) (i->data() + sizeof(CLBCommonHeader));
96 
97  frame.add(size, data);
98  }
99 
100  timeslice.push_back(frame);
101  }
102 
103  this->erase(this->begin());
104 
105  return timeslice;
106  }
107 
108 
109  /**
110  * Compare two frames by UDP sequence number.
111  *
112  * \param first first UDP packet
113  * \param second second UDP packet
114  * \return true if first packet before second; else false
115  */
116  static inline bool compare(const buffer_type& first,const buffer_type& second)
117  {
118  return (((const CLBCommonHeader*) first .data())->udpSequenceNumber() <
119  ((const CLBCommonHeader*) second.data())->udpSequenceNumber());
120  }
121 
122  private:
123  int detector;
124  int frame_index;
125  JDAQTimeslice timeslice;
126  };
127 }
128 
129 
130 /**
131  * \file
132  *
133  * Auxiliary program to convert CLB data to KM3NETDAQ::JDAQTimeslice data.
134  * \author mdejong
135  */
136 int main(int argc, char **argv)
137 {
138  using namespace std;
139  using namespace JPP;
140  using namespace KM3NETDAQ;
141 
142 
143  string inputFile;
144  int numberOfEvents;
146  int detector;
147  size_t queue;
148  int debug;
149 
150  try {
151 
152  JParser<> zap("Auxiliary program to convert CLB data to KM3NETDAQ::JDAQTimeslice data.");
153 
154  zap['f'] = make_field(inputFile, "input file).");
155  zap['o'] = make_field(outputFile, "output file.") = "clb.root";
156  zap['n'] = make_field(numberOfEvents) = numeric_limits<int>::max();
157  zap['Q'] = make_field(queue, "queue depth") = 1000;
158  zap['D'] = make_field(detector, "detector identifier") = 1;
159  zap['d'] = make_field(debug, "debug.") = 1;
160 
161  zap(argc, argv);
162  }
163  catch(const exception& error) {
164  FATAL(error.what() << endl);
165  }
166 
167 
168  outputFile.open();
169 
170  if (!outputFile.is_open()) {
171  FATAL("Error opening file " << outputFile << endl);
172  }
173 
174  outputFile.put(JMeta(argc, argv));
175 
176  map_type data(detector);
177 
178  uint32_t run = numeric_limits<uint32_t>::max();
179  uint32_t size;
180 
181  ifstream in(inputFile.c_str(), ios::binary);
182 
183  for (int count = 0; count != numberOfEvents && in.read((char*) &size, sizeof(uint32_t)); ++count) {
184 
185  STATUS(setw(8) << count << '\r'); DEBUG(endl);
186 
187  buffer_type buffer(size);
188 
189  if (in.read(buffer.data(), size)) {
190 
191  if (size >= sizeof(CLBCommonHeader)) {
192 
193  const CLBCommonHeader* header = (const CLBCommonHeader*) buffer.data();
194 
195  if (run == numeric_limits<uint32_t>::max()) {
196  run = header->runNumber();
197  }
198 
199  DEBUG("data: "
200  << setw(8) << header->runNumber() << ' '
201  << setw(9) << header->domIdentifier() << ' '
202  << setw(2) << header->udpSequenceNumber() << endl);
203 
204  if (header->dataType() == TDC) {
205 
206  if (header->runNumber() == run) {
207 
208  data[header->timeStamp().inMilliSeconds()][header->domIdentifier()].push_back(buffer);
209 
210  while (data.size() > queue) {
211  outputFile.put(data.pop());
212  }
213 
214  } else {
215 
216  WARNING("Run numbers differ " << run << ' ' << header->runNumber() << " -> skip data." << endl);
217  }
218  }
219  }
220  }
221  }
222  STATUS(endl);
223 
224  in.close();
225 
226  while (!data.empty()) {
227  outputFile.put(data.pop());
228  }
229 
230  outputFile.close();
231 }
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:71
Object writing to file.
static const JBits DAQ_UDP_RECEIVED_PACKETS(0, 15)
Mask of UDP received packets.
Utility class to parse command line options.
Definition: JParser.hh:1493
void clear()
Clear data.
#define WARNING(A)
Definition: JMessage.hh:65
ROOT TTree parameter settings.
int write(const int value) const
Write given value as bit mask.
Definition: JDAQ.hh:115
uint32_t domIdentifier() const
#define STATUS(A)
Definition: JMessage.hh:63
Recording of objects on file according a format that follows from the file name extension.
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
Definition: JSirene.sh:45
int write(const int value) const
Write given value as bit mask.
Definition: JDAQ.hh:238
uint32_t runNumber() const
UTCTime timeStamp() const
string outputFile
Data structure for UTC time.
then echo The file $DIR KM3NeT_00000001_00000000 root already please rename or remove it first
Detector file.
Definition: JHead.hh:130
Hit data structure.
Definition: JDAQHit.hh:34
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1954
ROOT I/O of application specific meta data.
Data time slice.
uint32_t udpSequenceNumber() const
int debug
debug level
Definition: JSirene.cc:61
static const JBit DAQ_UDP_TRAILER(31)
UDP trailer.
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
uint32_t dataType() const
std::vector< int > count
Definition: JAlgorithm.hh:184
Utility class to parse command line options.
static const JBit DAQ_WHITE_RABBIT(31)
White Rabbit status.
function queue()
Definition: qlib.sh:50
static const JBits DAQ_UDP_SEQUENCE_NUMBER(16, 31)
Mask of UDP sequence number.
Data frame of one optical module.
uint64_t inMilliSeconds() const
Definition: utctime.hh:27
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
int main(int argc, char *argv[])
Definition: Main.cpp:15