Jpp
Macros | Functions
JMarkovPathGenerator.cc File Reference
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <string>
#include "TRandom3.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TFile.h"
#include "TTree.h"
#include "TBranch.h"
#include "TGraph.h"
#include "Jeep/JParser.hh"
#include "JMarkov/JMarkovPathGenerator.hh"
#include "JMarkov/JPhotonPathWriter.hh"
#include "JPhysics/KM3NeT.hh"

Go to the source code of this file.

Macros

#define MPG_VERSION   2
 

Functions

int main (int argc, char **argv)
 

Macro Definition Documentation

◆ MPG_VERSION

#define MPG_VERSION   2

Definition at line 1 of file JMarkovPathGenerator.cc.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 42 of file JMarkovPathGenerator.cc.

43  {
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 ;
121  JScatteringModel sm ;
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 ;
JMARKOV::JMarkovPathGenerator::getFractionAccepted
double getFractionAccepted()
get the fraction of accepted steps during the last call to generateEnsemble (after burn-in)
Definition: JMarkovPathGenerator.hh:95
JTOOLS::n
const int n
Definition: JPolint.hh:628
std::vector
Definition: JSTDTypes.hh:12
JGEOMETRY3D::JVersor3D
Data structure for normalised vector in three dimensions.
Definition: JVersor3D.hh:23
JPARSER::JParser
Utility class to parse command line options.
Definition: JParser.hh:1493
JMARKOV::JMarkovPathGenerator::generateEnsemble
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...
Definition: JMarkovPathGenerator.hh:329
JIO::JWriterObjectOutput::put
virtual bool put(const T &object)
Object output.
Definition: JWriterObjectOutput.hh:50
JMARKOV::JMarkovPathGenerator
The JMarkovPathGenerator generates ensembles of photon paths using a Markov Chain Monte Carlo (MCMC).
Definition: JMarkovPathGenerator.hh:50
JMARKOV::JScatteringModel
Virtual base class for a scattering model.
Definition: JScatteringModel.hh:45
make_field
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1954
JMARKOV::JScatteringModel::getScatteringLength
virtual double getScatteringLength()
Definition: JScatteringModel.hh:72
KM3NET::getAngularAcceptance
double getAngularAcceptance(const double x)
Angular acceptence of KM3NeT PMT.
Definition: KM3NeT.hh:302
JLANG::JAccessibleOutputStream::close
virtual void close()
Close file.
Definition: JAccessibleStream.hh:142
JMARKOV::JPhotonPathWriter
Definition: JPhotonPathWriter.hh:16
JLANG::JAccessibleBinaryOutputStream::open
virtual void open(const char *file_name)
Open file.
Definition: JAccessibleBinaryStream.hh:92
MPG_VERSION
#define MPG_VERSION
Definition: JMarkovPathGenerator.cc:1
JPARSER::JParser::read
int read(const int argc, const char *const argv[])
Parse the program's command line options.
Definition: JParser.hh:1791