Jpp  debug
the software that should make you happy
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  */
29 namespace JDATABASE {}
30 namespace JPP { using namespace JDATABASE; }
31 
32 namespace JDATABASE {
33 
35  using JLANG::JException;
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;
167  int position;
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  */
203  {}
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  */
277  const JProductIntegration_t& trace(const JUPI_t& upi,
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));
509  range_const_iterator q = p;
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.
Definition: JException.hh:712
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.
Definition: JException.hh:684
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)
std::ostream & print(std::ostream &out, const JTestSummary &summary, const char delimiter=' ', const bool useColors=true)
Print test summary.
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 JPeriod_t &object)
Write period to output stream.
JTOOLS::JRange< JDate_t > JPeriod_t
Type definition of period.
std::ostream & separator(std::ostream &out)
Print separator.
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
std::string trim(const std::string &buffer)
Trim string.
Definition: JLangToolkit.hh:79
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
Definition: JPredicate.hh:128
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, JBool< false > option)
Configuration of value.
JRange< int > range_type
Definition: JSTDTypes.hh:14
Detector file.
Definition: JHead.hh:227
Date and time.
Definition: JDate_t.hh:35
std::multimap< JUPI_t, int > map_type
map_type out
link UPI to disintegrated data
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.
void configure(JProductIntegration_t &product, const JPeriod_t &period)
Configure detector integration for given detector identifier.
friend std::istream & operator>>(std::istream &in, JDetectorIntegration_t &object)
Read detector integration from input stream.
friend std::ostream & operator<<(std::ostream &out, const JDetectorIntegration_t &object)
Write detector integration to output stream.
map_type down
down link UPI to integration data
void print(std::ostream &out, const JUPI_t &upi) const
Print product trace.
void configure(const std::string &detid, const bool option=false)
Configure detector integration for given detector identifier.
std::pair< map_type::const_iterator, map_type::const_iterator > range_type
map_type::const_iterator range_const_iterator
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.
static const char *const getName()
Table name.
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.
const JProductIntegration_t & trace(const JUPI_t &upi, const JPBS_t &pbs=PBS::DETECTOR) const
Trace product up to given integration level.
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