Jpp  18.0.0-rc.3
the software that should make you happy
 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 <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 
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 
227  for (size_t index = 0; index != this->size(); ++index) {
228 
229  JProductIntegration_t& product = (*this)[index];
230 
231  product.unset();
232 
233  up .insert(make_pair(product.content .getUPI(), index));
234  down.insert(make_pair(product.container.getUPI(), index));
235  }
236 
237  for (iterator product = this->begin(); product != this->end(); ++product) {
238  if (product->operation == detid) {
239  configure(*product, JPeriod_t(product->start_date, product->end_date));
240  }
241  }
242 
243  if (option) {
244  this->erase(partition(this->begin(), this->end(), make_predicate(&JProductIntegration_t::is_set, true)), this->end());
245  }
246 
247  up .clear();
248  down.clear();
249 
250  for (size_t index = 0; index != this->size(); ++index) {
251 
252  const JProductIntegration_t& product = (*this)[index];
253 
254  if (product.is_set()) {
255  up .insert(make_pair(product.content .getUPI(), index));
256  down.insert(make_pair(product.container.getUPI(), index));
257  }
258  }
259  }
260 
261 
262  /**
263  * Trace product up to given integration level.
264  *
265  * \param upi %UPI
266  * \param pbs %PBS
267  * \return product
268  */
269  const JProductIntegration_t& trace(const JUPI_t& upi,
270  const JPBS_t& pbs = PBS::DETECTOR) const
271  {
272  using namespace std;
273 
274  if (upi.getPBS() >= pbs) {
275 
276  const range_type range = find(upi);
277 
278  switch (distance(range.first, range.second)) {
279 
280  case 1:
281  {
282  const JProductIntegration_t& product = (*this)[range.first->second];
283 
284  if (product.container.getPBS() == pbs)
285  return product;
286  else
287  return trace(product.container.getUPI(), pbs);
288  }
289 
290  case 0:
291  THROW(JDatabaseException, "Invalid UPI " << upi);
292 
293  default:
294  THROW(JDatabaseException, "Ambiguous integration of UPI " << upi);
295  }
296 
297  } else {
298 
299  THROW(JDatabaseException, "Invalid PBS " << upi.getPBS() << " < " << pbs);
300  }
301  }
302 
303 
304  /**
305  * Print product trace.
306  *
307  * \param out output stream
308  * \param upi %UPI
309  */
310  void print(std::ostream& out, const JUPI_t& upi) const
311  {
312  using namespace std;
313 
315 
316  range = find(upi);
317 
318  for (map_type::const_iterator i = range.first; i != range.second; ++i) {
319 
320  out << upi << " -> ";
321 
322  print(out, (*this)[i->second]);
323  }
324 
325  range = down.equal_range(upi);
326 
327  for (range_iterator i = range.first; i != range.second; ++i) {
328  out << "<- " << (*this)[i->second] << endl;
329  }
330  }
331 
332 
333  /**
334  * Print product trace.
335  *
336  * \param out output stream
337  * \param product product
338  */
339  void print(std::ostream& out, const JProductIntegration_t& product) const
340  {
341  using namespace std;
342 
343  out << product.container.getUPI() << ' '
344  //<< JPeriod_t(product.start_date, product.end_date) << ' '
345  << "-> ";
346 
347  const range_type range = find(product.container.getUPI());
348 
349  for (map_type::const_iterator i = range.first; i != range.second; ++i) {
350  print(out, (*this)[i->second]);
351  }
352 
353  if (distance(range.first, range.second) != 1) {
354  out << product.operation << std::endl;
355  }
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  using namespace std;
369 
370  for (JProductIntegration parameters; rs >> parameters; ) {
371 
372  const JProductIntegration_t product(parameters);
373 
374  detector.up .insert(make_pair(product.content .getUPI(), detector.size()));
375  detector.down.insert(make_pair(product.container.getUPI(), detector.size()));
376 
377  detector.push_back(product);
378  }
379 
380  rs.Close();
381 
382  return true;
383  }
384 
385 
386  /**
387  * Load detector integration from CSV formatted input file.
388  *
389  * The input should be conform output of <tt>JPrintDB -q "integration" -c ";" -W1</tt>.
390  *
391  * \param file_name file name
392  * \param separator separator
393  */
394  void load(const char* const file_name, const std::string& separator = ";")
395  {
396  using namespace std;
397  using namespace JPP;
398 
399  ifstream in(file_name);
400 
401  in.ignore(numeric_limits<streamsize>::max(), '\n');
402 
403  for (string buffer; getline(in, buffer); ) {
404 
405  istringstream is(buffer);
406 
407  const locale loc(is.getloc(), new JWhiteSpacesFacet(is.getloc(), separator));
408 
409  is.imbue(loc);
410 
412 
413  is >> buffer; istringstream(trim(buffer)) >> parameters.OPERATIONID;
414  is >> buffer; istringstream(trim(buffer)) >> parameters.CITY;
415  is >> buffer; istringstream(trim(buffer)) >> parameters.LOCATIONID;
416  is >> buffer; istringstream(trim(buffer)) >> parameters.LOGIN;
417  is >> buffer; istringstream(trim(buffer)) >> parameters.USERID;
418  is >> buffer; istringstream(trim(buffer)) >> parameters.STARTD;
419  is >> buffer; istringstream(trim(buffer)) >> parameters.ENDD;
420  is >> buffer; istringstream(trim(buffer)) >> parameters.CONTAINER_UPI;
421  is >> buffer; istringstream(trim(buffer)) >> parameters.POSITION;
422  is >> buffer; istringstream(trim(buffer)) >> parameters.CONTENT_UPI;
423 
424  const JProductIntegration_t product(parameters);
425 
426  this->up .insert(make_pair(product.content .getUPI(), this->size()));
427  this->down.insert(make_pair(product.container.getUPI(), this->size()));
428 
429  this->push_back(product);
430  }
431 
432  in.close();
433  }
434 
435 
436  /**
437  * Read detector integration from input stream.
438  *
439  * \param in input stream
440  * \param object detector integration
441  * \return input stream
442  */
443  friend inline std::istream& operator>>(std::istream& in, JDetectorIntegration_t& object)
444  {
445  using namespace std;
446 
447  for (JProductIntegration_t product; in >> product; ) {
448 
449  object.up .insert(make_pair(product.content .getUPI(), object.size()));
450  object.down.insert(make_pair(product.container.getUPI(), object.size()));
451 
452  object.push_back(product);
453  }
454 
455  return in;
456  }
457 
458 
459  /**
460  * Write detector integration to output stream.
461  *
462  * \param out output stream
463  * \param object detector integration
464  * \return output stream
465  */
466  friend inline std::ostream& operator<<(std::ostream& out, const JDetectorIntegration_t& object)
467  {
468  for (const_iterator i = object.begin(); i != object.end(); ++i) {
469  out << *i << std::endl;
470  }
471 
472  return out;
473  }
474 
475 
476  /**
477  * Find range of products with given %UPI.\n
478  * The returned range corresponds to the usual begin and end iterators,
479  * each pointing to an STL pair consisting of a %UPI and index.
480  *
481  * \param upi %UPI
482  * \return index
483  */
484  range_type find(const JUPI_t& upi) const
485  {
486  return up.equal_range(upi);
487  }
488 
489 
490  /**
491  * Find range of products with given %PBS.\n
492  * The returned range corresponds to the usual begin and end iterators,
493  * each pointing to an STL pair consisting of a %UPI and index.
494  *
495  * \param pbs %PBS
496  * \return range
497  */
498  range_type find(const JPBS_t& pbs) const
499  {
500  range_const_iterator p = up.lower_bound(JUPI_t(pbs));
501  range_const_iterator q = p;
502 
503  while (q != up.end() && (*this)[q->second].content.getPBS() <= pbs) {
504  ++q;
505  }
506 
507  return range_type(p,q);
508  }
509 
510 
511  /**
512  * Get components of product with given %UPI.\n
513  * The returned range corresponds to the usual begin and end iterators,
514  * each pointing to an STL pair consisting of a %UPI and index.
515  *
516  * \param upi %UPI
517  * \return index
518  */
519  range_type get(const JUPI_t& upi) const
520  {
521  return down.equal_range(upi);
522  }
523 
524 
525  protected:
526  /**
527  * Configure detector integration for given detector identifier.\n
528  * This method recursively sets the status all related products.
529  *
530  * \param product product
531  * \param period validity period
532  */
533  void configure(JProductIntegration_t& product, const JPeriod_t& period)
534  {
535  using namespace std;
536 
537  product.set();
538 
539  map<int, int> zmap; // position -> index
540 
541  const range_type range = down.equal_range(product.content);
542 
543  for (range_iterator i = range.first; i != range.second; ++i) {
544 
545  const JProductIntegration_t& object = (*this)[i->second];
546 
547  if (object.start_date <= period.getLowerLimit()) {
548  if (zmap.count(object.position) == 0 || object.start_date > (*this)[zmap[object.position]].start_date) {
549  zmap[object.position] = i->second;
550  }
551  }
552  }
553 
554  for (map<int, int>::iterator i = zmap.begin(); i != zmap.end(); ++i) {
555  configure((*this)[i->second], period);
556  }
557  }
558 
559  map_type up; //!< up link %UPI to integration data
560  map_type down; //!< down link %UPI to integration data
561  };
562 }
563 
564 #endif
General exception.
Definition: JException.hh:23
Exceptions.
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
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
void unset()
Unset product status.
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.
Database exception.
Definition: JException.hh:666
friend std::ostream & operator<<(std::ostream &out, const JDetectorIntegration_t &object)
Write detector integration to output stream.
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:696
void configure(JProductIntegration_t &product, const JPeriod_t &period)
Configure detector integration for given detector identifier.
void print(std::ostream &out, const JUPI_t &upi) const
Print product trace.
void load(const char *const file_name, const std::string &separator=";")
Load detector integration from CSV formatted input file.
*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
Universal product identifier (UPI).
Definition: JUPI_t.hh:29
Date and time.
Definition: JDate_t.hh:31
is
Definition: JDAQCHSM.chsm:167
range_type find(const JPBS_t &pbs) const
Find range of products with given PBS.
JProductIntegration_t()
Default constructor.
const JPBS_t & getPBS() const
Get PBS.
Definition: JPBS_t.hh:101
const JUPI_t & getUPI() const
Get UPI.
Definition: JUPI_t.hh:97
std::string trim(const std::string &buffer)
Trim string.
Definition: JLangToolkit.hh:79
std::pair< map_type::const_iterator, map_type::const_iterator > range_type
map_type::const_iterator range_const_iterator
static const char *const getName()
Table name.
friend std::istream & operator>>(std::istream &in, JDetectorIntegration_t &object)
Read detector integration from input stream.
std::ostream & separator(std::ostream &out)
Print separator.
const JProductIntegration_t & trace(const JUPI_t &upi, const JPBS_t &pbs=PBS::DETECTOR) const
Trace product up to given integration level.
JTOOLS::JRange< JDate_t > JPeriod_t
Type definition of period.
friend bool operator>>(ResultSet &rs, JDetectorIntegration_t &detector)
Read detector integration from result set.
then awk string
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
range_type find(const JUPI_t &upi) const
Find range of products with given UPI.
std::multimap< JUPI_t, int > map_type
print
Definition: JConvertDusj.sh:44
Range of values.
Definition: JRange.hh:38
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
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.
bool is_set() const
Check product status.
void configure(const std::string &detid, const bool option=false)
Configure detector integration for given detector identifier.
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
Product breakdown structure (PBS).
Definition: JPBS_t.hh:27
set_variable DETECTOR
do set_variable DETECTOR_TXT $WORKDIR detector
static const char *const getName()
Table name.
char * loc(char *orig)
friend std::ostream & operator<<(std::ostream &out, const JProductIntegration_t &object)
Write product integration to output stream.
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS for EMITTER in
Definition: JCanberra.sh:46
void print(std::ostream &out, const JProductIntegration_t &product) const
Print product trace.
friend std::istream & operator>>(std::istream &in, JProductIntegration_t &object)
Read product integration from input stream.
Auxiliary class for product integration data.