USGS

Isis 3.0 Application Source Code Reference

Home

HiCalUtil.h
Go to the documentation of this file.
1 #ifndef HiCalUtil_h
2 #define HiCalUtil_h
3 /**
4  * @file
5  * $Revision: 5059 $
6  * $Date: 2013-03-11 09:37:00 -0700 (Mon, 11 Mar 2013) $
7  *
8  * Unless noted otherwise, the portions of Isis written by the USGS are
9  * public domain. See individual third-party library and package descriptions
10  * for intellectual property information, user agreements, and related
11  * information.
12  *
13  * Although Isis has been used by the USGS, no warranty, expressed or
14  * implied, is made by the USGS as to the accuracy and functioning of such
15  * software and related material nor shall the fact of distribution
16  * constitute any such warranty, and no responsibility is assumed by the
17  * USGS in connection therewith.
18  *
19  * For additional information, launch
20  * $ISISROOT/doc//documents/Disclaimers/Disclaimers.html
21  * in a browser or see the Privacy & Disclaimers page on the Isis website,
22  * http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
23  * http://www.usgs.gov/privacy.html.
24  */
25 
26 #include <cmath>
27 #include <string>
28 #include <vector>
29 #include <iostream>
30 #include <sstream>
31 
32 #include "HiCalTypes.h"
33 #include "DbProfile.h"
34 #include "IString.h"
35 #include "Statistics.h"
36 #include "PvlKeyword.h"
37 #include "NumericalApproximation.h"
38 #include "FileName.h"
39 #include "Pvl.h"
40 #include "IException.h"
41 
42 namespace Isis {
43 
44  template <typename T> inline T MIN(const T &A, const T &B) {
45  if ( A < B ) { return (A); }
46  else { return (B); }
47  }
48 
49  template <typename T> inline T MAX(const T &A, const T &B) {
50  if ( A > B ) { return (A); }
51  else { return (B); }
52  }
53 
54 /**
55  * @brief Counts number of valid pixels in vector
56  * @param v Vector to inspect
57  * @return int Number valid pixels in vector
58  */
59 inline int ValidCount(const HiVector &v) {
60  int n = 0;
61  for (int i = 0 ; i < v.dim() ; i++) {
62  if (!IsSpecial(v[i])) n++;
63  }
64  return (n);
65 }
66 
67 /**
68  * @brief Counts number of invalid pixels in vector
69  * @param v Vector to inspect
70  * @return int Number invalid (special) pixels in vector
71  */
72 inline int InValidCount(const HiVector &v) {
73  int n = 0;
74  for (int i = 0 ; i < v.dim() ; i++) {
75  if (IsSpecial(v[i])) n++;
76  }
77  return (n);
78 }
79 
80 /**
81  * @brief Convert HiRISE Cpmm number to Ccd number
82  *
83  * @param cpmm Cpmm number
84  */
85 inline int CpmmToCcd(int cpmm) {
86  const int cpmm2ccd[] = {0,1,2,3,12,4,10,11,5,13,6,7,8,9};
87  if ( (cpmm < 0) || (cpmm >= (int)(sizeof(cpmm2ccd)/sizeof(int))) ) {
88  QString mess = "CpmmToCdd: Bad CpmmNumber (" + toString(cpmm) + ")";
89  throw IException(IException::User, mess, _FILEINFO_);
90  }
91  return (cpmm2ccd[cpmm]);
92 }
93 
94 
95 /**
96  * @brief Convert HiRISE Ccd number to string filter name
97  *
98  * @param ccd Ccd number of device
99  */
100 inline QString CcdToFilter(int ccd) {
101  if ( (ccd < 0) || (ccd > 13) ) {
102  QString mess = "CcdToFilter: Bad Ccd Number (" + QString(ccd) + ")";
103  throw IException(IException::User, mess, _FILEINFO_);
104  }
105 
106  QString filter;
107  if ( ccd <= 9 ) { filter = "RED"; }
108  else if (ccd <= 11) { filter = "IR"; }
109  else { filter = "BG"; }
110  return (filter);
111 }
112 
113 /**
114  * @brief Crop specified lines from a buffer
115  *
116  * This function extracts lines from a buffer and returns a new buffer with the
117  * extracted lines.
118  *
119  * @param m Buffer to extract lines from
120  * @param sline Starting line number (first line is 0)
121  * @param eline Last line to extract
122  *
123  * @return HiMatrix Buffer containing cropped lines
124  */
125 inline HiMatrix cropLines(const HiMatrix &m, int sline, int eline) {
126  int nlines(eline-sline+1);
127  HiMatrix mcrop(nlines, m.dim2());
128  for (int l = 0 ; l < nlines ; l++) {
129  for (int s = 0 ; s < m.dim2() ; s++) {
130  mcrop[l][s] = m[l+sline][s];
131  }
132  }
133  return (mcrop);
134 }
135 
136 /**
137  * @brief Crop specified samples from a buffer
138  *
139  * This function extracts samples from a buffer and returns a new buffer with
140  * the extracted samples.
141  *
142  * @param m Buffer to extract samples from
143  * @param ssamp Startling sample (first sample 0)
144  * @param esamp Ending sample to extract
145  *
146  * @return HiMatrix Buffer with cropped samples
147  */
148 inline HiMatrix cropSamples(const HiMatrix &m, int ssamp, int esamp) {
149  int nsamps(esamp-ssamp+1);
150  HiMatrix mcrop(m.dim1(), nsamps);
151  for (int l = 0 ; l < m.dim1() ; l++) {
152  for (int s = 0 ; s < nsamps ; s++) {
153  mcrop[l][s] = m[l][s+ssamp];
154  }
155  }
156  return (mcrop);
157 }
158 
159 /**
160  * @brief Reduces by averaging specified lines from a buffer
161  *
162  * This function produces a vector from a 2-D buffer of averaged lines at each
163  * vertical sample location
164  *
165  * @param m Buffer to reduce
166  * @param sline Starting line number (first line is 0)
167  * @param eline Last line to average (-1 means use all lines)
168  *
169  * @return HiVector Buffer containing averaged lines
170  */
171 inline HiVector averageLines(const HiMatrix &m, int sline = 0, int eline = -1) {
172  eline = (eline == -1) ? m.dim1() - 1 : eline;
173  HiVector v(m.dim2());
174  for (int s = 0 ; s < m.dim2() ; s++) {
175  Statistics stats;
176  for (int l = sline ; l <= eline ; l++) {
177  stats.AddData(&m[l][s], 1);
178  }
179  v[s] = stats.Average();
180  }
181  return (v);
182 }
183 
184 /**
185  * @brief Reduces by averaging specified samples from a buffer
186  *
187  * This function produces a vector from a 2-D buffer of averaged samples at each
188  * horizontal line location
189  *
190  * @param m Buffer to reduce
191  * @param ssamp Starting sample number (first sample is 0)
192  * @param esamp Last sample to average (-1 means use all samples)
193  *
194  * @return HiVector Buffer containing averaged samples
195  */
196 inline HiVector averageSamples(const HiMatrix &m, int ssamp = 0,
197  int esamp = -1) {
198  esamp = (esamp == -1) ? m.dim2() - 1 : esamp;
199  HiVector v(m.dim1());
200  for (int l = 0 ; l < m.dim1() ; l++) {
201  Statistics stats;
202  for (int s = ssamp ; s <= esamp ; s++) {
203  stats.AddData(&m[l][s], 1);
204  }
205  v[l] = stats.Average();
206  }
207  return (v);
208 }
209 
210 /**
211  * @brief Find a keyword in a profile using default for non-existant keywords
212  *
213  * This template function will extract keyword values from a profile and provide
214  * the values at the indicated index. If the keyword does not exist or the
215  * indicated value at index, the provided default will be used instead.
216  *
217  */
218 template <typename T>
219  T ConfKey(const DbProfile &conf, const QString &keyname, const T &defval,
220  int index = 0) {
221  if (!conf.exists(keyname)) { return (defval); }
222  if (conf.count(keyname) < index) { return (defval); }
223  QString iValue(conf.value(keyname, index));
224  T value = iValue; // This makes it work with a string?
225  return (value);
226 }
227 
228 /**
229  * @brief Helper function to convert values to Integers
230  *
231  * @param T Type of value to convert
232  * @param value Value to convert
233  *
234  * @return int Converted value
235  */
236 template <typename T> int ToInteger(const T &value) {
237  return (QString(value).trimmed().toInt());
238 }
239 
240 /**
241  * @brief Helper function to convert values to doubles
242  *
243  * @param T Type of value to convert
244  * @param value Value to convert
245  *
246  * @return double Converted value
247  */
248 template <typename T> double ToDouble(const T &value) {
249  return (QString(value).trimmed().toDouble());
250 }
251 
252 /**
253  * @brief Helper function to convert values to strings
254  *
255  * @param T Type of value to convert
256  * @param value Value to convert
257  *
258  * @return string Converted value
259  */
260 template <typename T> QString ToString(const T &value) {
261  return (toString(value).trimmed());
262 }
263 
264 /**
265  * @brief Shortened string equality test
266  *
267  * @param v1 First value
268  * @param v2 Second value
269  *
270  * @return bool True if they are equal w/o regard to case
271  */
272 inline bool IsEqual(const QString &v1, const QString &v2 = "TRUE") {
273  return (v1.toUpper() == v2.toUpper());
274 }
275 
276 /**
277  * @brief Determines if the keyword value is the expected value
278  *
279  * This function checks the existance of a keyword in a profile, extracts the
280  * first value and tests it for equivelance to the expected value. Note this
281  * test is case insensitive.
282  *
283  * @param prof Profile to find the expected keyword in
284  * @param key Name of keyword in profile to test
285  * @param value Value to test for in keyword
286  *
287  * @return bool Returns true only if the keyword exists in the profile and it is
288  * the value expected.
289  */
290 inline bool IsTrueValue(const DbProfile &prof, const QString &key,
291  const QString &value = "TRUE") {
292  if ( prof.exists(key) ) {
293  return (IsEqual(prof(key), value));
294  }
295  return (false);
296 }
297 
298 /**
299  * @brief Checks profile flag to skip the current Module
300  *
301  * This function looks for the keyword \b Debug::SkipModule and checks its
302  * value. True is returned if the value is TRUE (case insensentive).
303  *
304  * @param prof Module profile from config file
305  *
306  * @return bool True if the value of the Debug::SkipModule keyword is TRUE,
307  * otherwise it returns false for all other values.
308  */
309 inline bool SkipModule(const DbProfile &prof) {
310  return (IsTrueValue(prof, "Debug::SkipModule", "TRUE"));
311 }
312 
313 
314 inline HiMatrix appendLines(const HiMatrix &top, const HiMatrix &bottom) {
315  // Ensure same number samples
316  if (top.dim2() != bottom.dim2()) {
317  std::ostringstream mess;
318  mess << "Top buffer samples (" << top.dim2()
319  << ") do not match bottom buffer samples (" << bottom.dim2()
320  << ")";
321  throw IException(IException::User, mess.str(), _FILEINFO_);
322  }
323 
324  int nlines(top.dim1()+bottom.dim1());
325  HiMatrix mat(nlines, top.dim2());
326  for (int lt = 0 ; lt < top.dim1() ; lt++) {
327  for (int s = 0 ; s < top.dim2() ; s++) {
328  mat[lt][s] = top[lt][s];
329  }
330  }
331 
332  int topl = top.dim1();
333  for (int lb = 0 ; lb < bottom.dim1() ; lb++) {
334  for (int s = 0 ; s < top.dim2() ; s++) {
335  mat[topl+lb][s] = bottom[lb][s];
336  }
337  }
338  return (mat);
339 }
340 
342  // Ensure same number samples
343  if (right.dim1() != right.dim1()) {
344  std::ostringstream mess;
345  mess << "Left buffer lines (" << left.dim1()
346  << ") do not match right buffer lines (" << right.dim1()
347  << ")";
348  throw IException(IException::User, mess.str(), _FILEINFO_);
349  }
350 
351  int nsamps(left.dim2()+right.dim2());
352  HiMatrix mat(left.dim1(), nsamps);
353  for (int ll = 0 ; ll < left.dim1() ; ll++) {
354  for (int s = 0 ; s < left.dim2() ; s++) {
355  mat[ll][s] = left[ll][s];
356  }
357  }
358 
359  int lefts = left.dim2();
360  for (int lr = 0 ; lr < right.dim1() ; lr++) {
361  for (int s = 0 ; s < right.dim2() ; s++) {
362  mat[lr][lefts+s] = right[lr][s];
363  }
364  }
365  return (mat);
366 }
367 
368 /**
369  * @brief Compute HiRISE line times
370  *
371  * This class will compute the time (in seconds) for a HiRISE observation line
372  * based upon the binning mode and line number. It is assumed that the first
373  * line will be time 0, but that is up to the caller to keep that straight.
374  *
375  * @author ????-??-?? Unknown
376  *
377  * @internal
378  */
380  public:
381  HiLineTimeEqn() : _bin(1), _ltime(1.0) { }
382  HiLineTimeEqn(int bin, double ltime) : _bin(bin), _ltime(ltime) { }
383  virtual ~HiLineTimeEqn() { }
384 
385  void setLineTime(double ltime) { _ltime = ltime; }
386  void setBin(int bin) { _bin = bin; }
387  double Time(const double line) const {
388  return (line * (_bin * _ltime * 1.0E-6));
389  }
390  double operator()(const double line) const { return (Time(line)); }
391 
392  private:
393  double _bin;
394  double _ltime;
395 };
396 
397 /**
398  * @brief Implements (classic) HiRISE temperature equation
399  *
400  * This function computes the dark current temperature and returns the results
401  * in electrons/sec/pixel.
402  *
403  * @param temperature Temperature (typically of the FPGA)
404  * @param napcm2 Dark current for silicone diodes (nano-ampres/cm^2)
405  * @param px Pixel size in microns
406  *
407  * @return double Dark current temperature (electrons/sec/pixel)
408  */
409 inline double HiTempEqn(const double temperature, const double napcm2 = 2.0,
410  const double px = 12.0) {
411  double temp = temperature + 273.0;
412  double eg = 1.1557 - (7.021E-4 * temp * temp) / (1108.0 + temp);
413  const double K = 1.38E-23;
414  const double Q = 1.6E-19;
415  return (napcm2*(px*px)*2.55E7*std::pow(temp,1.5)*std::exp(-eg*Q/2.0/K/temp));
416 }
417 
418 /**
419  * @brief Rebins a vector to a different size
420  *
421  * This function can rebin to both larger and smaller sizes. It fits the data
422  * to a cubic spline and then computes the value at the rebin pixel index. One
423  * advantage to this approach is that on input, special pixels are ignored - on
424  * output there will never be special pixels unless there are not enough points
425  * to conpute the cubic spline on which case this function throws an exception.
426  *
427  * @param v Input vector to rebin
428  * @param n Size of the new output vector
429  *
430  * @return HiVector
431  * @history 2008-11-05 Jeannie Walldren Replaced references to
432  * DataInterp class with NumericalApproximation.
433  */
434 inline HiVector rebin(const HiVector &v, int n) {
435  if ( n == v.dim() ) { return (v); }
436  NumericalApproximation nterp(NumericalApproximation::CubicNatural);
437  double mag((double) v.dim()/ (double) n);
438 
439  for ( int i = 0 ; i < v.dim() ; i++ ) {
440  double x((double) i);
441  if ( !IsSpecial(v[i]) ) {
442  nterp.AddData(x,v[i]);
443  }
444  }
445 
446  // Compute the spline and fill the output vector
447  HiVector vout(n);
448  for ( int j = 0 ; j < n ; j++ ) {
449  double x = (double) j * mag;
450  vout[j] = nterp.Evaluate(x, NumericalApproximation::NearestEndpoint);
451  }
452  return (vout);
453 }
454 
455 /**
456  * @brief Deletes HiRISE specific BLOBS from cube file
457  *
458  * Ths function removes only the HiRISE specific
459  *
460  * @param label Input label associated with file from which to remove the HiRISE
461  * blobs
462  */
463 inline void RemoveHiBlobs(Pvl &label) {
464  for ( int blob = 0 ; blob < label.objects() ; blob++ ) {
465  if ( label.object(blob).isNamed("Table") ) {
466  QString name = label.object(blob)["Name"][0];
467  if ( name.toLower() == "hirise calibration ancillary" ||
468  name.toLower() == "hirise calibration image" ||
469  name.toLower() == "hirise ancillary" ) {
470  label.deleteObject(blob);
471  blob--;
472  }
473  }
474  }
475  return;
476 }
477 
478 /**
479  * @brief Return the statistics for a vector of data
480  *
481  * The default statistic returned is the median of the dataset but can be
482  * changed with a compile time change. The vector passed in will be sorted so
483  * that the median can be determined. If the vector has an even number of
484  * elements in it, the average of the two center values will be returned. The
485  * array is assumed to be clean data, no ISIS special pixels.
486  *
487  * @param data Vector containing data compute the statistic. It will be
488  * altered (sorted) upon return to the caller.
489  *
490  * @return double The median (default) of the data
491  */
492 inline double GainLineStat(std::vector<double> &data) {
493 
494  // Check for special conditions
495  if (data.size() == 0) return (Null);
496  if (data.size() == 1) return (data[0]);
497 
498 #if defined(USE_AVERAGE)
499  Statistics stats;
500  stats.AddData(&data[0], data.size());
501  return (stat.Average());
502 #else
503  std::sort(data.begin(), data.end());
504  int meanIndex = data.size()/2;
505  if ((data.size() % 2) == 1) return data[meanIndex];
506  return ((data[meanIndex-1]+data[meanIndex])/2.0);
507 #endif
508 }
509 
510 }; // namespace Isis
511 #endif
uint8 left[]
Definition: pmain.cpp:64
HiVector averageLines(const HiMatrix &m, int sline=0, int eline=-1)
Reduces by averaging specified lines from a buffer.
Definition: HiCalUtil.h:171
double Time(const double line) const
Definition: HiCalUtil.h:387
Compute HiRISE line times.
Definition: HiCalUtil.h:379
T MIN(const T &A, const T &B)
Implement templatized MIN fumnction.
Definition: Hillier.h:38
void RemoveHiBlobs(Pvl &label)
Deletes HiRISE specific BLOBS from cube file.
Definition: HiCalUtil.h:463
HiMatrix appendLines(const HiMatrix &top, const HiMatrix &bottom)
Definition: HiCalUtil.h:314
bool SkipModule(const DbProfile &prof)
Checks profile flag to skip the current Module.
Definition: HiCalUtil.h:309
int x
Definition: butterworth.cpp:18
int bottom
Definition: trim.cpp:12
TNT::Array2D< double > HiMatrix
2-D buffer
Definition: HiCalTypes.h:39
void setLineTime(double ltime)
Definition: HiCalUtil.h:385
TNT::Array1D< double > HiVector
1-D Buffer
Definition: HiCalTypes.h:38
T ConfKey(const DbProfile &conf, const QString &keyname, const T &defval, int index=0)
Find a keyword in a profile using default for non-existant keywords.
Definition: HiCalUtil.h:219
int ToInteger(const T &value)
Helper function to convert values to Integers.
Definition: HiCalUtil.h:236
HiVector rebin(const HiVector &v, int n)
Rebins a vector to a different size.
Definition: HiCalUtil.h:434
int line
Definition: blend.cpp:120
T MAX(const T &A, const T &B)
Implement templatized MAX function.
Definition: Hillier.h:48
double GainLineStat(std::vector< double > &data)
Return the statistics for a vector of data.
Definition: HiCalUtil.h:492
HiVector averageSamples(const HiMatrix &m, int ssamp=0, int esamp=-1)
Reduces by averaging specified samples from a buffer.
Definition: HiCalUtil.h:196
double HiTempEqn(const double temperature, const double napcm2=2.0, const double px=12.0)
Implements (classic) HiRISE temperature equation.
Definition: HiCalUtil.h:409
int CpmmToCcd(int cpmm)
Convert HiRISE Cpmm number to Ccd number.
Definition: HiCalUtil.h:85
double operator()(const double line) const
Definition: HiCalUtil.h:390
QString ToString(const T &value)
Helper function to convert values to strings.
Definition: CamTools.cpp:94
int ValidCount(const HiVector &v)
Counts number of valid pixels in vector.
Definition: HiCalUtil.h:59
Statistics stats
Definition: cubediff.cpp:36
void setBin(int bin)
Definition: HiCalUtil.h:386
bool IsTrueValue(const DbProfile &prof, const QString &key, const QString &value="TRUE")
Determines if the keyword value is the expected value.
Definition: HiCalUtil.h:290
HiLineTimeEqn(int bin, double ltime)
Definition: HiCalUtil.h:382
bool IsEqual(const QString &v1, const QString &v2="TRUE")
Shortened string equality test.
Definition: HiCalUtil.h:272
float Q[64]
Definition: decomp.cpp:35
HiMatrix cropSamples(const HiMatrix &m, int ssamp, int esamp)
Crop specified samples from a buffer.
Definition: HiCalUtil.h:148
double ToDouble(const T &value)
Helper function to convert values to doubles.
Definition: CamTools.cpp:82
virtual ~HiLineTimeEqn()
Definition: HiCalUtil.h:383
QString CcdToFilter(int ccd)
Convert HiRISE Ccd number to string filter name.
Definition: HiCalUtil.h:100
HiMatrix cropLines(const HiMatrix &m, int sline, int eline)
Crop specified lines from a buffer.
Definition: HiCalUtil.h:125
double toDouble(const T &value)
Helper function to convert values to doubles.
Definition: MdisCalUtils.h:49
HiMatrix appendSamples(const HiMatrix &left, const HiMatrix &right)
Definition: HiCalUtil.h:341
int top
Definition: trim.cpp:12
void filter(Buffer &in, double &v)
The filter depends on the user input kernel.
Definition: kernfilter.cpp:71
uint8 right[]
Definition: pmain.cpp:65
int InValidCount(const HiVector &v)
Counts number of invalid pixels in vector.
Definition: HiCalUtil.h:72
bool trimmed
Definition: trimfilter.cpp:10