StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
St_geant_Maker.cxx
1 // $Id: St_geant_Maker.cxx,v 1.182 2021/05/10 20:23:53 jwebb Exp $
2 // $Log: St_geant_Maker.cxx,v $
3 // Revision 1.182 2021/05/10 20:23:53 jwebb
4 // Add text file input option.
5 //
6 // Revision 1.181 2020/03/05 16:28:31 jwebb
7 //
8 // Fix two errors in FCS preshower hits.
9 //
10 // Revision 1.180 2020/02/26 21:26:20 jwebb
11 //
12 // Accumulate and report total energy deposited in all active elements
13 // of the detector modules for the job.
14 //
15 // Revision 1.179 2020/02/25 23:25:41 jwebb
16 // Include FCS preshower hits
17 //
18 // Revision 1.178 2020/02/04 17:46:23 jwebb
19 //
20 // Update to forward silicon geometry and associated changes to support.
21 //
22 // Revision 1.177 2020/01/15 02:18:54 perev
23 // PhysicsOff added but commented out
24 //
25 // Revision 1.176 2019/09/30 14:13:27 jwebb
26 //
27 // Integrate HITS for forward tracking and forward calorimeter.
28 //
29 // n.b. deprecates the legacy HcalGeo RnD detector.
30 //
31 // Revision 1.175 2018/12/03 00:56:32 perev
32 // Use uint64_t + cleanup
33 //
34 // Revision 1.174 2018/11/21 23:05:27 perev
35 // 64bits
36 //
37 // Revision 1.173 2018/10/30 13:54:03 jwebb
38 //
39 // Implemented a templated method for creating and filling the g2t hit tables.
40 //
41 // This reduces the boilerplate code required when integrating a new detector
42 // subsystem, and streamlines maintanence.
43 //
44 // We also add a summary printout of the number of hits found in each subsystem,
45 // allowing nightly tests to keep track of changes in the geometry introduced
46 // at the hit level.
47 //
48 // Code was tested for the first cut and last production geometry in each run
49 // from 2005 to 2018. For 1k pythia event -4.5 < eta < 4.5, geant.root file
50 // size is nearly identical (~few to 50 bits/event) comparing old and new version
51 // of St_geant_Maker. When file compression is switched off, file size is identical.
52 //
53 // Revision 1.172 2018/10/16 01:07:12 perev
54 // Two years old mistype fix
55 //
56 // Revision 1.171 2018/03/22 19:46:19 jwebb
57 // Get the hit count right for FTS
58 //
59 // Revision 1.170 2018/03/20 20:46:26 jwebb
60 //
61 // Re-enable the FTSA (fts "active") volume. (Temporarily lost when I during
62 // integration of the FtsdGeo1 model).
63 //
64 // Revision 1.169 2018/03/19 17:50:42 jwebb
65 // Setup support for 3 planes of Si tracking
66 //
67 // Revision 1.168 2017/12/28 19:10:33 jwebb
68 //
69 // Update sensitive volume names in St_geant_Maker and g2t_epd.F for interface
70 // to C++.
71 //
72 // Revision 1.167 2017/12/28 18:11:34 jwebb
73 //
74 // Add FMS postshower hits interface to C++...
75 //
76 // Revision 1.166 2017/11/13 19:11:05 jwebb
77 // Remove unecessary log output
78 //
79 // Revision 1.165 2017/10/02 15:29:38 jwebb
80 // Integration of ETOF into simulation
81 //
82 // Revision 1.164 2017/04/26 20:26:56 perev
83 // Hide m_DataSet
84 //
85 // Revision 1.163 2016/11/03 13:49:01 jwebb
86 // Integrate EPD into framework.
87 //
88 // Revision 1.162 2016/06/21 16:12:24 jwebb
89 // Compiler warning: nin set but not used.
90 //
91 // Revision 1.161 2016/06/21 16:02:36 jwebb
92 // Return value not checked / remove to make static checker happy.
93 //
94 // Revision 1.160 2016/06/21 15:59:36 jwebb
95 // Coverity believes index may go out of bounds here. Add guard.
96 //
97 // Revision 1.159 2016/06/21 15:56:54 jwebb
98 // Global pointer gGeometry is set during NEW at line 1776. Test here is redundant (but makes life easy on static checking tool which can't see the pointer get set).
99 //
100 // Revision 1.158 2016/06/21 15:53:14 jwebb
101 // No need to store result if we're not checking it.
102 //
103 // Revision 1.157 2016/05/02 17:24:54 jwebb
104 // Remove unused call to geant3->Gfhead, whose only purpose seems to be to cause a corruption of the stack (see ticket 3204).
105 //
106 // Revision 1.156 2015/10/30 13:37:10 jwebb
107 // Removed unnecessary printout of number of FTS hits.
108 //
109 // Revision 1.155 2015/10/12 20:46:57 jwebb
110 // Hit definition and starsim to root interface for FTS.
111 //
112 // Revision 1.154 2015/10/06 19:43:23 jwebb
113 // Added HCAL preshower to readout in St_geant_Maker.
114 //
115 // Revision 1.153 2015/06/23 20:27:53 jwebb
116 // Added hits for FTBF version of HCAL
117 //
118 // Revision 1.152 2015/01/13 19:02:47 jwebb
119 // Read out sensitive layer from FgtdGeoV.xml
120 //
121 // Revision 1.151 2015/01/08 21:24:18 jwebb
122 // Support FMS preshower detector in HCAL.
123 //
124 // Revision 1.150 2015/01/06 15:59:20 jwebb
125 // Add FMS preshower to data readout
126 //
127 // Revision 1.149 2014/07/29 17:51:29 jwebb
128 // Read in HCAL hits.
129 //
130 // Revision 1.148 2014/03/24 19:57:15 jwebb
131 // Added code to support reading new MTD active layers.
132 //
133 // Revision 1.147 2013/06/26 18:55:05 jwebb
134 // Updated MTD sensitive volume.
135 //
136 // Revision 1.146 2013/02/06 22:04:45 fisyak
137 // Add attribute hadr_off
138 //
139 // Revision 1.145 2013/01/17 15:10:55 fisyak
140 // Add handle for setting runG, be more careful with setting mag.field
141 //
142 // Revision 1.144 2012/11/26 18:45:55 jwebb
143 // Restoring to previous version of St_geant_Maker and adding in changes needed
144 // for new generator framework (i.e. exposing TGiant3 instance).
145 //
146 // Revision 1.142 2012/11/14 00:02:12 fisyak
147 // Add flux histograms, use Attributes intead of m_Mode
148 //
149 // Revision 1.141 2012/01/24 03:13:29 perev
150 // Etr added
151 //
152 // Revision 1.140 2011/09/11 20:57:12 fisyak
153 // Add kinematics definition via MuDst, Clean up
154 //
155 // Revision 1.139 2011/08/03 20:12:24 jwebb
156 // Add mtd to the geant maker.
157 //
158 // Revision 1.138 2011/07/20 17:37:12 perev
159 // Fsc added
160 //
161 // Revision 1.137 2011/04/19 15:52:05 fisyak
162 // Restore handle for pile-up events
163 //
164 // Revision 1.136 2011/01/26 19:42:37 perev
165 // FPD ==> STAR Soft
166 //
167 // Revision 1.135 2010/08/10 16:35:33 fisyak
168 // Add initialization of starsim parameter tables after opening zebra-file
169 //
170 // Revision 1.134 2010/05/27 13:36:14 fisyak
171 // 3rd attemp to synchronize mag.field. Now take care that the maker can be not Active and do InitRun in Work
172 //
173 // Revision 1.132 2010/05/24 15:38:40 fisyak
174 // Move geometry and mag.field initialization from Init into InitRun in order to allow mag. field settings from StMagFMaker::InitRun
175 //
176 // Revision 1.130 2010/05/10 14:19:52 fisyak
177 // move geometry load from Init to InitRun in order to allow MagF maker to set mag.field
178 //
179 // Revision 1.129 2010/04/23 23:19:26 perev
180 // Remove not needed and expencive call AgstHits
181 //
182 // Revision 1.128 2010/03/31 19:15:45 fine
183 // RT #1890 Fix the side effect introduced yesterdays
184 //
185 // Revision 1.127 2010/03/29 20:37:54 fine
186 // RT #1890 Fix the geometry leak that entails the warning message
187 //
188 // Revision 1.126 2010/02/22 15:02:18 fisyak
189 // Clean up, fix bug #1860 by replacing skip => trig
190 //
191 // Revision 1.125 2010/01/07 19:16:24 perev
192 // mArgs for agvolume is 9 now
193 //
194 // Revision 1.124 2009/12/31 00:02:59 perev
195 // Add the material name to the volume name
196 //
197 // Revision 1.123 2008/10/28 22:28:34 perev
198 // FGZD hits added
199 //
200 // Revision 1.122 2008/10/21 18:02:50 perev
201 // FGSC==>FGZC its division, Wei-Ming
202 //
203 // Revision 1.121 2008/07/30 15:04:35 fisyak
204 // Remove custom SetDebug, fix bug #1252
205 //
206 // Revision 1.120 2008/06/12 20:35:27 fisyak
207 // Move creation of TGiant from ctor to Init
208 //
209 // Revision 1.119 2007/07/12 20:34:02 fisyak
210 // use StarLogger
211 //
212 // Revision 1.118 2007/05/10 19:15:29 potekhin
213 // Improved handling of the Pythia event header translation,
214 // replaced a print statement with a logger call, plus
215 // a few cosmetic changes
216 //
217 // Revision 1.117 2007/04/28 17:56:12 perev
218 // Redundant StChain.h removed
219 //
220 // Revision 1.116 2007/04/26 15:51:31 fisyak
221 // Move creation of TGiant3 in ctor (fix byg 942)
222 //
223 // Revision 1.115 2007/04/26 04:18:27 perev
224 // Remove StBFChain dependency
225 //
226 // Revision 1.114 2007/03/07 16:46:04 fine
227 // Add the warning
228 //
229 // Revision 1.113 2007/03/03 02:30:50 fine
230 // fix the geometry file name. Thanks P.Nebski
231 //
232 // Revision 1.112 2007/03/03 00:35:42 fine
233 // Fix the leak of the ROOT objects and introduce the method to return the source code filename for the arbitrary geometry node
234 //
235 // Revision 1.111 2006/10/31 23:54:13 potekhin
236 // Corrected a typo in the GEMB hit readout -- credit goes to Ross Corliss
237 //
238 // Revision 1.110 2006/10/17 19:24:30 fisyak
239 // Mode initialization after open input fz-file
240 //
241 // Revision 1.109 2006/09/22 21:27:51 potekhin
242 // Added readout of hits for two R&D detectors,
243 // GEM and HPD
244 //
245 // Revision 1.108 2006/06/19 23:26:03 potekhin
246 // Need the correct handle on the IDT hits,
247 // the previous tags were obsolete
248 //
249 // Revision 1.107 2005/11/22 23:13:24 fisyak
250 // Add default kinematics if there is no input fiels and if maker is active
251 //
252 // Revision 1.106 2005/10/12 22:58:56 fisyak
253 // SetDateTime from fz-file if it was not set before
254 //
255 // Revision 1.105 2005/10/06 19:23:07 fisyak
256 // Add set date/time from fz-file
257 //
258 // Revision 1.104 2005/08/29 21:47:09 fisyak
259 // Changes for VMC
260 //
261 // Revision 1.103 2005/06/30 22:47:40 potekhin
262 // Adding the previosuly missing g2t_igt_hit header.
263 //
264 // Revision 1.102 2005/06/30 22:32:56 potekhin
265 // Included the newly developed Inner GEM tracker
266 // (fresh R&D by Gerrit and Nikolai), and also
267 // improved debug print statemetns in a few
268 // newer detectors
269 //
270 // Revision 1.101 2005/04/26 23:40:18 potekhin
271 // As Lilian pointed out, we need to treat the SSD hits separately
272 // from the SVT in the newer versions of the geometry (we decoupled
273 // those a while ago).
274 //
275 // To this end, we use two separate variables for the number of
276 // detected hits, and place them into corresponding tables.
277 //
278 // Revision 1.100 2005/04/18 23:27:18 potekhin
279 // Correct the name for the FGT (GEM) hits
280 //
281 // Revision 1.99 2005/04/15 14:52:37 potekhin
282 // Adding an interface for reading the FGT (GEM) hits
283 //
284 // Revision 1.98 2005/04/13 22:27:11 fisyak
285 // Add Hit description extractor (AgstHits)
286 //
287 // Revision 1.97 2005/03/23 21:56:30 potekhin
288 // Added the latest Kai's code for reading hits
289 // from the IST and FST tables
290 //
291 // Revision 1.96 2005/02/07 21:09:20 fisyak
292 // rename antique TGeant3 to TGiant3
293 //
294 // Revision 1.95 2004/11/24 04:09:42 jeromel
295 // Loss of one GtHash object per call fixed
296 //
297 // Revision 1.94 2004/08/05 16:40:12 potekhin
298 // Propagating Pythia event characterization data
299 //
300 // Revision 1.93 2004/07/30 00:29:54 potekhin
301 // Fixed an old indexing typo
302 //
303 // Revision 1.92 2004/03/16 18:37:49 potekhin
304 // Corrected a typo that caused an out-of-bounds
305 // array error.
306 //
307 // Revision 1.91 2004/03/01 17:29:54 fisyak
308 // switch to starsim
309 //
310 // Revision 1.89 2004/02/25 17:55:05 fine
311 // An extra protection against of crash with gGeometry == 0
312 //
313 // Revision 1.88 2004/02/24 17:16:44 fisyak
314 // remove creation of empty fVolume
315 //
316 // Revision 1.87 2004/02/10 23:16:34 potekhin
317 // First version of Ag2Geom
318 //
319 // Revision 1.86 2003/11/12 22:44:26 potekhin
320 // Kill a stray debug print statement
321 //
322 // Revision 1.85 2003/10/31 23:12:13 potekhin
323 // Added a piece of code to handle the pixel detector hits.
324 // Reformatted a few lines and changed some comments.
325 //
326 // Revision 1.84 2003/10/02 00:13:03 potekhin
327 // Added the handling of the gdat structure, for now being
328 // written into runco are. may want to later augment this
329 // so that it gets into geant.root file.
330 //
331 // Revision 1.83 2003/09/02 17:59:29 perev
332 // gcc 3.2 updates + WarnOff
333 //
334 // Revision 1.82 2003/05/14 22:54:23 potekhin
335 // Fixing the incompatibilities gradually accumulated, in the
336 // part that reads and propagates the event header info.
337 // In particular, the pseudoparticle codes were incorrect.
338 // FIll the header based on the parsed event record.
339 //
340 // Revision 1.81 2003/05/01 20:48:56 jeromel
341 // This one is ugly ... But needed for root transition again.
342 //
343 // Revision 1.80 2003/04/30 20:39:19 perev
344 // Warnings cleanup. Modified lines marked VP
345 //
346 // Revision 1.79 2003/04/18 15:53:26 geurts
347 // Code added for TOFr (tfr) tables.
348 //
349 // Revision 1.78 2002/11/28 02:35:53 jeromel
350 // Minor correction
351 //
352 // Revision 1.77 2002/11/27 21:54:32 potekhin
353 // Added new naming convention in ESM
354 //
355 // Revision 1.76 2002/11/01 03:17:41 fine
356 // the previous version has been restored. No need of the special flag
357 //
358 // Revision 1.74 2002/10/16 20:39:23 kopytin
359 // Added code to read out BBC GSTAR tables. Needed by StBbcSimulationMaker
360 //
361 // Revision 1.72 2002/06/17 16:12:43 perev
362 // fix wrong geant time
363 //
364 // Revision 1.71 2002/04/14 21:57:09 perev
365 // Obsolete StBroadcast
366 //
367 // Revision 1.70 2002/03/12 21:22:38 fisyak
368 // Set only one StEvtHddr as default option (due to Embedding)
369 //
370 // Revision 1.69 2001/11/18 00:58:14 perev
371 //
372 // Revision 1.68 2001/07/06 17:34:24 nevski
373 // type fixed
374 //
375 // Revision 1.67 2001/07/03 23:37:25 nevski
376 // forward pion detector added
377 //
378 // Revision 1.66 2001/07/03 15:51:48 nevski
379 // phmd added
380 //
381 // Revision 1.65 2001/06/01 03:03:57 perev
382 // overloaded GetDataSet -> FindDataSet
383 //
384 // Revision 1.64 2000/12/19 18:35:11 fisyak
385 // make proper allocation for cgnam
386 //
387 // Revision 1.63 2000/07/19 16:57:34 fisyak
388 // Protection against double resetting the same run no. (Sasha)
389 //
390 // Revision 1.62 2000/06/23 16:52:12 fisyak
391 // Add filling of Run/Event no./Type from geant
392 //
393 // Revision 1.61 2000/03/26 02:43:22 fine
394 // adjusted to ROOT 2.24
395 //
396 // Revision 1.60 2000/03/03 22:00:53 nevski
397 // protection against bad track number
398 //
399 // Revision 1.59 2000/03/03 20:53:48 nevski
400 // add protection against corrupted Itrac
401 //
402 // Revision 1.58 2000/02/29 22:25:52 lasiuk
403 // added FREO and QUAR to Rich hits
404 //
405 // Revision 1.57 2000/02/03 19:34:40 fisyak
406 // Clean up St_geant_Maker::Init, move its parameters to ctor
407 //
408 // Revision 1.56 2000/02/03 16:14:39 fisyak
409 // Add Kathy's histograms
410 //
411 // Revision 1.55 2000/02/02 21:21:19 fisyak
412 // Hack for CC5
413 //
414 // Revision 1.54 2000/01/23 19:20:53 nevski
415 // pseudo-doc
416 //
417 // Revision 1.53 2000/01/14 23:43:54 fisyak
418 // Add missing defines
419 //
420 // Revision 1.52 2000/01/04 21:51:11 fisyak
421 // Move TGiant3 to root4star
422 //
423 // Revision 1.51 1999/12/07 15:44:25 fisyak
424 // Add geane, new TGiant3 from Alice
425 //
426 // Revision 1.50 1999/11/13 17:30:05 fine
427 // scope for i within for loop fixed
428 //
429 // Revision 1.49 1999/11/13 02:40:55 fisyak
430 // Add gclose
431 //
432 // Revision 1.48 1999/11/11 05:16:30 fine
433 // GetDataSet method has been introduced to build GEANT geometry on fly
434 //
435 // Revision 1.47 1999/11/06 23:05:01 fisyak
436 // fix chars
437 //
438 // Revision 1.46 1999/10/20 19:18:17 nevski
439 // g2t_event table filled
440 //
441 // Revision 1.45 1999/09/24 01:23:42 fisyak
442 // Reduced Include Path
443 //
444 // Revision 1.44 1999/07/14 16:47:44 fisyak
445 // Set protection against empty event
446 //
447 // Revision 1.43 1999/07/09 02:18:03 fisyak
448 // Add Skip
449 //
450 // Revision 1.42 1999/07/09 01:15:48 fisyak
451 // Remove non printing character from generator type
452 //
453 // Revision 1.41 1999/07/03 22:40:11 fine
454 // St_geant_Maker::Work - workaround of LINUX compiler problem
455 //
456 // Revision 1.40 1999/04/30 15:17:03 perev
457 // SetOutput added to announce Geometry exists
458 //
459 // Revision 1.39 1999/04/29 19:29:27 nevski
460 // SetInputFile returns status
461 //
462 // Revision 1.38 1999/04/20 21:40:17 nevski
463 // all shapes are going via Victors hash
464 //
465 // Revision 1.37 1999/04/19 06:29:30 nevski
466 // update of user parameter extraction
467 //
468 // Revision 1.36 1999/04/19 06:25:35 nevski
469 // update of user parameter extraction
470 //
471 // Revision 1.35 1999/04/15 20:36:40 fine
472 // St_geant::Work() was void becomes TVolume *
473 //
474 // Revision 1.34 1999/04/12 23:17:11 fine
475 // Unique postion ID has been introduced
476 //
477 // Revision 1.33 1999/04/09 23:52:48 nevski
478 // checking 3 volume parameters now
479 //
480 // Revision 1.32 1999/04/08 00:39:08 fine
481 // Work metod - workaround for ROOT bug PCON definition
482 //
483 // Revision 1.31 1999/04/07 12:59:45 fine
484 // Fixed bug for PCON and PGON shapes
485 //
486 // Revision 1.30 1999/04/06 19:40:08 nevski
487 // variable size volumes
488 //
489 // Revision 1.29 1999/03/22 14:45:23 nevski
490 // geometry tree corrected
491 //
492 // Revision 1.28 1999/03/20 22:43:05 perev
493 // Do(trig)
494 //
495 // Revision 1.27 1999/03/11 00:15:22 perev
496 // St_geant_Maker in new maker schema
497 //
498 // Revision 1.26 1999/03/04 19:32:16 nevski
499 // esm/eem corrected
500 //
501 // Revision 1.25 1999/02/24 17:12:27 fine
502 // St_Table::New has been activated
503 //
504 // Revision 1.24 1999/02/23 18:59:50 nevski
505 // SVT 4th layer added to svt hit table
506 //
507 // Revision 1.23 1999/02/22 23:55:57 fine
508 // St_geant_Maker::rootmaptable is prepaed to use St_TableNew(), not activated yet
509 //
510 // Revision 1.22 1999/02/22 20:51:25 fisyak
511 // Mismatch between ctb/tof
512 //
513 // Revision 1.21 1999/02/22 19:27:20 fisyak
514 // add gtrigi and gtigc
515 //
516 // Revision 1.20 1999/02/20 20:23:45 fisyak
517 // Fix Aeast
518 //
519 // Revision 1.18 1999/02/19 14:41:00 fisyak
520 // Set kIsNotOwn Bit for geometry tables
521 //
522 // Revision 1.17 1999/02/18 15:44:47 fisyak
523 // Cleanup warinings
524 //
525 // Revision 1.16 1999/02/17 22:42:07 fisyak
526 // fix Linux parameters
527 //
528 // Revision 1.15 1999/02/17 15:55:38 fisyak
529 // Add GSTAR to ROOT geometry tables transformation
530 //
531 // Revision 1.14 1999/02/16 18:15:45 fisyak
532 // Check in the latest updates to fix them
533 //
534 // Revision 1.13 1999/02/12 17:57:01 nevski
535 // particle table
536 //
537 // Revision 1.12 1999/02/12 14:18:27 nevski
538 // merging 2 mods
539 //
540 // Revision 1.5 1999/01/10 20:37:31 fisyak
541 // Give access to Zebra
542 //
543 // Revision 1.4 1999/01/05 01:37:02 fisyak
544 // Intermeidate version with TVolume
545 //
546 // Revision 1.3 1999/01/03 20:56:35 fisyak
547 // Remove St_geom_Maker
548 //
549 // Revision 1.7 1998/12/25 21:02:13 nevski
550 // Add Set/Get method
551 //
552 // Revision 1.6 1998/12/17 14:38:00 fisyak
553 // Change default to no Higz window
554 //
555 // Revision 1.5 1998/12/16 20:56:24 fisyak
556 // Add gstar to ROOT
557 //
558 // Revision 1.4 1998/12/12 00:21:15 fisyak
559 // Remove gstar for the moment
560 //
561 // Revision 1.3 1998/12/12 00:18:00 fisyak
562 // Remove gstar for the moment
563 //
564 // Revision 1.2 1998/12/04 19:36:47 fisyak
565 // Add Pavel/Ruben gstar interface
566 //
567 // Revision 1.1 1998/10/31 00:28:31 fisyak
568 // Makers take care about branches
569 //
570 // Revision 1.6 1998/10/06 18:00:29 perev
571 // cleanup
572 //
573 // Revision 1.5 1998/10/02 13:46:08 fine
574 // DataSet->DataSetIter
575 //
576 // Revision 1.4 1998/08/14 15:25:58 fisyak
577 // add options
578 //
579 // Revision 1.3 1998/08/10 02:32:07 fisyak
580 // Clean up
581 //
582 // Revision 1.2 1998/07/20 15:08:15 fisyak
583 // Add tcl and tpt
584 //
586 // //
587 // St_geant_Maker class for Makers //
588 // //
590 #include "St_geant_Maker.h"
591 #include "TDataSetIter.h"
592 #include "TTable.h"
593 #include "Stiostream.h"
594 #include <stdio.h>
595 #include <string.h>
596 #include <string>
597 #include "TSystem.h"
598 #include "GtHash.h"
599 #include "TGeometry.h"
600 #include "TMaterial.h"
601 #include "TMixture.h"
602 #include "TString.h"
603 #include "TRegexp.h"
604 #include "TInterpreter.h"
605 #include "TClassTable.h"
606 #include "TVolume.h"
607 #include "TFile.h"
608 #include "TFileSet.h"
609 #include "TMath.h"
610 #include "TBRIK.h"
611 #include "TTRD1.h"
612 #include "TTRD2.h"
613 #include "TTRAP.h"
614 #include "TTUBE.h"
615 #include "TTUBS.h"
616 #include "TCONE.h"
617 #include "TCONS.h"
618 #include "TSPHE.h"
619 #include "TPARA.h"
620 #include "TPGON.h"
621 #include "TPCON.h"
622 #include "TELTU.h"
623 // #include "THYPE.h"
624 #include "TGTRA.h"
625 #include "TCTUB.h"
626 // new Geometry
627 #include "TGeoMaterial.h"
628 #include "TGeoMatrix.h"
629 #include "TGeoNode.h"
630 #include "TGeoManager.h"
631 #include "TGeoVolume.h"
632 #include "TGeoPcon.h"
633 #include "TGeoPgon.h"
634 #include "TObjString.h"
635 #include "TGraph.h"
636 #include "TH1.h"
637 #include "TH2.h"
638 #include "TH3.h"
639 #include "StarMagField.h"
640 //#include "tables/St_g2t_run_Table.h"
641 #include "tables/St_g2t_event_Table.h"
642 #include "tables/St_g2t_pythia_Table.h"
643 #include "tables/St_g2t_gepart_Table.h"
644 #include "tables/St_g2t_vertex_Table.h"
645 #include "tables/St_g2t_track_Table.h"
646 #include "tables/St_geom_gdat_Table.h"
647 #include "StDetectorDbMaker/St_MagFactorC.h"
648 #include "tables/St_det_user_Table.h"
649 #include "tables/St_det_hit_Table.h"
650 #include "tables/St_det_path_Table.h"
651 #include "tables/St_mfld_mflg_Table.h"
652 #include "TDataSetIter.h"
653 #include "TTreeIter.h"
654 // event header:
655 #include "g2t/St_g2t_get_event_Module.h"
656 // Pythia-specific header
657 #include "g2t/St_g2t_get_pythia_Module.h"
658 //
659 #include "g2t/St_g2t_get_kine_Module.h"
660 #include "g2t/St_g2t_particle_Module.h"
661 // Subsystems:
662 #include "g2t/St_g2t_svt_Module.h"
663 #include "g2t/St_g2t_ssd_Module.h"
664 #include "g2t/St_g2t_pix_Module.h"
665 #include "g2t/St_g2t_hpd_Module.h"
666 #include "g2t/St_g2t_ist_Module.h"
667 #include "g2t/St_g2t_igt_Module.h"
668 #include "g2t/St_g2t_gem_Module.h"
669 #include "g2t/St_g2t_fst_Module.h"
670 #include "g2t/St_g2t_fgt_Module.h"
671 #include "g2t/St_g2t_tpc_Module.h"
672 #include "g2t/St_g2t_mwc_Module.h"
673 #include "g2t/St_g2t_ftp_Module.h"
674 #include "g2t/St_g2t_ctb_Module.h"
675 #include "g2t/St_g2t_tof_Module.h"
676 #include "g2t/St_g2t_tfr_Module.h" // barrel tof
677 #include "g2t/St_g2t_eto_Module.h" // endcap tof
678 #include "g2t/St_g2t_rch_Module.h"
679 #include "g2t/St_g2t_emc_Module.h"
680 #include "g2t/St_g2t_smd_Module.h"
681 #include "g2t/St_g2t_eem_Module.h"
682 #include "g2t/St_g2t_esm_Module.h"
683 #include "g2t/St_g2t_zdc_Module.h"
684 #include "g2t/St_g2t_vpd_Module.h"
685 #include "g2t/St_g2t_pmd_Module.h"
686 #include "g2t/St_g2t_bbc_Module.h"
687 #include "g2t/St_g2t_fpd_Module.h"
688 #include "g2t/St_g2t_fsc_Module.h"
689 #include "g2t/St_g2t_mtd_Module.h"
690 #include "g2t/St_g2t_etr_Module.h"
691 #include "g2t/St_g2t_hca_Module.h"
692 #include "g2t/St_g2t_wca_Module.h"
693 #include "g2t/St_g2t_pre_Module.h"
694 #include "g2t/St_g2t_fts_Module.h"
695 #include "g2t/St_g2t_stg_Module.h"
696 #include "g2t/St_g2t_epd_Module.h"
697 
698 #include "St_db_Maker/St_db_Maker.h"
699 #include "TUnixTime.h"
700 #include "StarCallf77.h"
701 #include "StMagF.h"
702 #include "StMessMgr.h"
703 #ifdef DetectorIndex
704 #include "StarDetectorMap.h"
705 #endif
706 #include "StDetectorDbMaker/St_vertexSeedC.h"
707 #ifdef F77_NAME
708 #define geometry F77_NAME(geometry,GEOMETRY)
709 #define agstroot F77_NAME(agstroot,AGSTROOT)
710 #define csaddr F77_NAME(csaddr,CSADDR)
711 #define csjcal F77_NAME(csjcal,CSJCAL)
712 #define g2t_volume_id F77_NAME(g2t_volume_id,G2T_VOLUME_ID)
713 #define g2r_get_sys F77_NAME(g2r_get_sys,G2R_GET_SYS)
714 #define gfrotm F77_NAME(gfrotm,GFROTM)
715 #define gfxzrm F77_NAME(gfxzrm,GFXZRM)
716 #define dzddiv F77_NAME(dzddiv,DZDDIV)
717 #define agnzgete F77_NAME(agnzgete,AGNZGETE)
718 #define rootmaptable F77_NAME(rootmaptable,ROOTMAPTABLE)
719 #define agvolume F77_NAME(agvolume,AGVOLUME)
720 #define agvoluma F77_NAME(agvoluma,AGVOLUMA)
721 #define uhtoc F77_NAME(uhtoc,UHTOC)
722 #define agfpath F77_NAME(agfpath,UHTOC)
723 #if 0
724 #define mfldgeo F77_NAME(mfldgeo,MFLDGEO)
725 #endif
726 #define agfdig0 F77_NAME(agfdig0,AGFDIG0)
727 #define agfdpar F77_NAME(agfdpar,AGFDPAR)
728 #if 0
729 #define acfromr F77_NAME(acfromr,ACFROMR)
730 #endif
731 #define dstkine F77_NAME(dstkine,DSTKINE)
732 #endif
733 typedef long int (*addrfun)();
734 R__EXTERN "C" {
735  void *getPntB(int myDif);
736  void type_of_call geometry();
737  int type_of_call agstroot();
738  void type_of_call *csaddr(char *name, int l77name=0);
739  long int type_of_call csjcal(
740  addrfun *fun, /* addres of external routine */
741  int *narg, /* number of arguments */
742  ...); /* other narg arguments */
743 
744  int type_of_call g2t_volume_id (DEFCHARD, int* DEFCHARL);
745  void type_of_call g2r_get_sys (DEFCHARD, DEFCHARD, int&, int& DEFCHARL DEFCHARL);
746  void type_of_call gfrotm (int&,Float_t&,Float_t&,Float_t&,Float_t&,Float_t&,Float_t&);
747  void type_of_call gfxzrm (int &NLEV_0,Float_t &X,Float_t &Y,Float_t &Z,
748  Float_t &TET1,Float_t &PHI1,
749  Float_t &TET2,Float_t &PHI2,
750  Float_t &TET3,Float_t &PHI3,Float_t &TYPE);
751  void type_of_call agnzgete (int &ILK,int &IDE,
752  int &NPART,int &IRUN,int &IEVT,DEFCHARD CGNAM,
753  Float_t *VERT,int &IWTFL,Float_t &WEIGH DEFCHARL);
754  void type_of_call dzddiv (int &,int &,DEFCHARD,DEFCHARD,
755  int &,int &,int &,int & DEFCHARL DEFCHARL);
756  /*
757  * Input : ILK - Link number : 1 = primary, 2 = secondary (obsolete) *
758  * IDE - ID of event in gate ( ZEBRA IDN) *
759  * Output: NPART - Number of particles in event record *
760  * IRUN - run number as recorded by generator *
761  * IEVT - event number as recorded by generator *
762  * CGNAM - generator name *
763  * VERT(4)- x,y,z,t of event (metres,seconds or mm,mm/c) *
764  * IWTFL - weight flintag *
765  * WEIGH - event weight *
766  */
767  void type_of_call rootmaptable_(DEFCHARD,DEFCHARD,DEFCHARD, int&,Char_t *
768  DEFCHARL DEFCHARL DEFCHARL);
769  int type_of_call agvolume(uint64_t&, uint64_t&, uint64_t&, uint64_t&, int&
770  ,int&, uint64_t&, int&, int *);
771  int type_of_call agvoluma(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*);
772  void type_of_call uhtoc(int&,int &,DEFCHARD,int& DEFCHARL);
773  int type_of_call agfdig0 (const char*,const char*,int,int);
774  void type_of_call agfdpar (float &hits,const char *chit, float &alim, float &blim, float &bin, int);
775  void type_of_call agfpath(int *);
776  void type_of_call dstkine();
777 }
778 Char_t type_of_call *acfromr(Float_t r=8009359);
779 
780 Quest_t *St_geant_Maker::cquest;
781 Gclink_t *St_geant_Maker::clink;
782 Gcflag_t *St_geant_Maker::cflag;
783 Gcvolu_t *St_geant_Maker::cvolu;
784 Gcnum_t *St_geant_Maker::cnum;
785 int *St_geant_Maker::z_iq, *St_geant_Maker::z_lq;
786 Float_t *St_geant_Maker::z_q;
787 Gcsets_t *St_geant_Maker::csets;
788 Gckine_t *St_geant_Maker::ckine;
789 Gcking_t *St_geant_Maker::cking;
790 Gctrak_t *St_geant_Maker::ctrak;
791 Gcmate_t *St_geant_Maker::cmate;
792 Gccuts_t *St_geant_Maker::ccuts;
793 Gcphys_t *St_geant_Maker::cphys;
794 int St_geant_Maker::nlev;
795 static int irot = 0;
796 static TVolume *topnode=0;
797 typedef struct {
798  Float_t par[50];
799 } params;
800 typedef struct {
801  Float_t lseen, lstyle, lwidth, lcolor, lfill;
802 } attributes;
803 
804 static int ifz = 0;
805 ClassImp(St_geant_Maker)
806 
807 TDataSet *St_geant_Maker::fgGeom = 0;
808 TGiant3 *St_geant_Maker::geant3 = 0;
809 St_geant_Maker *St_geant_Maker::fgGeantMk = 0;
810 static TTreeIter *MuDstIter = 0;
811 //_____________________________________________________________________________
812 St_geant_Maker::St_geant_Maker(const Char_t *name,int nwgeant,int nwpaw, int iwtype):
813  StMaker(name),
814  fNwGeant(nwgeant), fNwPaw(nwpaw), fIwType(iwtype),
815  fVolume(0), fTopGeoVolume(0),
816  fInputFile(""),fGeoDirectory(0), fEvtHddr(0),
817  fRemakeGeometry(kFALSE),m_geom_gdat(0),mInitialization(""), mFieldOpt(""), mHitCounts()
818 {
819  fgGeantMk = this;
820  fgGeom = new TDataSet("geom");
821  AddConst(fgGeom);
822  SetOutput(fgGeom); //Declare this "geom" for output
823 }
824 //_____________________________________________________________________________
825 TDataSet *St_geant_Maker::FindDataSet (const char* logInput,const StMaker *uppMk,
826  const StMaker *dowMk) const
827 {
828  bool lookupHall = !strcmp(logInput,"HALL");
829  bool lookupGeoDir = !strcmp(logInput,"GeometryDirectory");
830 
831  TDataSet *ds = 0;
832  if ( !(lookupHall || lookupGeoDir) ) {
833  ds = StMaker::FindDataSet(logInput,uppMk,dowMk);
834  } else {
835  if (lookupHall) {
836  ds = fVolume;
837  if (!fVolume) {
838  ((St_geant_Maker *)this)->Work();
839  ds = fVolume;
840  if (fVolume) {
841  if (gGeometry) {
842  TList *listOfVolume = gGeometry->GetListOfNodes();
843 
844  // Remove hall from the list of ROOT nodes to make it free of ROOT control
845  listOfVolume->Remove(fVolume);
846  listOfVolume->Remove(fVolume);
847  }
848  // Add "hall" into ".const" area of this maker
849  ((St_geant_Maker *)this)->AddConst(fVolume);
850  if (Debug()) fVolume->ls(3);
851  }
852  }
853  } else if (lookupGeoDir) {
854  if (!fGeoDirectory) {
855  TString file("pams/geometry");
856  // Check the local path first
857  TFileSet *geoDir = new TFileSet(file.Data());
858  if (!geoDir->FindByName("geometry.g")) {
859  // Try the global one
860  delete geoDir;
861  TString starRoot = "$STAR/" + file;
862  geoDir = new TFileSet(starRoot.Data());
863  if (!geoDir->FindByName("geometry.g")) {
864  LOG_DEBUG << "NO STAR geometry source directory has been found" << endm;
865  delete geoDir; geoDir = 0;
866  } else {
867  TString star("$STAR/pams");
868  gSystem->ExpandPathName(star);
869  geoDir->SetTitle(star.Data());
870  }
871  } else {
872  TString wd = gSystem->WorkingDirectory();
873  wd += "/pams";
874  geoDir->SetTitle(wd.Data());
875  }
876  if (geoDir) {
877  ((St_geant_Maker *)this)->fGeoDirectory = geoDir;
878  TDataSet *container = new TDataSet("GeometryDirectory");
879  container->Add(geoDir);
880  ds = fGeoDirectory;
881  ((St_geant_Maker *)this)->AddConst(container);
882  if (Debug()) fGeoDirectory->ls(3);
883  }
884  }
885  ds = fGeoDirectory;
886  }
887  }
888  return ds;
889 }
890 //_____________________________________________________________________________
891 int St_geant_Maker::Init(){
892  // Initialize GEANT
893  if ( geant3) return kStOK;
894  PrintInfo();
895  geant3 = new TGiant3("C++ Interface to Geant3",fNwGeant,fNwPaw,fIwType);
896  assert(geant3);
897  cquest = (Quest_t *) geant3->Quest();
898  clink = (Gclink_t *) geant3->Gclink();
899  cflag = (Gcflag_t *) geant3->Gcflag();
900  cvolu = (Gcvolu_t *) geant3->Gcvolu();
901  cnum = (Gcnum_t *) geant3->Gcnum();
902  z_iq = (int *) geant3->Iq();
903  z_lq = (int *) geant3->Lq();
904  z_q = (Float_t *) geant3->Q();
905  csets = (Gcsets_t *) geant3->Gcsets();
906  ckine = (Gckine_t *) geant3->Gckine();
907  cking = (Gcking_t *) geant3->Gcking();
908  ctrak = (Gctrak_t *) geant3->Gctrak();
909  cmate = (Gcmate_t *) geant3->Gcmate();
910  ccuts = (Gccuts_t *) geant3->Gccuts();
911  cphys = (Gcphys_t *) geant3->Gcphys();
912  Do("kuip/s/filecase KEEP");
913  TString InputFile(fInputFile);
914  if (fInputFile != "") {//check that first word contains .fz then add "gfile p"
915  // -"- .nt then add "user/input user"
916  if (Debug()) LOG_INFO << "St_geant_Maker::Init File " << fInputFile.Data() << endm;
917  TString kuip("");
918  if (InputFile.Contains(".fz")) {ifz = 1; kuip = "gfile p "; kuip += InputFile;}
919  else if (InputFile.Contains(".nt")) {kuip = "user/input user "; kuip += InputFile;}
920  else if (InputFile.Contains(".tx")) {kuip = "user/input tx "; kuip += InputFile;}
921  else if (InputFile.Contains(".MuDst")) {
922  if (! MuDstIter) MuDstIter = new TTreeIter();
923  MuDstIter->AddFile(InputFile);
924  kuip = "user/input please MuDst.Dst";
925  // m_Mode = 10*(m_Mode/10);
926  // m_Mode += 1; // take time stamp from MuDst
927  SetAttr("Don'tTouchTimeStamp",kTRUE);
928  SetDatimeFromMuDst();
929  }
930  if (kuip != "") {
931  if (Debug()) LOG_INFO << "St_geant_Maker::Init kuip " << kuip.Data() << endm;
932  Do(kuip.Data());
933  if (cquest->iquest[0] > kStOK) {
934  LOG_INFO << "St_geant_Maker::Init File " << InputFile.Data() << " cannot be opened. Exit!" << endm;
935  gSystem->Exit(1);
936  }
937  InputFile = "";
938  }
939  } else {
940  if (IsActive()) {// default
941  Do("subevent 0;");
942  if (IAttr("Pythia")) {
943  Do("call bpythia");
944  // ** These particles will be decayed by geant instead of pythia **
945  Do("MDCY (102,1)=0");// ! PI0 111
946  Do("MDCY (106,1)=0");// ! PI+ 211
947  Do("MDCY (109,1)=0");// ! ETA 221
948  Do("MDCY (116,1)=0");// ! K+ 321
949  Do("MDCY (112,1)=0");// ! K_SHORT 310
950  Do("MDCY (105,1)=0");// ! K_LONG 130
951  Do("MDCY (164,1)=0");// ! LAMBDA0 3122
952  Do("MDCY (167,1)=0");// ! SIGMA0 3212
953  Do("MDCY (162,1)=0");// ! SIGMA- 3112
954  Do("MDCY (169,1)=0");// ! SIGMA+ 3222
955  Do("MDCY (172,1)=0");// ! Xi- 3312
956  Do("MDCY (174,1)=0");// ! Xi0 3322
957  Do("MDCY (176,1)=0");// ! OMEGA- 3334
958  Do("frame CMS");
959  Do("beam p p");
960  Double_t sqrtS = 510;
961  Do(Form("ener %f",sqrtS));
962  Do("CALL PyTUNE(329)"); // set the pythia tune
963  Do("gspread 0.015 0.015 42.00");
964  if (IAttr("Wenu")) {
965  // select W --> e nu production
966  Do("ckin 3=10.0");
967  Do("ckin 4=-1.0");
968  Do("msel 12");
969  }
970  if (IAttr("Wenu")) {
971  // close all decay channels
972  Do("call closeDecays(24)"); // real call
973  // ** enable W+/- --> e+/- nu
974  Do("call openDecay(24,206,1)");
975  }
976  //? GKINE -4 0 0. 510. -3.0 +3.0
977  Do("call pystat(1)");
978  } else {
979  // gkine #particles partid ptrange yrange phirange vertexrange
980  Do("gkine 80 6 1. 1. -2. 2. 0 6.28 0. 0.;");
981  }
982  Do("mode g2tm prin 1;");
983  // Do("next;");
984  // Do("dcut cave z 1 10 10 0.03 0.03;");
985  // if ((m_Mode/1000)%10 == 1) {// phys_off
986 
988 
989  if (Debug() > 1) {
990  Do("debug on;");
991  Do("swit 2 2;");
992  }
993  }
994  }
995  return kStOK;
996 }
997 //________________________________________________________________________________
998 int St_geant_Maker::InitRun(int run){
999  static Bool_t InitRunDone = kFALSE;
1000  if (InitRunDone) return kStOK;
1001  InitRunDone = kTRUE;
1002  if (mInitialization != "") {
1003  LOG_INFO << "St_geant_Maker::InitRun -- Do geometry initialization" << endm;
1004  LOG_INFO << "St_geant_Maker::InitRun -- with " << mInitialization.Data() << endm;
1005  Do(mInitialization.Data());
1006  Geometry();
1007  mInitialization = "";
1008  if (IAttr("phys_off")) {
1009  LOG_INFO << "St_geant_Maker::Init switch off physics" << endm;
1010  Do("DCAY 0");
1011  Do("ANNI 0");
1012  Do("BREM 0");
1013  Do("COMP 0");
1014  Do("HADR 0");
1015  Do("MUNU 0");
1016  Do("PAIR 0");
1017  Do("PFIS 0");
1018  Do("PHOT 0");
1019  Do("RAYL 0");
1020  Do("LOSS 4"); // no fluctuations
1021  // Do("LOSS 1"); // with delta electron above dcute
1022  Do("DRAY 0");
1023  Do("MULS 0");
1024  Do("STRA 0");
1025  // CUTS CUTGAM CUTELE CUTHAD CUTNEU CUTMUO BCUTE BCUTM DCUTE DCUTM PPCUTM TOFMAX GCUTS[5]
1026  Do("CUTS 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 50.e-6");
1027  Do("physi");
1028  } else if (IAttr("hadr_off")) {
1029  LOG_INFO << "St_geant_Maker::Init switch off hadron interactions" << endm;
1030  Do("DCAY 1");
1031  Do("ANNI 0");
1032  Do("BREM 0");
1033  Do("COMP 0");
1034  Do("HADR 0");
1035  Do("MUNU 0");
1036  Do("PAIR 0");
1037  Do("PFIS 0");
1038  Do("PHOT 0");
1039  Do("RAYL 0");
1040  Do("LOSS 1");
1041  Do("DRAY 0");
1042  Do("MULS 1");
1043  Do("STRA 0");
1044  // CUTS CUTGAM CUTELE CUTHAD CUTNEU CUTMUO BCUTE BCUTM DCUTE DCUTM PPCUTM TOFMAX GCUTS[5]
1045  Do("CUTS 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 50.e-6");
1046  Do("physi");
1047  } else if (IAttr("flux")) {
1048  Do("call agustep");
1049  Do("HADR 6"); // gcalor
1050  // CUTS CUTGAM CUTELE CUTHAD CUTNEU CUTMUO BCUTE BCUTM DCUTE DCUTM PPCUTM TOFMAX GCUTS[5]
1051  Do("CUTS 1e-5 1e-5 1e-3 1e-14 1e-3 1e-3 1e-3 1e-3 1e-3 1e-3 10");
1052  Do("physi");
1053  }
1054  Do("gclose all");
1055  }
1056  Agstroot();
1057  if (IAttr("RunG")) {
1058  LOG_INFO << "St_geant_Maker::InitRun -- Set RunG/rndm " << IAttr("RunG") << endl;
1059  Do(Form("rung %d 1",IAttr("RunG")));
1060  Do(Form("rndm %d",IAttr("RunG")));
1061  Do("rndm");
1062  }
1063  LOG_INFO << "St_geant_Maker::InitRun -- Do mag.field initialization" << endm;
1064  m_geom_gdat = (St_geom_gdat *) Find(".runco/geom/geom_gdat");
1065  if (! m_geom_gdat) {
1066  St_geom_gdat *geom_gdat = (St_geom_gdat *) Find(".const/geom/geom_gdat");
1067  if ( geom_gdat) {
1068  m_geom_gdat = new St_geom_gdat(*geom_gdat);
1069  AddRunco(m_geom_gdat);
1070  }
1071  }
1072  // if (m_Mode%10 != 1 && IsActive() ) {// Mixer mode == 1 or reco - do not modify EvtHddr and MagF
1073  if (! IAttr("Don'tTouchTimeStamp") && IsActive() ) {// Mixer mode == 1 or reco - do not modify EvtHddr and MagF
1074  fEvtHddr = (StEvtHddr*) GetTopChain()->GetDataSet("EvtHddr");
1075  if (!fEvtHddr) { // Standalone run
1076  fEvtHddr = new StEvtHddr(GetConst());
1077  fEvtHddr->SetRunNumber(0); // to have run positive and < 1000000 (to avoid mess with RunLog)
1078  SetOutput(fEvtHddr); //Declare this "EvtHddr" for output
1079  }
1080  if (! ifz ) {
1081  // if Simulation is read from zebra file set Scale to value got from the file
1082  // if Simulation is done on fly use mFieldOpt field option set by StBFChain
1083  // if data use Scale for Db unless it has been reset by StBFChain field option (in IsActive)
1084  if (! m_geom_gdat) {
1085  m_geom_gdat = new St_geom_gdat("geom_gdat",1);
1086  AddRunco(m_geom_gdat);
1087  geom_gdat_st row = {{0,0}, 1, "gstar"};
1088  m_geom_gdat->AddAt(&row);
1089  }
1090  } else {// set mag. field from already simulated data, only 5 option allowed
1091  if (MuDstIter) {
1092  // set mag field
1093  if (StarMagField::Instance() && StarMagField::Instance()->IsLocked()) {
1094  // Passive mode, do not change scale factor
1095  LOG_INFO << "St_geant_Maker::InitRun passive mode. Don't update Mag.Field from DB" << endm;
1096  } else {
1097  Float_t fScale = St_MagFactorC::instance()->ScaleFactor();
1098  if (TMath::Abs(fScale) < 1e-3) fScale = 1e-3;
1099  LOG_INFO << "St_geant_Maker::InitRun active mode ";
1100  if (! StarMagField::Instance()) {
1101  new StarMagField ( StarMagField::kMapped, fScale);
1102  LOG_INFO << "Initialize STAR magnetic field with scale factor " << fScale << endm;
1103  } else {
1104  StarMagField::Instance()->SetFactor(fScale);
1105  LOG_INFO << "Reset STAR magnetic field with scale factor " << fScale << endm;
1106  }
1107  }
1108  } else {
1109  Float_t mfscale = 1;
1110  if (m_geom_gdat) {
1111  geom_gdat_st *gdat = m_geom_gdat->GetTable();
1112  mfscale = gdat->mfscale;
1113  LOG_INFO << "St_geant_Maker::Init geom_gdata is found in fz-file ! ";
1114  } else {
1115  St_mfld_mflg *mfld_mflg = (St_mfld_mflg *) Find(".const/geom/mfld_mflg");
1116  if (mfld_mflg) {
1117  LOG_INFO << "St_geant_Maker::Init mfld_mflg is found in fz-file ! ";
1118  mfld_mflg_st *s = mfld_mflg->GetTable();
1119  mfscale = s->bfield/5.0;
1120  } else {
1121  LOG_INFO << "St_geant_Maker::Init geom_gdata is missing in fz-file ! Use default mag.field scale factor ";
1122  }
1123  }
1124  LOG_INFO << "St_geant_Maker::Init mfscale = " << mfscale << endm;
1125  struct Field_t {
1126  const Char_t *name;
1127  Float_t scale;
1128  };
1129  const Field_t FieldOptions[5] = {
1130  {"FullMagFNegative", -1.0},
1131  {"FullMagFPositive", 1.0},
1132  {"HalfMagFNegative", -0.5},
1133  {"HalfMagFPositive", 0.5},
1134  {"ZeroMagF", 0.0}
1135  };
1136  TString FieldOption("");
1137  for (int i = 0; i < 5; i++) {
1138  if (TMath::Abs(mfscale - FieldOptions[i].scale) < 2.e-2) {
1139  FieldOption = FieldOptions[i].name;
1140  break;
1141  }
1142  }
1143  if (FieldOption != "") {
1144  SetFlavor(FieldOption.Data(), "MagFactor");
1145  LOG_INFO << "St_geant_Maker::Init SetFlavor(\"" << FieldOption.Data()
1146  << "\",\"MagFactor\")" << endm;
1147  }
1148  delete StarMagField::Instance();
1149  if (! StarMagField::Instance()) {
1150  new StarMagField ( StarMagField::kMapped, mfscale, kTRUE);
1151  LOG_INFO << "St_geant_Maker::Init Create StarMagField and lock it"
1152  << endm;
1153  }
1154  else {
1155  StarMagField::Instance()->SetFactor(mfscale);
1156  StarMagField::Instance()->SetLock();
1157  LOG_INFO << "St_geant_Maker::Init Reset StarMagField and lock it"
1158  << endm;
1159  }
1160  }
1161  }
1162  }
1163  if (IsActive() && IAttr("Pythia")) {
1164  if (IAttr("beamLine")) {
1165  St_vertexSeedC* vSeed = St_vertexSeedC::instance();
1166  if (vSeed) {
1167  Double_t x0 = vSeed->x0() ;
1168  Double_t y0 = vSeed->y0() ;
1169  Double_t dxdz = vSeed->dxdz();
1170  Double_t dydz = vSeed->dydz();
1171  Do(Form("gvertex %f %f 1",x0,y0)); // ** setup the vertex
1172  Do(Form("gslope %f %f", dxdz, dydz));
1173  }
1174  }
1175  }
1176  return kStOK;
1177 }
1178 //_____________________________________________________________________________
1180  int /*nhits,nhit1,nhit2,nhit3,nhit4,*/link=1,ide=1,npart,irun,ievt,iwtfl;
1181  Float_t vert[4],weigh;
1182  if (GetDebug()) { Do("debug on;"); } else {Do("debug off;"); }
1183  int iRes = 0; if(iRes) {/*touch*/};
1184  Do("trig");
1185 
1186  // check EoF
1187  if (cquest->iquest[0]) {return kStEOF;}
1188  // prepare an empty g2t_event
1189  St_g2t_event *g2t_event = new St_g2t_event("g2t_event",1);
1190  AddData(g2t_event);
1191 
1192  Char_t cgnam[21] = " \0";
1193  Agnzgete(link,ide,npart,irun,ievt,cgnam,vert,iwtfl,weigh);
1194 
1195  // if (m_Mode%10 != 1) {
1196  if (! IAttr("Don'tTouchTimeStamp")) {
1197  if (fEvtHddr) {
1198  if (clink->jhead) {
1199  if (fEvtHddr->GetRunNumber() != *(z_iq+clink->jhead+1))
1200  fEvtHddr->SetRunNumber(*(z_iq+clink->jhead+1));
1201  fEvtHddr->SetEventNumber(*(z_iq+clink->jhead+2));
1202  }
1203  if (fInputFile != "") fEvtHddr->SetEventType(TString(gSystem->BaseName(fInputFile.Data()),7));
1204  fEvtHddr->SetProdDateTime();
1205 #if 1
1206  SetDateTime();
1207 #endif
1208  }
1209  }
1210  if (npart>0) {
1211  St_particle *particle = new St_particle("particle",npart);
1212  AddData(particle); iRes = g2t_particle(particle);
1213  // =======================
1214  if (Debug() > 1) particle->Print(0,10);
1215  particle_st *p = particle->GetTable();
1216 
1217  // 20030508 --max-- found a bug: 9999999
1218  // "istat==10" on the following line, changing to >=11
1219  // This "if should now work with both "old" and "new" ntuple conventions
1220  // if (m_Mode%10 != 1) {
1221  if (! IAttr("Don'tTouchTimeStamp")) {
1222  if ( (p->isthep == 10 && p->idhep == 9999999 && fEvtHddr) ||
1223  (p->isthep >= 11 && p->idhep == 999998 && fEvtHddr)) {
1224 
1225  fEvtHddr->SetBImpact (p->phep[0]);
1226  fEvtHddr->SetPhImpact (p->phep[1]);
1227  fEvtHddr->SetCenterOfMassEnergy(p->phep[2]);
1228 
1229  // Obsoleted: --max--
1230  // fEvtHddr->SetGenerType((int)p->phep[2]);
1231  // int west = (int)p->phep[4];
1232  // int east = (int)(1000.*p->phep[4]-1000.*((float)west));
1233  // fEvtHddr->SetAWest(west);
1234  // fEvtHddr->SetAEast(east);
1235 
1236  // Update the run number, if necessary
1237  // if ( m_Mode%100 != 1 &&
1238  if (! IAttr("KeepRunNumber") &&
1239  p->vhep[0] > 0 && p->vhep[0] < 10000 &&
1240  fEvtHddr->GetRunNumber() != p->vhep[0]) {
1241  fEvtHddr->SetRunNumber((int)p->vhep[0]);
1242 
1243  fEvtHddr->SetEventNumber((int)p->vhep[1]);
1244  int id = p->jdahep[0];
1245  int it = p->jdahep[1];
1246 
1247  if (id <= 0) id = 19991231;
1248  if (id <= 19000000) id +=19000000;
1249  if (id >= 20500000) id = 19991231;
1250  if (it < 0) it = 235959;
1251  if (it > 246060) it = 235959;
1252  fEvtHddr->SetDateTime(id,it);
1253  }
1254  }
1255  }
1256  }
1257 
1258  if (!cnum->nvertx || !cnum->ntrack) return kStErr;
1259  St_g2t_vertex *g2t_vertex = new St_g2t_vertex("g2t_vertex",cnum->nvertx);
1260  AddData(g2t_vertex);
1261  St_g2t_track *g2t_track = new St_g2t_track ("g2t_track",cnum->ntrack);
1262  AddData(g2t_track);
1263 
1264  /*iRes =*/ g2t_get_kine (g2t_vertex,g2t_track);
1265  if (Debug() > 1) {
1266  g2t_vertex->Print(0,10);
1267  g2t_track->Print(0,10);
1268  }
1269 
1270  iRes = g2t_get_event(g2t_event);
1271  if (Debug() > 1) {
1272  g2t_event->Print(0,10);
1273  }
1274 
1275  if(iRes>=10) { // means there was Pythia information detected in the input, see g2t_get_event code
1276  St_g2t_pythia *g2t_pythia = new St_g2t_pythia("g2t_pythia",1); // prepare an empty g2t_pythia
1277  AddData(g2t_pythia);
1278  LOG_INFO << "Pythia event header captured" << endm;
1279  /*iRes =*/ g2t_get_pythia(g2t_pythia);
1280  }
1281 
1282  // --max-- Filling the event header, addition due to the new coding
1283  // if (m_Mode%10 != 1) {
1284  if (! IAttr("Don'tTouchTimeStamp") ) {
1285  if(fEvtHddr) {
1286  fEvtHddr->SetAEast((*g2t_event)[0].n_wounded_east);
1287  fEvtHddr->SetAWest((*g2t_event)[0].n_wounded_west);
1288  }
1289  }
1290  //---------------------- inner part -------------------------//
1291 
1292  // Silicon vertex tracker
1293  AddHits<St_g2t_svt_hit>( "SVTH", {"SVTD"} , "g2t_svt_hit", g2t_svt );
1294 
1295  // Heavy flavor tracker
1296  AddHits<St_g2t_ssd_hit>( "SISH", {"SFSD"} , "g2t_ssd_hit", g2t_ssd );
1297  AddHits<St_g2t_pix_hit>( "PIXH", {"PLAC"} , "g2t_pix_hit", g2t_pix );
1298  AddHits<St_g2t_ist_hit>( "ISTH", {"IBSS"} , "g2t_ist_hit", g2t_ist );
1299 
1300  // Legacy RnD detectors
1301  AddHits<St_g2t_hpd_hit>( "HPDH", {"YPLA"} , "g2t_hpd_hit", g2t_hpd );
1302  AddHits<St_g2t_gem_hit>( "GEMH", {"GMDI"} , "g2t_gem_hit", g2t_gem );
1303  AddHits<St_g2t_igt_hit>( "IGTH", {"IGAL"} , "g2t_igt_hit", g2t_igt );
1304 //AddHits<St_g2t_fst_hit>( "FSTH", {"FDSW"} , "g2t_fst_hit", g2t_fst );
1305 
1306  // Forward GEM tracker
1307  AddHits<St_g2t_fgt_hit>( "FGTH", {"FGZC","FGZD","FZCB"}, "g2t_fgt_hit", g2t_fgt );
1308 
1309  // TPC pse
1310  AddHits<St_g2t_tpc_hit>( "TPCH", {"TPAD"} , "g2t_tpc_hit", g2t_tpc );
1311  AddHits<St_g2t_mwc_hit>( "TPCH", {"TMSE"} , "g2t_mwc_hit", g2t_mwc );
1312 
1313  // FTPC
1314  AddHits<St_g2t_ftp_hit>( "FTPH", {"FSEC"} , "g2t_ftp_hit", g2t_ftp );
1315 
1316  // BTOF
1317  AddHits<St_g2t_ctf_hit>( "BTOH", {"BXSA"} , "g2t_ctb_hit", g2t_ctb );
1318  AddHits<St_g2t_ctf_hit>( "BTOH", {"BCSB"} , "g2t_tof_hit", g2t_tof );
1319  AddHits<St_g2t_ctf_hit>( "BTOH", {"BRSG"} , "g2t_tfr_hit", g2t_tfr );
1320 
1321  // Endcap TOF
1322  AddHits<St_g2t_ctf_hit>( "ETOH", {"ECEL"}, "g2t_eto_hit", g2t_eto );
1323 
1324  // Ancient RICH
1325  AddHits<St_g2t_rch_hit>( "RICH", {"RGAP","RSCI","FREO","QUAR"}, "g2t_rch_hit", g2t_rch );
1326 
1327  // Barrel Calorimeter
1328  AddHits<St_g2t_emc_hit>( "CALH", {"CSUP"}, "g2t_emc_hit", g2t_emc );
1329  AddHits<St_g2t_emc_hit>( "CALH", {"CSDA"}, "g2t_smd_hit", g2t_smd );
1330 
1331  // Endcap Calorimeter
1332  AddHits<St_g2t_emc_hit>( "ECAH",{"ESCI","ELGR", "EPCT" },"g2t_eem_hit", g2t_eem );
1333  AddHits<St_g2t_emc_hit>( "ECAH",{"EXSE","EHMS" },"g2t_esm_hit", g2t_esm );
1334 
1335  // Vertex Position Detector
1336  AddHits<St_g2t_vpd_hit>( "VPDH", {"VRAD"}, "g2t_vpd_hit", g2t_vpd );
1337 
1338  // Photon Multiplicity Detector
1339  AddHits<St_g2t_pmd_hit>( "PHMH", {"PDGS"} , "g2t_pmd_hit", g2t_pmd );
1340 
1341  // Zero degree calorimeter
1342  AddHits<St_g2t_emc_hit>( "ZCAH", {"QSCI"} , "g2t_zdc_hit", g2t_zdc );
1343 
1344  // Beam beam counters
1345  AddHits<St_g2t_ctf_hit>( "BBCH", {"BPOL"} , "g2t_bbc_hit", g2t_bbc );
1346 
1347  // FPD/FPD++/FMS
1348  AddHits<St_g2t_emc_hit>( "FPDH", {"FLGR","FLXF","FPSC","FOSC"}, "g2t_fpd_hit", g2t_fpd );
1349 
1350  // RnD calorimenter
1351  AddHits<St_g2t_emc_hit>( "FSCH", {"FSCT"} , "g2t_fsc_hit", g2t_fsc );
1352 
1353  // Muon tagging detector
1354  AddHits<St_g2t_mtd_hit>( "MUTH",{"MIGG","MTTT", "MTTF" },"g2t_mtd_hit", g2t_mtd );
1355 
1356  // Endcap trd
1357  AddHits<St_g2t_etr_hit>( "EIDH", {"TABD"} , "g2t_etr_hit", g2t_etr );
1358 
1359  // Legacy RnD Forward Hadron calorimeter [deprecated]
1360 //AddHits<St_g2t_emc_hit>( "HCAH", {"HCEL","HCES","FPSC","BBCF","BBCB","LEDG","HSTP"} , "g2t_hca_hit", g2t_hca );
1361 
1362  // Forward tracker
1363  AddHits<St_g2t_fts_hit>( "FTSH",{"FTSA","FSIA", "FSIB", "FSIC"}, "g2t_fts_hit", g2t_fts );
1364 
1365  AddHits<St_g2t_fts_hit>( "FSTH",{"FTOS","FTIS","FTUS"}, "g2t_fsi_hit", g2t_fts );
1366  AddHits<St_g2t_fts_hit>( "STGH",{"STGP","STGL","STGS"}, "g2t_stg_hit", g2t_stg );
1367  AddHits<St_g2t_emc_hit>( "WCAH",{"WSCI"}, "g2t_wca_hit", g2t_wca );
1368  AddHits<St_g2t_hca_hit>( "HCAH",{"HSCI"}, "g2t_hca_hit", g2t_hca );
1369  AddHits<St_g2t_emc_hit>( "PREH",{"PSCI"}, "g2t_pre_hit", g2t_pre );
1370 
1371 
1372  // Event plane detector
1373  AddHits<St_g2t_epd_hit>( "EPDH", {"EPDT"} , "g2t_epd_hit", g2t_epd );
1374 
1375  if (cflag->ieorun) return kStEOF;
1376  if (cflag->ieotri) return kStErr;
1377 
1378  if (IAttr("flux")) {
1379  static TH1D *Vx = 0, *Vy = 0, *Vz = 0;
1380  static TH2D *BbcC = 0;
1381  if (! Vx) {
1382  if (GetChain()->GetTFile()) GetChain()->GetTFile()->cd();
1383  Vx = new TH1D("Vx","Geant primary vertex X",50,-5.0,5.0);
1384  Vy = new TH1D("Vy","Geant primary vertex Y",50,-5.0,5.0);
1385  Vz = new TH1D("Vz","Geant primary vertex Z",50,-100,100);
1386  }
1387  St_g2t_vertex *geantVertex=(St_g2t_vertex *) GetDataSet("g2t_vertex");
1388  g2t_vertex_st *gvt=geantVertex->GetTable();
1389  Vx->Fill(gvt->ge_x[0]);
1390  Vy->Fill(gvt->ge_x[1]);
1391  Vz->Fill(gvt->ge_x[2]);
1392  if (! BbcC) {
1393  BbcC = new TH2D("BbcC","BBC East versus BBC West",100,-1,9,100,-1,9);
1394  }
1395  Double_t BbcW = 0, BbcE = 0;
1396  St_g2t_ctf_hit *g2t_bbc_hit = (St_g2t_ctf_hit *) GetDataSet("g2t_bbc_hit");
1397  int N = g2t_bbc_hit->GetNRows();
1398  g2t_ctf_hit_st *bbc = g2t_bbc_hit->GetTable();
1399  for (int i = 0; i < N; i++, bbc++) {
1400  if (bbc->tof > 100e-9) continue;
1401  if (bbc->volume_id < 2000) BbcW++;
1402  else BbcE++;
1403  }
1404  if (BbcW <= 0) BbcW = 0.1;
1405  if (BbcE <= 0) BbcE = 0.1;
1406  BbcC->Fill(TMath::Log10(BbcW),TMath::Log10(BbcE));
1407  }
1408 
1409  return kStOK;
1410 }
1411 //_____________________________________________________________________________
1413  LOG_QA << "St_geant_Maker summary -QA- total number of active volumes with hits: " << mHitCounts.size() << endm;
1414  LOG_QA << "St_geant_Maker summary -QA- list of volumes with hits: " << endm;
1415  for ( auto i : mHitCounts ) {
1416  LOG_QA << "St_geant_Maker summary -QA- g2t hits (" << i.first.c_str() << ") nhits = " << i.second << endm;
1417  }
1418  LOG_QA << "St_geant_Maker summary -QA- energy deposition by container:" << endm;
1419  for ( auto i : mHitSum ) {
1420  LOG_QA << "St_geant_Maker summary -QA- g2t Esum (" << i.first.c_str() << ") Esum = " << i.second << endm;
1421  }
1422 
1423  return kStOK;
1424 }
1425 //_____________________________________________________________________________
1426 void St_geant_Maker::LoadGeometry(const Char_t *option){
1427 #if 0
1428  if (strlen(option)) Do (option);
1429  Geometry();
1430  Do("gclose all");
1431  Agstroot();
1432 #else
1433  mInitialization = option;
1434 #endif
1435 }
1436 //_____________________________________________________________________________
1437 void St_geant_Maker::Draw(const char* opt)
1438 {
1439  int two = 2;
1440  int zero = 0;
1441  int one = 1;
1442  const char *path = " ";
1443  Dzddiv (two,zero,path,opt,one,zero,one,one);
1444 }
1445 //_____________________________________________________________________________
1446 void St_geant_Maker::Do(const Char_t *job)
1447 {
1448  int l=strlen(job);
1449  if (l) geant3->Kuexel(job);
1450 }
1451 //_____________________________________________________________________________
1452 
1453 //_____________________________________________________________________________
1454 TVolume *St_geant_Maker::MakeVolume(TString *name, int ivo, int Nlevel, int *Names, int *Numbers){
1455  TVolume *node = 0;
1456  int jvolum = clink->jvolum;
1457  int jvo = z_lq[jvolum-ivo];
1458  if (jvo) {
1459  node = (TVolume *) topnode->FindObject(name->Data());
1460  if (! node) {
1461  TShape *shape = (TShape *) gGeometry->GetListOfShapes()->FindObject(name->Data());
1462  if (!shape ) {shape = MakeShape(name,ivo);}
1463  node = new TVolume(name->Data(), name->Data(), shape);
1464  }
1465 
1466  int nin =(int) z_q[jvo+3];
1467  if (nin > 0)
1468  {
1469  Nlevel++;
1470  for (int in=1; in<= nin; in++)
1471  {
1472  int jin = z_lq[jvo-in];
1473  int ivom = (int) z_q[jin+2];
1474  int nuser = (int) z_q[jin+3];
1475  TString namem((const Char_t *) &(z_iq[jvolum+ivom]), 4);
1476 
1477  Names[Nlevel] = z_iq[jvolum+ivom];
1478  Numbers[Nlevel] = nuser;
1479  int nlevv = Nlevel+1;
1480  // int Ierr;
1481  Float_t xx[3], theta1,phi1, theta2,phi2, theta3,phi3, type;
1482 
1483  geant3->Glvolu(nlevv, Names, Numbers);
1484 
1485  Gfxzrm(Nlevel, xx[0],xx[1],xx[2],
1486  theta1,phi1, theta2,phi2, theta3,phi3, type);
1487  TVolume *newnode = (TVolume *) topnode->FindObject(namem.Data());
1488 
1489  if (!newnode)
1490  { newnode = MakeVolume(&namem, ivom, nlevv, Names, Numbers); }
1491 
1492  irot++;
1493  Char_t ss[12];
1494  sprintf(ss,"rotm%i",irot);
1495  TRotMatrix *rotm = new TRotMatrix(ss,ss,
1496  theta1,phi1, theta2,phi2, theta3,phi3);
1497  node->Add(newnode,xx[0],xx[1],xx[2],rotm);
1498  }
1499  }
1500  if (nin < 0) {
1501  Nlevel++;
1502  }
1503  if (nin == 0) {Nlevel--;}
1504  }
1505  return node;
1506 }
1507 //_____________________________________________________________________________
1508 TShape *St_geant_Maker::MakeShape(TString *name, int ivo){
1509  // make geant3 volume
1510  typedef enum {BOX=1,TRD1,TRD2,TRAP,TUBE,TUBS,CONE,CONS,SPHE,PARA,
1511  PGON,PCON,ELTU,HYPE,GTRA=28,CTUB} shapes;
1512  int jvolum = clink->jvolum;
1513  int jvo = z_lq[jvolum-ivo];
1514  TShape* t;
1515  shapes shape = (shapes) z_q[jvo+2];
1516  int numed = (int) z_q[jvo+4];
1517  int npar = (int) z_q[jvo+5];
1518  params *p = (params *)&z_q[jvo+7];
1519  attributes *att = (attributes *)(&z_q[jvo+7] + npar);
1520  int jtmed = clink->jtmed;
1521  int jtm = z_lq[jtmed-numed];
1522  int nmat = (int)z_q[jtm+6];
1523  int jmate = clink->jmate;
1524  int jma = z_lq[jmate-nmat];
1525  int nmixt = (int) z_q[jma+11];
1526  int nm = TMath::Abs(nmixt);
1527 
1528  Char_t astring[20];
1529  if (nm <= 1) sprintf (astring,"mat%i",nmat);
1530  else sprintf (astring,"mix%i",nmat);
1531 
1532  TString Astring(astring);
1533  t = (TShape *) gGeometry->GetListOfShapes()->FindObject(name->Data());
1534  if (!t) {
1535  switch (shape) {
1536  case BOX: t = new TBRIK((Char_t *) name->Data(),"BRIK",(Char_t *) Astring.Data(),
1537  p->par[0],p->par[1],p->par[2]);
1538  break;
1539  case TRD1: t = new TTRD1((Char_t *) name->Data(),"TRD1",(Char_t *) Astring.Data(),
1540  p->par[0],p->par[1],p->par[2],p->par[3]);
1541  break;
1542  case TRD2: t = new TTRD2((Char_t *) name->Data(),"TRD2",(Char_t *) Astring.Data(),
1543  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4]);
1544  break;
1545  case TRAP: t = new TTRAP((Char_t *) name->Data(),"TRAP",(Char_t *) Astring.Data(),
1546  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4],
1547  p->par[5],p->par[6],p->par[7],p->par[8],p->par[9],
1548  p->par[10]);
1549  break;
1550  case TUBE: t = new TTUBE((Char_t *) name->Data(),"TUBE",(Char_t *) Astring.Data(),
1551  p->par[0],p->par[1],p->par[2]);
1552  break;
1553  case TUBS: t = new TTUBS((Char_t *) name->Data(),"TUBS",(Char_t *) Astring.Data(),
1554  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4]);
1555  break;
1556  case CONE: t = new TCONE((Char_t *) name->Data(),"CONE",(Char_t *) Astring.Data(),
1557  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4]);
1558  break;
1559  case CONS: t = new TCONS((Char_t *) name->Data(),"CONS",(Char_t *) Astring.Data(),
1560  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4],
1561  p->par[5],p->par[6]);
1562  break;
1563  case SPHE: t = new TSPHE((Char_t *) name->Data(),"SPHE",(Char_t *) Astring.Data(),
1564  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4],
1565  p->par[5]);
1566  break;
1567  case PARA: t = new TPARA((Char_t *) name->Data(),"PARA",(Char_t *) Astring.Data(),
1568  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4],
1569  p->par[5]);
1570  break;
1571  case PGON: t = new TPGON((Char_t *) name->Data(),"PGON",(Char_t *) Astring.Data(),
1572  p->par[0],p->par[1],(int)p->par[2],(int)p->par[3]);
1573  break;
1574  case PCON: t = new TPCON((Char_t *) name->Data(),"PCON",(Char_t *) Astring.Data(),
1575  p->par[0],p->par[1],(int)p->par[2]);
1576  break;
1577  case ELTU: t = new TELTU((Char_t *) name->Data(),"ELTU",(Char_t *) Astring.Data(),
1578  p->par[0],p->par[1],p->par[2]);
1579  break;
1580  // case HYPE: t = new THYPE((Char_t *) name->Data(),"HYPE",(Char_t *) Astring.Data(),
1581  // p->par[0],p->par[1],p->par[2],p->par[3]);
1582  // break;
1583  case GTRA: t = new TGTRA((Char_t *) name->Data(),"GTRA",(Char_t *) Astring.Data(),
1584  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4],
1585  p->par[5],p->par[6],p->par[7],p->par[8],p->par[9],
1586  p->par[10],p->par[11]);
1587  break;
1588  case CTUB: t = new TCTUB((Char_t *) name->Data(),"CTUB",(Char_t *) Astring.Data(),
1589  p->par[0],p->par[1],p->par[2],p->par[3],p->par[4],
1590  p->par[5],p->par[6],p->par[7],p->par[8],p->par[9],
1591  p->par[10]);
1592  break;
1593  // default: t = new TBRIK((Char_t *) name->Data(),"BRIK",(Char_t *) Astring.Data(),
1594  // p->par[0],p->par[1],p->par[2]);
1595  // break;
1596 
1597  default: assert(0);
1598 
1599  }
1600  if (att->lseen != 1) t->SetVisibility((int)att->lseen);
1601  if (att->lstyle != 1) t->SetLineStyle ((int)att->lstyle);
1602  if (att->lwidth != 1) t->SetLineWidth ((int)att->lwidth);
1603  if (att->lcolor != 1) t->SetLineColor ((int)att->lcolor);
1604  if (att->lfill != 1) t->SetFillStyle ((int)att->lfill);
1605  }
1606  return t;
1607 }
1608 //_____________________________________________________________________________
1609 void St_geant_Maker::Call(const Char_t *name)
1610 {
1611  int narg = 0;
1612  addrfun *address = (addrfun *) csaddr_((Char_t *)name, strlen(name));
1613  if (address) csjcal_(address, &narg);
1614 }
1615 //_____________________________________________________________________________
1616 void St_geant_Maker::ClearRootGeoms()
1617 {
1618  // Move the becoming obsolete ROOT representations if any
1619  if (fVolume) {
1620  TDataSet *dataSet = FindByName(".data");
1621  fVolume->Shunt(dataSet);
1622  fVolume = 0;
1623  }
1624  if (fTopGeoVolume) {
1625  LOG_ERROR << "Fix me we !!!. Seg fault danger !!!" <<endm;
1626  delete fTopGeoVolume;
1627  fTopGeoVolume = 0;
1628  }
1629 
1630 }
1631 //_____________________________________________________________________________
1632 TDataSet *St_geant_Maker::Work()
1633 {
1634  if (mInitialization != "") {
1635  InitRun(-1);
1636  }
1637  struct Medium
1638  { Char_t name[20]; int nmat, isvol, ifield; Float_t fieldm; };
1639  struct Volume
1640  { Char_t name[4],nick[4]; int npar; Float_t par[50]; };
1641  char matName[24];
1642  // int node = 0;
1643  // TVolume *volume=0;
1644  TVolume *node=0;
1645 
1646  Float_t *volu=0, *position=0, *mother=0, *p=0;
1647  int who=0, copy=0, npar=0;
1648  int nvol=cnum->nvolum;
1649  Float_t theta1,phi1, theta2,phi2, theta3,phi3, type;
1650  TObjArray nodes(nvol+1);
1651 
1652  if (!gGeometry) new TGeometry("STAR","nash STAR");
1653  GtHash *H = new GtHash;
1654 
1655  printf(" looping on agvolume \n");
1656  // ===============================================================
1657  // while(agvolume(node,volu,position,mother,who,copy,p,npar)) {
1658  // while(agvolume(&node,&volu,&position,&mother,&who,&copy,&p,&npar)) {
1659  while (Agvolume(node,volu,position,mother,who,copy,p,npar,matName))
1660  { // ===============================================================
1661 
1662  typedef enum {BOX=1,TRD1,TRD2,TRAP,TUBE,TUBS,CONE,CONS,SPHE,PARA,
1663  PGON,PCON,ELTU,HYPE,GTRA=28,CTUB} shapes;
1664  TShape* t;
1665  shapes shape = (shapes) volu[1];
1666  //int nin = 0;
1667  // int medium = (int) volu[3];
1668  int np = (int) volu[4];
1669  Float_t* p0 = volu+6;
1670  Float_t* att = p0+np;
1671  Char_t name[] = {0,0,0,0,0};
1672  Char_t nick[] = {0,0,0,0,0};
1673  float xx[3] = {0.,0.,0.};
1674  TVolume *newVolume = 0;
1675  //if (mother) nin = (int) mother[2];
1676  TVolume *Hp = 0;
1677 
1678  strncpy(nick,(const Char_t*)&cvolu->names[cvolu->nlevel-1],4);
1679  strncpy(name,(const Char_t*)(volu-5),4);
1680 
1681  Hp = (TVolume *) H->GetPointer(p,npar+1);
1682  if (Hp) newVolume = Hp;
1683  else
1684  { // printf(" creating object %s %f %f %f %s \n", name,p[0],p[1],p[2], );
1685  switch (shape)
1686  { case BOX: t=new TBRIK(nick,"BRIK",matName,
1687  p[0],p[1],p[2]); break;
1688  case TRD1: t=new TTRD1(nick,"TRD1",matName,
1689  p[0],p[1],p[2],p[3]); break;
1690  case TRD2: t=new TTRD2(nick,"TRD2",matName,
1691  p[0],p[1],p[2],p[3],p[4]); break;
1692  case TRAP: t=new TTRAP(nick,"TRAP",matName,
1693  p[0],p[1],p[2],p[3],p[4],p[5],
1694  p[6],p[7],p[8],p[9],p[10]); break;
1695  case TUBE: t=new TTUBE(nick,"TUBE",matName,
1696  p[0],p[1],p[2]); break;
1697  case TUBS: t=new TTUBS(nick,"TUBS",matName,
1698  p[0],p[1],p[2],p[3],p[4]); break;
1699  case CONE: t=new TCONE(nick,"CONE",matName,
1700  p[0],p[1],p[2],p[3],p[4]); break;
1701  case CONS: t=new TCONS(nick,"CONS",matName, // take care !
1702  p[0],p[1],p[2],p[3],p[4],p[5],p[6]); break;
1703  // p[1],p[2],p[3],p[4],p[0],p[5],p[6]); break;
1704  case SPHE: t=new TSPHE(nick,"SPHE",matName,
1705  p[0],p[1],p[2],p[3],p[4],p[5]); break;
1706  case PARA: t=new TPARA(nick,"PARA",matName,
1707  p[0],p[1],p[2],p[3],p[4],p[5]); break;
1708  case PGON: t=new TPGON(nick,"PGON",matName,p[0],p[1],(int)p[2],(int)p[3]);
1709  { Float_t *pp = p+4;
1710  for (int i=0; i<p[3]; i++) {
1711  Float_t z = *pp++;
1712  Float_t rmin = *pp++;
1713  Float_t rmax = *pp++;
1714  ((TPCON *)t)->DefineSection(i,z,rmin,rmax);
1715  // this is because of a compiler bug on Linux (VF 030699)
1716  // (( TPGON*)t)->DefineSection(i,*pp++,*pp++,*pp++);
1717  }
1718  } break;
1719  case PCON: t=new TPCON(nick,"PCON",matName,p[0],p[1],(int)p[2]);
1720  { Float_t *pp = p+3;
1721  for (int i=0; i<p[2]; i++) {
1722  Float_t z = *pp++;
1723  Float_t rmin = *pp++;
1724  Float_t rmax = *pp++;
1725  ((TPCON *)t)->DefineSection(i,z,rmin,rmax);
1726  // this is because of a compiler bug on Linux (VF 030699)
1727  // ((TPCON *)t)->DefineSection(i,*pp++,*pp++,*pp++);
1728  }
1729  } break;
1730  case ELTU: t=new TELTU(nick,"ELTU",matName,
1731  p[0],p[1],p[2]); break;
1732  // case HYPE: t=new THYPE(nick,"HYPE",matName,
1733  // p[0],p[1],p[2],p[3]); break;
1734  case GTRA: t=new TGTRA(nick,"GTRA",matName,
1735  p[0],p[1],p[2],p[3],p[4],p[5],
1736  p[6],p[7],p[8],p[9],p[10],p[11]); break;
1737  case CTUB: t=new TCTUB(nick,"CTUB",matName,
1738  p[0],p[1],p[2],p[3],p[4],p[5],
1739  p[6],p[7],p[8],p[9],p[10]); break;
1740  default: t=new TBRIK(nick,"BRIK",matName,
1741  p[0],p[1],p[2]); break;
1742  };
1743  t->SetLineColor((int)att[4]);
1744 
1745  // to build a compressed tree, name should be checked for repetition
1746  std::string nickMat = Form("%s(%s)", nick,matName);
1747  newVolume = new TVolume(name,nickMat.c_str(),t);
1748  // newVolume -> SetVisibility(ENodeSEEN(MapGEANT2StNodeVis(att[1])));
1749  newVolume -> SetVisibility((TVolume::ENodeSEEN)TVolume::MapGEANT2StNodeVis((int)att[1]));
1750  H->SetPointer(newVolume);
1751  }
1752 
1753  if (node)
1754  { Gfxzrm(nlev, xx[0],xx[1],xx[2], theta1,phi1,
1755  theta2,phi2, theta3,phi3, type);
1756  TRotMatrix *matrix=GetMatrix(theta1,phi1,theta2,phi2,theta3,phi3);
1757  node->Add(newVolume,xx[0],xx[1],xx[2],matrix,UInt_t(copy));
1758  }
1759  // volume = newVolume;
1760  node = newVolume;
1761  };
1762 
1763  // fVolume=volume;
1764  // gGeometry->GetListOfNodes()->Add(volume);
1765  delete H;
1766  fVolume=node;
1767  if ( gGeometry ) gGeometry->GetListOfNodes()->Add(node);
1768  return GetVolume();
1769 }
1770 //_____________________________________________________________________________
1771 void St_geant_Maker::Mark(TVolume *topvol) {
1772  int JSET = clink->jset;
1773  if (JSET <= 0) return;
1774  int NSET=z_iq[JSET-1];
1775  Char_t Uset[5], Udet[5], Uvol[5];
1776  memset (Uset, 0, 5);
1777  memset (Udet, 0, 5);
1778  memset (Uvol, 0, 5);
1779  for (int ISET=1;ISET<=NSET;ISET++) {
1780  int JS=z_lq[JSET-ISET];
1781  if (JS <= 0) continue;
1782  int NDET=z_iq[JS-1];
1783  memcpy (Uset, &z_iq[JSET+ISET], 4);
1784  for (int IDET=1;IDET<=NDET;IDET++) {
1785  int JD=z_lq[JS-IDET];
1786  if (JD <=0) continue;
1787  int NV=z_iq[JD+2];
1788  int NWHI=z_iq[JD+7];
1789  int NWDI=z_iq[JD+8];
1790  memcpy (Udet, &z_iq[JS+IDET], 4);
1791  LOG_INFO << " Set " << Uset << " Detector " << Udet
1792  << " NV " << NV << " NWHI " << NWHI << " NWDI " << NWDI << endm;
1793  int JDU = z_lq[JD-3];
1794  if (JDU > 0) {
1795  int i1 = (int)z_q[JDU+3], i2 = (int)z_q[JDU+5];
1796  LOG_INFO << " Volume/Bits :" << i1 << "/" << i2 << endm;
1797  for (int i=i1;i<i2;i += 3) {
1798  int j = JDU+i;
1799  int iv = (int)z_q[j+1];
1800  int Nmx = (int)z_q[j+2];
1801  int Nam = (int)z_iq[clink->jvolum+iv];
1802  int Nb = (int)z_q[j+3];
1803  memcpy (Uvol, &Nam, 4);
1804  LOG_INFO << "\t" << Uvol << "\t" << Nmx << "\t" << Nb << endm;
1805  }
1806  }
1807  else {
1808  if (NV > 0) {
1809  LOG_INFO << " Volume/Bits ";
1810  for (int I=1; I<=NV; I++) {
1811  memcpy (Uvol, &z_iq[JD+2*I+9], 4);
1812  LOG_INFO << "\t" << Uvol << "/\t" << z_iq[JD+2*I+10];
1813  }
1814  LOG_INFO << endm;
1815  }
1816  }
1817  }
1818  }
1819 #if 0
1820  geant3->Gfinds();
1821  if (csets->iset && csets->idet) {
1822  LOG_INFO << "Set/Det \t" << csets->iset << "/" << csets->idet
1823  << "\tidtype = \t" << csets->idtype
1824  << "\tnvname = \t" << csets->nvname << endm;
1825  int nLev, lNam[15], lNum[15];
1826  Char_t Name[4];
1827  geant3->Gfpath(csets->iset,csets->idet,csets->numbv, nLev, lNam, lNum);
1828  int four = 4;
1829  for (int i=0; i< nLev; i++) {
1830  uhtoc(lNam[i],four,PASSCHARD(Name),four PASSCHARL(Name));
1831  LOG_INFO << "\t" << Name << "\t" << lNum[i];
1832  }
1833  LOG_INFO << endm;
1834  }
1835 #endif
1836 }
1837 //_____________________________________________________________________________
1838 static Bool_t CompareMatrix(TRotMatrix &a,TRotMatrix &b)
1839 { double *pa=a.GetMatrix(); double *pb=b.GetMatrix();
1840  for (int i=0; i<9; i++) if (pa[i]!=pb[i]) return kFALSE;
1841  return kTRUE;
1842 }
1843 //_____________________________________________________________________________
1844 TRotMatrix *St_geant_Maker::GetMatrix(float thet1, float phii1,
1845  float thet2, float phii2,
1846  float thet3, float phii3)
1847 { char mname[20];
1848  THashList *list = gGeometry->GetListOfMatrices();
1849  int n=list->GetSize(); sprintf(mname,"matrix%d",n+1);
1850  TRotMatrix *pattern=new TRotMatrix(mname,mname,
1851  thet1,phii1,thet2,phii2,thet3,phii3);
1852 
1853  TRotMatrix *matrix=0; TIter nextmatrix(list);
1854  while ((matrix=(TRotMatrix *) nextmatrix()))
1855  { if (matrix!=pattern)
1856  { if (CompareMatrix(*matrix,*pattern))
1857  { list->Remove(pattern); delete pattern; return matrix; }
1858  } }
1859  return pattern;
1860 }
1861 //_____________________________________________________________________________
1862 TString St_geant_Maker::GetVolumeSrcFile(const char *volumeName) const
1863 {
1864  // Find the source code defining the "volumeName" GEANT volume
1865  TDataSet *found = 0;
1866  TString vName = volumeName;
1867  vName.ToUpper();
1868  if (fVolume && volumeName && volumeName[0]) {
1869  const TDataSet *myVolume = fVolume->FindByName(vName.Data());
1870  TFileSet *geoSrc = dynamic_cast<TFileSet*>(GetDataSet("GeometryDirectory"));
1871  if (geoSrc && myVolume ) {
1872  do {
1873  // construct the source code pattern
1874  TString pattern = myVolume->GetName();
1875  pattern.ToLower();
1876  pattern += "geo.g";
1877  found = geoSrc->FindByName(pattern.Data());
1878  } while (!found && (myVolume = myVolume->GetParent()) );
1879  }
1880  if (found) {
1881  // make the path up
1882  TString path = found->Path();
1883  Ssiz_t pos = path.Index("/geometry/");
1884  TString topDir = geoSrc->GetTitle();
1885  path.Replace(0,pos,topDir);
1886  return path;
1887  }
1888  }
1889  return "";
1890 }
1891 //_____________________________________________________________________________
1892 int St_geant_Maker::SetInputFile(const char *file)
1893 {
1894  fInputFile = file;
1895  return kStOK;
1896 }
1897 //_____________________________________________________________________________
1898 int St_geant_Maker::Skip(int Nskip)
1899 {
1900  if (Nskip >= 0) {
1901  Char_t kuip[20];
1902  sprintf (kuip,"trig %i",Nskip);
1903  if (GetDebug()) printf("St_geant_Maker skip %i\n record(s)",Nskip);
1904  Do((const char*)kuip);
1905 
1906  if (cquest->iquest[0]) {return kStEOF;}
1907  }
1908  return kStOK;
1909 }
1910 //_____________________________________________________________________________
1911 void type_of_call rootmaptable_(const Char_t* cdest,const Char_t* table , const Char_t* spec,
1912  int &k, Char_t *iq,
1913  const int lCdest,const int lTable, const int lSpec)
1914 {
1915  Char_t *Cdest = new char[(lCdest+1)]; strncpy(Cdest,cdest,lCdest); Cdest[lCdest] = 0;
1916  Char_t *Table = new char[(lTable+1)]; strncpy(Table,table,lTable); Table[lTable] = 0;
1917  Char_t *Spec = new char[(lSpec+1)]; strncpy(Spec,spec,lSpec); Spec[lSpec] = 0;
1918  St_geant_Maker::RootMapTable(Cdest,Table,Spec, k, iq);
1919  delete [] Cdest;
1920  delete [] Table;
1921  delete [] Spec;
1922 }
1923 //_____________________________________________________________________________
1924 void St_geant_Maker::RootMapTable(Char_t *Cdest,Char_t *Table, Char_t* Spec,
1925  int &k, Char_t *iq)
1926 {
1927  TString TableName(Table);
1928  TString t = TableName.Strip();
1929  t.ToLower();
1930 
1931  // Use St_Table::New(...) when it is available as follows:
1932  St_Table *table = St_Table::New(t.Data(),t.Data(),iq,k);
1933 #ifndef __CINT__
1934 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,05,04)
1935  if (table) {fgGeom->Add(table); table->SetBit(TTable::kIsNotOwn);}
1936 #else
1937  if (table) {fgGeom->Add(table); table->SetBit(kIsNotOwn);}
1938 #endif
1939 #endif
1940  if (fgGeantMk->Debug() > 1) {
1941  if (table) {
1942  int N = table->GetNRows();
1943  if (N > 10) N = 10; table->Print(0,N);
1944  }
1945  else LOG_DEBUG << "St_geant_Maker::Dictionary for table :" << t.Data()
1946  << " has not been defined yet. Skip it"
1947  << endm;
1948  }
1949 }
1950 //_____________________________________________________________________________
1951 int St_geant_Maker::G2t_volume_id(const Char_t *name, int *numbv){
1952  return g2t_volume_id(PASSCHARD(name),numbv PASSCHARL(name));
1953 }
1954 //_____________________________________________________________________________
1955 int St_geant_Maker::Agvolume(TVolume *&node, Float_t *&par, Float_t *&pos
1956  ,Float_t *&mot, int &who, int &copy
1957  ,Float_t *&par1, int &npar, char matName[24])
1958 {
1959  uint64_t myNode = (uint64_t)node;
1960  uint64_t myPar=0,myPos=0,myMot=0,myPar1=0;
1961  int ans = agvolume(myNode,myPar,myPos,myMot,who,copy,myPar1,npar,(int*)matName);
1962  node = (TVolume *)myNode;
1963  par = (float*)myPar;
1964  pos = (float*)myPos;
1965  mot = (float*)myMot;
1966  par1 = (float*)myPar1;
1967 
1968  matName[20]=0; char *cc = strstr(matName," "); if (cc) *cc=0;
1969  return ans;
1970 
1971 }
1972 
1973 //_____________________________________________________________________________
1974 void St_geant_Maker::Agnzgete (int &ILK,int &IDE,
1975  int &NPART,int &IRUN,int &IEVT,const Char_t *CGNAM,
1976  Float_t *VERT,int &IWTFL,Float_t &WEIGH){
1977  agnzgete (ILK,IDE,NPART,IRUN,IEVT,PASSCHARD(CGNAM),VERT,IWTFL,WEIGH
1978  PASSCHARL(CGNAM));
1979 }
1980 //______________________________________________________________________________
1981 void St_geant_Maker::Geometry() {
1982  // Move the becoming obsolete ROOT representations if any
1983  ClearRootGeoms();
1984  if (Remake()) {
1985  LOG_WARN << "The local version of the <libgeometry.so> shared library is to be re-built" << endm;
1986  gSystem->Exec("cons +geometry");
1987  LOG_WARN << "The local version of the <libgeometry.so> shared library has been re-built" << endm;
1988  LOG_WARN << "One has to re-load Geometry browser to see the new geometry" << endm;
1989  LOG_WARN << "Ask Pavel Nevski, \"Why?\"" << endm;
1990 // Do("make geometry");
1991  SetRemake(kFALSE);
1992  } else {
1993  geometry();
1994  }
1995 }
1996 //______________________________________________________________________________
1997 int St_geant_Maker::Agstroot() {
1998 //VP not used AgstHits();
1999  return agstroot();
2000 }
2001 //_____________________________________________________________________________
2002 void St_geant_Maker::Gfxzrm(int & Nlevel,
2003  Float_t &x, Float_t &y, Float_t &z,
2004  Float_t &Theta1, Float_t & Phi1,
2005  Float_t &Theta2, Float_t & Phi2,
2006  Float_t &Theta3, Float_t & Phi3,
2007  Float_t &Type){
2008  gfxzrm(Nlevel, x, y, z,
2009  Theta1, Phi1,
2010  Theta2, Phi2,
2011  Theta3, Phi3, Type);
2012 }
2013 //_____________________________________________________________________________
2014 void St_geant_Maker::Dzddiv(int& idiv ,int &Ldummy,const Char_t* path,const Char_t* opt,
2015  int& one,int &two,int &three,int& iw){
2016  dzddiv (idiv,Ldummy,PASSCHARD(path),PASSCHARD(opt),
2017  one,two,three,iw PASSCHARL(path) PASSCHARL(opt));
2018 }
2019 //________________________________________________________________________________
2020 void St_geant_Maker::SetDateTime(int idat, int itime) {
2021  // if ( m_Mode%100 == 1 || ! fEvtHddr ) return;
2022  if (IAttr("KeepRunNumber") || ! fEvtHddr ) return;
2023  if (! m_geom_gdat) { // taken from starsim/agzio/agfinfo.age
2024  LOG_INFO << "St_geant_Maker:: geom_gdat table is missing. Try to get it from GEANT." << endm;
2025  int jrung = clink->jrung;
2026  if (jrung > 0 && z_iq[jrung-1]>=10) {
2027  int jrunh = z_lq[jrung-1];
2028  if (jrunh > 0) {
2029  int l = z_iq[jrunh-1];
2030  Char_t *buf = new Char_t[4*l+1];
2031  memcpy (buf, &z_iq[jrunh+1], 4*l);
2032  buf[4*l] = '\0';
2033  LOG_INFO << "St_geant_Maker::SetDateTime runh buffer: " << buf << endm;
2034  TString C(buf);
2035  delete [] buf;
2036  Ssiz_t begin, index;
2037  begin = index = 0;
2038  TString version;
2039  Float_t mfscale = 5;
2040  // TRegexp separator(";");
2041  while ( ( begin < C.Length()) && (index != kNPOS) ) {
2042  // index = C.Index(separator,&end, begin);
2043  index = C.Index(';',1, begin,TString::kExact);
2044  if (index > begin) {
2045  TString line(C(begin,index-begin));
2046  line.ToLower();
2047  if (Debug()) LOG_INFO << line << endm;
2048  if (line.Contains("detp")) {
2049  int indx = line.Index("year");
2050  if (indx) {
2051  int end = line.Index(" ",1,indx,TString::kExact);
2052  if (end > indx) {
2053  version = TString(line(indx,end-indx));
2054  }
2055  }
2056  indx = line.Index("field");
2057  if (indx) {
2058  int eq = line.Index("=",indx+4,TString::kExact);
2059  sscanf(line.Data()+eq+1,"%f",&mfscale);
2060  }
2061  }
2062  }
2063  begin = index + 1;
2064  }
2065  if (version.Length()) {
2066  m_geom_gdat = new St_geom_gdat("geom_gdat",1);
2067  AddRunco(m_geom_gdat);
2068  geom_gdat_st gdat;
2069  gdat.system[0] = 0;
2070  gdat.system[1] = 0;
2071  gdat.mfscale = mfscale/5.;
2072  memset (&gdat.gtag[0], 0, 8);
2073  strncpy(&gdat.gtag[0], version.Data(), 8);
2074  m_geom_gdat->AddAt(&gdat);
2075  if (Debug()) m_geom_gdat->Print(0,1);
2076  if (StarMagField::Instance()) StarMagField::Instance()->SetFactor(gdat.mfscale);
2077  }
2078  }
2079  }
2080  }
2081  if (m_geom_gdat) {
2082  geom_gdat_st *gdat = m_geom_gdat->GetTable();
2083  TString version(&gdat->gtag[0],8);
2084  version.Strip();
2085  version.ToLower();
2086  if (version != "") {
2087  int id = St_db_Maker::AliasDate(version.Data());
2088  int it = St_db_Maker::AliasTime(version.Data());
2089  if (id && GetDate() >= 20330101) {
2090  LOG_INFO << "St_geant_Maker::SetDateTime Date/Time = "
2091  << id << "/" << it << "\tas " << version << endm;
2092  fEvtHddr->SetDateTime(id,it);
2093  }
2094  }
2095  }
2096 }
2097 //________________________________________________________________________________
2098 Char_t *acfromr(Float_t r) {// 'TYPE'
2099  const Char_t *S=" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
2100  Char_t *charm = new Char_t[5];
2101  memset (&charm[0], 0, 5);
2102  int k = (int) r;
2103  for (int i = 3; i >= 0; i--) {
2104  int j = 077 & k; k = k >> 6; charm[i] = S[j];
2105  // LOG_INFO << "i\t" << i << "\tj\t" << j << "\tk\t" << k << "\t" << charm[i] << endm;
2106  }
2107  // LOG_INFO << charm << endm;
2108  return charm;
2109 }
2110 //________________________________________________________________________________
2111 int St_geant_Maker::AgstHits()
2112 {
2113  if (! geant3) return kStErr;
2114  int JSET = clink->jset;
2115  if (JSET <= 0) return kStErr;
2116  int NSET=z_iq[JSET-1];
2117  Char_t Uset[8], Udet[8], Uvol[8];
2118  memset (Uset, 0, 8);
2119  memset (Udet, 0, 8);
2120  memset (Uvol, 0, 8);
2121  TDataSet *m_Detectors = new TDataSet("Detectors"); AddConst(m_Detectors);
2122  for (int ISET=1;ISET<=NSET;ISET++) {
2123  int JS=z_lq[JSET-ISET];
2124  if (JS <= 0) continue;
2125  int NDET=z_iq[JS-1];
2126  memcpy (Uset, &z_iq[JSET+ISET], 4);
2127  TDataSet *set = new TDataSet(Uset);
2128  m_Detectors->Add(set);
2129  for (int IDET=1;IDET<=NDET;IDET++) {
2130  int JD=z_lq[JS-IDET];
2131  if (JD <=0) continue;
2132  int NV=z_iq[JD+2];
2133  int NWHI=z_iq[JD+7];
2134  int NWDI=z_iq[JD+8];
2135  memcpy (Udet, &z_iq[JS+IDET], 4);
2136  if (Debug()) {
2137  LOG_INFO << " Set " << Uset << " Detector " << Udet
2138  << " NV " << NV << " NWHI " << NWHI << " NWDI " << NWDI << endm;
2139  }
2140  int JDU = z_lq[JD-3];
2141  int ivd = 0;
2142  if (JDU > 0) {
2143  TDataSet *det = new TDataSet(Udet);
2144  set->Add(det);
2145  St_det_user *detu = new St_det_user("User",1); det->Add(detu);
2146  det_user_st rowU;
2147  int i;
2148  rowU.i0 = (int) z_q[JDU+1];
2149  rowU.N = (int) z_q[JDU+2];
2150  rowU.i1 = (int) z_q[JDU+3];
2151  rowU.Nva = (int) z_q[JDU+4];
2152  rowU.i2 = (int) z_q[JDU+5];
2153  rowU.Nvb = (int) z_q[JDU+6];
2154  rowU.Goption = (int) z_q[JDU+7];
2155  rowU.Serial = (int) z_q[JDU+8];
2156  rowU.IdType = (int) z_q[JDU+9];
2157  rowU.Iprin = (int) z_q[JDU+10];
2158  detu->AddAt(&rowU);
2159  if (Debug()) {
2160  LOG_INFO << " displacement for hit description part = 10 " << rowU.i0 << endm;
2161  LOG_INFO << " Number of all hit descriptors (both in non- and cum. parts) " << rowU.N << endm;
2162  LOG_INFO << " displacement for volume description part=10+10*Nh " << rowU.i1 << endm;
2163  LOG_INFO << " Number of all volume descriptors (branching or not) " << rowU.Nva << endm;
2164  LOG_INFO << " displacement for the free space = 10+10*Nh+3*Nv " << rowU.i2 << endm;
2165  LOG_INFO << " number of real volume branchings for NUMBV " << rowU.Nvb << endm;
2166  LOG_INFO << " Hit option: 1 - single step, 4 - Calorimetry " << rowU.Goption << endm;
2167  LOG_INFO << " Valid serial number for this subset " << rowU.Serial << endm;
2168  LOG_INFO << " USER detector number " << rowU.IdType << endm;
2169  LOG_INFO << " current print flag both for HITS and DIGI " << rowU.Iprin << endm;
2170  }
2171  St_det_path *detuV = new St_det_path("Path",rowU.Nva);
2172  St_det_hit *detuH = new St_det_hit("Hit",rowU.N);
2173  det->Add(detuV);
2174  det->Add(detuH);
2175  det_path_st rowV;
2176  det_hit_st rowH;
2177  agfdig0(Uset,Udet,strlen(Uset),strlen(Udet));
2178  float hits[15],alim[15],blim[15],bin[15];
2179  memset (&hits[0],0,15*sizeof(float));
2180  memset (&alim[0],0,15*sizeof(float));
2181  memset (&blim[0],0,15*sizeof(float));
2182  memset (&bin[0] ,0,15*sizeof(float));
2183  const char chit[60]="";
2184  agfdpar(hits[0],chit,alim[0],blim[0],bin[0],4);
2185  for (i = 0; i < rowU.N; i++) {
2186  memset(&rowH,0,detuH->GetRowSize());
2187  int j = JDU + rowU.i0 + 10*i;
2188  // int Nam = (int) z_q[j+ 1];// encoded hit name in Display code
2189  // memcpy (&rowH.hit[0], &chit[4*i], 4);
2190  Char_t *HitName = acfromr(z_q[j+ 1]);
2191  memcpy (&rowH.hit[0], HitName, 4);
2192  delete [] HitName;
2193  rowH.option = (int) z_q[j+ 2];// encoded hit option (R-rounding,S-single step)
2194  rowH.Nb = (int) z_q[j+ 3];// number of bit requested
2195  rowH.Fmin = z_q[j+ 4];// hit low limit
2196  rowH.Fmax = z_q[j+ 5];// hit upper limit
2197  rowH.Origin = z_q[j+ 6];// Geant hit origin (-Fmin)
2198  rowH.Factor = z_q[j+ 7];// Geant packing factor
2199  rowH.Nbit = (int) z_q[j+ 8];// number of bit allocated
2200  rowH.Iext = (int) z_q[j+ 9];// address of the Geant user step routine
2201  rowH.Ifun = (int) z_q[j+10];// hit function code (1-18 at present)
2202 // Case IC of ( X Y Z R RR PHI THET ETA TDR CP _
2203 // U V W ETOT ELOS BIRK STEP LGAM TOF USER _
2204 // XX YY ZZ PX PY PZ SLEN PTOT LPTO rese )
2205  if (Debug()) {
2206  if (! i)
2207  LOG_INFO << "\thit \toption \tNb \tFmin \tFmax \tOrigin \tFactor \tNbit \tIext \tIfun" << endm;
2208  LOG_INFO << "\t" << setw(4) << rowH.hit
2209  << "\t" << rowH.option
2210  << "\t" << rowH.Nb
2211  << "\t" << rowH.Fmin //<< "/" << alim[i]
2212  << "\t" << rowH.Fmax //<< "/" << blim[i]
2213  << "\t" << rowH.Origin
2214  << "\t" << rowH.Factor //<< "/" << bin[i]
2215  << "\t" << rowH.Nbit
2216  << "\t" << rowH.Iext
2217  << "\t" << rowH.Ifun
2218  << endm;
2219  }
2220  detuH->AddAt(&rowH);
2221  }
2222  if (Debug()) detuH->Print(0,rowU.N);
2223  for (i = rowU.i1; i < rowU.i2; i += 3) {
2224  memset(&rowV,0,detuV->GetRowSize());
2225  int j = JDU+i;
2226  int iv = (int) z_q[j+1];
2227  rowV.Ncopy = (int) z_q[j+2];
2228  int Nam = (int) z_iq[clink->jvolum+iv];
2229  rowV.Nb = (int) z_q[j+3];
2230  memcpy (&rowV.VName[0], &Nam, 4);
2231  Char_t Udvol[] = " ";
2232  if (rowV.Nb > 0) {
2233  int Namd = (int) z_iq[JD+2*ivd+11]; ivd++;
2234  memcpy (Udvol, &Namd, 4);
2235  }
2236  if (Debug()) {
2237  LOG_INFO << "\t" << setw(4) << rowV.VName << "/" << Udvol
2238  << "\t" << rowV.Ncopy << "\t" << rowV.Nb << endm;
2239  }
2240  detuV->AddAt(&rowV);
2241  }
2242  if (Debug()) {
2243  for (; ivd<NV; ivd++) {
2244  int Namd = (int) z_iq[JD+2*ivd+11]; ivd++;
2245  Char_t Udvol[] = " ";
2246  memcpy (Udvol, &Namd, 4);
2247  LOG_INFO << "\t" << " " << "/" << Udvol << endm;
2248  }
2249  int n = detuV->GetNRows();
2250  detuV->Print(0,n);
2251  }
2252  }
2253  }
2254  }
2255  return kStOK;
2256 }
2257 #ifdef DetectorIndex
2258 //________________________________________________________________________________
2259 void St_geant_Maker::DetSetIndex() {
2260  TString vers = mInitialization;
2261  vers.ReplaceAll("detp geometry ","");
2262  LOG_INFO << "St_geant_Maker::DetSetIndex for geometry version " << vers << endm;
2263  int JSET = clink->jset;
2264  if (JSET <= 0) return;
2265  int NSET=z_iq[JSET-1];
2266  Char_t Uset[5], Udet[5], Uvol[5];
2267  memset (Uset, 0, 5);
2268  memset (Udet, 0, 5);
2269  memset (Uvol, 0, 5);
2270  for (int ISET=1;ISET<=NSET;ISET++) {
2271  int JS=z_lq[JSET-ISET];
2272  if (JS <= 0) continue;
2273  int NDET=z_iq[JS-1];
2274  memcpy (Uset, &z_iq[JSET+ISET], 4);
2275  TString set(Uset);
2276  set.ToLower();
2277  for (int IDET=1;IDET<=NDET;IDET++) {
2278  int JD=z_lq[JS-IDET];
2279  if (JD <=0) continue;
2280  memcpy (Udet, &z_iq[JS+IDET], 4);
2281  agfdig0(Uset,Udet,strlen(Uset),strlen(Udet));
2282  int JDU = z_lq[JD-3];
2283  if (JDU > 0) {
2284  int i1 = (int) z_q[JDU+3];
2285  int i2 = (int) z_q[JDU+5];
2286  int Nva = (int) z_q[JDU+4];
2287  int Nvb = (int) z_q[JDU+6];
2288  LOG_INFO << " Set " << Uset << " Detector " << Udet << "\tNva = " << Nva << "\tNvb = " << Nvb << endm;
2289  TArrayI NVmax(Nvb);
2290  int ivv = 0;
2291  TString fmt("");
2292  for (int i = i1; i < i2; i += 3) {
2293  int j = JDU+i;
2294  int iv = (int) z_q[j+1];
2295  int Ncopy = (int) z_q[j+2];
2296  int Nam = (int) z_iq[clink->jvolum+iv];
2297  int Nb = (int) z_q[j+3];
2298  memcpy (&Uvol[0], &Nam, 4);
2299  // LOG_INFO << Uvol << " copy " << Ncopy << " bits " << Nb << endm;
2300  fmt += "/";
2301  fmt += Uvol;
2302  if (Nb <= 0) fmt += "_1";
2303  else {NVmax[ivv] = Ncopy; ivv++; fmt += "_%d";}
2304  }
2305  TString CSYS("");
2306  TString Vol(Uvol);
2307  for (int i = 0; i < NoDetectors; i++)
2308  if (TString(Detectors[i].det) == Vol && TString(Detectors[i].set) != "") {
2309  CSYS = Detectors[i].Csys;
2310  break;
2311  }
2312  if (CSYS == "") {
2313  TArrayI Ids0;
2314  DumpIndex(Uvol, vers, fmt, NVmax, Ids0);
2315  continue;
2316  }
2317  int Nelem = 1;
2318  LOG_INFO << "format: " << fmt << endm;
2319  LOG_INFO << "NVmax";
2320  for (int i = 0; i < Nvb; i++) {Nelem *= NVmax[i]; LOG_INFO << "[" << NVmax[i] << "]";}
2321  LOG_INFO << endm;
2322  int numbv[15];
2323  memset (numbv, 0, 15*sizeof(int));
2324  TArrayI Ids(Nelem);
2325  for (int elem = 0; elem < Nelem; elem++) {
2326  int e = elem;
2327  for (int i = Nvb-1; i >= 0; i--) {
2328  numbv[i] = e%NVmax[i] + 1;
2329  e = e/NVmax[i];
2330  }
2331  // int volid = G2t_volume_id(set.Data(), numbv);
2332  int volid = G2t_volume_id(CSYS.Data(), numbv);
2333  if (volid < 0) volid = 0;
2334  Ids[elem] = volid;
2335  }
2336  DumpIndex(Uvol, vers, fmt, NVmax, Ids);
2337  }
2338  }
2339  }
2340  return;
2341 }
2342 //________________________________________________________________________________
2343 void St_geant_Maker::DumpIndex(const Char_t *name, const Char_t *vers, const Char_t *fmt, TArrayI &NVmax, TArrayI &Ids) {
2344 
2345  TString fOut(name);
2346  fOut += ".";
2347  fOut += vers;
2348  fOut += ".C";
2349  ofstream out;
2350  LOG_INFO << "Create " << fOut << endm;
2351  out.open(fOut.Data());
2352  out << "TDataSet *CreateTable() {" << endl;
2353  out << " if (!gROOT->GetClass(\"StarVMCDetector\")) return 0;" << endl;
2354  int NV = NVmax.GetSize();
2355  int Nelem = Ids.GetSize();
2356  if (NV > 0) {
2357  out << " int NVmax[" << NV << "] = {";
2358  for (int i = 0; i < NV; i++) {
2359  out << NVmax[i];
2360  if (i < NV - 1) out << ",";
2361  else out << "};";
2362  }
2363  out << endl;
2364 
2365  if (Nelem > 0) {
2366  out << " int Ids[" << Nelem << "] = {" << endl;
2367  out << "\t";
2368  int nn = 20;
2369  if (Ids[0] > 0 && TMath::Log10(Ids[0]) > 7) nn = 10;
2370  int nvl = NVmax[NV-1];
2371  if (nvl > 5 && nvl < nn) nn = NVmax[NV-1];
2372  if (nn >= nvl) nvl = Nelem;
2373  int j = 0;
2374  for (int i = 0; i < Nelem; i++) {
2375  out << Ids[i];
2376  j++;
2377  if (i < Nelem - 1) {
2378  out << ",";
2379  if (j % nn == 0 || (i+1) % nvl == 0) {out << endl; out << "\t"; j = 0;}
2380  }
2381  else out << "};";
2382  }
2383  out << endl;
2384  }
2385  }
2386  out << " StarVMCDetector *Set = new StarVMCDetector(\"" << name << "\");" << endl;
2387  if (NV > 0) {
2388  out << " Set->SetNVmax(" << NV << ", NVmax);" << endl;
2389  if (Nelem > 0) out << " Set->SetIds(" << Nelem << ", Ids);" << endl;
2390  else out << " Set->SetIds();" << endl;
2391  }
2392  out << " Set->SetFMT(\"" << fmt << "\");" << endl;
2393  out << " return (TDataSet *)Set;" << endl;
2394  out << "}" << endl;
2395  out.close();
2396 }
2397 #endif
2398 //________________________________________________________________________________
2399 void dstkine() {
2400  St_geant_Maker::instance()->KinematicsFromMuDst();
2401 }
2402 //_____________________________________________________________________________
2403 int St_geant_Maker::SetDatimeFromMuDst() {
2404  KinematicsFromMuDst(1);
2405  return kStOK;
2406 }
2407 //_____________________________________________________________________________
2408 int St_geant_Maker::KinematicsFromMuDst(int flag) {
2409  TTreeIter &muDstIter = *MuDstIter;
2410  static const int*& MuEvent_mEventInfo_mRunId = muDstIter("MuEvent.mEventInfo.mRunId");
2411  static const int*& MuEvent_mEventInfo_mId = muDstIter("MuEvent.mEventInfo.mId");
2412  static const int*& MuEvent_mEventInfo_mTime = muDstIter("MuEvent.mEventInfo.mTime");
2413  static const int*& MuEvent_mEventSummary_mNumberOfTracks = muDstIter("MuEvent.mEventSummary.mNumberOfTracks");
2414  static const int& NoPrimaryVertices = muDstIter("PrimaryVertices");
2415  static const Float_t*& PrimaryVertices_mPosition_mX1 = muDstIter("PrimaryVertices.mPosition.mX1");
2416  static const Float_t*& PrimaryVertices_mPosition_mX2 = muDstIter("PrimaryVertices.mPosition.mX2");
2417  static const Float_t*& PrimaryVertices_mPosition_mX3 = muDstIter("PrimaryVertices.mPosition.mX3");
2418  static const int& NoPrimaryTracks = muDstIter("PrimaryTracks");
2419  static const int*& PrimaryTracks_mIndex2Global = muDstIter("PrimaryTracks.mIndex2Global");
2420  static const int*& PrimaryTracks_mVertexIndex = muDstIter("PrimaryTracks.mVertexIndex");
2421  static const Float_t*& PrimaryTracks_mP_mX1 = muDstIter("PrimaryTracks.mP.mX1");
2422  static const Float_t*& PrimaryTracks_mP_mX2 = muDstIter("PrimaryTracks.mP.mX2");
2423  static const Float_t*& PrimaryTracks_mP_mX3 = muDstIter("PrimaryTracks.mP.mX3");
2424  static const Short_t*& PrimaryTracks_mHelix_mQ = muDstIter("PrimaryTracks.mHelix.mQ");
2425  static const int*& PrimaryTracks_mNSigmaElectron = muDstIter("PrimaryTracks.mNSigmaElectron");
2426  static const int*& PrimaryTracks_mNSigmaPion = muDstIter("PrimaryTracks.mNSigmaPion");
2427  static const int*& PrimaryTracks_mNSigmaKaon = muDstIter("PrimaryTracks.mNSigmaKaon");
2428  static const int*& PrimaryTracks_mNSigmaProton = muDstIter("PrimaryTracks.mNSigmaProton");
2429  static const Short_t*& GlobalTracks_mFlag = muDstIter("GlobalTracks.mFlag");
2430  //#define __USE_GLOBAL__
2431 #ifdef __USE_GLOBAL__
2432  static const int& NoGlobalTracks = muDstIter("GlobalTracks");
2433  static const Float_t*& GlobalTracks_mP_mX1 = muDstIter("GlobalTracks.mP.mX1");
2434  static const Float_t*& GlobalTracks_mP_mX2 = muDstIter("GlobalTracks.mP.mX2");
2435  static const Float_t*& GlobalTracks_mP_mX3 = muDstIter("GlobalTracks.mP.mX3");
2436  static const Short_t*& GlobalTracks_mHelix_mQ = muDstIter("GlobalTracks.mHelix.mQ");
2437  static const Float_t*& GlobalTracks_mFirstPoint_mX1 = muDstIter("GlobalTracks.mFirstPoint.mX1");
2438  static const Float_t*& GlobalTracks_mFirstPoint_mX2 = muDstIter("GlobalTracks.mFirstPoint.mX2");
2439  static const Float_t*& GlobalTracks_mFirstPoint_mX3 = muDstIter("GlobalTracks.mFirstPoint.mX3");
2440  static const int*& GlobalTracks_mNSigmaElectron = muDstIter("GlobalTracks.mNSigmaElectron");
2441  static const int*& GlobalTracks_mNSigmaPion = muDstIter("GlobalTracks.mNSigmaPion");
2442  static const int*& GlobalTracks_mNSigmaKaon = muDstIter("GlobalTracks.mNSigmaKaon");
2443  static const int*& GlobalTracks_mNSigmaProton = muDstIter("GlobalTracks.mNSigmaProton");
2444 #endif
2445  static const Double_t __SIGMA_SCALE__ = 1000.;
2446  static int flagS = -1;
2447  if (flagS != 1) {
2448  flagS = flag;
2449  do {
2450  if (! MuDstIter->Next()) {return kStEOF;}
2451  int id, it;
2452  TUnixTime ut(MuEvent_mEventInfo_mTime[0]); ut.GetGTime(id,it);
2453  fEvtHddr = (StEvtHddr*)GetDataSet("EvtHddr");
2454  if (!fEvtHddr) { // Standalone run
2455  fEvtHddr = new StEvtHddr(GetConst());
2456  SetOutput(fEvtHddr); //Declare this "EvtHddr" for output
2457  }
2458  fEvtHddr->SetDateTime(id,it);
2459  fEvtHddr->SetRunNumber(MuEvent_mEventInfo_mRunId[0]);
2460  fEvtHddr->SetEventNumber(MuEvent_mEventInfo_mId[0]);
2461  if (! MuEvent_mEventSummary_mNumberOfTracks[0]) continue;
2462  break;
2463  } while (1);
2464  if (flagS == 1) return kStOK;
2465  }
2466  flagS = flag;
2467  Float_t v[3];
2468  Float_t plab[3];
2469  int nvtx;
2470  int ipart;
2471  static int pId[4][2] = {
2472  { 2, 3}, // e+, e-
2473  {11,12}, // K+, K-
2474  {14,15}, // p, pbar
2475  { 8, 9} // pi+, pi-
2476  };
2477  for (int l = 0; l < NoPrimaryVertices; l++) {
2478  v[0] = PrimaryVertices_mPosition_mX1[l];
2479  v[1] = PrimaryVertices_mPosition_mX2[l];
2480  v[2] = PrimaryVertices_mPosition_mX3[l];
2481  nvtx = geant3->Gsvert(v, 0, 0);
2482  assert(nvtx == l+1);
2483  for (int k = 0; k < NoPrimaryTracks; k++) {
2484  if (l != PrimaryTracks_mVertexIndex[k]) continue;
2485  int kg = PrimaryTracks_mIndex2Global[k];
2486  if (GlobalTracks_mFlag[kg] < 100) continue;
2487  plab[0] = PrimaryTracks_mP_mX1[k];
2488  plab[1] = PrimaryTracks_mP_mX2[k];
2489  plab[2] = PrimaryTracks_mP_mX3[k];
2490 #ifndef __MUONS__
2491  Double_t nSigma[4] = {
2492  PrimaryTracks_mNSigmaElectron[k]/__SIGMA_SCALE__,
2493  PrimaryTracks_mNSigmaKaon[k]/__SIGMA_SCALE__,
2494  PrimaryTracks_mNSigmaProton[k]/__SIGMA_SCALE__,
2495  PrimaryTracks_mNSigmaPion[k]/__SIGMA_SCALE__};
2496  int s = 0;
2497  if (PrimaryTracks_mHelix_mQ[k] < 0) s = 1;
2498  ipart = pId[3][s];
2499  Double_t nSigmaMin = 1e9;
2500  for (int i = 0; i < 4; i++) {
2501  if (TMath::Abs(nSigma[i]) < nSigmaMin) {
2502  nSigmaMin = TMath::Abs(nSigma[i]);
2503  ipart = pId[i][s];
2504  }
2505  }
2506  if (nSigmaMin > 2) ipart = pId[3][s];
2507 #else
2508  ipart = 5; // muon+
2509  if (PrimaryTracks_mHelix_mQ[k] < 0) ipart = 6; // muon-
2510 #endif
2511  geant3->Gskine(plab, ipart, nvtx);
2512  }
2513  }
2514 #ifdef __USE_GLOBAL__
2515  for (int kg = 0; kg < NoGlobalTracks; kg++) {
2516  if (GlobalTracks_mFlag[kg] < 100) continue;
2517  Double_t nSigmaMin = 1e9;
2518  Double_t nSigma[4] = {
2519  GlobalTracks_mNSigmaElectron[kg]/__SIGMA_SCALE__,
2520  GlobalTracks_mNSigmaKaon[kg]/__SIGMA_SCALE__,
2521  GlobalTracks_mNSigmaProton[kg]/__SIGMA_SCALE__,
2522  GlobalTracks_mNSigmaPion[kg]/__SIGMA_SCALE__};
2523  int s = 0;
2524  if (GlobalTracks_mHelix_mQ[kg] < 0) s = 1;
2525  for (int k = 0; k < NoPrimaryTracks; k++) {
2526  if (kg == PrimaryTracks_mIndex2Global[k]) {
2527  goto NEXTGL;
2528  }
2529  }
2530  v[0] = GlobalTracks_mFirstPoint_mX1[kg];
2531  v[1] = GlobalTracks_mFirstPoint_mX2[kg];
2532  v[2] = GlobalTracks_mFirstPoint_mX3[kg];
2533  nvtx = geant3->Gsvert(v, 0, 0);
2534  plab[0] = GlobalTracks_mP_mX1[kg];
2535  plab[1] = GlobalTracks_mP_mX2[kg];
2536  plab[2] = GlobalTracks_mP_mX3[kg];
2537  ipart = pId[3][s];
2538  for (int i = 0; i < 4; i++) {
2539  if (TMath::Abs(nSigma[i]) < nSigmaMin) {
2540  nSigmaMin = TMath::Abs(nSigma[i]);
2541  ipart = pId[i][s];
2542  }
2543  }
2544  if (nSigmaMin > 2) ipart = pId[3][s];
2545  geant3->Gskine(plab, ipart, nvtx);
2546  NEXTGL: continue;
2547  }
2548 #endif
2549  if (Debug()) {
2550  Do("gprint vert");
2551  Do("gprint kine");
2552  }
2553  return kStOK;
2554 }
2555 //________________________________________________________________________________
2556 int St_geant_Maker::ipartx(int id) {
2557  int ipartxf = -1;
2558  if (id == 1) ipartxf = 1; // gamma
2559  else if (id == 2 || id == 3) ipartxf = 2; // e+/-
2560  else if (id == 5 || id == 6) ipartxf = 3; // mu+/-
2561  else if (id == 13) ipartxf = 4; // neutron
2562  else if ((id >= 8 && id <= 9) ||
2563  (id >= 11 && id <= 15)) ipartxf = 0; // all other charged particles
2564  return ipartxf;
2565 }
2566 //________________________________________________________________________________
2567 Float_t St_geant_Maker::dose(Float_t Z) {
2568  /* *
2569  * Function : Interpolation of gamma dose rate *
2570  * *
2571  * Arguments : Z Atom number */
2572  static TGraph *graph = 0;
2573  if (! graph) {
2574  int n = 43;
2575  Double_t x[] = {11., 12., 13., 14., 15., 17., 18., 19., 20., 22.,
2576  23., 24., 25., 26., 27., 28., 29., 30., 32., 33.,
2577  34., 35., 38., 40., 41., 42., 43., 46., 47., 48.,
2578  49., 50., 51., 53., 57., 66., 73., 74., 78., 79.,
2579  80., 82., 83.}; // Z
2580  Double_t y[] = {8.8033795E-02, 0.1175197 , 0.1043398 , 8.3658338E-02,
2581  7.6843806E-02, 5.7563554E-02, 4.0977564E-02, 4.6153713E-02,
2582  4.0977564E-02, 0.1257856 , 0.1797267 , 0.1679161 ,
2583  0.1650867 , 0.1828069 , 0.1828069 , 0.1956649 ,
2584  0.2094273 , 0.1923680 , 0.1923680 , 0.2612006 ,
2585  0.2795725 , 0.3095814 , 0.4499212 , 0.6880791 ,
2586  0.7240669 , 0.6213810 , 0.5 , 0.5 ,
2587  0.5 , 0.3546627 , 0.3796084 , 0.3428115 ,
2588  0.2941946 , 0.3370352 , 0.3 , 0.2702305 ,
2589  0.2941946 , 0.2567994 , 0.3607410 , 0.3607410 ,
2590  0.3428115 , 0.3 , 0.4}; // Dose
2591  graph = new TGraph(n,x,y);
2592  }
2593  return 13.1286072899874E-6*TMath::Max(0., TMath::Min(0.5, graph->Eval(Z)));
2594 }
2595 //________________________________________________________________________________
2596 void St_geant_Maker::usflux() {
2597  int id;
2598  Float_t OmegaN;
2599  int i;
2600  Float_t ZZ, RR;
2601  int NstepB;
2602  Float_t stepF, destepF, XYZ[3];
2603  Float_t RADIUS;
2604  int p;
2605  enum {Nregions = 1, Nparts = 5, NH1T = 3, NH2T = 9};
2606  const Char_t *NameV[Nregions] = {""};//,"Wall","Tunnel"};
2607  static TH1D *histV1[Nregions][NH1T][Nparts];
2608  static TH2D *histV2[Nregions][NH2T][Nparts];
2609  static TH2D *tofg = 0;
2610  static Bool_t first = kTRUE;
2611  if (first) {
2612  assert(GetChain()->GetTFile());
2613  GetChain()->GetTFile()->cd();
2614  first = kFALSE;
2615  memset(histV1, 0, sizeof(histV1));
2616  memset(histV2, 0, sizeof(histV2));
2617  Double_t xstep = 5;
2618  Double_t ystep = 2;
2619  Double_t xmax = 2000, xmin = - xmax;
2620  Double_t ymax = 1000, ymin = 0;
2621  int nx = (xmax - xmin)/xstep;
2622  int ny = (ymax - ymin)/ystep;
2623  struct Name_t {
2624  const Char_t *Name;
2625  const Char_t *Title;
2626  };
2627  struct NameX_t {
2628  Name_t name;
2629  int nX;
2630  Double_t xMin, xMax;
2631  int nY;
2632  Double_t yMin, yMax;
2633  };
2634  tofg = new TH2D("tofg","log_{10} (tof [nsec]) @ step versus particle type",140,-1,13,50,0.5,50.5);
2635  Name_t Particles[Nparts] = {
2636  {"", "#pi/K/p and others"}, // 0
2637  {"g","#gamma"}, // 1
2638  {"e","e^{#pm}"}, // 2
2639  {"m","#mu^{#pm}"}, // 3
2640  {"n","neutron"} // 4
2641  };
2642  NameX_t Types1[NH1T] = {
2643  {{"Ekin10" ,"Log_{10}(GEKIN) for %s for %s" }, 340, -14., 3.0, 0, 0, 0}, //5 -> 0 300
2644  {{"Ekin10s" ,"Log_{10}(GEKIN) for %s at step for %s Z < 0" }, 340, -14., 3.0, 0, 0, 0}, //6 -> 1 320
2645  {{"Ekin10V" ,"Log_{10}(GEKIN) for %s at production Vx for %s"}, 340, -14., 3.0, 0, 0, 0} //7 -> 2 400
2646  };
2647  NameX_t Types2[NH2T] = {
2648  {{"flux" ,"flux from %s * step for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //0 100
2649  {{"flux100keV","flux from %s * step E_{kin} > 100 keV for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //1 800
2650  {{"flux250meV","flux from %s * step E_{kin} < 250 meV for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //2 500
2651  {{"entries" ,"entries from %s for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //3 900
2652  {{"VxProd" ,"Vertex Production of %s for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //4 200
2653  {{"dose" ,"dose from charged particles and #gamma for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //8 ->5 600
2654  {{"star" ,"star density for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //9 ->6 700
2655  {{"RD" ,"Residual Dose for %s" }, nx, xmin, xmax, ny, ymin, ymax}, //0 ->7 701
2656  {{"DepEnergy" ,"Deposited energy at step (keV) for %s" }, nx, xmin, xmax, ny, ymin, ymax}
2657  };
2658  for (p = 0; p < Nparts; p++) {
2659  for (int r = 0; r < Nregions; r++) {
2660  for (int t = 0; t < NH1T; t++) {
2661  TString Name(Types1[t].name.Name); Name += Particles[p].Name; Name += NameV[r];
2662  TString Title(Form(Types1[t].name.Title,Particles[p].Title,NameV[r]));
2663  histV1[r][t][p] =
2664  new TH1D(Name,Title,Types1[t].nX,Types1[t].xMin,Types1[t].xMax);
2665  }
2666  for (int t = 0; t < NH2T; t++) {
2667  TString Name(Types2[t].name.Name); Name += Particles[p].Name; Name += NameV[r];
2668  TString Title(Form(Types2[t].name.Title,Particles[p].Title,NameV[r]));
2669  histV2[r][t][p] =
2670  new TH2D(Name,Title,Types2[t].nX,Types2[t].xMin,Types2[t].xMax,Types2[t].nY,Types2[t].yMin,Types2[t].yMax);//24,-180,180);
2671  }
2672  }
2673  }
2674  return;
2675  }
2676  // Fill histograms
2677  int Ipart = ckine->ipart%100;
2678  p = ipartx (Ipart);
2679  Double_t tofg10 = - 1;
2680  if (ctrak->tofg > 0) tofg10 = TMath::Log10(1e9*ctrak->tofg);
2681  tofg->Fill(tofg10,Ipart);
2682  if (p < 0) return;
2683  if (ctrak->gekin <= 0.0) {
2684  ctrak->istop = 2;
2685  return;
2686  }
2687  if (ctrak->upwght < 1) ctrak->upwght = 1;
2688  int r = 0;
2689  RR = TMath::Sqrt(ctrak->vect[0]*ctrak->vect[0] + ctrak->vect[1]*ctrak->vect[1]);
2690  ZZ = ctrak->vect[2];
2691  Double_t Phi = TMath::RadToDeg()*TMath::ATan2(ctrak->vect[1],ctrak->vect[0]);
2692  if (Phi < -180) Phi += 360;
2693  if (Phi > 180) Phi -= 360;
2694  // calculate particle flux in sensitive volumes
2695  if (! (ckine->charge == 0 && p < 0)) {
2696  /*
2697  * *** step cannot be bigger then 10 cm => suppose stright line in R/Z
2698  */
2699  if (ctrak->step > 0.0) {
2700  NstepB = ctrak->step + 0.5;
2701  NstepB = TMath::Max (1, NstepB);
2702  stepF = ctrak->step/NstepB;
2703  destepF = 1e6*ctrak->destep/NstepB;
2704  for (i = 1; i <= NstepB; i++) {
2705  XYZ[0] = ctrak->vect[0] + ctrak->vect[3]*stepF*(0.5 - i);
2706  XYZ[1] = ctrak->vect[1] + ctrak->vect[4]*stepF*(0.5 - i);
2707  XYZ[2] = ctrak->vect[2] + ctrak->vect[5]*stepF*(0.5 - i);
2708  RADIUS = TMath::Sqrt(XYZ[0]*XYZ[0] + XYZ[1]*XYZ[1]);
2709  Double_t phi = TMath::RadToDeg()*TMath::ATan2(XYZ[1],XYZ[0]);
2710  if (phi < -180) phi += 360;
2711  if (phi > 180) phi -= 360;
2712  histV2[r][0][p]->Fill(XYZ[2], RADIUS, stepF);
2713  if (ctrak->gekin >= 1.E-4) histV2[r][1][p]->Fill(XYZ[2], RADIUS, stepF);
2714  if (ctrak->gekin <= 0.25E-9) histV2[r][2][p]->Fill(XYZ[2], RADIUS, stepF);
2715  if (cmate->dens > 2.E-3 && ctrak->destep > 0.0)
2716  histV2[r][5][p]->Fill(XYZ[2], RADIUS, destepF/cmate->dens);
2717  histV2[r][8][p]->Fill(XYZ[2], RADIUS, destepF);
2718  }
2719  histV1[r][0][p]->Fill(TMath::Log10(ctrak->gekin));
2720  if (ctrak->vect[2] < 0.0) histV1[r][1][p]->Fill(TMath::Log10(ctrak->gekin));
2721  if (ctrak->inwvol == 1) {
2722  histV2[r][3][p]->Fill(ZZ, RR);
2723  }
2724  for (int i = 0; i < cking->ngkine; i++) {
2725  id = ((int)cking->gkin[i][4])%100;
2726  p = ipartx (id);
2727  if (p >= 0) {
2728  Char_t name[12];
2729  int itrtyp;
2730  Float_t mass, charge, tlife;
2731  TGiant3::Geant3()->Gfpart(id,name,itrtyp,mass,charge,tlife);
2732  histV2[r][4][p]->Fill(ZZ, RR);
2733  Double_t ekin =
2734  TMath::Sqrt(cking->gkin[i][0]*cking->gkin[i][0] +
2735  cking->gkin[i][1]*cking->gkin[i][1] +
2736  cking->gkin[i][2]*cking->gkin[i][2] + mass*mass) - mass;
2737  ekin = TMath::Max (1e-14, ekin);
2738  histV1[r][2][p]->Fill(TMath::Log10(ekin));
2739  }
2740  }
2741  }
2742  // Star density
2743  if (cking->ngkine > 0) {
2744  if (ctrak->vect[6] > 0.300 && p <= 0) {
2745  for (int i = 0; i < ctrak->nmec; i++) {
2746  if (ctrak->lmec[i] >= 12 && ctrak->lmec[i] <= 20) {
2747  if ( p>=0 ) histV2[r][6][p]->Fill(ZZ, RR);
2748  OmegaN = dose(cmate->z);
2749  if ( p>=0 ) histV2[r][7][p]->Fill(ZZ, RR, OmegaN );
2750  break;
2751  }
2752  }
2753  }
2754  }
2755  }
2756 }
2757 #if 0
2758 //________________________________________________________________________________
2759 void St_geant_Maker::PhysicsOff()
2760 {
2761  geant3->SetProcess("DCAY", 0);
2762  geant3->SetProcess("ANNI", 0);
2763  geant3->SetProcess("BREM", 0);
2764  geant3->SetProcess("COMP", 0);
2765  geant3->SetProcess("HADR", 0);
2766  geant3->SetProcess("MUNU", 0);
2767  geant3->SetProcess("PAIR", 0);
2768  geant3->SetProcess("PFIS", 0);
2769  geant3->SetProcess("PHOT", 0);
2770  geant3->SetProcess("RAYL", 0);
2771  geant3->SetProcess("LOSS", 4); // no fluctuations
2772  // geant3->SetProcess("LOSS 1"); // with delta electron above dcute
2773  geant3->SetProcess("DRAY", 0);
2774  geant3->SetProcess("MULS", 0);
2775  geant3->SetProcess("STRA", 0);
2776  geant3->SetCut("CUTGAM", 1e-3 );
2777  geant3->SetCut("CUTELE", 1e-3 );
2778  geant3->SetCut("CUTHAD", .001 );
2779  geant3->SetCut("CUTNEU", .001 );
2780  geant3->SetCut("CUTMUO", .001 );
2781  geant3->SetCut("BCUTE", .001 );
2782  geant3->SetCut("BCUTM", .001 );
2783  geant3->SetCut("DCUTE", 1e-3 );
2784  geant3->SetCut("DCUTM", .001 );
2785  geant3->SetCut("PPCUTM", .001 );
2786  geant3->SetCut("TOFMAX", 50.e-6);
2787 }
2788 #endif
static Int_t MapGEANT2StNodeVis(Int_t vis)
Definition: TVolume.cxx:152
virtual void AddData(TDataSet *data, const char *dir=".data")
User methods.
Definition: StMaker.cxx:332
virtual void Remove(TDataSet *set)
Remiove the &quot;set&quot; from this TDataSet.
Definition: TDataSet.cxx:641
virtual Int_t Finish()
void version(std::ostream &os=std::cout)
print HepMC version
Definition: Version.h:27
virtual Long_t GetNRows() const
Returns the number of the used rows for the wrapped table.
Definition: TTable.cxx:1388
virtual void ls(Option_t *option="") const
Definition: TDataSet.cxx:495
virtual void Do(const Char_t *option="dcut cave x 0.1 10 10 0.03 0.03")
Executes a KUIP command.
Definition: Stypes.h:43
virtual Int_t Make()
Definition: Stypes.h:40
static TTable * New(const Char_t *name, const Char_t *type, void *array, UInt_t size)
This static method creates a new TTable object if provided.
Definition: TTable.cxx:1515
virtual void Shunt(TDataSet *newParent=0)
Definition: TDataSet.cxx:810
Definition: TTable.h:48
virtual TDataSet * FindByName(const char *name, const char *path="", Option_t *opt="") const
Definition: TDataSet.cxx:378
virtual TString Path() const
return the full path of this data set
Definition: TDataSet.cxx:626
Definition: Stypes.h:44
Definition: GtHash.h:6
virtual Char_t * Print(Char_t *buf, Int_t n) const
Create IDL table defintion (to be used for XDF I/O)
Definition: TTable.cxx:1548
Definition: dbStruct.hh:78
virtual void LoadGeometry(const Char_t *option="detp geometry field_only")
Specifies GEANT3 geometry command.
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362