Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <limits>
8 #include <vector>
9 #include <map>
10 
11 #include "JTools/JRange.hh"
12 #include "JDB/JDB.hh"
14 #include "JDB/JPBS.hh"
15 #include "JDB/JUPI.hh"
16 #include "Jeep/JDate.hh"
17 #include "JLang/JEquals.hh"
18 #include "JLang/JComparable.hh"
19 #include "JLang/JException.hh"
20 
21 #include "dbclient/KM3NeTDBClient.h"
22 
23 
24 /**
25  * \author mdejong
26  */
27 namespace JDATABASE {}
28 namespace JPP { using namespace JDATABASE; }
29 
30 namespace JDATABASE {
31 
33  using JLANG::JException;
34 
35 
36  /**
37  * Type definition for integration date.
38  */
39  typedef JEEP::JDate<'/'> JDate_t;
40 
41 
42  /**
43  * Type definition of period.
44  */
46 
47 
48  /**
49  * Write period to output stream.
50  *
51  * \param out output stream
52  * \param object period
53  * \return output stream
54  */
55  inline std::ostream& operator<<(std::ostream& out, const JPeriod_t& object)
56  {
57  return out << "(" << object.getLowerLimit() << "," << object.getUpperLimit() << ")";
58  }
59 
60 
61  /**
62  * Auxiliary class for product integration data.
63  *
64  * This class is primarily used to
65  * - convert the string data from JDATABASE::JProductIntegration to corresponding data structures;
66  * - implement efficient (in)equality operations;
67  */
69  /**
70  * Default constructor.
71  */
73  status(false)
74  {}
75 
76 
77  /**
78  * Constructor.
79  *
80  * \param input product integration data
81  */
83  status(false)
84  {
85  using namespace std;
86 
87  this->operation = input.OPERATIONID;
88  this->position = input.POSITION;
89  this->container = input.CONTAINER_UPI;
90  this->content = input.CONTENT_UPI;
91 
92  istringstream(input.STARTD) >> this->start_date;
93  istringstream(input.ENDD) >> this->end_date;
94  }
95 
96 
97  /**
98  * Has status.
99  */
100  bool has() const
101  {
102  return status;
103  }
104 
105 
106  /**
107  * Set status.
108  */
109  void set()
110  {
111  status = true;
112  }
113 
114 
115  /**
116  * Unset status.
117  */
118  void unset()
119  {
120  status = false;
121  }
122 
123 
124  /**
125  * Check whether there is an overlap between products.
126  *
127  * The overlap is evaluated based on container UPI and position.
128  *
129  * \param product product
130  * \return true if this product overlaps with given product; else false
131  */
132  bool overlap(const JProductIntegration_t& product) const
133  {
134  return (this->container == product.container &&
135  this->position == product.position);
136  }
137 
138 
139  /**
140  * Write product integration to output stream.
141  *
142  * \param out output stream
143  * \param object product integration
144  * \return output stream
145  */
146  friend inline std::ostream& operator<<(std::ostream& out, const JProductIntegration_t& object)
147  {
148  using namespace std;
149 
150  out << object.operation << ' '
151  << object.container.getUPI() << ' '
152  << object.content .getUPI() << ' '
153  << object.position << ' '
154  << object.start_date << ' '
155  << object.end_date;
156 
157  return out;
158  }
159 
160 
161  std::string operation;
162  int position;
167  bool status;
168  };
169 
170 
171  /**
172  * Detector integration.
173  *
174  * This class is used
175  * - to read product integration data from the data base;
176  * - to organise detector specific integration data in memory;
177  * - to efficiently %trace a product;
178  * - to efficiently %find product(s);
179  */
181  {
182  static const char* const getName() { return JProductIntegration::getName(); } //!< Table name
183 
184 
186  typedef std::pair<map_type::const_iterator,
187  map_type::const_iterator> range_type;
188  typedef map_type::const_iterator range_const_iterator;
189  typedef map_type::const_iterator range_iterator;
190 
192  typedef data_type::const_iterator const_iterator;
193  typedef data_type::iterator iterator;
194  typedef data_type::const_reverse_iterator const_reverse_iterator;
195  typedef data_type::reverse_iterator reverse_iterator;
196 
197 
198  /**
199  * Default constructor.
200  */
202  {}
203 
204 
205  const_iterator begin() const { return data.begin(); } //!< begin of integration data
206  const_iterator end() const { return data.end(); } //!< end of integration data
207  const_reverse_iterator rbegin() const { return data.rbegin(); } //!< reverse begin of integration data
208  const_reverse_iterator rend() const { return data.rend(); } //!< reverse end of integration data
209 
210  bool empty() const { return data.empty(); } //!< check emptyness of integration data
211  size_t size() const { return data.size(); } //!< size of integration data
212 
213 
214  /**
215  * Get product at given index.
216  *
217  * \param index index
218  * \return product
219  */
220  const JProductIntegration_t& operator[](const int index) const
221  {
222  return data[index];
223  }
224 
225 
226  /**
227  * Configure detector integration for given detector identifier.
228  *
229  * The components of the given detector are selected based on the following rules:
230  * -# the component should have a start date before that of the given detector;
231  * -# if multiple components appear at the same place in the same container,
232  * the one with the latest start date is taken.
233  *
234  * \param detid detector identifier
235  */
236  void configure(const std::string& detid)
237  {
238  using namespace std;
239 
240  up .clear();
241  down.clear();
242 
243  for (size_t index = 0; index != data.size(); ++index) {
244 
245  JProductIntegration_t& product = data[index];
246 
247  product.unset();
248 
249  up .insert(make_pair(product.content .getUPI(), index));
250  down.insert(make_pair(product.container.getUPI(), index));
251  }
252 
253 
254  for (data_type::iterator product = data.begin(); product != data.end(); ++product) {
255  if (product->operation == detid) {
256  configure(*product, JPeriod_t(product->start_date, product->end_date));
257  }
258  }
259 
260 
261  up .clear();
262  down.clear();
263 
264  for (size_t index = 0; index != data.size(); ++index) {
265 
266  const JProductIntegration_t& product = data[index];
267 
268  if (product.has()) {
269  up .insert(make_pair(product.content .getUPI(), index));
270  down.insert(make_pair(product.container.getUPI(), index));
271  }
272  }
273  }
274 
275 
276  /**
277  * Trace product up to given integration level.
278  *
279  * \param upi %UPI
280  * \param pbs %PBS
281  * \return product
282  */
283  const JProductIntegration_t& trace(const JUPI& upi,
284  const JPBS& pbs = PBS::DETECTOR) const
285  {
286  if (upi.getPBS() >= pbs) {
287 
288  const int index = find(upi);
289 
290  if (index != -1) {
291 
292  const JProductIntegration_t& product = data[index];
293 
294  if (product.container.getPBS() == pbs)
295  return product;
296  else
297  return trace(product.container.getUPI(), pbs);
298 
299  } else {
300 
301  THROW(JDatabaseException, "Invalid UPI " << upi);
302  }
303 
304  } else {
305 
306  THROW(JDatabaseException, "Invalid PBS " << upi.getPBS() << " < " << pbs);
307  }
308  }
309 
310 
311  /**
312  * Print product trace.
313  *
314  * \param out output stream
315  * \param upi %UPI
316  */
317  void print(std::ostream& out, const JUPI& upi) const
318  {
319  using namespace std;
320 
321  const int index = find(upi);
322 
323  if (index != -1) {
324 
325  out << upi << " -> ";
326 
327  print(out, data[index]);
328  }
329 
330  const range_type range = down.equal_range(upi);
331 
332  for (range_iterator i = range.first; i != range.second; ++i) {
333  out << "<- " << data[i->second] << endl;
334  }
335  }
336 
337 
338  /**
339  * Print product trace.
340  *
341  * \param out output stream
342  * \param product product
343  */
344  void print(std::ostream& out, const JProductIntegration_t& product) const
345  {
346  out << product.container.getUPI() << ' '
347  << JPeriod_t(product.start_date, product.end_date) << ' '
348  << " -> ";
349 
350  const int index = find(product.container.getUPI());
351 
352  if (index != -1)
353  print(out, data[index]);
354  else
355  out << product.operation << std::endl;
356  }
357 
358 
359  /**
360  * Read detector integration from result set.
361  *
362  * \param rs result set
363  * \param detector detector
364  * \return true if read; else false
365  */
366  friend inline bool operator>>(ResultSet& rs, JDetectorIntegration_t& detector)
367  {
368  for (JProductIntegration parameters; rs >> parameters; ) {
369 
370  const JProductIntegration_t product(parameters);
371 
372  detector.up .insert(make_pair(product.content .getUPI(), detector.data.size()));
373  detector.down.insert(make_pair(product.container.getUPI(), detector.data.size()));
374 
375  detector.data.push_back(product);
376  }
377 
378  rs.Close();
379 
380  return true;
381  }
382 
383 
384  /**
385  * Write detector integration to output stream.
386  *
387  * \param out output stream
388  * \param object detector integration
389  * \return output stream
390  */
391  friend inline std::ostream& operator<<(std::ostream& out, const JDetectorIntegration_t& object)
392  {
393  for (const_iterator i = object.data.begin(); i != object.data.end(); ++i) {
394  out << *i << std::endl;
395  }
396 
397  return out;
398  }
399 
400 
401  /**
402  * Find index of unique product with given %UPI.\n
403  * This method can only be used after method JDetectorIntegration_t::configure.
404  *
405  * \param upi %UPI
406  * \return index
407  */
408  int find(const JUPI& upi) const
409  {
410  const range_type range = up.equal_range(upi);
411 
412  switch (std::distance(range.first, range.second)) {
413 
414  case 0:
415  return -1;
416 
417  case 1:
418  return range.first->second;
419 
420  default:
421  THROW(JDatabaseException, "Ambiguous integration of UPI (call first method JDetectorIntegration_t::configure) " << upi);
422  }
423  }
424 
425 
426  /**
427  * Find range of products with given %PBS.\n
428  * The returned range correspond to the usual begin and end iterators,
429  * each pointing to an STL pair consisting of a %UPI and index.
430  *
431  * \param pbs %PBS
432  * \return range
433  */
434  range_type find(const JPBS& pbs) const
435  {
436  range_const_iterator p = up.lower_bound(JUPI(pbs));
437  range_const_iterator q = p;
438 
439  while (q != up.end() && data[q->second].content.getPBS() <= pbs) {
440  ++q;
441  }
442 
443  return range_type(p,q);
444  }
445 
446  protected:
447  /**
448  * Configure detector integration for given detector identifier.\n
449  * This method sets the status all related products.
450  *
451  * \param product product
452  * \param period validity period
453  */
454  void configure(JProductIntegration_t& product, const JPeriod_t& period)
455  {
456  using namespace std;
457 
458  product.set();
459 
460  vector<int> buffer;
461 
462  range_type range = down.equal_range(product.content);
463 
464  for (range_iterator i = range.first; i != range.second; ++i) {
465 
466  if (data[i->second].start_date <= period.getLowerLimit()) {
467 
468  int ns = 0;
469 
470  for (vector<int>::iterator p = buffer.begin(); p != buffer.end(); ++p) {
471 
472  if (data[*p].overlap(data[i->second])) {
473 
474  ++ns;
475 
476  if (data[i->second].start_date > data[*p].start_date) {
477  *p = i->second;
478  }
479  }
480  }
481 
482  if (ns == 0) {
483  buffer.push_back(i->second);
484  }
485  }
486  }
487 
488  for (vector<int>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
489  configure(data[*i], period);
490  }
491  }
492 
493 
494  data_type data; //!< integration data
495  map_type up; //!< up link %UPI to integration data
496  map_type down; //!< down link %UPI to integration data
497  };
498 
499 
500  /**
501  * Auxiliary class to trace product.
502  */
503  struct JProductTrace :
504  std::vector<JProductIntegration_t>
505  {
506  /**
507  * Constructor.
508  *
509  * \param detector detector
510  * \param upi %UPI
511  * \param pbs %PBS
512  */
514  const JUPI& upi,
515  const std::vector<JPBS>& pbs)
516  {
517  JUPI __upi__ = upi;
518 
519  for (std::vector<JPBS>::const_iterator i = pbs.begin(); i != pbs.end(); ++i) {
520 
521  try {
522 
523  const JProductIntegration_t& product = detector.trace(__upi__, *i);
524 
525  push_back(product);
526 
527  __upi__ = product.container.getUPI();
528  }
529  catch(std::exception& error) {
530  break;
531  }
532  }
533  }
534  };
535 }
536 
537 #endif
JProductTrace(const JDetectorIntegration_t &detector, const JUPI &upi, const std::vector< JPBS > &pbs)
Constructor.
General exception.
Definition: JException.hh:23
Exceptions.
size_t size() const
size of integration data
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:215
const_iterator end() const
end of integration data
set_variable DETECTOR
Definition: JLegolas.sh:31
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
JProductIntegration_t(const JProductIntegration &input)
Constructor.
data_type::const_reverse_iterator const_reverse_iterator
Database exception.
Definition: JException.hh:648
const JPBS & getPBS() const
Get PBS.
Definition: JPBS.hh:105
friend std::ostream & operator<<(std::ostream &out, const JDetectorIntegration_t &object)
Write detector integration to output stream.
bool overlap(const JProductIntegration_t &product) const
Check whether there is an overlap between products.
map_type up
up link UPI to integration data
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
void configure(JProductIntegration_t &product, const JPeriod_t &period)
Configure detector integration for given detector identifier.
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
void print(std::ostream &out, const JUPI &upi) const
Print product trace.
const_reverse_iterator rend() const
reverse end of integration data
JProductIntegration_t()
Default constructor.
std::vector< JProductIntegration_t > data_type
range_type find(const JPBS &pbs) const
Find range of products with given PBS.
Auxiliary class to trace product.
std::pair< map_type::const_iterator, map_type::const_iterator > range_type
data_type::const_iterator const_iterator
map_type::const_iterator range_const_iterator
static const char *const getName()
Table name.
const JProductIntegration_t & operator[](const int index) const
Get product at given index.
const_reverse_iterator rbegin() const
reverse begin of integration data
Auxiliary class for simple date.
Definition: Jeep/JDate.hh:30
JTOOLS::JRange< JDate_t > JPeriod_t
Type definition of period.
friend bool operator>>(ResultSet &rs, JDetectorIntegration_t &detector)
Read detector integration from result set.
print
Definition: JConvertDusj.sh:44
Range of values.
Definition: JRange.hh:34
Product breakdown structure (PBS).
Definition: JPBS.hh:27
Universal product identifier (UPI).
Definition: JUPI.hh:30
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, JBool< false > option)
Configuration of value.
map_type down
down link UPI to integration data
Auxiliary class to define a range between two values.
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
data_type::reverse_iterator reverse_iterator
const JUPI & getUPI() const
Get UPI.
Definition: JUPI.hh:68
static const char *const getName()
Table name.
JEEP::JDate<'/'> JDate_t
Type definition for integration date.
friend std::ostream & operator<<(std::ostream &out, const JProductIntegration_t &object)
Write product integration to output stream.
int find(const JUPI &upi) const
Find index of unique product with given UPI.
const JProductIntegration_t & trace(const JUPI &upi, const JPBS &pbs=PBS::DETECTOR) const
Trace product up to given integration level.
void configure(const std::string &detid)
Configure detector integration for given detector identifier.
void print(std::ostream &out, const JProductIntegration_t &product) const
Print product trace.
const_iterator begin() const
begin of integration data
bool empty() const
check emptyness of integration data
Auxiliary class for product integration data.