// Read the documentation to learn more about C++ code generator // versioning. // %X% %Q% %Z% %W% // FunctionUtility #include #include #include #include #include "xsTypes.h" #include #include #include // Class FunctionUtility::NoInitializer FunctionUtility::NoInitializer::NoInitializer() : YellowAlert() { } FunctionUtility::NoInitializer::NoInitializer (const string& diag) : YellowAlert(" No Initializer for ") { *IosHolder::errHolder() << diag << '\n'; } // Class FunctionUtility::InvalidAbundanceFile FunctionUtility::InvalidAbundanceFile::InvalidAbundanceFile (const string& diag) : YellowAlert(" Invalid Abundance File ") { *IosHolder::errHolder() << diag << '\n'; } // Class FunctionUtility::FunctionException FunctionUtility::FunctionException::FunctionException (const string& diag) : YellowAlert(" in function ") { *IosHolder::errHolder() << diag << std::endl; } // Class FunctionUtility::Cosmology FunctionUtility::Cosmology::Cosmology () : H0(.0), q0(.0), lambda0(.0) { } // Class Utility FunctionUtility string FunctionUtility::s_XSECT = "bcmc"; string FunctionUtility::s_ABUND = "angr"; const string FunctionUtility::CROSSSECTFILE = "crosssections.dat"; string FunctionUtility::s_abundanceFile = "abundances.dat"; std::vector FunctionUtility::s_elements; string FunctionUtility::s_managerPath = ""; const size_t FunctionUtility::s_NELEMS = 30; string FunctionUtility::s_modelDataPath = ""; string FunctionUtility::s_NOT_A_KEY = "$$NOT$$"; FunctionUtility::Cosmology FunctionUtility::s_COSMO = FunctionUtility::Cosmology(); string FunctionUtility::s_abundPath; bool FunctionUtility::s_abundChanged = false; int FunctionUtility::s_xwriteChatter = 10; std::vector FunctionUtility::s_tempsDEM; std::vector FunctionUtility::s_DEM; std::map > FunctionUtility::s_abundanceVectors; std::map FunctionUtility::s_crossSections; std::map FunctionUtility::s_abundDoc; std::map FunctionUtility::s_modelStringDataBase; bool FunctionUtility::checkXsect (const string& arg) { try { const string& table = crossSections(arg); } catch (NoInitializer) { return false; } return true; } bool FunctionUtility::checkAbund (const string& arg) { try { const std::vector& element = abundanceVectors(arg); } catch (NoInitializer) { return false; } return true; } void FunctionUtility::readInitializers (string& xsects, string& abunds) { using namespace std; s_abundPath = s_managerPath; string fullAbundPath = s_abundPath + string("/") + s_abundanceFile; string fullXsectPath = s_managerPath + string("/") + CROSSSECTFILE; static const string NULLCHARS(" \t"); s_elements.reserve(s_NELEMS); ifstream abund(fullAbundPath.c_str()); abund.exceptions(ios_base::failbit); abunds = "[ "; try { string element; abund.ignore(256,':'); string abundLine(""); getline(abund,abundLine); istringstream abundString(abundLine); while ( abundString >> element ) { s_elements.push_back(element); } bool readingStrings(false); while (abund) { string rawLine(""); getline(abund, rawLine); vector abundances; abundances.reserve(s_NELEMS); int first(rawLine.find_first_not_of(NULLCHARS)); if (first > 0 )rawLine = rawLine.substr(first); if ( rawLine.length() != 0 && first != -1) { // ignore lines with '#' comment mark as first significant // character. if ( rawLine[0] == '#') continue; // ignore lines that do not meet syntax specification // (no delimiter) int delim = rawLine.find_first_of(":"); if (delim < 0 ) continue; string abundKey(rawLine.substr(0,rawLine.substr(0,delim). find_last_not_of(NULLCHARS)+1)); if (abundKey == "References") { readingStrings = true; continue; } if ( !readingStrings ) { abunds += abundKey + " | "; string abundData(rawLine.substr(delim+1)); istringstream abVector(abundData); float elementAbundance(0); while (abVector >> elementAbundance) { abundances.push_back(elementAbundance); } abundanceVectors(abundKey,abundances); } else { string descript(rawLine.substr(delim+1)); abundDoc(abundKey,descript); } } } } catch ( std::exception& ) { if ( !abund.eof()) { string diag = "Cannot read abundance file " + s_abundanceFile + "\n*** in XSPEC data file path (" + s_managerPath + ")... exiting\n" ; throw RedAlert(diag); } } abunds = abunds.substr(0,abunds.size()-2); abunds += "]"; ifstream xsect(fullXsectPath.c_str()); xsect.exceptions(ios_base::failbit); xsects = "[ "; try { string rawLine(""); while (getline(xsect,rawLine)) { int first(rawLine.find_first_not_of(NULLCHARS)); if (first > 0 )rawLine = rawLine.substr(first); if ( rawLine.length() != 0 && first != -1) { // ignore lines with '#' comment mark as first significant // character. if ( rawLine[0] == '#') continue; // ignore lines that do not meet syntax specification // (no delimiter) int delim = rawLine.find_first_of(":"); if (delim < 0 ) continue; string table(rawLine.substr(0,rawLine.substr(0,delim). find_last_not_of(NULLCHARS)+1)); xsects += table + " | "; string descript(rawLine.substr(delim+1)); crossSections(table,descript); } } } catch ( std::exception& ) { if ( !xsect.eof()) { string diag = "Cannot read cross section table file " + CROSSSECTFILE + "\n*** in XSPEC data file path (" + s_managerPath + ")... exiting\n" ; throw RedAlert(diag); } } xsects = xsects.substr(0,xsects.size()-2); xsects += "]"; } void FunctionUtility::readNewAbundances (const string& file) { using namespace std; const string name("file"); s_abundChanged = true; s_abundanceFile = file; s_abundPath = XSutility::getRunPath(); ifstream newAbundanceFile(file.c_str()); vector newVector(s_NELEMS,0); size_t count(0); try { float element; newAbundanceFile.exceptions(ios_base::failbit); while (count < s_NELEMS && newAbundanceFile >> element) { newVector[count] = element; ++count; } ABUND(name); abundanceVectors(name,newVector); } catch ( std::exception& ) { if (!newAbundanceFile.eof()) { string diag(file); diag += "\nCannot be read from. Either it does not exist or contains invalid data"; throw InvalidAbundanceFile(diag); } } if (count < s_NELEMS) { // write a warning to the logfile if file is short. if (XSstream* xscout = dynamic_cast(IosHolder::outHolder())) { XSstream::verbose(*xscout,0,20); *xscout << "\n*** Warning: new element vector has fewer elements than allowed." << "\n*** heavier nuclei set with abundance 0" << std::endl; XSstream::verbose(*xscout); } } } float FunctionUtility::getAbundance (const string& element) { std::vector::iterator f = std::find(s_elements.begin(),s_elements.end(),element); if ( f == s_elements.end() ) { *IosHolder::errHolder() << "XSPEC::getAbundance: Invalid element: " << element << " entered, returning 0.\n" ; return 0; } else { #ifndef STD_COUNT_DEFECT size_t index(std::distance(s_elements.begin(),f)); #else size_t index(0); std::distance(s_elements.begin(),f,index); #endif const std::vector& abVector = abundanceVectors(s_ABUND); return abVector[index]; } } const string& FunctionUtility::elements (size_t index) { return s_elements[index]; } const string& FunctionUtility::getModelString (const string& key) { std::map::iterator f(s_modelStringDataBase.find(key)); return ( f != s_modelStringDataBase.end() ? f->second : s_NOT_A_KEY ); } void FunctionUtility::setModelString (const string& key, const string& value) { if (!value.length()) { std::map::iterator itString = s_modelStringDataBase.find(key); if (itString != s_modelStringDataBase.end()) s_modelStringDataBase.erase(itString); } else s_modelStringDataBase[key] = value; } void FunctionUtility::eraseModelStringDataBase () { s_modelStringDataBase.clear(); } void FunctionUtility::setFunctionCosmoParams (double H0, double q0, double lambda0) { s_COSMO.H0 = static_cast(H0); s_COSMO.q0 = static_cast(q0); s_COSMO.lambda0 = static_cast(lambda0); } void FunctionUtility::XSECT (const string& value) { *IosHolder::outHolder() << " Cross Section Table set to " << value << ": " << s_crossSections[value] << std::endl; s_XSECT = value; } void FunctionUtility::ABUND (const string& value) { *IosHolder::outHolder() << " Solar Abundance Vector set to " << value << ": " << abundDoc(value) << std::endl; s_ABUND = value; } const std::vector< float >& FunctionUtility::abundanceVectors (string table) { std::map >::iterator f(s_abundanceVectors.find(table)); if ( f == s_abundanceVectors.end()) { // throw quietly to allow this to be caught and the program control // sent on to try to read abundance from a file. throw NoInitializer(); } return f->second; } const std::string& FunctionUtility::crossSections (string table) { std::map::iterator f(s_crossSections.find(table)); if ( f == s_crossSections.end()) { string diag = " cross section table named " + table; throw NoInitializer(diag); } return f->second; } const std::string FunctionUtility::abundDoc (string name) { std::map::iterator f(s_abundDoc.find(name)); if ( f == s_abundDoc.end()) { string doc(" User defined abundance vector / no description specified"); return doc; } else return f->second; } // Additional Declarations