any2matlab.cc
any2matlab.cc
Go to the documentation of this file.
1 
106 #include <iostream>
107 #include <fstream>
108 #include <sstream>
109 #include <cstdio>
110 #include <ctype.h>
111 #include <cstring>
112 #include <string>
113 #include <algorithm>
114 #include <vector>
115 #include <datrwxx/readany.h>
116 #include <libtime++.h>
117 #include <aff/series.h>
118 #include <gsexx.h>
119 #include <sffxx.h>
120 #include "mex.h"
121 
123 
129 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
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 }
392 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexFunction of any2matlab to read seismic data to MATLAB
Definition: any2matlab.cc:129