/***********************************************************************//** * @brief Set pointers * * Set pointers to all model parameters. The pointers are stored in a vector * that is member of the GModelData base class. ***************************************************************************/ void GCTAModelCubeBackground::set_pointers(void) { // Clear parameters m_pars.clear(); // Determine the number of parameters int n_spectral = (spectral() != NULL) ? spectral()->size() : 0; int n_temporal = (temporal() != NULL) ? temporal()->size() : 0; int n_pars = n_spectral + n_temporal; // Continue only if there are parameters if (n_pars > 0) { // Gather spectral parameters for (int i = 0; i < n_spectral; ++i) { m_pars.push_back(&((*spectral())[i])); } // Gather temporal parameters for (int i = 0; i < n_temporal; ++i) { m_pars.push_back(&((*temporal())[i])); } } // Return return; }
/***********************************************************************//** * @brief Write model into XML element * * @param[in] xml XML element. * * @todo Document method. ***************************************************************************/ void GCTAModelBackground::write(GXmlElement& xml) const { // Initialise pointer on source GXmlElement* src = NULL; // Search corresponding source int n = xml.elements("source"); for (int k = 0; k < n; ++k) { GXmlElement* element = xml.element("source", k); if (element->attribute("name") == name()) { src = element; break; } } // If no source with corresponding name was found then append one if (src == NULL) { src = xml.append("source"); if (spectral() != NULL) src->append(GXmlElement("spectrum")); if (spatial() != NULL) src->append(GXmlElement("spatialModel")); //if (temporal() != NULL) src->append(GXmlElement("temporalModel")); } // Set model type, name and optionally instruments src->attribute("name", name()); src->attribute("type", type()); if (instruments().length() > 0) { src->attribute("instrument", instruments()); } std::string identifiers = ids(); if (identifiers.length() > 0) { src->attribute("id", identifiers); } // Write spectral model if (spectral() != NULL) { GXmlElement* spec = src->element("spectrum", 0); spectral()->write(*spec); } // Write spatial model if (spatial() != NULL) { GXmlElement* spat = src->element("spatialModel", 0); spatial()->write(*spat); } // Write temporal model /* if (temporal() != NULL) { if (dynamic_cast<GModelTemporalConst*>(temporal()) == NULL) { GXmlElement* temp = src->element("temporalModel", 0); temporal()->write(*temp); } } */ // Return return; }
/***********************************************************************//** * @brief Write CTA instrument background model into XML element * * @param[in] xml XML element. * * Write CTA instrument background model information into an XML element. * The XML element will have the following structure * * <source name="..." type="..." instrument="..."> * <spectrum type="..."> * ... * </spectrum> * </source> * * If the model contains a non-constant temporal model, the temporal * component will also be written following the syntax * * <source name="..." type="..." instrument="..."> * <spectrum type="..."> * ... * </spectrum> * <temporalModel type="..."> * ... * </temporalModel> * </source> * * If no temporal component is found a constant model is assumed. ***************************************************************************/ void GCTAModelIrfBackground::write(GXmlElement& xml) const { // Initialise pointer on source GXmlElement* src = NULL; // Search corresponding source int n = xml.elements("source"); for (int k = 0; k < n; ++k) { GXmlElement* element = xml.element("source", k); if (element->attribute("name") == name()) { src = element; break; } } // If we have a temporal model that is either not a constant, or a // constant with a normalization value that differs from 1.0 then // write the temporal component into the XML element. This logic // assures compatibility with the Fermi/LAT format as this format // does not handle temporal components. bool write_temporal = ((m_temporal != NULL) && (m_temporal->type() != "Constant" || (*m_temporal)[0].value() != 1.0)); // If no source with corresponding name was found then append one if (src == NULL) { src = xml.append("source"); if (spectral() != NULL) src->append(GXmlElement("spectrum")); if (write_temporal) src->append(GXmlElement("temporalModel")); } // Set model type, name and optionally instruments src->attribute("name", name()); src->attribute("type", type()); if (instruments().length() > 0) { src->attribute("instrument", instruments()); } std::string identifiers = ids(); if (identifiers.length() > 0) { src->attribute("id", identifiers); } // Write spectral model if (spectral() != NULL) { GXmlElement* spec = src->element("spectrum", 0); spectral()->write(*spec); } // Optionally write temporal model if (write_temporal) { if (dynamic_cast<GModelTemporalConst*>(temporal()) == NULL) { GXmlElement* temp = src->element("temporalModel", 0); temporal()->write(*temp); } } // Return return; }
/***********************************************************************//** * @brief Evaluate function * * @param[in] event Observed event. * @param[in] obs Observation. * @return Function value. * * @exception GException::invalid_argument * Specified observation is not of the expected type. * * @todo Make sure that DETX and DETY are always set in GCTAInstDir. ***************************************************************************/ double GCTAModelIrfBackground::eval(const GEvent& event, const GObservation& obs) const { // Get pointer on CTA observation const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); if (cta == NULL) { std::string msg = "Specified observation is not a CTA observation.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Get pointer on CTA IRF response const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response()); if (rsp == NULL) { std::string msg = "Specified observation does not contain an IRF response.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Retrieve pointer to CTA background const GCTABackground* bgd = rsp->background(); if (bgd == NULL) { std::string msg = "Specified observation contains no background" " information.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Extract CTA instrument direction from event const GCTAInstDir* dir = dynamic_cast<const GCTAInstDir*>(&(event.dir())); if (dir == NULL) { std::string msg = "No CTA instrument direction found in event."; throw GException::invalid_argument(G_EVAL, msg); } // Set DETX and DETY in instrument direction GCTAInstDir inst_dir = cta->pointing().instdir(dir->dir()); // Evaluate function double logE = event.energy().log10TeV(); double spat = (*bgd)(logE, inst_dir.detx(), inst_dir.dety()); double spec = (spectral() != NULL) ? spectral()->eval(event.energy(), event.time()) : 1.0; double temp = (temporal() != NULL) ? temporal()->eval(event.time()) : 1.0; // Compute value double value = spat * spec * temp; // Apply deadtime correction value *= obs.deadc(event.time()); // Return value return value; }
/***********************************************************************//** * @brief Print CTA cube background model information * * @param[in] chatter Chattiness (defaults to NORMAL). * @return String containing CTA cube background model information. ***************************************************************************/ std::string GCTAModelCubeBackground::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("=== GCTAModelCubeBackground ==="); // Determine number of parameters per type int n_spectral = (spectral() != NULL) ? spectral()->size() : 0; int n_temporal = (temporal() != NULL) ? temporal()->size() : 0; // Append attributes result.append("\n"+print_attributes()); // Append model type result.append("\n"+gammalib::parformat("Model type")); if (n_spectral > 0) { result.append("\""+spectral()->type()+"\""); if (n_temporal > 0) { result.append(" * "); } } if (n_temporal > 0) { result.append("\""+temporal()->type()+"\""); } // Append parameters result.append("\n"+gammalib::parformat("Number of parameters") + gammalib::str(size())); result.append("\n"+gammalib::parformat("Number of spectral par's") + gammalib::str(n_spectral)); for (int i = 0; i < n_spectral; ++i) { result.append("\n"+(*spectral())[i].print()); } result.append("\n"+gammalib::parformat("Number of temporal par's") + gammalib::str(n_temporal)); for (int i = 0; i < n_temporal; ++i) { result.append("\n"+(*temporal())[i].print()); } } // endif: chatter was not silent // Return result return result; }
/***********************************************************************//** * @brief Print model information ***************************************************************************/ std::string GModelSky::print_model(void) const { // Initialise result string std::string result; // Determine number of parameters per type int n_spatial = (m_spatial != NULL) ? m_spatial->size() : 0; int n_spectral = (m_spectral != NULL) ? m_spectral->size() : 0; int n_temporal = (m_temporal != NULL) ? m_temporal->size() : 0; // Append attributes result.append(print_attributes()); // Append model type result.append("\n"+parformat("Model type")); if (n_spatial > 0) { result.append("\""+spatial()->type()+"\""); if (n_spectral > 0 || n_temporal > 0) { result.append(" * "); } } if (n_spectral > 0) { result.append("\""+spectral()->type()+"\""); if (n_temporal > 0) { result.append(" * "); } } if (n_temporal > 0) { result.append("\""+temporal()->type()+"\""); } // Append parameters result.append("\n"+parformat("Number of parameters")+str(size())); result.append("\n"+parformat("Number of spatial par's")+str(n_spatial)); for (int i = 0; i < n_spatial; ++i) { result.append("\n"+(*spatial())[i].print()); } result.append("\n"+parformat("Number of spectral par's")+str(n_spectral)); for (int i = 0; i < n_spectral; ++i) { result.append("\n"+(*spectral())[i].print()); } result.append("\n"+parformat("Number of temporal par's")+str(n_temporal)); for (int i = 0; i < n_temporal; ++i) { result.append("\n"+(*temporal())[i].print()); } // Return result return result; }
/***********************************************************************//** * @brief Write model into XML element * * @param[in] xml Source library. ***************************************************************************/ void GModelSky::write(GXmlElement& xml) const { // Initialise pointer on source GXmlElement* src = NULL; // Search corresponding source int n = xml.elements("source"); for (int k = 0; k < n; ++k) { GXmlElement* element = static_cast<GXmlElement*>(xml.element("source", k)); if (element->attribute("name") == name()) { src = element; break; } } // If no source with corresponding name was found then append one if (src == NULL) { src = new GXmlElement("source"); src->attribute("name") = name(); if (spectral() != NULL) src->append(new GXmlElement("spectrum")); if (spatial() != NULL) src->append(new GXmlElement("spatialModel")); xml.append(src); } // Set model attributes src->attribute("name", name()); src->attribute("type", type()); std::string instruments = this->instruments(); if (instruments.length() > 0) { src->attribute("instrument", instruments); } // Write spectral model if (spectral() != NULL) { GXmlElement* spec = static_cast<GXmlElement*>(src->element("spectrum", 0)); spectral()->write(*spec); } // Write spatial model if (spatial() != NULL) { GXmlElement* spat = static_cast<GXmlElement*>(src->element("spatialModel", 0)); spatial()->write(*spat); } // Return return; }
/***********************************************************************//** * @brief Verifies if model has all components * * Returns 'true' if models has a spectral and a temporal component. * Otherwise returns 'false'. ***************************************************************************/ bool GCTAModelCubeBackground::valid_model(void) const { // Set result bool result = ((spectral() != NULL) && (temporal() != NULL)); // Return result return result; }
/***********************************************************************//** * @brief Evaluate function * * @param[in] event Observed event. * @param[in] obs Observation. * @return Function value. * * @exception GException::invalid_argument * Specified observation is not of the expected type. ***************************************************************************/ double GCTAModelCubeBackground::eval(const GEvent& event, const GObservation& obs) const { // Get pointer on CTA observation const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); if (cta == NULL) { std::string msg = "Specified observation is not a CTA observation."; throw GException::invalid_argument(G_EVAL, msg); } // Get pointer on CTA IRF response const GCTAResponseCube* rsp = dynamic_cast<const GCTAResponseCube*>(cta->response()); if (rsp == NULL) { std::string msg = "Specified observation does not contain a cube response."; throw GException::invalid_argument(G_EVAL, msg); } // Extract CTA instrument direction from event const GCTAInstDir* dir = dynamic_cast<const GCTAInstDir*>(&(event.dir())); if (dir == NULL) { std::string msg = "No CTA instrument direction found in event."; throw GException::invalid_argument(G_EVAL, msg); } // Retrieve reference to CTA cube background const GCTACubeBackground& bgd = rsp->background(); // Evaluate function //double logE = event.energy().log10TeV(); double spat = bgd((*dir), event.energy()); double spec = (spectral() != NULL) ? spectral()->eval(event.energy(), event.time()) : 1.0; double temp = (temporal() != NULL) ? temporal()->eval(event.time()) : 1.0; // Compute value. Note that background rates are already per // livetime, hence no deadtime correction is needed here. double value = spat * spec * temp; // Return value return value; }
/***********************************************************************//** * @brief Evaluate function * * @param[in] event Observed event. * @param[in] obs Observation. * @return Function value. * * @exception GException::invalid_argument * No CTA instrument direction found in event. * * Evaluates tha CTA background model which is a factorization of a * spatial, spectral and temporal model component. This method also applies * a deadtime correction factor, so that the normalization of the model is * a real rate (counts/exposure time). * * @todo Add bookkeeping of last value and evaluate only if argument * changed ***************************************************************************/ double GCTAModelBackground::eval(const GEvent& event, const GObservation& obs) const { // Get pointer on CTA observation const GCTAObservation* ctaobs = dynamic_cast<const GCTAObservation*>(&obs); if (ctaobs == NULL) { std::string msg = "Specified observation is not a CTA observation.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Extract CTA instrument direction const GCTAInstDir* dir = dynamic_cast<const GCTAInstDir*>(&(event.dir())); if (dir == NULL) { std::string msg = "No CTA instrument direction found in event."; throw GException::invalid_argument(G_EVAL, msg); } // Create a Photon from the event. // We need the GPhoton to evaluate the spatial model. // For the background, GEvent and GPhoton are identical // since the IRFs are not folded in GPhoton photon(dir->dir(), event.energy(), event.time()); // Evaluate function and gradients double spat = (spatial() != NULL) ? spatial()->eval(photon) : 1.0; double spec = (spectral() != NULL) ? spectral()->eval(event.energy(), event.time()) : 1.0; double temp = (temporal() != NULL) ? temporal()->eval(event.time()) : 1.0; // Compute value double value = spat * spec * temp; // Apply deadtime correction value *= obs.deadc(event.time()); // Return return value; }
/***********************************************************************//** * @brief Return spatially integrated sky model * * @param[in] obsEng Measured photon energy. * @param[in] obsTime Measured photon arrival time. * @param[in] obs Observation. * * @exception GException::no_response * No valid instrument response function defined. * * Computes * \f[N"_{\rm pred} = \int_{\rm ROI} * S(\vec{p}, E, t) PSF(\vec{p'}, E', t' | \vec{d}, \vec{p}, E, t) \, * {\rm d}\vec{p'}\f] * where * \f$S(\vec{p}, E, t)\f$ is the source model, * \f$PSF(\vec{p'}, E', t' | \vec{d}, \vec{p}, E, t)\f$ is the point * spread function, * \f$\vec{p'}\f$ is the measured photon direction, * \f$E'\f$ is the measured photon energy, * \f$t'\f$ is the measured photon arrival time, * \f$\vec{p}\f$ is the true photon arrival direction, * \f$E\f$ is the true photon energy, * \f$t\f$ is the true photon arrival time, and * \f$d\f$ is the instrument pointing. * * \f${\rm ROI}\f$ is the region of interest that is stored in the * GObservation::m_roi member. The integration over the ROI is performed * by the GResponse::npred() method. * * @todo The actual method is only correct if no energy and time dispersion * exists. For the moment we set srcEng=obsEng and srcTime=obsTime. * Formally, Equation (2) of the instrument document has to be * computed, which is an integration over source energy, time * and arrival direction. For the moment, only the integration over * arrival direction is performed by GResponse::npred(). ***************************************************************************/ double GModelSky::npred(const GEnergy& obsEng, const GTime& obsTime, const GObservation& obs) const { // Initialise result double npred = 0.0; // Continue only if model is valid) if (valid_model()) { // Get response function GResponse* rsp = obs.response(); if (rsp == NULL) { throw GException::no_response(G_NPRED); } // Here we make the simplifying approximations // srcEng=obsEng and srcTime=obsTime. To be fully correct we should // integrate over true energy and true time here ... at least true // time if we want to consider energy dispersion ... GEnergy srcEng = obsEng; GTime srcTime = obsTime; // Set source GSource source(this->name(), *m_spatial, srcEng, srcTime); // Compute response components double npred_spatial = rsp->npred(source, obs); double npred_spectral = spectral()->eval(srcEng); double npred_temporal = temporal()->eval(srcTime); // Compute response npred = npred_spatial * npred_spectral * npred_temporal; // Compile option: Check for NaN/Inf #if defined(G_NAN_CHECK) if (isnotanumber(npred) || isinfinite(npred)) { std::cout << "*** ERROR: GModelSky::npred:"; std::cout << " NaN/Inf encountered"; std::cout << " (npred=" << npred; std::cout << ", npred_spatial=" << npred_spatial; std::cout << ", npred_spectral=" << npred_spectral; std::cout << ", npred_temporal=" << npred_temporal; std::cout << ", srcEng=" << srcEng; std::cout << ", srcTime=" << srcTime; std::cout << ")" << std::endl; } #endif } // endif: model was valid // Return npred return npred; }
void graphsound(unsigned f[], int n){ int i, y; float tmp; window(1,18,80,50); clrscr(); window(1,1,80,50); for(i = 0; i < n; i++){ tmp = (float)f[i] * 78 / MAX_FREQ; y = (int)tmp; gotoxy(2, i + 18); spectral(y+1); } }
/***********************************************************************//** * @brief Perform integration over temporal component * * @param[in] event Observed event. * @param[in] obs Observation. * @param[in] grad Evaluate gradients. * * @exception GException::no_response * Observation has no valid instrument response * @exception GException::feature_not_implemented * Temporal integration not yet implemented * * This method integrates the source model over the temporal component. If * the response function has no time dispersion then no temporal integration * is needed and the observed photon arrival time is identical to the true * photon arrival time. * * @todo Needs implementation of temporal integration to handle time * dispersion. ***************************************************************************/ double GModelSky::temporal(const GEvent& event, const GObservation& obs, bool grad) const { // Initialise result double value = 0.0; // Get response function GResponse* rsp = obs.response(); if (rsp == NULL) { throw GException::no_response(G_TEMPORAL); } // Determine if time integration is needed bool integrate = rsp->hastdisp(); // Case A: Integraion if (integrate) { throw GException::feature_not_implemented(G_TEMPORAL); } // Case B: No integration (assume no time dispersion) else { value = spectral(event, event.time(), obs, grad); } // Compile option: Check for NaN/Inf #if defined(G_NAN_CHECK) if (isnotanumber(value) || isinfinite(value)) { std::cout << "*** ERROR: GModelSky::temporal:"; std::cout << " NaN/Inf encountered"; std::cout << " (value=" << value; std::cout << ", event=" << event; std::cout << ")" << std::endl; } #endif // Return value return value; }
//-***************************************************************************** int main(int argc, char* argv[]) { int powerOfTwo = 12; ewav::RSpatialField2Df spatial(powerOfTwo); int N = spatial.width(); std::cout << "Made " << N << " x " << N << " spatial field." << std::endl; ewav::CSpectralField2Df spectral(powerOfTwo); std::cout << "Made " << N << " x " << N << " spectral field." << std::endl; ewav::SpectralToSpatial2Df convert(spectral, spatial); std::cout << "Made " << N << " x " << N << " converter." << std::endl; // Fill spectral { RandFillFunctor F; F.Spectral = spectral.data(); F.StrideJ = spectral.stride(); F.N = N; F.Domain = 1000.0f; F.Seed = 54321; // Rows, then columns. tbb::blocked_range2d<int> range{0, spectral.height(), 1, 0, spectral.width(), 512}; tbb::parallel_for(range, F); } std::cout << "Filled spectral array with gaussian random numbers" << std::endl; // Convert. convert.execute(spectral, spatial); std::cout << "Converted to spatial." << std::endl << "Spatial midpoint: " << spatial[N / 2][N / 2] << std::endl; return 0; }
void main(){ int i; int key = 0, flag = 0; int sel = 0; int reps = 1; unsigned freq[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0}; unsigned t[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0}; textmode(C4350); clrscr(); graphsound(freq, 32); gotoxy(1, sel + 18); putch(26); _setcursortype(_NOCURSOR); gotoxy(50, 4); cprintf("Frecuencia: %5u Hz", freq[sel]); gotoxy(50, 5); cprintf("Tiempo: %03.3f secs", (float)t[sel] / 1000); gotoxy(50, 6); cprintf("Repeticiones: %3d ", reps); int lastsel = 0; gotoxy(2,2); cputs("F1 Reset\n\r"); cputs(" F2 Guardar\n\r"); cputs(" F3 Cargar\n\r "); putch(24); putch(25); cputs(" Seleccionar\n\r "); putch(27); putch(26); cputs(" Disminuir/Incrementar frecuencia\n\r"); cputs(" -+ Disminuir/Incrementar tiempo\n\r"); cputs(" ENTER Ejecutar sonido\n\r"); cputs(" Fin/Inicio Disminuir/Incrementar tiempo total\n\r"); cputs(" F9/F10 Disminuir/Incrementar frecuencia en todos\n\r"); cputs(" ESPACIO Ejecutar seleccionado\n\r"); cputs(" F4 Editar frecuencia\n\r"); cputs(" F5 Editar tiempo\n\r"); cputs(" F6 Invertir frecuencia\n\r"); cputs(" RePag Incrementa las repeticiones\n\r"); cputs(" AvPag Disminuye las repeticiones\n\r"); cputs(" ESC Salir"); do{ key = 0; key = bioskey(0); if(key == SC_ARRIBA) sel--; if(key == SC_ABAJO) sel++; if(key == SC_DER){ freq[sel]+=4; gotoxy(2, sel + 18); spectral((int)((float)freq[sel] * 78 / MAX_FREQ)); } if(key == SC_IZQ){ freq[sel]-=4; gotoxy(2, sel + 18); spectral((int)((float)freq[sel] * 78 / MAX_FREQ)); } if(sel > 31) sel = 0; if(sel < 0) sel = 31; if(freq[sel] < 0) freq[sel] = 0; if(freq[sel] > MAX_FREQ) freq[sel] = MAX_FREQ; gotoxy(1, lastsel + 18); putch(32); gotoxy(1, sel + 18); putch(26); if(key == SC_MINUS) t[sel]--; if(key == SC_PLUS) t[sel]++; if(key == SC_ENTER) play(freq, t, 32, reps); if(key == 0x011B) flag = 1; if(key == 0x5100) reps--; if(key == 0x4900) reps++; if(key == 0x3C00) savesound(freq, t, 32); if(key == 0x3D00){ loadsound(freq, t, 32); graphsound(freq, 32); } if(key == 0x3920){ sound(freq[sel]); delay(t[sel]); nosound(); } if(key == 0x3B00){ for(i = 0; i < 32; i++){ freq[i] = 0; t[i] = 0; } graphsound(freq,32); } if(key == 0x3E00){ gotoxy(1,1); printf("Frecuencia: "); _setcursortype(_NORMALCURSOR); scanf("%d", &freq[sel]); _setcursortype(_NOCURSOR); fflush(stdin); gotoxy(1,1); printchars(32, 79); graphsound(freq, 32); } if(key == 0x3F00){ gotoxy(1,1); printf("Tiempo (milisegundos): "); _setcursortype(_NORMALCURSOR); scanf("%d", &t[sel]); _setcursortype(_NOCURSOR); fflush(stdin); gotoxy(1,1); printchars(32, 79); } if(key == 0x4000){ freq[sel] = MAX_FREQ - freq[sel]; gotoxy(2, sel + 18); spectral((int)((float)freq[sel] * 78 / MAX_FREQ)); } if(key == 0x4700){ for(i = 0; i < 32; i++){ if(freq[i] != 0) t[i]++; } } if(key == 0x4F00){ for(i = 0; i < 32; i++){ if((freq[i] != 0) && (t[i] != 0)) t[i]--; } } if(key == 0x4300){ for(i = 0; i < 32; i++){ if(freq[i] != 0) freq[i]-=4; if(kbhit())getch(); } graphsound(freq, 32); } if(key == 0x4400){ for(i = 0; i < 32; i++){ freq[i]+=4; if(freq[i] > MAX_FREQ) freq[i] = MAX_FREQ; if(kbhit())getch(); } graphsound(freq, 32); } if(t[sel] > 5000) t[sel] = 5000; gotoxy(1, lastsel + 18); putch(32); gotoxy(1, sel + 18); putch(26); gotoxy(50, 4); cprintf("Frecuencia: %5u Hz", freq[sel]); gotoxy(50, 5); cprintf("Tiempo: %03.3f secs", (float)t[sel] / 1000); gotoxy(50, 6); cprintf("Repeticiones: %3d ", reps); lastsel = sel; }while(flag == 0); _setcursortype(_NORMALCURSOR); clrscr(); }
/***********************************************************************//** * @brief Return spatially integrated background model * * @param[in] obsEng Measured event energy. * @param[in] obsTime Measured event time. * @param[in] obs Observation. * @return Spatially integrated model. * * @exception GException::invalid_argument * The specified observation is not a CTA observation. * * Spatially integrates the instrumental background model for a given * measured event energy and event time. This method also applies a deadtime * correction factor, so that the normalization of the model is a real rate * (counts/MeV/s). ***************************************************************************/ double GCTAModelIrfBackground::npred(const GEnergy& obsEng, const GTime& obsTime, const GObservation& obs) const { // Initialise result double npred = 0.0; bool has_npred = false; // Build unique identifier std::string id = obs.instrument() + "::" + obs.id(); // Check if Npred value is already in cache #if defined(G_USE_NPRED_CACHE) if (!m_npred_names.empty()) { // Search for unique identifier, and if found, recover Npred value // and break for (int i = 0; i < m_npred_names.size(); ++i) { if (m_npred_names[i] == id && m_npred_energies[i] == obsEng) { npred = m_npred_values[i]; has_npred = true; #if defined(G_DEBUG_NPRED) std::cout << "GCTAModelIrfBackground::npred:"; std::cout << " cache=" << i; std::cout << " npred=" << npred << std::endl; #endif break; } } } // endif: there were values in the Npred cache #endif // Continue only if no Npred cache value has been found if (!has_npred) { // Evaluate only if model is valid if (valid_model()) { // Get pointer on CTA observation const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); if (cta == NULL) { std::string msg = "Specified observation is not a CTA" " observation.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } // Get pointer on CTA IRF response const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response()); if (rsp == NULL) { std::string msg = "Specified observation does not contain" " an IRF response.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } // Retrieve pointer to CTA background const GCTABackground* bgd = rsp->background(); if (bgd == NULL) { std::string msg = "Specified observation contains no background" " information.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } // Get CTA event list const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs.events()); if (events == NULL) { std::string msg = "No CTA event list found in observation.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } // Get reference to ROI centre const GSkyDir& roi_centre = events->roi().centre().dir(); // Get ROI radius in radians double roi_radius = events->roi().radius() * gammalib::deg2rad; // Get log10 of energy in TeV double logE = obsEng.log10TeV(); // Setup integration function GCTAModelIrfBackground::npred_roi_kern_theta integrand(bgd, logE); // Setup integrator GIntegral integral(&integrand); integral.eps(g_cta_inst_background_npred_theta_eps); // Spatially integrate radial component npred = integral.romberg(0.0, roi_radius); // Store result in Npred cache #if defined(G_USE_NPRED_CACHE) m_npred_names.push_back(id); m_npred_energies.push_back(obsEng); m_npred_times.push_back(obsTime); m_npred_values.push_back(npred); #endif // Debug: Check for NaN #if defined(G_NAN_CHECK) if (gammalib::is_notanumber(npred) || gammalib::is_infinite(npred)) { std::string origin = "GCTAModelIrfBackground::npred"; std::string message = " NaN/Inf encountered (npred=" + gammalib::str(npred) + ", roi_radius=" + gammalib::str(roi_radius) + ")"; gammalib::warning(origin, message); } #endif } // endif: model was valid } // endif: Npred computation required // Multiply in spectral and temporal components npred *= spectral()->eval(obsEng, obsTime); npred *= temporal()->eval(obsTime); // Apply deadtime correction npred *= obs.deadc(obsTime); // Return Npred return npred; }
/***********************************************************************//** * @brief Return simulated list of events * * @param[in] obs Observation. * @param[in] ran Random number generator. * @return Pointer to list of simulated events (needs to be de-allocated by * client) * * @exception GException::invalid_argument * Specified observation is not a CTA observation. * * Draws a sample of events from the background model using a Monte * Carlo simulation. The region of interest, the energy boundaries and the * good time interval for the sampling will be extracted from the observation * argument that is passed to the method. The method also requires a random * number generator of type GRan which is passed by reference, hence the * state of the random number generator will be changed by the method. * * The method also applies a deadtime correction using a Monte Carlo process, * taking into account temporal deadtime variations. For this purpose, the * method makes use of the time dependent GObservation::deadc method. * * For each event in the returned event list, the sky direction, the nominal * coordinates (DETX and DETY), the energy and the time will be set. ***************************************************************************/ GCTAEventList* GCTAModelIrfBackground::mc(const GObservation& obs, GRan& ran) const { // Initialise new event list GCTAEventList* list = new GCTAEventList; // Continue only if model is valid) if (valid_model()) { // Retrieve CTA observation const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); if (cta == NULL) { std::string msg = "Specified observation is not a CTA observation.\n" + obs.print(); throw GException::invalid_argument(G_MC, msg); } // Get pointer on CTA IRF response const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response()); if (rsp == NULL) { std::string msg = "Specified observation does not contain" " an IRF response.\n" + obs.print(); throw GException::invalid_argument(G_MC, msg); } // Retrieve CTA response and pointing const GCTAPointing& pnt = cta->pointing(); // Get pointer to CTA background const GCTABackground* bgd = rsp->background(); if (bgd == NULL) { std::string msg = "Specified observation contains no background" " information.\n" + obs.print(); throw GException::invalid_argument(G_MC, msg); } // Retrieve event list to access the ROI, energy boundaries and GTIs const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs.events()); if (events == NULL) { std::string msg = "No CTA event list found in observation.\n" + obs.print(); throw GException::invalid_argument(G_MC, msg); } // Get simulation region const GCTARoi& roi = events->roi(); const GEbounds& ebounds = events->ebounds(); const GGti& gti = events->gti(); // Set simulation region for result event list list->roi(roi); list->ebounds(ebounds); list->gti(gti); // Create a spectral model that combines the information from the // background information and the spectrum provided by the model GModelSpectralNodes spectral(bgd->spectrum()); for (int i = 0; i < spectral.nodes(); ++i) { GEnergy energy = spectral.energy(i); double intensity = spectral.intensity(i); double norm = m_spectral->eval(energy, events->tstart()); spectral.intensity(i, norm*intensity); } // Loop over all energy boundaries for (int ieng = 0; ieng < ebounds.size(); ++ieng) { // Compute the background rate in model within the energy // boundaries from spectral component (units: cts/s). // Note that the time here is ontime. Deadtime correction will // be done later. double rate = spectral.flux(ebounds.emin(ieng), ebounds.emax(ieng)); // Debug option: dump rate #if defined(G_DUMP_MC) std::cout << "GCTAModelIrfBackground::mc(\"" << name() << "\": "; std::cout << "rate=" << rate << " cts/s)" << std::endl; #endif // Loop over all good time intervals for (int itime = 0; itime < gti.size(); ++itime) { // Get Monte Carlo event arrival times from temporal model GTimes times = m_temporal->mc(rate, gti.tstart(itime), gti.tstop(itime), ran); // Get number of events int n_events = times.size(); // Reserve space for events if (n_events > 0) { list->reserve(n_events); } // Debug option: provide number of times and initialize // statisics #if defined(G_DUMP_MC) std::cout << " Interval " << itime; std::cout << " times=" << n_events << std::endl; int n_killed_by_deadtime = 0; int n_killed_by_roi = 0; #endif // Loop over events for (int i = 0; i < n_events; ++i) { // Apply deadtime correction double deadc = obs.deadc(times[i]); if (deadc < 1.0) { if (ran.uniform() > deadc) { #if defined(G_DUMP_MC) n_killed_by_deadtime++; #endif continue; } } // Get Monte Carlo event energy from spectral model GEnergy energy = spectral.mc(ebounds.emin(ieng), ebounds.emax(ieng), times[i], ran); // Get Monte Carlo event direction from spatial model. // This only will set the DETX and DETY coordinates. GCTAInstDir instdir = bgd->mc(energy, times[i], ran); // Derive sky direction from instrument coordinates GSkyDir skydir = pnt.skydir(instdir); // Set sky direction in GCTAInstDir object instdir.dir(skydir); // Allocate event GCTAEventAtom event; // Set event attributes event.dir(instdir); event.energy(energy); event.time(times[i]); // Append event to list if it falls in ROI if (events->roi().contains(event)) { list->append(event); } #if defined(G_DUMP_MC) else { n_killed_by_roi++; } #endif } // endfor: looped over all events // Debug option: provide statisics #if defined(G_DUMP_MC) std::cout << " Killed by deadtime="; std::cout << n_killed_by_deadtime << std::endl; std::cout << " Killed by ROI="; std::cout << n_killed_by_roi << std::endl; #endif } // endfor: looped over all GTIs } // endfor: looped over all energy boundaries } // endif: model was valid // Return return list; }
/***********************************************************************//** * @brief Return spatially integrated background model * * @param[in] obsEng Measured event energy. * @param[in] obsTime Measured event time. * @param[in] obs Observation. * @return Spatially integrated model. * * @exception GException::invalid_argument * The specified observation is not a CTA observation. * * Spatially integrates the cube background model for a given measured event * energy and event time. This method also applies a deadtime correction * factor, so that the normalization of the model is a real rate * (counts/MeV/s). ***************************************************************************/ double GCTAModelCubeBackground::npred(const GEnergy& obsEng, const GTime& obsTime, const GObservation& obs) const { // Initialise result double npred = 0.0; bool has_npred = false; // Build unique identifier std::string id = obs.instrument() + "::" + obs.id(); // Check if Npred value is already in cache #if defined(G_USE_NPRED_CACHE) if (!m_npred_names.empty()) { // Search for unique identifier, and if found, recover Npred value // and break for (int i = 0; i < m_npred_names.size(); ++i) { if (m_npred_names[i] == id && m_npred_energies[i] == obsEng) { npred = m_npred_values[i]; has_npred = true; #if defined(G_DEBUG_NPRED) std::cout << "GCTAModelCubeBackground::npred:"; std::cout << " cache=" << i; std::cout << " npred=" << npred << std::endl; #endif break; } } } // endif: there were values in the Npred cache #endif // Continue only if no Npred cache value has been found if (!has_npred) { // Evaluate only if model is valid if (valid_model()) { // Get pointer on CTA observation const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); if (cta == NULL) { std::string msg = "Specified observation is not a CTA" " observation.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } // Get pointer on CTA cube response const GCTAResponseCube* rsp = dynamic_cast<const GCTAResponseCube*>(cta->response()); if (rsp == NULL) { std::string msg = "Specified observation does not contain" " a cube response.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } // Get log10 of energy in TeV double logE = obsEng.log10TeV(); // Retrieve CTA background const GCTACubeBackground bgd = rsp->background(); // Integrate the background map at a certain energy npred = bgd.integral(logE); // Store result in Npred cache #if defined(G_USE_NPRED_CACHE) m_npred_names.push_back(id); m_npred_energies.push_back(obsEng); m_npred_times.push_back(obsTime); m_npred_values.push_back(npred); #endif // Debug: Check for NaN #if defined(G_NAN_CHECK) if (gammalib::is_notanumber(npred) || gammalib::is_infinite(npred)) { std::string origin = "GCTAModelCubeBackground::npred"; std::string message = " NaN/Inf encountered (npred=" + gammalib::str(npred) + ")"; gammalib::warning(origin, message); } #endif } // endif: model was valid } // endif: Npred computation required // Multiply in spectral and temporal components npred *= spectral()->eval(obsEng, obsTime); npred *= temporal()->eval(obsTime); // Apply deadtime correction npred *= obs.deadc(obsTime); // Return Npred return npred; }
/***********************************************************************//** * @brief Evaluate function * * @param[in] event Observed event. * @param[in] obs Observation. * @param[in] gradients Compute gradients? * @return Function value. * * @exception GException::invalid_argument * Specified observation is not of the expected type. * * If the @p gradients flag is true the method will also set the parameter * gradients of the model parameters. * * @todo Make sure that DETX and DETY are always set in GCTAInstDir. ***************************************************************************/ double GCTAModelAeffBackground::eval(const GEvent& event, const GObservation& obs, const bool& gradients) const { // Get pointer on CTA observation const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); if (cta == NULL) { std::string msg = "Specified observation is not a CTA observation.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Get pointer on CTA IRF response const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response()); if (rsp == NULL) { std::string msg = "Specified observation does not contain an IRF response.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Retrieve pointer to CTA Effective Area const GCTAAeff* aeff = rsp->aeff(); if (aeff == NULL) { std::string msg = "Specified observation contains no effective area" " information.\n" + obs.print(); throw GException::invalid_argument(G_EVAL, msg); } // Extract CTA instrument direction from event const GCTAInstDir* dir = dynamic_cast<const GCTAInstDir*>(&(event.dir())); if (dir == NULL) { std::string msg = "No CTA instrument direction found in event."; throw GException::invalid_argument(G_EVAL, msg); } // Set DETX and DETY in instrument direction GCTAInstDir inst_dir = cta->pointing().instdir(dir->dir()); // Set theta and phi from instrument coordinates double theta = std::sqrt(inst_dir.detx() * inst_dir.detx() + inst_dir.dety() * inst_dir.dety()); double phi = gammalib::atan2d(inst_dir.dety(), inst_dir.detx()) * gammalib::deg2rad; // Evaluate function double logE = event.energy().log10TeV(); double spat = (*aeff)(logE, theta, phi, cta->pointing().zenith(), cta->pointing().azimuth(), false); double spec = (spectral() != NULL) ? spectral()->eval(event.energy(), event.time(), gradients) : 1.0; double temp = (temporal() != NULL) ? temporal()->eval(event.time(), gradients) : 1.0; // Compute value double value = spat * spec * temp; // Apply deadtime correction double deadc = obs.deadc(event.time()); value *= deadc; // Optionally compute partial derivatives if (gradients) { // Multiply factors to spectral gradients if (spectral() != NULL) { double fact = spat * temp * deadc; if (fact != 1.0) { for (int i = 0; i < spectral()->size(); ++i) (*spectral())[i].factor_gradient((*spectral())[i].factor_gradient() * fact ); } } // Multiply factors to temporal gradients if (temporal() != NULL) { double fact = spat * spec * deadc; if (fact != 1.0) { for (int i = 0; i < temporal()->size(); ++i) (*temporal())[i].factor_gradient((*temporal())[i].factor_gradient() * fact ); } } } // endif: computed partial derivatives // Return value return value; }
/***********************************************************************//** * @brief Return spatially integrated data model * * @param[in] obsEng Measured event energy. * @param[in] obsTime Measured event time. * @param[in] obs Observation. * @return Spatially integrated model. * * @exception GException::invalid_argument * No CTA event list found in observation. * No CTA pointing found in observation. * * Spatially integrates the data model for a given measured event energy and * event time. This method also applies a deadtime correction factor, so that * the normalization of the model is a real rate (counts/exposure time). ***************************************************************************/ double GCTAModelBackground::npred(const GEnergy& obsEng, const GTime& obsTime, const GObservation& obs) const { // Initialise result double npred = 0.0; bool has_npred = false; // Build unique identifier std::string id = obs.instrument() + "::" + obs.id(); // Check if Npred value is already in cache #if defined(G_USE_NPRED_CACHE) if (!m_npred_names.empty()) { // Search for unique identifier, and if found, recover Npred value // and break for (int i = 0; i < m_npred_names.size(); ++i) { if (m_npred_names[i] == id && m_npred_energies[i] == obsEng) { npred = m_npred_values[i]; has_npred = true; #if defined(G_DEBUG_NPRED) std::cout << "GCTAModelBackground::npred:"; std::cout << " cache=" << i; std::cout << " npred=" << npred << std::endl; #endif break; } } } // endif: there were values in the Npred cache #endif // Continue only if no Npred cache value was found if (!has_npred) { // Evaluate only if model is valid if (valid_model()) { // Get CTA event list const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs.events()); if (events == NULL) { std::string msg = "No CTA event list found in observation.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } #if !defined(G_NPRED_AROUND_ROI) // Get CTA pointing direction GCTAPointing* pnt = dynamic_cast<GCTAPointing*>(obs.pointing()); if (pnt == NULL) { std::string msg = "No CTA pointing found in observation.\n" + obs.print(); throw GException::invalid_argument(G_NPRED, msg); } #endif // Get reference to ROI centre const GSkyDir& roi_centre = events->roi().centre().dir(); // Get ROI radius in radians double roi_radius = events->roi().radius() * gammalib::deg2rad; // Get distance from ROI centre in radians #if defined(G_NPRED_AROUND_ROI) double roi_distance = 0.0; #else double roi_distance = roi_centre.dist(pnt->dir()); #endif // Initialise rotation matrix to transform from ROI system to // celestial coordinate system GMatrix ry; GMatrix rz; ry.eulery(roi_centre.dec_deg() - 90.0); rz.eulerz(-roi_centre.ra_deg()); GMatrix rot = (ry * rz).transpose(); // Compute position angle of ROI centre with respect to model // centre (radians) #if defined(G_NPRED_AROUND_ROI) double omega0 = 0.0; #else double omega0 = pnt->dir().posang(events->roi().centre().dir()); #endif // Setup integration function GCTAModelBackground::npred_roi_kern_theta integrand(spatial(), obsEng, obsTime, rot, roi_radius, roi_distance, omega0); // Setup integrator GIntegral integral(&integrand); integral.eps(1e-3); // Setup integration boundaries #if defined(G_NPRED_AROUND_ROI) double rmin = 0.0; double rmax = roi_radius; #else double rmin = (roi_distance > roi_radius) ? roi_distance-roi_radius : 0.0; double rmax = roi_radius + roi_distance; #endif // Spatially integrate radial component npred = integral.romb(rmin, rmax); // Store result in Npred cache #if defined(G_USE_NPRED_CACHE) m_npred_names.push_back(id); m_npred_energies.push_back(obsEng); m_npred_times.push_back(obsTime); m_npred_values.push_back(npred); #endif // Debug: Check for NaN #if defined(G_NAN_CHECK) if (gammalib::is_notanumber(npred) || gammalib::is_infinite(npred)) { std::cout << "*** ERROR: GCTAModelBackground::npred:"; std::cout << " NaN/Inf encountered"; std::cout << " (npred=" << npred; std::cout << ", roi_radius=" << roi_radius; std::cout << ")" << std::endl; } #endif } // endif: model was valid } // endif: Npred computation required // Multiply in spectral and temporal components npred *= spectral()->eval(obsEng, obsTime); npred *= temporal()->eval(obsTime); // Apply deadtime correction npred *= obs.deadc(obsTime); // Return Npred return npred; }
/***********************************************************************//** * @brief Evaluate function and gradients * * @param[in] event Observed event. * @param[in] obs Observation. * @return Function value. * * @exception GException::invalid_argument * No CTA instrument direction found in event. * * Evaluates tha CTA background model and parameter gradients. The CTA * background model is a factorization of a spatial, spectral and * temporal model component. This method also applies a deadtime correction * factor, so that the normalization of the model is a real rate * (counts/exposure time). * * @todo Add bookkeeping of last value and evaluate only if argument * changed ***************************************************************************/ double GCTAModelBackground::eval_gradients(const GEvent& event, const GObservation& obs) const { // Get pointer on CTA observation const GCTAObservation* ctaobs = dynamic_cast<const GCTAObservation*>(&obs); if (ctaobs == NULL) { std::string msg = "Specified observation is not a CTA observation.\n" + obs.print(); throw GException::invalid_argument(G_EVAL_GRADIENTS, msg); } // Extract CTA instrument direction const GCTAInstDir* dir = dynamic_cast<const GCTAInstDir*>(&(event.dir())); if (dir == NULL) { std::string msg = "No CTA instrument direction found in event."; throw GException::invalid_argument(G_EVAL_GRADIENTS, msg); } // Create a Photon from the event // We need the photon to evaluate the spatial model // For the background, GEvent and GPhoton are identical // since the IRFs are not folded in GPhoton photon = GPhoton(dir->dir(), event.energy(),event.time()); // Evaluate function and gradients double spat = (spatial() != NULL) ? spatial()->eval_gradients(photon) : 1.0; double spec = (spectral() != NULL) ? spectral()->eval_gradients(event.energy(), event.time()) : 1.0; double temp = (temporal() != NULL) ? temporal()->eval_gradients(event.time()) : 1.0; // Compute value double value = spat * spec * temp; // Apply deadtime correction double deadc = obs.deadc(event.time()); value *= deadc; // Multiply factors to spatial gradients if (spatial() != NULL) { double fact = spec * temp * deadc; if (fact != 1.0) { for (int i = 0; i < spatial()->size(); ++i) (*spatial())[i].factor_gradient( (*spatial())[i].factor_gradient() * fact ); } } // Multiply factors to spectral gradients if (spectral() != NULL) { double fact = spat * temp * deadc; if (fact != 1.0) { for (int i = 0; i < spectral()->size(); ++i) (*spectral())[i].factor_gradient( (*spectral())[i].factor_gradient() * fact ); } } // Multiply factors to temporal gradients if (temporal() != NULL) { double fact = spat * spec * deadc; if (fact != 1.0) { for (int i = 0; i < temporal()->size(); ++i) (*temporal())[i].factor_gradient( (*temporal())[i].factor_gradient() * fact ); } } // Return value return value; }
/***********************************************************************//** * @brief Returns spatial model component * * @param[in] event Observed event. * @param[in] srcEng True photon energy. * @param[in] srcTime True photon arrival time. * @param[in] obs Observation. * @param[in] grad Evaluate gradients. * * @exception GException::no_response * Observation has no valid instrument response * * This method computes the spatial model component for a given true photon * energy and arrival time. ***************************************************************************/ double GModelSky::spatial(const GEvent& event, const GEnergy& srcEng, const GTime& srcTime, const GObservation& obs, bool grad) const { // Initialise result double value = 0.0; // Continue only if the model has a spatial component if (m_spatial != NULL) { // Get response function GResponse* rsp = obs.response(); if (rsp == NULL) { throw GException::no_response(G_SPATIAL); } // Set source GSource source(this->name(), *m_spatial, srcEng, srcTime); // Get IRF value. This method returns the spatial component of the // source model. double irf = rsp->irf(event, source, obs); // Case A: evaluate gradients if (grad) { // Evaluate source model double spec = (spectral() != NULL) ? spectral()->eval_gradients(srcEng) : 1.0; double temp = (temporal() != NULL) ? temporal()->eval_gradients(srcTime) : 1.0; // Set value value = spec * temp * irf; // Compile option: Check for NaN/Inf #if defined(G_NAN_CHECK) if (isnotanumber(value) || isinfinite(value)) { std::cout << "*** ERROR: GModelSky::spatial:"; std::cout << " NaN/Inf encountered"; std::cout << " (value=" << value; std::cout << ", spec=" << spec; std::cout << ", temp=" << temp; std::cout << ", irf=" << irf; std::cout << ")" << std::endl; } #endif // Multiply factors to spectral gradients if (spectral() != NULL) { double fact = temp * irf; if (fact != 1.0) { for (int i = 0; i < spectral()->size(); ++i) { (*spectral())[i].gradient((*spectral())[i].gradient() * fact); } } } // Multiply factors to temporal gradients if (temporal() != NULL) { double fact = spec * irf; if (fact != 1.0) { for (int i = 0; i < temporal()->size(); ++i) { (*temporal())[i].gradient((*temporal())[i].gradient() * fact); } } } } // endif: gradient evaluation has been requested // Case B: evaluate no gradients else { // Evaluate source model double spec = (m_spectral != NULL) ? m_spectral->eval(srcEng) : 1.0; double temp = (m_temporal != NULL) ? m_temporal->eval(srcTime) : 1.0; // Set value value = spec * temp * irf; // Compile option: Check for NaN/Inf #if defined(G_NAN_CHECK) if (isnotanumber(value) || isinfinite(value)) { std::cout << "*** ERROR: GModelSky::spatial:"; std::cout << " NaN/Inf encountered"; std::cout << " (value=" << value; std::cout << ", spec=" << spec; std::cout << ", temp=" << temp; std::cout << ", irf=" << irf; std::cout << ")" << std::endl; } #endif } } // endif: Gamma-ray source model had a spatial component // Return value return value; }
/***********************************************************************//** * @brief Return spatially integrated background model * * @param[in] obsEng Measured event energy. * @param[in] obsTime Measured event time. * @param[in] obs Observation. * @return Spatially integrated model. * * @exception GException::invalid_argument * The specified observation is not a CTA observation. * * Spatially integrates the effective area background model for a given * measured event energy and event time. This method also applies a deadtime * correction factor, so that the normalization of the model is a real rate * (counts/MeV/s). ***************************************************************************/ double GCTAModelAeffBackground::npred(const GEnergy& obsEng, const GTime& obsTime, const GObservation& obs) const { // Set number of iterations for Romberg integration. //static const int iter_theta = 6; //static const int iter_phi = 6; // Initialise result double npred = 0.0; bool has_npred = false; // Build unique identifier std::string id = obs.instrument() + "::" + obs.id(); // Check if Npred value is already in cache #if defined(G_USE_NPRED_CACHE) if (!m_npred_names.empty()) { // Search for unique identifier, and if found, recover Npred value // and break for (int i = 0; i < m_npred_names.size(); ++i) { if (m_npred_names[i] == id && m_npred_energies[i] == obsEng) { npred = m_npred_values[i]; has_npred = true; #if defined(G_DEBUG_NPRED) std::cout << "GCTAModelAeffBackground::npred:"; std::cout << " cache=" << i; std::cout << " npred=" << npred << std::endl; #endif break; } } } // endif: there were values in the Npred cache #endif // Continue only if no Npred cache value has been found if (!has_npred) { // Evaluate only if model is valid if (valid_model()) { // Get log10 of energy in TeV double logE = obsEng.log10TeV(); // Spatially integrate effective area component npred = this->aeff_integral(obs, logE); // Store result in Npred cache #if defined(G_USE_NPRED_CACHE) m_npred_names.push_back(id); m_npred_energies.push_back(obsEng); m_npred_times.push_back(obsTime); m_npred_values.push_back(npred); #endif // Debug: Check for NaN #if defined(G_NAN_CHECK) if (gammalib::is_notanumber(npred) || gammalib::is_infinite(npred)) { std::string origin = "GCTAModelAeffBackground::npred"; std::string message = " NaN/Inf encountered (npred=" + gammalib::str(npred) + ")"; gammalib::warning(origin, message); } #endif } // endif: model was valid } // endif: Npred computation required // Multiply in spectral and temporal components npred *= spectral()->eval(obsEng, obsTime); npred *= temporal()->eval(obsTime); // Apply deadtime correction npred *= obs.deadc(obsTime); // Return Npred return npred; }