Isis 3.0 Application Source Code Reference |
Home |
00001 #ifndef ControlByRow_h 00002 #define ControlByRow_h 00003 /** 00004 * @file 00005 * $Revision: 1.2 $ 00006 * $Date: 2007/01/30 22:12:21 $ 00007 * 00008 * Unless noted otherwise, the portions of Isis written by the USGS are 00009 * public domain. See individual third-party library and package descriptions 00010 * for intellectual property information, user agreements, and related 00011 * information. 00012 * 00013 * Although Isis has been used by the USGS, no warranty, expressed or 00014 * implied, is made by the USGS as to the accuracy and functioning of such 00015 * software and related material nor shall the fact of distribution 00016 * constitute any such warranty, and no responsibility is assumed by the 00017 * USGS in connection therewith. 00018 * 00019 * For additional information, launch 00020 * $ISISROOT/doc//documents/Disclaimers/Disclaimers.html 00021 * in a browser or see the Privacy & Disclaimers page on the Isis website, 00022 * http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on 00023 * http://www.usgs.gov/privacy.html. 00024 */ 00025 00026 #include <vector> 00027 #include "ControlMeasure.h" 00028 #include "ControlMeasureLogData.h" 00029 #include "Statistics.h" 00030 #include "CollectorMap.h" 00031 #include "iString.h" 00032 #include <gsl/gsl_math.h> 00033 00034 namespace Isis { 00035 00036 /** 00037 * @brief Container for point collection 00038 */ 00039 struct PointData { 00040 ControlMeasure refPoint; 00041 ControlMeasure chpPoint; 00042 }; 00043 00044 /** 00045 * @brief Less than test for Control point group 00046 * 00047 * This function tests the reference line numbers and returns true if the first 00048 * point reference line is less than the second. 00049 * 00050 * @param p1 First PointData set to compare 00051 * @param p2 Second PointData set to compare 00052 * 00053 * @return bool If first point reference line is less than the second 00054 */ 00055 inline bool PointLess(const PointData &p1, const PointData &p2) { 00056 return (p1.refPoint.GetLine() < p2.refPoint.GetLine()); 00057 } 00058 00059 /** 00060 * @brief Equality test for Control point group 00061 * 00062 * This function tests the reference line numbers for equality and returns true 00063 * if the line references are equivalent, according to an approximation using an 00064 * epsilon of 1.0e-6. 00065 * 00066 * @param p1 First PointData set to compare 00067 * @param p2 Second PointData set to compare 00068 * 00069 * @return bool If the reference point lines are (approximately) equivalent 00070 */ 00071 inline bool PointEqual(const PointData &p1, const PointData &p2) { 00072 return (gsl_fcmp(p1.refPoint.GetLine(), p2.refPoint.GetLine(), 1.0E-6) == 0); 00073 } 00074 00075 /** 00076 * @brief Collector for Control points within the same row for analysis 00077 * 00078 * This class is designed to be used as a Functor object collecting control net 00079 * file and collapsing all column measures into on row. This is primarily used 00080 * for analysis of coregistration results with one or more columns specified 00081 * in the search/pattern chip strategy. 00082 * 00083 * @author ????-??-?? Unknown 00084 * 00085 * @internal 00086 */ 00087 class ControlByRow { 00088 public: 00089 /** 00090 * @brief Structure to return control point statistics for row 00091 * 00092 * This structure contains the row statistics of merged control points. 00093 * This will eventually be used to compute the spline interpolations for 00094 * line and sample offsets. 00095 * 00096 */ 00097 struct RowPoint { 00098 RowPoint() : refLine(0.0), refSamp(0.0), chpLine(0.0), chpSamp(0.0), 00099 total(0), count(0) { } 00100 double refLine; //!< Reference line (row) 00101 double refSamp; //!< Reference sample 00102 double chpLine; //!< Registered line 00103 double chpSamp; //!< Registered sample 00104 int total; //!< Total points in row 00105 int count; //!< Valid points found 00106 00107 Statistics rSStats; 00108 Statistics cLStats; 00109 Statistics cSStats; 00110 Statistics cLOffset; 00111 Statistics cSOffset; 00112 Statistics GOFStats; 00113 }; 00114 00115 public: 00116 /** 00117 * @brief Default constructor 00118 */ 00119 ControlByRow() { 00120 _minGOF = DBL_MIN; 00121 _maxGOF = DBL_MAX; 00122 } 00123 00124 /** 00125 * @brief Constructor that sets the maximum goodness of fit tolerance 00126 * @param maxGOF Value that specifies the maximum goodness of fit which is 00127 * typically never expected to exceed 1.0 for a good fit. 00128 */ 00129 ControlByRow(double maxGOF) { 00130 _minGOF = DBL_MIN; 00131 _maxGOF = maxGOF; 00132 } 00133 00134 /** 00135 * @brief Constructor that sets the maximum goodness of fit tolerance 00136 * @param minGOF Value of minimum goodness of fit. Allows user selectable 00137 * adjustment to coregistration minimum tolerance 00138 * @param maxGOF Value that specifies the maximum goodness of fit which is 00139 * typically never expected to exceed 1.0 for a good fit. 00140 */ 00141 ControlByRow(double minGOF, double maxGOF) { 00142 _minGOF = minGOF; 00143 _maxGOF = maxGOF; 00144 } 00145 00146 /** 00147 * @brief Destructor 00148 */ 00149 ~ControlByRow() { } 00150 00151 /** 00152 * @brief Determines the number of points (rows) found valid 00153 * 00154 * The number returned is really the number of unique rows of coregistration 00155 * chips gleened from the control net. 00156 * 00157 * @return unsigned int Row/line count 00158 */ 00159 inline unsigned int size() const { 00160 return (_rowList.size()); 00161 } 00162 00163 /** 00164 * @brief Set the minimum acceptable goodness of fit value 00165 * 00166 * This sets the minimum (absolute) value used to gleen valid points from 00167 * the control net data. 00168 * 00169 * @param minGOF Minimum goodness of fit tolerance 00170 */ 00171 void setMinGOF(double minGOF) { 00172 _minGOF = minGOF; 00173 } 00174 00175 /** 00176 * @brief Set the maximum acceptable goodness of fit value 00177 * 00178 * This sets the maximum (absolute) value used to gleen valid points from 00179 * the control net data. This is intended to use to exclude wild points 00180 * that exceed the level of reasonable tolerance. This is typically 1.0 for 00181 * most coregistration algorithms. 00182 * 00183 * @param maxGOF Maximum goodness of fit tolerance 00184 */ 00185 void setMaxGOF(double maxGOF) { 00186 _maxGOF = maxGOF; 00187 } 00188 00189 /** 00190 * @brief Operator used to add a point to the data set 00191 * 00192 * This method provides support for the STL for_each algorithm. This allows 00193 * this class to be used as a functor object. 00194 * 00195 * @param p Point to tested for acceptance in the list 00196 */ 00197 void operator()(const PointData &p) { 00198 addPoint(p); 00199 return; 00200 } 00201 00202 /** 00203 * @brief Formal method of adding a control point to the data set 00204 * 00205 * This method will add the provided point to the collection of rows (or 00206 * lines of points). 00207 * 00208 * @param p Point to add to the list 00209 */ 00210 void addPoint(const PointData &p) { 00211 if(_rowList.exists(p.refPoint.GetLine())) { 00212 PointList &r = _rowList.get(p.refPoint.GetLine()); 00213 r.push_back(p); 00214 } 00215 else { 00216 PointList pl; 00217 pl.push_back(p); 00218 _rowList.add(p.refPoint.GetLine(), pl); 00219 } 00220 return; 00221 } 00222 00223 /** 00224 * @brief Returns a point at the ith location 00225 * 00226 * Traverses the list of points after computing the merge statistics for the 00227 * ith row. 00228 * 00229 * @param i Index of point to return 00230 * 00231 * @return RowPoint Structure containing the (statistically) merged row 00232 */ 00233 RowPoint operator[](int i) const { 00234 try { 00235 return (computeStats(_rowList.getNth(i))); 00236 } 00237 catch(iException &oor) { 00238 std::string msg = "Requested value (" + iString(i) + ") not found"; 00239 throw iException::Message(Isis::iException::User, msg, _FILEINFO_); 00240 } 00241 } 00242 00243 private: 00244 typedef std::vector<PointData> PointList; //!< Composite list 00245 typedef CollectorMap<double, PointList, RobustFloatCompare> CNetRow; /** 00246 * Nifty templated collector class works just 00247 * nicely for merging rows of correlations 00248 */ 00249 double _minGOF; //!< Minimum acceptable goodness of fit 00250 double _maxGOF; //!< Maximum acceptable goodness of fit 00251 CNetRow _rowList; //!< Collection of merged rows/lines 00252 00253 /** 00254 * @brief Convenience method for adding point to Statistics class 00255 * 00256 * The interface to the Isis Statistics class requires the value to be added 00257 * by address. This method expedites the addition of values from say a 00258 * function or method. 00259 * 00260 * @param value Value to add to Statistics class 00261 * @param stats Statistics class to add the data point to 00262 */ 00263 inline void addToStats(double value, Statistics &stats) const { 00264 stats.AddData(&value, 1); 00265 return; 00266 } 00267 00268 /** 00269 * @brief All important method that computes statistics for a row 00270 * 00271 * This method computes the statistics for a potentially merged row of 00272 * coregistration chips. It applies the minimum and maximum goodness of fit 00273 * tolerance checks and add valid points to each statistical component of 00274 * the merge. 00275 * 00276 * @param cols List of column chip registrations 00277 * 00278 * @return RowPoint Structure containing the statistics for row/line of 00279 * merged registration columns 00280 */ 00281 RowPoint computeStats(const std::vector<PointData> &cols) const { 00282 RowPoint rp; 00283 rp.refLine = cols[0].refPoint.GetLine(); 00284 for(unsigned int i = 0; i < cols.size() ; i++) { 00285 double regGOF = 00286 cols[i].chpPoint.GetLogData(ControlMeasureLogData::GoodnessOfFit) 00287 .GetNumericalValue(); 00288 if(fabs(regGOF) > _maxGOF) continue; 00289 if(fabs(regGOF) < _minGOF) continue; 00290 (rp.count)++; 00291 addToStats(cols[i].refPoint.GetSample(), rp.rSStats); 00292 addToStats(cols[i].chpPoint.GetLine(), rp.cLStats); 00293 addToStats(cols[i].chpPoint.GetSample(), rp.cSStats); 00294 addToStats(cols[i].chpPoint.GetLineResidual(), rp.cLOffset); 00295 addToStats(cols[i].chpPoint.GetSampleResidual(), rp.cSOffset); 00296 addToStats(regGOF, rp.GOFStats); 00297 } 00298 00299 rp.total = cols.size(); 00300 rp.refSamp = rp.rSStats.Average(); 00301 rp.chpLine = rp.cLStats.Average(); 00302 rp.chpSamp = rp.cSStats.Average(); 00303 return (rp); 00304 } 00305 00306 }; 00307 00308 00309 } // namespace Isis 00310 00311 #endif