1
0
Fork 0
mirror of https://github.com/gwm17/Specter.git synced 2024-11-26 12:18:51 -05:00

Compare commits

..

3 Commits

Author SHA1 Message Date
Gordon McCann 7fca02119e
Delete LICENSE.txt 2022-10-08 16:13:00 -04:00
Gordon McCann 18b38d7d28
Create LICENSE.txt 2022-10-08 15:34:30 -04:00
Gordon McCann c2dd1059dd Finally implement randomization for conversion between integers to floating points. Eliminates binning artifacts in histograms. 2022-10-08 15:21:56 -04:00
4 changed files with 76 additions and 5 deletions

View File

@ -84,16 +84,20 @@ namespace Specter {
{ {
sabreFlag = true; sabreFlag = true;
if (hit.longEnergy > iter->second.GetValue()) if (hit.longEnergy > iter->second.GetValue())
iter->second.SetValue(hit.longEnergy); iter->second.SetValue(hit.longEnergy + RandomGenerator::GetUniformFraction());
continue; continue;
} }
//Note randomization of values. In general, we want to plot/calculate as floating point.
//Especially for histograms, care has to be taken to randomize the decimal to account for binning.
//For timestamps from PSD, since we reduce accuracy by 3 orders of mag, no randomization needed.
//For timestamps from PHA, need randomization on interval from 0 to digitizer sampling period.
switch (hit.id) switch (hit.id)
{ {
case s_scintLeftID: case s_scintLeftID:
{ {
if (hit.longEnergy > scintLeft.GetValue()) if (hit.longEnergy > scintLeft.GetValue())
scintLeft.SetValue(hit.longEnergy); scintLeft.SetValue(hit.longEnergy + RandomGenerator::GetUniformFraction());
break; break;
} }
case s_beamIntID: case s_beamIntID:
@ -104,7 +108,7 @@ namespace Specter {
case s_cathodeID: case s_cathodeID:
{ {
if (hit.longEnergy > cathode.GetValue()) if (hit.longEnergy > cathode.GetValue())
cathode.SetValue(hit.longEnergy); cathode.SetValue(hit.longEnergy + RandomGenerator::GetUniformFraction());
break; break;
} }
case s_delayFrontLeftID: case s_delayFrontLeftID:
@ -134,13 +138,13 @@ namespace Specter {
case s_anodeFrontID: case s_anodeFrontID:
{ {
if (hit.longEnergy > anodeFront.GetValue()) if (hit.longEnergy > anodeFront.GetValue())
anodeFront.SetValue(hit.longEnergy); anodeFront.SetValue(hit.longEnergy + RandomGenerator::GetUniformFraction());
break; break;
} }
case s_anodeBackID: case s_anodeBackID:
{ {
if (hit.longEnergy > anodeBack.GetValue()) if (hit.longEnergy > anodeBack.GetValue())
anodeBack.SetValue(hit.longEnergy); anodeBack.SetValue(hit.longEnergy + RandomGenerator::GetUniformFraction());
break; break;
} }
} }
@ -148,6 +152,7 @@ namespace Specter {
//If you want to use parameters to calculate another parameter, you //If you want to use parameters to calculate another parameter, you
//need to check that the parameter is valid (set in this event)! //need to check that the parameter is valid (set in this event)!
//Note subsequent calculations no longer need randomization.
if(delayFLTime.IsValid() && delayFRTime.IsValid()) if(delayFLTime.IsValid() && delayFRTime.IsValid())
x1.SetValue((delayFLTime.GetValue() - delayFRTime.GetValue())*0.5*0.4762); x1.SetValue((delayFLTime.GetValue() - delayFRTime.GetValue())*0.5*0.4762);

View File

@ -105,6 +105,7 @@ target_sources(Specter PRIVATE
Specter/Physics/Daqromancy/DYOnlineSource.cpp Specter/Physics/Daqromancy/DYOnlineSource.cpp
Specter/Utils/Functions.h Specter/Utils/Functions.h
Specter/Utils/Functions.cpp Specter/Utils/Functions.cpp
Specter/Utils/RandomGenerator.h
) )
#ImPlot sources #ImPlot sources

View File

@ -35,5 +35,6 @@
#include "Specter/Utils/TestServerLayer.h" #include "Specter/Utils/TestServerLayer.h"
#include "Specter/Utils/Instrumentor.h" #include "Specter/Utils/Instrumentor.h"
#include "Specter/Utils/Functions.h" #include "Specter/Utils/Functions.h"
#include "Specter/Utils/RandomGenerator.h"
#endif #endif

View File

@ -0,0 +1,64 @@
/*
RandomGenerator.h
Thread-safe implementation of stl random number generator library. A single Mersenne-Twister generator is created for
each thread. The paramters for the distributions are passed in to the function call, and a random number is calculated
for the requested distribution. Note that distributions are templated so that one can specify the type of distributions,
but most distributions only support a limited range of types. The valid types are commented for each case.
Oct 2022 -- GWM
*/
#ifndef RANDOM_GENERATOR_H
#define RANDOM_GENERATOR_H
#include <random>
namespace Specter {
class RandomGenerator
{
public:
//Valid for float, double, long double
template<typename T>
static T GetUniformReal(T min, T max)
{
std::uniform_real_distribution<T> distribution(min, max);
return distribution(GetGenerator());
}
//Valid for any integer type (signed or unsigned)
template<typename T>
static T GetUniformInt(T min, T max)
{
std::uniform_int_distribution<T> distribution(min, max);
return distribution(GetGenerator());
}
//Valid for float, double, long double
template<typename T>
static T GetNormal(T mean, T sigma)
{
std::normal_distribution<T> distribution(mean, sigma);
return distribution(GetGenerator());
}
//This is the most common use case, so we eliminate recreation of distribution, templating.
//For randomization of decimals in conversion from integer -> floating point for histograming
static double GetUniformFraction()
{
static std::uniform_real_distribution<double> distribution(0.0, 1.0);
return distribution(GetGenerator());
}
private:
static std::mt19937& GetGenerator()
{
static thread_local std::mt19937 generator((std::random_device())());
return generator;
}
};
}
#endif