// // XSPEC12 November 2003 // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { void showAbund(); void showControl(); void showFiles(); void showFit(); void showNoticed(); void showParams(bool onlyFree); void showPha(); void showPlot(); void showRates(); void showRespPars(bool onlyFree); void showResponse(); void showSpecificParams(const StringArray& parIDs, bool isRespPar=false); void showXsect(); void commonDataReport(const DataSet* ds, const SpectralData* sd); void rebinDisplay(int plotGroup, const Plot::RebinInfo& rbInfo); } int XSGlobal::xsShow(ClientData cdata,Tcl_Interp* tclInterp,int objc, Tcl_Obj* CONST objv[]) { using namespace std; using namespace XSContainer; static string prevOption("all"); int optLen = 0; string option(""); enum OPTIONS {ABUND, ALL, ALLFILE, CONTROL, DATA, FILES, FIT, FREE, MODEL, NOTICED, PARAMETER, PHA, PLOT, RATES, RESPONSE, RPARAMETER, XSECT}; static map allowedOptions; allowedOptions["abund"] = ABUND; allowedOptions["all"] = ALL; allowedOptions["allfile"] = ALLFILE; allowedOptions["control"] = CONTROL; allowedOptions["data"] = DATA; allowedOptions["files"] = FILES; allowedOptions["fit"] = FIT; allowedOptions["free"] = FREE; allowedOptions["model"] = MODEL; allowedOptions["noticed"] = NOTICED; allowedOptions["parameters"] = PARAMETER; allowedOptions["pha"] = PHA; allowedOptions["plot"] = PLOT; allowedOptions["rates"] = RATES; allowedOptions["response"] = RESPONSE; allowedOptions["rparameters"] = RPARAMETER; allowedOptions["xsect"] = XSECT; if (objc > 1) { option = string(Tcl_GetStringFromObj(objv[1],&optLen)); option = XSutility::lowerCase(option); if (option == "?") { XSutility::printValidOptions(tcout, string("show"), allowedOptions); return TCL_OK; } } else option = prevOption; map::const_iterator itOpt(allowedOptions.lower_bound(option)); map::const_iterator itOptEnd(allowedOptions.end()); size_t selected = 0; if (itOpt != itOptEnd && itOpt->first.find(option) == 0) selected = itOpt->second; else { tcout << "Unrecognized show option." << std::endl; XSutility::printValidOptions(tcout, string("show"), allowedOptions); return TCL_OK; } try { switch (selected) { case ABUND: showAbund(); break; case ALL: showControl(); if (tpout.maxChatter() >= 15) { showAbund(); } showPlot(); showResponse(); datasets->showData(true); models->showModel(); showFit(); break; case ALLFILE: showResponse(); datasets->showData(true); break; case CONTROL: showControl(); break; case DATA: datasets->showData(false); break; case FILES: showFiles(); break; case FIT: showFit(); break; case FREE: Parameter::onlyPrintFree(true); showParams(true); Parameter::onlyPrintFree(false); break; case MODEL: models->showModel(); break; case NOTICED: showNoticed(); break; case PARAMETER: if (objc > 2) { StringArray inArgs; for (int i=2; i 2) { StringArray inArgs; for (int i=2; ifirst; } return TCL_OK; } namespace { using namespace std; using namespace XSContainer; void showAbund() { tcout << "\nSolar Abundance Table: \n"; const string& abund = FunctionUtility::ABUND(); tcout << abund << ": " << FunctionUtility::abundDoc(abund) << '\n'; const size_t& n = FunctionUtility::NELEMS(); const vector& abundances = FunctionUtility::abundanceVectors(abund); ios_base::fmtflags currentSetting(tcout.flags()); streamsize p(tcout.precision(3)); tcout.setf(ios_base::scientific | ios_base::showpoint | ios_base::uppercase ); for ( size_t j = 0; j < n; ++j) { tcout << left << " " << setw(4) << FunctionUtility::elements(j) + ":" << right << setw(10) << abundances[j]; if ( j % 5 == 4 || j == n - 1) tcout << '\n'; } tcout << flush; tcout.flags(currentSetting); tcout.precision(p); } void showControl() { time_t calndrTime; char timebuf[100]; time(&calndrTime); strcpy(timebuf, ctime(&calndrTime)); tcout << "\n" << timebuf; size_t saveFreq = XSGlobal::globalData->autoSaveFrequency(); if (saveFreq == XSparse::NOTFOUND()) { tcout << " Auto-saving is disabled." << endl; } else if (saveFreq == 1) { tcout << " Auto-saving is done after every command." << endl; } else { tcout << " Auto-saving is done after every " << saveFreq << " commands." << endl; } tcout << " Fit statistic in use: " << fit->statMethod()->fullName() << endl; tcout << " Minimization technique: " << fit->fitMethod()->fullName() << endl; tcout << " Convergence criterion = " << fit->fitMethod()->deltaCrit() << endl; Real parDelta = XSContainer::models->proportionalDelta(); tcout << " Parameter fit deltas: "; if (parDelta <= 0.0) tcout << "fixed values" << endl; else tcout << parDelta << " * parValue" << endl; tcout << " Always calculate parameter derivatives using full (slower) numerical differentiation: "; if (fit->useNumericalDifferentiation()) tcout << "Yes" << std::endl; else tcout << "No" << std::endl; if (fit->queryMode() == Fit::ON) { tcout << " Querying enabled." << endl; } else { if (fit->queryMode() == Fit::YES) { tcout << " Querying disabled - will continue fitting." << endl; } else { tcout << " Querying disabled - will not continue fitting." << endl; } } if (fit->renormType() == Fit::AUTO) { tcout << " Auto-renorming enabled." << endl; } else if (fit->renormType() == Fit::PREFIT) { tcout << " Prefit-renorming enabled." << endl; } if (models->modelSystematicError() >= SMALL) { tcout << " Model systematic error = " << models->modelSystematicError() << endl; } tcout << " Solar abundance table: " << FunctionUtility::ABUND() << endl; showXsect(); tcout << " Cosmology in use: H0 = " << models->cosmo().H0 << " q0 = " << models->cosmo().q0 << " Lambda0 = " << models->cosmo().lambda0 << endl << " Model data directory: " << FunctionUtility::modelDataPath() << endl; } //end showControl void showFiles() { // Essentially the same as showData, but outputs spectra in order // of DataSet file names rather than spectrum number. if (datasets->dataArray().empty()) { tcout << "\n No Spectra defined." << endl; } else { string filx = datasets->dataArray().size() > 1 ? " files " : " file "; string spec = datasets->numberOfSpectra() > 1 ? " spectra " : " spectrum "; tcout << '\n' << datasets->dataArray().size() << filx << datasets->numberOfSpectra() << spec << endl; DataArrayConstIt itDs = datasets->dataArray().begin(); DataArrayConstIt itDsEnd = datasets->dataArray().end(); while (itDs != itDsEnd) { if (itDs->second->isMultiple()) { SpectralDataMapConstIt itSd = itDs->second->multiSpectralData().begin(); SpectralDataMapConstIt itSdEnd = itDs->second->multiSpectralData().end(); while (itSd != itSdEnd) { tcout << endl; itDs->second->report(itSd->first); ++itSd; } } else { tcout << endl; itDs->second->report(0); } ++itDs; } tcout << flush; } } void showFit() { fit->statMethod()->report(fit); tcout << " Weighting method: " << DataUtility::statWeight().name() << endl; if (fit->useNumericalDifferentiation()) tcout << " Fit is using the full (slower) numerical differentiation method." << endl; } void showNoticed() { if (datasets->dataArray().empty()) { tcout << "\n No Spectra defined." << endl; } else { const size_t nSpecs = datasets->numberOfSpectra(); for (size_t i=1; i<=nSpecs; ++i) { const SpectralData* sd = datasets->lookup(i); tcout << endl << "Spectrum No. " << sd->spectrumNumber() << endl; commonDataReport(sd->parent(), sd); sd->reportNoticed(); } } } void showParams(bool onlyFree) { if (onlyFree) { tcout << "\nFree parameters defined:"; } else { tcout << "\nParameters defined:"; } const ModelMap& mods = models->modelSet(); if (mods.empty()) { tcout << " none" << endl; } else { map::const_iterator itModNames = models->activeModelNames().begin(); map::const_iterator itNamesEnd = models->activeModelNames().end(); while (itModNames != itNamesEnd) { vector mods = models->lookupModelGroup(itModNames->first); // mods should always have size >=1 if in activeModelNames map. mods[0]->printHeading(); for (size_t i=0; iprintMixComp(); tcout << string(72,'_') << std::endl; ++itModNames; } tcout << endl; } if (responses->totalResponseParams()) { showRespPars(onlyFree); } } // end showParams void showRespPars(bool onlyFree) { if (onlyFree) { tcout << "\nFree response parameters defined:"; } else { tcout << "\nResponse parameters defined:"; } if (!responses->totalResponseParams()) { tcout << " none" << endl; } else { responses->reportResponseParams(); } } // end showRespPars void showPha() { if (datasets->dataArray().empty()) { tcout << "\n No Spectra defined." << endl; } else { const size_t nSpecs = datasets->numberOfSpectra(); tcout << endl; for (size_t i=1; i<=nSpecs; ++i) { const SpectralData* sd = datasets->lookup(i); tcout << " Information for spectrum " << i << "\n belonging to plot group " << sd->plotGroup() << ", data group " << sd->parent()->dataGroup() << endl; sd->reportKeywords(); tcout << endl; sd->reportPha(); tcout << endl; } } } void showPlot() { using XSContainer::plot; tcout << " Plot settings:" << endl; string onOrOff = plot->showAddComponents() ? string("ON."):string("OFF."); tcout << " Showing of individual additive components is " << onOrOff << endl; onOrOff = plot->showBackground() ? string("ON.") : string("OFF."); tcout << " Showing of background spectra is " << onOrOff << endl; onOrOff = plot->divideByArea().first ? string("ON."):string("OFF."); tcout << " Effective area normalization is " << onOrOff << endl; string xMode; if (plot->xOption() == Plot::ENERGY) xMode = "Energy"; else if (plot->xOption() == Plot::WAVELENGTH) xMode = "Wavelength"; else xMode = "Channels"; tcout << " X-Axis data display mode: " << xMode << endl; tcout << " Device: " << plot->graph()->deviceName() << endl; onOrOff = plot->plotIDs() ? string("ON."):string("OFF."); tcout << " Plotting of line IDs is " << onOrOff << endl; if (plot->plotIDs()) { tcout << " Temperature: " << plot->temperature() << " Emissivity Limit: " << plot->emisLimit() << " Redshift: " << plot->redshift() << endl; } onOrOff = plot->splashPage() ? string("ON."):string("OFF."); tcout << " Splashpage is " << onOrOff << endl; onOrOff = plot->xLog() ? string("ON."):string("OFF."); tcout << " xlog for data plots is " << onOrOff << endl; onOrOff = plot->yLog() ? string("ON."):string("OFF."); tcout << " ylog for data plots is " << onOrOff << endl; tcout <<"\n Default plot rebin settings for all plot groups:"<::const_iterator itRb = plot->groupsRebinInfo().find(-1); // Entry for -1 should ALWAYS be in plot rebin map. tcout << " Min. Signif. Max. # Bins Error Type"<< endl; rebinDisplay(-1, itRb->second); map::const_iterator itRbEnd = plot->groupsRebinInfo().end(); ++itRb; if (itRb != itRbEnd) { tcout << " With overridden rebin settings for the following plot groups:" << endl; tcout << " Groups Min. Signif. Max. # Bins Error Type"<< endl; while (itRb != itRbEnd) { rebinDisplay(itRb->first, itRb->second); ++itRb; } } } // end showPlot void showRates() { if (datasets->dataArray().empty()) { tcout << "\n No Spectra defined." << endl; } else { const size_t nSpecs = datasets->numberOfSpectra(); for (size_t i=1; i<=nSpecs; ++i) { const SpectralData* sd = datasets->lookup(i); tcout << endl; commonDataReport(sd->parent(), sd); sd->reportRates(); tcout << " Spectral data counts: " << sd->totalFlux()*sd->exposureTime() << endl; models->reportModelRate(sd->spectrumNumber(), sd->parent()->dataGroup(), sd->areaScale()); } } } void showResponse() { // primitive data printing option tcout << "\n Responses read: "; if (responses->responseList().size() == 1) { tcout << " none " << endl; if (responses->responseList().begin()->first != DUMMY_RSP) { throw RedAlert(" Dummy Response Corrupted or deleted "); } } else { tcout << '\n'; ResponseMapConstIter resp = responses->responseList().begin(); while (resp != responses->responseList().end()) { if ( resp->first != DUMMY_RSP) { Response* current(resp->second); string respName(resp->first); if (respName == USR_DUMMY_RSP) respName = "Dummy response"; tcout << " " << respName << " associated with spectrum " << current->spectrumNumber() << " source " << current->sourceNumber(); if (current->dataGroup() > 1) { tcout << " data group " << current->dataGroup(); } tcout << "\n energies: " << current->numEnergies() << " channels: " << current->numChannels() << endl; if (current->isGainApplied()) { tcout << " With applied gain: slope = " << current->gainFactor()[1] << " offset = " << current->gainFactor()[0] << endl; } if (current->getConstGain() || current->getLinearGain()) { tcout << " Gain parameters will be adjusted by fit." << endl; } } ++resp; } RMFMapConstIter rmf = responses->RMFmap().begin(); tcout << " Distinct RMF files: \n"; while (rmf != responses->RMFmap().end()) { tcout << " " << rmf->first ; ++rmf; } tcout << endl; } } // end showResponse void showSpecificParams(const StringArray& parIDs, bool isRespPar) { string prevModName; const size_t linelen(72); for (size_t i=0; irespParContainer().size()) tcout << string(linelen,'=') << "\nSource No.: " << sourceNum << "\nRpar Spectrum Rmodel Rpar_name Unit Value\n" << std::endl; else { string errMsg("Out of range source number specifier: "); errMsg += modName + '\n'; throw YellowAlert(errMsg); } } // end if resppar else { // Just get any model object from the group given by modName. // It doesn't matter which for printing the heading. const string searchName = modName.length() ? modName : Model::DEFAULT(); const Model* mod = XSContainer::models->lookup(searchName); if (mod) mod->printHeading(); else { string err = modName.length() ? "Cannot find model: " + modName + "\n" : string("No unnamed models loaded. Must enter :\n"); throw YellowAlert(err); } } } // end if new name for (size_t j=0; j(range[j]); const Parameter* specificPar = isRespPar ? HandlerUtils::lookupStringIntObj(modName,iPar) : HandlerUtils::lookupStringIntObj(modName,iPar); if (specificPar) { tcout <<*specificPar; } } if (i == parIDs.size()-1) tcout << string(linelen,'_') << '\n' << std::endl; } // end args loop } // end showSpecificParams void showXsect() { tcout << " Photoionization Cross-Section Table:\n "; tcout << FunctionUtility::XSECT() << ": " << FunctionUtility::crossSections(FunctionUtility::XSECT()) << endl; } void commonDataReport(const DataSet* ds, const SpectralData* sd) { tcout << "Spectral Data File: " << ds->dataName(); if (sd->rowNumber() > 0 ) tcout << "{" << sd->rowNumber() <<"}"; tcout << "\n Assigned to Data Group " << ds->dataGroup() << " and Plot Group " << sd->plotGroup() << endl; } void rebinDisplay(int plotGroup, const Plot::RebinInfo& rbInfo) { string modeStr; switch (rbInfo.mode) { case Plot::ROOTN: modeStr = "sqrt"; break; case Plot::GEHRELS1: modeStr = "poiss-1"; break; case Plot::GEHRELS2: modeStr = "poiss-2"; break; case Plot::GEHRELSM: modeStr = "poiss-3"; break; default: modeStr = "quad"; break; } ios_base::fmtflags saveFmt(tcout.flags()); if (plotGroup != -1) tcout << setw(9) << plotGroup; tcout << showpoint << setw(15) <