McXtrace logo

McXtrace - An X-ray ray-trace simulation package

Synchrotron SOLEIL DTU Physics

McXtrace

About McXtrace
 Publications
 Project Partners
 Project People
 Goal

Download
 Components

Documentation
 Manual
 Commands
 Wiki (GitHub)
 Tutorial

Mailing list

Links

Search

Code-repository (GitHub)

Report bugs (GitHub)


Reading a data file into a vector/matrix (Table input, read_able-lib)

B.2  Reading a data file into a vector/matrix (Table input, read_table-lib)

The read_table-lib library provides functionalities for reading text (and binary) data files. To use this library, add a %include "read_table-lib" in your component definition DECLARE or SHARE section. Tables are structures of type t_Table (see read_table-lib.h file for details):

1    /* t_Table structure (most important members) */ 
2    double *data;     /* Use Table_Index(Table, i j) to extract [i,j] element */ 
3    long    rows;     /* number of rows */ 
4    long    columns;  /* number of columns */ 
5    char   *header;   /* the header with comments */ 
6    char   *filename; /* file name or title */ 
7    double  min_x;    /* minimum value of 1st column/vector */ 
8    double  max_x;    /* maximum value of 1st column/vector */

Available functions to read a single vector/matrix are:

  • Table_Init(&\(Table\), \(rows\), \(columns\)) returns an allocated Table structure. Use \(rows=columns=0\) not to allocate memory and return an empty table. Calls to Table_Init are optional, since initialization is being performed by other functions already.

  • Table_Read(&\(Table\), \(filename\), \(block\)) reads numerical block number \(block\) (0 to catenate all) data from text file \(filename\) into \(Table\), which is as well initialized in the process. The block number changes when the numerical data changes its size, or a comment is encoutered (lines starting by ’# ; % /’). If the data could not be read, then \(Table.data\) is NULL and \(Table.rows = 0\). You may then try to read it using Table_Read_Offset_Binary. Return value is the number of elements read.

  • Table_Read_Offset(&\(Table\), \(filename\), \(block\), &offset, \(n_{rows}\)) does the same as Table_Read except that it starts at offset offset (0 means begining of file) and reads \(n_{rows}\) lines (0 for all). The offset is returned as the final offset reached after reading the \(n_{rows}\) lines.

  • Table_Read_Offset_Binary(&\(Table\), \(filename\), \(type\), \(block\), &offset, \(n_{rows}\), \(n_{columns}\)) does the same as Table_Read_Offset, but also specifies the \(type\) of the file (may be ”float” or ”double”), the number \(n_{rows}\) of rows to read, each of them having \(n_{columns}\) elements. No text header should be present in the file.

  • Table_Rebin(&\(Table\)) rebins all \(Table\) rows with increasing, evenly spaced first column (index 0), e.g. before using Table_Value. Linear interpolation is performed for all other columns. The number of bins for the rebinned table is determined from the smallest first column step.

  • Table_Info\((Table)\) print information about the table \(Table\).

  • Table_Index(\(Table, m, n\)) reads the \(Table[m][n]\) element.

  • Table_Value(\(Table, x, n\)) looks for the closest \(x\) value in the first column (index 0), and extracts in this row the \(n\)-th element (starting from 0). The first column is thus the ’x’ axis for the data.

  • Table_Free(&\(Table\)) free allocated memory blocks.

  • Table_Value2d(\(Table\), \(X\), \(Y\)) Uses 2D linear interpolation on a Table, from (X,Y) coordinates and returns the corresponding value.

Available functions to read an array of vectors/matrices in a text file are:

  • Table_Read_Array(\(File\), &\(n\)) read and split \(file\) into as many blocks as necessary and return a t_Table array. Each block contains a single vector/matrix. This only works for text files. The number of blocks is put into \(n\).

  • Table_Free_Array(&\(Table\)) free the \(Table\) array.

  • Table_Info_Array(&\(Table\)) display information about all data blocks.

The format of text files is free. Lines starting by ’# ; % /’ characters are considered to be comments, and stored in \(Table.header\). Data blocks are vectors and matrices. Block numbers are counted starting from 1, and changing when a comment is found, or the column number changes. For instance, the file ’MCXTRACE/data/Rh.txt’ (Material data for Rhodium) looks like:

1#Rh (Z  45) 
2#Atomic weight: A[r]  102.9055 
3#Nominal density: rho 1.2390E+01 
4#    14 edges. Edge energies (keV): K 23.22, L-I 3.41, ... 
5#------------------------------------------------- 
6#Form Factors, Attenuation and Scattering Cross-sections 
7#Z=45, E = 0.001 - 433 keV 
8# 
9#     E(keV)    f[1]      f[2]    [mu/rho] 
101.069000E-02  1.894E+00  4.805E+00  1.838E+05 
111.142761E-02  2.096E+00  5.102E+00  1.826E+05 
121.221612E-02  2.327E+00  5.401E+00  1.808E+05 
131.305903E-02  2.585E+00  5.699E+00  1.784E+05 
141.396010E-02  2.872E+00  5.993E+00  1.755E+05 
15  ...

Binary files should be of type ”float” (i.e. REAL*32) and ”double” (i.e. REAL*64), and should not contain text header lines. These files are platform dependent (little or big endian).

The \(filename\) is first searched into the current directory (and all user additional locations specified using the -I option, see the ’Running McXtrace ’ chapter in the User Manual), and if not found, in the data sub-directory of the MCXTRACE library location. This way, you do not need to have local copies of the McXtrace Library Data files (see table 1.1).

A usage example for this library part may be:

1  t_Table Table;       // declare a t_Table structure 
2  char file[]="Rh.txt";  // a file name 
3  double x,y; 
4 
5  Table_Read(&Table, file, 1);  // initialize and read the first numerical block 
6  Table_Info(Table);           // display table informations 
7  ... 
8  x = Table_Index(Table, 2,5);  // read the 3rd row, 6th column element 
9                               // of the table. Indexes start at zero in C. 
10  y = Table_Value(Table, 1.45,1);  // look for value 1.45 in 1st column (x axis) 
11                               // and extract 2nd column value of that row 
12  Table_Free(&Table);          // free allocated memory for table

Additionally, if the block number (3rd) argument of Table_Read is 0, all blocks will be catenated. The Table_Value function assumes that the ’x’ axis is the first column (index 0). Other functions are used the same way with a few additional parameters, e.g. specifying an offset for reading files, or reading binary data.

This other example for text files shows how to read many data blocks:

1  t_Table *Table;       // declare a t_Table structure array 
2  long     n; 
3  double y; 
4 
5  Table = Table_Read_Array("file.dat", &n); // initialize and read the all numerical block 
6  n = Table_Info_Array(Table);     // display informations for all blocks (also returns n) 
7 
8  y = Table_Index(Table[0], 2,5);  // read in 1st block the 3rd row, 6th column element 
9                                  // ONLY use Table[i] with i < n ! 
10  Table_Free_Array(Table);         // free allocated memory for Table

You may look into, for instance, the source files for Lens_parab or Filter for other implementation examples.


Last Modified: Monday, 05-Oct-2026 10:48:08 CEST
Search website mailinglist archive GitHub repos