2 #include "StiVMCToolKit.h"
6 #if !defined(__CINT__) || defined(__MAKECINT__)
14 #include "StMessMgr.h"
16 #define BIT(n) (1 << (n))
18 static Int_t __addelement__(Int_t NElem,
const TGeoMaterial *mat,
Elem_t *ElementList) {
19 return StiVMCToolKit::Add2ElementList(NElem, mat, ElementList);
27 Elem_t() : index(0),W(0),A(0),Z(0) {}
36 static Int_t m_Debug = 0;
37 static const Int_t NoElemMax = 10000;
39 {
"PIPE",
"the STAR beam pipe mother volume",
"HALL_1/CAVE_1/PIPE_1-2/*",
"",
""},
40 {
"PIPC",
"the Central Beam PIPe Volum",
"HALL_1/CAVE_1/PIPE_1-2/PIPC_1/*",
"",
""},
41 {
"PVAC",
"the Vacuum Volume of Be section of pipe",
"HALL_1/CAVE_1/PIPE_1-2/PIPC_1/PVAC_1",
"",
""},
42 {
"PIPO",
"Steel pipe from Be to 1st flanges",
"HALL_1/CAVE_1/PIPE_1-2/PIPO_1/PVAO_1",
"",
""},
43 {
"PVAO",
"its cavity",
"HALL_1/CAVE_1/PIPE_1-2/PIPO_1/PVAO_1",
"",
""},
45 {
"PXBX",
"Extrenal Berillium tube",
"HALL_1/CAVE_1/PXBX_1",
"",
""},
47 {
"SOUM",
"Outer shileding structure",
"HALL_1/CAVE_1/SVTT_1/SOUM_1/*",
"",
""},
48 {
"SXRL",
"Circular water feeds",
"HALL_1/CAVE_1/SVTT_1/SXRL_1-2/*",
"",
""},
49 {
"SXR1",
"Circular water feeds",
"HALL_1/CAVE_1/SVTT_1/SXR1_3-4/*",
"",
""},
50 {
"SXR2",
"Circular water feeds",
"HALL_1/CAVE_1/SVTT_1/SXR2_5-6/*",
"",
""},
51 {
"SCBM",
"Mother of All Cables",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/*",
"",
""},
52 {
"SCBL",
"The bundles of cables connecting PCBs with the transition boards",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCBL_1",
"",
""},
53 {
"SCB1",
"The bundles of cables connecting PCBs with the transition boards",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCB1_2",
"",
""},
54 {
"SCB2",
"The bundles of cables connecting PCBs with the transition boards",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCB2_3",
"",
""},
55 {
"SCB3",
"The bundles of cables connecting PCBs with the transition boards",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCB3_4",
"",
""},
56 {
"SFED",
"bundles of water pipes",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SFED_1",
"",
""},
57 {
"SFE1",
"bundles of water pipes",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SFE1_2",
"",
""},
58 {
"SFE2",
"bundles of water pipes",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SFE2_3",
"",
""},
59 {
"SPLS",
"plastic of the water pipes",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SPLS_1",
"",
""},
60 {
"SPL1",
"plastic of the water pipes",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SPL1_2",
"",
""},
61 {
"SPL2",
"plastic of the water pipes",
"HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SPL2_3",
"",
""},
62 {
"SALM",
"aluminum shield mesh",
"HALL_1/CAVE_1/SVTT_1/SALM_1-2",
"",
""},
63 {
"SOSH",
"SVT outer shield",
"HALL_1/CAVE_1/SVTT_1/SOSH_1",
"",
""},
64 {
"SISH",
"SVT inner shield",
"HALL_1/CAVE_1/SVTT_1/SISH_1",
"",
""},
65 {
"SLYD",
"layer mother",
"HALL_1/CAVE_1/SVTT_1/SLYD_1/*",
"",
""},
66 {
"SLY1",
"layer mother",
"HALL_1/CAVE_1/SVTT_1/SLY1_2/*",
"",
""},
67 {
"SLY2",
"layer mother",
"HALL_1/CAVE_1/SVTT_1/SLY2_3/*",
"",
""},
68 {
"SLY3",
"layer mother",
"HALL_1/CAVE_1/SVTT_1/SLY3_4/*",
"",
""},
69 {
"SLY4",
"layer mother",
"HALL_1/CAVE_1/SVTT_1/SLY4_5/*",
"",
""},
70 {
"SLY5",
"layer mother",
"HALL_1/CAVE_1/SVTT_1/SLY5_6/*",
"",
""},
71 {
"SVTD",
"an active wafer volume",
"HALL_1/CAVE_1/SVTT_1/SLY*/SLS*/SLD*/STL*/STS*/SVTD_1",
"svt",
"SVTD"},
72 {
"SROD",
"Support rod",
"HALL_1/CAVE_1/SVTT_1/SROD_1-2",
"",
""},
73 {
"SBSP",
"Beampipe support mother",
"HALL_1/CAVE_1/SVTT_1/SBSP_1-2",
"",
""},
75 {
"SBWC",
"water manifold to support cone bracket mother",
"HALL_1/CAVE_1/SVTT_1/SBWC_1-2/*",
"",
""},
76 {
"SWMM",
"water manifold mother",
"HALL_1/CAVE_1/SVTT_1/SWMM_1-2/*",
"",
""},
77 {
"SIES",
"Volume to hold inner endring screws",
"HALL_1/CAVE_1/SVTT_1/SIES_1-2/*",
"",
""},
78 {
"SOES",
"Volume to hold outer endring screws",
"HALL_1/CAVE_1/SVTT_1/SOES_1-2/*",
"",
""},
79 {
"SBRG",
"Bracket joining the end rungs",
"HALL_1/CAVE_1/SVTT_1/SBRG_1-2/*",
"",
""},
80 {
"SOER",
"outer end ring",
"HALL_1/CAVE_1/SVTT_1/SOER_1-2/*",
"",
""},
81 {
"SIRT",
"inner end ring tube piece ",
"HALL_1/CAVE_1/SVTT_1/SIRT_1-2",
"",
""},
82 {
"SIRP",
"inner end ring polygon piece ",
"HALL_1/CAVE_1/SVTT_1/SIRP_1-2",
"",
""},
83 {
"STAC",
"twinax cable approximation, copper",
"HALL_1/CAVE_1/SVTT_1/SCON_1/STAC_1-2",
"",
""},
86 {
"SCMP",
"SSD mounting plate inserted in the cone",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SCMP_1-8",
"",
""},
87 {
"SCVM",
"SSD V-shape mouting piece",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SCVM_1-8/*",
"",
""},
88 {
"SSLT",
"the linking (sector to the cone) tube",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SSLT_1-8",
"",
""},
89 {
"SSLB",
"the linking (sector to the cone)",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SSLB_1-8",
"",
""},
90 {
"SSRS",
"the side of the small rib",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SSRS_1-4",
"",
""},
91 {
"SSRT",
"the top of the side rib",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SSRT_1-4",
"",
""},
92 {
"SSSS",
"Side parts of the small sectors",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SSSS_1-4",
"",
""},
93 {
"SSST",
"Top parts of the small sectors",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SSST_1-4",
"",
""},
95 {
"SFSM",
"the structure mother volume",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/SFSM_1/*",
"",
""},
96 {
"SFDM",
"the detectors and adcs mother volume",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/SFDM_1/*",
"",
""},
97 {
"SFSD",
"the strip detector",
"HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/SFDM_1/SFSW_1-16/SFSD_1",
"ssd",
""},
100 {
"TPCW",
"the TPC supporting endcap Wheel",
"HALL_1/CAVE_1/TPCE_1/TPCW_1-2/*",
"",
""},
101 {
"TPEA",
"one endcap placed in TPC",
"HALL_1/CAVE_1/TPCE_1/TPEA_1-2/*",
"",
""},
102 {
"TPCM",
"the Central Membrane placed in TPC",
"HALL_1/CAVE_1/TPCE_1/TPCM_1",
"",
""},
103 {
"TOFC",
"defines outer field cage - fill it with insulating gas already",
"HALL_1/CAVE_1/TPCE_1/TOFC_1/*",
"",
""},
104 {
"TIFC",
"defines the Inner Field Cage placed in TPC",
"HALL_1/CAVE_1/TPCE_1/TIFC_1/*",
"",
""},
105 {
"TPGV",
"the Gas Volume placed in TPC",
"HALL_1/CAVE_1/TPCE_1/TPGV_1-2/*",
"",
""},
106 {
"TPSS",
"a division of gas volume corresponding to a supersectors",
"HALL_1/CAVE_1/TPCE_1/TPGV_1-2/TPSS_1-12/*",
"",
""},
107 {
"TPAD",
"(inner) real padrow with dimensions defined at positioning time",
"HALL_1/CAVE_1/TPCE_1/TPGV_1-2/TPSS_1-12/TPAD_1-39",
"tpc",
""},
108 {
"TPA1",
"(outer) real padrow with dimensions defined at positioning time",
"HALL_1/CAVE_1/TPCE_1/TPGV_1-2/TPSS_1-12/TPA1_40-73",
"tpc",
""}
110 static Int_t NofVolToBEAveraged =
sizeof(VolumesToBeAveraged)/
sizeof(
VolumeMap_t);
112 {
"BBCM",
"Beam Beam Counter Modules Geometry",
"",
"",
""},
113 {
"BTOF",
"the whole CTF system envelope",
"",
"",
""},
114 {
"CALB",
"the geometry of the Barrel EM Calorimeter",
"",
"",
""},
115 {
"ECAL",
"the EM EndCap Calorimeter GEOmetry",
"",
"",
""},
116 {
"FBOX",
"one Pb-Glass fpd detector",
"",
"",
""},
117 {
"FBO1",
"an other Pb-Glass fpd detector",
"",
"",
""},
118 {
"FTMO",
"the mother of the single FTPC RO barrel",
"",
"",
""},
119 {
"IBEM",
"the IBeam structure beneath the Bell reducer cone",
"",
"",
""},
120 {
"MAGP",
"the geometry of the STAR magnet",
"",
"",
""},
121 {
"PHMD",
"the Photon Multiplicity Detector",
"",
"",
""},
122 {
"SUPO",
"the geometry of the Forward TPC supports in STAR",
"",
"",
""},
124 {
"SVTT",
"the SVT geometry for STAR",
"",
"",
""},
126 {
"SFMO",
"the mother of all Silicon Strip Detector volumes (inside of SVTT)",
"",
"",
""},
128 {
"FTPC",
"the geometry of the Forward TPC in STAR (inside of SVTT)",
"",
"",
""},
130 {
"UPST",
"the geometry of the UPSTREAM AreA.",
"",
"",
""},
131 {
"VPDD",
"the Pseudo Vertex Position Detector of STAR",
"",
"",
""},
132 {
"ZCAL",
"the geometry of the Zero deg. Quartz Calorimeter",
"",
"",
""}
134 static Int_t nTopVol =
sizeof(TopVolumes)/
sizeof(
VolumeMap_t);
143 {
"N_2", 14.00674, 7, 2*78.084, 0},
144 {
"O_2", 15.9994 , 8, 2*(20.946 + 0.033), 0},
145 {
"C", 12.011, 6, 0.033, 0},
146 {
"Ar", 39.948, 18, 0.934, 0}
148 static Int_t NAir = 0;
150 {
"Ar", 40,18,0.95744680,0},
151 {
"C" , 12, 6,0.03191489,0},
152 {
"H" , 1, 1,0.01063830,0}
154 static Int_t NP10 = 3;
163 void StiVMCToolKit::SetDebug(Int_t m) {m_Debug = m;}
165 Int_t StiVMCToolKit::Debug() {
return m_Debug;}
167 void StiVMCToolKit::PrintShape(TGeoShape *shape) {
168 TGeoBBox *box = 0, *Box = 0;
172 TGeoTubeSeg *tubs = 0;
176 TGeoConeSeg *cons = 0;
182 Double_t paramsBC[4];
185 shape->GetBoundingCylinder(paramsBC);
186 shape->ComputeBBox();
187 Box = (TGeoBBox *) shape;
188 for (Int_t bit = 24; bit >= 9; bit--) {
189 if (shape->TestShapeBit(BIT(bit))) {
191 case TGeoShape::kGeoBox:
192 box = (TGeoBBox *) shape;
193 cout <<
"Box \tdX\t" << box->GetDX() <<
"\tdY\t" << box->GetDY() <<
"\tdZ\t" << box->GetDZ()
196 case TGeoShape::kGeoTrd1:
197 trd1 = (TGeoTrd1 *) shape;
198 cout <<
"Trd1\tdX1\t" << trd1->GetDx1() <<
"\tdX2\t" << trd1->GetDx2()
199 <<
"\tdY\t" << trd1->GetDy() <<
"\tdZ\t" << trd1->GetDz()
202 case TGeoShape::kGeoTrd2:
203 trd2 = (TGeoTrd2 *) shape;
204 cout <<
"Trd2\tdX1\t" << trd2->GetDx1() <<
"\tdX2\t" << trd2->GetDx2()
205 <<
"\tdY1\t" << trd2->GetDy1() <<
"\tdY2\t" << trd2->GetDy2()
206 <<
"\tdZ\t" << trd2->GetDz() << endl;
208 case TGeoShape::kGeoTubeSeg:
209 tubs = (TGeoTubeSeg *) shape;
210 cout <<
"Tubs\tRmin\t" << tubs->GetRmin() <<
"\tRmax\t" << tubs->GetRmax() <<
"\tdZ\t" << tubs->GetDz()
211 <<
"\tPhi1\t" << tubs->GetPhi1() <<
"\tPhi2\t" << tubs->GetPhi2()
214 case TGeoShape::kGeoTube:
215 tube = (TGeoTube *) shape;
216 cout <<
"Tube\tRmin\t" << tube->GetRmin() <<
"\tRmax\t" << tube->GetRmax() <<
"\tdZ\t" << tube->GetDz()
219 case TGeoShape::kGeoPcon:
220 pcon = (TGeoPcon *) shape;
223 <<
"\tPhi1\t" << pcon->GetPhi1() <<
"\tDphi\t" << pcon->GetDphi() <<
"\tNz\t" << Nz << endl;
224 for (i = 0; i < Nz; i++) {
225 cout << i <<
"\tZ\t" << pcon->GetZ(i) <<
"\tRmin\t" << pcon->GetRmin(i) <<
"\tRmax\t" << pcon->GetRmax(i) << endl;
229 case TGeoShape::kGeoPgon:
230 pgon = (TGeoPgon *) shape;
233 cout <<
"Pgon\tNedges\t" << pgon->GetNedges()
234 <<
"\tPhi1\t" << pgon->GetPhi1() <<
"\tDphi\t" << pgon->GetDphi() <<
"\tNz\t" <<Nz << endl;
235 for (i = 0; i <Nz; i++) {
236 cout << i <<
"\tZ\t" << pgon->GetZ(i) <<
"\tRmin\t" << pgon->GetRmin(i) <<
"\tRmax\t" << pgon->GetRmax(i) << endl;
240 case TGeoShape::kGeoCone:
241 cone = (TGeoCone *) shape;
242 cout <<
"Cone\tdZ\t" << cone->GetDz()
243 <<
"\tRmin1\t" << cone->GetRmin1() <<
"\tRmax1\t" << cone->GetRmax1()
244 <<
"\tRmin2\t" << cone->GetRmin2() <<
"\tRmax2\t" << cone->GetRmax2()
247 case TGeoShape::kGeoConeSeg:
248 cons = (TGeoConeSeg *) shape;
249 cout <<
"Cons\tdZ\t" << cons->GetDz()
250 <<
"\tPhi1\t" << cons->GetPhi1() <<
"\tPhi2\t" << cons->GetPhi2()
251 <<
"\tRmin1\t" << cons->GetRmin1() <<
"\tRmax1\t" << cons->GetRmax1()
252 <<
"\tRmin2\t" << cons->GetRmin2() <<
"\tRmax2\t" << cons->GetRmax2()
255 case TGeoShape::kGeoArb8:
256 case TGeoShape::kGeoTrap:
257 arb8 = (TGeoArb8 *) shape;
258 XY = arb8->GetVertices();
260 for (j = 0; j < 2; j++) {
261 cout <<
"Trap/Arb8\tdZ\t";
262 if (j == 0) cout << -dZ;
264 for (i = 4*j; i < 4*j+4; i++)
265 cout <<
"\t(" << XY[2*i] <<
"," << XY[2*i+1] <<
")";
269 case TGeoShape::kGeoEltu:
270 eltu = (TGeoEltu *) shape;
271 cout <<
"Eltu\tdZ\t" << eltu->GetDz()
272 <<
"\tA\t" << eltu->GetA() <<
"\tB\t" << eltu->GetB()
275 case TGeoShape::kGeoTorus:
276 case TGeoShape::kGeoPara:
277 case TGeoShape::kGeoSph:
278 case TGeoShape::kGeoCtub:
280 cout << bit <<
"\t has not yet implemented for " << shape->GetName() << endl;
288 Double_t StiVMCToolKit::GetShapeVolume(TGeoShape *shape) {
289 TGeoBBox *box = 0, *Box = 0;
293 TGeoTubeSeg *tubs = 0;
297 TGeoConeSeg *cons = 0;
300 Double_t paramsBC[4];
305 shape->GetBoundingCylinder(paramsBC);
306 shape->ComputeBBox();
307 Box = (TGeoBBox *) shape;
308 volBB = 8*Box->GetDX()*Box->GetDY()*Box->GetDZ();
309 volBC = 2*TMath::Pi()*(paramsBC[1] - paramsBC[0])*Box->GetDZ();;
310 for (Int_t bit = 24; bit >= 9; bit--) {
311 if (shape->TestShapeBit(BIT(bit))) {
312 Int_t kbit = BIT(bit);
314 case TGeoShape::kGeoBox:
315 box = (TGeoBBox *) shape;
316 volume = 8*box->GetDX()*box->GetDY()*box->GetDZ();
318 case TGeoShape::kGeoTrd1:
319 trd1 = (TGeoTrd1 *) shape;
320 volume = 4*(trd1->GetDx1()+trd1->GetDx2())*trd1->GetDy()*trd1->GetDz();
322 case TGeoShape::kGeoTrd2:
323 trd2 = (TGeoTrd2 *) shape;
324 volume = 2*(trd2->GetDx1() + trd2->GetDx2())*(trd2->GetDy1() + trd2->GetDy2())*trd2->GetDz();
326 case TGeoShape::kGeoTubeSeg:
327 case TGeoShape::kGeoTube:
328 tube = (TGeoTube *) shape;
329 volume = 2*TMath::Pi()*(tube->GetRmax()* tube->GetRmax() - tube->GetRmin()*tube->GetRmin())*
331 if (kbit == TGeoShape::kGeoTubeSeg) {
332 tubs = (TGeoTubeSeg *) shape;
333 volume *= TMath::Abs(tubs->GetPhi2()-tubs->GetPhi1())/360.;
336 case TGeoShape::kGeoPcon:
337 case TGeoShape::kGeoPgon:
338 pcon = (TGeoPcon *) shape;
341 for (i = 1; i < Nz; i++) {
343 ((pcon->GetRmax(i)*pcon->GetRmax(i) + pcon->GetRmax(i-1)*pcon->GetRmax(i-1) + pcon->GetRmax(i)*pcon->GetRmax(i-1)) -
344 (pcon->GetRmin(i)*pcon->GetRmin(i) + pcon->GetRmin(i-1)*pcon->GetRmin(i-1) + pcon->GetRmin(i)*pcon->GetRmin(i-1)))*
345 TMath::Abs((pcon->GetZ(i) - pcon->GetZ(i-1)));
347 if (kbit == TGeoShape::kGeoPgon) {
348 pgon = (TGeoPgon *) shape;
349 volume *= TMath::Tan(TMath::Pi()/180.*TMath::Abs(pgon->GetDphi()/pgon->GetNedges()/2.))/3.*pgon->GetNedges();
352 volume *= TMath::Pi()/3.*TMath::Abs(pcon->GetDphi())/360.;
355 case TGeoShape::kGeoCone:
356 case TGeoShape::kGeoConeSeg:
357 cone = (TGeoCone *) shape;
358 volume = TMath::Pi()*2./3.*
359 ((cone->GetRmax2()*cone->GetRmax2() + cone->GetRmax1()*cone->GetRmax1() + cone->GetRmax2()*cone->GetRmax1()) -
360 (cone->GetRmin2()*cone->GetRmin2() + cone->GetRmin1()*cone->GetRmin1() + cone->GetRmin2()*cone->GetRmin1()))*
362 if (kbit == TGeoShape::kGeoConeSeg) {
363 cons = (TGeoConeSeg *) shape;
364 volume *= TMath::Abs(cons->GetPhi2() - cons->GetPhi1())/360.;
367 case TGeoShape::kGeoEltu:
368 eltu = (TGeoEltu *) shape;
369 volume = 2*TMath::Pi()*eltu->GetA()*eltu->GetB()*eltu->GetDz();
371 case TGeoShape::kGeoArb8:
372 case TGeoShape::kGeoTrap:
373 case TGeoShape::kGeoTorus:
374 case TGeoShape::kGeoPara:
375 case TGeoShape::kGeoSph:
376 case TGeoShape::kGeoCtub:
379 cout << bit <<
"\t has not yet implemented for " << shape->GetName() << endl;
380 volume = TMath::Min(volBB,volBC);
387 cout <<
" =============> Volume = " << volume
388 <<
"\t" << shape->GetName() <<
"\tBB\t" << volBB <<
"\tBC\t" << volBC << endl;
390 if (Debug() && ! (volBB - volume > -1e-7 && volBC - volume > -1.e-7) ) {
392 cout <<
"volume\t" << volume <<
"\tvolBB\t" << volBB <<
"\tvolBC\t" << volBC << endl;
393 cout <<
"\tBoundingBox dX\t" << Box->GetDX() <<
"\tdY\t" << Box->GetDY() <<
"\tdZ\t" << Box->GetDZ() << endl;
394 cout <<
"\tBoundingCylinder\trMin\t" << TMath::Sqrt(paramsBC[0]) <<
"\trMax\t" << TMath::Sqrt(paramsBC[1])
395 <<
"\tdZ\t" << Box->GetDZ() << endl;
397 assert(volBB - volume > -1e-7 && volBC - volume > -1.e-7);
402 Int_t StiVMCToolKit::Add2ElementList(Int_t NElem,
const TGeoMaterial *mat,
Elem_t *ElementList) {
403 assert(NElem>=0 && NElem<NoElemMax);
405 NAir =
sizeof(Air)/
sizeof(
ElemV_t);
407 for (Int_t i = 0; i < NAir; i++) W += Air[i].A*Air[i].V;
408 for (Int_t i = 0; i < NAir; i++) Air[i].W = Air[i].A*Air[i].V/W;
410 if (mat->InheritsFrom(
"TGeoMixture")) {
411 TGeoMixture *mix = (TGeoMixture *) mat;
412 Int_t N = mix->GetNelements();
413 Double_t *A = mix->GetAmixt();
414 Double_t *Z = mix->GetZmixt();
415 Double_t *W = mix->GetWmixt();
416 for (Int_t i = 0; i < N; i++) {
417 if (TMath::Abs(Z[i] - 7.30) < 1.e-3 &&
418 TMath::Abs(A[i] - 14.61) < 1.e-3) {
419 for (Int_t j = 0; j < NAir; j++) {
420 ElementList[NElem].index = NElem+1;
421 ElementList[NElem].W = W[i]*Air[j].W;
422 ElementList[NElem].A = Air[j].A;
423 ElementList[NElem].Z = Air[j].Z;
427 if (TMath::Abs(Z[i] - 17.436 ) < 1.e-3 &&
428 TMath::Abs(A[i] - 38.691) < 1.e-3) {
429 for (Int_t j = 0; j < NP10; j++) {
430 ElementList[NElem].index = NElem+1;
431 ElementList[NElem].W = W[i]*P10[j].W;
432 ElementList[NElem].A = P10[j].A;
433 ElementList[NElem].Z = P10[j].Z;
437 ElementList[NElem].index = NElem+1;
438 ElementList[NElem].W = W[i];
439 ElementList[NElem].A = A[i];
440 ElementList[NElem].Z = Z[i];
446 Double_t A = mat->GetA();
447 Double_t Z = mat->GetZ();
448 if (TMath::Abs(Z - 7.30) < 1.e-3 &&
449 TMath::Abs(A - 14.61) < 1.e-3) {
450 for (Int_t j = 0; j < NAir; j++) {
451 ElementList[NElem].index = NElem+1;
452 ElementList[NElem].W = Air[j].W;
453 ElementList[NElem].A = Air[j].A;
454 ElementList[NElem].Z = Air[j].Z;
458 if (TMath::Abs(Z - 17.436 ) < 1.e-3 &&
459 TMath::Abs(A - 38.691) < 1.e-3) {
460 for (Int_t j = 0; j < NP10; j++) {
461 ElementList[NElem].index = NElem+1;
462 ElementList[NElem].W = P10[j].W;
463 ElementList[NElem].A = P10[j].A;
464 ElementList[NElem].Z = P10[j].Z;
468 ElementList[NElem].index = NElem+1;
469 ElementList[NElem].W = 1.;
470 ElementList[NElem].A = A;
471 ElementList[NElem].Z = Z;
476 assert(NElem < NoElemMax);
480 Int_t StiVMCToolKit::Merge2ElementList(Int_t NElem,
Elem_t *ElementList,
481 Int_t NElemD,
Elem_t *ElementListD, Double_t weight) {
482 assert(NElem>=0 && NElem<NoElemMax);
483 for (Int_t i = 0; i < NElemD; i++) {
484 ElementList[NElem].index = NElem+1;
485 ElementList[NElem].W = weight*ElementListD[i].W;
486 ElementList[NElem].A = ElementListD[i].A;
487 ElementList[NElem].Z = ElementListD[i].Z;
489 assert(NElem < NoElemMax);
494 Int_t StiVMCToolKit::NormolizeElementList(Int_t NElem,
Elem_t *ElementList){
495 assert(NElem>=0 && NElem<NoElemMax);
497 for (Int_t i = 0; i < NElem; i++) W += ElementList[i].W ;
498 for (Int_t i = 0; i < NElem; i++) ElementList[i].W /= W;
499 for (Int_t k = 0; k < NElem; k++) {
500 if (ElementList[k].W > 0) {
501 for (Int_t l = k+1; l < NElem; l++) {
502 if (ElementList[l].W > 0 &&
503 ElementList[k].A == ElementList[l].A &&
504 ElementList[k].Z == ElementList[l].Z) {
505 ElementList[k].W += ElementList[l].W;
506 ElementList[l].W = -1;
513 for (Int_t k = 0; k < NElem; k++) {
514 if (ElementList[k].W <= 0)
continue;
516 ElementList[N] = ElementList[k];
522 Double_t StiVMCToolKit::GetWeight(TGeoNode *nodeT,
const TString &pathT,
523 Int_t *NElem,
Elem_t *ElementList) {
525 Double_t WeightT = 0;
527 if (! gGeoManager)
return Weight;
528 gGeoManager->RestoreMasterVolume();
529 gGeoManager->CdTop();
530 gGeoManager->cd(pathT.Data());
531 nodeT = gGeoManager->GetCurrentNode();
532 if (! nodeT)
return Weight;
534 TGeoVolume *volT = nodeT->GetVolume();
535 const TGeoMaterial *mat = volT->GetMaterial();
537 Double_t dens = mat->GetDensity();
538 TGeoShape *shapeT = (TGeoShape *) volT->GetShape();
539 if (! shapeT)
return Weight;
540 Double_t volume = GetShapeVolume(shapeT);
541 WeightT = Weight = dens*volume;
543 if (! ElementList ) {
544 ElementList =
new Elem_t[NoElemMax];
545 NElem =
new Int_t[1]; NElem[0] = 0;
548 assert(ElementList && NElem);
550 Int_t im1 = NElem[0];
551 NElem[0] = __addelement__(NElem[0], mat, ElementList);
552 Int_t im2 = NElem[0];
555 TObjArray *nodes = volT->GetNodes();
556 Int_t nd = nodeT->GetNdaughters();
559 vector<Double_t> weights(nd);
560 for (Int_t
id = 0;
id < nd;
id++) {
561 TGeoNode *node = (TGeoNode*)nodes->UncheckedAt(
id);
562 if (! node)
continue;
564 TGeoVolume *vol = node->GetVolume();
566 TString name(TString(vol->GetName()));
568 TGeoShape *shapeD = (TGeoShape *) vol->GetShape();
569 if (! shapeD )
continue;
570 Double_t weight = dens*GetShapeVolume(shapeD);
573 TString path = pathT;
574 if (path !=
"") path +=
"/";
575 path += node->GetName();
576 Int_t NElemD[1] = {0};
577 Elem_t ElementListD[NoElemMax];
578 weights[id] = GetWeight(node,path,NElemD,ElementListD);
579 Weight += weights[id];
580 NElem[0] = Merge2ElementList(NElem[0], ElementList, NElemD[0], ElementListD, weights[
id]);
583 for (Int_t i = im1; i < im2; i++) {
584 ElementList[i].W *= WeightT;
586 NElem[0] = NormolizeElementList(NElem[0],ElementList);
591 Double_t StiVMCToolKit::GetVolumeWeight(TGeoVolume *volT, Int_t *NElem,
Elem_t *ElementList)
593 if (! volT || !volT->GetShape())
return 0;
596 Double_t WeightT = 0;
597 const TGeoMaterial *mat = volT->GetMaterial();
598 TGeoShape *shapeT = (TGeoShape *) volT->GetShape();
599 if (! shapeT)
return 0;
601 Double_t dens = mat->GetDensity();
603 cout <<
"volT \t" << volT->GetName() <<
"\t" << volT->GetTitle() << endl;
604 Double_t volume = GetShapeVolume(shapeT);
605 Weight = dens*volume;
608 if (! ElementList ) {
610 ElementList =
new Elem_t[NoElemMax];
611 NElem =
new Int_t[1]; NElem[0] = 0;
614 assert(ElementList &&
"StiVMCToolKit::GetWeight: Create the the array first!");
617 Int_t im2 = __addelement__(im1, mat, ElementList);
621 TObjArray *nodes = volT->GetNodes();
622 Int_t nd = volT->GetNdaughters();
625 vector<Double_t> weights(nd);
626 for (Int_t
id = 0;
id < nd;
id++) {
627 TGeoNode *node = (TGeoNode*) nodes->UncheckedAt(
id);
628 if (! node)
continue;
630 TGeoVolume *vol = node->GetVolume();
632 TString name(TString(vol->GetName()));
634 TGeoShape *shapeD = (TGeoShape *) vol->GetShape();
635 if (! shapeD )
continue;
636 Double_t weight = dens*GetShapeVolume(shapeD);
639 Int_t NElemD[1] = {0};
640 Elem_t ElementListD[NoElemMax];
641 weights[id] = GetVolumeWeight(vol,NElemD,ElementListD);
642 Weight += weights[id];
644 Int_t imm = Merge2ElementList(im, ElementList, NElemD[0], ElementListD, weights[
id]);
648 for (Int_t i = im1; i < im2; i++) {
649 ElementList[i].W *= WeightT;
652 Int_t inn= NormolizeElementList(in,ElementList);
657 void StiVMCToolKit::MakeAverageVolume(TGeoVolume *volT, TGeoShape *&newshape, TGeoMedium *&newmed, Double_t *xyzM) {
659 vector<Elem_t> ElementList(NoElemMax);
663 Elem_t *el = &ElementList[0];
664 TGeoVolume *v = volT;
671 const TGeoMedium *med = volT->GetMedium();
672 const TGeoMaterial *mat = volT->GetMaterial();
674 if (med->GetParam(0)) cout <<
"===================" << endl;
675 else cout <<
"+++++++++++++++++++" << endl;
676 cout << volT->GetName() <<
" === "
677 <<
" Weight " << Weight <<
"[g]\t";
678 cout <<
"material\t" << mat->GetName() <<
"\tmedium\t" << med->GetName() << endl;
680 TGeoShape *shapeT = (TGeoShape *) volT->GetShape();
681 Double_t volume = GetShapeVolume(shapeT);
682 if (Debug()) PrintShape(shapeT);
683 shapeT->ComputeBBox();
684 TGeoBBox * Box = (TGeoBBox *) shapeT;
685 Double_t dx=-2001, dy=-2002, dz=-2003, rmin=-2009, rmax=-2010;
686 Double_t paramsBC[4];
687 shapeT->GetBoundingCylinder(paramsBC);
688 Double_t volBB = 8*Box->GetDX()*Box->GetDY()*Box->GetDZ();
689 Double_t volBC = 2*TMath::Pi()*(paramsBC[1] - paramsBC[0])*Box->GetDZ();
691 if (Debug()) cout << shapeT->GetName();
692 enum ShapeId {kBox = 1, kTube, kKeep};
694 TString name(volT->GetName());
695 if (name ==
"SROD") {
697 Double_t S = TMath::Pi()*(paramsBC[1] - paramsBC[0]);
698 dy = TMath::Sqrt(paramsBC[1]) - TMath::Sqrt(paramsBC[0]);
701 Box->SetBoxDimensions(dx,dy,dz);
702 volB = volBB = volBC;
704 if ((shapeT->TestShapeBit(TGeoShape::kGeoTube) ||
705 shapeT->TestShapeBit(TGeoShape::kGeoTubeSeg)) &&
706 xyzM && xyzM[0]*xyzM[0] + xyzM[1]*xyzM[1] < 1.e-3) {
709 if (Debug()) cout <<
"\tKeep shape ===========\t";
712 if ( (volBB <= volBC) || (xyzM && xyzM[0]*xyzM[0] + xyzM[1]*xyzM[1] > 1.e-3) ) {
718 if (Debug()) cout <<
"\tBoundingBox dX\t" << dx <<
"\tdY\t" << dy <<
"\tdZ\t" << dz;
722 rmin = TMath::Sqrt(paramsBC[0]);
723 rmax = TMath::Sqrt(paramsBC[1]);
725 if (Debug()) cout <<
"\tBoundingCylinder\trMin\t" << rmin <<
"\trMax\t" << rmax <<
"\tdZ\t" << dz;
729 Double_t Dens = Weight/volB;
730 if (Debug()) cout <<
"\tvolume\t" << volume <<
"\tvolB\t" << volB <<
"\tDens\t" << Dens << endl;
731 TString newmatname(mat->GetName());
734 TGeoMixture *newmat =
new TGeoMixture(newmatname.Data(),NElem, Dens);
735 for (Int_t i = 0; i < NElem; i++) {
737 cout << Form(
"id%3i\tW%10.3g\tA%5.1f\t%5.1f\n",
738 ElementList[i].index,ElementList[i].W,ElementList[i].A,ElementList[i].Z);
741 newmat->DefineElement(i,ElementList[i].A,ElementList[i].Z,ElementList[i].W);
743 newmat->SetUniqueID(gGeoManager->AddMaterial(newmat));
744 Int_t matid = newmat->GetUniqueID();
747 for (Int_t i = 0; i < 10; i++) params[i] = med->GetParam(i);
748 newmed =
new TGeoMedium(newmatname.Data(),matid,newmat,params);
749 if (Debug() && xyzM) {
750 cout <<
"\txyzM x\t" << xyzM[0] <<
"\ty\t" << xyzM[1] <<
"\tz\t" << xyzM[2] << endl;
753 if (iShape == 1) newshape =
new TGeoBBox(dx, dy, dz);
754 else if (iShape == 2) {
755 newshape =
new TGeoTube(rmin, rmax, dz);
759 TGeoManager * StiVMCToolKit::GetVMC() {
760 TGeoManager *gGeo = 0;
765 if (gGeo)
return gGeo;
766 LOG_INFO <<
"StiVMCToolKit::GetVMC() : Get VMC geometry" <<endm;
767 if (StMaker::GetChain()) {
768 StMaker::GetChain()->GetDataBase(
"VmcGeometry");
771 LOG_ERROR <<
"StiVMCToolKit::GetVMC() : Can't get VMC geometry" <<endm;
777 void StiVMCToolKit::TestVMC4Reconstruction(){
782 Int_t NV[2] = {nTopVol,NofVolToBEAveraged};
784 TGeoVolume *volT = 0;
785 cout <<
"<table>" << endl;
786 cout <<
"<tr><td>name</td><td>Comment </td><td>Volume[cm**3]</td><td>Weight[g]</td><td>Av.Dens.[g/cm**3]</td></tr>" << endl;
787 for (Int_t i = 0; i < 2; i++) {
788 if (i == 0) list = TopVolumes;
789 else list = VolumesToBeAveraged;
790 for (Int_t j = 0; j < NV[i]; j++) {
791 volT = gGeoManager->GetVolume(list[j].name);
793 if (! volT) {cout <<
"Can't find " << list[j].name <<
"\t" << list[j].comment << endl;
continue;}
794 TGeoShape *shapeT = volT->GetShape();
795 Double_t volume = GetShapeVolume(shapeT);
796 Double_t weight = GetVolumeWeight(volT, 0, 0);
797 cout <<
"<tr><td>"<< list[j].name <<
"</td><td>" << list[j].comment <<
"</td>"
798 <<
"<td>" << Form(
"%10.3g",volume) <<
"</td>"
799 <<
"<td>" << Form(
"%10.3g",weight) <<
"</td>"
800 <<
"<td>" << Form(
"%10.3g",weight/volume) <<
"</td></tr>"
804 cout <<
"</table>" << endl;
807 TGeoPhysicalNode *StiVMCToolKit::Alignment(
const TGeoNode *nodeT,
const Char_t *pathT,
808 TGeoVolume *volT, TGeoShape *newshape, TGeoMedium* newmed) {
810 TObjArray *listP = gGeoManager->GetListOfPhysicalNodes();
811 TGeoPhysicalNode *nodeP = 0;
812 TGeoCombiTrans *trP = 0;
814 Int_t N = listP->GetEntries();
815 for (Int_t i = 0; i < N; i++) {
816 TGeoPhysicalNode *nod =
dynamic_cast<TGeoPhysicalNode *
> (listP->At(i));
817 if (nod && TString(nod->GetName()) == TString(pathT)) {
822 Double_t local[3] = {0,0,0};
823 TGeoShape *shapeT = volT->GetShape();
825 LOG_INFO <<
"StiVMCToolKit::Alignment : node\t" << nodeT->GetName()
826 <<
"\tvolume\t" << volT->GetName() <<
"\t:" << volT->GetTitle()
827 <<
"\tshape\t" << shapeT->GetName() <<
"\tmaterial\t" << volT->GetMaterial()->GetName();
828 if (newshape) LOG_INFO <<
"\tnewshape\t" << newshape->GetName();
831 if (shapeT->TestShapeBit(TGeoShape::kGeoPcon) || shapeT->TestShapeBit(TGeoShape::kGeoPgon)) {
832 TGeoPcon *pcon = (TGeoPcon *) shapeT;
833 Int_t Nz = pcon->GetNz();
834 local[2] = 0.5*(pcon->GetZ(0) + pcon->GetZ(Nz-1));
837 nodeT->LocalToMaster(local,master);
839 cout <<
"\tmaster x\t" << master[0] <<
"\ty\t" << master[1] <<
"\tz\t" << master[2] << endl;
840 if (!nodeP) nodeP = gGeoManager->MakePhysicalNode(pathT);
841 if (!nodeP)
return nodeP;
843 if (nodeP->IsAligned()) {
844 trP = nodeP->GetNode()->GetMatrix();
845 trP->SetTranslation(master[0], master[1], master[2]);
847 trP =
new TGeoCombiTrans(master[0], master[1], master[2], nodeP->GetNode()->GetMatrix());
850 nodeP->Align(trP,newshape);
851 TGeoVolume *newvol = nodeP->GetNode(-1)->GetVolume();
853 cout <<
"newvol\t" << newvol->GetName() <<
"\tmed\t" << newvol->GetMedium()->GetName() << endl;
854 newvol->SetMedium(newmed);
855 newvol->SetTitle(
"AVERAGED");
856 newvol->SetLineColor(1);
857 newvol->SetVisibility(1);
858 TObjArray *nodes = newvol->GetNodes();
859 if (nodes && ! newvol->TObject::TestBit(TGeoVolume::kVolumeImportNodes)) {
862 newvol->ClearNodes();
867 TGeoPhysicalNode *StiVMCToolKit::LoopOverNodes(
const TGeoNode *nodeT,
const Char_t *pathT,
868 const Char_t *name,
void ( *callback)(TGeoPhysicalNode *)){
869 TGeoVolume *volT = nodeT->GetVolume();
870 const Char_t *nameT = volT->GetName();
871 TGeoPhysicalNode *nodeP = 0;
872 TGeoShape *newshape = 0;
873 TGeoMedium* newmed = 0;
874 if (nameT && name && ! strncmp(nameT,name,4)) {
876 Double_t local[3] = {0, 0, 0};
877 TGeoShape *shapeT = volT->GetShape();
878 if (shapeT->TestShapeBit(TGeoShape::kGeoPcon) || shapeT->TestShapeBit(TGeoShape::kGeoPgon)) {
879 TGeoPcon *pcon = (TGeoPcon *) shapeT;
880 Int_t Nz = pcon->GetNz();
881 local[2] = 0.5*(pcon->GetZ(0) + pcon->GetZ(Nz-1));
884 nodeT->LocalToMaster(local,master);
885 MakeAverageVolume(volT, newshape, newmed, master);
886 nodeP = Alignment(nodeT,pathT, volT, newshape, newmed);
888 if (! callback) MakeVolume(nodeP);
889 else callback(nodeP);
893 TObjArray *nodes = volT->GetNodes();
894 Int_t nd = volT->GetNdaughters();
895 for (Int_t
id = 0;
id < nd;
id++) {
896 TGeoNode *node = (TGeoNode*) nodes->UncheckedAt(
id);
897 if (! node)
continue;
898 TString path = pathT;
899 if (path !=
"") path +=
"/";
900 path += node->GetName();
901 if (! name && Debug()) {
903 TGeoVolume *vol = node->GetVolume();
904 const TGeoMedium *med = vol->GetMedium();
905 if (med->GetParam(0)) {cout <<
"\t===================" << endl;
continue;}
908 LoopOverNodes(node, path, name, callback);
913 void StiVMCToolKit::MakeVolume(TGeoPhysicalNode *nodeP) {
915 LOG_INFO <<
"StiVMCToolKit::MakeVolume : TGeoPhysicalNode\t" << nodeP->GetName() << endm;
916 TGeoVolume *volP = nodeP->GetVolume();
917 TGeoMaterial *matP = volP->GetMaterial(); matP->Print(
"");
918 TGeoShape *shapeP = nodeP->GetShape(); cout <<
"New Shape\t"; PrintShape(shapeP);
919 TGeoHMatrix *hmat = nodeP->GetMatrix(); hmat->Print(
"");
923 Double_t StiVMCToolKit::GetPotI(
const TGeoMaterial *mat) {
926 Double_t s1 = 0, s2 = 0;
927 if (mat->InheritsFrom(
"TGeoMixture")) {
928 TGeoMixture *mix = (TGeoMixture *) mat;
929 Int_t N = mix->GetNelements();
931 Double_t *A = mix->GetAmixt();
932 Double_t *Z = mix->GetZmixt();
933 Double_t *W = mix->GetWmixt();
934 for (Int_t i = 0; i < N; i++) {
935 s1 += W[i]*Z[i]/A[i];
936 s2 += W[i]*Z[i]*TMath::Log(Z[i])/A[i];
938 PotI=16.e-9*TMath::Exp(0.9*s2/s1);
940 Double_t Z = mat->GetZ();
941 PotI=16.e-9*TMath::Power(Z,0.9);
947 void StiVMCToolKit::GetVMC4Reconstruction(
const Char_t *pathT,
const Char_t *nameT){
954 gGeoManager->RestoreMasterVolume();
955 gGeoManager->CdTop();
957 if (pathT) {gGeoManager->cd(pathT); path = pathT;}
958 else {path = gGeoManager->GetCurrentNode()->GetName();}
959 TGeoNode *nodeT = gGeoManager->GetCurrentNode();
962 LoopOverNodes(nodeT, path, nameT);
964 for (Int_t i = 0; i < NofVolToBEAveraged; i++) {
965 LoopOverNodes(nodeT, path, VolumesToBeAveraged[i].name);
975 TString path(
"HALL_1/CAVE_1/SVTT_1");
976 Double_t weight = 1.e-3*StiVMCToolKit::GetWeight(0,path, 0, 0);
977 cout <<
"StiVMCToolKit::TestVMCTK() -I- total weight for "
978 << path.Data() <<
"\t" << weight <<
"[kg]" << endl;
979 StiVMCToolKit::TestVMC4Reconstruction();
983 Double_t StiVMCToolKit::Nice(Double_t phi) {
984 while (phi < 2*TMath::Pi()) phi += 2*TMath::Pi();
985 while (phi >= 2*TMath::Pi()) phi -= 2*TMath::Pi();