Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JMultipleFileScanner.hh
Go to the documentation of this file.
1 #ifndef __JSUPPORT__JMULTIPLEFILESCANNER__
2 #define __JSUPPORT__JMULTIPLEFILESCANNER__
3 
4 #include <string>
5 #include <vector>
6 #include <limits>
7 
8 #include "TChain.h"
9 #include "TChainElement.h"
10 
11 #include "JLang/JObjectIterator.hh"
12 #include "JLang/JTypeList.hh"
13 #include "JLang/JNullType.hh"
14 #include "JLang/JMultiEquals.hh"
15 #include "JLang/JException.hh"
16 
17 #include "JSupport/JLimit.hh"
18 #include "JSupport/JFileScanner.hh"
19 
20 
21 /**
22  * \file
23  * Scanning of objects from multiple files according a format that follows from the extension of each file name.
24  * \author mdejong
25  */
26 namespace JSUPPORT {}
27 namespace JPP { using namespace JSUPPORT; }
28 
29 namespace JSUPPORT {
30 
32  using JLANG::JPointer;
33  using JLANG::JTypeList;
34  using JLANG::JTYPELIST;
35  using JLANG::JNullType;
36  using JLANG::JMultiEquals;
37  using JLANG::skip_type;
38  using JLANG::JException;
39 
40 
41  /**
42  * Auxiliary base class for list of file names.
43  */
45  public std::vector<std::string>
46  {
47  /**
48  * Default constructor.
49  */
51  {}
52 
53 
54  /**
55  * Constructor.
56  *
57  * \param file_name file name
58  */
59  JMultipleFileScanner_t(const std::string& file_name) :
60  std::vector<std::string>(1, file_name)
61  {}
62 
63 
64  /**
65  * Constructor.
66  *
67  * \param chain ROOT chain
68  */
69  JMultipleFileScanner_t(const TChain& chain)
70  {
71  const TObjArray* array = chain.GetListOfFiles();
72 
73  for (Int_t i = 0; i != array->GetEntries(); ++i) {
74 
75  const TChainElement* p = (const TChainElement*) array->At(i);
76 
77  this->push_back(p->GetTitle());
78  }
79  }
80 
81 
82  /**
83  * Get file list.
84  *
85  * \return list of file names
86  */
88  {
89  return static_cast<const JMultipleFileScanner_t&>(*this);
90  }
91  };
92 
93 
94  /**
95  * General purpose class for object reading from a list of file names.
96  */
97  template<class T = JNullType>
99 
100 
101  /**
102  * Template specialisation of JMultipleFileScanner for undefined type.\n
103  * This specialisation is used as a virtual base class for all implementations of JMultipleFileScanner for defined type(s).
104  *
105  * This class is a simple container for a list of file names and has an additional counter limit by extending from JSUPPORT::JLimit.\n
106  * This counter limit will be used to limit the number of calls to the method <tt>next</tt> of the derived class.\n
107  * Note that the counter limit can only be set via the member or friend methods of JSUPPORT::JLimit.
108  */
109  template<>
111  public JMultipleFileScanner_t,
112  public JLimit,
113  public JMultiEquals<JMultipleFileScanner<JNullType>,
114  JTYPELIST<JLimit, JMultipleFileScanner_t>::typelist>
115  {
116  public:
117 
119 
120  /**
121  * Default constructor.
122  */
124  {}
125 
126 
127  /**
128  * Virtual destructor.
129  */
131  {}
132 
133 
134  /**
135  * Configure.
136  *
137  * \param input list of file names
138  * \param limit limit
139  */
140  void configure(const input_type& input, const JLimit& limit)
141  {
142  static_cast<JMultipleFileScanner_t&>(*this) = input;
143 
144  this->setLimit(limit);
145  }
146 
147 
148  /**
149  * Read multiple file scanner from input.
150  *
151  * Note that only file names are read.
152  *
153  * \param in input stream
154  * \param file_list multiple file scanner
155  * \return input stream
156  */
157  friend inline std::istream& operator>>(std::istream& in, JMultipleFileScanner& file_list)
158  {
159  for (std::string buffer; in >> buffer; ) {
160  file_list.push_back(buffer.c_str());
161  }
162 
163  return in;
164  }
165 
166 
167  /**
168  * Write multiple file scanner to output.
169  *
170  * Note that only file names are written.
171  *
172  * \param out output stream
173  * \param file_list multiple file scanner
174  * \return output stream
175  */
176  friend inline std::ostream& operator<<(std::ostream& out, const JMultipleFileScanner& file_list)
177  {
178  for (const_iterator i = file_list.begin(); i != file_list.end(); ++i) {
179  out << *i << std::endl;
180  }
181 
182  return out;
183  }
184  };
185 
186 
187  /**
188  * Implementation of object reading for single data type from a list of file names.
189  *
190  * This class extends the JMultipleFileScanner<JNullType> class and
191  * implements the JLANG::JRewindableObjectIterator interface.\n
192  * When the method hasNext() is called,
193  * the next file in the list is opened when the previous file is exhausted.
194  */
195  template<class T>
196  class JMultipleFileScanner :
197  public virtual JMultipleFileScanner<>,
198  public JRewindableObjectIterator<T>
199  {
200  public:
201 
204 
205  /**
206  * Default constructor.
207  */
209  index (0),
210  counter(0)
211  {}
212 
213 
214  /**
215  * Copy constructor.
216  *
217  * Note that the counter limit is not copied and the index and counter are set to zero.
218  *
219  * \param input input
220  */
221  template<class JTypelist_t>
223  index (0),
224  counter(0)
225  {
226  this->configure(input.getFilelist(), JLimit());
227  }
228 
229 
230  /**
231  * Constructor.
232  *
233  * \param file_list list of file names
234  * \param limit limit
235  */
236  JMultipleFileScanner(const input_type& file_list, const JLimit& limit = JLimit()) :
237  index (0),
238  counter(0)
239  {
240  configure(file_list, limit);
241  }
242 
243 
244  /**
245  * Get current file name.
246  *
247  * Note that this method should only be called when method hasNext() returns true.
248  *
249  * \return file name
250  */
251  const std::string& getFilename() const
252  {
253  return this->at(index);
254  }
255 
256 
257  /**
258  * Get counter.
259  *
260  * \return counter
261  */
263  {
264  return counter;
265  }
266 
267 
268  /**
269  * Rewind.
270  */
271  virtual void rewind()
272  {
273  if (scanner.is_open()) {
274  scanner.close();
275  }
276 
277  index = 0;
278  counter = 0;
279 
280  scanner.reset();
281  }
282 
283 
284  /**
285  * Check availability of next element.
286  *
287  * \return true if the iteration has more elements; else false
288  */
289  virtual bool hasNext()
290  {
291  if (is_valid()) {
292 
293  if (counter < getUpperLimit() && index != this->size()) {
294 
295  // first time around
296 
297  if (!scanner.is_open()) {
298  scanner.open(getFilename().c_str());
299  }
300 
301  if (counter < getLowerLimit()) {
302  counter += scanner.skip(getLowerLimit() - counter);
303  }
304 
305  if (!scanner.hasNext()) {
306 
307  scanner.close();
308 
309  ++index;
310 
311  return hasNext();
312  }
313 
314  return true;
315 
316  } else {
317 
318  // last time around
319 
320  if (scanner.is_open()) {
321  scanner.close();
322  }
323 
324  scanner.reset();
325  }
326  }
327 
328  return false;
329  }
330 
331 
332  /**
333  * Get next element.
334  *
335  * \return pointer to element
336  */
337  virtual const pointer_type& next()
338  {
339  ++counter;
340 
341  return scanner.next();
342  }
343 
344 
345  /**
346  * Skip items.
347  *
348  * \param ns number of items to skip
349  * \return number of items skipped
350  */
351  virtual skip_type skip(const skip_type ns)
352  {
353  skip_type i = 0;
354 
355  while (this->hasNext() && i != ns) {
356  i += scanner.skip(ns - i);
357  }
358 
359  counter += i;
360 
361  return i;
362  }
363 
364 
365  protected:
367  unsigned int index;
369  };
370 
371 
372  /**
373  * Implementation of object reading for multiple data types from a list of file names.
374  *
375  * This class recursively implements the JLANG::JRewindableObjectIterator interface
376  * for all data types by deriving from:
377  * - JMultipleFileScanner<JHead_t>; and
378  * - JMultipleFileScanner<JTail_t>.
379  *
380  * The method rewind(), rewinds each object iterator.
381  */
382  template<class JHead_t, class JTail_t>
383  class JMultipleFileScanner< JTypeList<JHead_t, JTail_t> > :
384  public virtual JMultipleFileScanner<>,
385  public JRewindableObjectIterator< JTypeList<JHead_t, JTail_t> >,
386  public JMultipleFileScanner<JHead_t>,
387  public JMultipleFileScanner<JTail_t>
388  {
389  public:
390 
392 
395 
396 
397  /**
398  * Default constructor.
399  */
402  {}
403 
404 
405  /**
406  * Copy constructor.
407  *
408  * Note that the counter limit is not copied and the index and counter are set to zero.
409  *
410  * \param input input
411  */
412  template<class JTypelist_t>
414  {
415  this->configure(input.getFilelist(), JLimit());
416  }
417 
418 
419  /**
420  * Constructor.
421  *
422  * \param file_list list of file names
423  * \param limit limit
424  */
425  JMultipleFileScanner(const input_type& file_list, const JLimit& limit = JLimit())
426  {
427  this->configure(file_list, limit);
428  }
429 
430 
431  /**
432  * Rewind.\n
433  * This method rewinds the JMultipleFileScanner for each data type.
434  */
435  virtual void rewind()
436  {
439  }
440 
441 
442  /**
443  * Skip items.
444  *
445  * \param ns number of items to skip
446  * \return number of items skipped
447  */
448  virtual skip_type skip(const skip_type ns)
449  {
450  if (JMultipleFileScanner<JHead_t>::skip(ns) == ns &&
452  return ns;
453  else
454  throw JException("JMultipleFileScanner::skip(): inconsistent number of items skipped.");
455  }
456  };
457 
458 
459  /**
460  * Terminator class of recursive JMultipleFileScanner class.
461  */
462  template<class JHead_t>
464  public JMultipleFileScanner<JHead_t>
465  {
466  public:
467 
469 
470  /**
471  * Default constructor.
472  */
474  JMultipleFileScanner<JHead_t>()
475  {}
476 
477 
478  /**
479  * Copy constructor.
480  *
481  * Note that the counter limit is not copied and the index and counter are set to zero.
482  *
483  * \param input input
484  */
485  template<class JTypelist_t>
487  {
488  this->configure(input.getFilelist(), JLimit());
489  }
490 
491 
492  /**
493  * Constructor.
494  *
495  * \param file_list list of file names
496  * \param limit limit
497  */
498  JMultipleFileScanner(const input_type& file_list, const JLimit& limit = JLimit())
499  {
500  this->configure(file_list, limit);
501  }
502  };
503 }
504 
505 #endif
General exception.
Definition: JException.hh:40
virtual const pointer_type & next()
Get next element.
Exceptions.
JMultipleFileScanner(const JMultipleFileScanner< JTypelist_t > &input)
Copy constructor.
Interface for object iteration with rewinding.
JMultipleFileScanner()
Default constructor.
virtual ~JMultipleFileScanner()
Virtual destructor.
JRewindableObjectIterator< T >::pointer_type pointer_type
unsigned int skip_type
Type definition for number of objects to skip.
JMultipleFileScanner_t(const TChain &chain)
Constructor.
Long64_t counter_type
Type definition for counter.
Definition: JCounter.hh:24
virtual skip_type skip(const skip_type ns)
Skip items.
JMultipleFileScanner_t(const std::string &file_name)
Constructor.
Template definition of auxiliary base class for composite data structures composed of base classes wi...
Definition: JMultiEquals.hh:31
Type list.
Definition: JTypeList.hh:22
friend std::ostream & operator<<(std::ostream &out, const JMultipleFileScanner &file_list)
Write multiple file scanner to output.
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
friend std::istream & operator>>(std::istream &in, JMultipleFileScanner &file_list)
Read multiple file scanner from input.
JMultipleFileScanner_t()
Default constructor.
Auxiliary class for recursive type list generation.
Definition: JTypeList.hh:377
Auxiliary class for no type definition.
Definition: JNullType.hh:19
Template implementation of class that holds pointer to object(s).
Definition: JPointer.hh:22
const JMultipleFileScanner_t & getFilelist() const
Get file list.
const std::string & getFilename() const
Get current file name.
JMultipleFileScanner(const JMultipleFileScanner< JTypelist_t > &input)
Copy constructor.
virtual bool hasNext()
Check availability of next element.
Auxiliary base class for list of file names.
JMultipleFileScanner::input_type input_type
JMultipleFileScanner(const JMultipleFileScanner< JTypelist_t > &input)
Copy constructor.
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, JBool< false > option)
Configuration of value.
General purpose class for object reading from a list of file names.
virtual skip_type skip(const skip_type ns)
Skip items.
JMultipleFileScanner(const input_type &file_list, const JLimit &limit=JLimit())
Constructor.
Object reading from file.
Definition: JFileScanner.hh:34
void configure(const input_type &input, const JLimit &limit)
Configure.
counter_type getCounter() const
Get counter.
Auxiliaries for defining the range of iterations of objects.
bool is_valid(const T &value)
Check validity of given value.
Definition: JHead.hh:711