/** * @brief Initialize class from input PVL and Cube files * * This method is typically called at class instantiation time, * but is reentrant. It reads the parameter PVL file and * extracts Photometric model and Normalization models from it. * The cube is needed to match all potential profiles for each * band. * * @param pvl Input PVL parameter files * @param cube Input cube file to correct * * @author Kris Becker - 2/22/2010 * @history 2010-02-25 Kris Becker Added check for valid incidence angle */ void Hillier::init(PvlObject &pvl, Cube &cube) { // Make it reentrant _profiles.clear(); _bandpho.clear(); // Interate over all Photometric groups _normProf = DbProfile(pvl.findObject("NormalizationModel").findGroup("Algorithm", Pvl::Traverse)); _iRef = toDouble(ConfKey(_normProf, "IncRef", toString(30.0))); _eRef = toDouble(ConfKey(_normProf, "EmaRef", toString(0.0))); _gRef = toDouble(ConfKey(_normProf, "PhaRef", toString(_iRef))); // Check for valid incidence angle if(_iRef > fabs(90.0)) { ostringstream mess; mess << "Invalid incidence angle (" << _iRef << " >= 90.0) provided in PVL config file " << pvl.fileName(); throw IException(IException::User, mess.str(), _FILEINFO_); } PvlObject &phoObj = pvl.findObject("PhotometricModel"); DbProfile phoProf = DbProfile(phoObj); PvlObject::PvlGroupIterator algo = phoObj.beginGroup(); while(algo != phoObj.endGroup()) { if(algo->name().toLower() == "algorithm") { _profiles.push_back(DbProfile(phoProf, DbProfile(*algo))); } ++algo; } Pvl *label = cube.label(); PvlKeyword center = label->findGroup("BandBin", Pvl::Traverse)["Center"]; QString errs(""); for(int i = 0; i < cube.bandCount() ; i++) { Parameters parms = findParameters(toDouble(center[i])); if(parms.IsValid()) { parms.band = i + 1; _camera->SetBand(i + 1); parms.phoStd = photometry(parms, _iRef, _eRef, _gRef); _bandpho.push_back(parms); } else { // Appropriate photometric parameters not found ostringstream mess; mess << "Band " << i + 1 << " with wavelength Center = " << center[i] << " does not have PhotometricModel Algorithm group/profile"; IException e(IException::User, mess.str(), _FILEINFO_); errs += e.toString() + "\n"; } } // Check for errors and throw them all at the same time if(!errs.isEmpty()) { errs += " --> Errors in the input PVL file \"" + pvl.fileName() + "\""; throw IException(IException::User, errs, _FILEINFO_); } return; }
/** * @brief Extracts necessary Hillier parameters from profile * * Given a profile read from the input PVL file, this method * extracts needed parameters (from Keywords) in the PVL profile * and creates a container of the converted values. * * @author Kris Becker - 2/22/2010 * * @param p Profile to extract/convert * * @return Hillier::Parameters Container of extracted values */ Hillier::Parameters Hillier::extract(const DbProfile &p) const { Parameters pars; pars.b0 = toDouble(ConfKey(p, "B0", toString(0.0))); pars.b1 = toDouble(ConfKey(p, "B1", toString(0.0))); pars.a0 = toDouble(ConfKey(p, "A0", toString(0.0))); pars.a1 = toDouble(ConfKey(p, "A1", toString(0.0))); pars.a2 = toDouble(ConfKey(p, "A2", toString(0.0))); pars.a3 = toDouble(ConfKey(p, "A3", toString(0.0))); pars.a4 = toDouble(ConfKey(p, "A4", toString(0.0))); pars.wavelength = toDouble(ConfKey(p, "BandBinCenter", toString(Null))); pars.tolerance = toDouble(ConfKey(p, "BandBinCenterTolerance", toString(Null))); // Determine equation units - defaults to Radians pars.units = ConfKey(p, "HillierUnits", QString("Radians")); pars.phaUnit = (pars.units.toLower() == "degrees") ? 1.0 : rpd_c(); return (pars); }
DriftCorrect::DriftCorrect(const HiCalConf &conf) : NonLinearLSQ(), Component("DriftCorrect") { DbProfile prof = conf.getMatrixProfile(); _history.add("Profile["+ prof.Name()+"]"); _timet.setBin(ToInteger(prof("Summing"))); _timet.setLineTime(ToDouble(prof("ScanExposureDuration"))); _skipFit = IsEqual(ConfKey(prof, "ZdSkipFit", std::string("TRUE")), "TRUE"); _useLinFit = IsTrueValue(prof, "ZdOnFailUseLinear"); _absErr = ConfKey(prof, "AbsoluteError", 1.0E-4); _relErr = ConfKey(prof, "RelativeError", 1.0E-4); _sWidth = ConfKey(prof, "GuessFilterWidth", 17); _sIters = ConfKey(prof, "GuessFilterIterations", 1); if ( prof.exists("MaximumIterations") ) { setMaxIters(ToInteger(prof("MaximumIterations"))); } _maxLog = ConfKey(prof, "MaximumLog", 709.0); _badLines = ToInteger(prof("TrimLines"))/ToInteger(prof("Summing")); _minLines = ConfKey(prof,"ZdMinimumLines", 100); string histstr = "DriftCorrect(AbsErr[" + ToString(_absErr) + "],RelErr[" + ToString(_relErr) + "],MaxIter[" + ToString(maxIters()) + "])"; _history.add(histstr); }
/** * @brief Determine Hillier parameters given a wavelength * * This method determines the set of Hillier parameters to use * for a given wavelength. It iterates through all band * profiles as read from the PVL file and computes the * difference between the "wavelength" parameter and the * BandBinCenter keyword. The absolute value of this value is * checked against the BandBinCenterTolerance paramter and if it * is less than or equal to it, a Parameter container is * returned. * * @author Kris Becker - 2/22/2010 * * @param wavelength Wavelength used to find parameter set * * @return Hillier::Parameters Container of valid values. If * not found, a value of iProfile = -1 is returned. */ Hillier::Parameters Hillier::findParameters(const double wavelength) const { for(unsigned int i = 0 ; i < _profiles.size() ; i++) { const DbProfile &p = _profiles[i]; if(p.exists("BandBinCenter")) { double p_center = toDouble(ConfKey(p, "BandBinCenter", toString(Null))); double tolerance = toDouble(ConfKey(p, "BandBinCenterTolerance", toString(1.0E-6))); if(fabs(wavelength - p_center) <= fabs(tolerance)) { Parameters pars = extract(p); pars.iProfile = i; pars.wavelength = wavelength; pars.tolerance = tolerance; return (pars); } } } // Not found if we reach here return (Parameters()); }