EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VstRadLength.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file VstRadLength.C
1 
2 // Hard to match ALICE TDR scale;
3 #define _PHI_MIN_ 2.00
4 #define _PHI_MAX_ 62.00
5 
6 #define _BIN_NUM_ 1000
7 
8 // Try to match ALICE TDR scale;
9 #define _YAXIS_MAX_ 0.80
10 
11 struct {
12  char *name;
13  int color;
14 } dets[] = {
15  // Colors a-la ALICE TDR;
16  {"VST/VstStove00/VstChipAssembly00/VstMimosaShell", kGreen+1},
17 
18  {"VST/VstStove00/VstChipAssembly00/VstWaterPipe", kCyan+1},
19  {"VST/VstStove00/VstChipAssembly00/VstWater", kBlue},
20 
21  {"VST/VstStove00/VstChipAssembly00/VstColdPlate", kBlack},
22 
23  {"VST/VstStove00/VstChipAssembly00/VstSideWall", kGray+2},
24  {"VST/VstStove00/VstChipAssembly00/VstFlatRoof", kGray+2},
25  {"VST/VstStove00/VstChipAssembly00/VstRoofSideBeam", kGray+2},
26 
27  {"VST/VstStove00/VstChipAssembly00/VstEnforcementBeam", kBlack},
28 
29  {"VST/VstStove00/VstChipAssembly00/VstCellFlexLayer", kRed+1},
30  {"VST/VstStove00/VstChipAssembly00/VstAluStrips", kRed+1},
31 };
32 
33 TString RemoveCrap(TString &path)
34 {
35  TString ret;
36  unsigned len = path.Length();
37  bool skip = true;
38 
39  // Admittedly this will NOT work for volume names containing underscores;
40  for(unsigned iq=0; iq<len; iq++) {
41  if (path[iq] == '/')
42  skip = false;
43  else if (path[iq] == '_')
44  skip = true;
45 
46  if (!skip) ret += path[iq];
47  } //for iq
48 
49  return ret;
50 } // RemoveCrap()
51 
52 
53 void VstRadLength() {
54  gROOT->Macro("$VMCWORKDIR/gconfig/rootlogon.C");
55 
56  TFile* f = new TFile("simparams.root");
57  f->Get("FairBaseParSet");
58 
59  // NB: CAVE material is not really accounted (so only subdetectors);
60  TString cavePrefix = "/cave";
61  int cave = -1;
62 
63  vector <TString> subs;
64  for(int i=0; i<sizeof(dets)/sizeof(dets[0]); i++)
65  if (!strcmp(dets[i].name, "cave")) {
66  subs.push_back(cavePrefix);
67  cave = i;
68  }
69  else
70  subs.push_back(cavePrefix + "/" + dets[i].name);
71 
72  // Yes, this way it works in CINT (but can not use sizeof(dets) trick directly);
73  const int NSUB = subs.size();
74 
75  TH1F* h[NSUB];
76  for (int i = 0; i < NSUB; i++) {
77  TH1F* tmp = h[i] = new TH1F(dets[i].name, dets[i].name, _BIN_NUM_, _PHI_MIN_, _PHI_MAX_);
78 
79  tmp->SetMarkerStyle(21);
80  tmp->SetMarkerColor(dets[i].color);
81  tmp->SetMarkerSize(1.0);
82  tmp->SetFillColor(dets[i].color);
83  }
84 
85  double phi_bin_width = (_PHI_MAX_ - _PHI_MIN_)/_BIN_NUM_;
86 
87  for (Int_t i = 0; i < _BIN_NUM_; i++) {
88  // The trick is that I do not want to account cave air beyond the last tracking element
89  // along this theta line; makes sense?;
90  double caveAccu = 0.0;
91 
92  double phi = (_PHI_MIN_ + (i - 0.5)*phi_bin_width)*TMath::Pi()/180.;
93  printf("bin# %3d (of %3d) ...\n", i, _BIN_NUM_);
94 
95  //double xx[3] = {0.0, 0.0, 0.1}, nn[3] = {TMath::Sin(theta), 0.0, TMath::Cos(theta)};
96  double xx[3] = {0.0, 0.0, 0.1}, nn[3] = {TMath::Cos(phi), TMath::Sin(phi)};
97  gGeoManager->SetCurrentPoint (xx);
98  gGeoManager->SetCurrentDirection(nn);
99 
100  for(TGeoNode *node = gGeoManager->GetCurrentNode(); ; ) {
101  TGeoMaterial *material = node->GetVolume()->GetMaterial();
102  double radlen = material->GetRadLen();
103 
104  gGeoManager->FindNextBoundary();
105  double thickness = gGeoManager->GetStep();
106 
107  //cout << gGeoManager->GetPath() << endl;
108  // Well, basically want to convert /cave_1/fstAir06_77/fst@06_6 to
109  // /cave/fstAir06/fst@06, etc;
110  TString path = RemoveCrap(gGeoManager->GetPath());
111 
112  // See whether I'm interested in such a part; NB: first match wins!;
113  for (int iii = 0; iii < NSUB; iii++)
114  if (iii == cave && path.EqualTo( cavePrefix )) {
115  // Pending approval ...;
116  caveAccu += thickness/radlen;
117  break;
118  }
119  else if (iii != cave && path.BeginsWith( subs[iii] )) {
120  if (caveAccu) {
121  h[cave]->SetBinContent(i+1, h[cave]->GetBinContent(i+1) + 100. * caveAccu);
122  caveAccu = 0.0;
123  } //if
124 
125  h[iii]->SetBinContent(i+1, h[iii]->GetBinContent(i+1) + 100. * thickness/radlen);
126  break;
127  } //for..if
128 
129  // Switch to next node along {xx, nn[]} 3D line;
130  node = gGeoManager->Step();
131  assert(gGeoManager->IsEntering());
132 
133  // Once out of volume, break;
134  if (gGeoManager->IsOutside()) break;
135  } //for inf
136  } //for i
137 
138  THStack *hs = new THStack("hs","EIC Detector Geometry: Radiation Length Scan");
139  for (int i = 0; i < NSUB; i++) {
140  hs->Add( h[i] );
141  }
142 
143  TCanvas* c1 = new TCanvas("c1","c1", 800, 600);
144  c1->SetFrameBorderSize(0);
145  hs->Draw();
146 
147  hs->GetXaxis()->SetTitle("Phi");
148  hs->GetXaxis()->SetLabelSize(0.03);
149  hs->GetYaxis()->SetTitle("radiation length X/X0, [%]");
150  hs->GetYaxis()->SetLabelSize(0.03);
151  hs->SetMaximum(_YAXIS_MAX_);
152 
153  TLegend *legend=new TLegend(0.38,0.88 - NSUB*.04,0.62,0.88);
154  legend->SetTextFont(72);
155  legend->SetTextSize(0.03);
156  for (int i = 0; i < NSUB; i++) {
157  legend->AddEntry(h[ NSUB - i - 1 ], dets[NSUB - i - 1].name,"p");
158  }
159  //legend->Draw();
160 
161  // Calculate average rad.length;
162  {
163  double averageRadLength = 0.0;
164 
165  for (int iii = 0; iii < NSUB; iii++)
166  for(unsigned iq=0; iq<_BIN_NUM_; iq++)
167  averageRadLength += h[iii]->GetBinContent(iq+1);
168 
169  printf("Average rad.length: %5.3f\n", averageRadLength/_BIN_NUM_);
170  }
171 
172  c1->SaveAs("radlen.gif");
173  //exit(0);
174 }