Waveform filter programs
sigscale.cc
Go to the documentation of this file.
1 
35 #define SIGSCALE_VERSION \
36  "SIGSCALE V1.0 apply scaling relations to input signals"
37 
38 #include <iostream>
39 #include <cmath>
40 #include <tfxx/commandline.h>
41 #include <tfxx/error.h>
42 #include <tfxx/seitosh.h>
43 #include <datrwxx/channeltranslation.h>
44 
45 #include <fstream>
46 #include <string>
47 #include <tfxx/xcmdline.h>
48 #include <tfxx/stringfunc.h>
49 #include <tfxx/rangestring.h>
50 #include <tfxx/rangelist.h>
51 #include <tfxx/misc.h>
52 #include <datrwxx/readany.h>
53 #include <datrwxx/writeany.h>
54 #include <sffxx.h>
55 #include <aff/iterator.h>
56 
57 using datrw::tsoft::Econversion;
58 using datrw::tsoft::ChannelDescription;
59 using datrw::tsoft::SFFchannelid;
60 using datrw::tsoft::channel;
61 
62 typedef aff::Series<double> Tseries;
63 
64 /*----------------------------------------------------------------------*/
65 
66 struct Options {
68  bool overwrite;
69  std::string inputformat, outputformat;
70 }; // struct Options
71 
72 /*======================================================================*/
73 
74 /*
75  * the following fragment is taken from
76  * DDAS3_man_technical_ch5_UIPCsoftware_2010-07-16_BFO-Excerpt.docx
77  * as sent by Eric Brinton Fri, 16 Jul 2010 15:52:55 -0700
78  */
79 
80 namespace DDAS3 {
81 
82  const double VL[4] = { 1.32412, 1.11732, 0.923142, 0.079767 };
83  const double VU[4] = { 1.69812, 1.42013, 1.139350, 0.999614 };
84  const int ND[4] = { 10, 11, 12, 11};
85  const double A [4][12] =
86  {{ 7.556358, -5.917261, 0.237238, -0.334636, -0.058642, -0.019929,
87  -0.020715, -0.014814, -0.008789, -0.008554, 0.000000, 0.000000},
88  {17.304227, -7.894688, 0.453442, 0.002243, 0.158036, -0.193093,
89  0.155717, -0.085185, 0.078550, -0.018312, 0.039255, 0.000000},
90  {71.818025, -53.799888, 1.669931, 2.314228, 1.566635, 0.723026,
91  -0.149503, 0.046876, -0.388555, 0.056889, 0.116823, 0.058580},
92  {287.756797, -194.144823, -3.837903, -1.318325, -0.109120, -0.393265,
93  0.146911, -0.111192, 0.028877, -0.029286, 0.015619, 0.000000}};
94 
95  // Chebychev fit coeff for SiDiode
96 #define TRANGE_12K 0
97 #define TRANGE_24K 1
98 #define TRANGE_100K 2
99 #define TRANGE_475K 3
100 
101  void report_sidiode_table(int range)
102  {
103  std::cout << " to be implemented " << std::endl;
104  std::cout << " range " << range << std::endl;
105  } // void report_sidiode_table()
106 
108  // convert_pt100_ohms_to_celsius
110  double convert_pt100_ohms_to_celsius(double ohms)
111  {
112  return( (double)(1.0/0.00385) * ((ohms/(double)100.0) - (double)1.0) );
113  } // double convert_pt100_ohms_to_celsius(double ohms)
114 
116  // convert_pt100_ohms_to_celsius
118  double convert_pt100_ohms_to_Kelvin(double ohms)
119  {
120  return( 273.15 + convert_pt100_ohms_to_celsius(ohms)) ;
121  } // double convert_pt100_ohms_to_Kelvin(double ohms)
122 
124  // convert_volts_to_psi
126  double convert_volts_to_psi(double volts)
127  {
128  return( (volts - 6.0) * 0.250) ;
129  } // double convert_volts_to_psi(double volts)
130 
132  // convert_td_ohms_to_celsius
134  double convert_td_ohms_to_celsius(double ohms)
135  {
136  double a, b, c, Ro, Rt, T;
137 
138  Ro = 1854;
139  Rt = ohms;
140 
141  c = Ro - Rt;
142  b = 3.84 * 0.001 * Ro;
143  a = 4.94 * 0.000001 * Ro;
144 
145  T = ((-b) + sqrt((b*b) - (4.0*a*c))) / (2.0*a);
146 
147  return( T );
148  } // double convert_td_ohms_to_celsius(double ohms)
149 
151  // convert_volts_to_sidiode
153  double convert_sidiode_volts_to_kelvin(double volts)
154  {
155  double x, t, v, vl, vu;
156  int i, nd, range;
157 
158  if ( volts < 0.24963 )
159  // clip value to 410K if out of range e.g.sensor unplugged
160  return 410.0 ;
161 
162  // Coefficients table ends at 1.4K
163  if ( volts > 1.698120 )
164  // clip value to 1.4K if out of range //changed 09/08
165  return 1.40 ;
166 
167  if ( volts > VU[TRANGE_12K] ) range = 0 ;
168  else if ( volts>VU[TRANGE_24K ] && volts<=VU[TRANGE_12K ] ) range = 0;
169  else if ( volts>VU[TRANGE_100K] && volts<=VU[TRANGE_24K ] ) range = 1;
170  else if ( volts>VU[TRANGE_475K] && volts<=VU[TRANGE_100K] ) range = 2;
171  else /*volts<=VU[TRANGE_475K]*/ range = 3;
172 
173  v = volts;
174  vl = VL[range];
175  vu = VU[range];
176  nd = ND[range];
177  x = ((v-vl)-(vu-v))/(vu-vl);
178 
179  if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
180 
181  t = 0.0;
182  for( i=0; i<nd; i++ )
183  t = t + A[range][i]*cos(i*acos(x));
184 
185  return t;
186  } // double convert_sidiode_volts_to_kelvin(double volts)
187 
189  // convert_volts_to_sidiode_with_correction
190  // NEED to add correction factor for non magnetic sensor.
193  {
194  double x, t, v, vl, vu;
195  int i, nd, range;
196 
197 
198  if ( volts < 0.24963 )
199  // clip value to 410K if out of range e.g.sensor unplugged
200  return 410.0 ;
201 
202  // Coefficients table ends at 1.4K
203  if ( volts > 1.698120 )
204  // clip value to 1.4K if out of range //changed 09/08
205  return 1.40 ;
206 
207  // std::cout << "\n\nDEBUG in SIDIODE4: " << volts << std::endl;
208 
209  if ( volts > VU[TRANGE_12K] ) range = 0 ;
210  else if ( volts>VU[TRANGE_24K ] && volts<=VU[TRANGE_12K ] ) range = 0;
211  else if ( volts>VU[TRANGE_100K] && volts<=VU[TRANGE_24K ] ) range = 1;
212  else if ( volts>VU[TRANGE_475K] && volts<=VU[TRANGE_100K] ) range = 2;
213  else /*volts<=VU[TRANGE_475K]*/ range = 3;
214 
215  v = volts;
216  vl = VL[range];
217  vu = VU[range];
218  nd = ND[range];
219  x = ((v-vl)-(vu-v))/(vu-vl);
220 
221  if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
222 
223  t = 0.0;
224  for( i=0; i<nd; i++ )
225  t = t + A[range][i]*cos(i*acos(x));
226 
227  return t;
228  } // double convert_sidiode_volts_to_kelvin_with_correction(double volts)
229 
230  /****************************************************************************/
231  // convert_GEPLHe19_volts_to_percent
232  // 19" (482.6mm) Active Length * 45 ohm / mm = 219.583 ohms total at 0%
233  // Excitation current = 73.53 mA, V=16.14581
234  // Electronics gain = 0.5, Vout at 0% = 8.0729
235  // coeficient = 100 / 8.0729 = 12.3871
236  /****************************************************************************/
238  {
239  return(100.0 + (volts * -12.3871)) ;
240  } // double convert_GEPLHe19_volts_to_percent(double volts)
241 
242  /****************************************************************************/
243  /****************************************************************************/
244  // convert_GEPLHe23_volts_to_percent
245  // 23" (584.2mm) Active Length * 45 ohm / mm = 265.811 ohms total at 0%
246  // Excitation current = 73.53 mA, V=19.5449
247  // Electronics gain = 0.5, Vout at 0% = 9.77246
248  // coeficient = 100 / 9.77246 = 10.2328
249  /****************************************************************************/
251  {
252  return(100.0 + (volts * -10.2328)) ;
253  } // double convert_GEPLHe23_volts_to_percent(double volts)
254 
255  /****************************************************************************/
256  // convert_volts_to_Pres_PSI_0-500
257  // This routine is called when the tag PSI-500 is used in the Chan Config file
259  // Converts presssure sensor with 4 to 20 mA output and 500 PSI range
260  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
261  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
262  // our sense voltage capabilities
263  // Excitation = 12VDC.
264  // 4mA = 0.1996V = 0 PSI
265  // 20mA = 0.9980V = 500PSI
266  // PSI/V = 500PSI/0.7984 = 626.2525
267  // Volt_Zero_Offset = 0.1996V
268  /****************************************************************************/
269  double convert_v_to_Pres_PSI_0_500(double volts)
270  {
271  double dPSI;
272 
273  if ( volts < 0.1 )
274  // clip value to -10PSI if out of range e.g.sensor faulty
275  return -10.0 ;
276 
277  else if ( volts > 1.8 )
278  // clip value to 1000PSI if out of range e.g.sensor unplugged
279  return 1000 ;
280 
281  dPSI = (volts - 0.1996) * 626.2525 ;
282 
283  //Should there be an error condition??
284  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
285  return dPSI;
286  } // double convert_v_to_Pres_PSI_0_500(double volts)
287 
288  /****************************************************************************/
289  // convert_volts_to_Pres_PSI_0-3000
290  // This routine is called when the tag PSI-3000 is used in the Chan Config file
292  // Converts presssure sensor with 4 to 20 mA output and 3000 PSI range
293  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
294  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
295  // our sense voltage capabilities
296  // Excitation = 12VDC.
297  // 4mA = 0.1996V = 0 PSI
298  // 20mA = 0.9980V = 3000PSI
299  // PSI/V = 3000PSI/0.7984 = 3757.5150
300  // Volt_Zero_Offset = 0.1996V
301  /****************************************************************************/
302  double convert_v_to_Pres_PSI_0_3000(double volts)
303  {
304  double dPSI;
305 
306  if ( volts < 0.1 )
307  // clip value to -400PSI if out of range e.g.sensor faulty
308  return -400.0 ;
309 
310  else if ( volts > 1.8 )
311  // clip value to 6000PSI if out of range e.g.sensor unplugged
312  return 6000 ;
313 
314  dPSI = (volts - 0.1996) * 3757.5150 ;
315 
316  //Should there be an error condition??
317  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
318  return dPSI;
319  } // double convert_v_to_Pres_PSI_0_3000(double volts)
320 
321  /****************************************************************************/
322  // convert_volts_to_Pres_KPa_0-3447
323  // This routine is called when the tag KPa-3447 is used in the Chan Config file
324  // THIS IS FOR THE 500PSI SENSOR
326  // Converts presssure sensor with 4 to 20 mA output and 3000 PSI range
327  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
328  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
329  // our sense voltage capabilities
330  // Excitation = 12VDC.
331  // 4mA = 0.1996V = 0 KPa
332  // 20mA = 0.9980V = 3447.37864KPa
333  // KPa/V = 3447.37864KPa/0.7984 = 4317.8590
334  // Volt_Zero_Offset = 0.1996V
335  /****************************************************************************/
336  double convert_v_to_Pres_KPa_0_3447(double volts)
337  {
338  double KPa;
339 
340  if ( volts < 0.1 )
341  // clip value to -450KPa if out of range e.g.sensor faulty
342  return -450.0 ;
343 
344  else if ( volts > 1.8 )
345  // clip value to 7000KPa if out of range e.g.sensor unplugged
346  return 7000 ;
347 
348  KPa = (volts - 0.1996) * 4317.8590 ;
349 
350  //Should there be an error condition??
351  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
352  return KPa;
353  } // double convert_v_to_Pres_KPa_0_3447(double volts)
354 
355  /****************************************************************************/
356  // convert_volts_to_Pres_KPa_0-20684
357  // This routine is called when the tag KPa-20684 is used in the Chan Config file
358  // THIS IS FOR THE 3000PSI SENSOR
360  // Converts presssure sensor with 4 to 20 mA output and 3000 PSI range
361  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
362  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
363  // our sense voltage capabilities
364  // Excitation = 12VDC.
365  // 4mA = 0.1996V = 0 KPa
366  // 20mA = 0.9980V = 20684.2718KPa
367  // KPa/V = 20684.2718KPa/0.7984 = 25907.154108
368  // Volt_Zero_Offset = 0.1996V
369  /****************************************************************************/
370  double convert_v_to_Pres_KPa_0_20684(double volts)
371  {
372  double KPa;
373 
374  if ( volts < 0.1 )
375  // clip value to -2700KPa if out of range e.g.sensor faulty
376  return -2700.0 ;
377 
378  else if ( volts > 1.8 )
379  // clip value to 42000KPa if out of range e.g.sensor unplugged
380  return 42000 ;
381 
382  KPa = (volts - 0.1996) * 25907.1541 ;
383 
384  //Should there be an error condition??
385  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
386  return KPa;
387  } // double convert_v_to_Pres_KPa_0_20684(double volts)
388 
389  // new 10/14/09 //kh
390  /****************************************************************************/
391  // convert_volts_to_Pres_PSI_0_2500
392  // This routine is called when the tag PSI-2500 is used in the Chan Config file
394  // Converts presssure sensor with 4 to 20 mA output and 2500 PSI range
395  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
396  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
397  // our sense voltage capabilities
398  // Excitation = 12VDC.
399  // 4mA = 0.1996V = 0 PSI
400  // 20mA = 0.9980V = 2500PSI
401  // voltage span = Vmax - Vzero = .9980V - .1996V = .7984V
402  // PSI/V = 2500PSI/0.7984 = 3131.263 PSI/volt
403  // Volt_Zero_Offset = 0.1996V
404  /****************************************************************************/
405  double convert_v_to_Pres_PSI_0_2500(double volts)
406  {
407  double dPSI;
408 
409  if ( volts < 0.1 )
410  // clip value to -400PSI if out of range e.g.sensor faulty
411  return -400.0 ;
412 
413  else if ( volts > 1.8 )
414  // clip value to 6000PSI if out of range e.g.sensor unplugged
415  return 6000 ;
416 
417  dPSI = (volts - 0.1996) * 3131.263 ;
418 
419  //Should there be an error condition??
420  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
421  return dPSI;
422  } // double convert_v_to_Pres_PSI_0_2500(double volts)
423 
424  /****************************************************************************/
425  // convert_volts_to_Pres_KPa_0_17236
426  // This routine is called when the tag KPa-17236 is used in the Chan Config file
427  // THIS IS FOR THE 2500PSI SENSOR
429  // Converts presssure sensor with 4 to 20 mA output and 2500 PSI range
430  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
431  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
432  // our sense voltage capabilities
433  // Excitation = 12VDC.
434  // 4mA = 0.1996V = 0 KPa
435  // 20mA = 0.9980V = 17236.8932KPa
436  // voltage span = Vmax - Vzero = .9980V - .1996V = .7984V
437  // KPa/V = 17236.8932KPa/0.7984 = 21589.29509
438  // Volt_Zero_Offset = 0.1996V
439  /****************************************************************************/
440  double convert_v_to_Pres_KPa_0_17236(double volts)
441  {
442  double KPa;
443 
444  if ( volts < 0.1 )
445  // clip value to -2700KPa if out of range e.g.sensor faulty
446  return -2700.0 ;
447 
448  else if ( volts > 1.8 )
449  // clip value to 42000KPa if out of range e.g.sensor unplugged
450  return 42000 ;
451 
452  KPa = (volts - 0.1996) * 21589.295 ;
453 
454  //Should there be an error condition??
455  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
456  return KPa;
457  } // double convert_v_to_Pres_KPa_0_17236(double volts)
458 
459  /****************************************************************************/
460  // convert_volts_to_Pres_MPa_0_17236
461  // This routine is called when the tag MPa-17236 is used in the Chan Config file
462  // THIS IS FOR THE 2500PSI SENSOR
464  // Converts presssure sensor with 4 to 20 mA output and 2500 PSI range
465  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
466  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
467  // our sense voltage capabilities
468  // Excitation = 12VDC.
469  // 4mA = 0.1996V = 0 MPa
470  // 20mA = 0.9980V = 17.2368932MPa
471  // voltage span = Vmax - Vzero = .9980V - .1996V = .7984V
472  // MPa/V = 17.2368932MPa/0.7984V = 21.58929509 MPa/V
473  // Volt_Zero_Offset = 0.1996V
474  /****************************************************************************/
475  double convert_v_to_Pres_MPa_0_17236(double volts)
476  {
477  double MPa;
478 
479  if ( volts < 0.1 )
480  // clip value to -2.700MPa if out of range e.g.sensor faulty
481  return -2.7000 ;
482 
483  else if ( volts > 1.8 )
484  // clip value to 42.000MPa if out of range e.g.sensor unplugged
485  return 42.000 ;
486 
487  MPa = (volts - 0.1996) * 21.589295 ;
488 
489  //Should there be an error condition??
490  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
491  return MPa;
492  } // double convert_v_to_Pres_MPa_0_17236(double volts)
493 
494  /****************************************************************************/
495  // convert_volts_to_Pres_MPa_0_3447
496  // This routine is called when the tag MPa-3447 is used in the Chan Config file
497  // THIS IS FOR THE 500PSI SENSOR
499  // Converts presssure sensor with 4 to 20 mA output and 500 PSI range
500  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
501  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
502  // our sense voltage capabilities
503  // Excitation = 12VDC.
504  // 4mA = 0.1996V = 0 MPa
505  // 20mA = 0.9980V = 3.44738MPa
506  // voltage span = Vmax - Vzero = .9980V - .1996V = .7984V
507  // MPa/V = 3.44738MPa/0.7984 = 4.317859
508  // Volt_Zero_Offset = 0.1996V
509  /****************************************************************************/
510  double convert_v_to_Pres_MPa_0_3447(double volts)
511  {
512  double MPa;
513 
514  if ( volts < 0.1 )
515  // clip value to -4.50MPa if out of range e.g.sensor faulty
516  return -4.500 ;
517 
518  else if ( volts > 1.8 )
519  // clip value to 7.000MPa if out of range e.g.sensor unplugged
520  return 7.000 ;
521 
522  MPa = (volts - 0.1996) * 4.317859 ;
523 
524  //Should there be an error condition??
525  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
526  return MPa;
527  } // double convert_v_to_Pres_MPa_0_3447(double volts)
528 
529  /****************************************************************************/
530  // convert_volts_to_Pres_MPa_0_20684
531  // This routine is called when the tag MPa-20684 is used in the Chan Config file
532  // THIS IS FOR THE 3000PSI SENSOR
534  // Converts presssure sensor with 4 to 20 mA output and 3000 PSI range
535  // Voltage sense resistor in GEP3 remote PCB is 49.9 ohms
536  // NOTE: Can NOT use 499.9 ohm voltage sense resistor without exceeding
537  // our sense voltage capabilities
538  // Excitation = 12VDC.
539  // 4mA = 0.1996V = 0 MPa
540  // 20mA = 0.9980V = 20.6842718MPa
541  // MPa/V = 20684.2718MPa/0.7984V = 25.907154108 MPa/V
542  // Volt_Zero_Offset = 0.1996V
543  /****************************************************************************/
544  double convert_v_to_Pres_MPa_0_20684(double volts)
545  {
546  double MPa;
547 
548  if ( volts < 0.1 )
549  // clip value to -2.7MPa if out of range e.g.sensor faulty
550  return -2.7000 ;
551 
552  else if ( volts > 1.8 )
553  // clip value to 42.000MPa if out of range e.g.sensor unplugged
554  return 42.000 ;
555 
556  MPa = (volts - 0.1996) * 25.90715 ;
557 
558  //Should there be an error condition??
559  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
560  return MPa;
561  } // double convert_v_to_Pres_MPa_0_20684(double volts)
562 
563  /****************************************************************************/
564  // convert_volts_to_FAN16
565  // This routine is called with the tag FAN16
567  // Converts control voltage supplied to an amplifier powering external tree fans
568  // to %fan speed. Assumes min fan control voltage acceptable is 1.6V=16% (hence FAN16)
569  // NOTE: The fans should NOT be turned off completely, in their "off" state they are kept
570  // idiling to prevent stall and burnout.
571  // To accomplish this, the Newport controller (I16D)is programmed to supply a minimum
572  // 16% * 10 V = 1.6 volts at the output of out-1
573  // 1.6V = 0%
574  // 9.9V = 100%
575  // voltage span = Vmax - Vzero = 9.9V - 1.6V = 8.3V
576  // %/V = 100%/8.3V = 12.04819 %/volt
577  // Volt_Zero_Offset = 1.60V
578  /****************************************************************************/
579  double convert_v_to_FAN16(double volts)
580  {
581  double dFanPercent;
582 
583  if ( volts < 1.6 ) // clip value to 0%
584  return 0 ;
585 
586  else if ( volts > 9.9 ) // clip value to 100%
587  return 100 ;
588 
589  dFanPercent = (volts - 1.6) * 12.04819 ;
590 
591  //Should there be an error condition??
592  //if ( x <= -1.0 || x >= 1.0 ) x = 0 ; /* error condition */
593  return dFanPercent;
594  } // double convert_v_to_FAN16(double volts)
595 
596  /*----------------------------------------------------------------------*/
597 
599  // convert_to_display_units
601  double convert_to_display_units(const Econversion& ConvCode,
602  const double& chanval)
603  {
604  double retval, V, Vcor;
605 
606  switch (ConvCode)
607  {
608  case datrw::tsoft::SIDIODE:
609  case datrw::tsoft::SIDIODE1:
610  retval = convert_sidiode_volts_to_kelvin(chanval);
611  break;
612  case datrw::tsoft::PT100:
613  retval = convert_pt100_ohms_to_celsius(chanval);
614  break;
615  case datrw::tsoft::PT100V:
616  // changed from 1000 to 100 4/23/08 for rev3 pcb
617  retval = convert_pt100_ohms_to_celsius(100.0 * chanval);
618  break;
619  case datrw::tsoft::PT100_K: // Added 8/02 per eb
620  retval = convert_pt100_ohms_to_Kelvin(chanval);
621  break;
622  case datrw::tsoft::PT100V_K: // Added 8/02 per eb
623  // changed from 1000 to 100 4/23/08 for rev3 pcb
624  retval = convert_pt100_ohms_to_Kelvin(100.0 * chanval);
625  break;
626  case datrw::tsoft::PSI_1_1: // Added 11/05 per eb
627  retval = convert_volts_to_psi( chanval);
628  break;
629  case datrw::tsoft::GEPLHe19: // Added 11/05 per eb
630  retval = convert_GEPLHe19_volts_to_percent( chanval);
631  break;
632  case datrw::tsoft::GEPLHe23: // Added 8/07 per eb
633  retval = convert_GEPLHe23_volts_to_percent( chanval);
634  break;
635  case datrw::tsoft::TD:
636  retval = convert_td_ohms_to_celsius(chanval);
637  break;
638  case datrw::tsoft::TDV:
639  retval = convert_td_ohms_to_celsius(1000.0 * chanval);
640  break;
641  case datrw::tsoft::MASFLO1:
642  // Mass Airflow Sensor Manufactured by Microswitch, Model #AWM3100V
643  // Equation from Bruno Meurers 3rd degree polynomial fit using data
644  // from manufacturers data sheet flow =
645  // -39.35+(48.390*voltage)-(11.737*voltage^2)+(2.3064*voltage^3)
646  V = chanval;
647  retval = ( -39.35 + (48.390 * V) - (11.737 * V * V) + (2.3064 * V * V * V) ) ;
648  break;
649  //else if( coeff == MASFLO1:
650  //{
651  // retval = chanval;
652  // break;
653  case datrw::tsoft::H2OFLO1:
654  retval = chanval;
655  break;
656  case datrw::tsoft::SIDIODE2:
657  //non-magnetic sensor raw voltage no gain from scanner
658  Vcor = chanval ;
659  if ( Vcor > 1.25 ) { Vcor = chanval - (0.2363 * ( chanval - 1.25 )); }
660  // removed /4.98 8/02 per eb
662  break;
663  case datrw::tsoft::SIDIODE3:
664  // voltage with 4.98x amp from gep aux pcb
665  Vcor = chanval/4.98 ;
666  retval = convert_sidiode_volts_to_kelvin(Vcor);
667  break;
668  case datrw::tsoft::SIDIODE4:
669  //non-magnetic sensor with 4.98x amp from gep aux pcb
670  Vcor = chanval/4.98 ;
671  if ( Vcor > 1.25) { Vcor = Vcor - (0.2363 * ( Vcor - 1.25 )); }
673  break;
674  case datrw::tsoft::POWERV:
675  if ( chanval < 0.0)
676  { retval = 0.0 ; } /* changed 6/06 per Eric */
677  else
678  { retval = chanval * chanval; } /* power = volts^2 */
679  break;
680  case datrw::tsoft::PSI_500:
681  retval = convert_v_to_Pres_PSI_0_500(chanval);
682  break;
683  case datrw::tsoft::PSI_3000:
684  retval = convert_v_to_Pres_PSI_0_3000(chanval);
685  break;
686  case datrw::tsoft::KPA_3447:
687  retval = convert_v_to_Pres_KPa_0_3447(chanval);
688  break;
689  case datrw::tsoft::KPA_20684:
690  retval = convert_v_to_Pres_KPa_0_20684(chanval);
691  break;
692  case datrw::tsoft::PSI_2500:
693  retval = convert_v_to_Pres_PSI_0_2500(chanval);
694  break;
695  case datrw::tsoft::KPA_17236:
696  retval = convert_v_to_Pres_KPa_0_17236(chanval);
697  break;
698  case datrw::tsoft::MPA_17236:
699  retval = convert_v_to_Pres_MPa_0_17236(chanval);
700  break;
701  case datrw::tsoft::MPA_3447:
702  retval = convert_v_to_Pres_MPa_0_3447(chanval);
703  break;
704  case datrw::tsoft::MPA_20684:
705  retval = convert_v_to_Pres_MPa_0_20684(chanval);
706  break;
707  case datrw::tsoft::FAN16:
708  retval = convert_v_to_FAN16(chanval);
709  break;
710  case datrw::tsoft::C20P4:
711  retval = chanval * 20.4;
712  break;
713  case datrw::tsoft::CNSP:
714  case datrw::tsoft::CNFD:
715  retval = chanval;
716  break;
717  default:
718  std::cerr << "WARNING: \n"
719  << " unknown channel conversion code: " << ConvCode << "\n";
720  retval = chanval;
721  }
722 
723  return retval;
724  } // double convert_to_display_units(const Econversion& ConvCode,
725  // const double& chanval)
726 
727  /*----------------------------------------------------------------------*/
728 
730  // conversion code
732  std::string conversion_code(const Econversion& ConvCode)
733  {
734  switch (ConvCode)
735  {
736  case datrw::tsoft::SIDIODE:
737  return "SIDIODE"; break;
738  case datrw::tsoft::SIDIODE1:
739  return "SIDIODE1"; break;
740  case datrw::tsoft::PT100:
741  return "PT100"; break;
742  case datrw::tsoft::PT100V:
743  return "PT100V"; break;
744  case datrw::tsoft::PT100_K:
745  return "PT100_K"; break;
746  case datrw::tsoft::PT100V_K:
747  return "PT100V_K"; break;
748  case datrw::tsoft::PSI_1_1:
749  return "PSI_1_1"; break;
750  case datrw::tsoft::GEPLHe19:
751  return "GEPLHe19"; break;
752  case datrw::tsoft::GEPLHe23:
753  return "GEPLHe23"; break;
754  case datrw::tsoft::TD:
755  return "TD"; break;
756  case datrw::tsoft::TDV:
757  return "TDV"; break;
758  case datrw::tsoft::MASFLO1:
759  return "MASFLO1"; break;
760  case datrw::tsoft::H2OFLO1:
761  return "H2OFLO1"; break;
762  case datrw::tsoft::SIDIODE2:
763  return "SIDIODE2"; break;
764  case datrw::tsoft::SIDIODE3:
765  return "SIDIODE3"; break;
766  case datrw::tsoft::SIDIODE4:
767  return "SIDIODE4"; break;
768  case datrw::tsoft::POWERV:
769  return "POWERV"; break;
770  case datrw::tsoft::PSI_500:
771  return "PSI_500"; break;
772  case datrw::tsoft::PSI_3000:
773  return "PSI_3000"; break;
774  case datrw::tsoft::KPA_3447:
775  return "KPA_3447"; break;
776  case datrw::tsoft::KPA_20684:
777  return "KPA_20684"; break;
778  case datrw::tsoft::PSI_2500:
779  return "PSI_2500"; break;
780  case datrw::tsoft::KPA_17236:
781  return "KPA_17236"; break;
782  case datrw::tsoft::MPA_17236:
783  return "MPA_17236"; break;
784  case datrw::tsoft::MPA_3447:
785  return "MPA_3447"; break;
786  case datrw::tsoft::MPA_20684:
787  return "MPA_20684"; break;
788  case datrw::tsoft::FAN16:
789  return "FAN16"; break;
790  case datrw::tsoft::C20P4:
791  return "C20P4"; break;
792  case datrw::tsoft::CNSP:
793  return "CNSP"; break;
794  case datrw::tsoft::CNFD:
795  return "not found"; break;
796  default:
797  return "unknown"; break;
798  }
799 
800  return "unknown";
801  } // std::string conversion_code(const Econversion& ConvCode)
802 
803 } // namespace DDAS3
804 
805 /*======================================================================*/
806 
807 using std::cout;
808 using std::cerr;
809 using std::endl;
810 
811 int main(int iargc, char* argv[])
812 {
813 
814  // define usage information
815  char usage_text[]=
816  {
817  SIGSCALE_VERSION "\n"
818  "usage: sigscale [-v] [-o] [-itype type] [-otype type]" "\n"
819  " outfile infile [t:T] [f:F] [infile [t:T] [f:F] ... ]" "\n"
820  " or: sigscale --help|-h" "\n"
821  " or: sigscale --xhelp" "\n"
822  };
823 
824  // define full help text
825  char help_text[]=
826  {
827  "outfile name of output file" "\n"
828  "infile name of input file" "\n"
829  " t:T select traces T, where T may be any range" "\n"
830  " specification like \'3-4\' or \'5,6,7-12,20\'" "\n"
831  " f:F specifies an input file format differing from" "\n"
832  " the format selected by \"-type\"" "\n"
833  "\n"
834  "-xhelp print detailed information regarding file formats" "\n"
835  "-v be verbose" "\n"
836  "-DEBUG produce debug output" "\n"
837  "-DEBREP report internal scaling values for debugging" "\n"
838  "-o overwrite output" "\n"
839  "-itype type choose input file format (default: sff)" "\n"
840  "-otype type choose output file format (default: sff)" "\n"
841  "\n"
842  "This program is designed for auxilliary data from superconduction\n"
843  "gravimeter SG056 at BFO. It uses scling relations provided by GWR\n"
844  "to convert sample values to meaningful physical units."
845  };
846 
847  // define commandline options
848  using namespace tfxx::cmdline;
849  static Declare options[]=
850  {
851  // 0: print help
852  {"help",arg_no,"-"},
853  // 1: verbose mode
854  {"v",arg_no,"-"},
855  // 2: overwrite mode
856  {"o",arg_no,"-"},
857  // 3: input file format
858  {"itype",arg_yes,"sff"},
859  // 4: output file format
860  {"otype",arg_yes,"sff"},
861  // 5: generate debug output
862  {"DEBUG",arg_no,"-"},
863  // 6: output file format
864  {"xhelp",arg_no,"-"},
865  // 7: generate debug output
866  {"DEBREP",arg_no,"-"},
867  {NULL}
868  };
869 
870  // file specific keys
871  static const char tracekey[]="t";
872  static const char formatkey[]="f";
873 
874  // define commandline argument modifier keys
875  static const char* cmdlinekeys[]
876  ={tracekey, formatkey, 0};
877 
878  // no arguments? print usage...
879  if (iargc<2)
880  {
881  cerr << usage_text << endl;
882  cerr << tfxx::seitosh::repository_reference << endl;
883  exit(0);
884  }
885 
886  // collect options from commandline
887  Commandline cmdline(iargc, argv, options);
888 
889  // help requested? print full help text...
890  if (cmdline.optset(0))
891  {
892  cerr << usage_text << endl;
893  cerr << help_text << endl;
894  datrw::supported_data_types(cerr);
895  cerr << endl << tfxx::seitosh::repository_reference << endl;
896  exit(0);
897  }
898 
899  // help on file format details requested?
900  if (cmdline.optset(6))
901  {
902  cerr << usage_text << endl;
903  cerr << endl;
904  datrw::online_help(cerr);
905  cerr << endl << tfxx::seitosh::repository_reference << endl;
906  exit(0);
907  }
908  // extract commandline options
909  Options opt;
910  opt.verbose=cmdline.optset(1);
911  opt.overwrite=cmdline.optset(2);
912  opt.inputformat=cmdline.string_arg(3);
913  opt.outputformat=cmdline.string_arg(4);
914  opt.debug=cmdline.optset(5);
915  // 6 is --xhelp
916  opt.debrep=cmdline.optset(7);
917 
918  /*======================================================================*/
919 
920  if (opt.debrep) {
921  cout << SIGSCALE_VERSION << endl;
922 
927  exit(2);
928  }
929 
930  /*======================================================================*/
931 
932  if (opt.verbose)
933  { cout << SIGSCALE_VERSION << endl; }
934 
935  // extract commandline arguments
936  TFXX_assert(cmdline.extra(), "missing output file");
937  std::string outfile=cmdline.next();
938  TFXX_assert(cmdline.extra(), "missing input file");
939  tfxx::cmdline::Tparsed arguments=parse_cmdline(cmdline, cmdlinekeys);
940  if ((arguments.size()>1) && opt.verbose)
941  {
942  cout << "NOTICE: file specific information (SRCE line and file FREE)" <<
943  endl
944  << " will be taken from first file only!" << endl;
945  }
946 
947  /*======================================================================*/
948  // start processing
949 
950  // open output file
951  // ----------------
952  if (opt.verbose) { cout << "open output file " << outfile << endl; }
953  // check if output file exists and open
954  if (!opt.overwrite)
955  {
956  std::ifstream file(outfile.c_str(),std::ios_base::in);
957  TFXX_assert((!file.good()),"ERROR: output file exists!");
958  }
959  std::ios_base::openmode oopenmode
960  =datrw::oanystream::openmode(opt.outputformat);
961  std::ofstream ofs(outfile.c_str(), oopenmode);
962  datrw::oanystream os(ofs, opt.outputformat, opt.debug);
963 
964  // set flag to process header of first input file
965  bool firstfile=true;
966  // cycle through all input files
967  // -----------------------------
968  tfxx::cmdline::Tparsed::const_iterator infile=arguments.begin();
969  while (infile != arguments.end())
970  {
971  // open input file
972  if (opt.verbose) { cout << "open input file " << infile->name << endl; }
973  std::string inputformat=opt.inputformat;
974  if (infile->haskey(formatkey))
975  {
976  inputformat=infile->value(formatkey);
977  }
978  std::ios_base::openmode iopenmode
979  =datrw::ianystream::openmode(inputformat);
980  std::ifstream ifs(infile->name.c_str(), iopenmode);
981  datrw::ianystream is(ifs, inputformat);
982 
983  // handle file header
984  // ------------------
985  sff::FREE filefree;
986  if (firstfile)
987  {
988  if (is.hasfree())
989  {
990  sff::FREE infilefree;
991  is >> infilefree;
992  filefree.append("block read from first input file:");
993  filefree.append(infilefree);
994  }
995  if (os.handlesfilefree()) { os << filefree; }
996  if (is.hassrce())
997  {
998  sff::SRCE insrceline;
999  is >> insrceline;
1000  if (os.handlessrce()) { os << insrceline; }
1001  }
1002  }
1003 
1004  // cycle through traces of input file
1005  // ----------------------------------
1006  // setup trace selection
1007  typedef tfxx::RangeList<int> Trangelist;
1008  bool doselect=infile->haskey(tracekey);
1009  Trangelist traceranges=
1010  tfxx::string::rangelist<Trangelist::Tvalue>(infile->value(tracekey));
1011  int itrace=0;
1012  while (is.good())
1013  {
1014  ++itrace;
1015  if ((!doselect) || traceranges.contains(itrace))
1016  {
1017  TFXX_debug(opt.debug, "main", "process trace #" << itrace );
1018  if (opt.verbose)
1019  { std::cout << " process trace #" << itrace << ":"; }
1020  Tseries series;
1021  is >> series;
1022 
1023  sff::WID2 wid2;
1024  is >> wid2;
1025  TFXX_debug(opt.debug, "main",
1026  " series and WID2 are read");
1027  sff::INFO info;
1028  if (is.hasinfo())
1029  {
1030  is >> info;
1031  }
1032 
1033  /*----------------------------------------------------------------------*/
1034  // apply scaling
1035  ChannelDescription CD;
1036  SFFchannelid sid;
1037  sid.station=wid2.station;
1038  sid.channel=wid2.channel;
1039  sid.instrument=wid2.instype;
1040  sid.auxid=wid2.auxid;
1041  CD=channel(sid);
1042 
1043  std::string CCstring=DDAS3::conversion_code(CD.cc);
1044 
1045  aff::Iterator<Tseries> I(series);
1046  while (I.valid())
1047  {
1048  Tseries::Tvalue v= *I;
1049  *I = DDAS3::convert_to_display_units(CD.cc, v);
1050  ++I;
1051  }
1052 
1053  /*----------------------------------------------------------------------*/
1054 
1055  os << wid2;
1056  TFXX_debug(opt.debug, "main",
1057  " series and WID are written");
1058  if (is.hasinfo())
1059  {
1060  if (os.handlesinfo()) { os << info; }
1061  }
1062  if (is.hasfree() || true)
1063  {
1064  sff::FREE tracefree;
1065  is >> tracefree;
1066  tracefree.append(SIGSCALE_VERSION);
1067  tracefree.append("read from file " + infile->name);
1068  tracefree.append("applied scaling for conversion code \""
1069  + CCstring +"\"");
1070  if (os.handlestracefree()) { os << tracefree; }
1071  }
1072  TFXX_debug(opt.debug, "main",
1073  "trace #" << itrace << " successfully processed");
1074  os << series;
1075  }
1076  else
1077  {
1078  TFXX_debug(opt.debug, "main", "skip trace #" << itrace );
1079  if (opt.verbose)
1080  { std::cout << " skip trace #" << itrace << std::endl; }
1081  is.skipseries();
1082  }
1083  }
1084 
1085  // go to next file
1086  firstfile=false;
1087  ++infile;
1088  }
1089 }
1090 
1091 /* ----- END OF sigscale.cc ----- */
double convert_v_to_Pres_KPa_0_3447(double volts)
Definition: sigscale.cc:336
double convert_v_to_Pres_MPa_0_3447(double volts)
Definition: sigscale.cc:510
double convert_pt100_ohms_to_Kelvin(double ohms)
Definition: sigscale.cc:118
int main(int iargc, char *argv[])
Definition: sigscale.cc:811
double convert_pt100_ohms_to_celsius(double ohms)
Definition: sigscale.cc:110
double convert_v_to_Pres_MPa_0_20684(double volts)
Definition: sigscale.cc:544
const int ND[4]
Definition: sigscale.cc:84
double convert_td_ohms_to_celsius(double ohms)
Definition: sigscale.cc:134
double convert_sidiode_volts_to_kelvin_with_correction(double volts)
Definition: sigscale.cc:192
#define SIGSCALE_VERSION
Definition: sigscale.cc:35
std::string inputformat
Definition: cross.cc:75
const double A[4][12]
Definition: sigscale.cc:85
aff::Series< double > Tseries
Definition: sigscale.cc:62
double convert_volts_to_psi(double volts)
Definition: sigscale.cc:126
double convert_v_to_Pres_KPa_0_17236(double volts)
Definition: sigscale.cc:440
static const char * cmdlinekeys[]
Definition: fidasexx.cc:131
double Tvalue
Definition: fidasexx.cc:136
#define TRANGE_24K
Definition: sigscale.cc:97
const double VU[4]
Definition: sigscale.cc:83
static const char formatkey[]
Definition: fidasexx.cc:128
bool overwrite
Definition: autocorr.cc:61
std::string outputformat
Definition: cross.cc:75
double convert_sidiode_volts_to_kelvin(double volts)
Definition: sigscale.cc:153
bool debug
Definition: autocorr.cc:61
double convert_v_to_FAN16(double volts)
Definition: sigscale.cc:579
double convert_to_display_units(const Econversion &ConvCode, const double &chanval)
Definition: sigscale.cc:601
double convert_v_to_Pres_PSI_0_3000(double volts)
Definition: sigscale.cc:302
bool verbose
Definition: autocorr.cc:61
std::string conversion_code(const Econversion &ConvCode)
Definition: sigscale.cc:732
void report_sidiode_table(int range)
Definition: sigscale.cc:101
#define TRANGE_475K
Definition: sigscale.cc:99
const double VL[4]
Definition: sigscale.cc:82
double convert_GEPLHe19_volts_to_percent(double volts)
Definition: sigscale.cc:237
const char *const tracekey
key to select traces
Definition: deconv.cc:68
bool debrep
Definition: sigscale.cc:67
#define TRANGE_100K
Definition: sigscale.cc:98
#define TRANGE_12K
Definition: sigscale.cc:96
double convert_v_to_Pres_PSI_0_500(double volts)
Definition: sigscale.cc:269
double convert_v_to_Pres_MPa_0_17236(double volts)
Definition: sigscale.cc:475
double convert_v_to_Pres_PSI_0_2500(double volts)
Definition: sigscale.cc:405
aff::Series< double > Tseries
Definition: cross.cc:69
double convert_v_to_Pres_KPa_0_20684(double volts)
Definition: sigscale.cc:370
double convert_GEPLHe23_volts_to_percent(double volts)
Definition: sigscale.cc:250