/******************************************************************************* * \file Calculate total hit probability for paths with a given number of scatterings The calculation is based on an input file containing (what is assumed to be) a representative sample of JPhotonPaths. Also, the JScatteringModel used to generate the paths must be supplied. Approximates the total probability density integral by importance sampling paths from vertex positions distributions that are based on the input path ensemble. *******************************************************************************/ // C++ standard library #include #include #include #include #include #include // ROOT #include "TRandom3.h" #include "TFile.h" #include "TPolyLine3D.h" #include "TPolyMarker3D.h" #include "TAxis3D.h" #include "TView.h" #include "TView3D.h" #include "TCanvas.h" #include "TPad.h" // JPP #include "Jeep/JParser.hh" #include "JMarkov/JPhotonPath.hh" #include "JMarkov/JPhotonPathReader.hh" #include "JMarkov/JPhotonPathWriter.hh" #include "JMarkov/JScatteringModel.hh" // namespaces using namespace std ; // this little line removes the make_field macro defined in JParser.hh // so that we can call the // JPARSER::make_field(T,string) function ourselves #undef make_field using namespace JPP; int main( int argc, char** argv ) { cout << "JMarkovPathIntegrator" << endl << "Written by Martijn Jongen" << endl << endl ; gRandom->SetSeed(0) ; string ifname_paths ; string ifname_model ; string ofname ; int nsamples ; int nscat ; int nbins ; try { JParser zap ; // this argument parser can handle strings zap["f"] = make_field(ifname_paths,"input file name (binary file containing JPhotonPaths)") ; zap["m"] = make_field(ifname_model,"input file name (root file containing JScatteringModel)") ; zap["o"] = make_field(ofname,"OPTIONAL file name for root output") = "" ; zap["n"] = make_field(nscat,"number of scatterings") ; zap["N"] = make_field(nsamples,"number of samples") = 10000 ; zap["nbins"] = make_field(nbins,"nbins of vertex distribution histograms") = 1000 ; if (zap.read(argc, argv) != 0) { return 1 ; } } catch(const exception &error) { cout << error.what() << endl ; cout << "Type '" << argv[0] << " -h!' to display the command-line options." << endl ; exit(1) ; } cout << "SETTINGS: " << endl ; cout << " Input file (paths) = '" << ifname_paths << "'" << endl ; cout << " Input file (model) = '" << ifname_model << "'" << endl ; cout << " Output file = '" << ofname << "'" << endl ; cout << " nsamples = " << nsamples << endl ; cout << " nscat = " << nscat << endl ; cout << " nbins = " << nbins << endl ; cout << endl ; int nvert = nscat + 2 ; // the number of vertices in each path // read in the scatteringmodel cout << "Loading scattering model" << endl ; JMARKOV::JScatteringModel* sm ; // open the root file TFile* f = new TFile(ifname_model.c_str(),"read") ; if( f->IsZombie() ) { cerr << "Could not open file '" << ifname_model << "'." << endl ; exit(1) ; } sm = (JMARKOV::JScatteringModel*) f->Get("JMARKOV::JScatteringModel") ; if( sm == NULL ) { cerr << "Could not read JScatteringModel from file!" << endl ; exit(1) ; } cout << "JScatteringModel loaded" << endl << " absorption length = " << sm->getAbsorptionLength() << " m" << endl << " scattering length = " << sm->getScatteringLength() << " m" << endl << endl ; // read the paths from the file JMARKOV::JPhotonPathReader reader ; reader.open(ifname_paths.c_str()) ; if( !reader.is_open() ) { cerr << "FATAL ERROR: unable to open input file '" << ifname_paths << "'." << endl ; exit(1) ; } int nread = 0 ; JMARKOV::JPhotonPath* p = NULL ; cout << "Reading file" << endl ; vector paths ; while( reader.hasNext() ) { p = reader.next() ; if( p->size() == (unsigned int)nvert ) paths.push_back(*p) ; else cout << p->size() << endl ; ++nread ; } reader.close() ; int npaths = paths.size() ; if( npaths == 0 ) { cerr << "FATAL ERROR: No JPhotonPaths with nscat=" << nscat << " in '" << ifname_paths << "'." << endl ; exit(1) ; } cout << "Done reading file. Selected " << npaths << " / " << nread << " JPhotonPaths." << endl ; cout << endl ; // find the minimal and maximal values of each coordinate of each vertex JMARKOV::JPhotonPath minvals(nscat) ; JMARKOV::JPhotonPath maxvals(nscat) ; double INF = 1.0/0.0 ; double MININF = -1.0/0.0 ; // initialize to +- infinity for( int i=0 ; i::iterator p=paths.begin() ; p!=paths.end() ; ++p ) { // loop over the vertices for( int i=0; iat(i).getX()), min(minvals[i].getY(),p->at(i).getY()), min(minvals[i].getZ(),p->at(i).getZ()) ) ; maxvals[i] = JGEOMETRY3D::JPosition3D( max(maxvals[i].getX(),p->at(i).getX()), max(maxvals[i].getY(),p->at(i).getY()), max(maxvals[i].getZ(),p->at(i).getZ()) ) ; } } cout << endl ; cout << "Allocating histograms." << endl ; // allocate histograms for the vertex positions vector hX(nvert) ; // x positions of vertices vector hY(nvert) ; // y positions of vertices vector hZ(nvert) ; // z positions of vertices for( int n=0; n::iterator p=paths.begin() ; p!=paths.end() ; ++p ) { // loop over the vertices for( int n=0; nFill( p->at(n).getX() ) ; hY[n]->Fill( p->at(n).getY() ) ; hZ[n]->Fill( p->at(n).getZ() ) ; } } cout << endl ; // normalize the histograms to 1 cout << "Normalizing histograms." << endl ; for( int n=0 ; nScale( 1.0 / hX[n]->Integral() ) ; hY[n]->Scale( 1.0 / hY[n]->Integral() ) ; hZ[n]->Scale( 1.0 / hZ[n]->Integral() ) ; } cout << endl ; // #tmp temporarily save the paths with extremely high contributions // to a file JMARKOV::JPhotonPathWriter writer ; writer.open("high_contribution_paths.paths") ; // MC-integrate the path probability, using the vertex distributions as // our sampling function cout << "Computing scattering probability" << endl ; double Pscat = 0 ; double Pscat_err ; vector integralConts(nsamples) ; vector rhos(nsamples) ; vector ws(nsamples) ; TH1F* hRhos ; TH1F* hWs ; TH1F* hIntegralConts ; TH1F* hIntegralConts_zoom ; // define test path JMARKOV::JPhotonPath testpath(nscat) ; // starting vertex testpath[0] = JGEOMETRY3D::JPosition3D( hX[0]->GetMean(1), hY[0]->GetMean(1), hZ[0]->GetMean(1) ) ; // ending vertex testpath[nvert-1] = JGEOMETRY3D::JPosition3D( hX[nvert-1]->GetMean(1), hY[nvert-1]->GetMean(1), hZ[nvert-1]->GetMean(1) ) ; // integrate over the free vertices for( int i=0 ; iGetRandom() ; double y = hY[n]->GetRandom() ; double z = hZ[n]->GetRandom() ; Int_t xbin = hX[n]->GetXaxis()->FindBin(x) ; Int_t ybin = hY[n]->GetXaxis()->FindBin(y) ; Int_t zbin = hZ[n]->GetXaxis()->FindBin(z) ; double wx = hX[n]->GetBinContent(xbin) / hX[n]->GetBinWidth(xbin) ; double wy = hY[n]->GetBinContent(ybin) / hY[n]->GetBinWidth(ybin) ; double wz = hZ[n]->GetBinContent(zbin) / hZ[n]->GetBinWidth(zbin) ; w *= wx * wy * wz ; testpath[n] = JGEOMETRY3D::JPosition3D(x,y,z) ; } double rho = sm->getRho(testpath) ; rhos[i] = rho ; ws[i] = w ; integralConts[i] = rho/w ; Pscat += rho / w ; if( rho/w > 0.001 ) { /*cout << "Found high rho/w = " << rho/w << endl ; cout << "rho = " << rho << ", w = " << w << endl ; cout << "Rerunning calculation of rho in verbose mode" << endl ; sm->getRho(testpath,true) ; cout << "Path: " << endl ; for( JMARKOV::JPhotonPath::iterator it=testpath.begin() ; it!=testpath.end() ; ++it ) { cout << "( " << it->getX() << ", " << it->getY() << ", " << it->getZ() << " ) " ; } cout << endl ; cout << endl ;*/ writer.put( testpath ) ; } } Pscat /= nsamples ; writer.close() ; // statistical characteristics of the integral contributions double sigma = 0 ; // standard deviation { double max ; char hname[200] ; char htitle[300] ; // histogram of path probability densities (whole range) max = *(max_element( rhos.begin(), rhos.end() )) ; sprintf( hname, "hRhos_nscat%i", nscat ) ; sprintf( htitle, "Path probability density for nscat = %i", nscat ) ; hRhos = new TH1F(hname,htitle,100,0,1.01*max) ; // histogram of path probability densities (whole range) max = *(max_element( ws.begin(), ws.end() )) ; sprintf( hname, "hWs_nscat%i", nscat ) ; sprintf( htitle, "Path weights for nscat = %i", nscat ) ; hWs = new TH1F(hname,htitle,100,0,1.01*max) ; // histogram of integral contributions (whole range) max = *(max_element( integralConts.begin(), integralConts.end() )) ; sprintf( hname, "hIntegralConts_nscat%i", nscat ) ; sprintf( htitle, "Contributions to the integral for nscat = %i", nscat ) ; hIntegralConts = new TH1F(hname,htitle,100,0,1.01*max) ; // histogram of integral contributions (up to 10*mean) max = 10*Pscat ; sprintf( hname, "hIntegralConts_nscat%i_zoom", nscat ) ; sprintf( htitle, "Contributions to the integral for nscat = %i (zoom)", nscat ) ; hIntegralConts_zoom = new TH1F(hname,htitle,100,0,1.01*max) ; for( int i=0; iFill( rhos[i] ) ; hWs->Fill( ws[i] ) ; hIntegralConts->Fill( integralConts[i] ) ; hIntegralConts_zoom->Fill( integralConts[i] ) ; } // get sample variance double var = 0 ; for( int i=0; imkdir(dname)->cd() ; hRhos->Write() ; hWs->Write() ; hIntegralConts->Write() ; hIntegralConts_zoom->Write() ; for( int n=0; nWrite() ; hY[n]->Write() ; hZ[n]->Write() ; } fout->cd() ; fout->Close() ; delete fout ; cout << "Output written to '" << ofname << "'." << endl ; cout << endl ; } cout << "Done!" << endl ; return 0 ; }