any2matlab.cc
Functions
any2matlab.cc File Reference

This es a MEX-file using Thomas Forbriger's datrwxx library importing seismic dataformats to MATLAB. More...

#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <ctype.h>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <datrwxx/readany.h>
#include <libtime++.h>
#include <aff/series.h>
#include <gsexx.h>
#include <sffxx.h>
#include "mex.h"

Go to the source code of this file.

Functions

void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
 mexFunction of any2matlab to read seismic data to MATLAB More...
 

Detailed Description

This es a MEX-file using Thomas Forbriger's datrwxx library importing seismic dataformats to MATLAB.

Author
Daniel Armbruster
Version
V1.4
Date
07/09/2011
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software

Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

REVISIONS and CHANGES

General

The gateway routine to every MEX-file is called mexFunction.

Parameters
nrhsNumber of inputs (Right Hand Side)
prhsArray of pointers to input data.

The input data is read-only and should not be altered by your mexFunction .

Returns
nlhs Number of expected mxArrays (Left Hand Side)
plhs: Array of pointers to expected outputs

The variables nrhs and nlhs are the number of variables that MATLAB requested at this instance. They are analogous to NARGIN and NARGOUT in MATLAB.
The variables prhs and plhs are not mxArrays. They are arrays of pointers to mxArrays. So if a function is given three inputs, prhs will be an array of three pointers to the mxArrays that contain the data passed in. The variable prhs is declared as const. This means that the values that are passed into the MEX-file should not be altered. Doing so can cause segmentation violations in MATLAB. The values in plhs are invalid when the MEX-file begins. The mxArrays they point to must be explicitly created before they are used. Compilers will not catch this issue, but it will cause incorrect results or segmentation violations.

Usage

tfstruct = any2matlab('name.ftype');
or: tfstruct = any2matlab('name', 'ftype');
or: tfstruct = any2matlab('name', 'ftype', 'dtype');

  1. int for less memory use
  2. double as default
  3. Attention: The integer data is generated by cutting the decimals of the double data. Due to rounding problems on computers it can occur, that a double number of 9.999*10^1 will be casted to 0 (zero).
  1. date: date of first sample. format: 'YYYY/MM/DD'
  2. time: time of the first sample. format: 'hh:mm:ss.milsec'
  3. tdate: timevector: [YYYY MM DD hh mm ss.milsec]
  4. station: Station code. type: string
  5. channel: FDSN channel code. type: string
  6. auxid: Auxiliary identification code. type: string
  7. samps: Number of samples. type: int
  8. dt: Sampling interval (sec). type: double
  9. calib: Calibration factor. type: double
  10. calper: Calibration reference period. type: double
  11. instype: Instrument type. type: string
  12. trace: [sampsx1 double] or [sampsx1 int]

For further information watch sff::WID2

Detailed Information

To allocate sufficient memory any2matlab has to open a first time the desired datafile to get the number of traces and the number of samps per trace.
While opening the datafile a second time any2matlab will read one trace and write it immediately to tfstruct until there are no traces left.
With this method you are able to read as much traces as fit to your machines memory.

Definition in file any2matlab.cc.

Function Documentation

◆ mexFunction()

void mexFunction ( int  nlhs,
mxArray *  plhs[],
int  nrhs,
const mxArray *  prhs[] 
)

mexFunction of any2matlab to read seismic data to MATLAB

Parameters
nlhsnumber of return arguments
plhsthe return arguments
nrhsnumber of input arguments
prhsthe input arguments

Definition at line 129 of file any2matlab.cc.

