Jpp 19.3.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
JDetectorIntegration_t.hh
Go to the documentation of this file.
1#ifndef __JDB__JDETECTORINTEGRATION_T__
2#define __JDB__JDETECTORINTEGRATION_T__
3
4#include <istream>
5#include <ostream>
6#include <sstream>
7#include <fstream>
8#include <vector>
9#include <map>
10#include <algorithm>
11
12#include "JTools/JRange.hh"
13#include "JDB/JDB.hh"
15#include "JDB/JPBS_t.hh"
16#include "JDB/JUPI_t.hh"
17#include "JDB/JDate_t.hh"
18#include "JLang/JException.hh"
20#include "JLang/JLangToolkit.hh"
21#include "JLang/JPredicate.hh"
22
23#include "dbclient/KM3NeTDBClient.h"
24
25
26/**
27 * \author mdejong
28 */
29namespace JDATABASE {}
30namespace JPP { using namespace JDATABASE; }
31
32namespace JDATABASE {
33
36
37
38 /**
39 * Type definition of period.
40 */
42
43
44 /**
45 * Write period to output stream.
46 *
47 * \param out output stream
48 * \param object period
49 * \return output stream
50 */
51 inline std::ostream& operator<<(std::ostream& out, const JPeriod_t& object)
52 {
53 return out << "(" << object.getLowerLimit() << "," << object.getUpperLimit() << ")";
54 }
55
56
57 /**
58 * Auxiliary class for product integration data.
59 *
60 * This class is primarily used to
61 * - convert the string data from JDATABASE::JProductIntegration to corresponding data structures;
62 * - implement efficient (in)equality operations;
63 */
65 /**
66 * Default constructor.
67 */
69 status(false)
70 {}
71
72
73 /**
74 * Constructor.
75 *
76 * \param input product integration data
77 */
79 status(false)
80 {
81 using namespace std;
82
83 this->operation = input.OPERATIONID;
84 this->position = input.POSITION;
85 this->container = input.CONTAINER_UPI;
86 this->content = input.CONTENT_UPI;
87
88 istringstream(input.STARTD) >> this->start_date;
89 istringstream(input.ENDD) >> this->end_date;
90 }
91
92
93 /**
94 * Check product status.
95 *
96 * \return true if set; else false
97 */
98 bool is_set() const
99 {
100 return status;
101 }
102
103
104 /**
105 * Set product status.
106 */
107 void set()
108 {
109 status = true;
110 }
111
112
113 /**
114 * Unset product status.
115 */
116 void unset()
117 {
118 status = false;
119 }
120
121
122 /**
123 * Read product integration from input stream.
124 *
125 * \param in input stream
126 * \param object product integration
127 * \return input stream
128 */
129 friend inline std::istream& operator>>(std::istream& in, JProductIntegration_t& object)
130 {
131 using namespace std;
132
133 in >> object.operation
134 >> object.container
135 >> object.content
136 >> object.position
137 >> object.start_date
138 >> object.end_date;
139
140 return in;
141 }
142
143
144 /**
145 * Write product integration to output stream.
146 *
147 * \param out output stream
148 * \param object product integration
149 * \return output stream
150 */
151 friend inline std::ostream& operator<<(std::ostream& out, const JProductIntegration_t& object)
152 {
153 using namespace std;
154
155 out << object.operation << ' '
156 << object.container << ' '
157 << object.content << ' '
158 << object.position << ' '
159 << object.start_date << ' '
160 << object.end_date;
161
162 return out;
163 }
164
165
166 std::string operation;
172 bool status;
173 };
174
175
176 /**
177 * Detector integration.
178 *
179 * This class is used
180 * - to read product integration data from the data base;
181 * - to organise detector specific integration data in memory;
182 * - to efficiently %trace a product;
183 * - to efficiently %find product(s);
184 *
185 * Note that the method JDetectorIntegration_t::configure should be used to set up the integration data for a specific detector.
186 */
188 public std::vector<JProductIntegration_t>
189 {
190 static const char* const getName() { return JProductIntegration::getName(); } //!< Table name
191
193 typedef std::pair<map_type::const_iterator,
194 map_type::const_iterator> range_type;
195 typedef map_type::const_iterator range_const_iterator;
196 typedef map_type::const_iterator range_iterator;
197
198
199 /**
200 * Default constructor.
201 */
204
205
206 /**
207 * Configure detector integration for given detector identifier.
208 *
209 * The components of the given detector are selected based on the following rules:
210 * -# the component should have a start date before that of the given detector;
211 * -# if multiple components appear at the same place in the same container,
212 * the one with the latest start date is taken.
213 *
214 * The option can be used to retain only those products that are part of the given detector.
215 *
216 * \param detid detector identifier
217 * \param option option
218 */
219 void configure(const std::string& detid, const bool option = false)
220 {
221 using namespace std;
222 using namespace JPP;
223
224 up .clear();
225 down.clear();
226 out .clear();
227
228 for (size_t index = 0; index != this->size(); ++index) {
229
230 JProductIntegration_t& product = (*this)[index];
231
232 product.unset();
233
234 if (product.content != JUPI_t()) {
235
236 up .insert(make_pair(product.content .getUPI(), index));
237 down.insert(make_pair(product.container.getUPI(), index));
238
239 } else {
240
241 out .insert(make_pair(product.container.getUPI(), index));
242 }
243 }
244
245 for (iterator product = this->begin(); product != this->end(); ++product) {
246 if (product->operation == detid) {
247 configure(*product, JPeriod_t(product->start_date, product->end_date));
248 }
249 }
250
251 if (option) {
252 this->erase(partition(this->begin(), this->end(), make_predicate(&JProductIntegration_t::is_set, true)), this->end());
253 }
254
255 up .clear();
256 down.clear();
257
258 for (size_t index = 0; index != this->size(); ++index) {
259
260 const JProductIntegration_t& product = (*this)[index];
261
262 if (product.is_set()) {
263 up .insert(make_pair(product.content .getUPI(), index));
264 down.insert(make_pair(product.container.getUPI(), index));
265 }
266 }
267 }
268
269
270 /**
271 * Trace product up to given integration level.
272 *
273 * \param upi %UPI
274 * \param pbs %PBS
275 * \return product
276 */
278 const JPBS_t& pbs = PBS::DETECTOR) const
279 {
280 using namespace std;
281
282 if (upi.getPBS() >= pbs) {
283
284 const range_type range = find(upi);
285
286 switch (distance(range.first, range.second)) {
287
288 case 1:
289 {
290 const JProductIntegration_t& product = (*this)[range.first->second];
291
292 if (product.container.getPBS() == pbs)
293 return product;
294 else
295 return trace(product.container.getUPI(), pbs);
296 }
297
298 case 0:
299 THROW(JDatabaseException, "Invalid UPI " << upi);
300
301 default:
302 THROW(JDatabaseException, "Ambiguous integration of UPI " << upi);
303 }
304
305 } else {
306
307 THROW(JDatabaseException, "Invalid PBS " << upi.getPBS() << " < " << pbs);
308 }
309 }
310
311
312 /**
313 * Print product trace.
314 *
315 * \param out output stream
316 * \param upi %UPI
317 */
318 void print(std::ostream& out, const JUPI_t& upi) const
319 {
320 using namespace std;
321
322 range_type range;
323
324 range = find(upi);
325
326 for (map_type::const_iterator i = range.first; i != range.second; ++i) {
327
328 out << upi << " -> ";
329
330 print(out, (*this)[i->second]);
331 }
332
333 range = down.equal_range(upi);
334
335 for (range_iterator i = range.first; i != range.second; ++i) {
336 out << "<- " << (*this)[i->second] << endl;
337 }
338 }
339
340
341 /**
342 * Print product trace.
343 *
344 * \param out output stream
345 * \param product product
346 */
347 void print(std::ostream& out, const JProductIntegration_t& product) const
348 {
349 using namespace std;
350
351 out << product.container.getUPI() << ' '
352 //<< JPeriod_t(product.start_date, product.end_date) << ' '
353 << "-> ";
354
355 const range_type range = find(product.container.getUPI());
356
357 for (map_type::const_iterator i = range.first; i != range.second; ++i) {
358 print(out, (*this)[i->second]);
359 }
360
361 if (distance(range.first, range.second) != 1) {
362 out << product.operation << std::endl;
363 }
364 }
365
366
367 /**
368 * Read detector integration from result set.
369 *
370 * \param rs result set
371 * \param detector detector
372 * \return true if read; else false
373 */
374 friend inline bool operator>>(ResultSet& rs, JDetectorIntegration_t& detector)
375 {
376 using namespace std;
377
378 for (JProductIntegration parameters; rs >> parameters; ) {
379
380 const JProductIntegration_t product(parameters);
381
382 detector.up .insert(make_pair(product.content .getUPI(), detector.size()));
383 detector.down.insert(make_pair(product.container.getUPI(), detector.size()));
384
385 detector.push_back(product);
386 }
387
388 rs.Close();
389
390 return true;
391 }
392
393
394 /**
395 * Load detector integration from CSV formatted input file.
396 *
397 * The input should be conform output of <tt>JPrintDB -q "integration" -c ";" -W1</tt>.
398 *
399 * \param file_name file name
400 * \param separator separator
401 */
402 void load(const char* const file_name, const std::string& separator = ";")
403 {
404 using namespace std;
405 using namespace JPP;
406
407 ifstream in(file_name);
408
409 in.ignore(numeric_limits<streamsize>::max(), '\n');
410
411 for (string buffer; getline(in, buffer); ) {
412
413 istringstream is(buffer);
414
415 const locale loc(is.getloc(), new JWhiteSpacesFacet(is.getloc(), separator));
416
417 is.imbue(loc);
418
419 JProductIntegration parameters;
420
421 is >> buffer; istringstream(trim(buffer)) >> parameters.OPERATIONID;
422 is >> buffer; istringstream(trim(buffer)) >> parameters.CITY;
423 is >> buffer; istringstream(trim(buffer)) >> parameters.LOCATIONID;
424 is >> buffer; istringstream(trim(buffer)) >> parameters.LOGIN;
425 is >> buffer; istringstream(trim(buffer)) >> parameters.USERID;
426 is >> buffer; istringstream(trim(buffer)) >> parameters.STARTD;
427 is >> buffer; istringstream(trim(buffer)) >> parameters.ENDD;
428 is >> buffer; istringstream(trim(buffer)) >> parameters.CONTAINER_UPI;
429 is >> buffer; istringstream(trim(buffer)) >> parameters.POSITION;
430 is >> buffer; istringstream(trim(buffer)) >> parameters.CONTENT_UPI;
431
432 const JProductIntegration_t product(parameters);
433
434 this->up .insert(make_pair(product.content .getUPI(), this->size()));
435 this->down.insert(make_pair(product.container.getUPI(), this->size()));
436
437 this->push_back(product);
438 }
439
440 in.close();
441 }
442
443
444 /**
445 * Read detector integration from input stream.
446 *
447 * \param in input stream
448 * \param object detector integration
449 * \return input stream
450 */
451 friend inline std::istream& operator>>(std::istream& in, JDetectorIntegration_t& object)
452 {
453 using namespace std;
454
455 for (JProductIntegration_t product; in >> product; ) {
456
457 object.up .insert(make_pair(product.content .getUPI(), object.size()));
458 object.down.insert(make_pair(product.container.getUPI(), object.size()));
459
460 object.push_back(product);
461 }
462
463 return in;
464 }
465
466
467 /**
468 * Write detector integration to output stream.
469 *
470 * \param out output stream
471 * \param object detector integration
472 * \return output stream
473 */
474 friend inline std::ostream& operator<<(std::ostream& out, const JDetectorIntegration_t& object)
475 {
476 for (const_iterator i = object.begin(); i != object.end(); ++i) {
477 out << *i << std::endl;
478 }
479
480 return out;
481 }
482
483
484 /**
485 * Find range of products with given %UPI.\n
486 * The returned range corresponds to the usual begin and end iterators,
487 * each pointing to an STL pair consisting of a %UPI and index.
488 *
489 * \param upi %UPI
490 * \return index
491 */
492 range_type find(const JUPI_t& upi) const
493 {
494 return up.equal_range(upi);
495 }
496
497
498 /**
499 * Find range of products with given %PBS.\n
500 * The returned range corresponds to the usual begin and end iterators,
501 * each pointing to an STL pair consisting of a %UPI and index.
502 *
503 * \param pbs %PBS
504 * \return range
505 */
506 range_type find(const JPBS_t& pbs) const
507 {
508 range_const_iterator p = up.lower_bound(JUPI_t(pbs));
510
511 while (q != up.end() && (*this)[q->second].content.getPBS() <= pbs) {
512 ++q;
513 }
514
515 return range_type(p,q);
516 }
517
518
519 /**
520 * Get components of product with given %UPI.\n
521 * The returned range corresponds to the usual begin and end iterators,
522 * each pointing to an STL pair consisting of a %UPI and index.
523 *
524 * \param upi %UPI
525 * \return index
526 */
527 range_type get(const JUPI_t& upi) const
528 {
529 return down.equal_range(upi);
530 }
531
532
533 /**
534 * Compare two product integrations.
535 *
536 * \param first first product integration
537 * \param second second product integration
538 * \return true if first integrated before second; else false
539 */
540 static inline bool compare(const JProductIntegration_t& first, const JProductIntegration_t& second)
541 {
542 if (first.start_date == second.start_date)
543 return first.operation < second.operation;
544 else
545 return first.start_date < second.start_date;
546 }
547
548
549 protected:
550 /**
551 * Configure detector integration for given detector identifier.\n
552 * This method recursively sets the status all related products.
553 *
554 * \param product product
555 * \param period validity period
556 */
557 void configure(JProductIntegration_t& product, const JPeriod_t& period)
558 {
559 using namespace std;
560
561 range_type range;
562
563 range = out.equal_range(product.container);
564
565 for (range_iterator i = range.first; i != range.second; ++i) {
566
567 const JProductIntegration_t& object = (*this)[i->second];
568
569 if (object.position == product.position &&
570 object.start_date <= period.getLowerLimit() &&
571 object.start_date > product.start_date) {
572 return;
573 }
574 }
575
576 product.set();
577
578 map<int, int> zmap; // position -> index
579
580 range = down.equal_range(product.content);
581
582 for (range_iterator i = range.first; i != range.second; ++i) {
583
584 const JProductIntegration_t& object = (*this)[i->second];
585
586 if (object.start_date <= period.getLowerLimit()) {
587 if (zmap.count(object.position) == 0 || compare((*this)[zmap[object.position]], object)) {
588 zmap[object.position] = i->second;
589 }
590 }
591 }
592
593 for (map<int, int>::iterator i = zmap.begin(); i != zmap.end(); ++i) {
594 configure((*this)[i->second], period);
595 }
596 }
597
598
599 map_type up; //!< up link %UPI to integration data
600 map_type down; //!< down link %UPI to integration data
601 map_type out; //!< link %UPI to disintegrated data
602 };
603}
604
605#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Auxiliary class to define a range between two values.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Database exception.
General exception.
Definition JException.hh:24
Auxiliary class to specify white space character(s) in currect locale.
Range of values.
Definition JRange.hh:42
T getLowerLimit() const
Get lower limit.
Definition JRange.hh:202
char * loc(char *orig)
static const JPBS_t DETECTOR(0)
PBS of detector
Auxiliary classes and methods for database I/O.
Definition JAHRS.hh:14
std::ostream & operator<<(std::ostream &out, const JAHRSCalibration &calibration)
Write AHRS calibration to output stream.
JTOOLS::JRange< JDate_t > JPeriod_t
Type definition of period.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Detector file.
Definition JHead.hh:227
map_type out
link UPI to disintegrated data
static const char *const getName()
Table name.
range_type get(const JUPI_t &upi) const
Get components of product with given UPI.
void load(const char *const file_name, const std::string &separator=";")
Load detector integration from CSV formatted input file.
std::pair< map_type::const_iterator, map_type::const_iterator > range_type
const JProductIntegration_t & trace(const JUPI_t &upi, const JPBS_t &pbs=PBS::DETECTOR) const
Trace product up to given integration level.
std::multimap< JUPI_t, int > map_type
void configure(JProductIntegration_t &product, const JPeriod_t &period)
Configure detector integration for given detector identifier.
map_type::const_iterator range_const_iterator
map_type down
down link UPI to integration data
void print(std::ostream &out, const JUPI_t &upi) const
Print product trace.
friend std::ostream & operator<<(std::ostream &out, const JDetectorIntegration_t &object)
Write detector integration to output stream.
void configure(const std::string &detid, const bool option=false)
Configure detector integration for given detector identifier.
void print(std::ostream &out, const JProductIntegration_t &product) const
Print product trace.
static bool compare(const JProductIntegration_t &first, const JProductIntegration_t &second)
Compare two product integrations.
friend std::istream & operator>>(std::istream &in, JDetectorIntegration_t &object)
Read detector integration from input stream.
range_type find(const JPBS_t &pbs) const
Find range of products with given PBS.
range_type find(const JUPI_t &upi) const
Find range of products with given UPI.
friend bool operator>>(ResultSet &rs, JDetectorIntegration_t &detector)
Read detector integration from result set.
map_type up
up link UPI to integration data
Product breakdown structure (PBS).
Definition JPBS_t.hh:29
const JPBS_t & getPBS() const
Get PBS.
Definition JPBS_t.hh:101
Auxiliary class for product integration data.
JProductIntegration_t(const JProductIntegration &input)
Constructor.
friend std::ostream & operator<<(std::ostream &out, const JProductIntegration_t &object)
Write product integration to output stream.
friend std::istream & operator>>(std::istream &in, JProductIntegration_t &object)
Read product integration from input stream.
bool is_set() const
Check product status.
static const char *const getName()
Table name.
Universal product identifier (UPI).
Definition JUPI_t.hh:32
const JUPI_t & getUPI() const
Get UPI.
Definition JUPI_t.hh:100