DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
materialBudget.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 //==========================================================================
11 //
12 // Compute the material budget in terms of integrated radiation and ineraction
13 // lengths as seen from the IP for various subdetector regions given in
14 // a simple steering file. Creates a root file w/ histograms and dumps numbers
15 // the screen.
16 //
17 // Author : F.Gaede, DESY
18 //
19 //==========================================================================
20 
21 // Framework include files
22 #include <DD4hep/DetType.h>
23 #include <DD4hep/Printout.h>
24 #include <DD4hep/Detector.h>
25 #include <DDRec/MaterialManager.h>
26 
27 #include <TFile.h>
28 #include <TH1F.h>
29 #include <TError.h>
30 
31 #include <cerrno>
32 #include <fstream>
33 #include <climits>
34 
35 #include "main.h"
36 
37 using namespace dd4hep;
38 using namespace dd4hep::rec;
39 
40 void dumpExampleSteering() ;
41 
42 namespace {
43 
44  struct SDetHelper{
45  std::string name { };
46  double r0 { 0.0 };
47  double r1 { 0.0 };
48  double z0 { 0.0 };
49  double z1 { 0.0 };
50  TH1F* hx { nullptr };
51  TH1F* hl { nullptr };
52  };
53 
55  Vector3D pointOnCylinder( double theta, double r, double z, double phi){
56 
57  double theta0 = atan2( r, z ) ;
58 
59  Vector3D v = ( theta > theta0 ?
60  Vector3D( r , phi , r / tan( theta ) , Vector3D::cylindrical ) :
61  Vector3D( z * tan( theta ) , phi , z , Vector3D::cylindrical ) ) ;
62  return v ;
63  }
64 
65 }
66 
67 int main_wrapper(int argc, char** argv) {
68 
69  struct Handler {
70  Handler() { SetErrorHandler(Handler::print); }
71 
72  static void print(int level, Bool_t abort, const char *location, const char *msg) {
73  if ( level > kInfo || abort ) ::printf("%s: %s\n", location, msg);
74  }
75 
76  static void usage() {
77  std::cout << " usage: materialBudget compact.xml steering.txt" << std::endl
78  << " -> create histograms with the material budget as seen from the IP within fixed ranges of (rmin, rmax, zmin. zmax)" << std::endl
79  << " see example steering file for details ..." << std::endl
80  << " -x : dump example steering file " << std::endl
81  << std::endl;
82  exit(1);
83  }
84 
85  } _handler;
86 
87 
88  if( argc == 2 ){
89  std::string dummy = argv[1] ;
90 
91  if( dummy == "-x" )
93  else
95  }
96 
97  if( argc != 3 )
99 
100 
101  // ================== parse steering file ========================================================
102  std::string compactFile = argv[1];
103  std::string steeringFile = argv[2];
104  int nbins = 90 ;
105  double phi0 = M_PI / 2. ;
106  double thetaMin = 0. ;
107  double thetaMax = 90. ;
108  double etaMin = 0. ;
109  double etaMax = -1. ;
110  std::string outFileName("material_budget.root") ;
111  std::vector<SDetHelper> subdets ;
112 
113 
114  std::ifstream infile(steeringFile );
115  std::string line;
116 
117  while (std::getline(infile, line)) {
118  // ignore empty lines and comments
119  if( line.empty() || line.find("#") == 0 )
120  continue ;
121 
122  std::istringstream iss(line);
123  std::string token ;
124  iss >> token ;
125 
126  if( token == "nbins" ){
127  iss >> nbins ;
128  }
129  else if( token == "thetaMin" ){
130  iss >> thetaMin ;
131  }
132  else if( token == "thetaMax" ){
133  iss >> thetaMax ;
134  }
135  else if( token == "etaMin" ){
136  iss >> etaMin ;
137  }
138  else if( token == "etaMax" ){
139  iss >> etaMax ;
140  }
141  else if( token == "rootfile" ){
142  iss >> outFileName ;
143  }
144  else if( token == "phi" ){
145  iss >> phi0 ;
146  phi0 = phi0 / 180. * M_PI ;
147  }
148  else if( token == "subdet" ){
149  SDetHelper det;
150  iss >> det.name >> det.r0 >> det.z0 >> det.r1 >> det.z1 ;
151  subdets.emplace_back( det );
152  }
153 
154  if ( iss.fail() ){
155  std::cout << " ERROR parsing line : " << line << std::endl ;
156  ::exit(EINVAL);
157  }
158  }
159 
160  if ( nbins <= 0 ) {
161  std::cout << "Invalid value for binning (nbins) " << nbins << std::endl;
162  return EINVAL;
163  }
164 
165  // =================================================================================================
166  setPrintLevel(WARNING);
167 
168  Detector& description = Detector::getInstance();
169  description.fromXML(compactFile ) ;
170 
171  //----- open root file and book histograms
172  TFile* rootFile = new TFile(outFileName.c_str(),"recreate");
173  for( auto& det : subdets ) {
174  std::string hxn(det.name), hxnn(det.name) ;
175  std::string hln(det.name), hlnn(det.name) ;
176 
177  if( etaMax > 0. ) { // use eta
178  hxn += "x0" ;
179  hxnn += " integrated X0 vs eta" ;
180  det.hx = new TH1F( hxn.c_str(), hxnn.c_str(), nbins, etaMin , etaMax ) ;
181 
182  hln += "lambda" ;
183  hlnn += " integrated int. lengths vs eta" ;
184  det.hl = new TH1F( hln.c_str(), hlnn.c_str(), nbins, etaMin , etaMax ) ;
185  }
186  else { // use polar angle
187  hxn += "x0" ;
188  hxnn += " integrated X0 vs -theta" ;
189  det.hx = new TH1F( hxn.c_str(), hxnn.c_str(), nbins, -thetaMax , -thetaMin ) ;
190 
191  hln += "lambda" ;
192  hlnn += " integrated int. lengths vs -theta" ;
193  det.hl = new TH1F( hln.c_str(), hlnn.c_str(), nbins, -thetaMax , -thetaMin ) ;
194  }
195  }
196  //-------------------------
197 
198 
199  Volume world = description.world().volume() ;
200 
201  MaterialManager matMgr( world ) ;
202 
203  thetaMin = thetaMin / 180. * M_PI ;
204  thetaMax = thetaMax / 180. * M_PI ;
205  double dTheta = (thetaMax-thetaMin)/nbins; // bin size
206  double dEta = (etaMax-etaMin)/nbins ;
207 
208  std::cout << "====================================================================================================" << std::endl ;
209  std::cout << "theta:f/" ;
210  for(auto& det : subdets){ std::cout << det.name << "_x0:f/" << det.name << "_lam:f/" ; }
211  std::cout << std::endl ;
212 
213  if ( nbins <= 0 || nbins > USHRT_MAX ) {
214  std::cout << "Unreasonable number of bins: " << nbins << std::endl;
215  ::exit(EINVAL);
216  }
217 
218  for(int i=0 ; i< nbins ;++i){
219  double theta = ( etaMax > 0. ? 2. * atan ( exp ( - ( etaMin + (0.5+i)*dEta) ) ) : ( thetaMin + (0.5+i)*dTheta ) ) ;
220  std::stringstream paramLine;
221 
222  paramLine << std::scientific << theta << " " ;
223  for( auto& det : subdets ) {
224  Vector3D p0 = pointOnCylinder( theta, det.r0 , det.z0 , phi0 ) ;// double theta, double r, double z, double phi)
225  Vector3D p1 = pointOnCylinder( theta, det.r1 , det.z1 , phi0 ) ;// double theta, double r, double z, double phi)
226  const MaterialVec& materials = matMgr.materialsBetween(p0, p1);
227  double sum_x0(0.), sum_lambda(0.);
228  // double path_length(0.);
229 
230  for( auto amat : materials ) {
231  TGeoMaterial* mat = amat.first->GetMaterial();
232  double length = amat.second;
233  double nx0 = length / mat->GetRadLen();
234  sum_x0 += nx0;
235  double nLambda = length / mat->GetIntLen();
236  sum_lambda += nLambda;
237  // path_length += length;
238  }
239 
240  double binX = ( etaMax > 0. ? (etaMin + (0.5+i)*dEta) : -theta/M_PI*180. ) ;
241  det.hx->Fill( binX , sum_x0 ) ;
242  det.hl->Fill( binX , sum_lambda ) ;
243  paramLine << std::scientific << sum_x0 << " " << sum_lambda << " " ; // << path_length ;
244  }
245  std::cout << paramLine.str() << std::endl;
246  }
247  std::cout << "====================================================================================================" << std::endl ;
248  rootFile->Write();
249  rootFile->Close();
250  return 0;
251 }
252 
254  std::cout << "# Example steering file for materialBudget (taken from ILD_l5_v02)" << std::endl ;
255  std::cout << std::endl ;
256  std::cout << "# root output file" << std::endl ;
257  std::cout << "rootfile material_budget.root" << std::endl ;
258  std::cout << "# number of bins for polar angle (default 90)" << std::endl ;
259  std::cout << "nbins 90" << std::endl ;
260  std::cout << std::endl ;
261  std::cout << "# use polar angle - specify minimum and maximum theta value" << std::endl ;
262  std::cout << "# thetaMin 0." << std::endl ;
263  std::cout << "# thetaMax 90." << std::endl ;
264  std::cout << std::endl ;
265  std::cout << "# use pseudo rapidity rather than polar angle - specify minimum and maximum eta value" << std::endl ;
266  std::cout << "# etaMin -3." << std::endl ;
267  std::cout << "# etaMax 3." << std::endl ;
268  std::cout << std::endl ;
269  std::cout << "# phi direction in deg (default: 90./y-axis)" << std::endl ;
270  std::cout << "phi 90." << std::endl ;
271  std::cout << std::endl ;
272  std::cout << "# names and subdetector ranges given in [rmin,zmin,rmax,zmax] - e.g. for ILD_l5_vo2 (run dumpdetector -d to get numbers... ) " << std::endl ;
273  std::cout << std::endl ;
274  std::cout << "subdet vxd 0. 0. 6.549392e+00 1.450000e+01" << std::endl ;
275  std::cout << "subdet sitftd 0. 0. 3.024000e+01 2.211800e+02" << std::endl ;
276  std::cout << "subdet tpc 0. 0. 1.692100e+02 2.225000e+02" << std::endl ;
277  std::cout << "subdet outtpc 0. 0. 1.769800e+02 2.350000e+02" << std::endl ;
278  std::cout << "subdet set 0. 0. 1.775200e+02 2.300000e+02" << std::endl ;
279  ::exit(0);
280 }
dd4hep::Detector::world
virtual DetElement world() const =0
Return reference to the top-most (world) detector element.
dd4hep::rec
Namespace for the reconstruction part of the AIDA detector description toolkit.
Definition: SurfaceInstaller.h:28
v
View * v
Definition: MultiView.cpp:28
dd4hep::rec::Vector3D
Definition: Vector3D.h:32
Detector.h
M_PI
#define M_PI
Definition: Handle.h:33
dd4hep::rec::MaterialVec
std::vector< std::pair< Material, double > > MaterialVec
Definition: MaterialManager.h:30
dd4hep::rec::Vector3D::cylindrical
static Cylindrical cylindrical()
Definition: Vector3D.h:278
DetType.h
dd4hep::Detector::getInstance
static Detector & getInstance(const std::string &name="default")
—Factory method----—
Definition: DetectorImp.cpp:150
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:370
dd4hep::DetElement::volume
Volume volume() const
Access to the logical volume of the detector element's placement.
Definition: DetElement.cpp:352
dd4hep::rec::MaterialManager
Definition: MaterialManager.h:41
main_wrapper
int main_wrapper(int argc, char **argv)
Definition: materialBudget.cpp:67
dd4hep::rec::MaterialManager::materialsBetween
const MaterialVec & materialsBetween(const Vector3D &p0, const Vector3D &p1, double epsilon=1e-4)
Definition: MaterialManager.cpp:40
main.h
MaterialManager.h
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::Detector::fromXML
virtual void fromXML(const std::string &fname, DetectorBuildType type=BUILD_DEFAULT)=0
Read any geometry description or alignment file.
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
usage
void usage(std::string argv0)
Definition: listcomponents.cpp:41
Printout.h
dumpExampleSteering
void dumpExampleSteering()
Definition: materialBudget.cpp:253