130 {
131 
132  const char *field_names[] = {"date", "time", "tdate", "station", "channel", "auxid", "samps", "dt",
133 "calib", "calper", "instype", "trace"};
134  int number_of_fields;
135  int date_field, time_field, tdate_field, station_field, channel_field;
136  int auxid_field, samps_field, dt_field, calib_field, calper_field;
137  int instype_field, trace_field;
138  std::vector<int> ntraces;
139  ntraces.reserve(100);
140 
141  // calculate number of fields
142  number_of_fields = sizeof(field_names) / sizeof(*field_names);
143 
144  // check: if input is correct
145  if (nrhs == 0)
146  mexErrMsgTxt("ERROR: missing input filename!");
147  // check: more than 2 arguments
148  else if (nrhs > 3)
149  mexErrMsgTxt("ERROR: too many input arguments!");
150  // check: one argument and string
151  else if ((nrhs == 1) && !mxIsChar(prhs[0]))
152  mexErrMsgTxt("ERROR: input value must be a string!");
153  // check: 2 arguments and string
154  else if (nrhs == 2 && (!mxIsChar(prhs[0]) || !mxIsChar(prhs[1])))
155  mexErrMsgTxt("Error: input values must be strings!");
156  // input must be a row vectors
157  else if (nrhs == 2 && ((mxGetM(prhs[0]) != 1) || mxGetM(prhs[1]) != 1))
158  mexErrMsgTxt("Error: input isn't valid!");
159  else if (nrhs == 3 && (!mxIsChar(prhs[0]) || !mxIsChar(prhs[1]) || !mxIsChar(prhs[2])))
160  mexErrMsgTxt("Error: input values must be strings!");
161  else if (nrhs == 3) {
162  for(int i = 0; i < 3; ++i) {
163  if(mxGetM(prhs[i]) != 1)
164  mexErrMsgTxt("Error: input isn't valid!");
165  }
166  }
167 
168  std::string infile;
169  std::string filetype;
170 
171  // If only one argument is given to any2matlab.mexa64
172  if (nrhs == 1) {
173  infile = std::string(mxArrayToString(prhs[0]));
174 
175  /*
176  * Important note:
177  * If only one argument is given to any2matlab.mexa64 the given filename must
178  * contain at least one dot. After the the dot there must be one of the
179  * following endings.
180  */
181  if (nrhs == 1 && infile.rfind(".") != string::npos) {
182  filetype = infile.substr(infile.rfind(".") + 1);
183  }
184  else
185  mexErrMsgTxt("Error: not a valid filename!");
186  }
187 
188  // check: 2 arguments
189  if (nrhs == 2) {
190  infile = std::string(mxArrayToString(prhs[0]));
191  filetype = std::string(mxArrayToString(prhs[1]));
192  }
193 
194  // set format to default value: double
195  std::string dtype("double");
196 
197  // check: 3 arguments
198  if (nrhs == 3) {
199  infile = std::string(mxArrayToString(prhs[0]));
200  filetype = std::string(mxArrayToString(prhs[1]));
201 
202  std::string arg2(mxArrayToString(prhs[2]));
203  // check: third argument
204  if (arg2 == "int" || arg2 == "double") {
205  dtype = arg2;
206  }
207  else {
208  mexErrMsgTxt("Error: third argument is not valid!");
209  }
210  }
211 
212  // set filetype to lower case
213  transform(filetype.begin(), filetype.end(), filetype.begin(), tolower);
214  mwSize trace = 0;
215  bool hot = false;
216 
217  {
218  std::ifstream ifs(infile.c_str(), datrw::ianystream::openmode(filetype));
219  datrw::ianystream is(ifs, filetype);
220 
221  /* get number of traces in infile */
222  /* while skipping series */
223  hot=is.good();
224 
225  while (hot) {
226  is.skipseries();
227 
228  sff::WID2 wid2;
229  // read the WID2 header
230  is >> wid2;
231 
232  ntraces.push_back(wid2.nsamples);
233  //mexPrintf("samples: %d\n", wid2.nsamples);
234 
235  trace++;
236 
237  hot=(!is.last());
238  }
239  }
240 
241  mwSize dims[2] = {1, trace};
242  // create a 1-by-n array of strucntraces.
243  plhs[0] = mxCreateStructArray(2, dims, number_of_fields, field_names);
244 
245  date_field = mxGetFieldNumber(plhs[0], "date");
246  time_field = mxGetFieldNumber(plhs[0], "time");
247  tdate_field = mxGetFieldNumber(plhs[0], "tdate");
248  station_field = mxGetFieldNumber(plhs[0], "station");
249  auxid_field = mxGetFieldNumber(plhs[0], "auxid");
250  channel_field = mxGetFieldNumber(plhs[0], "channel");
251  samps_field = mxGetFieldNumber(plhs[0], "samps");
252  dt_field = mxGetFieldNumber(plhs[0], "dt");
253  calib_field = mxGetFieldNumber(plhs[0], "calib");
254  calper_field = mxGetFieldNumber(plhs[0], "calper");
255  instype_field = mxGetFieldNumber(plhs[0], "instype");
256  trace_field = mxGetFieldNumber(plhs[0], "trace");
257 
258  {
259  std::ifstream ifs(infile.c_str(), datrw::ianystream::openmode(filetype));
260  datrw::ianystream is(ifs, filetype);
261  hot = is.good();
262 
263  int i = 0;
264 
265  while(hot) {
266  mxArray *field_value;
267 
268  // read integer data
269  if (dtype == "int") {
270  datrw::Tiseries iseries;
271 
272  // read the series
273  is >> iseries;
274 
275  // set trace-field
276  field_value = mxCreateNumericMatrix(ntraces[i], 1, mxINT32_CLASS,
277  mxREAL);
278  // copy stuff
279  int *p = iseries.pointer();
280  int *ptr = static_cast<int*>(mxGetData(field_value));
281  for(int j = 0; j < iseries.size(); ++j) {
282  *ptr = *p;
283  p++;
284  ptr++;
285  }
286  mxSetFieldByNumber(plhs[0], i, trace_field, field_value);
287  }
288  // read double data - default
289  else {
290  datrw::Tdseries dseries;
291  // read the series
292  is >> dseries;
293 
294  // set trace-field
295  field_value = mxCreateNumericMatrix(ntraces[i], 1, mxDOUBLE_CLASS,
296  mxREAL);
297  // copy stuff
298  double *ptr = mxGetPr(field_value);
299  double *tmp = dseries.pointer();
300  for(int j = 0; j < dseries.size(); ++j) {
301  ptr[j] = *tmp;
302  tmp++;
303  }
304  mxSetFieldByNumber(plhs[0], i, trace_field, field_value);
305  }
306 
307  sff::WID2 wid2;
308  // read the WID2 header
309  is >> wid2;
310 
311  // set date-field
312  {
313  std::ostringstream str;
314  str << wid2.date.year() << "/"
315  << wid2.date.month() << "/"
316  << wid2.date.day() << std::ends;
317  std::string datestring;
318  datestring.append(str.str());
319  mxSetFieldByNumber(plhs[0], i, date_field,
320  mxCreateString(datestring.c_str()));
321  }
322 
323  // set date-field
324  {
325  std::ostringstream str;
326  std::string timestring;
327  str << wid2.date.hour() << ":"
328  << wid2.date.minute() << ":"
329  << wid2.date.second() << "."
330  << wid2.date.milsec() << std::ends;
331  timestring.append(str.str());
332  mxSetFieldByNumber(plhs[0], i, time_field,
333  mxCreateString(timestring.c_str()));
334  }
335 
336  // set tdate-field
337  double time [6];
338  time [0] = wid2.date.year();
339  time [1] = wid2.date.month();
340  time [2] = wid2.date.day();
341  time [3] = wid2.date.hour();
342  time [4] = wid2.date.minute();
343  time [5] = wid2.date.second() + wid2.date.milsec() * 0.001;
344 
345  field_value = mxCreateDoubleMatrix(1,
346  sizeof(time) / sizeof(time[0]), mxREAL);
347  memmove(mxGetPr(field_value), &time,
348  sizeof(time) / sizeof(time[0]) * sizeof(double));
349  mxSetFieldByNumber(plhs[0], i, tdate_field, field_value);
350 
351  // set station-field
352  mxSetFieldByNumber(plhs[0], i, station_field,
353  mxCreateString(wid2.station.c_str()));
354 
355  // set channel-field
356  mxSetFieldByNumber(plhs[0], i, channel_field,
357  mxCreateString(wid2.channel.c_str()));
358 
359  // set auxid-field
360  mxSetFieldByNumber(plhs[0], i, auxid_field,
361  mxCreateString(wid2.auxid.c_str()));
362 
363  // set samps-field
364  field_value = mxCreateDoubleMatrix(1, 1, mxREAL);
365  *mxGetPr(field_value) = wid2.nsamples;
366  mxSetFieldByNumber(plhs[0], i, samps_field, field_value);
367 
368  // set dt-field
369  field_value = mxCreateDoubleMatrix(1, 1, mxREAL);
370  *mxGetPr(field_value) = wid2.dt;
371  mxSetFieldByNumber(plhs[0], i, dt_field, field_value);
372 
373  // set calib-field
374  field_value = mxCreateDoubleMatrix(1, 1, mxREAL);
375  *mxGetPr(field_value) = wid2.calib;
376  mxSetFieldByNumber(plhs[0], i, calib_field, field_value);
377 
378  // set calper-field
379  field_value = mxCreateDoubleMatrix(1, 1, mxREAL);
380  *mxGetPr(field_value) = wid2.calper;
381  mxSetFieldByNumber(plhs[0], i, calper_field, field_value);
382 
383  // set instype-field
384  mxSetFieldByNumber(plhs[0], i, instype_field,
385  mxCreateString(wid2.instype.c_str()));
386 
387  i++;
388  hot=(!is.last());
389  }
390  }
391 }