示例#1
0
/***********************************************************************//**
 * @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;
}
示例#2
0
/***********************************************************************//**
 * @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;
}
示例#3
0
/***********************************************************************//**
 * @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;
}
示例#4
0
/***********************************************************************//**
 * @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;
}
示例#5
0
/***********************************************************************//**
 * @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;
}
示例#6
0
/***********************************************************************//**
 * @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;
}
示例#8
0
//
// 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);
         }
      }
   }
}