Jpp test-rotations-old
the software that should make you happy
Loading...
Searching...
No Matches
JMarkovPathGenerator.cc
Go to the documentation of this file.
1#define MPG_VERSION 2
2
3/*******************************************************************************
4 * \file Markov Chain Monte Carlo to generate photon paths
5
6 The result is saved to a file.
7*******************************************************************************/
8#include<iostream>
9#include<sstream>
10#include<iomanip>
11#include<vector>
12#include<cmath>
13#include<cstdlib>
14#include<string>
15
16#include "TRandom3.h"
17#include "TH1F.h"
18#include "TH2F.h"
19#include "TFile.h"
20#include "TTree.h"
21#include "TBranch.h"
22#include "TGraph.h"
23
24// JPP includes
25#include "Jeep/JParser.hh"
28#include "JPhysics/KM3NeT.hh"
29//#include "JMarkov/JScatteringModel.hh"
30
31// this little line removes the make_field macro defined in JParser.hh
32// so that we can call the
33// JPARSER::make_field(T,string) function ourselves
34#undef make_field
35using namespace JPP;
36
37using namespace JMARKOV ;
38using namespace std ;
39
40//ClassImp(ScatteringModel)
41
42
43int main( int argc, char** argv ) {
44 cout << "JMarkovPathGenerator version " << MPG_VERSION << endl
45 << "Written by Martijn Jongen" << endl
46 << endl ;
47 cout << "Type '" << argv[0] << " -h!' to display the command-line options." << endl ;
48 cout << endl ;
49
50 string outfile = "out.paths" ; // output file
51 string smoutfile = "" ; // output file to save scattering model to
52 double lHG = 60.241 ; // scattering length for Henyey-Greenstein model
53 double g = 0.924 ; // parameter g in Heyney-Greenstein model
54 double lR = 294.118 ; // scattering length for Rayleigh scattering
55 double a = 0.853 ; // a parameter for Rayleigh scatteing
56 double lA = 50 ; // absorption length
57 double d = 37 ; // distance to target
58 int npaths = 100 ; // number of paths to simulate
59 int nscat = 2 ; // number of scatterings
60 int interval = 1000 ; // number of MCMC steps between saved paths
61 int burnIn = 50000 ; // number of MCMC steps for initialization
62 double stepsize = 10 ; // size of the MCMC steps
63 bool sourceNB ;
64 double target_zenith ;
65
66 try {
67 JParser<string> zap ; // this argument parser can handle strings
68 zap["o"] = make_field(outfile,"output file name") ;
69 zap["O"] = make_field(smoutfile,"OPTIONAL: output file name for scattering model") ;
70 zap["-lH"] = make_field(lHG,"scattering length in m for Henyey-Greenstein scattering") ;
71 zap["g"] = make_field(g,"parameter g for Henyey-Greenstein function") ;
72 zap["R"] = make_field(lR,"scattering length in m for Rayleigh scattering") ;
73 zap["a"] = make_field(a,"parameter a for Rayleigh scattering") ;
74 zap["A"] = make_field(lA,"absorption length in m") ;
75 zap["d"] = make_field(d,"distance between source and target in m") ;
76 zap["n"] = make_field(npaths,"number of paths to generate") ;
77 zap["N"] = make_field(nscat,"number of scatterings") ;
78 zap["i"] = make_field(interval,"number of MCMC steps to take between saving paths") ;
79 zap["b"] = make_field(burnIn,"number of burn-in steps") ;
80 zap["s"] = make_field(stepsize,"step size for the MCMC steps") ;
81 zap["sourceNB"] = make_field(sourceNB,"Use a nanobeacon profile as source (currently a uniform distribution in a 45 degree cone around the positive z-direction") ;
82 zap["target_zenith"] = make_field(target_zenith,"[degrees] OPTIONAL: set to use a realistic PMT acceptance") = -1 ;
83
84 if (zap.read(argc, argv) != 0) {
85 return 1 ;
86 }
87 }
88 catch(const exception &error) {
89 // ignore exceptions
90 }
91
92 // inform user of the settings
93 cout << "output file name = '" << outfile << "'." << endl ;
94 cout << "absorption length = " << lA << " m" << endl ;
95 cout << "distance to target = " << d << " m" << endl ;
96 cout << "npaths = " << npaths << endl ;
97 cout << "nscat = " << nscat << endl ;
98 cout << "interval = " << interval << " steps" << endl ;
99 cout << "burn-in = " << burnIn << " steps" << endl ;
100 cout << "step size = " << stepsize << " m" << endl ;
101 cout << endl ;
102
103 // Henyey-Greenstein scattering model
104 JScatteringModel smHG ;
105 cout << "Henyey-Greenstein scattering length = " << lHG << " m" << endl ;
106 cout << "g = " << g << endl ;
107 smHG.setScatteringLength(lHG) ;
108 smHG.setScatteringProfileHG(g) ;
109 cout << endl ;
110
111 // Rayleigh scattering model
112 JScatteringModel smR ;
113 cout << "Rayleigh scattering length = " << lR << " m" << endl ;
114 cout << "a = " << a << endl ;
115 smR.setScatteringLength(lR) ;
116 smR.setScatteringProfileRayleigh(a) ;
117 cout << endl ;
118
119 // combined scattering model
120 cout << "Combining HG and Rayleigh scattering into a single effective model." << endl ;
122 setEffectiveScatteringModel( smHG, smR, sm ) ;
123 cout << "Effective scattering length = " << sm.getScatteringLength() << " m" << endl ;
124 sm.setAbsorptionLength(lA) ;
125
126 cout << "Integral over scattering profile = " << sm.hscat->Integral("width")*2*M_PI << " (should be 1)" << endl ;
127 cout << endl ;
128
129 // set source distribution
130 if( sourceNB ) {
131 cout << "Setting source distribution to a preliminary approximation of a nanobeacon profile. Light is emitted uniformly within a cone around the positive z-axis." << endl ;
132 // we oversample each bin
133 const int n = 100 ;
134 for( Int_t xbin=1; xbin<=sm.hsource->GetNbinsX() ; ++xbin ) {
135 double val = 0 ;
136 double xmin = sm.hsource->GetXaxis()->GetBinLowEdge(bin) ;
137 double xmax = sm.hsource->GetXaxis()->GetBinUpEdge(bin) ;
138 for( int i=0 ; i<n ; ++i ) {
139 double ct = xmin + (xmax-xmin)*(i+0.5)/n ;
140 if( ct >= sqrt(0.5) ) val += 1 ;
141 }
142 val /= n ;
143 for( Int_t ybin=1 ; ybin<=sm.hsource->GetNbinsY() ; ++ybin ) {
144 Int_t bin = sm.hsource->GetBin(xbin,ybin) ;
145 sm.hsource->SetBinContent(bin,val) ;
146 }
147 }
148 sm.hsource->Scale( sqrt(2)/(2*M_PI*(sqrt(2)-1)) ) ;
149 cout << endl ;
150 }
151
152 cout << "Integral over source profile = " << sm.hsource->Integral("width") << " (should be 1)" << endl ;
153 cout << endl ;
154
155 // set PMT efficiency
156 if( target_zenith >= 0 ) {
157 cout << "Setting target to a KM3NeT PMT." << endl
158 << "Its orientation is rotated " << target_zenith << " degrees w.r.t. the negative z-axis" << endl
159 << "(the rotation is in the yz-plane)" << endl ;
160 target_zenith *= M_PI/180 ; // convert to radians
161 JGEOMETRY3D::JVersor3D pmtdir( sin(target_zenith), 0, cos(target_zenith) ) ;
162 for( Int_t xbin=1; xbin<=sm.htarget->GetXaxis()->GetNbins() ; ++xbin ) {
163 double ct = sm.htarget->GetXaxis()->GetBinCenter(xbin) ;
164 double theta = acos(ct) ;
165 for( Int_t ybin=1; ybin<=sm.htarget->GetYaxis()->GetNbins() ; ++ybin ) {
166 Int_t bin = sm.htarget->GetBin(xbin,ybin) ;
167 double phi = sm.htarget->GetYaxis()->GetBinCenter(ybin) ;
168
169 JGEOMETRY3D::JVersor3D testdir( cos(phi)*sin(theta),
170 sin(phi)*sin(theta),
171 cos(theta) ) ;
172 double effct = -testdir.getDot(pmtdir) ;
173 double val = KM3NET::getAngularAcceptance(effct) ;
174 // safety catch: I never want my probability to be exactly 0
175 // so I just set it to a really low number!
176 if( val == 0 ) val = 1e-10 ;
177 sm.htarget->SetBinContent(bin,val) ;
178 }
179 }
180 double maxval = sm.htarget->GetBinContent( sm.htarget->GetMaximumBin() ) ;
181 sm.htarget->Scale(1.0/maxval) ;
182 cout << endl ;
183 }
184
185 // create output root file containing the scattering model
186 if( smoutfile != "" ) {
187 cout << "Saving scattering model to '" << smoutfile << "'." << endl ;
188 TFile* fout = new TFile(smoutfile.c_str(),"recreate") ;
189 sm.Write() ;
190 // we also save the source, scattering and target histograms to a separate
191 // folder, so that we can view them immediately from a TBrowser
192 fout->mkdir("ScatteringModel_ingredients")->cd() ;
193 sm.hsource->Write() ;
194 sm.hscat->Write() ;
195 sm.htarget->Write() ;
196 fout->cd() ;
197 fout->Close() ;
198 cout << endl ;
199 }
200
201 // generate an ensemble of paths
202 cout << "Generating ensemble" << endl ;
204 vector<JPhotonPath> ensemble = mpg.generateEnsemble( npaths, nscat, sm, burnIn, interval, d, stepsize ) ;
205 cout << "Done generating ensemble." << endl ;
206 double acceptance = mpg.getFractionAccepted() ;
207 cout << 100*acceptance << "% of steps were accepted" << endl
208 << "(as a rule of thumb, ~23% is optimal for high-dimensional spaces)" << endl
209 << endl ;
210
211 // write the generated photon paths to a file
212 cout << "Writing generated ensemble to '" << outfile << "'." << endl ;
214 writer.open(outfile.c_str()) ;
215 for( vector<JPhotonPath>::iterator it=ensemble.begin() ; it!=ensemble.end() ; ++it ) {
216 writer.put( *it ) ;
217 }
218 writer.close() ;
219 cout << endl ;
220
221 cout << "Done!" << endl ;
222
223 return 0 ;
224}
int main(int argc, char **argv)
#define MPG_VERSION
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Properties of KM3NeT PMT and deep-sea water.
Data structure for normalised vector in three dimensions.
Definition JVersor3D.hh:28
double getDot(const JVersor3D &versor) const
Get dot product.
Definition JVersor3D.hh:156
virtual void open(const char *file_name) override
Open file.
virtual void close()
Close file.
virtual bool put(const T &object)=0
Object output.
The JMarkovPathGenerator generates ensembles of photon paths using a Markov Chain Monte Carlo (MCMC).
std::vector< JPhotonPath > generateEnsemble(int n, const JPhotonPath &start_path, JSourceModel *src, JScatteringModel *sm, JTargetModel *trg, double lambda_abs, int nsteps_burn_in, int nsteps_save)
Generate an ensemble of n paths with a fixed number of scatterings by MCMC-sampling the given scatter...
double getFractionAccepted()
get the fraction of accepted steps during the last call to generateEnsemble (after burn-in)
Virtual base class for a scattering model.
virtual double getScatteringLength()
Utility class to parse command line options.
Definition JParser.hh:1698
int read(const int argc, const char *const argv[])
Parse the program's command line options.
Definition JParser.hh:1992
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
const int n
Definition JPolint.hh:791