LCOV - code coverage report
Current view: top level - src/module - Observer.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 55.2 % 223 123
Test Date: 2026-06-18 09:49:19 Functions: 46.0 % 50 23

            Line data    Source code
       1              : #include "crpropa/module/Observer.h"
       2              : #include "crpropa/Units.h"
       3              : #include "crpropa/ParticleID.h"
       4              : #include "crpropa/Cosmology.h"
       5              : 
       6              : #include "kiss/logger.h"
       7              : 
       8              : #include <iostream>
       9              : #include <cmath>
      10              : 
      11              : namespace crpropa {
      12              : 
      13              : // Observer -------------------------------------------------------------------
      14           10 : Observer::Observer() :
      15           10 :                 makeInactive(true), clone(false) {
      16           10 : }
      17              : 
      18           10 : void Observer::add(ObserverFeature *feature) {
      19           10 :         features.push_back(feature);
      20           10 : }
      21              : 
      22            2 : void Observer::onDetection(Module *action, bool clone_) {
      23            2 :         detectionAction = action;
      24            2 :         clone = clone_;
      25            2 : }
      26              : 
      27          476 : void Observer::process(Candidate *candidate) const {
      28              :         // loop over all features and have them check the particle
      29              :         DetectionState state = NOTHING;
      30          952 :         for (int i = 0; i < features.size(); i++) {
      31          476 :                 DetectionState s = features[i]->checkDetection(candidate);
      32          476 :                 if (s == VETO)
      33              :                         state = VETO;
      34          476 :                 else if ((s == DETECTED) && (state != VETO))
      35              :                         state = DETECTED;
      36              :         }
      37              : 
      38          476 :         if (state == DETECTED) {
      39           42 :                 for (int i = 0; i < features.size(); i++) {
      40           21 :                         features[i]->onDetection(candidate);
      41              :                 }
      42              : 
      43           21 :                 if (detectionAction.valid()) {
      44            6 :                         if (clone)
      45            0 :                                 detectionAction->process(candidate->clone(false));
      46              :                         else
      47            6 :                                 detectionAction->process(candidate);
      48              :                 }
      49              : 
      50           21 :                 if (!flagKey.empty())
      51            5 :                         candidate->setProperty(flagKey, flagValue);
      52              : 
      53           21 :                 if (makeInactive)
      54           18 :                         candidate->setActive(false);
      55              :         }
      56          476 : }
      57              : 
      58            2 : void Observer::setFlag(std::string key, std::string value) {
      59            2 :         flagKey = key;
      60            2 :         flagValue = value;
      61            2 : }
      62              : 
      63            0 : std::string Observer::getDescription() const {
      64            0 :         std::stringstream ss;
      65            0 :         ss << "Observer";
      66            0 :         for (int i = 0; i < features.size(); i++)
      67            0 :                 ss << "\n    " << features[i]->getDescription() << "\n";
      68            0 :         ss << "    Flag: '" << flagKey << "' -> '" << flagValue << "'\n";
      69            0 :         ss << "    MakeInactive: " << (makeInactive ? "yes\n" : "no\n");
      70            0 :         if (detectionAction.valid())
      71            0 :                 ss << "    Action: " << detectionAction->getDescription() << ", clone: " << (clone ? "yes" : "no");
      72              : 
      73            0 :         return ss.str();
      74            0 : }
      75              : 
      76            6 : void Observer::setDeactivateOnDetection(bool deactivate) {
      77            6 :         makeInactive = deactivate;
      78            6 : }
      79              : 
      80              : // ObserverFeature ------------------------------------------------------------
      81            0 : DetectionState ObserverFeature::checkDetection(Candidate *candidate) const {
      82            0 :         return NOTHING;
      83              : }
      84              : 
      85           21 : void ObserverFeature::onDetection(Candidate *candidate) const {
      86           21 : }
      87              : 
      88            0 : std::string ObserverFeature::getDescription() const {
      89            0 :         return description;
      90              : }
      91              : 
      92              : // ObserverDetectAll ----------------------------------------------------------
      93            2 : DetectionState ObserverDetectAll::checkDetection(Candidate *candidate) const {
      94            2 :         return DETECTED;
      95              : }
      96              : 
      97            0 : std::string ObserverDetectAll::getDescription() const {
      98            0 :         return description;
      99              : }
     100              : 
     101              : // ObserverTracking --------------------------------------------------------
     102            0 : ObserverTracking::ObserverTracking(Vector3d center, double radius, double stepSize) :
     103            0 :                 center(center), radius(radius), stepSize(stepSize) {
     104              :         if (stepSize == 0) {
     105              :                 stepSize = radius / 10.;
     106              :         }
     107            0 : }
     108              : 
     109            0 : DetectionState ObserverTracking::checkDetection(Candidate *candidate) const {
     110              :         // current distance to observer sphere center
     111            0 :         double d = (candidate->current.getPosition() - center).getR();
     112              : 
     113              :         // no detection if outside of observer sphere
     114            0 :         if (d > radius) {
     115              :                 // conservatively limit next step to prevent overshooting
     116            0 :                 candidate->limitNextStep(fabs(d - radius));
     117              : 
     118            0 :                 return NOTHING;
     119              :         } else {
     120              :                 // limit next step
     121            0 :                 candidate->limitNextStep(stepSize);
     122              : 
     123            0 :                 return DETECTED;
     124              :         }
     125              : }
     126              : 
     127            0 : std::string ObserverTracking::getDescription() const {
     128            0 :         std::stringstream ss;
     129            0 :         ss << "ObserverTracking: ";
     130            0 :         ss << "center = " << center / Mpc << " Mpc, ";
     131            0 :         ss << "radius = " << radius / Mpc << " Mpc";
     132            0 :         ss << "stepSize = " << stepSize / Mpc << " Mpc";
     133            0 :         return ss.str();
     134            0 : }
     135              : 
     136              : // Observer1D --------------------------------------------------------------
     137          456 : DetectionState Observer1D::checkDetection(Candidate *candidate) const {
     138          456 :         double x = candidate->current.getPosition().x;
     139          456 :         if (x > 0) {
     140              :                 // Limits the next step size to prevent candidates from overshooting in case of non-detection
     141          449 :                 candidate->limitNextStep(x);
     142          449 :                 return NOTHING;
     143              :         }
     144              :         // Detects particles when reaching x = 0
     145              :         return DETECTED;
     146              : }
     147              : 
     148            0 : std::string Observer1D::getDescription() const {
     149            0 :         return "Observer1D: observer at x = 0";
     150              : }
     151              : 
     152              : // ObserverRedshiftWindow -----------------------------------------------------
     153            0 : ObserverRedshiftWindow::ObserverRedshiftWindow(double zmin, double zmax) :
     154            0 :                 zmin(zmin), zmax(zmax) {
     155            0 : }
     156              : 
     157            0 : DetectionState ObserverRedshiftWindow::checkDetection(
     158              :                 Candidate *candidate) const {
     159            0 :         double z = candidate->getRedshift();
     160            0 :         if (z > zmax)
     161              :                 return VETO;
     162            0 :         if (z < zmin)
     163            0 :                 return VETO;
     164              :         return NOTHING;
     165              : }
     166              : 
     167            0 : std::string ObserverRedshiftWindow::getDescription() const {
     168            0 :         std::stringstream ss;
     169            0 :         ss << "ObserverRedshiftWindow: z = " << zmin << " - " << zmax;
     170            0 :         return ss.str();
     171            0 : }
     172              : 
     173              : // ObserverInactiveVeto -------------------------------------------------------
     174            0 : DetectionState ObserverInactiveVeto::checkDetection(Candidate *c) const {
     175            0 :         if (not(c->isActive()))
     176            0 :                 return VETO;
     177              :         return NOTHING;
     178              : }
     179              : 
     180            0 : std::string ObserverInactiveVeto::getDescription() const {
     181            0 :         return "ObserverInactiveVeto";
     182              : }
     183              : 
     184              : // ObserverNucleusVeto --------------------------------------------------------
     185            0 : DetectionState ObserverNucleusVeto::checkDetection(Candidate *c) const {
     186            0 :         if (isNucleus(c->current.getId()))
     187            0 :                 return VETO;
     188              :         return NOTHING;
     189              : }
     190              : 
     191            0 : std::string ObserverNucleusVeto::getDescription() const {
     192            0 :         return "ObserverNucleusVeto";
     193              : }
     194              : 
     195              : // ObserverNeutrinoVeto -------------------------------------------------------
     196            0 : DetectionState ObserverNeutrinoVeto::checkDetection(Candidate *c) const {
     197            0 :         int id = abs(c->current.getId());
     198            0 :         if ((id == 12) or (id == 14) or (id == 16))
     199            0 :                 return VETO;
     200              :         return NOTHING;
     201              : }
     202              : 
     203            0 : std::string ObserverNeutrinoVeto::getDescription() const {
     204            0 :         return "ObserverNeutrinoVeto";
     205              : }
     206              : 
     207              : // ObserverPhotonVeto ---------------------------------------------------------
     208            0 : DetectionState ObserverPhotonVeto::checkDetection(Candidate *c) const {
     209            0 :         if (c->current.getId() == 22)
     210            0 :                 return VETO;
     211              :         return NOTHING;
     212              : }
     213              : 
     214            0 : std::string ObserverPhotonVeto::getDescription() const {
     215            0 :         return "ObserverPhotonVeto";
     216              : }
     217              : 
     218              : // ObserverElectronVeto ---------------------------------------------------------
     219            0 : DetectionState ObserverElectronVeto::checkDetection(Candidate *c) const {
     220            0 :         if (abs(c->current.getId()) == 11)
     221            0 :                 return VETO;
     222              :         return NOTHING;
     223              : }
     224              : 
     225            0 : std::string ObserverElectronVeto::getDescription() const {
     226            0 :         return "ObserverElectronVeto";
     227              : }
     228              : 
     229              : // ObserverCustomVeto -------------------------------------------------------
     230            0 : ObserverParticleIdVeto::ObserverParticleIdVeto(int pId) {
     231            0 :         vetoParticleId = pId;
     232            0 : }
     233              : 
     234            0 : DetectionState ObserverParticleIdVeto::checkDetection(Candidate *c) const {
     235            0 :         if (c->current.getId() == vetoParticleId)
     236            0 :                 return VETO;
     237              :         return NOTHING;
     238              : }
     239              : 
     240            0 : std::string ObserverParticleIdVeto::getDescription() const {
     241            0 :         return "ObserverParticleIdVeto";
     242              : }
     243              : 
     244              : 
     245              : // ObserverTimeEvolution --------------------------------------------------------
     246            0 : ObserverTimeEvolution::ObserverTimeEvolution() {}
     247              : 
     248            1 : ObserverTimeEvolution::ObserverTimeEvolution(double min, double dist, double numb) {
     249              :         setIsLogarithmicScaling(false);
     250            1 :         setMaximum(min + (numb - 1) * dist);
     251            1 :         setMinimum(min);
     252            1 :         setNIntervals(numb);
     253            1 : }
     254              : 
     255            2 : ObserverTimeEvolution::ObserverTimeEvolution(double min, double max, double numb, bool log) {
     256              :         setIsLogarithmicScaling(log);
     257            2 :         setMinimum(min);
     258              :         setMaximum(max);
     259            2 :         setNIntervals(numb);
     260            2 : }
     261              : 
     262            1 : ObserverTimeEvolution::ObserverTimeEvolution(const std::vector<double> &detList){
     263            1 :         setTimes(detList);
     264            1 : }
     265              : 
     266            9 : DetectionState ObserverTimeEvolution::checkDetection(Candidate *c) const {
     267              : 
     268            9 :         if (nIntervals) {
     269            9 :                 double length = c->getTrajectoryLength();
     270              :                 size_t index;
     271            9 :                 const std::string DI = "DetectionIndex";
     272              : 
     273              :                 // Load the last detection index
     274            9 :                 if (c->hasProperty(DI)) {
     275           10 :                         index = c->getProperty(DI).asUInt64();
     276              :                 }
     277              :                 else {
     278              :                         index = 0;
     279              :                 }
     280              : 
     281              :                 // Break if the particle has been detected once for all possible times.
     282            9 :                 if (index >= nIntervals) {
     283              :                         return NOTHING;
     284              :                 }
     285              : 
     286              :                 // Calculate the distance to next detection
     287            9 :                 double distance = length - getTime(index);
     288              : 
     289              :                 // Limit next step and detect candidate.
     290              :                 // Increase the index by one in case of detection
     291            9 :                 if (distance < 0.) {
     292            4 :                         c->limitNextStep(-distance);
     293              :                         return NOTHING;
     294              :                 }
     295              :                 else {
     296              : 
     297            5 :                         if (index < nIntervals-2) {
     298            1 :                                 c->limitNextStep(getTime(index+1)-length);
     299              :                         }
     300            5 :                         c->setProperty(DI, Variant::fromUInt64(index+1));
     301              : 
     302            5 :                         return DETECTED;
     303              :                 }
     304              :         }
     305              :         return NOTHING;
     306              : }
     307              : 
     308            3 : void ObserverTimeEvolution::clear(){
     309            3 :         doDetListConstruction = false;
     310              :         detList.clear();
     311            3 :         detList.resize(0);
     312              :         setNIntervals(0);
     313            3 : }
     314              : 
     315           12 : void ObserverTimeEvolution::constructDetListIfEmpty(){
     316           12 :         if (detList.empty() && doDetListConstruction) {
     317              :                 std::vector<double> detListTemp;
     318              :                 size_t counter = 0;
     319            7 :                 while (getTime(counter)<=maximum) {
     320            6 :                         detListTemp.push_back(getTime(counter));
     321            6 :                         counter++;
     322              :                 }
     323            1 :                 detList.assign(detListTemp.begin(), detListTemp.end());
     324            1 :         }
     325           12 : }
     326              : 
     327           12 : void ObserverTimeEvolution::addTime(const double &time){
     328           12 :         constructDetListIfEmpty();
     329           12 :         detList.push_back(time);
     330           12 :         setNIntervals(nIntervals + 1);  // increase number of entries by one
     331           12 : }
     332              : 
     333            2 : void ObserverTimeEvolution::addTimeRange(double min, double max, double numb, bool log) {
     334           12 :         for (size_t i = 0; i < numb; i++) {
     335           10 :                 if (log) {
     336            4 :                         if ( min <= 0 ){
     337              :                                 std::cout << "min can not be <= 0 if log=true" << std::endl;
     338            0 :                                 throw new std::runtime_error("min can not be <= 0 if log=true");
     339              :                         }
     340            4 :                         addTime(min * pow(max / min, i / (numb - 1.0)));
     341              :                 } else {
     342            6 :                         addTime(min + i * (max - min) / (numb - 1.0));
     343              :                 }
     344              :         }
     345              :         // allready corrected by addTime, just here to be safe
     346            2 :         setNIntervals(detList.size());
     347            2 : }
     348              : 
     349            1 : void ObserverTimeEvolution::setTimes(const std::vector<double> &detList){
     350            1 :         this->detList.assign(detList.begin(), detList.end());
     351            1 :         setNIntervals(detList.size());
     352            1 :         setMinimum(detList.front());
     353            1 :         setMaximum(detList.back());
     354            1 :         doDetListConstruction = false;
     355            1 : }
     356              : 
     357            4 : void ObserverTimeEvolution::setMinimum(double min){
     358            4 :         if ( (min <= 0) && isLogarithmicScaling){
     359              :                 std::cout << "minimum can not be <= 0 if isLogarithmicScaling=true" << std::endl;
     360            0 :                 throw new std::runtime_error("minimum can not be <= 0 if isLogarithmicScaling=true");
     361              :         }
     362            4 :         this->minimum = min;
     363            4 : }
     364              : 
     365           65 : double ObserverTimeEvolution::getTime(size_t index) const {
     366           65 :         if (!detList.empty()) {
     367           36 :                 return detList.at(index);
     368           29 :         } else if (isLogarithmicScaling) {
     369            6 :                 return minimum * pow(maximum / minimum, index / (nIntervals - 1.0));
     370              :         } else {
     371           23 :                 return minimum + index * (maximum - minimum) / (nIntervals - 1.0);
     372              :         }
     373              : }
     374              : 
     375            9 : const std::vector<double>& ObserverTimeEvolution::getTimes() const {
     376            9 :         tempDetList.resize(nIntervals);
     377           51 :         for (size_t i = 0; i < nIntervals; i++){
     378           42 :                 tempDetList[i] = getTime(i);
     379              :         }
     380            9 :         return tempDetList;
     381              : }
     382              : 
     383            0 : std::string ObserverTimeEvolution::getDescription() const {
     384            0 :         std::stringstream s;
     385            0 :         s << "List of Detection lengths in kpc";
     386            0 :         for (size_t i = 0; i < nIntervals; i++)
     387            0 :           s << "  - " << getTime(i) / kpc;
     388            0 :         return s.str();
     389            0 : }
     390              : 
     391              : // ObserverSurface--------------------------------------------------------------
     392            2 : ObserverSurface::ObserverSurface(Surface* _surface) : surface(_surface) { }
     393              : 
     394            4 : DetectionState ObserverSurface::checkDetection(Candidate *candidate) const
     395              : {
     396            4 :                 double currentDistance = surface->distance(candidate->current.getPosition());
     397            4 :                 double previousDistance = surface->distance(candidate->previous.getPosition());
     398            4 :                 candidate->limitNextStep(fabs(currentDistance));
     399              : 
     400            4 :                 if (currentDistance * previousDistance > 0)
     401              :                         return NOTHING;
     402            2 :                 else if (previousDistance == 0)
     403              :                         return NOTHING;
     404              :                 else
     405            2 :                         return DETECTED;
     406              : }
     407              : 
     408            0 : std::string ObserverSurface::getDescription() const {
     409            0 :         std::stringstream ss;
     410            0 :         ss << "ObserverSurface: << " << surface->getDescription();
     411            0 :         return ss.str();
     412            0 : }
     413              : 
     414              : 
     415              : } // namespace crpropa
        

Generated by: LCOV version 2.0-1