Program Listing for File Observer.cpp

Return to documentation for file (src/module/Observer.cpp)

#include "crpropa/module/Observer.h"
#include "crpropa/Units.h"
#include "crpropa/ParticleID.h"
#include "crpropa/Cosmology.h"

#include "kiss/logger.h"

#include <iostream>
#include <cmath>

namespace crpropa {

// Observer -------------------------------------------------------------------
Observer::Observer() :
                makeInactive(true), clone(false) {
}

void Observer::add(ObserverFeature *feature) {
        features.push_back(feature);
}

void Observer::onDetection(Module *action, bool clone_) {
        detectionAction = action;
        clone = clone_;
}

void Observer::process(Candidate *candidate) const {
        // loop over all features and have them check the particle
        DetectionState state = NOTHING;
        for (int i = 0; i < features.size(); i++) {
                DetectionState s = features[i]->checkDetection(candidate);
                if (s == VETO)
                        state = VETO;
                else if ((s == DETECTED) && (state != VETO))
                        state = DETECTED;
        }

        if (state == DETECTED) {
                for (int i = 0; i < features.size(); i++) {
                        features[i]->onDetection(candidate);
                }

                if (detectionAction.valid()) {
                        if (clone)
                                detectionAction->process(candidate->clone(false));
                        else
                                detectionAction->process(candidate);
                }

                if (!flagKey.empty())
                        candidate->setProperty(flagKey, flagValue);

                if (makeInactive)
                        candidate->setActive(false);
        }
}

void Observer::setFlag(std::string key, std::string value) {
        flagKey = key;
        flagValue = value;
}

std::string Observer::getDescription() const {
        std::stringstream ss;
        ss << "Observer";
        for (int i = 0; i < features.size(); i++)
                ss << "\n    " << features[i]->getDescription() << "\n";
        ss << "    Flag: '" << flagKey << "' -> '" << flagValue << "'\n";
        ss << "    MakeInactive: " << (makeInactive ? "yes\n" : "no\n");
        if (detectionAction.valid())
                ss << "    Action: " << detectionAction->getDescription() << ", clone: " << (clone ? "yes" : "no");

        return ss.str();
}

void Observer::setDeactivateOnDetection(bool deactivate) {
        makeInactive = deactivate;
}

// ObserverFeature ------------------------------------------------------------
DetectionState ObserverFeature::checkDetection(Candidate *candidate) const {
        return NOTHING;
}

void ObserverFeature::onDetection(Candidate *candidate) const {
}

std::string ObserverFeature::getDescription() const {
        return description;
}

// ObserverDetectAll ----------------------------------------------------------
DetectionState ObserverDetectAll::checkDetection(Candidate *candidate) const {
        return DETECTED;
}

std::string ObserverDetectAll::getDescription() const {
        return description;
}

// ObserverTracking --------------------------------------------------------
ObserverTracking::ObserverTracking(Vector3d center, double radius, double stepSize) :
                center(center), radius(radius), stepSize(stepSize) {
        if (stepSize == 0) {
                stepSize = radius / 10.;
        }
}

DetectionState ObserverTracking::checkDetection(Candidate *candidate) const {
        // current distance to observer sphere center
        double d = (candidate->current.getPosition() - center).getR();

        // no detection if outside of observer sphere
        if (d > radius) {
                // conservatively limit next step to prevent overshooting
                candidate->limitNextStep(fabs(d - radius));

                return NOTHING;
        } else {
                // limit next step
                candidate->limitNextStep(stepSize);

                return DETECTED;
        }
}

std::string ObserverTracking::getDescription() const {
        std::stringstream ss;
        ss << "ObserverTracking: ";
        ss << "center = " << center / Mpc << " Mpc, ";
        ss << "radius = " << radius / Mpc << " Mpc";
        ss << "stepSize = " << stepSize / Mpc << " Mpc";
        return ss.str();
}

// Observer1D --------------------------------------------------------------
DetectionState Observer1D::checkDetection(Candidate *candidate) const {
        double x = candidate->current.getPosition().x;
        if (x > 0) {
                // Limits the next step size to prevent candidates from overshooting in case of non-detection
                candidate->limitNextStep(x);
                return NOTHING;
        }
        // Detects particles when reaching x = 0
        return DETECTED;
}

std::string Observer1D::getDescription() const {
        return "Observer1D: observer at x = 0";
}

// ObserverRedshiftWindow -----------------------------------------------------
ObserverRedshiftWindow::ObserverRedshiftWindow(double zmin, double zmax) :
                zmin(zmin), zmax(zmax) {
}

DetectionState ObserverRedshiftWindow::checkDetection(
                Candidate *candidate) const {
        double z = candidate->getRedshift();
        if (z > zmax)
                return VETO;
        if (z < zmin)
                return VETO;
        return NOTHING;
}

std::string ObserverRedshiftWindow::getDescription() const {
        std::stringstream ss;
        ss << "ObserverRedshiftWindow: z = " << zmin << " - " << zmax;
        return ss.str();
}

// ObserverInactiveVeto -------------------------------------------------------
DetectionState ObserverInactiveVeto::checkDetection(Candidate *c) const {
        if (not(c->isActive()))
                return VETO;
        return NOTHING;
}

std::string ObserverInactiveVeto::getDescription() const {
        return "ObserverInactiveVeto";
}

// ObserverNucleusVeto --------------------------------------------------------
DetectionState ObserverNucleusVeto::checkDetection(Candidate *c) const {
        if (isNucleus(c->current.getId()))
                return VETO;
        return NOTHING;
}

std::string ObserverNucleusVeto::getDescription() const {
        return "ObserverNucleusVeto";
}

// ObserverNeutrinoVeto -------------------------------------------------------
DetectionState ObserverNeutrinoVeto::checkDetection(Candidate *c) const {
        int id = abs(c->current.getId());
        if ((id == 12) or (id == 14) or (id == 16))
                return VETO;
        return NOTHING;
}

std::string ObserverNeutrinoVeto::getDescription() const {
        return "ObserverNeutrinoVeto";
}

// ObserverPhotonVeto ---------------------------------------------------------
DetectionState ObserverPhotonVeto::checkDetection(Candidate *c) const {
        if (c->current.getId() == 22)
                return VETO;
        return NOTHING;
}

std::string ObserverPhotonVeto::getDescription() const {
        return "ObserverPhotonVeto";
}

// ObserverElectronVeto ---------------------------------------------------------
DetectionState ObserverElectronVeto::checkDetection(Candidate *c) const {
        if (abs(c->current.getId()) == 11)
                return VETO;
        return NOTHING;
}

std::string ObserverElectronVeto::getDescription() const {
        return "ObserverElectronVeto";
}

// ObserverCustomVeto -------------------------------------------------------
ObserverParticleIdVeto::ObserverParticleIdVeto(int pId) {
        vetoParticleId = pId;
}

DetectionState ObserverParticleIdVeto::checkDetection(Candidate *c) const {
        if (c->current.getId() == vetoParticleId)
                return VETO;
        return NOTHING;
}

std::string ObserverParticleIdVeto::getDescription() const {
        return "ObserverParticleIdVeto";
}


// ObserverTimeEvolution --------------------------------------------------------
ObserverTimeEvolution::ObserverTimeEvolution() {}

ObserverTimeEvolution::ObserverTimeEvolution(double min, double dist, double numb) {
        double max = min + numb * dist;
        bool log = false;
        addTimeRange(min, max, numb, log);
}

ObserverTimeEvolution::ObserverTimeEvolution(double min, double max, double numb, bool log) {
        addTimeRange(min, max, numb, log);
}


DetectionState ObserverTimeEvolution::checkDetection(Candidate *c) const {

        if (detList.size()) {
                double length = c->getTrajectoryLength();
                size_t index;
                const std::string DI = "DetectionIndex";
                std::string value;

                // Load the last detection index
                if (c->hasProperty(DI)) {
                        index = c->getProperty(DI).asUInt64();
                }
                else {
                        index = 0;
                }

                // Break if the particle has been detected once for all detList entries.
                if (index > detList.size()) {
                        return NOTHING;
                }

                // Calculate the distance to next detection
                double distance = length - detList[index];

                // Limit next step and detect candidate.
                // Increase the index by one in case of detection
                if (distance < 0.) {
                        c->limitNextStep(-distance);
                        return NOTHING;
                }
                else {

                        if (index < detList.size()-1) {
                                c->limitNextStep(detList[index+1]-length);
                        }
                        c->setProperty(DI, Variant::fromUInt64(index+1));

                        return DETECTED;
                }
        }
        return NOTHING;
}

void ObserverTimeEvolution::addTime(const double& t) {
        detList.push_back(t);
}

void ObserverTimeEvolution::addTimeRange(double min, double max, double numb, bool log) {
        for (size_t i = 0; i < numb; i++) {
                if (log == true) {
                        addTime(min * pow(max / min, i / (numb - 1.0)));
                } else {
                        addTime(min + i * (max - min) / numb);
                }
        }
}

const std::vector<double>& ObserverTimeEvolution::getTimes() const {
        return detList;
}

std::string ObserverTimeEvolution::getDescription() const {
        std::stringstream s;
        s << "List of Detection lengths in kpc";
        for (size_t i = 0; i < detList.size(); i++)
          s << "  - " << detList[i] / kpc;
        return s.str();
}

// ObserverSurface--------------------------------------------------------------
ObserverSurface::ObserverSurface(Surface* _surface) : surface(_surface) { }

DetectionState ObserverSurface::checkDetection(Candidate *candidate) const
{
                double currentDistance = surface->distance(candidate->current.getPosition());
                double previousDistance = surface->distance(candidate->previous.getPosition());
                candidate->limitNextStep(fabs(currentDistance));

                if (currentDistance * previousDistance > 0)
                        return NOTHING;
                else if (previousDistance == 0)
                        return NOTHING;
                else
                        return DETECTED;
}

std::string ObserverSurface::getDescription() const {
        std::stringstream ss;
        ss << "ObserverSurface: << " << surface->getDescription();
        return ss.str();
}

} // namespace crpropa