Commit 0d13fc6058437b50c52bc7bd35934e43aef26135
1 parent
0d9c23cf
Spectrum points
Showing
3 changed files
with
157 additions
and
29 deletions
scripts/obsutils.py
| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | # ========================================================================== |
| 21 | 21 | import ctools |
| 22 | 22 | import gammalib |
| 23 | - | |
| 23 | +import numpy | |
| 24 | 24 | |
| 25 | 25 | # ===================== # |
| 26 | 26 | # Simulate observations # |
| ... | ... | @@ -516,3 +516,92 @@ def set_obs_patterns(pattern, ra=83.6331, dec=22.0145, offset=1.5): |
| 516 | 516 | |
| 517 | 517 | # Return observation definition list |
| 518 | 518 | return obsdeflist |
| 519 | + | |
| 520 | +# =================================================# | |
| 521 | +# Make spectrum for one Source in aCTA Observation # | |
| 522 | +# ================================================ # | |
| 523 | +def getlogbins(nbins=12,emin=0.1,emax=100): | |
| 524 | + """ | |
| 525 | + Returns list with logarithmiscenergy bins in | |
| 526 | + format [[emin1,emax1],[emin2,emax2],..] | |
| 527 | + | |
| 528 | + Parameters: | |
| 529 | + nbins Number of bins | |
| 530 | + emin Minimum energy | |
| 531 | + emax Maximum energy | |
| 532 | + """ | |
| 533 | + lgemin=numpy.log10(emin) | |
| 534 | + lgemax=numpy.log10(emax) | |
| 535 | + lgbins=[] | |
| 536 | + lgedges=numpy.arange(lgemin,lgemax,(lgemax-lgemin)/nbins) | |
| 537 | + lgedges=numpy.append(lgedges,[lgemax]) | |
| 538 | + for ii in range(len(lgedges)-1): | |
| 539 | + lgbins.append([lgedges[ii],lgedges[ii+1]]) | |
| 540 | + ebins=numpy.power(10,lgbins) | |
| 541 | + return ebins | |
| 542 | +def specpoints(obs,source,ebins): | |
| 543 | + """ | |
| 544 | + Returns spectral points in the given binning for | |
| 545 | + the passed observations and source. | |
| 546 | + | |
| 547 | + Parameters: | |
| 548 | + obs - Pointing direction | |
| 549 | + source - Source name for which spectrum should be done | |
| 550 | + ebins - Binning passed as a list in units of TeV as | |
| 551 | + [[emin1,emax1],[emin2,emax2],..] | |
| 552 | + Keywords: | |
| 553 | + """ | |
| 554 | + #Fix all parameters except prefactor | |
| 555 | + for model in obs.models(): | |
| 556 | + for par in range(model.size()): | |
| 557 | + model[par].fix() | |
| 558 | + | |
| 559 | + opt_spectral = obs.models()[source].spectral() | |
| 560 | + opt_spectral["Prefactor"].free() | |
| 561 | + | |
| 562 | + #Define spectrum dictionary, units are in format readable by astropy | |
| 563 | + pars = {"value":[],"eu_value":[],"ed_value":[],"unit":[]} | |
| 564 | + spec = {"energy":pars.copy(),"flux":pars.copy(),"TS":[]} | |
| 565 | + | |
| 566 | + #Loop over energy bins, fit and write result to spectrum | |
| 567 | + for ebin in ebins: | |
| 568 | + #Get logarithmic bin center and flux value of all energy fit | |
| 569 | + ecenter = numpy.power(10,(numpy.log10(ebin[1])+numpy.log10(ebin[0]))/2.) | |
| 570 | + allflux = opt_spectral.eval(gammalib.GEnergy(ecenter,"TeV"),gammalib.GTime(0)) | |
| 571 | + | |
| 572 | + #Clone observations and reset energy thresholds | |
| 573 | + select = ctools.ctselect(obs) | |
| 574 | + select["ra"].real(-1.0) | |
| 575 | + select["dec"].real(-1.0) | |
| 576 | + select["rad"].real(-1.0) | |
| 577 | + select["tmin"].real(0) | |
| 578 | + select["tmax"].real(0) | |
| 579 | + select["emin"].real(ebin[0]) | |
| 580 | + select["emax"].real(ebin[1]) | |
| 581 | + select.run() | |
| 582 | + obsclone = select.obs() | |
| 583 | + | |
| 584 | + #Refit and write out to spectrum | |
| 585 | + binlike=fit(obsclone,log=False, debug=False, edisp=False) | |
| 586 | + binopt_spectral = binlike.obs().models()[source].spectral() | |
| 587 | + binflux=binopt_spectral.eval(gammalib.GEnergy(ecenter,"TeV"),gammalib.GTime(0)) | |
| 588 | + if binopt_spectral["Prefactor"].value()>0: | |
| 589 | + relerr=binopt_spectral["Prefactor"].error()/binopt_spectral["Prefactor"].value() | |
| 590 | + else: | |
| 591 | + relerr=0 | |
| 592 | + | |
| 593 | + #Store and convert to TeV from MeV | |
| 594 | + spec["energy"]["value"].append(ecenter) | |
| 595 | + spec["energy"]["ed_value"].append(ecenter-ebin[0]) | |
| 596 | + spec["energy"]["eu_value"].append(ebin[1]-ecenter) | |
| 597 | + spec["energy"]["unit"].append("1e12 eV") | |
| 598 | + | |
| 599 | + spec["flux"]["value"].append(binflux*1e6) | |
| 600 | + spec["flux"]["ed_value"].append(relerr*binflux*1e6) | |
| 601 | + spec["flux"]["eu_value"].append(relerr*binflux*1e6) | |
| 602 | + spec["flux"]["unit"].append("cm-2 1e-12 eV-1") | |
| 603 | + | |
| 604 | + spec["TS"].append(binlike.obs().models()[source].ts()) | |
| 605 | + | |
| 606 | + #Return spectrum | |
| 607 | + return spec | ... | ... |
src/ctlike/ctlike.cpp
| ... | ... | @@ -267,6 +267,39 @@ void ctlike::run(void) |
| 267 | 267 | |
| 268 | 268 | // Optimize model parameters using LM optimizer |
| 269 | 269 | optimize_lm(); |
| 270 | + | |
| 271 | + // Store original models and max. likelihood | |
| 272 | + double logL_src=m_logL; | |
| 273 | + GModels* models_orig = m_obs.models().clone(); | |
| 274 | + | |
| 275 | + //Store models whith free parameters | |
| 276 | + std::vector<std::string> free_srcs; | |
| 277 | + GModels models = m_obs.models(); | |
| 278 | + for (int ii=0; ii < models.size();ii++){ | |
| 279 | + GModel* model = models[ii]; | |
| 280 | + for(int jj=0; jj < model->size();jj++){ | |
| 281 | + GModelPar par = model->at(jj); | |
| 282 | + if (par.is_free()){ | |
| 283 | + free_srcs.push_back(model->name()); | |
| 284 | + break; | |
| 285 | + } | |
| 286 | + } | |
| 287 | + } | |
| 288 | + //Loop over stored models, remove source and refit | |
| 289 | + for (int ii=0; ii < free_srcs.size();ii++){ | |
| 290 | + models.remove(free_srcs[ii]); | |
| 291 | + m_obs.models(models); | |
| 292 | + optimize_lm(); | |
| 293 | + double logL_nosrc=m_logL; | |
| 294 | + double TS = 2* (logL_src-logL_nosrc); | |
| 295 | + std::string name = free_srcs[ii]; | |
| 296 | + (*models_orig)[name]->ts(TS); | |
| 297 | + models = *models_orig; | |
| 298 | + } | |
| 299 | + // Restore best fit values | |
| 300 | + // TODO: store fit results before and avoid refitting | |
| 301 | + m_obs.models(*models_orig); | |
| 302 | + optimize_lm(); | |
| 270 | 303 | |
| 271 | 304 | // Compute number of observed events in all observations |
| 272 | 305 | double num_events = 0.0; | ... | ... |
src/ctselect/ctselect.cpp
| ... | ... | @@ -511,7 +511,8 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) |
| 511 | 511 | |
| 512 | 512 | // Set requested selections |
| 513 | 513 | bool select_time = (m_tmin != 0.0 || m_tmax != 0.0); |
| 514 | - | |
| 514 | + bool select_roi = ((m_dec != -1.0 && m_ra != -1.0 && m_rad != -1.0) || m_usepnt); | |
| 515 | + | |
| 515 | 516 | // Set RA/DEC selection |
| 516 | 517 | double ra = m_ra; |
| 517 | 518 | double dec = m_dec; |
| ... | ... | @@ -520,7 +521,7 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) |
| 520 | 521 | ra = pnt.dir().ra_deg(); |
| 521 | 522 | dec = pnt.dir().dec_deg(); |
| 522 | 523 | } |
| 523 | - | |
| 524 | + | |
| 524 | 525 | // Set time selection interval. We make sure here that the time selection |
| 525 | 526 | // interval cannot be wider than the GTIs covering the data. This is done |
| 526 | 527 | // using GGti's reduce() method. |
| ... | ... | @@ -565,26 +566,29 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) |
| 565 | 566 | log << gammalib::parformat("Energy range"); |
| 566 | 567 | log << m_emin << " - " << m_emax << " TeV" << std::endl; |
| 567 | 568 | } |
| 568 | - if (selection.length() > 0) { | |
| 569 | - selection += " && "; | |
| 570 | - } | |
| 571 | 569 | |
| 572 | 570 | // Make ROI selection |
| 573 | - sprintf(cra, "%.6f", ra); | |
| 574 | - sprintf(cdec, "%.6f", dec); | |
| 575 | - sprintf(crad, "%.6f", m_rad); | |
| 576 | - selection += "ANGSEP("+std::string(cra)+"," + | |
| 577 | - std::string(cdec)+",RA,DEC) <= " + | |
| 578 | - std::string(crad); | |
| 579 | - if (logTerse()) { | |
| 580 | - log << gammalib::parformat("Acceptance cone centre"); | |
| 581 | - log << "RA=" << ra << ", DEC=" << dec << " deg" << std::endl; | |
| 582 | - log << gammalib::parformat("Acceptance cone radius"); | |
| 583 | - log << m_rad << " deg" << std::endl; | |
| 584 | - } | |
| 585 | - if (logTerse()) { | |
| 586 | - log << gammalib::parformat("cfitsio selection"); | |
| 587 | - log << selection << std::endl; | |
| 571 | + if (select_roi){ | |
| 572 | + if (selection.length() > 0) { | |
| 573 | + selection += " && "; | |
| 574 | + } | |
| 575 | + | |
| 576 | + sprintf(cra, "%.6f", ra); | |
| 577 | + sprintf(cdec, "%.6f", dec); | |
| 578 | + sprintf(crad, "%.6f", m_rad); | |
| 579 | + selection += "ANGSEP("+std::string(cra)+"," + | |
| 580 | + std::string(cdec)+",RA,DEC) <= " + | |
| 581 | + std::string(crad); | |
| 582 | + if (logTerse()) { | |
| 583 | + log << gammalib::parformat("Acceptance cone centre"); | |
| 584 | + log << "RA=" << ra << ", DEC=" << dec << " deg" << std::endl; | |
| 585 | + log << gammalib::parformat("Acceptance cone radius"); | |
| 586 | + log << m_rad << " deg" << std::endl; | |
| 587 | + } | |
| 588 | + if (logTerse()) { | |
| 589 | + log << gammalib::parformat("cfitsio selection"); | |
| 590 | + log << selection << std::endl; | |
| 591 | + } | |
| 588 | 592 | } |
| 589 | 593 | |
| 590 | 594 | // Add additional expression |
| ... | ... | @@ -645,11 +649,13 @@ void ctselect::select_events(GCTAObservation* obs, const std::string& filename) |
| 645 | 649 | // Get CTA event list pointer |
| 646 | 650 | GCTAEventList* list = |
| 647 | 651 | static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events())); |
| 648 | - | |
| 649 | - // Set ROI | |
| 650 | - GCTAInstDir instdir; | |
| 651 | - instdir.dir().radec_deg(ra, dec); | |
| 652 | - list->roi(GCTARoi(instdir, m_rad)); | |
| 652 | + | |
| 653 | + if (select_roi){ | |
| 654 | + // Set ROI | |
| 655 | + GCTAInstDir instdir; | |
| 656 | + instdir.dir().radec_deg(ra, dec); | |
| 657 | + list->roi(GCTARoi(instdir, m_rad)); | |
| 658 | + } | |
| 653 | 659 | |
| 654 | 660 | // Set GTI |
| 655 | 661 | list->gti(gti); |
| ... | ... | @@ -689,9 +695,9 @@ void ctselect::init_members(void) |
| 689 | 695 | m_outfile.clear(); |
| 690 | 696 | m_prefix.clear(); |
| 691 | 697 | m_usepnt = false; |
| 692 | - m_ra = 0.0; | |
| 693 | - m_dec = 0.0; | |
| 694 | - m_rad = 0.0; | |
| 698 | + m_ra = -1.0; | |
| 699 | + m_dec = -1.0; | |
| 700 | + m_rad = -1.0; | |
| 695 | 701 | m_tmin = 0.0; |
| 696 | 702 | m_tmax = 0.0; |
| 697 | 703 | m_emin = 0.0; | ... | ... |