DATRW++ library: seismic data I/O with multiple formats
thiesdl1file.cc
Go to the documentation of this file.
1 /*! \file thiesdl1file.cc
2  * \brief handle a ThiesDL1 data file (implementation)
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 13/09/2011
8  *
9  * handle a ThiesDL1 data file (implementation)
10  *
11  * Copyright (c) 2011 by Thomas Forbriger (BFO Schiltach)
12  *
13  * ----
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27  * ----
28  *
29  * REVISIONS and CHANGES
30  * - 13/09/2011 V1.0 Thomas Forbriger
31  * - 31/10/2012 V1.1 distinguish warning and critical warning; the latter
32  * for duplicate sample values being at variance
33  * - 07/11/2012 V1.2 add sample values for duplicate entries
34  * - 07/01/2015 V1.3
35  * modifications applied to File::put() function:
36  * - accept duplicate time stamps as part of normal
37  * operation; this is consistent with the behaviour
38  * of DL1logger as implemented on 20/03/2014; it is
39  * further consistent with the tested behaviour of
40  * the ThiesDL1 logger (see note below).
41  * - add sample values for duplicate time stamps
42  * - tr-mode (input stream tolerates redundant samples)
43  * now suppresses a notice-message which otherwise
44  * would be output to the terminal in cases of
45  * duplicate time stamps
46  * - 08/07/2016 V1.4 thof:
47  * - make correct use of new DATRW_report_assert
48  * - make correct use of new DATRW_nonfatal_assert
49  *
50  * ============================================================================
51  * A statement of Volker König at ThiesClima regarding the duplicate entries
52  * in the data files is added at the end of this source file.
53  * ============================================================================
54  * Since the statement by Volker König is quite unsatisfactory, Peter Duffner
55  * and Thomas Forbriger on 07.11.2012 checked Thies DL1 recordings of several
56  * month against manual readings taken directly at the display of the Thies
57  * DL1 logger by Peter Duffner for cases where duplicate samples are present
58  * in the recorded data. The result is, that the values provided on the data
59  * loggers display are obtained, if data values for lines with duplicate time
60  * value are added to form the final value for the respective minute.
61  * ============================================================================
62  */
63 #define DATRW_THIESDL1FILE_CC_VERSION \
64  "DATRW_THIESDL1FILE_CC V1.4"
65 
66 #include <datrwxx/thiesdl1file.h>
67 #include <datrwxx/thiesdl1line.h>
68 #include <datrwxx/error.h>
69 #include <aff/seriesoperators.h>
70 
71 namespace datrw {
72 
73  namespace thiesdl1 {
74 
75  const char* const precipitationID="WR1";
76 
77  const libtime::TRelativeTime dl1samplinginterval(0,0,1);
78 
80  this->Exception::report();
81  this->my_report();
82  } // void ExceptionRecordWindow::report() const
83 
84  /*----------------------------------------------------------------------*/
85 
87  std::cerr << " earliest in expected window: " <<
88  this->Mearliest.timestring();
89  std::cerr << " latest in expected window: " <<
90  this->Mlatest.timestring();
91  std::cerr << " DL1 data line: " << this->Mdataline;
92  } // void ExceptionRecordWindow::my_report() const
93 
94  /*======================================================================*/
95 
96 #define DL1_rcassert( C, M, E, L, N ) \
97  if (!(C)) { throw( thiesdl1::ExceptionRecordWindow( M , __FILE__, \
98  __LINE__, #C, \
99  E, L, N)); }
100 
101  /*======================================================================*/
102 
104  {
105  this->lines.lines.clear();
106  this->expectedinitialdataline.clear();
107  this->expectedfinaldataline.clear();
108  this->initialdataline.clear();
109  this->readsuccessfully=false;
110  } // void FileHeader::clear()
111 
112  /*----------------------------------------------------------------------*/
113 
114  FileHeader readheader(std::istream & is)
115  {
116  FileHeader retval;
117  retval.readsuccessfully=false;
118  struct Found {
119  Found():
120  initial(false),
121  final(false),
122  earliest(false),
123  latest(false),
124  creation(false)
125  { }
126  bool initial,
127  final,
128  earliest,
129  latest,
130  creation;
131  }; // Found
132  Found found;
133  std::string line;
134  DATRW_assert(getline(is, line), "ERROR: reading file");
135  while (line.substr(0,2) == "# ")
136  {
137  retval.lines.append(line.substr(2));
138  if (line.substr(2,15) == "earliest date: ")
139  {
140  retval.earliestdate=
141  libtime::TAbsoluteTime(line.substr(27,4)+":"+
142  line.substr(24,2)+":"+
143  line.substr(21,2)+":"+
144  line.substr(32,15));
145  // std::cout << retval.earliestdate.timestring() << std::endl;
146  found.earliest=true;
147  }
148  else if (line.substr(2,15) == "latest date: ")
149  {
150  retval.latestdate=
151  libtime::TAbsoluteTime(line.substr(27,4)+":"+
152  line.substr(24,2)+":"+
153  line.substr(21,2)+":"+
154  line.substr(32,15));
155  // std::cout << retval.latestdate.timestring() << std::endl;
156  found.latest=true;
157  }
158  else if (line.substr(2,15) == "creation date: ")
159  {
160  retval.creationdate=
161  libtime::TAbsoluteTime(line.substr(27,4)+":"+
162  line.substr(24,2)+":"+
163  line.substr(21,2)+":"+
164  line.substr(32,15));
165  // std::cout << retval.creationdate.timestring() << std::endl;
166  found.creation=true;
167  }
168  else if (line.substr(2,15) == "initial line: ")
169  {
170  retval.expectedinitialdataline=line.substr(17);
171  // std::cout << retval.expectedinitialdataline << std::endl;
172  found.initial=true;
173  }
174  else if (line.substr(2,15) == "final line: ")
175  {
176  retval.expectedfinaldataline=line.substr(17);
177  // std::cout << retval.expectedfinaldataline << std::endl;
178  found.final=true;
179  }
180  // read next line
181  DATRW_assert(getline(is, line), "ERROR: reading file");
182  } // while (line.substr(0,2) == "# ")
183  DATRW_assert(found.initial &&
184  found.final &&
185  found.earliest &&
186  found.latest &&
187  found.creation,
188  "ERROR: could not extract full header data");
190  "initial data line is not matsching"
191  "\n expected: "
192  << retval.expectedinitialdataline <<
193  "\n found: "
194  << line);
195  DATRW_assert(line == retval.expectedinitialdataline,
196  "ERROR: missing expected initial data line");
197  DATRW_assert(retval.earliestdate<=retval.latestdate,
198  "ERROR: inconsistent date values in data header");
199  DATRW_assert(retval.latestdate<=retval.creationdate,
200  "ERROR: inconsistent date values in data header");
201  retval.initialdataline=line;
202  retval.readsuccessfully=true;
203  return(retval);
204  } // FileHeader readheader(std::istream & is)
205 
206  /*----------------------------------------------------------------------*/
207 
208  unsigned int FileHeader::nsamples() const
209  {
211  "FileHeader::nsamples: Data is not set ready");
212  return((this->latestdate-this->earliestdate)/dl1samplinginterval);
213  } // unsigned int FileHeader::nsamples() const
214 
215  /*----------------------------------------------------------------------*/
216 
217  sff::WID2 FileHeader::wid2line() const
218  {
220  "FileHeader::wid2line: Data is not set ready");
221  sff::WID2 retval;
222  retval.date=this->earliestdate+(dl1samplinginterval/2);
223  retval.dt=libtime::time2double(dl1samplinginterval);
224  retval.nsamples=(this->nsamples());
225  retval.station=expectedfinaldataline.substr(12,5);
226  retval.instype=expectedfinaldataline.substr(21,5);
227  retval.channel=precipitationID;
228  return(retval);
229  } // sff::WID2 FileHeader::wid2line() const
230 
231  /*======================================================================*/
232 
233  void File::readwithheader(std::istream& is)
234  {
235  Mheader=readheader(is);
236  this->read(is, Mheader);
237  } // void File::readwithheader(std::istream& is)
238 
239  /*----------------------------------------------------------------------*/
240 
241  void File::read(std::istream& is, const FileHeader& header)
242  {
243  Mheader=header;
245  "ERROR: File container is not empty");
246  Mreadsuccessfully=false;
247  Mreadyforreading=false;
248  libtime::TRelativeTime fileduration=Mheader.latestdate-
251  fileduration<libtime::TRelativeTime(5),
252  "Duration of file is larger than 5 days!\n"
253  "earlist sample: "
254  << Mheader.earliestdate.timestring()
255  << "\n"
256  << "latest sample: "
257  << Mheader.latestdate.timestring()
258  << "\n");
259  // prepare sample container
262  Miseries=0;
263  Mfilled=aff::Series<bool>(Mnsamples);
264  Mfilled=false;
265  // read samples
266  bool hot=true;
267  while (hot && is.good())
268  {
269  std::string line;
270  DATRW_assert(getline(is, line), "ERROR: reading file");
271  if (line==Mheader.expectedfinaldataline)
272  {
273  hot=false;
274  }
275  else
276  {
277  DataLine dataline(line);
278  this->put(line);
279  }
280  } // while (hot && is.good())
281  DATRW_assert(!hot, "missed expected last line of data file");
282  Mreadsuccessfully=true;
283  } // void File::read(std::istream& is)
284 
285  /*----------------------------------------------------------------------*/
286 
287  void File::clear()
288  {
289  Mreadyforreading=true;
291  Mheader.clear();
292  Mnsamples=0;
293  Mreadsuccessfully=false;
294  Mtracefree.lines.clear();
295  Miseries=0;
296  Mfilled=false;
297  } // void File::clear()
298 
299  /*----------------------------------------------------------------------*/
300 
301  bool File::isproperlyfilled(const bool& throwerrors) const
302  {
303  if (throwerrors)
304  {
306  "No data was read into File structure");
308  "Header data not read successfully");
310  "Data not read successfully");
311  }
312  return((!Mreadyforreading)
314  } // bool File::isproperlyfilled(const bool& throwerrors=false) const
315 
316  /*----------------------------------------------------------------------*/
317 
318  void File::put(const DataLine& line)
319  {
320  std::ostringstream oss;
321  // check the time value against the expected time range
323  {
324  DL1_rcassert ((line.time()>=this->Mheader.earliestdate)
325  && (line.time()<=this->Mheader.latestdate),
326  "sample does not fit in expected window",
327  this->Mheader.earliestdate, this->Mheader.latestdate,
328  line.line());
329  }
330  else
331  {
332  if ((line.time()<this->Mheader.earliestdate)
333  || (line.time()>this->Mheader.latestdate))
334  {
335  std::cerr << "sample does not fit in expected window";
336  std::cerr << " earliest in expected window: " <<
337  this->Mheader.earliestdate.timestring();
338  std::cerr << " latest in expected window: " <<
339  this->Mheader.latestdate.timestring();
340  std::cerr << " DL1 data line: " << line.line();
341  oss.clear();
342  oss.str("");
343  oss << "ERROR: data line with weird time: " << line.line();
344  Mtracefree.append(oss.str());
346  }
347  }
348  // evaluate value and fill my record of samples
349  // this uses libtime nfit, which provides safe rounding
350  unsigned int i=(line.time()-
352  if (!this->Mbetolerantagainstwrongtime)
353  {
354  DL1_rcassert (((i>=0) && (i<Mnsamples)),
355  "sample index out of range",
356  this->Mheader.earliestdate,
357  this->Mheader.latestdate,
358  line.line());
359  }
360  if (i>=0 && i<Mnsamples)
361  {
362  if (Mfilled(i))
363  {
364  oss.clear();
365  oss.str("");
366  oss << "NOTICE: duplicate sample time (index "
367  << i << "): " << line.line();
368  if (!this->Mbetolerantagainstredundant)
369  {
370  std::cerr << oss.str() << std::endl;
371  }
372  Mtracefree.append(oss.str());
373  }
374  Mfilled(i)=true;
375  Miseries(i) += line.counts();
376  }
377  else
378  {
379  oss.clear();
380  oss.str("");
381  oss << "ERROR: sample index " << i << " out of range: " << line.line();
382  std::cerr << oss.str() << std::endl;
383  Mtracefree.append(oss.str());
384  }
385  } // void File::put(const DataLine& line)
386 
387  /*----------------------------------------------------------------------*/
388 
389  int File::nsamples() const
390  {
391  return(this->Mheader.nsamples());
392  } // int File::nsamples() const
393 
394  /*----------------------------------------------------------------------*/
395 
396  sff::WID2 File::wid2line() const
397  {
399  "Data is not set ready");
400  return(Mheader.wid2line());
401  } // sff::WID2 File::wid2line() const
402 
403  /*----------------------------------------------------------------------*/
404 
405  //! return data block of values
407  {
408  Tfseries retval(Mnsamples);
409  retval.copyin(Miseries);
410  retval *= DataLine::gain;
411  return(retval);
412  } // Tdseries File::fseries() const
413 
414  /*----------------------------------------------------------------------*/
415 
416  //! return data block of values
418  {
419  Tdseries retval(Mnsamples);
420  retval.copyin(Miseries);
421  retval *= DataLine::gain;
422  return(retval);
423  } // Tdseries File::dseries() const
424 
425  /*----------------------------------------------------------------------*/
426 
427  //! return data block of counts
429  {
430  return(Miseries);
431  } // Tiseries File::iseries() const
432 
433  } // namespace thiesdl1
434 
435 } // namespace datrw
436 
437 /*======================================================================*/
438 /*
439  * E-Mail from Volker König at ThiesClima regarding duplicate entries in the
440  * loggers data files.
441  * -------------------------------------------------------------------------
442 
443 From Volker.Koenig@thiesclima.com Wed Nov 7 11:34:00 2012
444 Date: Wed, 7 Nov 2012 11:33:48 +0100
445 From: "Koenig, Volker" <Volker.Koenig@thiesclima.com>
446 To: "Forbriger, Thomas (GPI)" <thomas.forbriger@kit.edu>
447 Subject: AW: AW: doppelte Einträge Datenerfassung Thies DL1/N V1.10a
448 
449 Sehr geehrter Herr Forbriger,
450 
451 Aufgrund der Auftragsnummer können wir sicher sein, dass der Datalogger mit der neuesten Software arbeitet.
452 
453 Der Datalogger legt jeweils um 24:00 einen zusätzlichen Status-Datensatz mit 0.0 ab. Dies entspricht damit
454 der normalen Funktion.
455 
456 Die 8 anderen Werte mit gleichen (doppelten) Zeitstempel können wir im Moment nicht eindeutig erklären.
457 Eine Ursache könnte sein, dass die interne Uhr des Loggers zu den Messzeitpunkten von außern neu gestellt wurde
458 und dadurch zwei Messwerte mit gleichem Zeitstempel erfasst wurden.
459 Eine andere Möglichkeit könnte ein Timing Problem sein. Das wirklich knapp zum Anfang und Ende einer Minute ein
460 Meßwert erfasst wird. Ein solches Timing Problem ist jedoch bisher nicht bekannt und läßt sich wahrscheinlich
461 nur schwer nachvollziehen, wenn es wirklich nur so selten auftritt.
462 Sind wir mit einer der beiden Ursachen auf der richtigen Spur, sollten die beiden Messwerte addiert werden
463 um den richtigen Summenwert zu erhalten.
464 
465 Wenn Sie uns den Datalogger zusenden, könnten wir diesen in unserem Haus überprüfen bzw. testen. Dies kann jedoch
466 unter Umständen einen längeren Zeitraum erfordern.
467 
468 Für Rückfragen stehen wir jederzeit zur Verfügung.
469 
470 Mit freundlichen Grüßen
471 
472 ............................................
473 Adolf Thies GmbH & Co.KG
474 Meteorologie - Umweltmesstechnik
475 Vertrieb Süd
476 
477 Volker König
478 
479 Tel.: +49 (0) 551 79001 125
480 Fax: +49 (0) 551 79001 64
481 
482 Volker.Koenig@thiesclima.com
483 www.thiesclima.com
484 
485 ADOLF THIES GMBH & CO. KG Hauptstr. 76 37083 Göttingen
486 Registergericht Göttingen HRA 2488 Geschäftsführer: Wolfgang Behrens
487 
488 
489 
490 -----Ursprüngliche Nachricht-----
491 Von: Thomas Forbriger (GPI, BFO) [mailto:Thomas.Forbriger@kit.edu]
492 Gesendet: Dienstag, 6. November 2012 13:37
493 An: Forbriger, Thomas (GPI)
494 Cc: Koenig, Volker; Peter Duffner
495 Betreff: Re: AW: doppelte Einträge Datenerfassung Thies DL1/N V1.10a
496 
497 Sehr geehrter Herr König,
498 
499 uns ist gerade aufgefallen, dass wir den Datenlogger separat bestellt haben und dieser garnicht auf der Rechnung steht, die ich Ihnen geschickt habe. Die Rechnung für den Datenlogger ist vom 19.7.2007. Die Auftragsnummer war
500 AB0702712 und die Rechnungsnummer RE0704090. Ich hoffe, dass Sie damit die Spur aufnehmen können.
501 
502 Beste Grüße,
503 Thomas Forbriger
504 
505 On Mon, 5 Nov 2012, Forbriger, Thomas (GPI) wrote:
506 
507 > Sehr geehrter Herr König,
508 >
509 > im Anhang sende ich Ihnen zwei Fotos (Aufkleber Datenlogger und Rechnung).
510 > Ich hoffe, dass Ihnen eine der darauf angegebenen Nummern weiterhilft.
511 > Falls Sie die Seriennummer daraus erschließen können, wäre ich für
512 > eine Mitteilung dankbar, damit ich sie in unserem Stationsbuch vermerken kann.
513 >
514 > Beste Grüße,
515 > Thomas Forbriger
516 >
517 > On Fri, 2 Nov 2012, Koenig, Volker wrote:
518 >
519 >> Sehr geehrter Herr Forbriger,
520 >>
521 >> können Sie mit noch die Auftragsnummer oder Seriennummer nennen, mit
522 >> denen der Logger geliefert wurde.
523 >>
524 >> Wissen Sie außerdem ob in den letzten Jahren bei diesem Logger ein
525 >> Software-Update durchgeführt wurde.
526 >>
527 >> Für Rückfragen stehen wir jederzeit zur Verfügung.
528 >>
529 >> Mit freundlichen Grüßen
530 >>
531 >> ............................................
532 >> Adolf Thies GmbH & Co.KG
533 >> Meteorologie - Umweltmesstechnik
534 >> Vertrieb Süd
535 >>
536 >> Volker König
537 >>
538 >> Tel.: +49 (0) 551 79001 125
539 >> Fax: +49 (0) 551 79001 64
540 >>
541 >> Volker.Koenig@thiesclima.com
542 >> www.thiesclima.com
543 >>
544 >> ADOLF THIES GMBH & CO. KG Hauptstr. 76 37083 Göttingen
545 >> Registergericht Göttingen HRA 2488 Geschäftsführer: Wolfgang Behrens
546 >>
547 >>
548 >> -----Ursprüngliche Nachricht-----
549 >> Von: Thomas Forbriger (GPI, BFO) [mailto:Thomas.Forbriger@kit.edu]
550 >> Gesendet: Freitag, 2. November 2012 11:58
551 >> An: Koenig, Volker
552 >> Cc: Peter Duffner; Rudolf Widmer-Schnidrig
553 >> Betreff: doppelte Einträge Datenerfassung Thies DL1/N V1.10a
554 >>
555 >> Sehr geehrter Herr König,
556 >>
557 >> wie eben telefonische besprochen, sende ich Ihnen ein paar Beispiele zum geschilderten Problem.
558 >>
559 >> Ich will kurz nochmal die Situation schildern. Seit 2008 betreiben wir einen Regenmesser Ihrer Firma zusammen mit einem DL1/N Datenlogger. Der Datenlogger wird von einem PC aus über serielle Schnittstelle ausgelesen.
560 >> Auf diese Weise erstellen wir Dateien, die jeweils die Messdaten eines Tages enthalten. Solche Dateien schicke ich im Anhang mit.
561 >>
562 >> Beim Verarbeiten der Daten ist schon immer aufgefallen, dass immer wieder doppelte Einträge in den Dateien vorhanden sind. Häufig ist das für den 24:00 Uhr Eintrag der Fall. Ich hänge Ihnen ein Protokoll einer Datenauswertung im Anhang an (Datei dataextract.log). Dort sehen Sie die Meldungen doppelter Einträge, in diesem Fall auch mal um 18:25 am 21.5.2012.
563 >> Wir haben diese Einträge immer ignoriert, weil wir davon ausgegangen sind, dass einfach die gleiche Datenzeile zweimal gesendet wurde.
564 >>
565 >> Bei der Analyse der letzten 2,5 Jahre sind allerdings acht Einträge aufgefallen, in denen zwei unterschiedliche Regenwerte zur selben Minute gemeldet werden (siehe Datei critical.log). Das wirft jetzt die konkrete Frage auf, wie der korrekte Messwert für Minuten lautet, für die ein doppelter Eintrag ausgegeben wird.
566 >>
567 >> Sollen wir die erste Zeile verwenden?
568 >> Sollen wir den jeweils größeren Messwert verwenden?
569 >> Sollen wir die Summe der beiden Messwerte verwenden?
570 >>
571 >> Die betroffenen Tages-Dateien hänge ich ebenfalls an diese E-Mail an.
572 >>
573 >> Ich hoffe, dass Sie anhand der Software im Datenlogger das Problem nachvollziehen können und uns mitteilen können, wie mit den doppelten Einträgen korrekt verfahren werden soll.
574 >>
575 >> Mit freundlichen Grüßen,
576 >> Thomas Forbriger
577 >>
578 >> --
579 >> | Dr. Thomas Forbriger e-mail: Thomas.Forbriger@kit.edu
580 >> | Observatorium Schiltach (BFO), Heubach 206, D-77709 Wolfach,
581 >> | Germany,
582 >> | Tel.: ++49 (0)7836/2151, Fax.: ++49 (0)7836/955240
583 >> | http://www.rz.uni-karlsruhe.de/~bi77
584 */
585 
586 /* ----- END OF thiesdl1file.cc ----- */
void clear()
clear entries
#define DATRW_assert(C, M)
Check an assertion and report by throwing an exception.
Definition: error.h:92
FileHeader readheader(std::istream &is)
Read and parse a file header.
unsigned int counts() const
return count value
Definition: thiesdl1line.h:81
aff::Series< float > Tfseries
Definition: types.h:46
Tdseries dseries() const
return data block of values
bool Mbetolerantagainstwrongtime
mode: do not abort upon wrong sample time
Definition: thiesdl1file.h:196
bool readsuccessfully
true if header data was read successfully
Definition: thiesdl1file.h:106
#define DL1_rcassert(C, M, E, L, N)
Definition: thiesdl1file.cc:96
Store one line of data as read from DL1.
Definition: thiesdl1line.h:70
libtime::TAbsoluteTime time() const
return date and time
Definition: thiesdl1line.h:77
aff::Series< double > Tdseries
Definition: types.h:45
const libtime::TRelativeTime dl1samplinginterval
expected sampling interval of DL1
unsigned int Mnsamples
number of samples
Definition: thiesdl1file.h:183
static const double gain
gain value in mm/count
Definition: thiesdl1line.h:84
unsigned int nsamples() const
number of samples
bool Mbetolerantagainstredundant
mode: do not abort upon redundant samples
Definition: thiesdl1file.h:194
FileHeader header() const
return file header
Definition: thiesdl1file.h:160
aff::Series< bool > Mfilled
an array to keep track of samples
Definition: thiesdl1file.h:189
std::string line() const
return data line
Definition: thiesdl1line.h:75
exception class declaration for libdatrwxx (prototypes)
Tiseries Miseries
prepare are series of counts
Definition: thiesdl1file.h:187
void readwithheader(std::istream &is)
actually read file
libtime::TAbsoluteTime latestdate
latest date
Definition: thiesdl1file.h:102
::sff::FREE lines
A collection of header lines with hash sign stripped off.
Definition: thiesdl1file.h:92
std::string initialdataline
Initial data line.
Definition: thiesdl1file.h:98
bool isproperlyfilled(const bool &throwerrors=false) const
bool Mreadyforreading
is this container empty and ready for reading?
Definition: thiesdl1file.h:177
libtime::TAbsoluteTime creationdate
creation date
Definition: thiesdl1file.h:104
bool Mfoundunexpecteddatatime
found unexpected data time
Definition: thiesdl1file.h:185
Tiseries iseries() const
return data block of counts
Root namespace of library.
Definition: aalibdatrwxx.cc:16
::sff::WID2 wid2line() const
return WID2 header
Store the header of a data file.
Definition: thiesdl1file.h:87
libtime::TAbsoluteTime Mearliest
Definition: thiesdl1file.h:77
FileHeader Mheader
file header
Definition: thiesdl1file.h:181
void read(std::istream &is, const FileHeader &header)
actually read file
::sff::FREE Mtracefree
comment header lines
Definition: thiesdl1file.h:191
void clear()
clear container
aff::Series< int > Tiseries
Definition: types.h:47
#define DATRW_nonfatal_assert(F, C, M)
Macro to distinguish between fatal and non fatal assertions.
Definition: error.h:138
std::string expectedfinaldataline
Expected final data line (as announced in header lines)
Definition: thiesdl1file.h:96
Tfseries fseries() const
return data block of values
libtime::TAbsoluteTime earliestdate
earliest date
Definition: thiesdl1file.h:100
virtual void report() const
Screen report.
Definition: thiesdl1file.cc:79
const char *const precipitationID
SEED channel identifier for precipitation.
Definition: thiesdl1file.cc:75
virtual void report() const
Screen report.
Definition: exception.cc:96
int nsamples() const
number of samples expected in this data set
std::string expectedinitialdataline
Expected initial data line (as announced in header lines)
Definition: thiesdl1file.h:94
bool Mreadsuccessfully
true if data was read successfully
Definition: thiesdl1file.h:179
void put(const DataLine &line)
drop a data line
#define DATRW_report_assert(C, M)
Check an assertion and report only.
Definition: error.h:120
::sff::WID2 wid2line() const
return WID2 header