Skip to content

Commit 3800d90

Browse files
authored
Merge pull request #82 from rest-for-physics/jgalan_hotfix
GSL Integration implementation, TRestAxionMagneticField ReMap feature and HOT bug fix.
2 parents 2137538 + a6c5786 commit 3800d90

15 files changed

+711
-196
lines changed

inc/TRestAxionField.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@
2424
#define _TRestAxionField
2525

2626
#include "TRestAxionBufferGas.h"
27+
#include "TRestAxionMagneticField.h"
2728

2829
//! A basic class to define analytical axion-photon conversion calculations for axion helioscopes
2930
class TRestAxionField : public TObject {
3031
private:
3132
Bool_t fDebug = false; //!
3233

33-
/// The magnetic field in Teslas
34+
/// The magnetic field in Teslas (used for constant field formulas)
3435
Double_t fBmag = 2.5;
3536

36-
/// The coherence lenght (in mm) where the magnetic field is defined
37+
/// The coherence lenght (in mm) where the magnetic field is defined (for constant field)
3738
Double_t fLcoh = 10000;
3839

3940
/// The energy of the axion in keV
@@ -42,7 +43,16 @@ class TRestAxionField : public TObject {
4243
void Initialize();
4344

4445
/// A pointer to the buffer gas definition
45-
TRestAxionBufferGas* fBufferGas = NULL; //!
46+
TRestAxionBufferGas* fBufferGas = nullptr; //!
47+
48+
/// A pointer to the magnetic field definition
49+
TRestAxionMagneticField* fMagneticField = nullptr; //!
50+
51+
std::pair<Double_t, Double_t> ComputeOffResonanceIntegral(Double_t q, Double_t Gamma, Double_t accuracy,
52+
Int_t num_intervals, Int_t qawo_levels);
53+
54+
std::pair<Double_t, Double_t> ComputeResonanceIntegral(Double_t Gamma, Double_t accuracy,
55+
Int_t num_intervals);
4656

4757
public:
4858
void SetMagneticField(Double_t b) { fBmag = b; }
@@ -62,6 +72,9 @@ class TRestAxionField : public TObject {
6272
/// It assigns a gas buffer medium to the calculation
6373
void AssignBufferGas(TRestAxionBufferGas* buffGas) { fBufferGas = buffGas; }
6474

75+
/// It assigns a magnetic field to the calculation
76+
void AssignMagneticField(TRestAxionMagneticField* mField) { fMagneticField = mField; }
77+
6578
/// It assigns a gas buffer medium to the calculation
6679
void SetBufferGas(TRestAxionBufferGas* buffGas) { fBufferGas = buffGas; }
6780

@@ -78,6 +91,21 @@ class TRestAxionField : public TObject {
7891
Double_t GammaTransmissionProbability(std::vector<Double_t> Bmag, Double_t deltaL, Double_t Ea,
7992
Double_t ma, Double_t mg = 0, Double_t absLength = 0);
8093

94+
std::pair<Double_t, Double_t> GammaTransmissionFieldMapProbability(Double_t Ea, Double_t ma,
95+
Double_t accuracy = 1.e-1,
96+
Int_t num_intervals = 100,
97+
Int_t qawo_levels = 20);
98+
99+
/// Integrand used for axion-photon probability integration
100+
static double Integrand(double x, void* params) {
101+
auto* data = reinterpret_cast<std::pair<TRestAxionMagneticField*, double>*>(params);
102+
103+
TRestAxionMagneticField* field = data->first;
104+
double gamma = data->second;
105+
106+
return exp(0.5 * gamma * x) * field->GetTransversalComponentInParametricTrack(x);
107+
}
108+
81109
Double_t GammaTransmissionFWHM(Double_t step = 0.00001);
82110

83111
std::vector<std::pair<Double_t, Double_t>> GetMassDensityScanning(std::string gasName = "He",

inc/TRestAxionFieldPropagationProcess.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,21 @@
3434
//! A process to introduce the magnetic field profile integration along the track
3535
class TRestAxionFieldPropagationProcess : public TRestAxionEventProcess {
3636
private:
37-
/// The differential length in mm used for the field integration
38-
Double_t fIntegrationStep = 50; //<
39-
4037
/// The additional length in mm that the converted photon propagates without magnetic field
4138
Double_t fBufferGasAdditionalLength = 0; //<
4239

40+
/// The tolerance or accuracy used inside the GSL integrator
41+
Double_t fAccuracy = 0.1;
42+
43+
/// Number of intervales used by the GSL integrator
44+
Int_t fNumIntervals = 100;
45+
46+
/// Number of levels used by the GSL integrator to parameterize the cosine integral
47+
Int_t fQawoLevels = 20;
48+
49+
/// It will re-size the cells in the magnetic field (affecting the time required for integral computation)
50+
TVector3 fReMap = TVector3(30, 30, 100);
51+
4352
/// A pointer to the magnetic field description stored in TRestRun
4453
TRestAxionMagneticField* fMagneticField = nullptr; //!
4554

@@ -63,7 +72,14 @@ class TRestAxionFieldPropagationProcess : public TRestAxionEventProcess {
6372
void PrintMetadata() override {
6473
BeginPrintProcess();
6574

66-
RESTMetadata << "Integration step length : " << fIntegrationStep << " mm" << RESTendl;
75+
RESTMetadata << "Integration parameters" << RESTendl;
76+
RESTMetadata << "- Integration accuracy/tolerance : " << fAccuracy << RESTendl;
77+
RESTMetadata << "- Max number of integration intervals : " << fNumIntervals << RESTendl;
78+
RESTMetadata << "- Number of QAWO levels : " << fQawoLevels << RESTendl;
79+
RESTMetadata << " " << RESTendl;
80+
RESTMetadata << "Field re-mapping size : (" << fReMap.X() << ", " << fReMap.Y() << ", " << fReMap.Z()
81+
<< ")" << RESTendl;
82+
RESTMetadata << " " << RESTendl;
6783
RESTMetadata << "Buffer gas additional length : " << fBufferGasAdditionalLength * units("m") << " m"
6884
<< RESTendl;
6985

inc/TRestAxionMagneticField.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ class TRestAxionMagneticField : public TRestMetadata {
5858
/// A constant field component that will be added to the field map
5959
std::vector<TVector3> fConstantField; //<
6060

61-
/// The size of a grid element from the mesh in mm
61+
/// The size of a grid element from the mesh in mm. Initially, it must be the same as the binary input
62+
/// data
6263
std::vector<TVector3> fMeshSize; //<
6364

6465
/// The type of the mesh used (default is cylindrical)
@@ -67,9 +68,21 @@ class TRestAxionMagneticField : public TRestMetadata {
6768
/// A vector to store the maximum bounding box values
6869
std::vector<TVector3> fBoundMax; //<
6970

71+
/// A vector that defines the new mesh cell volume. It will re-scale the original fMeshSize.
72+
TVector3 fReMap = TVector3(0, 0, 0); //<
73+
7074
/// A magnetic field volume structure to store field data and mesh.
7175
std::vector<MagneticFieldVolume> fMagneticFieldVolumes; //!
7276

77+
/// The start track position used to parameterize the field along a track
78+
TVector3 fTrackStart = TVector3(0, 0, 0); //!
79+
80+
/// The track direction used to parameterize the field along a track
81+
TVector3 fTrackDirection = TVector3(0, 0, 0); //!
82+
83+
/// The total length of the track which defines the limit for field parameterization
84+
Double_t fTrackLength = 0; //!
85+
7386
/// A helper histogram to plot the field
7487
TH2D* fHisto; //!
7588

@@ -102,6 +115,14 @@ class TRestAxionMagneticField : public TRestMetadata {
102115
public:
103116
void LoadMagneticVolumes();
104117

118+
void ReMap(const size_t& n, const TVector3& newMapSize);
119+
120+
void SetTrack(const TVector3& position, const TVector3& direction);
121+
122+
Double_t GetTrackLength() const { return fTrackLength; }
123+
TVector3 GetTrackStart() const { return fTrackStart; }
124+
TVector3 GetTrackDirection() const { return fTrackDirection; }
125+
105126
/// It returns true if no magnetic field map was loaded for that volume
106127
Bool_t IsFieldConstant(Int_t id) {
107128
if (GetMagneticVolume(id)) return GetMagneticVolume(id)->field.size() == 0;
@@ -135,6 +156,7 @@ class TRestAxionMagneticField : public TRestMetadata {
135156
TVector3 GetVolumeCenter(Int_t id);
136157

137158
Double_t GetTransversalComponent(TVector3 position, TVector3 direction);
159+
Double_t GetTransversalComponentInParametricTrack(Double_t x);
138160

139161
std::vector<Double_t> GetTransversalComponentAlongPath(TVector3 from, TVector3 to, Double_t dl = 1.,
140162
Int_t Nmax = 0);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "TCanvas.h"
2+
#include "TGraph.h"
3+
#include "TLatex.h"
4+
#include "TLegend.h"
5+
#include "TLine.h"
6+
#include "TRestAxionBufferGas.h"
7+
#include "TRestAxionField.h"
8+
//*******************************************************************************************************
9+
//*** Description: This script will launch the integration of the axion-field with given parameters.
10+
//*** It allows to test different magnetic field cell sizes, for a given mass that can be off-resonance
11+
//*** for dm different from zero, and a given maximum tolerance or error for the integration routine.
12+
//***
13+
//*** The macro sets the TRestAxionField under debug mode to print the different results on screen.
14+
//***
15+
//*** --------------
16+
//*** Usage: restManager FieldIntegrationTests [sX=10] [sX=10] [sZ=10] [dm=0.01] [tolerance=0.1] [Ea=4.2]
17+
//*** --------------
18+
//***
19+
//*** Author: Javier Galan
20+
//*******************************************************************************************************
21+
int REST_Axion_FieldIntegrationTests(Double_t sX = 10, Double_t sY = 10, Double_t sZ = 50, Double_t dm = 0.01,
22+
Double_t tolerance = 0.1, Double_t Ea = 4.2) {
23+
/// Setting up magnetic field and track to evaluate
24+
TRestAxionMagneticField magneticField("fields.rml", "babyIAXO_HD");
25+
26+
for (size_t n = 0; n < magneticField.GetNumberOfVolumes(); n++)
27+
magneticField.ReMap(n, TVector3(sX, sY, sZ));
28+
magneticField.SetTrack(TVector3(-110, -110, -11000), TVector3(0.01, 0.01, 1));
29+
magneticField.PrintMetadata();
30+
31+
/// Setting up the gas
32+
TRestAxionBufferGas* gas = new TRestAxionBufferGas();
33+
gas->SetGasDensity("He", 3.267069078540181e-10);
34+
gas->PrintMetadata();
35+
Double_t ma = gas->GetPhotonMass(Ea);
36+
37+
/// Setting up the axion-field and assign gas and magnetic field.
38+
TRestAxionField* ax = new TRestAxionField();
39+
ax->AssignBufferGas(gas);
40+
ax->AssignMagneticField(&magneticField);
41+
ax->SetAxionEnergy(Ea);
42+
43+
/// Enable debugging mode in axion-field
44+
ax->SetDebug(true);
45+
46+
std::pair<double, double> prob =
47+
ax->GammaTransmissionFieldMapProbability(Ea, ma - dm, tolerance, 100, 25);
48+
49+
return 0;
50+
}

pipeline/ray-tracing/axion-field/Validate.C

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#include <TH1D.h>
22
#include <TRestRun.h>
33

4-
Double_t probTolerance = 1.e-21;
5-
Double_t fieldTolerance = 0.01;
4+
Double_t probTolerance = 1.e-22;
65

7-
Int_t Validate(Double_t prob = 5.18573e-19, Double_t fieldAverage = 1.5764) {
6+
Int_t Validate(Double_t prob = 2.34295e-21) {
87
TRestRun* run = new TRestRun("AxionPhotonProbability.root");
98

109
if (run->GetEntries() != 100) {
@@ -34,25 +33,30 @@ Int_t Validate(Double_t prob = 5.18573e-19, Double_t fieldAverage = 1.5764) {
3433
return 3;
3534
}
3635

37-
run->GetAnalysisTree()->Draw("axionPhoton_fieldAverage", "axionPhoton_fieldAverage");
36+
/* We do not add the field average observable anymore at TRestAxionFieldPropagationProcess
37+
* We would need to create a new process that does this, since it is computationally
38+
* not negligible
39+
*
40+
run->GetAnalysisTree()->Draw("axionPhoton_fieldAverage", "axionPhoton_fieldAverage");
3841
39-
TH1D* h2 = (TH1D*)run->GetAnalysisTree()->GetHistogram();
40-
if (h2 == nullptr) {
41-
std::cout << "Problems generating field average histogram" << std::endl;
42-
return 4;
43-
}
42+
TH1D* h2 = (TH1D*)run->GetAnalysisTree()->GetHistogram();
43+
if (h2 == nullptr) {
44+
std::cout << "Problems generating field average histogram" << std::endl;
45+
return 4;
46+
}
4447
45-
Double_t field = h2->Integral() / run->GetEntries();
46-
std::cout << "Average magnetic field: " << field << " T" << std::endl;
47-
std::cout << "Expected field: " << fieldAverage << std::endl;
48-
std::cout << "Tolerance: " << fieldTolerance << std::endl;
49-
std::cout << "Low : " << fieldAverage - fieldTolerance << " high: " << fieldAverage + fieldTolerance
50-
<< std::endl;
48+
Double_t field = h2->Integral() / run->GetEntries();
49+
std::cout << "Average magnetic field: " << field << " T" << std::endl;
50+
std::cout << "Expected field: " << fieldAverage << std::endl;
51+
std::cout << "Tolerance: " << fieldTolerance << std::endl;
52+
std::cout << "Low : " << fieldAverage - fieldTolerance << " high: " << fieldAverage + fieldTolerance
53+
<< std::endl;
5154
52-
if (field < fieldAverage - fieldTolerance || field > fieldAverage + fieldTolerance) {
53-
std::cout << "Wrong average field!" << std::endl;
54-
return 5;
55-
}
55+
if (field < fieldAverage - fieldTolerance || field > fieldAverage + fieldTolerance) {
56+
std::cout << "Wrong average field!" << std::endl;
57+
return 5;
58+
}
59+
*/
5660

5761
delete run;
5862

pipeline/ray-tracing/axion-field/photonConversion.rml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@
2626
</addProcess>
2727
<addProcess type="TRestAxionTransportProcess" zPosition="-5m" name="to5m"/>
2828
<addProcess type="TRestAxionDeviationProcess" name="dev" devAngle="2deg" seed="137"/>
29-
<addProcess type="TRestAxionFieldPropagationProcess" name="axionPhoton" integrationStep="5cm" bufferGasAdditionalLength="3m" observables="all" verboseLevel="info"/>
29+
30+
<addProcess type="TRestAxionFieldPropagationProcess" name="axionPhoton" bufferGasAdditionalLength="3m" observables="all" verboseLevel="info">
31+
<parameter name="accuracy" value="0.1"/>
32+
<parameter name="numIntervals" value="100" />
33+
<parameter name="qawoLevels" value="20"/>
34+
</addProcess>
35+
3036
<addProcess type="TRestAxionAnalysisProcess" name="at5m" observables="all"/>
3137
</TRestProcessRunner>
3238
<addTask command="EventProcess-&gt;RunProcess()" value="ON"/>

pipeline/ray-tracing/axion-field/plots.rml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
22
<TRestManager name="SpecPlot" title="Example" verboseLevel="info">
33
<TRestRun name="DummyRun"/>
4+
<!--- Some of these observables are only available up to release v2.4.1. After release v2.4.2 these observables have changed! -->
45
<TRestAnalysisPlot name="restplot" title="Optics Plots" verboseLevel="warning">
56
<parameter name="previewPlot" value="false"/>
67
<canvas size="(3600,2400)" divide="(3,3)" save="axionFieldPlots.png"/>

pipeline/ray-tracing/full-chain/ValidateChain.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Int_t ValidateChain(std::string fname) {
4646
Double_t integral2 = g->Integral() / run->GetEntries();
4747
std::cout << "Average window transmission : " << integral2 << std::endl;
4848

49-
if (integral < 9.71489e-24 || integral > 9.91489e-24) {
49+
if (integral > 2.01953e-22 || integral < 1.99953e-22) {
5050
std::cout << "Axion-photon probability is not within the expected range!" << std::endl;
5151
return 3;
5252
}

0 commit comments

Comments
 (0)