casacore
Loading...
Searching...
No Matches
ReadAsciiTable.h
Go to the documentation of this file.
1// # ReadAsciiTable.h: Filling a table from an Ascii file
2// # Copyright (C) 1993,1994,1995,1999,2001,2002
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef TABLES_READASCIITABLE_H
27#define TABLES_READASCIITABLE_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/casa/BasicSL/String.h>
32#include <casacore/casa/Arrays/IPosition.h>
33#include <casacore/tables/Tables/Table.h>
34
35// # Forward Declarations
36#include <casacore/casa/iosfwd.h>
37
38namespace casacore { // # NAMESPACE CASACORE - BEGIN
39
40class Regex;
41class IPosition;
42class LogIO;
43class TableRecord;
44class TableColumn;
45
46// <summary>
47// Filling a table from an Ascii file.
48// </summary>
49// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
50// </reviewed>
51
52// <use visibility=export>
53
54// <prerequisite>
55// <li> <linkto class="Table:description">Table</linkto>
56// </prerequisite>
57
58// <synopsis>
59// Global functions to fill a table from an Ascii file.
60//
61// The table columns are filled from a file containing the data values
62// separated by a separator (optionally followed by whitespace). The
63// default separator is a comma. Non-given values default to 0, False, or
64// blank string (depending on data type). A value is not given between 2
65// consecutive separators or if less values are given than needed.
66// One line per table row should be given.
67// The following two header lines define the columns in the table:
68// <ol>
69// <li> The first line contains the names of the variables in each column.
70// These names may be enclosed in double quotes.
71// <li> The second line contains the data types of each column.
72// Valid types are:
73// <ul>
74// <li> S for Short Integer data
75// <li> I for Integer data
76// <li> R for Real data
77// <li> D for Double Precision data
78// <li> X for Complex data (Real, Imaginary)
79// <li> DX for Double Precision Complex data (R,I)
80// <li> Z for Complex data (Amplitude, Phase)
81// <li> DZ for Double Precision Complex data (A,P)
82// <li> A for ASCII data (must be enclosed in double
83// quotes if it contains one or more blanks)
84// <li> DMS for MVAngle-format position in DMS (converted to radians)
85// In this case a colon separated position is seen as
86// degrees and not as hours.
87// Blanks instead of : can be used as separator.
88// <li> HMS for MVAngle-format position in HMS (converted to radians)
89// Blanks instead of : can be used as separator.
90// </ul>
91// The type can optionally be followed by one or more positive numbers
92// (separated by commas without whitespace) indicating that the column
93// contains an array. The numbers give the shape of the array.
94// E.g. <src>D2,4</src> defines a column containing arrays with
95// shape [2,4]. It "consumes" 8 numbers in each input data line.
96// The last column can contain a 0 in one of the shape numbers.
97// It indicates that the arrays are variable shaped; it "consumes"
98// all remaining numbers in each input data line. If needed,
99// the arrays are filled with default values (0, False, or blank).
100// E.g. <src>I0</src> indicates a variable shaped vector.
101// <src>I0,4</src> with a line with remaining input
102// <src>1 2 3 4 5 6 7 8 9</src> results in an array with shape [3,4]
103// (filled with with 3 zeroes).
104// </ol>
105// If the <src>autoHeader</src> argument is True, the column definition
106// lines should not be given. It recognizes the types from the first data
107// line. It gives the names 'column0', etc. to the columns.
108// It can recognize integer, double, and string types.
109// It is possible to give a shape argument which has the same function
110// as the shape values discussed above.
111// <p>
112// There are two forms of the readAsciiTable function:
113// <ol>
114// <li> The simplest form has two input files.
115// The second input file contains the column data.
116// The first input file contains the keywords (if any)
117// and the column definitions.
118// The keywords in the first file, if there are any, must be enclosed
119// between a line that starts with ".keywords" and a line that starts
120// with ".endkeywords". To define column keywords, .keywords should be
121// followed by whitespace and the column name.
122// Between these two lines each line should contain the following:
123// <ul>
124// <li> The keyword name, e.g., ANYKEY
125// <li> The datatype of the keyword (cf. list of valid types above)
126// <li> The value or values for the keyword (the keyword may contain a
127// scalar or a vector of values). e.g., 3.14159 21.78945
128// </ul>
129// After the keywords definitions, the two column definition lines
130// should follow (unless <src>autoHeader=True</src> is given).
131// <br>For example:
132// <srcblock>
133// .keywords
134// KEYI I 10
135// KEYIV I 11 12 13 14
136// KEYF R 1.2
137// KEYFV R -3.2 0 5.6
138// KEYD D 1.23456789
139// KEYDV D 1 2 3 4 5 6 7 8 9
140// KEYX X -1.5 -3
141// KEYXC X 0 1 2 3 4 5 6 7 8 9
142// KEYZ Z -3 -1.5
143// KEYZV Z 0 0.1 0.2 0.3 0.4 0.5
144// KEYS A "1 2 3 4 5"
145// KEYSV A " 1 2 " "AAA" BBB bbb CCc C "@#$%^&*()"
146// .endkeywords
147// .keywords COLDX
148// IKEYS A "coldx ikey"
149// DKEYS A "coldx dkey"
150// .endkeywords
151// COLI COLF COLD COLX COLZ COLS
152// I R D X Z A
153// </srcblock>
154// defines a table with 12 table keywords (of which 6 contain vector
155// values), 2 keywords for column COLDX, and and 6 columns.
156// The number of rows is determined by the number of
157// lines in the second input file.
158// <li> The other form is to combine the two files in one file.
159// In that case the data lines must be preceeded by the optional
160// keyword and column definitions (without an intermediate blank line).
161// </ol>
162// </synopsis>
163
164// <example>
165// <srcblock>
166// readAsciiTable ("file.in", "", "table.test");
167// </srcblock>
168// creates a table with name <src>table.test</src> from the text file
169// <src>file.in</src>. The text file could look like:
170// <srcblock>
171// COLI COLF COLD COLX COLZ COLS
172// I R D X Z A
173// 1 1.1 1.11 1.12 1.13 1.14 1.15 Str1
174// 10 11 12 13 14 15 16 String17
175// </srcblock>
176// resulting in a table with 6 columns and 2 rows.
177// </example>
178
179// <group name=readAsciiTable>
181// Create a table with name as given by tableName.
182// If autoHeader==True, the format is automatically derived from the
183// first data line. It can recognize integer, double, and String types.
184// The columns will be named column1, column2, etc..
185// If the autoShape argument is given with 1 or more axes, all values are
186// treated as a single column with the given shape. Note that one of the
187// can have length 0 indicating a variable shaped array.
188// If autoHeader==False, the layout of the table has to be defined in
189// the first 2 lines of the input file. The remaining lines in the
190// input file contain the data.
191//
192// When the tableDescName is not blank, the table description will
193// be stored in a table description file with the given name.
194// <br>It returns a string containing the format of the columns in
195// the form COL1=R, COL2=D, ...
196//
197// The separator gives the character separating the values. The default
198// is a blank. Note that irrespective of the separator, blanks between
199// values are always ignored. A string value has to be enclosed in
200// double quotes if it has to contain blanks or the separator value.
201//
202// Header and data lines starting with the regular expression given in the
203// commentMarker are ignored. By default no comment marker is present.
204// E.g. "#" ignores all lines starting with the #-sign.
205// " *#" does the same, but the lines to ignore can start with whitespace.
206//
207// The first and last line argument give the 1-relative number of the
208// first and last line to read from the file. firstLine <= 0 is the
209// same as 1. lastLine <= 0 means until end-of-file.
210// Note that lines matching the comment marker are also counted.
211String readAsciiTable(const String& filein, const String& tableDescName, const String& tableName,
212 Bool autoHeader = False, Char separator = ' ',
213 const String& commentMarkerRegex = "", Int firstLine = 1, Int lastLine = -1,
214 const IPosition& autoShape = IPosition());
215
216// This form gets the header info in the given vectors.
217// Each element in the dataTypes vector has to be of the form as would
218// be given in a header line.
219String readAsciiTable(const String& filein, const String& tableproto, const String& tablename,
220 const Vector<String>& columnNames, const Vector<String>& dataTypes,
221 Char separator, const String& commentMarkerRegex, Int firstLine,
222 Int lastLine);
223
224// This form reads TWO Ascii files. The first file may contain
225// keywords and their values as well as the two lines described above for
226// the names and type of variables. The second file is intended for data only.
227//
228// When the tableDescName is not blank, the table description will
229// be stored in a table description file with the given name.
230// <br>It returns a string containing the format of the columns in
231// the form COL1=R, COL2=D, ...
232//
233// The separator gives the character separating the values. The default
234// is a blank. Note that irrespective of the separator, blanks between
235// values are always ignored. A string value has to be enclosed in
236// double quotes if it has to contain blanks or the separator value.
237//
238// Header and data lines starting with the regular expression given in the
239// commentMarker are ignored. By default no comment marker is present.
240// E.g. "#" ignores all lines starting with the #-sign.
241// " *#" does the same, but the lines to ignore can start with whitespace.
242//
243// The first and last line argument give the 1-relative number of the
244// first and last line to read from the data file. firstLine <= 0 is the
245// same as 1. lastLine <= 0 means until end-of-file.
246// Note that lines matching the comment marker are also counted.
247// <group>
248String readAsciiTable(const String& headerFile, const String& dataFile, const String& tableDescName,
249 const String& tablename, Char separator = ' ',
250 const String& commentMarkerRegex = "", Int firstLine = 1, Int lastLine = -1);
251// # Note that this char* version is needed, because of the first version
252// # Taking a Bool as the 4th argument.
253String readAsciiTable(const String& headerFile, const String& dataFile, const String& tableDescName,
254 const char* tablename, Char separator = ' ',
255 const String& commentMarkerRegex = "", Int firstLine = 1, Int lastLine = -1);
256// </group>
257
258// Similar versions as above, but returning a Table object.
259// The format string is returned in the first argument.
260// The type of Table can be given (Plain or Memory).
261// <group>
262Table readAsciiTable(String& formatString, Table::TableType tableType, const String& filein,
263 const String& tableDescName, const String& tableName, Bool autoHeader = False,
264 Char separator = ' ', const String& commentMarkerRegex = "", Int firstLine = 1,
265 Int lastLine = -1, const IPosition& autoShape = IPosition());
266Table readAsciiTable(String& formatString, Table::TableType tableType, const String& filein,
267 const String& tableproto, const String& tablename,
268 const Vector<String>& columnNames, const Vector<String>& dataTypes,
269 Char separator, const String& commentMarkerRegex, Int firstLine, Int lastLine);
270Table readAsciiTable(String& formatString, Table::TableType tableType, const String& headerFile,
271 const String& dataFile, const String& tableDescName, const String& tablename,
272 Char separator = ' ', const String& commentMarkerRegex = "", Int firstLine = 1,
273 Int lastLine = -1);
274Table readAsciiTable(String& formatString, Table::TableType tableType, const String& headerFile,
275 const String& dataFile, const String& tableDescName, const char* tablename,
276 Char separator = ' ', const String& commentMarkerRegex = "", Int firstLine = 1,
277 Int lastLine = -1);
278// </group>
279
280// </group>
281
282// <summary>
283// Helper class for readAsciiTable
284// </summary>
285// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
286// </reviewed>
287
288// <use visibility=local>
289
290// <synopsis>
291// This class contains static functions as helpers for readAsciiTable.
292// </synopsis>
293
295 public:
296 // Run the readAsciiTable.
297 static String run(const String& headerfile, const String& filein, const String& tableproto,
298 const String& tablename, Bool autoHeader, const IPosition& autoShape,
299 const Vector<String>& columnNames, const Vector<String>& dataTypes,
300 Char separator, const String& commentMarkerRegex, Int firstLine, Int lastLine);
301 static Table runt(String& formatString, Table::TableType tableType, const String& headerfile,
302 const String& filein, const String& tableproto, const String& tablename,
303 Bool autoHeader, const IPosition& autoShape, const Vector<String>& columnNames,
304 const Vector<String>& dataTypes, Char separator,
305 const String& commentMarkerRegex, Int firstLine, Int lastLine);
306
307 // Read a position using MVAngle.
308 // If isDMS is True, a position with : is treated as DMS instead of HMS.
309 // This function is a bit more relaxed than MVAngle::read.
310 // It allows whitespace. Furthermore it allows whitespace as separator :.
311 static double stringToPos(const String& pos, Bool isDMS);
312
313 private:
314 // Define types.
329
330 // Do the actual run.
331 static String doRun(const String& headerfile, const String& filein, const String& tableproto,
332 const String& tablename, Bool autoHeader, const IPosition& autoShape,
333 const Vector<String>& columnNames, const Vector<String>& dataTypes,
334 Char separator, Bool testComment, const Regex& commentMarker, Int firstLine,
335 Int lastLine);
336
337 // Do the actual work of making and filling the table.
338 static Table makeTab(String& formatString, Table::TableType tableType, const String& headerfile,
339 const String& filein, const String& tableproto, const String& tablename,
340 Bool autoHeader, const IPosition& autoShape,
341 const Vector<String>& columnNames, const Vector<String>& dataTypes,
342 Char separator, Bool testComment, const Regex& commentMarker, Int firstLine,
343 Int lastLine);
344
345 // Get the next line. Skip lines to be ignored.
346 // It returns False when no more lines are available.
347 static Bool getLine(ifstream& file, Int& lineNumber, char* line, Int lineSize, Bool testComment,
348 const Regex& commentMarker, Int firstLine, Int lastLine);
349
350 // Get the next part of the line using the separator as delimiter.
351 // Leading blanks are ignored.
352 static Int getNext(const Char* string, Int strlen, Char* result, Int& at, Char separator);
353
354 // Derive the types from the values in the first data line.
355 static void getTypes(const IPosition& shape, const Char* in, Int leng, Char* string1,
356 Char* string2, Char separator);
357
358 // Turn the string into a Bool value.
359 // Empty string, value 0 and any value starting with f, F, n or N are False.
360 static Bool makeBool(const String& str);
361
362 // Handle a keyword set.
363 static void handleKeyset(Int lineSize, char* string1, char* first, char* second,
364 TableRecord& keysets, LogIO& logger, const std::string& fileName,
365 ifstream& jFile, Int& lineNumber, Char separator, Bool testComment,
366 const Regex& commentMarker, Int firstLine, Int lastLine);
367
368 // Get the shape and type from the type string.
369 static Int getTypeShape(const String& typestr, IPosition& shape, Int& type);
370
371 // Get the next scalar value with the given type from string1.
372 static Bool getValue(char* string1, Int lineSize, char* first, Int& at1, Char separator, Int type,
373 void* value);
374
375 // Handle the next scalar with the given type from the data line and
376 // put it into the table column.
377 static void handleScalar(char* string1, Int lineSize, char* first, Int& at1, Char separator,
378 Int type, TableColumn& tabcol, rownr_t rownr);
379
380 // Get the next array with the given type from string1.
381 // It returns the shape (for variable shaped arrays).
382 static IPosition getArray(char* string1, Int lineSize, char* first, Int& at1, Char separator,
383 const IPosition& shape, Int varAxis, Int type, void* valueBlock);
384
385 // Get the next array with the given type from the data line and
386 // put it into the table column.
387 static void handleArray(char* string1, Int lineSize, char* first, Int& at1, Char separator,
388 const IPosition& shape, Int varAxis, Int type, TableColumn& tabcol,
389 rownr_t rownr);
390};
391
392} // namespace casacore
393
394#endif
Helper class for readAsciiTable.
static Int getNext(const Char *string, Int strlen, Char *result, Int &at, Char separator)
Get the next part of the line using the separator as delimiter.
static IPosition getArray(char *string1, Int lineSize, char *first, Int &at1, Char separator, const IPosition &shape, Int varAxis, Int type, void *valueBlock)
Get the next array with the given type from string1.
static Bool getLine(ifstream &file, Int &lineNumber, char *line, Int lineSize, Bool testComment, const Regex &commentMarker, Int firstLine, Int lastLine)
Get the next line.
static void getTypes(const IPosition &shape, const Char *in, Int leng, Char *string1, Char *string2, Char separator)
Derive the types from the values in the first data line.
static Table runt(String &formatString, Table::TableType tableType, const String &headerfile, const String &filein, const String &tableproto, const String &tablename, Bool autoHeader, const IPosition &autoShape, const Vector< String > &columnNames, const Vector< String > &dataTypes, Char separator, const String &commentMarkerRegex, Int firstLine, Int lastLine)
static Table makeTab(String &formatString, Table::TableType tableType, const String &headerfile, const String &filein, const String &tableproto, const String &tablename, Bool autoHeader, const IPosition &autoShape, const Vector< String > &columnNames, const Vector< String > &dataTypes, Char separator, Bool testComment, const Regex &commentMarker, Int firstLine, Int lastLine)
Do the actual work of making and filling the table.
static String doRun(const String &headerfile, const String &filein, const String &tableproto, const String &tablename, Bool autoHeader, const IPosition &autoShape, const Vector< String > &columnNames, const Vector< String > &dataTypes, Char separator, Bool testComment, const Regex &commentMarker, Int firstLine, Int lastLine)
Do the actual run.
static void handleScalar(char *string1, Int lineSize, char *first, Int &at1, Char separator, Int type, TableColumn &tabcol, rownr_t rownr)
Handle the next scalar with the given type from the data line and put it into the table column.
static double stringToPos(const String &pos, Bool isDMS)
Read a position using MVAngle.
static Bool getValue(char *string1, Int lineSize, char *first, Int &at1, Char separator, Int type, void *value)
Get the next scalar value with the given type from string1.
static void handleArray(char *string1, Int lineSize, char *first, Int &at1, Char separator, const IPosition &shape, Int varAxis, Int type, TableColumn &tabcol, rownr_t rownr)
Get the next array with the given type from the data line and put it into the table column.
static Int getTypeShape(const String &typestr, IPosition &shape, Int &type)
Get the shape and type from the type string.
static void handleKeyset(Int lineSize, char *string1, char *first, char *second, TableRecord &keysets, LogIO &logger, const std::string &fileName, ifstream &jFile, Int &lineNumber, Char separator, Bool testComment, const Regex &commentMarker, Int firstLine, Int lastLine)
Handle a keyword set.
static Bool makeBool(const String &str)
Turn the string into a Bool value.
static String run(const String &headerfile, const String &filein, const String &tableproto, const String &tablename, Bool autoHeader, const IPosition &autoShape, const Vector< String > &columnNames, const Vector< String > &dataTypes, Char separator, const String &commentMarkerRegex, Int firstLine, Int lastLine)
Run the readAsciiTable.
String: the storage and methods of handling collections of characters.
Definition String.h:355
TableType
Define the possible table types.
Definition Table.h:184
struct Node * first
Definition malloc.h:325
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:42
IPosition shape(const RecordFieldId &) const
Get the actual shape of this field.
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
NewDelAllocator< T > NewDelAllocator< T >::value
Definition Allocator.h:360
uInt64 rownr_t
Define the type of a row number in a table.
Definition aipsxtype.h:44
char Char
Definition aipstype.h:44
String readAsciiTable(const String &headerFile, const String &dataFile, const String &tableDescName, const char *tablename, Char separator=' ', const String &commentMarkerRegex="", Int firstLine=1, Int lastLine=-1)
String readAsciiTable(const String &headerFile, const String &dataFile, const String &tableDescName, const String &tablename, Char separator=' ', const String &commentMarkerRegex="", Int firstLine=1, Int lastLine=-1)
This form reads TWO Ascii files.
Table readAsciiTable(String &formatString, Table::TableType tableType, const String &filein, const String &tableproto, const String &tablename, const Vector< String > &columnNames, const Vector< String > &dataTypes, Char separator, const String &commentMarkerRegex, Int firstLine, Int lastLine)
String readAsciiTable(const String &filein, const String &tableproto, const String &tablename, const Vector< String > &columnNames, const Vector< String > &dataTypes, Char separator, const String &commentMarkerRegex, Int firstLine, Int lastLine)
This form gets the header info in the given vectors.
String readAsciiTable(const String &filein, const String &tableDescName, const String &tableName, Bool autoHeader=False, Char separator=' ', const String &commentMarkerRegex="", Int firstLine=1, Int lastLine=-1, const IPosition &autoShape=IPosition())
Create a table with name as given by tableName.
Table readAsciiTable(String &formatString, Table::TableType tableType, const String &headerFile, const String &dataFile, const String &tableDescName, const String &tablename, Char separator=' ', const String &commentMarkerRegex="", Int firstLine=1, Int lastLine=-1)
Table readAsciiTable(String &formatString, Table::TableType tableType, const String &filein, const String &tableDescName, const String &tableName, Bool autoHeader=False, Char separator=' ', const String &commentMarkerRegex="", Int firstLine=1, Int lastLine=-1, const IPosition &autoShape=IPosition())
Similar versions as above, but returning a Table object.
Table readAsciiTable(String &formatString, Table::TableType tableType, const String &headerFile, const String &dataFile, const String &tableDescName, const char *tablename, Char separator=' ', const String &commentMarkerRegex="", Int firstLine=1, Int lastLine=-1)