Jpp 19.3.0-rc.2
the software that should make you happy
Loading...
Searching...
No Matches
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#include <fstream>
8
9#pragma GCC diagnostic push
10#pragma GCC diagnostic ignored "-Wall"
11#include "TChain.h"
12#include "TChainElement.h"
13#pragma GCC diagnostic pop
14
16#include "JLang/JTypeList.hh"
17#include "JLang/JNullType.hh"
18#include "JLang/JMultiEquals.hh"
19#include "JLang/JException.hh"
20#include "JSystem/JGlob.hh"
21
22#include "JSupport/JLimit.hh"
24
25
26/**
27 * \file
28 * Scanning of objects from multiple files according a format that follows from the extension of each file name.
29 * \author mdejong
30 */
31namespace JSUPPORT {}
32namespace JPP { using namespace JSUPPORT; }
33
34namespace JSUPPORT {
35
37 using JLANG::JPointer;
38 using JLANG::JTypeList;
39 using JLANG::JTYPELIST;
40 using JLANG::JNullType;
42 using JLANG::skip_type;
44
45
46 /**
47 * Auxiliary base class for list of file names.
48 */
50 public std::vector<std::string>
51 {
52 /**
53 * Default constructor.
54 */
57
58
59 /**
60 * Constructor.
61 *
62 * \param file_name file name
63 */
64 JMultipleFileScanner_t(const std::string& file_name) :
65 std::vector<std::string>(1, file_name)
66 {}
67
68
69 /**
70 * Constructor.
71 *
72 * \param file_list file list
73 */
75 std::vector<std::string>(file_list)
76 {}
77
78
79 /**
80 * Constructor.
81 *
82 * \param chain ROOT chain
83 */
84 JMultipleFileScanner_t(const TChain& chain)
85 {
86 const TObjArray* array = chain.GetListOfFiles();
87
88 for (Int_t i = 0; i != array->GetEntries(); ++i) {
89
90 const TChainElement* p = (const TChainElement*) array->At(i);
91
92 this->push_back(p->GetTitle());
93 }
94 }
95
96
97 /**
98 * Get file list.
99 *
100 * \return list of file names
101 */
103 {
104 return static_cast<const JMultipleFileScanner_t&>(*this);
105 }
106
107
108 /**
109 * Get file list.
110 *
111 * \return list of file names
112 */
114 {
115 return static_cast<JMultipleFileScanner_t&>(*this);
116 }
117
118
119 /**
120 * Set file list.
121 *
122 * \param file_list list of file names
123 */
124 void setFilelist(const JMultipleFileScanner_t& file_list)
125 {
126 static_cast<JMultipleFileScanner_t&>(*this) = file_list;
127 }
128
129
130 /**
131 * Add file list.
132 *
133 * \param file_list list of file names
134 */
135 void addFilelist(const JMultipleFileScanner_t& file_list)
136 {
137 for (const_iterator i = file_list.begin(); i != file_list.end(); ++i) {
138 this->push_back(*i);
139 }
140 }
141
142
143 /**
144 * Read file list from input.
145 *
146 * \param in input stream
147 * \param object file list
148 * \return input stream
149 */
150 friend inline std::istream& operator>>(std::istream& in, JMultipleFileScanner_t& object)
151 {
152 using namespace std;
153 using namespace JPP;
154
155 for (string buffer; in >> buffer; ) {
156
157 if (getFilenameExtension(buffer) == FILE_LIST_FORMAT) {
158
159 ifstream ls(buffer.c_str());
160
161 ls >> object;
162
163 ls.close();
164
165 } else {
166
167 try {
168 object.addFilelist(getFilenames(buffer));
169 }
170 catch(const exception&) {
171 object.addFilelist(buffer);
172 }
173 }
174 }
175
176 return in;
177 }
178
179
180 /**
181 * Write file list to output.
182 *
183 * \param out output stream
184 * \param object file list
185 * \return output stream
186 */
187 friend inline std::ostream& operator<<(std::ostream& out, const JMultipleFileScanner_t& object)
188 {
189 for (const_iterator i = object.begin(); i != object.end(); ++i) {
190 out << *i << std::endl;
191 }
192
193 return out;
194 }
195 };
196
197
198 /**
199 * General purpose class for object reading from a list of file names.
200 */
201 template<class T = JNullType>
203
204
205 /**
206 * Template specialisation of JMultipleFileScanner for undefined type.\n
207 * This specialisation is used as a virtual base class for all implementations of JMultipleFileScanner for defined type(s).\n
208 * The method JMultipleFileScanner::configure should be used to set the internal parameters.
209 *
210 * This class is a simple container for a list of file names and has an additional counter limit by extending from JSUPPORT::JLimit.\n
211 * This counter limit will be used to limit the number of calls to the method <tt>next</tt> of the derived class.\n
212 * Note that the counter limit can only be set via the member or friend methods of class JSUPPORT::JLimit.
213 */
214 template<>
217 public JLimit,
218 public JMultiEquals<JMultipleFileScanner<JNullType>,
219 JTYPELIST<JLimit, JMultipleFileScanner_t>::typelist>
220 {
221 public:
222
224
225 /**
226 * Default constructor.
227 */
230
231
232 /**
233 * Virtual destructor.
234 */
236 {}
237
238
239 /**
240 * Configure.
241 *
242 * \param input list of file names
243 * \param limit limit
244 */
245 void configure(const input_type& input, const JLimit& limit)
246 {
247 this->setFilelist(input);
248 this->setLimit (limit);
249 }
250
251
252 /**
253 * Configure.
254 *
255 * \param input list of file names
256 */
257 void configure(const input_type& input)
258 {
259 this->configure(input, JLimit());
260 }
261
262
263 /**
264 * Read multiple file scanner from input.
265 *
266 * Note that only file names are read.
267 *
268 * \param in input stream
269 * \param object multiple file scanner
270 * \return input stream
271 */
272 friend inline std::istream& operator>>(std::istream& in, JMultipleFileScanner& object)
273 {
274 return in >> object.getFilelist();
275 }
276
277
278 /**
279 * Write multiple file scanner to output.
280 *
281 * Note that only file names are written.
282 *
283 * \param out output stream
284 * \param object multiple file scanner
285 * \return output stream
286 */
287 friend inline std::ostream& operator<<(std::ostream& out, const JMultipleFileScanner& object)
288 {
289 return out << object.getFilelist();
290 }
291 };
292
293
294 /**
295 * Implementation of object reading for single data type from a list of file names.
296 *
297 * This class extends the JMultipleFileScanner<JNullType> class and
298 * implements the JLANG::JRewindableObjectIterator interface.\n
299 * When the method hasNext() is called,
300 * the next file in the list is opened when the previous file is exhausted.
301 */
302 template<class T>
304 public virtual JMultipleFileScanner<>,
306 {
307 public:
308
311
312 /**
313 * Default constructor.
314 */
316 index (0),
317 counter(0)
318 {}
319
320
321 /**
322 * Copy constructor.
323 *
324 * Note that the counter limit is not copied and the index and counter are set to zero.
325 *
326 * \param input input
327 */
328 template<class JTypelist_t>
330 index (0),
331 counter(0)
332 {
333 this->configure(input.getFilelist(), JLimit());
334 }
335
336
337 /**
338 * Constructor.
339 *
340 * \param file_list list of file names
341 */
343 index (0),
344 counter(0)
345 {
346 configure(file_list, JLimit());
347 }
348
349
350 /**
351 * Constructor.
352 *
353 * \param file_list list of file names
354 * \param limit limit
355 */
356 JMultipleFileScanner(const input_type& file_list, const JLimit& limit) :
357 index (0),
358 counter(0)
359 {
360 configure(file_list, limit);
361 }
362
363
364 /**
365 * Get current file name.
366 *
367 * Note that this method should only be called when method hasNext() returns true.
368 *
369 * \return file name
370 */
371 const std::string& getFilename() const
372 {
373 return this->at(index);
374 }
375
376
377 /**
378 * Get counter.
379 *
380 * \return counter
381 */
383 {
384 return counter;
385 }
386
387
388 /**
389 * Rewind.
390 */
391 virtual void rewind() override
392 {
393 if (scanner.is_open()) {
394 scanner.close();
395 }
396
397 index = 0;
398 counter = 0;
399
400 scanner.reset();
401 }
402
403
404 /**
405 * Check availability of next element.
406 *
407 * \return true if the iteration has more elements; else false
408 */
409 virtual bool hasNext() override
410 {
411 if (is_valid()) {
412
413 if (counter < getUpperLimit() && index != this->size()) {
414
415 // first time around
416
417 if (!scanner.is_open()) {
418 scanner.open(getFilename().c_str());
419 }
420
421 if (counter < getLowerLimit()) {
422 counter += scanner.skip(getLowerLimit() - counter);
423 }
424
425 if (!scanner.hasNext()) {
426
427 scanner.close();
428
429 ++index;
430
431 return hasNext();
432 }
433
434 return true;
435
436 } else {
437
438 // last time around
439
440 if (scanner.is_open()) {
441 scanner.close();
442 }
443
444 scanner.reset();
445 }
446 }
447
448 return false;
449 }
450
451
452 /**
453 * Get next element.
454 *
455 * \return pointer to element
456 */
457 virtual const pointer_type& next() override
458 {
459 ++counter;
460
461 return scanner.next();
462 }
463
464
465 /**
466 * Skip items.
467 *
468 * \param ns number of items to skip
469 * \return number of items skipped
470 */
471 virtual skip_type skip(const skip_type ns) override
472 {
473 skip_type i = 0;
474
475 while (this->hasNext() && i != ns) {
476 i += scanner.skip(ns - i);
477 }
478
479 counter += i;
480
481 return i;
482 }
483
484
485 protected:
487 unsigned int index;
489 };
490
491
492 /**
493 * Implementation of object reading for multiple data types from a list of file names.
494 *
495 * This class recursively implements the JLANG::JRewindableObjectIterator interface
496 * for all data types by deriving from:
497 * - JMultipleFileScanner<JHead_t>; and
498 * - JMultipleFileScanner<JTail_t>.
499 *
500 * The method rewind(), rewinds each object iterator.
501 */
502 template<class JHead_t, class JTail_t>
503 class JMultipleFileScanner< JTypeList<JHead_t, JTail_t> > :
504 public virtual JMultipleFileScanner<>,
505 public JRewindableObjectIterator< JTypeList<JHead_t, JTail_t> >,
506 public JMultipleFileScanner<JHead_t>,
507 public JMultipleFileScanner<JTail_t>
508 {
509 public:
510
512
513 using JMultipleFileScanner<JHead_t>::hasNext;
514 using JMultipleFileScanner<JHead_t>::next;
515
516
517 /**
518 * Default constructor.
519 */
523
524
525 /**
526 * Copy constructor.
527 *
528 * Note that the counter limit is not copied and the index and counter are set to zero.
529 *
530 * \param input input
531 */
532 template<class JTypelist_t>
534 {
535 this->configure(input.getFilelist(), JLimit());
536 }
537
538
539 /**
540 * Constructor.
541 *
542 * \param file_list list of file names
543 */
545 {
546 this->configure(file_list, JLimit());
547 }
548
549
550 /**
551 * Constructor.
552 *
553 * \param file_list list of file names
554 * \param limit limit
555 */
556 JMultipleFileScanner(const input_type& file_list, const JLimit& limit)
557 {
558 this->configure(file_list, limit);
559 }
560
561
562 /**
563 * Rewind.\n
564 * This method rewinds the JMultipleFileScanner for each data type.
565 */
571
572
573 /**
574 * Skip items.
575 *
576 * \param ns number of items to skip
577 * \return number of items skipped
578 */
579 virtual skip_type skip(const skip_type ns) override
580 {
583 return ns;
584 else
585 THROW(JException, "JMultipleFileScanner::skip(): inconsistent number of items skipped.");
586 }
587 };
588
589
590 /**
591 * Terminator class of recursive JMultipleFileScanner class.
592 */
593 template<class JHead_t>
595 public JMultipleFileScanner<JHead_t>
596 {
597 public:
598
600
601 /**
602 * Default constructor.
603 */
607
608
609 /**
610 * Copy constructor.
611 *
612 * Note that the counter limit is not copied and the index and counter are set to zero.
613 *
614 * \param input input
615 */
616 template<class JTypelist_t>
618 {
619 this->configure(input.getFilelist(), JLimit());
620 }
621
622
623 /**
624 * Constructor.
625 *
626 * \param file_list list of file names
627 */
629 {
630 this->configure(file_list, JLimit());
631 }
632
633
634 /**
635 * Constructor.
636 *
637 * \param file_list list of file names
638 * \param limit limit
639 */
640 JMultipleFileScanner(const input_type& file_list, const JLimit& limit)
641 {
642 this->configure(file_list, limit);
643 }
644 };
645}
646
647#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
File list.
Auxiliaries for defining the range of iterations of objects.
General exception.
Definition JException.hh:24
Template implementation of class that holds pointer to object(s).
Definition JPointer.hh:24
Interface for object iteration with rewinding.
Object reading from file.
void configure(const input_type &input)
Configure.
friend std::istream & operator>>(std::istream &in, JMultipleFileScanner &object)
Read multiple file scanner from input.
friend std::ostream & operator<<(std::ostream &out, const JMultipleFileScanner &object)
Write multiple file scanner to output.
void configure(const input_type &input, const JLimit &limit)
Configure.
JMultipleFileScanner(const JMultipleFileScanner< JTypelist_t > &input)
Copy constructor.
JMultipleFileScanner(const input_type &file_list, const JLimit &limit)
Constructor.
virtual skip_type skip(const skip_type ns) override
Skip items.
JMultipleFileScanner(const JMultipleFileScanner< JTypelist_t > &input)
Copy constructor.
JMultipleFileScanner(const input_type &file_list, const JLimit &limit)
Constructor.
General purpose class for object reading from a list of file names.
virtual void rewind() override
Rewind.
JMultipleFileScanner(const JMultipleFileScanner< JTypelist_t > &input)
Copy constructor.
virtual bool hasNext() override
Check availability of next element.
counter_type getCounter() const
Get counter.
virtual const pointer_type & next() override
Get next element.
JMultipleFileScanner()
Default constructor.
JMultipleFileScanner(const input_type &file_list)
Constructor.
JMultipleFileScanner ::input_type input_type
const std::string & getFilename() const
Get current file name.
JRewindableObjectIterator< T >::pointer_type pointer_type
JMultipleFileScanner(const input_type &file_list, const JLimit &limit)
Constructor.
virtual skip_type skip(const skip_type ns) override
Skip items.
std::string getFilenameExtension(const std::string &file_name)
Get file name extension, i.e. part after last JEEP::FILENAME_SEPARATOR if any.
unsigned int skip_type
Type definition for number of objects to skip.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Long64_t counter_type
Type definition for counter.
bool is_valid(const json &js)
Check validity of JSon data.
Support classes and methods for experiment specific I/O.
static const char *const FILE_LIST_FORMAT
file name extension ASCII format with list of file names
static JGlob getFilenames
Function object to get list of files for given pattern.
Definition JGlob.hh:123
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, JBool< false > option)
Configuration of value.
Template definition of auxiliary base class for data structures composed of multiple base classes wit...
Auxiliary class for no type definition.
Definition JNullType.hh:19
Auxiliary class for recursive type list generation.
Definition JTypeList.hh:351
Type list.
Definition JTypeList.hh:23
Auxiliary class for defining the range of iterations of objects.
Definition JLimit.hh:45
Auxiliary base class for list of file names.
const JMultipleFileScanner_t & getFilelist() const
Get file list.
JMultipleFileScanner_t(const std::string &file_name)
Constructor.
void setFilelist(const JMultipleFileScanner_t &file_list)
Set file list.
friend std::ostream & operator<<(std::ostream &out, const JMultipleFileScanner_t &object)
Write file list to output.
friend std::istream & operator>>(std::istream &in, JMultipleFileScanner_t &object)
Read file list from input.
JMultipleFileScanner_t()
Default constructor.
void addFilelist(const JMultipleFileScanner_t &file_list)
Add file list.
JMultipleFileScanner_t(const std::vector< std::string > &file_list)
Constructor.
JMultipleFileScanner_t & getFilelist()
Get file list.
JMultipleFileScanner_t(const TChain &chain)
Constructor.
Auxiliary data structure to list files in directory.