/***********************************************************************//** * @brief Print energy boundaries * * @param[in] chatter Chattiness (defaults to NORMAL). * @return String containing energy boundary information. ***************************************************************************/ std::string GEbounds::print(const GChatter& chatter) const { // Initialise result string std::string result; // Continue only if chatter is not silent if (chatter != SILENT) { // Append Header result.append("=== GEbounds ==="); // Append information result.append("\n"+gammalib::parformat("Number of intervals")); result.append(gammalib::str(size())); result.append("\n"+gammalib::parformat("Energy range")); result.append(emin().print()); result.append(" - "); result.append(emax().print()); // If there are multiple energy bins then append them if (chatter >= EXPLICIT) { if (size() > 1) { for (int i = 0; i < size(); ++i) { result.append("\n"); result.append(gammalib::parformat("Energy interval ")); result.append(gammalib::str(i)); result.append(emin(i).print()); result.append(" - "); result.append(emax(i).print()); } } } // endif: chatter was less than explicit } // endif: chatter was not silent // Return return result; }
/***********************************************************************//** * @brief Write energy boundaries into XML element * * @param[in] xml XML element. * * Writes energy boundaries into an XML element. The format of the energy * boundaries is * * <parameter name="EnergyBoundaries" emin="0.1" emax="10.0"/> * * The units of the @a emin and @a emax parameters are MeV. * * This method does nothing if the energy boundaries are empty. ***************************************************************************/ void GEbounds::write(GXmlElement& xml) const { // Continue only if there are energy boundaries if (!is_empty()) { // Get parameter GXmlElement* par = gammalib::xml_need_par(G_WRITE_XML, xml, "EnergyBoundaries"); // Write attributes par->attribute("emin", gammalib::str(emin().MeV())); par->attribute("emax", gammalib::str(emax().MeV())); } // endif: energy boundaries were not empty // Return return; }
/***********************************************************************//** * @brief Print spectrum * * @param[in] chatter Chattiness (defaults to NORMAL). * @return String containing spectrum ***************************************************************************/ std::string GMWLSpectrum::print(const GChatter& chatter) const { // Initialise result string std::string result; // Continue only if chatter is not silent if (chatter != SILENT) { // Append header result.append("=== GMWLSpectrum ==="); // Append information result.append("\n"+gammalib::parformat("Telescope")+m_telescope); result.append("\n"+gammalib::parformat("Instrument")+m_instrument); result.append("\n"+gammalib::parformat("Number of points")); result.append(gammalib::str(size())); result.append("\n"+gammalib::parformat("Time interval")); if (m_gti.size() > 0) { result.append(gammalib::str(tstart().secs())+" - "); result.append(gammalib::str(tstop().secs())+" sec"); } else { result.append("not defined"); } result.append("\n"+gammalib::parformat("Energy range")); if (m_ebounds.size() > 0) { result.append(emin().print()+" - "+emax().print()); } else { result.append("not defined"); } // EXPLICIT: Append spectral points if (chatter >= EXPLICIT) { for (int i = 0; i < size(); ++i) { // Build energy string std::string energy = m_data[i].m_eng.print(); if (m_data[i].m_eng_err.MeV() > 0.0) { energy += " +/- "+m_data[i].m_eng_err.print(); } // Build flux string std::string flux = gammalib::str(m_data[i].m_flux); if (m_data[i].m_flux_err > 0.0) { flux += " +/- "+gammalib::str(m_data[i].m_flux_err); } flux += " ph/cm2/s/MeV"; // Append to string result.append("\n"+gammalib::parformat(energy)); result.append(flux); } // endfor: looped over spectral points } // endif: EXPLICIT level } // endif: chatter was not silent // Return result return result; }
/***********************************************************************//** * @brief Print event cube information * * @param[in] chatter Chattiness (defaults to NORMAL). * @return String containing event cube information. ***************************************************************************/ std::string GLATEventCube::print(const GChatter& chatter) const { // Initialise result string std::string result; // Continue only if chatter is not silent if (chatter != SILENT) { // Append header result.append("=== GLATEventCube ==="); // Append information result.append("\n"+gammalib::parformat("Number of elements") + gammalib::str(size())); result.append("\n"+gammalib::parformat("Number of pixels")); result.append(gammalib::str(m_map.nx()) + " x " + gammalib::str(m_map.ny())); result.append("\n"+gammalib::parformat("Number of energy bins") + gammalib::str(ebins())); result.append("\n"+gammalib::parformat("Number of events") + gammalib::str(number())); // Append time interval result.append("\n"+gammalib::parformat("Time interval")); if (gti().size() > 0) { result.append(gammalib::str(tstart().secs()) + " - " + gammalib::str(tstop().secs())+" sec"); } else { result.append("not defined"); } // Append energy range result.append("\n"+gammalib::parformat("Energy range")); if (ebounds().size() > 0) { result.append(emin().print()+" - "+emax().print(chatter)); } else { result.append("not defined"); } // Append detailed information GChatter reduced_chatter = gammalib::reduce(chatter); if (reduced_chatter > SILENT) { // Append sky projection if (m_map.projection() != NULL) { result.append("\n"+m_map.projection()->print(reduced_chatter)); } // Append source maps result.append("\n"+gammalib::parformat("Number of source maps")); result.append(gammalib::str(m_srcmap.size())); for (int i = 0; i < m_srcmap.size(); ++i) { result.append("\n"+gammalib::parformat(" "+m_srcmap_names[i])); result.append(gammalib::str(m_srcmap[i]->nx())); result.append(" x "); result.append(gammalib::str(m_srcmap[i]->ny())); result.append(" x "); result.append(gammalib::str(m_srcmap[i]->nmaps())); } } } // endif: chatter was not silent // Return result return result; }
/***********************************************************************//** * @brief Read Auxiliary Response File * * @param[in] table ARF FITS table. * * Reads the Auxiliary Response File from a FITS table. The true energy * boundaries are expected in the `ENERG_LO` and `ENERG_HI` columns, the * response information is expected in the `SPECRESP` column. * * The method will analyze the unit of the `SPECRESP` column, and if either * `m^2` or `m2` are encountered, multiply the values of the column by * \f$10^4\f$ to convert the response into units of \f$cm^2\f$. Units of the * `ENERG_LO` and `ENERG_HI` columns are also interpreted for conversion. * * See * http://heasarc.gsfc.nasa.gov/docs/heasarc/caldb/docs/memos/cal_gen_92_002/cal_gen_92_002.html#tth_sEc4 * for details about the Auxiliary Response File format. ***************************************************************************/ void GArf::read(const GFitsTable& table) { // Clear members clear(); // Get pointer to data columns const GFitsTableCol* energy_lo = table["ENERG_LO"]; const GFitsTableCol* energy_hi = table["ENERG_HI"]; const GFitsTableCol* specresp = table["SPECRESP"]; // Determine effective area conversion factor. Internal // units are cm^2 std::string u_specresp = gammalib::tolower(gammalib::strip_whitespace(specresp->unit())); double c_specresp = 1.0; if (u_specresp == "m^2" || u_specresp == "m2") { c_specresp = 10000.0; } // Extract number of energy bins int num = energy_lo->length(); // Set energy bins for (int i = 0; i < num; ++i) { // Append energy bin GEnergy emin(energy_lo->real(i), energy_lo->unit()); GEnergy emax(energy_hi->real(i), energy_hi->unit()); m_ebounds.append(emin, emax); // Append effective area value double aeff = specresp->real(i) * c_specresp; m_specresp.push_back(aeff); } // endfor: looped over energy bins // Read any additional columns for (int icol = 0; icol < table.ncols(); ++icol) { // Fall through if the column is a standard column std::string colname(table[icol]->name()); if ((colname == "ENERG_LO") || (colname == "ENERG_HI") || (colname == "SPECRESP")) { continue; } // Get pointer to column const GFitsTableCol* column = table[icol]; // Set column vector std::vector<double> coldata; for (int i = 0; i < num; ++i) { coldata.push_back(column->real(i)); } // Append column append(colname, coldata); } // endfor: looped over all additional columns // Return return; }
/***********************************************************************//** * @brief Setup observation container * * @exception GException::no_cube * No event cube found in CTA observation. * * This method sets up the observation container for processing. There are * two cases: * * If there are no observations in the actual observation container, the * method will check in "infile" parameter. If this parameter is "NONE" or * empty, the task parameters will be used to construct a model map. * Otherwise, the method first tries to interpret the "infile" parameter as * a counts map, and attemps loading of the file in an event cube. If this * fails, the method tries to interpret the "infile" parameter as an * observation definition XML file. If this also fails, an exception will * be thrown. * * If observations exist already in the observation container, the method * will simply keep them. * * Test if all CTA observations contain counts maps. * * Finally, if no models exist so far in the observation container, the * models will be loaded from the model XML file. ***************************************************************************/ void ctmodel::setup_obs(void) { // If there are no observations in the container then try to build some if (m_obs.size() == 0) { // If no input filename has been specified, then create a model map // from the task parameters if ((m_infile == "NONE") || (gammalib::strip_whitespace(m_infile) == "")) { // Set pointing direction GCTAPointing pnt; GSkyDir skydir; skydir.radec_deg(m_ra, m_dec); pnt.dir(skydir); // Setup energy range covered by model GEnergy emin(m_emin, "TeV"); GEnergy emax(m_emax, "TeV"); GEbounds ebds(m_enumbins, emin, emax); // Setup time interval covered by model GGti gti; GTime tmin(m_tmin); GTime tmax(m_tmax); gti.append(tmin, tmax); // Setup skymap GSkymap map = GSkymap(m_proj, m_coordsys, m_xref, m_yref, -m_binsz, m_binsz, m_nxpix, m_nypix, m_enumbins); // Create model cube from sky map GCTAEventCube cube(map, ebds, gti); // Allocate CTA observation GCTAObservation obs; // Set CTA observation attributes obs.pointing(pnt); obs.ontime(gti.ontime()); obs.livetime(gti.ontime()*m_deadc); obs.deadc(m_deadc); // Set event cube in observation obs.events(cube); // Append CTA observation to container m_obs.append(obs); // Signal that no XML file should be used for storage m_use_xml = false; } // endif: created model map from task parameters // ... otherwise try to load information from the file else { // First try to open the file as a counts map try { // Allocate CTA observation GCTAObservation obs; // Load counts map in CTA observation obs.load_binned(m_infile); // Append CTA observation to container m_obs.append(obs); // Signal that no XML file should be used for storage m_use_xml = false; } // ... otherwise try to open as XML file catch (GException::fits_open_error &e) { // Load observations from XML file. This will throw // an exception if it fails. m_obs.load(m_infile); // Signal that XML file should be used for storage m_use_xml = true; } } // endelse: loaded information from input file } // endif: there was no observation in the container // If there are no models associated with the observations then // load now the model definition from the XML file if (m_obs.models().size() == 0) { m_obs.models(GModels(m_srcmdl)); } // Check if all CTA observations contain an event cube and setup response // for all observations for (int i = 0; i < m_obs.size(); ++i) { // Is this observation a CTA observation? GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); // Yes ... if (obs != NULL) { // Throw an exception if this observation does not contain // an event cube if (dynamic_cast<const GCTAEventCube*>(obs->events()) == NULL) { throw GException::no_cube(G_SETUP_OBS); } // Set response if it isn't set already if (obs->response().aeff() == NULL) { // Set calibration database. If specified parameter is a // directory then use this as the pathname to the calibration // database. Otherwise interpret this as the instrument name, // the mission being "cta" GCaldb caldb; if (gammalib::dir_exists(m_caldb)) { caldb.rootdir(m_caldb); } else { caldb.open("cta", m_caldb); } // Set reponse obs->response(m_irf, caldb); } // endif: observation already has a response } // endif: observation was a CTA observation } // endfor: looped over all observations // Return return; }
/***********************************************************************//** * @brief Update precomputed values * * @param[in] srcEng Source energy ***************************************************************************/ void GModelSpectralPlaw2::update(const GEnergy& srcEng) const { // Compute index+1 double gamma = index() + 1.0; // Change in spectral index? if (index() != m_last_index) { // Save actual spectral index m_last_index = index(); // Change in energy boundaries? if (emin() != m_last_emin || emax() != m_last_emax) { m_log_emin = std::log(emin().MeV()); m_last_emin = emin(); m_log_emax = std::log(emax().MeV()); m_last_emax = emax(); } // Compute normalization factors if (gamma != 0.0) { m_pow_emin = std::pow(emin().MeV(), gamma); m_pow_emax = std::pow(emax().MeV(), gamma); double d = m_pow_emax - m_pow_emin; m_norm = gamma / d; m_g_norm = 1.0/gamma - (m_pow_emax*m_log_emax - m_pow_emin*m_log_emin)/d; } else { m_norm = 1.0 / (m_log_emax - m_log_emin); m_g_norm = 0.0; } // Update power law factor m_power = std::pow(srcEng.MeV(), index()); m_last_energy = srcEng; } // endif: change in spectral index // ... no change in spectral index else { // Change in energy boundaries? if (emin() != m_last_emin || emax() != m_last_emax) { // Update energy boundaries m_log_emin = std::log(emin().MeV()); m_last_emin = emin(); m_log_emax = std::log(emax().MeV()); m_last_emax = emax(); // Compute power law normalization if (gamma != 0.0) { m_pow_emin = std::pow(emin().MeV(), gamma); m_pow_emax = std::pow(emax().MeV(), gamma); double d = m_pow_emax - m_pow_emin; m_norm = gamma / d; m_g_norm = 1.0/gamma - (m_pow_emax*m_log_emax - m_pow_emin*m_log_emin)/d; } else { m_norm = 1.0 / (m_log_emax - m_log_emin); m_g_norm = 0.0; } } // endif: change in energy boundaries // Change in energy? if (srcEng != m_last_energy) { m_power = std::pow(srcEng.MeV(), index()); m_last_energy = srcEng; } } // endelse: no change in spectral index // Return return; }
// // R_InitSubMap // // Initialize translucency filter map // void R_InitSubMap(bool force) { static bool prev_fromlump = false; static int prev_lumpnum = -1; static bool prev_built = false; static byte prev_palette[768]; AutoPalette pal(wGlobalDir); byte *playpal = pal.get(); // if forced to rebuild, do it now regardless of settings if(force) { prev_fromlump = false; prev_lumpnum = -1; prev_built = false; memset(prev_palette, 0, sizeof(prev_palette)); } int lump = W_CheckNumForName("SUBMAP"); // If a translucency filter map lump is present, use it if(lump != -1) // Set a pointer to the translucency filter maps. { // check if is same as already loaded if(prev_fromlump && prev_lumpnum == lump && !memcmp(playpal, prev_palette, 768)) return; if(main_submap) efree(main_submap); main_submap = (byte *)(wGlobalDir.cacheLumpNum(lump, PU_STATIC)); // killough 4/11/98 prev_fromlump = true; prev_lumpnum = lump; prev_built = false; memcpy(prev_palette, playpal, 768); } else { // check if is same as already loaded if(prev_built && !memcmp(playpal, prev_palette, 768)) return; // Compose a default transparent filter map based on PLAYPAL. if(main_submap) efree(main_submap); main_submap = ecalloc(byte *, 256, 256); // killough 4/11/98 prev_fromlump = false; prev_lumpnum = -1; prev_built = true; memcpy(prev_palette, playpal, 768); int pal[3][256], tot[256]; // First, convert playpal into long int type, and transpose array, // for fast inner-loop calculations. Precompute tot array. { int i = 255; const unsigned char *p = playpal + 255 * 3; do { int t,d; pal[0][i] = t = p[0]; d = t*t; pal[1][i] = t = p[1]; d += t*t; pal[2][i] = t = p[2]; d += t*t; p -= 3; tot[i] = d/2; } while (--i >= 0); } // Next, compute all entries using minimum arithmetic. byte *tp = main_submap; for(int i = 0; i < 256; i++) { int r1 = pal[0][i]; int g1 = pal[1][i]; int b1 = pal[2][i]; for(int j = 0; j < 256; j++, tp++) { int color = 255; int err; // haleyjd: subtract and clamp to 0 int r = emax(r1 - pal[0][j], 0); int g = emax(g1 - pal[1][j], 0); int b = emax(b1 - pal[2][j], 0); int best = INT_MAX; do { if((err = tot[color] - pal[0][color]*r - pal[1][color]*g - pal[2][color]*b) < best) best = err, *tp = color; } while(--color >= 0); } } } }