Skip to content

Reworking of the ObserverTimeEvolution #511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 87 additions & 20 deletions include/crpropa/module/Observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,52 +240,119 @@ class ObserverParticleIdVeto: public ObserverFeature {
This observer is very useful if the time evolution of the particle density is needed. It detects all candidates in lin-spaced, log-spaced, or user-defined time intervals and limits the nextStep of candidates to prevent overshooting of detection intervals.
*/
class ObserverTimeEvolution: public ObserverFeature {
private:
protected:
int numb;
bool islog = false, useCustomGetTime = false;
bool islog = false;
double min, max;
public:
// List containing all used times, is constructed in constructor or by user manually
// (leave empty if you want to rather use functions)
/** Vector containing all used times.
It is only constructed by the user manually.
If it is not empty, the vector will be used instead of the getTime function.
(leave empty if you want to rather use functions)
*/
std::vector<double> detList;

// Pointer to user defined version of getTime (should return time for corresponding index)
double (*customGetTime)(int index, double min, double max, int numb);

/**
A temporary storage for detList, this enables the return of a List in getTimes
without risking to modify detList
*/
mutable std::vector<double> tempDetList;

public:
/** Default constructor
*/
ObserverTimeEvolution();
/** Constructor (calculates the maximum from min + dist * numb)
/** Constructor
@param min minimum time
@param dist time interval for detection
@param numb number of time intervals

This constructor calculates the maximum from max = min + (numb - 1) * dist
*/
ObserverTimeEvolution(double min, double dist, double numb);
/** Constructor
@param min minimum time
@param max maximum time
@param numb number of time intervals
@param log log (input: true) or lin (input: false) scaling between min and max with numb steps

This constructor sets the maximum directly and gets numb automatically.
You need to set the log parameter, since an overload for the first three doubles exist.
*/
ObserverTimeEvolution(double min, double max, double numb, bool log);
/** Constructor
@param detList user defined vector<double> with times to check

This constructor uses a predefined vector containing the times that should be observed.
The so created detList can then be modified via addTime, addTimeRange and setTimes.
*/
ObserverTimeEvolution(const std::vector<double> &detList);
// Destructor
/** Destructor
*/
~ObserverTimeEvolution(){}

/** Function to set a user defined function, which takes index, min, max and numb to calculate the time at index
@param userDefinedFunction function which will be called instead of getTime, should return time for corresponding index
min time, max time, and number of times
/** Function
Generates the detList if it is empty when for example the
ObserverTimeEvolution(const std::vector<double> &detList) constructor
was not used.
Use this function to create a detList with can then be modified.
When detList is not empty its entries are used instead of a runtime calculation of the times.
*/
void constructDetListIfEmpty();
/** Function
@param candidate Candidate usally given by a module list

Checks whether to make a detection at the current step of candidate or not.
This function is called in Observer.process with the simulated Candidate.
*/
void setUserDefinedGetTime(double (*userDefinedFunction)(int index, double min, double max, int numb));
// Get time at specified index, either with log or lin spacing of times
// in the range between min and max for obeserving particles.
double getTime(std::size_t index) const;
// Return a vector containing all times between min and max generated by getTime
const std::vector<double>& getTimes();
DetectionState checkDetection(Candidate *candidate) const;

// setter functions:
/** Function
@param time Time that should be appended to detList

Makes a push_back on detList with the given time.
*/
void addTime(const double &time);
/** Function
@param min minimum time
@param max maximum time
@param numb number of time intervals
@param log log (input: true) or lin (input: false) scaling between min and max with numb steps

Appends a linear or logarithmic time range to detList via repeatedly calling addTime
*/
void addTimeRange(double min, double max, double numb, bool log = false);
/** Function
@param detList vector<double> containing times when to observe

Sets this->detList to detList, with this it is possible to fully modify detList
*/
void setTimes(const std::vector<double> &detList);
void setMin(double min){this->min = min;}
void setMax(double max){this->max = max;}
void setNumb(int numb){this->numb = numb;}
void setIslog(bool log){this->islog = islog;}

// getter functions:
/** Function
@param index index of the required time

Replaces the previous preconstructed detList and return the time for a specific index
*/
virtual double getTime(std::size_t index) const;
double getMin() const {return min;}
double getMax() const {return max;}
int getNumb() const {return numb;}
bool getIsLog() const {return islog;}
/** Function
Returns a vector<double> containing all times between min and max generated by getTime.
This function does not return detList directly, it rather appends a new vector with
getTime numb times.
*/
const std::vector<double>& getTimes() const;
/** Function
Returns a string containing a representation of all times.
This function does not create a detList.
*/
std::string getDescription() const;
};
/** @} */
Expand Down
75 changes: 51 additions & 24 deletions src/module/Observer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ std::string ObserverParticleIdVeto::getDescription() const {
ObserverTimeEvolution::ObserverTimeEvolution() {}

ObserverTimeEvolution::ObserverTimeEvolution(double min, double dist, double numb) {
this->max = min + numb * dist;
this->max = min + (numb - 1) * dist;
this->min = min;
this->numb = numb;
this->islog = false;
Expand All @@ -260,15 +260,7 @@ ObserverTimeEvolution::ObserverTimeEvolution(double min, double max, double numb
}

ObserverTimeEvolution::ObserverTimeEvolution(const std::vector<double> &detList){
this->detList = detList;
this->numb = detList.size();
this->min = detList.front();
this->max = detList.back();
}

void ObserverTimeEvolution::setUserDefinedGetTime(double (*userDefinedFunction)(int index, double min, double max, int numb)){
this->customGetTime = userDefinedFunction;
this->useCustomGetTime = true;
setTimes(detList);
}

DetectionState ObserverTimeEvolution::checkDetection(Candidate *c) const {
Expand All @@ -287,7 +279,7 @@ DetectionState ObserverTimeEvolution::checkDetection(Candidate *c) const {
}

// Break if the particle has been detected once for all possible times.
if (index > numb) {
if (index >= numb) {
return NOTHING;
}

Expand All @@ -302,7 +294,7 @@ DetectionState ObserverTimeEvolution::checkDetection(Candidate *c) const {
}
else {

if (index < numb-1) {
if (index < numb-2) {
c->limitNextStep(getTime(index+1)-length);
}
c->setProperty(DI, Variant::fromUInt64(index+1));
Expand All @@ -313,27 +305,62 @@ DetectionState ObserverTimeEvolution::checkDetection(Candidate *c) const {
return NOTHING;
}

void ObserverTimeEvolution::constructDetListIfEmpty(){
if (detList.empty()) {
std::vector<double> detListTemp;
size_t counter = 0;
while (getTime(counter)<=max) {
detListTemp.push_back(getTime(counter));
counter++;
}
detList = detListTemp;
}
}

void ObserverTimeEvolution::addTime(const double &time){
constructDetListIfEmpty();
detList.push_back(time);
numb += 1; // increase number of entries by one
max = time; // sets the max to the newly added time
}

void ObserverTimeEvolution::addTimeRange(double min, double max, double numb, bool log) {
for (size_t i = 0; i < numb; i++) {
if (log) {
addTime(min * pow(max / min, i / (numb - 1.0)));
} else {
addTime(min + i * (max - min) / (numb - 1.0));
}
}
// allready corrected by addTime, just here to be safe
this->numb = detList.size();
this->min = detList.front();
this->max = detList.back();
}

void ObserverTimeEvolution::setTimes(const std::vector<double> &detList){
this->detList = detList;
this->numb = detList.size();
this->min = detList.front();
this->max = detList.back();
}

double ObserverTimeEvolution::getTime(size_t index) const {
if (!detList.empty()) {
return detList[index];
} else if (useCustomGetTime) {
return customGetTime(index, min, max, numb);
} else if (log) {
return detList.at(index);
} else if (islog) {
return min * pow(max / min, index / (numb - 1.0));
} else {
return min + index * (max - min) / (numb - 1.0);
}
}

const std::vector<double>& ObserverTimeEvolution::getTimes() {
if (detList.empty()) {
size_t counter = 0;
while (getTime(counter)<=max) {
detList.push_back(getTime(counter));
counter++;
}
const std::vector<double>& ObserverTimeEvolution::getTimes() const {
tempDetList.clear();
for (size_t i = 0; i < numb; i++){
tempDetList.push_back(getTime(i));
}
return detList;
return tempDetList;
}

std::string ObserverTimeEvolution::getDescription() const {
Expand Down