52 #include "TRestAxionLikelihood.h"
57 TRestAxionLikelihood::TRestAxionLikelihood() :
TRestMetadata() {
63 TRestAxionLikelihood::TRestAxionLikelihood(
const char* cfgFileName,
string name)
65 cout <<
"Entering TRestAxionLikelihood constructor( cfgFileName, name )" << endl;
69 LoadConfigFromFile(fConfigFileName, name);
75 TRestAxionLikelihood::~TRestAxionLikelihood() {
97 void TRestAxionLikelihood::GenerateMonteCarlo() {
99 Double_t expTimeInSeconds = fTExpVacuum * 3600.;
100 Double_t energyRange = fErange.Y() - fErange.X();
102 RESTDebug <<
"Energy range : " << energyRange <<
RESTendl;
104 Double_t mean = fBackgroundLevel * fSpotArea * expTimeInSeconds * energyRange;
106 fMeasuredCountsVacuum =
fRandom->Poisson(mean);
107 RESTDebug <<
"Vacuum phase. Mean counts : " << mean <<
RESTendl;
108 RESTDebug <<
"Vacuum phase. Measured counts : " << fMeasuredCountsVacuum <<
RESTendl;
112 fMeasuredCountsPerStep.clear();
114 if (fTExpPerStep >= 0) {
115 for (
int n = 0; n < fNSteps; n++) {
117 Double_t exposureTime = fTExpPerStep;
118 if (n < 3) exposureTime = 0;
119 fExposureTimePerStep.push_back(exposureTime);
122 Double_t rho = fLastStepDensity * (n + 1) / fNSteps;
123 fDensityInStep.push_back(rho);
125 }
else if (fTExpPerStep == -2)
127 Double_t totalDays = 0;
128 for (
int n = 0; n < fNSteps; n++) {
130 Double_t rho = fLastStepDensity * (n + 1) / fNSteps;
133 fDensityInStep.push_back(rho);
139 Double_t nGamma = GetSignal(mgamma, 1., rho, 1.);
141 Double_t ksvzFactor = 3.75523 * mgamma;
142 Double_t exposureTime = TMath::Log(20.) / TMath::Power(ksvzFactor, 4) / nGamma;
144 if (mgamma < 0.0475) exposureTime = 0;
145 totalDays += exposureTime;
147 fExposureTimePerStep.push_back(exposureTime);
150 for (
int n = 0; n < fNSteps; n++) {
151 cout <<
"Step : " << n <<
" Time : " << fExposureTimePerStep[n] / 12 << endl;
155 (fExposureTimePerStep[4] + fExposureTimePerStep[5] + fExposureTimePerStep[6]) / 7.;
156 cout <<
"Share time : " << shareTime / 12. << endl;
157 for (
int n = 0; n < 7; n++) fExposureTimePerStep[n] = shareTime;
161 Double_t totalTime = 0;
162 for (
int n = 0; n < fNSteps; n++) {
163 cout <<
"Step : " << n <<
" Time : " << fExposureTimePerStep[n] / 12 << endl;
164 totalTime += fExposureTimePerStep[n] / 12.;
175 for (
int n = 0; n < fNSteps; n++) {
176 mean = fBackgroundLevel * fSpotArea * fExposureTimePerStep[n] * 3600. * energyRange;
177 Int_t counts =
fRandom->Poisson(mean);
178 fMeasuredCountsPerStep.push_back(counts);
180 RESTDebug <<
"Step : " << n <<
" measured : " << counts <<
" :: " << fMeasuredCountsPerStep.back()
182 RESTDebug <<
"Time : " << fExposureTimePerStep[n] / 12 <<
" days" <<
RESTendl;
185 RESTDebug <<
"Number of steps : " << fNSteps <<
" :: " << fMeasuredCountsPerStep.size() <<
RESTendl;
188 void TRestAxionLikelihood::LikelihoodTest(
const string& fname) {
189 FILE* f = fopen(fname.c_str(),
"wt");
191 for (Double_t m = 0.008; m < 10; m = m * 1.04) {
192 Double_t integral = 0;
195 cout <<
"Calculating mass : " << m <<
" eV" << endl;
196 cout <<
"-------------------------------_" << endl;
197 for (Double_t g4 = 1.e-12; g4 < 1.e10; g4 = g4 * 1.02) {
198 double l = LogLikelihood(m, g4, fMeasuredCountsVacuum, 0.0, fTExpVacuum);
202 for (
int n = 0; n < fNSteps; n++) {
203 Double_t rho = fDensityInStep[n];
213 if (g4 == 1.e-12) cout <<
"Calculating Lhood for step " << n << endl;
214 if (g4 == 1.e-12) cout <<
"step time " << fExposureTimePerStep[n] / 12. <<
" days" << endl;
215 l = l * LogLikelihood(m, g4, fMeasuredCountsPerStep[n], rho, fExposureTimePerStep[n]);
224 integral += l * (g4 - gBef);
236 for (Double_t g4 = 1.e-12; g4 < 1.e10; g4 = g4 * 1.02) {
237 double l = LogLikelihood(m, g4, fMeasuredCountsVacuum, 0.0, fTExpVacuum);
242 for (
int n = 0; n < fNSteps; n++) {
243 Double_t rho = fDensityInStep[n];
250 l = l * LogLikelihood(m, g4, fMeasuredCountsPerStep[n], rho, fExposureTimePerStep[n]);
259 int95 += l * (g4 - gBef);
264 if (int95 / integral > 0.95) {
266 cout <<
"gLimit : " << g4 << endl;
273 printf(
"ma : %e\t gL %e\n", m, sqrt(sqrt(gLimit)) * 1.e-10);
275 fprintf(f,
"%lf\t%e\n", m, sqrt(sqrt(gLimit)) * 1.e-10);
282 Double_t TRestAxionLikelihood::GetSignal(Double_t ma, Double_t g10_4, Double_t rho, Double_t tExp) {
285 Double_t magnetArea = fNbores * TMath::Pi() * TMath::Power(fRmag * REST_Units::cm, 2);
289 for (Double_t en = fErange.X(); en < fErange.Y(); en = en + dE) {
290 Double_t Phi_a = fAxionSpectrum->GetDifferentialSolarAxionFlux(en);
295 Double_t nGamma = Pa_g * Phi_a;
309 return signal * dE * tExp * 3600. * magnetArea * fEfficiency * g10_4;
312 Double_t TRestAxionLikelihood::LogLikelihood(Double_t ma, Double_t g10_4, Double_t Nmeas, Double_t rho,
314 Double_t signal = GetSignal(ma, g10_4, rho, tExp);
321 Double_t bckMean = fBackgroundLevel * (tExp * 3600.) * fSpotArea * (fErange.Y() - fErange.X());
322 Double_t mu = signal + bckMean;
324 Double_t lhood = TMath::Exp(-mu + Nmeas);
325 if (Nmeas > 0) lhood += TMath::Exp(-mu + Nmeas) * pow(mu / Nmeas, Nmeas);
334 if (isinf(lhood) || isnan(lhood)) {
335 cout <<
"IS INF" << endl;
360 fBmag = GetDblParameterWithUnits(
"Bmag", 4.5);
361 fRmag = GetDblParameterWithUnits(
"Rmag", 300);
362 fLmag = GetDblParameterWithUnits(
"Lmag", 4500.);
391 RESTMetadata <<
" Number of magnet bores : " << fNbores <<
RESTendl;
393 RESTMetadata <<
" Magnetic field : " << fBmag <<
" T" <<
RESTendl;
394 RESTMetadata <<
" Magnet length : " << fLmag <<
" mm" <<
RESTendl;
396 RESTMetadata <<
" Magnet radius : " << fRmag <<
" mm" <<
RESTendl;
397 RESTMetadata <<
" Signal overall efficiency : " << fEfficiency <<
RESTendl;
399 RESTMetadata <<
" Background level : " << fBackgroundLevel <<
" cpd keV-1 s-1" <<
RESTendl;
400 RESTMetadata <<
" Energy range : (" << fErange.X() <<
", " << fErange.Y() <<
")" <<
RESTendl;
402 RESTMetadata <<
" Vacuum phase exposure time : " << fTExpVacuum <<
" hours" <<
RESTendl;
403 RESTMetadata <<
" Gas phase exposure time per step : " << fTExpPerStep <<
RESTendl;
404 RESTMetadata <<
" Total number of steps : " << fNSteps <<
RESTendl;
405 RESTMetadata <<
" Last step Helium density : " << fLastStepDensity <<
" g/cm3" <<
RESTendl;
407 RESTMetadata <<
"+++++++++++++++++++++++++++++++++++++++++++++++++" <<
RESTendl;
A metadata class to define the gas properties used in axion search calculations.
Double_t GetPhotonMass(double en)
It returns the equivalent photon mass (in eV) for the gas mixture at the given input energy expressed...
void SetGasDensity(TString gasName, Double_t density)
It adds a new gas component to the mixture. If it already exists it will update its density.
A basic class to define analytical axion-photon conversion calculations for axion helioscopes.
void AssignBufferGas(TRestAxionBufferGas *buffGas)
It assigns a gas buffer medium to the calculation.
void Initialize()
Making default settings.
TRandom3 * fRandom
Random number generator.
void PrintMetadata()
Implemented it in the derived metadata class to print out specific metadata information.
void InitFromConfigFile()
To make settings from rml file. This method must be implemented in the derived class.
A metadata class to define a solar axion spectrum and functions to evaluate it.
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Double_t StringToDouble(std::string in)
Gets a double from a string.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.