ARTS  1.0.222
file.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000, 2001 Stefan Buehler <sbuehler@uni-bremen.de>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 
20 // File description
22 
33 // External declarations
36 
37 #include <stdexcept>
38 #include <math.h>
39 #include <cfloat>
40 #include "arts.h"
41 #include "matpackI.h"
42 #include "array.h"
43 #include "messages.h"
44 #include "file.h"
45 
46 
47 
49 // Default file names
51 
53 
65  String& filename,
66  const String& varname )
67 {
68  if ( "" == filename )
69  {
70  extern const String out_basename;
71  filename = out_basename+"."+varname+".aa";
72  }
73 }
74 
75 
76 
78 // Functions to open and read ASCII files
80 
82 
91 void open_output_file(ofstream& file, const String& name)
92 {
93  // Tell the stream that it should throw exceptions.
94  // Badbit means that the entire stream is corrupted, failbit means
95  // that the last operation has failed, but the stream is still
96  // valid. We don't want either to happen!
97  // FIXME: This does not yet work in egcs-2.91.66, try again later.
98  file.exceptions(ios::badbit |
99  ios::failbit);
100 
101  // c_str explicitly converts to c String.
102  file.open(name.c_str() );
103 
104  // See if the file is ok.
105  // FIXME: This should not be necessary anymore in the future, when
106  // g++ stream exceptions work properly. (In that case we would not
107  // get here if there really was a problem, because of the exception
108  // thrown by open().)
109  if (!file)
110  {
111  ostringstream os;
112  os << "Cannot open output file: " << name << '\n'
113  << "Maybe you don't have write access "
114  << "to the directory or the file?";
115  throw runtime_error(os.str());
116  }
117 }
118 
119 
120 
122 
130 void open_input_file(ifstream& file, const String& name)
131 {
132  // Tell the stream that it should throw exceptions.
133  // Badbit means that the entire stream is corrupted.
134  // On the other hand, end of file will not lead to an exception, you
135  // have to check this manually!
136  file.exceptions(ios::badbit);
137 
138  // c_str explicitly converts to c String.
139  file.open(name.c_str() );
140 
141  // See if the file is ok.
142  // FIXME: This should not be necessary anymore in the future, when
143  // g++ stream exceptions work properly.
144  if (!file)
145  {
146  ostringstream os;
147  os << "Cannot open input file: " << name << '\n'
148  << "Maybe the file does not exist?";
149  throw runtime_error(os.str());
150  }
151 }
152 
153 
154 
156 
165 void read_text_from_stream(ArrayOfString& text, istream& is)
166 {
167  String linebuffer;
168 
169  // Read as long as `is' is good.
170  // Contary to what I understood from the book, the explicit check
171  // for eof is necessary here, otherwise the last line is read twice
172  // if it is not terminated by a newline character!
173  while (is && !is.eof())
174  {
175  // Read line from file into linebuffer:
176  getline(is,linebuffer);
177 
178  // Append to end of text:
179  text.push_back(linebuffer);
180  }
181 
182  // Check for error:
183  // FIXME: This should not be necessary anymore when stream
184  // exceptions work properly.
185  if ( !is.eof() ) {
186  ostringstream os;
187  os << "Read Error. Last line read:\n" << linebuffer;
188  throw runtime_error(os.str());
189  }
190 
191 }
192 
193 
194 
196 
206 void read_text_from_file(ArrayOfString& text, const String& name)
207 {
208  ifstream ifs;
209 
210  // Open input stream:
211  open_input_file(ifs, name);
212  // No need to check for error, because open_input_file throws a
213  // runtime_error with an appropriate error message.
214 
215  // Read the text from the stream. Here we catch the exception,
216  // because then we can issue a nicer error message that includes the
217  // filename.
218  try
219  {
220  read_text_from_stream(text,ifs);
221  }
222  catch (runtime_error x)
223  {
224  ostringstream os;
225  os << "Error reading file: " << name << '\n'
226  << x.what();
227  throw runtime_error(os.str());
228  }
229 }
230 
231 
232 
234 
242 void replace_all(String& s, const String& what, const String& with)
243 {
244  Index j = (Index)s.find(what);
245  while ( j != s.npos )
246  {
247  s.replace(j,1,with);
248  j = (Index)s.find(what,j+with.size());
249  }
250 }
251 
252 
253 
255 // Matrix/Vector IO routines for ASCII files
257 
259 
269  const ArrayOfMatrix& am)
270 {
271  extern const String full_name;
272 
273  // Determine the precision, depending on whether Numeric is double
274  // or float:
275  Index precision;
276  switch (sizeof(Numeric)) {
277  case sizeof(float) : precision = FLT_DIG; break;
278  case sizeof(double) : precision = DBL_DIG; break;
279  default: out0 << "Numeric must be double or float\n"; exit(1);
280  }
281 
282  os << "# Generated by "
283  << full_name << ", "
284  << __DATE__ << ", "
285  << __TIME__ << "\n";
286 
287  // Number of array elements:
288  const Index n = am.nelem();
289  os << n << '\n';
290 
291  for (Index i=0; i<n; ++i)
292  {
293  // Number of elements:
294  os << am[i].nrows() << ' ' << am[i].ncols() << '\n';
295 
296  os << setprecision((int)precision);
297  // Write the elements:
298  for (Index r=0; r<am[i].nrows(); ++r)
299  {
300  os << am[i](r,0);
301 
302  for (Index c=1; c<am[i].ncols(); ++c)
303  {
304  os << " " << am[i](r,c);
305  }
306 
307  os << '\n';
308  }
309  }
310 }
311 
312 
313 
315 
323  const ArrayOfMatrix& am)
324 {
325  ofstream of;
326 
327  out2 << " Writing " << filename << '\n';
328  open_output_file(of, filename);
329 
330  // Write the array of matrix to the stream:
332 }
333 
343 void skip_comments(istream & is)
344 {
345  bool comments=true;
346  char c;
347  String linebuffer;
348  while (comments)
349  {
350  is >> ws;
351  is.get(c);
352  if ('#'==c)
353  getline(is,linebuffer);
354  else if ('<'==c)
355  throw runtime_error ("Invalid character (<) in input stream.\nAre you probably trying to read an XML file?");
356  else
357  {
358  is.unget();
359  comments = false;
360  }
361  }
362 }
363 
365 
372  istream& is)
373 {
374  Index n;
375  skip_comments(is); // Skip comment lines.
376  is >> n;
377  // cout << "n: " << n << "\n";
378  am.resize(n);
379  for( Index i=0; i<n; ++i )
380  {
381  // cout << "- " << i << "\n";
382  {
383  Index nr,nc;
384  skip_comments(is); // Skip comment lines.
385  is >> nr >> nc;
386  // cout << "nr: " << nr << "\n";
387  // cout << "nc: " << nc << "\n";
388  am[i].resize(nr,nc);
389  // cout << "am[i]: " << am[i].nrows() << " / " << am[i].ncols() << "\n";
390  for(Index ir=0; ir<nr; ++ir)
391  for(Index ic=0; ic<nc; ++ic)
392  {
393  // cout << "ir / ic = " << ir << " / " << ic << "\n";
394  skip_comments(is); // Skip comment lines.
395  is >> am[i](ir,ic);
396  }
397  }
398  }
399 
400  if ( is.fail() || is.bad() )
401  throw runtime_error("Stream gave fail or bad.");
402 
403  is >> ws;
404 
405  if ( !is.eof() )
406  throw runtime_error("Input finished, but end of stream not reached.");
407 
408  // Some output to the lowest priority stream:
409  out3 << " Dimensions:\n";
410  out3 << " "<< am.nelem() << "\n";
411  for ( Index i=0; i<am.nelem(); ++i )
412  out3 << " " << am[i].nrows() << ", " << am[i].ncols() << "\n";
413 }
414 
415 
416 
418 
426  const String& filename)
427 {
428  ifstream ifs;
429 
430  out2 << " Reading " << filename << '\n';
431 
432  // Open input stream:
433  open_input_file(ifs, filename);
434  // No need to check for error, because open_input_file throws a
435  // runtime_error with an appropriate error message.
436 
437  // Read the matrix from the stream. Here we catch the exception,
438  // because then we can issue a nicer error message that includes the
439  // filename.
440  try
441  {
443  }
444  catch (runtime_error x)
445  {
446  ostringstream os;
447  os << "Error reading file: " << filename << '\n'
448  << x.what();
449  throw runtime_error(os.str());
450  }
451 }
452 
453 
454 
456 // STRING IO routines for ASCII files
458 
460 
470  ostream& os,
471  const ArrayOfString& as )
472 {
473  extern const String full_name;
474 
475  os << "# Generated by " << full_name << "\n";
476 
477  // Number of array elements:
478  const Index n = as.nelem();
479  os << n << '\n';
480 
481  for (Index i=0; i<n; ++i)
482  os << as[i] << '\n';
483 }
484 
485 
486 
488 
498  const String& filename,
499  const ArrayOfString& as )
500 {
501  ofstream of;
502 
503  out2 << " Writing " << filename << '\n';
504  open_output_file(of, filename);
505 
506  // Write the array of String to the stream:
508 }
509 
510 
511 
513 
523  ArrayOfString& as,
524  istream& is )
525 {
526  // First, skip all the lines that have a # at the beginning. (Maybe
527  // preceded by whitespace.)
528  bool comments=true;
529  char c;
530  String linebuffer;
531  while (comments)
532  {
533  is >> ws;
534  is.get(c);
535  if ('#'==c)
536  getline(is,linebuffer);
537 
538  else
539  {
540  is.unget();
541  comments = false;
542  }
543  }
544 
545  // Read the Array of Strings from the input stream:
546  {
547  Index n;
548  is >> n;
549  // cout << "n: " << n << "\n";
550  as.resize(n);
551  for( Index i=0; i<n; ++i )
552  {
553  // cout << "- " << i << "\n";
554  is >> as[i];
555  }
556  }
557 
558  if ( is.fail() || is.bad() )
559  throw runtime_error("Stream gave fail or bad.");
560 
561  is >> ws;
562  if ( !is.eof() )
563  throw runtime_error("Input finished, but end of stream not reached.");
564 
565  // Some output to the lowest priority stream:
566  out3 << " Dimension: "
567  << as.nelem() << ", ";
568 }
569 
570 
571 
573 
583  ArrayOfString& as,
584  const String& filename )
585 {
586  ifstream ifs;
587 
588  out2 << " Reading " << filename << '\n';
589 
590  // Open input stream:
591  open_input_file(ifs, filename);
592  // No need to check for error, because open_input_file throws a
593  // runtime_error with an appropriate error message.
594 
595  // Read the matrix from the stream. Here we catch the exception,
596  // because then we can issue a nicer error message that includes the
597  // filename.
598  try
599  {
601  }
602  catch (runtime_error x)
603  {
604  ostringstream os;
605  os << "Error reading file: " << filename << '\n'
606  << x.what();
607  throw runtime_error(os.str());
608  }
609 }
610 
612 
622  ostream& os,
623  const TagGroups& tgs )
624 {
625  extern const String full_name;
626  extern const Array<SpeciesRecord> species_data;
627 
628  os << "# Generated by " << full_name << "\n";
629 
630  // Number of array elements:
631  const Index n = tgs.nelem();
632  os << n << '\n';
633 
634  for (Index i=0; i<n; ++i)
635  {
636  if ( tgs[i].nelem() > 0 )
637  {
638  // A reference to the relevant record of the species data:
639  const SpeciesRecord& spr = species_data[tgs[i][0].Species()];
640  os << spr.Name() << '\n';
641  }
642  }
643 }
644 
645 
647 
657  const String& filename,
658  const TagGroups& tgs )
659 {
660  ofstream of;
661 
662  out2 << " Writing " << filename << '\n';
663  open_output_file(of, filename);
664 
665  // Write the array of String to the stream:
667 }
out2
Out2 out2
Level 2 output stream.
Definition: messages.cc:54
read_array_of_matrix_from_stream
void read_array_of_matrix_from_stream(ArrayOfMatrix &am, istream &is)
A helper function that reads an array of matrix from a stream.
Definition: file.cc:371
write_array_of_matrix_to_file
void write_array_of_matrix_to_file(const String &filename, const ArrayOfMatrix &am)
A helper function that writes an array of matrix to a file.
Definition: file.cc:322
out0
Out0 out0
Level 0 output stream.
Definition: messages.cc:50
open_input_file
void open_input_file(ifstream &file, const String &name)
Open a file for reading.
Definition: file.cc:130
write_array_of_String_to_stream
void write_array_of_String_to_stream(ostream &os, const ArrayOfString &as)
A helper function that writes an array of String to a stream.
Definition: file.cc:469
write_array_of_matrix_to_stream
void write_array_of_matrix_to_stream(ostream &os, const ArrayOfMatrix &am)
A helper function that writes an array of matrix to a stream.
Definition: file.cc:268
array.h
This file contains the definition of Array.
matpackI.h
Array
This can be used to make arrays out of anything.
Definition: array.h:48
read_text_from_stream
void read_text_from_stream(ArrayOfString &text, istream &is)
Read an ASCII stream and append the contents to the String array text.
Definition: file.cc:165
full_name
String full_name
The ARTS running version number.
Definition: version.cc:32
species_data
Array< SpeciesRecord > species_data
Definition: species_data.cc:36
messages.h
Declarations having to do with the four output streams.
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:61
skip_comments
void skip_comments(istream &is)
A helper function that skips lines containing comments.
Definition: file.cc:343
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: arts.h:147
write_tag_groups_species_to_stream
void write_tag_groups_species_to_stream(ostream &os, const TagGroups &tgs)
A helper function that writes an array of String to a stream.
Definition: file.cc:621
write_array_of_String_to_file
void write_array_of_String_to_file(const String &filename, const ArrayOfString &as)
A help function that writes an array of String to a file.
Definition: file.cc:497
read_array_of_String_from_stream
void read_array_of_String_from_stream(ArrayOfString &as, istream &is)
A help function to read an array of String from a stream.
Definition: file.cc:522
out_basename
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:38
open_output_file
void open_output_file(ofstream &file, const String &name)
Open a file for writing.
Definition: file.cc:91
read_array_of_String_from_file
void read_array_of_String_from_file(ArrayOfString &as, const String &filename)
A help function to read an array of String from a file.
Definition: file.cc:582
SpeciesRecord
Contains the lookup data for one species.
Definition: absorption.h:284
read_text_from_file
void read_text_from_file(ArrayOfString &text, const String &name)
Reads an ASCII file and appends the contents to the String vector text.
Definition: file.cc:206
out3
Out3 out3
Level 3 output stream.
Definition: messages.cc:56
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: arts.h:153
SpeciesRecord::Name
const String & Name() const
Definition: absorption.h:337
read_array_of_matrix_from_file
void read_array_of_matrix_from_file(ArrayOfMatrix &am, const String &filename)
A helper function that reads an array of matrix from a file.
Definition: file.cc:425
filename_ascii
void filename_ascii(String &filename, const String &varname)
Gives the default file name for the ASCII formats.
Definition: file.cc:64
file.h
This file contains basic functions to handle ASCII and binary (HDF) data files.
my_basic_string::npos
static const Index npos
Define npos:
Definition: mystring.h:87
write_tag_groups_species_to_file
void write_tag_groups_species_to_file(const String &filename, const TagGroups &tgs)
A help function that writes an array of String to a file.
Definition: file.cc:656
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:115
arts.h
The global header file for ARTS.
replace_all
void replace_all(String &s, const String &what, const String &with)
Replace all occurances of ‘what’ in ‘s’ with ‘with’.
Definition: file.cc:242