Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

TGeant3.cxx

Go to the documentation of this file.
00001 
00002 /**************************************************************************
00003  * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
00004  *                                                                        *
00005  * Author: The ALICE Off-line Project.                                    *
00006  * Contributors are mentioned in the code where appropriate.              *
00007  *                                                                        *
00008  * Permission to use, copy, modify and distribute this software and its   *
00009  * documentation strictly for non-commercial purposes is hereby granted   *
00010  * without fee, provided that the above copyright notice appears in all   *
00011  * copies and that both the copyright notice and this permission notice   *
00012  * appear in the supporting documentation. The authors make no claims     *
00013  * about the suitability of this software for any purpose. It is          *
00014  * provided "as is" without express or implied warranty.                  *
00015  **************************************************************************/
00016 
00017 /* $Id: TGeant3.cxx,v 1.17 2009/02/09 00:50:32 schubert Exp $ */
00018 
00019 /*
00020 Revision 1.59  2007/07/25 20:06:49  brun
00021 From Ivana:
00022 Changed the fPDGCode type to TArrayI to allow
00023 its dynamic size (thanks to Susan Kasahara).
00024 
00025 Revision 1.58  2007/07/24 19:43:24  brun
00026 From Ivana:
00027 Do not add particles in TDatabasePDG if they
00028 are were already aded;
00029 (thanks to Susan Kasahara for this suggestion)
00030 
00031 Revision 1.57  2007/07/23 20:04:03  brun
00032 From Ivana:
00033 Implemented the new pdg "standard" codes for ions
00034 defined in pdg-2006, thanks to Susan Kasahara
00035 for this suggestion.
00036 
00037 Revision 1.56  2007/05/18 08:44:15  brun
00038 A major update of GEANTE by Andrea Fontana and Alberto Rotondi
00039 
00040 
00041 1) update of the Coulomb multiple scattering parametrization;
00042 2) update of the straggling of energy loss for thin materials;
00043 3) new options to extrapolate the track parameters to the point
00044    of closest approach to a point or to a wire (straight line).
00045 
00046 Details on the physical motivation behind this work can be found
00047 in our report for the Panda Collaboration, available at:
00048 
00049 http://www.pv.infn.it/~fontana/tracking.pdf
00050 
00051 Feel free to contact us for questions and discussions about these
00052 topics by using the following email addresses:
00053 
00054 alberto.rotondi@pv.infn.it
00055 andrea.fontana@pv.infn.it
00056 
00057 ---
00058 
00059 List of changes in the fortran and C++ routines of the geant3
00060 VMC directory:
00061 
00062 - gcmore.inc
00063   gtmore.inc
00064   geant3LinkDef.h
00065   gcomad.F
00066 
00067  Added a new common that contains all the new variables:
00068       COMMON/GCMORE/GCALPHA,ICLOSE,PFINAL(3),DSTRT,WIRE1(3),WIRE2(3),
00069      +              P1(3),P2(3),P3(3),CLENG(3)
00070 
00071      input to ERLAND:
00072       GCALPHA: energy cut parameter for energy loss fluctuations
00073 
00074      input to EUSTEP:
00075       ICLOSE: = 1 the use of the common is enabled for the closest
00076                   approach to a point PFINAL(3)
00077               = 2 the use of the common is enabled for the closest
00078                   approach to a wire of extremes WIRE1(3) and WIRE2(3)
00079               = 0 the common is empty and disabled
00080       PFINAL(3): assigned point
00081       DSTRT: assigned distance between initial point in ERTRAK
00082              and PFINAL along straight line (currently noy used)
00083       WIRE1(3): first point of a wire
00084       WIRE2(3): second point of a wire
00085 
00086      output from EUSTEP:
00087       P1(3): point previous to the point of closest approach to
00088              PFINAL() or wire
00089       P2(3): point of closest approach to PFINAL() or wire
00090       P3(3): point next to the point of closest approach to
00091              PFINAL() or wire
00092       CLENG(3): track length to the previous 3 points
00093 
00094       Important note: the calculated points of closest approach are
00095       depending on the GEANE steps. For calculating the true point
00096       of closest approach the last 3 points of the extrapolation, i.e.
00097       the previous to closest, the closest and the next to closest are
00098       returned to the user. Different algorithms can be implemented, but
00099       we decided to leave this to the users in the C++ interface to GEANE.
00100 
00101 - ermcsc.F
00102  new expression for the variance of the Coulomb multiple scattering
00103  according to Fruhwirth and Regler, NIM A 456 (2001) 369
00104 
00105 - ertrch.F
00106  added DESTEP in the calling string of ERLAND for calculation with
00107  Urban model. Added and saved previous step PRSTEP.
00108 
00109 - erland.F
00110  added new calculation for sigma of straggling in energy loss
00111  to include in Geane the Urban/Landau approximation, as explained
00112  in the Geant manual and related papers.
00113  The model parametrization can be controlled with a user variable (GCALPHA)
00114  in the new GCMORE common block: 1 is for old gaussian model valid
00115  for dense materials, other values (see the report) are for gaseous
00116  materials.
00117 
00118 - eustep.F
00119  added the calculation to the distance of closest approach to a point
00120  or to a wire.
00121 
00122 - TGeant3.h
00123 - TGeant3.cxx
00124  added the possibility to define user cuts (already present in the gccuts
00125  struct but not in the TGeant3::SetCUTS method) and to define the new
00126  variables of the GCMORE common with two new methods SetECut() and
00127  SetClose().
00128  Added new method InitGEANE() to initialize GEANE to the old behaviour
00129  (default) for backward compatibility. Only the multiple scattering has
00130  been updated to a more correct formula.
00131  Corrected a typo in the call to the routine Trscsd().
00132 
00133 Revision 1.55  2007/03/26 10:15:04  brun
00134 Fix a problem when adding a new tracking medium to the TObjArray.
00135 
00136 Revision 1.54  2007/03/23 21:11:44  brun
00137 From Ivana Hrivnacova and Andrea Fontana:
00138 Reintroduce functionality in TGeant3::SetCuts that was removed in a previous patch.
00139 
00140 Revision 1.53  2007/03/22 08:58:41  brun
00141 From Ivana:
00142 Restore the function TGeant3::MediumId
00143 
00144 Revision 1.52  2007/02/28 16:25:14  brun
00145 From Federico:
00146 Suppress compiler warnings coming from unused arguments
00147 
00148 Revision 1.51  2006/12/19 13:16:19  brun
00149 from Mohammad Al-Turany & Denis Bertini
00150 
00151 Changes in  TGeant3/TGeant3.cxx and TGeant3.h
00152 ------------------------------------
00153 1. Geane interface functions are added:
00154     void  eufill(Int_t n, Float_t *ein, Float_t *xlf);
00155     void  eufilp(const int n,Float_t *ein,Float_t *pli,Float_t *plf);
00156     void  eufilv(Int_t n, Float_t *ein, Char_t *namv, Int_t *numv,Int_t *iovl);
00157     void  trscsd(Float_t *pc,Float_t *rc,Float_t *pd,Float_t *rd,
00158                  Float_t *h,Float_t ch,Int_t ierr,Float_t spu,Float_t *dj,Float_t *dk);
00159     void  trsdsc(Float_t *pd,Float_t *rd,Float_t *pc,Float_t *rc,
00160                            Float_t *h,Float_t *ch,Int_t *ierr,Float_t *spu,Float_t *dj,Float_t *dk);
00161     void  trscsp(Float_t *ps,Float_t *rs,Float_t *pc,Float_t *rc,Float_t *h,
00162                         Float_t *ch,Int_t *ierr,Float_t *spx);
00163     void  trspsc(Float_t *ps,Float_t *rs,Float_t *pc,Float_t *rc,Float_t *h,
00164                         Float_t *ch,Int_t *ierr,Float_t *spx);
00165 
00166 2. The Gfang function wrapper is added
00167     void  g3fang( Float_t *, Float_t &,Float_t &, Float_t &, Float_t &,Int_t & );
00168 
00169 
00170 
00171 
00172 changes in TGeant3/TGeant3gu.cxx
00173 --------------------------
00174 Adding GCalor interface
00175         1. function calsig() and gcalor() are added
00176         2. setting ihadr=5 will call the GCalor routine
00177 
00178 
00179 
00180 
00181 changes in TGeant3/TGeant3.h
00182 -----------------------
00183 1. Structures for Geane output are setted as public so that the user can access them
00184 
00185     Ertrio_t *fErtrio
00186     Eropts_t *fEropts
00187     Eroptc_t *fEroptc
00188     Erwork_t *fErwork
00189     Trcom3_t *fTrcom3
00190 
00191 2. The size of the error matrix errin is corrected to 15
00192 
00193 Revision 1.49  2006/04/20 10:14:55  brun
00194 From Peter Hristov:
00195 small change in TGeant3.cxx:
00196 to avoid some rare problems in glandz.F and probably in other places where the random number should not
00197 be equal to 0 and 1.
00198 
00199 Revision 1.48  2006/03/15 08:12:11  brun
00200 -New Makefile.macosx
00201 
00202 -delete all TGeant3 GUI and graphics classes
00203 
00204 -Remove all references to GUI/Graphics classes from G3Volume.cxx and TGeant3.cxx
00205 
00206 -Remove TGeant3/galicef.F and rdummies.F
00207 
00208 -Remove references to GUI/Graphics classes from geant3LinkDef.h
00209 
00210 -delete added/dummies2.F
00211 
00212 -change added/dummies.c, keeping only __attribute__ and MAIN__
00213 
00214 -Change Makefile accordingly
00215 
00216 Revision 1.47  2005/11/18 21:25:22  brun
00217 From Bjorn, Andrei:
00218 Implemented new VMC functions for access to geometry;
00219 added -Woverloaded-virtual to Makefile.linux
00220 
00221 Revision 1.46  2005/07/21 17:54:37  brun
00222 Implement same code in the float* versions that were already implemented
00223 in the Double* versions.
00224 
00225 Revision 1.45  2005/07/20 09:22:50  brun
00226 From Federico:
00227 Fixes to compile with gcc4CVS: ----------------------------------------------------------------------
00228 
00229 Revision 1.44  2005/05/21 05:48:33  brun
00230 In TGeant3::Init put the code calling ConstructGeometry conditional
00231 on ROOT versions >-5.01/01
00232 
00233 Revision 1.43  2005/05/17 12:47:00  brun
00234 From Ivana:
00235 - Added call to new TVirtualMCApplication::ConstructOpGeometry() function
00236 - Bug fix in G3Mixture (do not update wmat values twice)
00237 - In CreateFloatArray: added check for values > FLT_MAX
00238 
00239 Revision 1.42  2005/02/16 08:01:51  brun
00240 Implement function grndmq. It returns gRandom->GetSeed().
00241 The result makes sense only when Trandom is the generator.
00242 
00243 Revision 1.41  2005/02/08 11:22:03  brun
00244 From Ivana:
00245 For TGeant3.h:
00246 Added IsRootGeometrySupported() function
00247 (now required by TVirtualMC)
00248 
00249 For TGeant3.cxx:
00250 Updated text in Fatal in SetRootGeometry.
00251 
00252 Revision 1.40  2005/01/07 11:34:43  brun
00253 Change the J/Psi lifetime from 0 to 7.6e-21
00254 (thanks Yuri Kharlov)
00255 
00256 Revision 1.39  2004/12/21 15:34:48  brun
00257 Implement TGeant3TGeo::isRootGeometry returning kTRUE
00258 
00259 Revision 1.38  2004/12/17 11:55:47  brun
00260 A new class TGeant3TGeo (deriving from TGeant3) is introduced.
00261 TGeant3 uses by default the geant3 geometry. TGeant3TGeo uses the TGeo classes.
00262 The two classes are built in the same library. The choice of which version to use
00263 can now be made dynamically at run time (eg based on an environment variable)
00264 or a job control option.
00265 For example the examples like gexam1, gexam4 have been modified to run
00266 with either geant3 geometry or TGeo. To run gexam1 with geant3 geometry do
00267   gexam1 TGeant3
00268 to run with TGeo (default) do
00269   gexam1
00270 The examples E01.C, E02 and E03 have also been modified to select the option
00271 at run time based on the environment variable TVirtualMC (set in .rootrc)
00272 If TVirtualMC is set to TGeant3TGeo TGeo geometry will be used.
00273 The Makefile has been modified to build the two classes in the same library.
00274 
00275 Revision 1.37  2004/11/23 14:52:52  brun
00276 From Andreas Morsch:
00277 on request of ALICE/TPC I added a new method to TVirtualMC.h
00278 
00279 void TVirtualMC::ForceDecayTime(Float_t);
00280 
00281 
00282 This allows to force the decay time of the current particle.
00283 The use-case implemented in AliRoot is the decay of primary particles
00284 within a user defined radius range.
00285 
00286 Revision 1.36  2004/10/13 10:38:32  brun
00287 From Andrei Gheata:
00288 some modifications in the current TGeant3.cxx :
00289 
00290 from Mihaela:
00291 - modifications in STATISTICS option: added branches to statistics tree
00292 (statsame + statpath)
00293 - global gckine added. gckine->itrtyp == 7 used in gtnext to optimize
00294 speed - 1% gain (computation of global matrix only when called from gtckov)
00295 - bias of 1E-7 (used previously for making sure a boundary is crossed)
00296 eliminated
00297 
00298 I removed the option WITHBOTH and fixed a problem in VolId() - in the
00299 last version of AliRoot some detector was calling gMC->VolId(name) with
00300 a name containing a blank at the end and now all volumes have the blanks
00301 supressed. Fixing this I noticed that there are 4 detectors that in
00302 their StepManager() they call at each step things like:
00303   if (gMC->CurrentVolId(copy) == gMC->VolId("RICH")) ...
00304 Incredible !!! In G3 native this search by name does not penalize so
00305 much since names are converted to Int_t and the volume bank is looked
00306 for this Int_t. In TGeo we cannot do this since we support long names so
00307 we have to go to gGeoManager->GetVolume("name") which scans a list of
00308 2000 objects at each step several times...   I fixed this by hand by
00309 puting static variables in these methods and Peter will commit the
00310 changes. The gain in speed for TGeo case is considerable with full AliRoot.
00311 
00312 Revision 1.35  2004/10/12 07:46:23  brun
00313 >From Ivana:
00314 Implemented new functions from TVirtualMC:
00315   Int_t NofVolDaughters(const char* volName) const;
00316   const char*  VolDaughterName(const char* volName, Int_t i) const;
00317   Int_t        VolDaughterCopyNo(const char* volName, Int_t i) const;
00318   const char* CurrentVolPath();
00319 
00320 Revision 1.34  2004/09/17 08:51:55  brun
00321 >From Ivana
00322  SetRootGeometry() allowed only with WITHROOT option;
00323  added Fatal() for other modes.
00324 
00325 Revision 1.33  2004/08/25 07:28:54  brun
00326 >From Ivana and Lionel Chaussard
00327  In method DefineParticles(), we had:
00328 
00329          pdgcode(Tau+)=15
00330          pdgcode(Tau-)=-15
00331 
00332  This is in contradiction with the other leptons (pdgcode>0 for
00333  negative leptons, pdgcode<0 for positive leptons). I also checked
00334  in the PDG WEB pages that Tau- should have a code +15.
00335 
00336  changed to:
00337          pdgcode(tau+)=-15
00338          pdgcode(tau-)=+15 ?
00339 
00340 Revision 1.32  2004/08/05 12:20:39  brun
00341 >From Andrei Gheata:
00342 I have found/fixed a bug in TGeoManager::IsSameLocation(x,y,z). Also I
00343 have eliminated the penalizing check of IsSameLocation() in gtnext().
00344 
00345 Revision 1.31  2004/07/09 12:15:12  brun
00346 >From Ivana:
00347 in case a user defines geometry via TGeo and associates more tracking
00348  media with the same material, TGeant3 duplicates this material
00349  for each tracking medium.
00350  I haven't found a function for getting the number of
00351  materials/media (TList) so I count them by a loop
00352  - maybe it can be done more intelligently...
00353 
00354 Revision 1.30  2004/07/09 08:11:29  brun
00355 Fix by Ivana/Andrei to call TGeoMedium::setId and not TGeoMedium::SetUniqueID
00356 
00357 Revision 1.29  2004/06/17 13:56:53  rdm
00358 changed several "const int" arguments to "int". Was causing warnings of
00359 type "qualifier is meaningless".
00360 
00361 Revision 1.28  2004/06/08 10:27:19  brun
00362 >From Ivana:
00363 - Added Bool_t return value to methods
00364   SetCut(), SetProcess(), DefineParticle(), DefineIon()
00365 - Removed  DefineParticles()
00366 
00367 Revision 1.27  2004/05/28 13:45:00  brun
00368 >From Ivana
00369 Implementation of StopRun (new function in TVirtualMC)
00370 
00371 Revision 1.26  2004/05/14 08:32:01  brun
00372 In function gtnext, call GetNextBoundary(-step) instead of (step).
00373 This fixes a problem when tracking Cherenkov photons.
00374 (Thanks to Yuri Kharlov for reporting the problem and Andrei for fixing it)
00375 
00376 Revision 1.25  2004/03/23 11:16:44  brun
00377 >From Ivana
00378 With the previous changes by Andrei, all fixes by Ivana were lost.
00379 This patch merges Ivana and Andrei versions.
00380 
00381 Revision 1.23  2004/03/15 12:18:45  brun
00382 >From Andrei Gheata:
00383  - minor modifications to cope with geometry retreival from file:
00384  - ConstructGeometry does not need to be called
00385  - CloseGeometry not needed
00386 
00387 Revision 1.22  2004/02/03 12:47:34  brun
00388 >From Andrei Gheata:
00389 TGeant3:
00390 
00391 - calls to gtonly return now always a true value (G3 is seeing an ONLY
00392 geometry with TGeo)
00393 - IsSameLocation inside gtnext not yet eliminated, but I am getting only
00394 1 exception instead of 400 now (when the location really changes)
00395 
00396 Revision 1.21  2004/01/28 18:05:24  brun
00397 New version from Peter Hristov adding the graphics interface
00398 
00399 Revision 1.20  2004/01/28 08:30:54  brun
00400 Change the call to TRandom::RndmArray in function grndm
00401 
00402 Revision 1.19  2004/01/28 08:14:48  brun
00403 Add a CPP option STATISTICS to monitor the fequency of calls to the geometry functions.
00404 
00405 Revision 1.18  2003/12/10 15:39:37  brun
00406 iFollowing recent improvements by Andrei, replace in ggperp
00407 the computation of normals:
00408     Double_t *dblnorm = gGeoManager->FindNormal(kFALSE);
00409 with :
00410     Double_t *dblnorm = gGeoManager->FindNormalFast();
00411 
00412 Revision 1.17  2003/12/10 10:32:09  brun
00413 Add a protection in TGeant3::Gsmate in case the material density is null
00414 
00415 Revision 1.16  2003/12/01 23:51:22  brun
00416 >From Andrei and Peter:
00417 add a few missing cases when compiling with the WITHROOT option.
00418 
00419 Revision 1.15  2003/11/28 09:44:15  brun
00420 New version of TGeant3 supporting the options WITHG3 and WITHROOT
00421 
00422 Revision 1.14  2003/10/09 06:28:45  brun
00423 In TGeant3::ParticleName, increase size of local array name[20] to name[21]
00424 
00425 Revision 1.13  2003/09/26 15:01:08  brun
00426 >From Ivana;
00427 - implemented new functions from TVirtualMC
00428   enabling user to define own particles and ions
00429   + getter functions::
00430     DefineParticle(..)
00431     DefineIon(..)
00432     ParticleName(..) const
00433     ParticleMass(..) const
00434     Double_t  ParticleCharge(..) const
00435     Double_t  ParticleLifeTime(..) const
00436     TMCParticleType ParticleMCType(..) const
00437 - corrected charge in AddParticlesToPdgDataBase
00438 
00439 Revision 1.12  2003/07/22 06:53:28  brun
00440 This version does not yet support TGeo geometry.
00441 TVirtualMC must be initialized with the 3rd argument set to kFALSE
00442 
00443 Revision 1.11  2003/07/18 10:22:50  brun
00444 Changes to reflect the equivalent changes in the abstract classes in vmc
00445 (thanks Peter Hristov)
00446 
00447 Revision 1.10  2003/07/16 07:40:09  brun
00448 >From Andreas Morsch
00449 
00450 - default g3 specific initialisation moved to TGeant3::Init()
00451   (This avoids the cast to TGeant3* in the Config.C)
00452 - "CKOV" added to SetProcess
00453 
00454 Revision 1.9  2003/06/03 21:26:46  brun
00455 New version of gustep by Andreas Morsch
00456 
00457 Revision 1.8  2003/02/28 10:41:49  brun
00458 >From Andreas
00459  In DefineParticles(): rho0 decay channel corrected
00460 
00461 Revision 1.7  2003/02/04 17:50:34  brun
00462 >From Ivana
00463  In Mixture(): pass abs(nlmat) to CreateFloatArray calls
00464  as nlmat can be negative.
00465 
00466 Revision 1.6  2003/01/31 18:23:06  brun
00467 Ivana suggested corrections.
00468 - corrected tau pdg code
00469 - Warning if external decayer needed but not defined.
00470 
00471 Revision 1.5  2003/01/23 11:34:04  brun
00472 In gustep, replace
00473    gMC->TrackPosition(x,y,z);
00474 by
00475    geant3->TrackPosition(x,y,z);
00476 
00477 Revision 1.4  2003/01/06 17:20:52  brun
00478 Add new functions TrackPosition and TrackMomentum as alternative to the original
00479 functions filling a TLorentzVector object.
00480 Use these new functions in gustep and gudcay.
00481 This makes a 25 per cent speed improvement in case of Alice.
00482 
00483 Revision 1.3  2002/12/10 07:58:36  brun
00484 Update by Federico for the calls to Grndm
00485 
00486 Revision 1.2  2002/12/06 16:50:30  brun
00487 >From Federico:
00488 the following modifications provide an >6% improvement in speed for
00489 AliRoot.
00490 
00491 Revision 1.1.1.1  2002/07/24 15:56:26  rdm
00492 initial import into CVS
00493 
00494 Revision 1.5  2002/07/10 09:33:19  hristov
00495 Array with variable size created by new
00496 
00497 Revision 1.4  2002/07/10 08:38:54  alibrary
00498 Cleanup of code
00499 
00500 */
00501 
00503 //                                                                    //
00504 //  Interface Class to the Geant3.21 Monte Carlo                      //
00505 //                                                                    //
00506 //                                                                    //
00507 //                                                                    //
00509 //sk:begin
00510 // For cerr output
00511 #include <iostream>
00512 using namespace std;
00513 //sk:end
00514 
00515 #include <ctype.h>
00516 #include <stdlib.h>
00517 
00518 #include "TROOT.h"
00519 #include "TParticle.h"
00520 #include "TDatabasePDG.h"
00521 #include "TLorentzVector.h"
00522 #include "TArrayI.h"
00523 #include "TArrayD.h"
00524 #include "TString.h"
00525 #include "TParameter.h"
00526 #include "TGeoMatrix.h"
00527 #include "TObjString.h"
00528 
00529 #include "TGeant3.h"
00530 
00531 #include "TCallf77.h"
00532 #include "TVirtualMCDecayer.h"
00533 #include "TPDGCode.h"
00534 
00535 #ifndef WIN32
00536 # define g3zebra  g3zebra_
00537 # define grfile   grfile_
00538 # define g3pcxyz  g3pcxyz_
00539 # define g3gclos  g3gclos_
00540 # define g3last   g3last_
00541 # define g3init   g3init_
00542 # define g3cinit  g3cinit_
00543 # define g3run    g3run_
00544 # define g3trig   g3trig_
00545 # define g3trigc  g3trigc_
00546 # define g3trigi  g3trigi_
00547 # define g3work   g3work_
00548 # define g3zinit  g3zinit_
00549 # define g3fmate  g3fmate_
00550 # define g3fpart  g3fpart_
00551 # define g3ftmed  g3ftmed_
00552 //sk:begin
00553 //    Modified: S. Kasahara  2006/05/19 Add method to print media
00554 # define g3ptmed  g3ptmed_
00555 //sk:end
00556 //sk:begin
00557 //    Modified: S. Kasahara  2007/07/24 Add method to print particles
00558 # define g3ppart  g3ppart_
00559 //sk:end
00560 # define g3ftmat  g3ftmat_
00561 # define g3mate   g3mate_
00562 # define g3part   g3part_
00563 # define g3sdk    g3sdk_
00564 # define g3smate  g3smate_
00565 # define g3fang   g3fang_ 
00566 # define g3smixt  g3smixt_
00567 # define g3spart  g3spart_
00568 # define g3stmed  g3stmed_
00569 # define g3sckov  g3sckov_
00570 # define g3stpar  g3stpar_
00571 # define g3fkine  g3fkine_
00572 # define g3fvert  g3fvert_
00573 # define g3skine  g3skine_
00574 # define g3svert  g3svert_
00575 # define g3physi  g3physi_
00576 # define g3debug  g3debug_
00577 # define g3ekbin  g3ekbin_
00578 # define g3finds  g3finds_
00579 # define g3sking  g3sking_
00580 # define g3skpho  g3skpho_
00581 # define g3sstak  g3sstak_
00582 # define g3sxyz   g3sxyz_
00583 # define g3many   g3many_
00584 # define g3track  g3track_
00585 # define g3treve  g3treve_
00586 # define gtreveroot  gtreveroot_
00587 # define grndm    grndm_
00588 # define grndmq   grndmq_
00589 # define g3dtom   g3dtom_
00590 # define g3lmoth  g3lmoth_
00591 # define g3media  g3media_
00592 # define g3mtod   g3mtod_
00593 # define g3sdvn   g3sdvn_
00594 # define g3sdvn2  g3sdvn2_
00595 # define g3sdvs   g3sdvs_
00596 # define g3sdvs2  g3sdvs2_
00597 # define g3sdvt   g3sdvt_
00598 # define g3sdvt2  g3sdvt2_
00599 # define g3sord   g3sord_
00600 # define g3spos   g3spos_
00601 # define g3sposp  g3sposp_
00602 # define g3srotm  g3srotm_
00603 # define g3protm  g3protm_
00604 # define g3svolu  g3svolu_
00605 # define g3print  g3print_
00606 # define dzshow   dzshow_
00607 # define g3satt   g3satt_
00608 # define g3fpara  g3fpara_
00609 # define gckpar   gckpar_
00610 # define g3ckmat  g3ckmat_
00611 # define g3lvolu  g3lvolu_
00612 # define geditv   geditv_
00613 # define mzdrop   mzdrop_
00614 
00615 # define ertrak  ertrak_
00616 # define ertrgo  ertrgo_
00617 # define eufill  eufill_
00618 # define eufilp  eufilp_
00619 # define eufilv  eufilv_
00620 # define trscsp  trscsp_
00621 # define trspsc  trspsc_
00622 # define trscsd  trscsd_
00623 # define trsdsc  trsdsc_
00624 
00625 # define gcomad gcomad_
00626 
00627 # define g3brelm g3brelm_
00628 # define g3prelm g3prelm_
00629 
00630 # define rxgtrak rxgtrak_
00631 # define rxouth  rxouth_
00632 # define rxinh   rxinh_
00633 
00634 
00635 #else
00636 
00637 # define gzebra  GZEBRA
00638 # define grfile  GRFILE
00639 # define gpcxyz  GPCXYZ
00640 # define ggclos  GGCLOS
00641 # define glast   GLAST
00642 # define ginit   GINIT
00643 # define g3cinit G3CINIT
00644 # define grun    GRUN
00645 # define gtrig   GTRIG
00646 # define gtrigc  GTRIGC
00647 # define gtrigi  GTRIGI
00648 # define gwork   GWORK
00649 # define g3zinit G3ZINIT
00650 # define gfmate  GFMATE
00651 # define gfpart  GFPART
00652 # define gftmed  GFTMED
00653 # define gftmat  GFTMAT
00654 # define gmate   GMATE
00655 # define gpart   GPART
00656 # define gsdk    GSDK
00657 # define gsmate  GSMATE
00658 # define gsmixt  GSMIXT
00659 # define gspart  GSPART
00660 # define gstmed  GSTMED
00661 # define gsckov  GSCKOV
00662 # define gstpar  GSTPAR
00663 # define gfkine  GFKINE
00664 # define gfvert  GFVERT
00665 # define gskine  GSKINE
00666 # define gsvert  GSVERT
00667 # define gphysi  GPHYSI
00668 # define gdebug  GDEBUG
00669 # define gekbin  GEKBIN
00670 # define gfinds  GFINDS
00671 # define gsking  GSKING
00672 # define gskpho  GSKPHO
00673 # define gsstak  GSSTAK
00674 # define gsxyz   GSXYZ
00675 # define gtrack  GTRACK
00676 # define gtreve  GTREVE
00677 # define gtreveroot  GTREVEROOT
00678 # define grndm   GRNDM
00679 # define grndmq  GRNDMQ
00680 # define gdtom   GDTOM
00681 # define glmoth  GLMOTH
00682 # define gmedia  GMEDIA
00683 # define gmtod   GMTOD
00684 # define gsdvn   GSDVN
00685 # define gsdvn2  GSDVN2
00686 # define gsdvs   GSDVS
00687 # define gsdvs2  GSDVS2
00688 # define gsdvt   GSDVT
00689 # define gsdvt2  GSDVT2
00690 # define gsord   GSORD
00691 # define gspos   GSPOS
00692 # define gsposp  GSPOSP
00693 # define gsrotm  GSROTM
00694 # define gprotm  GPROTM
00695 # define gsvolu  GSVOLU
00696 # define gprint  GPRINT
00697 # define dzshow  DZSHOW
00698 # define gsatt   GSATT
00699 # define gfpara  GFPARA
00700 # define gckpar  GCKPAR
00701 # define gckmat  GCKMAT
00702 # define glvolu  GLVOLU
00703 # define geditv  GEDITV
00704 # define mzdrop  MZDROP
00705 
00706 # define ertrak  ERTRAK
00707 # define ertrgo  ERTRGO
00708 # define eufill  EUFILL
00709 # define eufilp  EUFILP
00710 # define eufilv  EUFILV
00711 # define trscsp  TRSCSP
00712 # define trspsc  TRSPSC
00713 # define trscsd  TRSCSD
00714 # define trsdsc  TRSDSC
00715 
00716 # define gcomad  GCOMAD
00717 
00718 # define gbrelm  GBRELM
00719 # define gprelm  GPRELM
00720 
00721 # define rxgtrak RXGTRAK
00722 # define rxouth  RXOUTH
00723 # define rxinh   RXINH
00724 # define gfang   GFANG 
00725 
00726 #endif
00727 
00728 //______________________________________________________________________
00729 extern "C"
00730 {
00731   //
00732   // Prototypes for GEANT functions
00733   //
00734   void type_of_call g3zebra(const int&);
00735 
00736   void type_of_call g3pcxyz();
00737 
00738   void type_of_call g3gclos();
00739 
00740   void type_of_call g3last();
00741 
00742   void type_of_call g3init();
00743 
00744   void type_of_call g3cinit();
00745 
00746   void type_of_call g3run();
00747 
00748   void type_of_call g3trig();
00749 
00750   void type_of_call g3trigc();
00751 
00752   void type_of_call g3trigi();
00753 
00754   void type_of_call g3work(const int&);
00755 
00756   void type_of_call g3zinit();
00757 
00758   void type_of_call g3mate();
00759 
00760   void type_of_call g3part();
00761 
00762   void type_of_call g3sdk(Int_t &, Float_t *, Int_t *);
00763 
00764   void type_of_call g3fkine(Int_t &, Float_t *, Float_t *, Int_t &,
00765                            Int_t &, Float_t *, Int_t &);
00766 
00767   void type_of_call g3fvert(Int_t &, Float_t *, Int_t &, Int_t &,
00768                            Float_t &, Float_t *, Int_t &);
00769 
00770   void type_of_call g3skine(Float_t *,Int_t &, Int_t &, Float_t *,
00771                            Int_t &, Int_t &);
00772 
00773   void type_of_call g3svert(Float_t *,Int_t &, Int_t &, Float_t *,
00774                            Int_t &, Int_t &);
00775 
00776   void type_of_call g3physi();
00777 
00778   void type_of_call g3debug();
00779 
00780   void type_of_call g3ekbin();
00781 
00782   void type_of_call g3finds();
00783 
00784   void type_of_call g3sking(Int_t &);
00785 
00786   void type_of_call g3skpho(Int_t &);
00787 
00788   void type_of_call g3sstak(Int_t &);
00789 
00790   void type_of_call g3sxyz();
00791 
00792   void type_of_call g3many();
00793 
00794   void type_of_call g3track();
00795 
00796   void type_of_call g3treve();
00797 
00798   void type_of_call gtreveroot();
00799 
00800   void type_of_call grndm(Float_t *r, const Int_t &n)
00801   {
00802      //gRandom->RndmArray(n,r);
00803      for(Int_t i=0; i<n; i++)
00804        do r[i]=gRandom->Rndm(); while(0>=r[i] || r[i]>=1);
00805   }
00806 
00807   void type_of_call grndmq(Int_t &is1, Int_t &is2, const Int_t &,
00808                            DEFCHARD DEFCHARL)
00809   {is1=gRandom->GetSeed(); is2=0; /*only valid with TRandom;*/}
00810 
00811   void type_of_call g3dtom(Float_t *, Float_t *, Int_t &);
00812 
00813   void type_of_call g3lmoth(DEFCHARD, Int_t &, Int_t &, Int_t *,
00814                            Int_t *, Int_t * DEFCHARL);
00815 
00816   void type_of_call g3media(Float_t *, Int_t &, Int_t&);
00817 
00818   void type_of_call g3mtod(Float_t *, Float_t *, Int_t &);
00819 
00820   void type_of_call g3srotm(const Int_t &, const Float_t &, const Float_t &,
00821                            const Float_t &, const Float_t &, const Float_t &,
00822                            const Float_t &);
00823 
00824   void type_of_call g3protm(const Int_t &);
00825 
00826   void type_of_call g3rfile(const Int_t&, DEFCHARD,
00827                            DEFCHARD DEFCHARL DEFCHARL);
00828 
00829   void type_of_call g3fmate(const Int_t&, DEFCHARD, Float_t &, Float_t &,
00830                            Float_t &, Float_t &, Float_t &, Float_t *,
00831                            Int_t& DEFCHARL);
00832 
00833   void type_of_call g3fang( Float_t *, Float_t &,
00834                             Float_t &, Float_t &, Float_t &,
00835                             Int_t & ); 
00836 
00837   void type_of_call g3fpart(const Int_t&, DEFCHARD, Int_t &, Float_t &,
00838                            Float_t &, Float_t &, Float_t *, Int_t & DEFCHARL);
00839 
00840 //sk:begin
00841 //    Modified: S. Kasahara  2007/07/24 Add method to print particles
00842   void type_of_call g3ppart(const Int_t&);
00843 //sk:end
00844 
00845   void type_of_call g3ftmed(const Int_t&, DEFCHARD, Int_t &, Int_t &, Int_t &,
00846                            Float_t &, Float_t &, Float_t &, Float_t &,
00847                            Float_t &, Float_t &, Float_t *, Int_t * DEFCHARL);
00848 
00849 //sk:begin
00850 //    Modified: S. Kasahara  2006/05/19 Add method to print media
00851   void type_of_call g3ptmed(const Int_t&);
00852 //sk:end
00853 
00854   void type_of_call g3ftmat(const Int_t&, const Int_t&, DEFCHARD, const Int_t&,
00855                            Float_t*, Float_t*
00856                            ,Float_t *, Int_t & DEFCHARL);
00857 
00858   void type_of_call g3smate(const Int_t&, DEFCHARD, Float_t &, Float_t &,
00859                            Float_t &, Float_t &, Float_t &, Float_t *,
00860                            Int_t & DEFCHARL);
00861 
00862   void type_of_call g3smixt(const Int_t&, DEFCHARD, const Float_t *,
00863                const Float_t *, const Float_t &, const Int_t &,
00864                Float_t * DEFCHARL);
00865 
00866   void type_of_call g3spart(const Int_t&, DEFCHARD, Int_t &, Float_t &,
00867                            Float_t &, Float_t &, Float_t *, Int_t & DEFCHARL);
00868 
00869 
00870   void type_of_call g3stmed(const Int_t&, DEFCHARD, Int_t &, Int_t &, Int_t &,
00871                            Float_t &, Float_t &, Float_t &, Float_t &,
00872                            Float_t &, Float_t &, Float_t *, Int_t & DEFCHARL);
00873 
00874   void type_of_call g3sckov(Int_t &itmed, Int_t &npckov, Float_t *ppckov,
00875                            Float_t *absco, Float_t *effic, Float_t *rindex);
00876   void type_of_call g3stpar(const Int_t&, DEFCHARD, Float_t & DEFCHARL);
00877 
00878   void type_of_call g3sdvn(DEFCHARD,DEFCHARD, Int_t &, Int_t &
00879                           DEFCHARL DEFCHARL);
00880 
00881   void type_of_call g3sdvn2(DEFCHARD,DEFCHARD, Int_t &, Int_t &, Float_t &,
00882                            Int_t & DEFCHARL DEFCHARL);
00883 
00884   void type_of_call g3sdvs(DEFCHARD,DEFCHARD, Float_t &, Int_t &, Int_t &
00885                           DEFCHARL DEFCHARL);
00886 
00887   void type_of_call g3sdvs2(DEFCHARD,DEFCHARD, Float_t &, Int_t &, Float_t &,
00888                            Int_t & DEFCHARL DEFCHARL);
00889 
00890   void type_of_call g3sdvt(DEFCHARD,DEFCHARD, Float_t &, Int_t &, Int_t &,
00891                           Int_t & DEFCHARL DEFCHARL);
00892 
00893   void type_of_call g3sdvt2(DEFCHARD,DEFCHARD, Float_t &, Int_t &, Float_t&,
00894                            Int_t &, Int_t & DEFCHARL DEFCHARL);
00895 
00896   void type_of_call g3sord(DEFCHARD, Int_t & DEFCHARL);
00897 
00898   void type_of_call g3spos(DEFCHARD, Int_t &, DEFCHARD, Float_t &, Float_t &,
00899                           Float_t &, Int_t &, DEFCHARD DEFCHARL DEFCHARL
00900                           DEFCHARL);
00901 
00902   void type_of_call g3sposp(DEFCHARD, Int_t &, DEFCHARD, Float_t &, Float_t &,
00903                            Float_t &, Int_t &, DEFCHARD,
00904                            Float_t *, Int_t & DEFCHARL DEFCHARL DEFCHARL);
00905 
00906   void type_of_call g3svolu(DEFCHARD, DEFCHARD, Int_t &, Float_t *, Int_t &,
00907                            Int_t & DEFCHARL DEFCHARL);
00908 
00909   void type_of_call g3satt(DEFCHARD, DEFCHARD, Int_t & DEFCHARL DEFCHARL);
00910 
00911   void type_of_call g3fpara(DEFCHARD , Int_t&, Int_t&, Int_t&, Int_t&, 
00912                             Float_t*, Float_t* DEFCHARL);
00913 
00914   void type_of_call gckpar(Int_t&, Int_t&, Float_t*);
00915 
00916   void type_of_call g3ckmat(Int_t&, DEFCHARD DEFCHARL);
00917 
00918   void type_of_call g3lvolu(Int_t&, Int_t*, Int_t*, Int_t&);
00919 
00920   void type_of_call g3print(DEFCHARD,const int& DEFCHARL);
00921 
00922   void type_of_call dzshow(DEFCHARD,const int&,const int&,DEFCHARD,const int&,
00923                            const int&, const int&, const int& DEFCHARL
00924                            DEFCHARL);
00925   void type_of_call mzdrop(Int_t&, Int_t&, DEFCHARD DEFCHARL);
00926 
00927   void type_of_call setbomb(Float_t &);
00928 
00929   void type_of_call setclip(DEFCHARD, Float_t &,Float_t &,Float_t &,Float_t &,
00930                             Float_t &, Float_t & DEFCHARL);
00931 
00932   void type_of_call gcomad(DEFCHARD, Int_t*& DEFCHARL);
00933 
00934   void type_of_call ertrak(const Float_t *const x1, const Float_t *const p1,
00935                            const Float_t *x2, const Float_t *p2,
00936                            const Int_t &ipa, DEFCHARD DEFCHARL);
00937   void type_of_call eufill(Int_t n, Float_t *ein,
00938                        Float_t *xlf);
00939   void type_of_call eufilp(const int n,Float_t *ein,
00940                            Float_t *pli,Float_t *plf);
00941   void type_of_call eufilv(Int_t n, Float_t *ein,
00942                         Char_t *namv, Int_t *numv,Int_t *iovl);
00943   void type_of_call trscsd(Float_t *pc,Float_t *rc,Float_t *pd,Float_t *rd,
00944                          Float_t *h,Float_t ch,Int_t ierr,Float_t spu,Float_t *dj,Float_t *dk);
00945   void type_of_call trsdsc(Float_t *pd,Float_t *rd,Float_t *pc,Float_t *rc,
00946                          Float_t *h,Float_t *ch,Int_t *ierr,Float_t *spu,Float_t *dj,Float_t *dk);
00947   void type_of_call trscsp(Float_t *ps,Float_t *rs,Float_t *pc,Float_t *rc,Float_t *h,
00948                         Float_t *ch,Int_t *ierr,Float_t *spx);
00949   void type_of_call trspsc(Float_t *ps,Float_t *rs,Float_t *pc,Float_t *rc,Float_t *h,
00950                         Float_t *ch,Int_t *ierr,Float_t *spx);
00951 
00952   void type_of_call ertrgo();
00953  
00954     float type_of_call g3brelm(const Float_t &z, const Float_t& t, 
00955                                const Float_t& cut);
00956     float type_of_call g3prelm(const Float_t &z, const Float_t& t, 
00957                                const Float_t& cut);
00958 }
00959 
00960 #ifndef WIN32
00961 #  define gudigi gudigi_
00962 #  define guhadr guhadr_
00963 #  define guout  guout_
00964 #  define guphad guphad_
00965 #  define gudcay gudcay_
00966 #  define guiget guiget_
00967 #  define guinme guinme_
00968 #  define guinti guinti_
00969 #  define gunear gunear_
00970 #  define guskip guskip_
00971 #  define guview guview_
00972 #  define gupara gupara_
00973 #  define gudtim gudtim_
00974 #  define guplsh guplsh_
00975 #  define gutrev gutrev_
00976 #  define gutrak gutrak_
00977 #  define guswim guswim_
00978 #  define gufld  gufld_
00979 #  define gustep gustep_
00980 #  define gukine gukine_
00981 
00982 #  define gheish gheish_
00983 #  define flufin flufin_
00984 #  define gfmfin gfmfin_
00985 #  define gpghei gpghei_
00986 #  define fldist fldist_
00987 #  define gfmdis gfmdis_
00988 #  define g3helx3 g3helx3_
00989 #  define g3helix g3helix_
00990 #  define g3rkuta g3rkuta_
00991 #  define g3track g3track_
00992 #  define gtreveroot gtreveroot_
00993 #  define g3last  g3last_
00994 #  define g3invol g3invol_
00995 #  define g3tmedi g3tmedi_
00996 #  define g3media g3media_
00997 #  define g3tmany g3tmany_
00998 #  define g3tnext g3tnext_
00999 #  define g3gperp g3gperp_
01000 #  define ginvol ginvol_
01001 #  define gtmedi gtmedi_
01002 #  define gtmany gtmany_
01003 #  define gtonly gtonly_
01004 #  define gmedia gmedia_
01005 #  define glvolu glvolu_
01006 #  define gtnext gtnext_
01007 #  define ggperp ggperp_
01008 
01009 #else
01010 #  define gudigi GUDIGI
01011 #  define guhadr GUHADR
01012 #  define guout  GUOUT
01013 #  define guphad GUPHAD
01014 #  define gudcay GUDCAY
01015 #  define guiget GUIGET
01016 #  define guinme GUINME
01017 #  define guinti GUINTI
01018 #  define gunear GUNEAR
01019 #  define guskip GUSKIP
01020 #  define guview GUVIEW
01021 #  define gupara GUPARA
01022 #  define gudtim GUDTIM
01023 #  define guplsh GUPLSH
01024 #  define gutrev GUTREV
01025 #  define gutrak GUTRAK
01026 #  define guswim GUSWIM
01027 #  define gufld  GUFLD
01028 #  define gustep GUSTEP
01029 #  define gukine GUKINE
01030 
01031 #  define gheish GHEISH
01032 #  define flufin FLUFIN
01033 #  define gfmfin GFMFIN
01034 #  define gpghei GPGHEI
01035 #  define fldist FLDIST
01036 #  define gfmdis GFMDIS
01037 #  define g3helx3 G3HELX3
01038 #  define g3helix G3HELIX
01039 #  define g3gperp G3GPERP
01040 #  define g3rkuta G3RKUTA
01041 #  define gtrack GTRACK
01042 #  define gtreveroot GTREVEROOT
01043 #  define glast  GLAST
01044 #  define ginvol GINVOL
01045 #  define gtmedi GTMEDI
01046 #  define gtmany GTMANY
01047 #  define gmedia GMEDIA
01048 #  define glvolu GLVOLU
01049 #  define gtnext GTNEXT
01050 #  define ggperp GGPERP
01051 
01052 #endif
01053 
01054 extern "C" type_of_call void gheish();
01055 extern "C" type_of_call void flufin();
01056 extern "C" type_of_call void gfmfin();
01057 extern "C" type_of_call void gpghei();
01058 extern "C" type_of_call void fldist();
01059 extern "C" type_of_call void gfmdis();
01060 extern "C" type_of_call void g3helx3(Float_t&, Float_t&, Float_t*, Float_t*);
01061 extern "C" type_of_call void g3helix(Float_t&, Float_t&, Float_t*, Float_t*);
01062 extern "C" type_of_call void g3rkuta(Float_t&, Float_t&, Float_t*, Float_t*);
01063 extern "C" type_of_call void g3gperp(Float_t*, Float_t*, Int_t&);
01064 extern "C" type_of_call void g3track();
01065 extern "C" type_of_call void gtreveroot();
01066 extern "C" type_of_call void g3last();
01067 extern "C" type_of_call void g3invol(Float_t*, Int_t&);
01068 extern "C" type_of_call void g3tmedi(Float_t*, Int_t&);
01069 extern "C" type_of_call void g3tmany(Int_t&);
01070 extern "C" type_of_call void g3media(Float_t*, Int_t&, Int_t&);
01071 extern "C" type_of_call void g3tnext();
01072 extern "C" type_of_call void ginvol(Float_t*, Int_t&);
01073 extern "C" type_of_call void gtmedi(Float_t*, Int_t&);
01074 extern "C" type_of_call void gtmany(Int_t&);
01075 extern "C" type_of_call void gtonly(Int_t&);
01076 extern "C" type_of_call void gmedia(Float_t*, Int_t&, Int_t&);
01077 extern "C" type_of_call void glvolu(Int_t &nlev, Int_t *lnam,Int_t *lnum, Int_t &ier);
01078 extern "C" type_of_call void gtnext();
01079 extern "C" type_of_call void ggperp(Float_t*, Float_t*, Int_t&);
01080 
01081 
01082 //
01083 // Geant3 global pointer
01084 //
01085 Gctrak_t *gctrak = 0;
01086 Gcvolu_t *gcvolu = 0;
01087 Gckine_t *gckine = 0;
01088 TGeant3* geant3 = 0;
01089 static const Int_t kDefSize = 600;
01090 Int_t count_ginvol = 0;
01091 Int_t count_gmedia = 0;
01092 Int_t count_gtmedi = 0;
01093 Int_t count_gtnext = 0;
01094 Gcchan_t *gcchan = 0;
01095 
01096 extern "C"  type_of_call void gtonlyg3(Int_t&);
01097 void (*fginvol)(Float_t*, Int_t&) = 0;
01098 void (*fgtmedi)(Float_t*, Int_t&) = 0;
01099 void (*fgtmany)(Int_t&) = 0;
01100 void (*fgtonly)(Int_t&) = 0;
01101 void (*fgmedia)(Float_t*, Int_t&, Int_t&) = 0;
01102 void (*fglvolu)(Int_t &nlev, Int_t *lnam,Int_t *lnum, Int_t &ier) = 0;
01103 void (*fgtnext)() = 0;
01104 void (*fggperp)(Float_t*, Float_t*, Int_t&) = 0;
01105 
01106 //#define STATISTICS
01107 #ifdef STATISTICS
01108 #include "TTree.h"
01109 #include "TFile.h"
01110 Double_t oldvect[6], oldstep, oldsafety;
01111 Int_t statcode, statsame;
01112 Char_t statpath[120];
01113 Double_t statsafety, statsnext;
01114 TTree *stattree =0;
01115 TFile *statfile=0;
01116 #endif
01117 
01118 //______________________________________________________________________
01119 TGeant3::TGeant3()
01120   : TVirtualMC(),
01121     fNG3Particles(0),
01122     fNPDGCodes(0),
01123     fPDGCode(),
01124     fMCGeo(0),
01125     fImportRootGeometry(kFALSE),
01126     fStopRun(kFALSE),
01127 //sk:begin Modified S. Kasahara 2007/09/06 Add member to configure user decay
01128     fUserDecayProductStableMinLifetime(1.E-15)
01129 //sk:end
01130 {
01131   //
01132   // Default constructor
01133   //
01134    geant3 = this;
01135 }
01136 
01137 //______________________________________________________________________
01138 TGeant3::TGeant3(const char *title, Int_t nwgeant)
01139   : TVirtualMC("TGeant3",title, kFALSE),
01140     fNG3Particles(0),
01141     fNPDGCodes(0),
01142     fPDGCode(),
01143     fMCGeo(0),
01144     fImportRootGeometry(kFALSE),
01145     fStopRun(kFALSE),
01146 //sk:begin Modified S. Kasahara 2007/09/06 Add member to configure user decay
01147     fUserDecayProductStableMinLifetime(1.E-15)
01148 //sk:end
01149 {
01150   //
01151   // Standard constructor for TGeant3 with ZEBRA initialization
01152   //
01153 
01154 #ifdef STATISTICS
01155    statfile = new TFile("stat.root","recreate");
01156    stattree = new TTree("stat","stat tree");
01157    stattree->Branch("statcode",&statcode,"statcode/I");
01158    stattree->Branch("statsame",&statsame,"statsame/I");
01159    stattree->Branch("statpath",statpath,"statpath/C");
01160    stattree->Branch("oldvect",oldvect,"oldvect[6]/D");
01161    stattree->Branch("oldsafety",&oldsafety,"oldsafety/D");
01162    stattree->Branch("oldstep",&oldstep,"oldstep/D");
01163    stattree->Branch("snext",&statsnext,"statsnext/D");
01164    stattree->Branch("safety",&statsafety,"statsafety/D");
01165 #endif
01166 
01167   geant3 = this;
01168 
01169   if(nwgeant) {
01170     g3zebra(nwgeant);
01171     g3init();
01172     g3zinit();
01173   } else {
01174     g3cinit();
01175   }
01176   //
01177   // Load Address of Geant3 commons
01178   LoadAddress();
01179   //
01180   // Zero number of particles
01181   fNG3Particles = 0;
01182   fNPDGCodes=0;
01183   
01184   // Set initial size to fPDGCode table
01185   fPDGCode.Set(100);
01186 
01187   //set pointers to tracker functions
01188   fginvol = g3invol;
01189   fgtmedi = g3tmedi;
01190   fgtmany = g3tmany;
01191   fgtonly = gtonlyg3;
01192   fgmedia = g3media;
01193   fglvolu = g3lvolu;
01194   fgtnext = g3tnext;
01195   fggperp = g3gperp;
01196 
01197   InitGEANE();
01198 }
01199 
01200 //______________________________________________________________________
01201 TGeant3::~TGeant3()
01202 {
01203   if(fVolNames) {
01204     delete [] fVolNames;
01205     fVolNames=0;
01206   }
01207 }
01208 
01209 //______________________________________________________________________
01210 Int_t TGeant3::CurrentMaterial(Float_t &a, Float_t &z, Float_t &dens,
01211                                Float_t &radl, Float_t &absl) const
01212 {
01213   //
01214   // Return the parameters of the current material during transport
01215   //
01216   z     = fGcmate->z;
01217   a     = fGcmate->a;
01218   dens  = fGcmate->dens;
01219   radl  = fGcmate->radl;
01220   absl  = fGcmate->absl;
01221   return 1;  //this could be the number of elements in mixture
01222 }
01223 
01224 //______________________________________________________________________
01225 void TGeant3::DefaultRange()
01226 {
01227   //
01228   // Set range of current drawing pad to 20x20 cm
01229   //
01230 }
01231 
01232 //______________________________________________________________________
01233 void TGeant3::InitHIGZ()
01234 {
01235   //
01236   // Initialize HIGZ
01237   //
01238 }
01239 
01240 //______________________________________________________________________
01241 void TGeant3::InitGEANE()
01242 {
01243   //
01244   // Initialize GEANE for default use
01245   //
01246   Float_t pf[3]={0.,0.,0.};
01247   Float_t w1[3]={0.,0.,0.};
01248   Float_t w2[3]={0.,0.,0.};
01249   Float_t p1[3]={0.,0.,0.};
01250   Float_t p2[3]={0.,0.,0.};
01251   Float_t p3[3]={0.,0.,0.};
01252   Float_t cl[3]={0.,0.,0.};
01253   geant3 = this;
01254   geant3->SetECut(1.);
01255   geant3->SetClose(0,pf,999.,w1,w2,p1,p2,p3,cl);
01256 }
01257 
01258 //______________________________________________________________________
01259 void TGeant3::LoadAddress()
01260 {
01261   //
01262   // Assigns the address of the GEANT common blocks to the structures
01263   // that allow their access from C++
01264   //
01265    Int_t *addr;
01266    gcomad(PASSCHARD("QUEST"), (int*&) fQuest PASSCHARL("QUEST"));
01267    gcomad(PASSCHARD("GCBANK"),(int*&) fGcbank  PASSCHARL("GCBANK"));
01268    gcomad(PASSCHARD("GCLINK"),(int*&) fGclink  PASSCHARL("GCLINK"));
01269    gcomad(PASSCHARD("GCCUTS"),(int*&) fGccuts  PASSCHARL("GCCUTS"));
01270    gcomad(PASSCHARD("GCMORE"),(int*&) fGcmore  PASSCHARL("GCMORE"));
01271    gcomad(PASSCHARD("GCMULO"),(int*&) fGcmulo  PASSCHARL("GCMULO"));
01272    gcomad(PASSCHARD("GCFLAG"),(int*&) fGcflag  PASSCHARL("GCFLAG"));
01273    gcomad(PASSCHARD("GCKINE"),(int*&) fGckine  PASSCHARL("GCKINE"));
01274    gcomad(PASSCHARD("GCKING"),(int*&) fGcking  PASSCHARL("GCKING"));
01275    gcomad(PASSCHARD("GCKIN2"),(int*&) fGckin2  PASSCHARL("GCKIN2"));
01276    gcomad(PASSCHARD("GCKIN3"),(int*&) fGckin3  PASSCHARL("GCKIN3"));
01277    gcomad(PASSCHARD("GCMATE"),(int*&) fGcmate  PASSCHARL("GCMATE"));
01278    gcomad(PASSCHARD("GCTMED"),(int*&) fGctmed  PASSCHARL("GCTMED"));
01279    gcomad(PASSCHARD("GCTRAK"),(int*&) fGctrak  PASSCHARL("GCTRAK"));
01280    gcomad(PASSCHARD("GCTPOL"),(int*&) fGctpol  PASSCHARL("GCTPOL"));
01281    gcomad(PASSCHARD("GCVOLU"),(int*&) fGcvolu  PASSCHARL("GCVOLU"));
01282    gcomad(PASSCHARD("GCNUM"), (int*&) fGcnum   PASSCHARL("GCNUM"));
01283    gcomad(PASSCHARD("GCSETS"),(int*&) fGcsets  PASSCHARL("GCSETS"));
01284    gcomad(PASSCHARD("GCPHYS"),(int*&) fGcphys  PASSCHARL("GCPHYS"));
01285    gcomad(PASSCHARD("GCPHLT"),(int*&) fGcphlt  PASSCHARL("GCPHLT"));
01286    gcomad(PASSCHARD("GCOPTI"),(int*&) fGcopti  PASSCHARL("GCOPTI"));
01287    gcomad(PASSCHARD("GCTLIT"),(int*&) fGctlit  PASSCHARL("GCTLIT"));
01288    gcomad(PASSCHARD("GCVDMA"),(int*&) fGcvdma  PASSCHARL("GCVDMA"));
01289    gcomad(PASSCHARD("GCCHAN"),(int*&) gcchan   PASSCHARL("GCCHAN"));
01290 
01291    // Commons for GEANE
01292    gcomad(PASSCHARD("ERTRIO"),(int*&) fErtrio  PASSCHARL("ERTRIO"));
01293    gcomad(PASSCHARD("EROPTS"),(int*&) fEropts  PASSCHARL("EROPTS"));
01294    gcomad(PASSCHARD("EROPTC"),(int*&) fEroptc  PASSCHARL("EROPTC"));
01295    gcomad(PASSCHARD("ERWORK"),(int*&) fErwork  PASSCHARL("ERWORK"));
01296 
01297 //sk:begin
01298 //    Modified: S. Kasahara  2006/05/07
01299 //    Add section for G3PTSim customization commons
01300    gcomad(PASSCHARD("PTOPTS"),(int*&) fPtopts  PASSCHARL("PTOPTS"));
01301    fPtopts -> use_alt_dedx = 1;  // default
01302 //sk:end
01303 
01304    // Variables for ZEBRA store
01305    gcomad(PASSCHARD("IQ"), addr  PASSCHARL("IQ"));
01306    fZiq = addr;
01307    gcomad(PASSCHARD("LQ"), addr  PASSCHARL("LQ"));
01308    fZlq = addr;
01309    fZq       = (float*)fZiq;
01310    gctrak = fGctrak;
01311    gcvolu = fGcvolu;
01312    gckine = fGckine;
01313 }
01314 
01315 //______________________________________________________________________
01316 void TGeant3::GeomIter()
01317 {
01318   //
01319   // Geometry iterator for moving upward in the geometry tree
01320   // Initialize the iterator
01321   //
01322   fNextVol=fGcvolu->nlevel;
01323 }
01324 
01325 //______________________________________________________________________
01326 Int_t TGeant3::NextVolUp(Text_t *name, Int_t &copy)
01327 {
01328   //
01329   // Geometry iterator for moving upward in the geometry tree
01330   // Return next volume up
01331   //
01332   fNextVol--;
01333   Int_t i, gname;
01334   if(fNextVol>=0) {
01335     gname=fGcvolu->names[fNextVol];
01336     copy=fGcvolu->number[fNextVol];
01337     i=fGcvolu->lvolum[fNextVol];
01338     name = fVolNames[i-1];
01339     if(gname == fZiq[fGclink->jvolum+i]) return i;
01340     else printf("GeomTree: Volume %s not found in bank\n",name);
01341   }
01342   return 0;
01343 }
01344 
01345 //______________________________________________________________________
01346 void TGeant3::BuildPhysics()
01347 {
01348   Gphysi();
01349 }
01350 
01351 //______________________________________________________________________
01352 void TGeant3::AddParticlesToPdgDataBase() const
01353 {
01354 
01355 //
01356 // Add particles to the PDG data base
01357 
01358     TDatabasePDG *pdgDB = TDatabasePDG::Instance();
01359 
01360     const Double_t kAu2Gev=0.9314943228;
01361     const Double_t khSlash = 1.0545726663e-27;
01362     const Double_t kErg2Gev = 1/1.6021773349e-3;
01363     const Double_t khShGev = khSlash*kErg2Gev;
01364     const Double_t kYear2Sec = 3600*24*365.25;
01365 //
01366 // Bottom mesons
01367 // mass and life-time from PDG
01368 //
01369 // Done by default now from Pythia6 table!
01370 //
01371 //
01372 // Ions
01373 //
01374 
01375   if ( !pdgDB->GetParticle(GetIonPdg(1,2)) )
01376     pdgDB->AddParticle("Deuteron","Deuteron",2*kAu2Gev+8.071e-3,kTRUE,
01377                        0,3,"Ion",GetIonPdg(1,2));
01378 
01379   if ( !pdgDB->GetParticle(GetIonPdg(1,3)) )
01380     pdgDB->AddParticle("Triton","Triton",3*kAu2Gev+14.931e-3,kFALSE,
01381                        khShGev/(12.33*kYear2Sec),3,"Ion",GetIonPdg(1,3));
01382 
01383   if ( !pdgDB->GetParticle(GetIonPdg(2,4)) )
01384     pdgDB->AddParticle("Alpha","Alpha",4*kAu2Gev+2.424e-3,kTRUE,
01385                        khShGev/(12.33*kYear2Sec),6,"Ion",GetIonPdg(2,4));
01386 
01387   if ( !pdgDB->GetParticle(GetIonPdg(2,3)) )
01388     pdgDB->AddParticle("HE3","HE3",3*kAu2Gev+14.931e-3,kFALSE,
01389                        0,6,"Ion",GetIonPdg(2,3));
01390 
01391 // Special particles
01392 //
01393   if ( !pdgDB->GetParticle(GetSpecialPdg(50)) )
01394     pdgDB->AddParticle("Cherenkov","Cherenkov",0,kFALSE,
01395                        0,0,"Special",GetSpecialPdg(50));
01396 
01397   if ( !pdgDB->GetParticle(GetSpecialPdg(51)) )
01398     pdgDB->AddParticle("FeedbackPhoton","FeedbackPhoton",0,kFALSE,
01399                        0,0,"Special",GetSpecialPdg(51));
01400 
01401 }
01402 
01403 
01404 //______________________________________________________________________
01405 Int_t TGeant3::CurrentVolID(Int_t &copy) const
01406 {
01407   //
01408   // Returns the current volume ID and copy number
01409   //
01410   Int_t i, gname;
01411   if( (i=fGcvolu->nlevel-1) < 0 ) {
01412     Warning("CurrentVolID","Stack depth only %d\n",fGcvolu->nlevel);
01413   } else {
01414     gname=fGcvolu->names[i];
01415     copy=fGcvolu->number[i];
01416     i=fGcvolu->lvolum[i];
01417     if(gname == fZiq[fGclink->jvolum+i]) return i;
01418     else Warning("CurrentVolID","Volume %4s not found\n",(char*)&gname);
01419   }
01420   return 0;
01421 }
01422 
01423 //______________________________________________________________________
01424 Int_t TGeant3::CurrentVolOffID(Int_t off, Int_t &copy) const
01425 {
01426   //
01427   // Return the current volume "off" upward in the geometrical tree
01428   // ID and copy number
01429   //
01430   Int_t i, gname;
01431   if( (i=fGcvolu->nlevel-off-1) < 0 ) {
01432     Warning("CurrentVolOffID","Offset requested %d but stack depth %d\n",
01433             off,fGcvolu->nlevel);
01434   } else {
01435     gname=fGcvolu->names[i];
01436     copy=fGcvolu->number[i];
01437     i=fGcvolu->lvolum[i];
01438     if(gname == fZiq[fGclink->jvolum+i]) return i;
01439     else Warning("CurrentVolOffID","Volume %4s not found\n",(char*)&gname);
01440   }
01441   return 0;
01442 }
01443 
01444 //______________________________________________________________________
01445 const char* TGeant3::CurrentVolName() const
01446 {
01447   //
01448   // Returns the current volume name
01449   //
01450   Int_t i;
01451   if( (i=fGcvolu->nlevel-1) < 0 ) {
01452     Warning("CurrentVolName","Stack depth %d\n",fGcvolu->nlevel);
01453     return 0;
01454   }
01455   Int_t gname=fGcvolu->names[i];
01456   i=fGcvolu->lvolum[i];
01457   if(gname == fZiq[fGclink->jvolum+i]) return fVolNames[i-1];
01458   else Warning("CurrentVolName","Volume %4s not found\n",(char*) &gname);
01459   return 0;
01460 }
01461 
01462 //______________________________________________________________________
01463 const char* TGeant3::CurrentVolOffName(Int_t off) const
01464 {
01465   //
01466   // Return the current volume "off" upward in the geometrical tree
01467   // ID, name and copy number
01468   // if name=0 no name is returned
01469   //
01470   Int_t i;
01471   if( (i=fGcvolu->nlevel-off-1) < 0 ) {
01472     Warning("CurrentVolOffName",
01473             "Offset requested %d but stack depth %d\n",off,fGcvolu->nlevel);
01474     return 0;
01475   }
01476   Int_t gname=fGcvolu->names[i];
01477   i=fGcvolu->lvolum[i];
01478   if(gname == fZiq[fGclink->jvolum+i]) return fVolNames[i-1];
01479   else Warning("CurrentVolOffName","Volume %4s not found\n",(char*)&gname);
01480   return 0;
01481 }
01482 
01483 //______________________________________________________________________
01484 const char* TGeant3::CurrentVolPath()
01485 {
01486 // Return the path in geometry tree for the current volume
01487 // ---
01488 
01489   return GetPath();
01490 }
01491 
01492 //______________________________________________________________________
01493 Int_t TGeant3::IdFromPDG(Int_t pdg) const
01494 {
01495   //
01496   // Return Geant3 code from PDG and pseudo ENDF code
01497   //
01498   for(Int_t i=0;i<fNPDGCodes;++i)
01499     if(pdg==fPDGCode[i]) return i;
01500   return -1;
01501 }
01502 
01503 //______________________________________________________________________
01504 Int_t TGeant3::PDGFromId(Int_t id) const
01505 {
01506   //
01507   // Return PDG code and pseudo ENDF code from Geant3 code
01508   //
01509   if(id>0 && id<fNPDGCodes) return fPDGCode[id];
01510   else return -1;
01511 }
01512 
01513 //______________________________________________________________________
01514 void TGeant3::DefineParticles()
01515 {
01516   //
01517   // Define standard Geant 3 particles
01518   Gpart();
01519   //
01520   // Load standard numbers for GEANT particles and PDG conversion
01521   fPDGCode[fNPDGCodes++]=-99;   //  0 = unused location
01522   fPDGCode[fNPDGCodes++]=22;    //  1 = photon
01523   fPDGCode[fNPDGCodes++]=-11;   //  2 = positron
01524   fPDGCode[fNPDGCodes++]=11;    //  3 = electron
01525   fPDGCode[fNPDGCodes++]=12;    //  4 = neutrino e
01526   fPDGCode[fNPDGCodes++]=-13;   //  5 = muon +
01527   fPDGCode[fNPDGCodes++]=13;    //  6 = muon -
01528   fPDGCode[fNPDGCodes++]=111;   //  7 = pi0
01529   fPDGCode[fNPDGCodes++]=211;   //  8 = pi+
01530   fPDGCode[fNPDGCodes++]=-211;  //  9 = pi-
01531   fPDGCode[fNPDGCodes++]=130;   // 10 = Kaon Long
01532   fPDGCode[fNPDGCodes++]=321;   // 11 = Kaon +
01533   fPDGCode[fNPDGCodes++]=-321;  // 12 = Kaon -
01534   fPDGCode[fNPDGCodes++]=2112;  // 13 = Neutron
01535   fPDGCode[fNPDGCodes++]=2212;  // 14 = Proton
01536   fPDGCode[fNPDGCodes++]=-2212; // 15 = Anti Proton
01537   fPDGCode[fNPDGCodes++]=310;   // 16 = Kaon Short
01538   fPDGCode[fNPDGCodes++]=221;   // 17 = Eta
01539   fPDGCode[fNPDGCodes++]=3122;  // 18 = Lambda
01540   fPDGCode[fNPDGCodes++]=3222;  // 19 = Sigma +
01541   fPDGCode[fNPDGCodes++]=3212;  // 20 = Sigma 0
01542   fPDGCode[fNPDGCodes++]=3112;  // 21 = Sigma -
01543   fPDGCode[fNPDGCodes++]=3322;  // 22 = Xi0
01544   fPDGCode[fNPDGCodes++]=3312;  // 23 = Xi-
01545   fPDGCode[fNPDGCodes++]=3334;  // 24 = Omega-
01546   fPDGCode[fNPDGCodes++]=-2112; // 25 = Anti Neutron
01547   fPDGCode[fNPDGCodes++]=-3122; // 26 = Anti Lambda
01548   fPDGCode[fNPDGCodes++]=-3222; // 27 = Anti Sigma -
01549   fPDGCode[fNPDGCodes++]=-3212; // 28 = Anti Sigma 0
01550   fPDGCode[fNPDGCodes++]=-3112; // 29 = Anti Sigma +
01551   fPDGCode[fNPDGCodes++]=-3322; // 30 = Anti Xi 0      
01552   fPDGCode[fNPDGCodes++]=-3312; // 31 = Anti Xi +
01553   fPDGCode[fNPDGCodes++]=-3334; // 32 = Anti Omega +
01554 
01555 
01556   Int_t mode[6];
01557   Int_t kz, ipa;
01558   Float_t bratio[6];
01559 
01560   fNG3Particles = 33;
01561 
01562   /* --- Define additional particles */
01563   Gspart(fNG3Particles++,"OMEGA(782)",3,0.782,0.,7.836e-23);// 33 = OMEGA(782)
01564   fPDGCode[fNPDGCodes++]=223;   // 33 = Omega(782)
01565 
01566   Gspart(fNG3Particles++,"PHI(1020)",3,1.019,0.,1.486e-22);// 34 = PHI(1020)
01567   fPDGCode[fNPDGCodes++]=333;   // 34 = PHI (1020)
01568 
01569   Gspart(fNG3Particles++, "D +", 4, 1.8693, 1., 1.040e-12);      // 35 = D+        // G4DMesonPlus
01570   fPDGCode[fNPDGCodes++]=411;   // 35 = D+
01571 
01572   Gspart(fNG3Particles++, "D -", 4, 1.8693, -1., 1.040e-12);     // 36 = D-        // G4DMesonMinus
01573   fPDGCode[fNPDGCodes++]=-411;  // 36 = D-
01574 
01575   Gspart(fNG3Particles++, "D 0", 3, 1.8645, 0., 0.415e-12);      // 37 = D0        // G4DMesonZero
01576   fPDGCode[fNPDGCodes++]=421;   // 37 = D0
01577 
01578   Gspart(fNG3Particles++,"ANTI D 0",3,1.8645,0.,0.415e-12);      // 38 = Anti D0   // G4AntiDMesonZero
01579   fPDGCode[fNPDGCodes++]=-421;  // 38 = D0 bar
01580 
01581 
01582   fNG3Particles++;
01583   fPDGCode[fNPDGCodes++]=-99;  // 39 = unassigned
01584 
01585   fNG3Particles++;
01586   fPDGCode[fNPDGCodes++]=-99;  // 40 = unassigned
01587 
01588   fNG3Particles++;
01589   fPDGCode[fNPDGCodes++]=-99;  // 41 = unassigned
01590 
01591   Gspart(fNG3Particles++, "RHO +", 4, 0.768, 1., 4.353e-24);  // 42 = Rho+
01592   fPDGCode[fNPDGCodes++]=213;   // 42 = RHO+
01593 
01594   Gspart(fNG3Particles++, "RHO -", 4, 0.768, -1., 4.353e-24); // 43 = Rho-
01595   fPDGCode[fNPDGCodes++]=-213;   // 43 = RHO-
01596 
01597   Gspart(fNG3Particles++, "RHO 0", 3, 0.768, 0., 4.353e-24);  // 44 = Rho0
01598   fPDGCode[fNPDGCodes++]=113;   //  44 = RHO0
01599 
01600 //
01601 // Ions
01602 
01603   fNG3Particles++;
01604   fPDGCode[fNPDGCodes++]=GetIonPdg(1, 2); // 45 = Deuteron
01605 
01606   fNG3Particles++;
01607   fPDGCode[fNPDGCodes++]=GetIonPdg(1, 3); // 46 = Triton
01608 
01609   fNG3Particles++;
01610   fPDGCode[fNPDGCodes++]=GetIonPdg(2, 4); // 47 = Alpha
01611 
01612   fNG3Particles++;
01613   fPDGCode[fNPDGCodes++]=0;               // 48 = geantino mapped to rootino
01614 
01615   fNG3Particles++;
01616   fPDGCode[fNPDGCodes++]=GetIonPdg(2, 3); // 49 = HE3
01617 
01618   fNG3Particles++;
01619   fPDGCode[fNPDGCodes++]=GetSpecialPdg(50); // 50 = Cherenkov
01620 // special
01621   Gspart(fNG3Particles++, "FeedbackPhoton", 7, 0., 0.,1.e20 );
01622   fPDGCode[fNPDGCodes++]=GetSpecialPdg(51); // 51 = FeedbackPhoton
01623 //
01624 
01625   Gspart(fNG3Particles++, "Lambda_c-", 4, 2.28646, +1., 2.06e-13);
01626   // Gspart(fNG3Particles++, "Lambda_c+", 4, 2.28646, +1., 0.200e-12); // G4LambdacPlus
01627   fPDGCode[fNPDGCodes++]=4122;         //52 = Lambda_c+
01628 
01629   Gspart(fNG3Particles++, "Lambda_c-", 4, 2.28646, -1., 2.06e-13);
01630   // Gspart(fNG3Particles++, "Lambda_c-", 4, 2.2849, -1., 0.200e-12);  // G4AntiLamdacPlus
01631   fPDGCode[fNPDGCodes++]=-4122;        //53 = Lambda_c-
01632 
01633   Gspart(fNG3Particles++, "D_s+", 4, 1.9682, +1., 0.490e-12);       // G4DsMesonPlus * booklet (July 2006): lifetime=0.500e-12  
01634   fPDGCode[fNPDGCodes++]=431;          //54 = D_s+
01635 
01636   Gspart(fNG3Particles++, "D_s-", 4, 1.9682, -1., 0.490e-12);       // G4DsMesonMinus * booklet: lifetime=0.500e-12
01637   fPDGCode[fNPDGCodes++]=-431;         //55 = D_s-
01638 
01639   Gspart(fNG3Particles++, "Tau+", 5, 1.77699, +1., 290.6e-15);      // G4TauPlus *
01640   fPDGCode[fNPDGCodes++]=-15;          //56 = Tau+
01641 
01642   Gspart(fNG3Particles++, "Tau-", 5, 1.77699, -1., 290.6e-15);      // G4TauMinus *
01643   fPDGCode[fNPDGCodes++]= 15;          //57 = Tau-
01644 
01645   Gspart(fNG3Particles++, "B0",     3, 5.2794, +0., 1.532e-12);     // G4BMesonZero
01646   fPDGCode[fNPDGCodes++]=511;          //58 = B0
01647 
01648   Gspart(fNG3Particles++, "B0 bar", 3, 5.2794, -0., 1.532e-12);     // G4AntiBMesonZero
01649   fPDGCode[fNPDGCodes++]=-511;         //58 = B0bar
01650 
01651   Gspart(fNG3Particles++, "B+",     4, 5.2790, +1., 1.638e-12);     // G4BMesonPlus *
01652   fPDGCode[fNPDGCodes++]=521;          //60 = B+
01653 
01654   Gspart(fNG3Particles++, "B-",     4, 5.2790, -1., 1.638e-12);     // G4BMesonMinus *
01655   fPDGCode[fNPDGCodes++]=-521;         //61 = B-
01656 
01657   Gspart(fNG3Particles++, "Bs",     3, 5.3675, +0., 1.466e-12);     // G4BsMesonZero
01658   fPDGCode[fNPDGCodes++]=531;          //62 = B_s
01659 
01660   Gspart(fNG3Particles++, "Bs bar", 3, 5.3675, -0., 1.466e-12);     // G4AntiBsMesonZero
01661   fPDGCode[fNPDGCodes++]=-531;         //63 = B_s bar
01662 
01663   Gspart(fNG3Particles++, "Lambda_b",     3, 5.624, +0., 1.24e-12);
01664   fPDGCode[fNPDGCodes++]=5122;         //64 = Lambda_b
01665 
01666   Gspart(fNG3Particles++, "Lambda_b bar", 3, 5.624, -0., 1.24e-12);
01667   fPDGCode[fNPDGCodes++]=-5122;        //65 = Lambda_b bar
01668 
01669   Gspart(fNG3Particles++, "J/Psi",       3, 3.096916, 0., 7.6e-21);   // G4JPsi
01670   fPDGCode[fNPDGCodes++]=443;          // 66 = J/Psi
01671 
01672   Gspart(fNG3Particles++, "Psi Prime",   3, 3.686,   0., 0.);
01673   fPDGCode[fNPDGCodes++]=20443;        // 67 = Psi prime
01674 
01675   Gspart(fNG3Particles++, "Upsilon(1S)", 3, 9.46037, 0., 0.);
01676   fPDGCode[fNPDGCodes++]=553;          // 68 = Upsilon(1S)
01677 
01678   Gspart(fNG3Particles++, "Upsilon(2S)", 3, 10.0233, 0., 0.);
01679   fPDGCode[fNPDGCodes++]=20553;        // 69 = Upsilon(2S)
01680 
01681   Gspart(fNG3Particles++, "Upsilon(3S)", 3, 10.3553, 0., 0.);
01682   fPDGCode[fNPDGCodes++]=30553;        // 70 = Upsilon(3S)
01683 
01684   Gspart(fNG3Particles++, "Anti Neutrino (e)",       3, 0., 0., 1.e20);
01685   fPDGCode[fNPDGCodes++]=-12;          // 71 = anti electron neutrino
01686 
01687   Gspart(fNG3Particles++, "Neutrino (mu)",           3, 0., 0., 1.e20);
01688   fPDGCode[fNPDGCodes++]=14;           // 72 = muon neutrino
01689 
01690   Gspart(fNG3Particles++, "Anti Neutrino (mu)", 3, 0., 0., 1.e20);
01691   fPDGCode[fNPDGCodes++]=-14;          // 73 = anti muon neutrino
01692 
01693   Gspart(fNG3Particles++, "Neutrino (tau)",     3, 0., 0., 1.e20);
01694   fPDGCode[fNPDGCodes++]=16;           // 74 = tau neutrino
01695 
01696   Gspart(fNG3Particles++, "Anti Neutrino (tau)",3, 0., 0., 1.e20);
01697   fPDGCode[fNPDGCodes++]=-16;          // 75 = anti tau neutrino
01698 
01699 /* --- Define additional decay modes --- */
01700 /* --- omega(783) --- */
01701     for (kz = 0; kz < 6; ++kz) {
01702         bratio[kz] = 0.;
01703         mode[kz] = 0;
01704     }
01705     ipa = 33;
01706     bratio[0] = 89.;
01707     bratio[1] = 8.5;
01708     bratio[2] = 2.5;
01709     mode[0] = 70809;
01710     mode[1] = 107;
01711     mode[2] = 908;
01712     Gsdk(ipa, bratio, mode);
01713 /* --- phi(1020) --- */
01714     for (kz = 0; kz < 6; ++kz) {
01715         bratio[kz] = 0.;
01716         mode[kz] = 0;
01717     }
01718     ipa = 34;
01719     bratio[0] = 49.;
01720     bratio[1] = 34.4;
01721     bratio[2] = 12.9;
01722     bratio[3] = 2.4;
01723     bratio[4] = 1.3;
01724     mode[0] = 1112;
01725     mode[1] = 1610;
01726     mode[2] = 4407;
01727     mode[3] = 90807;
01728     mode[4] = 1701;
01729     Gsdk(ipa, bratio, mode);
01730 /* --- D+ --- */
01731     /*
01732     for (kz = 0; kz < 6; ++kz) {
01733         bratio[kz] = 0.;
01734         mode[kz] = 0;
01735     }
01736     ipa = 35;
01737     bratio[0] = 25.;
01738     bratio[1] = 25.;
01739     bratio[2] = 25.;
01740     bratio[3] = 25.;
01741     mode[0] = 80809;
01742     mode[1] = 120808;
01743     mode[2] = 111208;
01744     mode[3] = 110809;
01745     Gsdk(ipa, bratio, mode);
01746     */
01747 /* --- D- --- */
01748     /*
01749     for (kz = 0; kz < 6; ++kz) {
01750         bratio[kz] = 0.;
01751         mode[kz] = 0;
01752     }
01753     ipa = 36;
01754     bratio[0] = 25.;
01755     bratio[1] = 25.;
01756     bratio[2] = 25.;
01757     bratio[3] = 25.;
01758     mode[0] = 90908;
01759     mode[1] = 110909;
01760     mode[2] = 121109;
01761     mode[3] = 120908;
01762     Gsdk(ipa, bratio, mode);
01763     */
01764 /* --- D0 --- */
01765     /*
01766     for (kz = 0; kz < 6; ++kz) {
01767         bratio[kz] = 0.;
01768         mode[kz] = 0;
01769     }
01770     ipa = 37;
01771     bratio[0] = 33.;
01772     bratio[1] = 33.;
01773     bratio[2] = 33.;
01774     mode[0] = 809;
01775     mode[1] = 1208;
01776     mode[2] = 1112;
01777     Gsdk(ipa, bratio, mode);
01778     */
01779 /* --- Anti D0 --- */
01780     /*
01781     for (kz = 0; kz < 6; ++kz) {
01782         bratio[kz] = 0.;
01783         mode[kz] = 0;
01784     }
01785     ipa = 38;
01786     bratio[0] = 33.;
01787     bratio[1] = 33.;
01788     bratio[2] = 33.;
01789     mode[0] = 809;
01790     mode[1] = 1109;
01791     mode[2] = 1112;
01792     Gsdk(ipa, bratio, mode);
01793     */
01794 /* --- rho+ --- */
01795     for (kz = 0; kz < 6; ++kz) {
01796         bratio[kz] = 0.;
01797         mode[kz] = 0;
01798     }
01799     ipa = 42;
01800     bratio[0] = 100.;
01801     mode[0] = 807;
01802     Gsdk(ipa, bratio, mode);
01803 /* --- rho- --- */
01804     for (kz = 0; kz < 6; ++kz) {
01805         bratio[kz] = 0.;
01806         mode[kz] = 0;
01807     }
01808     ipa = 43;
01809     bratio[0] = 100.;
01810     mode[0] = 907;
01811     Gsdk(ipa, bratio, mode);
01812 /* --- rho0 --- */
01813     for (kz = 0; kz < 6; ++kz) {
01814         bratio[kz] = 0.;
01815         mode[kz] = 0;
01816     }
01817     ipa = 44;
01818     bratio[0] = 100.;
01819     mode[0] = 809;
01820     Gsdk(ipa, bratio, mode);
01821     /*
01822 // --- jpsi ---
01823     for (kz = 0; kz < 6; ++kz) {
01824         bratio[kz] = 0.;
01825         mode[kz] = 0;
01826     }
01827     ipa = 113;
01828     bratio[0] = 50.;
01829     bratio[1] = 50.;
01830     mode[0] = 506;
01831     mode[1] = 605;
01832     Gsdk(ipa, bratio, mode);
01833 // --- upsilon ---
01834     ipa = 114;
01835     Gsdk(ipa, bratio, mode);
01836 // --- phi ---
01837     ipa = 115;
01838     Gsdk(ipa, bratio, mode);
01839     */
01840 //
01841     AddParticlesToPdgDataBase();
01842 }
01843 
01844 //______________________________________________________________________
01845 Int_t TGeant3::VolId(const Text_t *name) const
01846 {
01847   //
01848   // Return the unique numeric identifier for volume name
01849   //
01850   Int_t gname,i;
01851   strncpy((char *) &gname, name, 4);
01852   for(i=1; i<=fGcnum->nvolum; i++)
01853     if(gname == fZiq[fGclink->jvolum+i]) return i;
01854   printf("VolId: Volume %s not found\n",name);
01855   return 0;
01856 }
01857 
01858 //______________________________________________________________________
01859 Int_t TGeant3::MediumId(const Text_t *medName) const
01860 {
01861     // Return the unique numeric identifier for medium name                  
01862 
01863   Int_t nmed = fMedNames.GetEntriesFast();
01864   for ( Int_t imed = 1; imed < nmed; imed++ ) {
01865   
01866     TString name = ((TObjString*)fMedNames.At(imed))->GetString();
01867     if ( name == TString(medName) )  return imed;
01868   }
01869   printf("MediumId: Medium %s not found\n", medName);
01870   return 0;
01871 }      
01872         
01873 //______________________________________________________________________
01874 Int_t TGeant3::NofVolumes() const
01875 {
01876   //
01877   // Return total number of volumes in the geometry
01878   //
01879   return fGcnum->nvolum;
01880 }
01881 
01882 //______________________________________________________________________
01883 Int_t TGeant3::NofVolDaughters(const char* volName) const
01884 {
01885 // Return number of daughters of the volume specified by volName
01886 // According to A. Morsch' G3toRoot class
01887 // ---
01888 
01889   Int_t idvol = VolId(volName);
01890 
01891   Int_t jvo = fZlq[fGclink->jvolum-idvol];
01892   Int_t nin = Int_t(fZq[jvo+3]);
01893   return nin;
01894 }
01895 
01896 //______________________________________________________________________
01897 const char*  TGeant3::VolDaughterName(const char* volName, Int_t i) const
01898 {
01899 // Return the name of i-th daughters of the volume specified by volName
01900 // According to A. Morsch' G3toRoot class
01901 // ---
01902 
01903   Int_t idvol = VolId(volName);
01904 
01905   Int_t jvo = fZlq[fGclink->jvolum-idvol];
01906   Int_t nin=i+1;
01907   Int_t jin = fZlq[jvo-nin];
01908   Int_t idvold = Int_t(fZq[jin+2]);;
01909 
01910   return VolName(idvold);
01911 }
01912 
01913 
01914 //______________________________________________________________________
01915 Int_t TGeant3::VolDaughterCopyNo(const char* volName, Int_t i) const
01916 {
01917 // Return the copyNo of i-th daughters of the volume specified by volName
01918 // According to A. Morsch' G3toRoot class
01919 // ---
01920 
01921   Int_t idvol = VolId(volName);
01922 
01923   Int_t jvo = fZlq[fGclink->jvolum-idvol];
01924   Int_t nin=i+1;
01925   Int_t jin = fZlq[jvo-nin];
01926 
01927   return  Int_t(fZq[jin +3]);
01928 }
01929 
01930 //______________________________________________________________________
01931 Int_t TGeant3::VolId2Mate(Int_t id) const
01932 {
01933   //
01934   // Return material number for a given volume id
01935   //
01936   if(id<1 || id > fGcnum->nvolum || fGclink->jvolum<=0)
01937     return 0;
01938   else {
01939     Int_t jvo = fZlq[fGclink->jvolum-id];
01940     return Int_t(fZq[jvo+4]);
01941   }
01942 }
01943 
01944 //______________________________________________________________________
01945 const char* TGeant3::VolName(Int_t id) const
01946 {
01947   //
01948   // Return the volume name given the volume identifier
01949   //
01950   if(id<1 || id > fGcnum->nvolum || fGclink->jvolum<=0)
01951     return fVolNames[fGcnum->nvolum];
01952   else
01953     return fVolNames[id-1];
01954 }
01955 
01956 //______________________________________________________________________
01957 Bool_t  TGeant3::SetCut(const char* cutName, Double_t cutValue)
01958 {
01959   //
01960   // Set transport cuts for particles
01961   //
01962   Bool_t success = kTRUE;
01963 
01964   if(!strcmp(cutName,"CUTGAM"))
01965     fGccuts->cutgam=cutValue;
01966   else if(!strcmp(cutName,"CUTELE"))
01967     fGccuts->cutele=cutValue;
01968   else if(!strcmp(cutName,"CUTNEU"))
01969     fGccuts->cutneu=cutValue;
01970   else if(!strcmp(cutName,"CUTHAD"))
01971     fGccuts->cuthad=cutValue;
01972   else if(!strcmp(cutName,"CUTMUO"))
01973     fGccuts->cutmuo=cutValue;
01974   else if(!strcmp(cutName,"BCUTE"))
01975     fGccuts->bcute=cutValue;
01976   else if(!strcmp(cutName,"BCUTM"))
01977     fGccuts->bcutm=cutValue;
01978   else if(!strcmp(cutName,"DCUTE"))
01979     fGccuts->dcute=cutValue;
01980   else if(!strcmp(cutName,"DCUTM"))
01981     fGccuts->dcutm=cutValue;
01982   else if(!strcmp(cutName,"PPCUTM"))
01983     fGccuts->ppcutm=cutValue;
01984   else if(!strcmp(cutName,"TOFMAX"))
01985     fGccuts->tofmax=cutValue;
01986   else {
01987     Warning("SetCut","Cut %s not implemented\n",cutName);
01988     success = kFALSE;
01989   }
01990 
01991   return success;
01992 }
01993 
01994 //______________________________________________________________________
01995 Bool_t  TGeant3::SetProcess(const char* flagName, Int_t flagValue)
01996 {
01997   //
01998   // Set thresholds for different processes
01999   //
02000   Bool_t success = kTRUE;
02001 
02002   if(!strcmp(flagName,"PAIR"))
02003     fGcphys->ipair=flagValue;
02004   else if(!strcmp(flagName,"COMP"))
02005     fGcphys->icomp=flagValue;
02006   else if(!strcmp(flagName,"PHOT"))
02007     fGcphys->iphot=flagValue;
02008   else if(!strcmp(flagName,"PFIS"))
02009     fGcphys->ipfis=flagValue;
02010   else if(!strcmp(flagName,"DRAY"))
02011     fGcphys->idray=flagValue;
02012   else if(!strcmp(flagName,"ANNI"))
02013     fGcphys->ianni=flagValue;
02014   else if(!strcmp(flagName,"BREM"))
02015     fGcphys->ibrem=flagValue;
02016   else if(!strcmp(flagName,"HADR"))
02017     fGcphys->ihadr=flagValue;
02018   else if(!strcmp(flagName,"MUNU"))
02019     fGcphys->imunu=flagValue;
02020   else if(!strcmp(flagName,"DCAY"))
02021     fGcphys->idcay=flagValue;
02022   else if(!strcmp(flagName,"LOSS"))
02023     fGcphys->iloss=flagValue;
02024   else if(!strcmp(flagName,"MULS"))
02025     fGcphys->imuls=flagValue;
02026   else if(!strcmp(flagName,"RAYL"))
02027     fGcphys->irayl=flagValue;
02028   else if(!strcmp(flagName,"STRA"))
02029     fGcphlt->istra=flagValue;
02030   else if(!strcmp(flagName,"SYNC"))
02031     fGcphlt->isync=flagValue;
02032   else if(!strcmp(flagName,"CKOV"))
02033     fGctlit->itckov = flagValue;
02034   else  {
02035     Warning("SetFlag","Flag %s not implemented\n",flagName);
02036     success = kFALSE;
02037   }
02038 
02039   return  success;
02040 }
02041 
02042  //______________________________________________________________________
02043 Bool_t TGeant3::DefineParticle(Int_t pdg,const char* name,TMCParticleType type,
02044                       Double_t mass, Double_t charge, Double_t lifetime)
02045 {
02046 // Old function definition, now replaced with more arguments
02047 
02048   TVirtualMC::DefineParticle(pdg, name, type, mass, charge, lifetime);
02049   
02050   return false;
02051 }                        
02052                       
02053 
02054 //______________________________________________________________________
02055 Bool_t TGeant3::DefineParticle(Int_t pdg,const char* name, TMCParticleType mcType,
02056                       Double_t mass, Double_t charge, Double_t lifetime,
02057                       const TString& /*pType*/, Double_t /*width*/, 
02058                       Int_t /*iSpin*/, Int_t /*iParity*/, Int_t /*iConjugation*/, 
02059                       Int_t /*iIsospin*/, Int_t /*iIsospinZ*/, Int_t /*gParity*/,
02060                       Int_t /*lepton*/, Int_t /*baryon*/,
02061                       Bool_t /*stable*/, Bool_t /*shortlived*/,
02062                       const TString& /*subType*/,
02063                       Int_t /*antiEncoding*/, Double_t /*magMoment*/,
02064                       Double_t /*excitation*/)
02065 {
02066 //
02067 // Set a user defined particle
02068 // Function is ignored if particle with specified pdg
02069 // already exists and error report is printed.
02070 // ---
02071 
02072   // Check if particle with specified pdg already exists
02073   // in TGeant3
02074   if (IdFromPDG(pdg) > 0) {
02075     Error("SetParticle", "Particle already exists.");
02076     return kFALSE;
02077   }
02078 
02079   // Check if particle type is known to Geant3
02080   Int_t itrtyp = TransportMethod(mcType);
02081   if (itrtyp < 0) {
02082     Error("SetParticle", "Unknown particle transport.");
02083     return kFALSE;
02084   }
02085 
02086   // Add particle to Geant3
02087   Gspart(fNG3Particles++, name, itrtyp, mass, charge, lifetime);
02088 
02089   // Add particle to TDatabasePDG
02090   // (if it does not yet exist here)
02091   if (!TDatabasePDG::Instance()->GetParticle(pdg))
02092     TDatabasePDG::Instance()
02093       ->AddParticle(name, name, mass, kTRUE, 0, charge*3,
02094                     ParticleClass(mcType).Data(), pdg);
02095                     
02096   // Resize fPDGCode table if needed
02097   if ( fNPDGCodes >= fPDGCode.GetSize() ) 
02098     fPDGCode.Set( fPDGCode.GetSize() + 100);                 
02099 
02100   fPDGCode[fNPDGCodes++] = pdg;
02101 
02102   return kTRUE;
02103 }
02104 
02105 //______________________________________________________________________
02106 Bool_t  TGeant3::DefineIon(const char* name, Int_t Z, Int_t A, Int_t Q,
02107                            Double_t /* excEnergy */, Double_t mass)
02108 {
02109 //
02110 // Set a user defined ion.
02111 // ---
02112 
02113   // Define pdgEncoding
02114   //
02115   Int_t pdg = GetIonPdg(Z, A);
02116   Int_t pdgMax = pdg + 9;
02117 
02118   // Find isomer number which is not yet used
02119   while (TDatabasePDG::Instance()->GetParticle(pdg) &&
02120          pdg < pdgMax)
02121       pdg++;
02122   if (TDatabasePDG::Instance()->GetParticle(pdg)) {
02123       Fatal("SetIon", "All isomer numbers are already used");
02124       return kFALSE;
02125   }
02126 
02127   // Particle properties
02128         // excitation energy not used by G3
02129   if (mass < 1e-09) mass = 0.9382723 * A;
02130      // approximative mass if not specified by user
02131   Double_t charge = Q;
02132   TMCParticleType partType = kPTIon;
02133   Double_t lifetime = 1.e20;
02134 
02135   // Call DefineParticle now
02136   return DefineParticle(
02137            pdg, name, partType, mass, charge, lifetime,
02138            "nucleus", 0.0, 1, 1, 0, 1, 1, 0, 0, 1, kTRUE);
02139 }
02140 
02141 //______________________________________________________________________
02142 TString  TGeant3::ParticleName(Int_t pdg) const
02143 {
02144 //  Return G3 particle name
02145 // ---
02146 
02147   char name[21];
02148   Int_t itrtyp;
02149   Float_t amass, charge, tlife;
02150   Gfpart(pdg, name, itrtyp,amass, charge, tlife);
02151   name[20] = '\0';
02152 
02153   return TString(name);
02154 }
02155 
02156 //______________________________________________________________________
02157 Double_t  TGeant3::ParticleMass(Int_t pdg) const
02158 {
02159 //  Return G3 particle mass
02160 // ---
02161 
02162   char name[20];
02163   Int_t itrtyp;
02164   Float_t mass, charge, tlife;
02165   Gfpart(pdg,name, itrtyp, mass, charge, tlife);
02166 
02167   return mass;
02168 }
02169 
02170 //______________________________________________________________________
02171 Double_t  TGeant3::ParticleCharge(Int_t pdg) const
02172 {
02173 // Return G3 particle charge (in e)
02174 // ---
02175 
02176   char name[20];
02177   Int_t itrtyp;
02178   Float_t mass, charge, tlife;
02179   Gfpart(pdg,name, itrtyp, mass, charge, tlife);
02180 
02181   return charge;
02182 }
02183 
02184 //______________________________________________________________________
02185 Double_t  TGeant3::ParticleLifeTime(Int_t pdg) const
02186 {
02187 // Return G3 particle life time
02188 // ---
02189 
02190   char name[20];
02191   Int_t itrtyp;
02192   Float_t mass, charge, tlife;
02193   Gfpart(pdg, name, itrtyp, mass, charge, tlife);
02194 
02195   return tlife;
02196 }
02197 
02198 //______________________________________________________________________
02199 TMCParticleType TGeant3::ParticleMCType(Int_t pdg) const
02200 {
02201 // Return MC particle type
02202 // ---
02203 
02204   char name[20];
02205   Int_t itrtyp;
02206   Float_t mass, charge, tlife;
02207   Gfpart(pdg,name, itrtyp, mass, charge, tlife);
02208 
02209   return ParticleType(itrtyp);
02210 }
02211 
02212 
02213 //______________________________________________________________________
02214 Double_t TGeant3::Xsec(char* reac, Double_t /* energy */,
02215                       Int_t part, Int_t /* mate */)
02216 {
02217   //
02218   // Calculate X-sections -- dummy for the moment
02219   //
02220   if(!strcmp(reac,"PHOT"))
02221   {
02222     if(part!=22) {
02223       Error("Xsec","Can calculate photoelectric only for photons\n");
02224     }
02225   }
02226   return 0;
02227 }
02228 
02229 //______________________________________________________________________
02230 void TGeant3::TrackPosition(TLorentzVector &xyz) const
02231 {
02232   //
02233   // Return the current position in the master reference frame of the
02234   // track being transported
02235   //
02236   xyz[0]=fGctrak->vect[0];
02237   xyz[1]=fGctrak->vect[1];
02238   xyz[2]=fGctrak->vect[2];
02239   xyz[3]=fGctrak->tofg;
02240 }
02241 
02242 //______________________________________________________________________
02243 void TGeant3::TrackPosition(Double_t &x, Double_t &y, Double_t &z) const
02244 {
02245   //
02246   // Return the current position in the master reference frame of the
02247   // track being transported
02248   //
02249   x=fGctrak->vect[0];
02250   y=fGctrak->vect[1];
02251   z=fGctrak->vect[2];
02252 }
02253 
02254 //______________________________________________________________________
02255 Double_t TGeant3::TrackTime() const
02256 {
02257   //
02258   // Return the current time of flight of the track being transported
02259   //
02260   return fGctrak->tofg;
02261 }
02262 
02263 //______________________________________________________________________
02264 void TGeant3::TrackMomentum(TLorentzVector &xyz) const
02265 {
02266   //
02267   // Return the direction and the momentum (GeV/c) of the track
02268   // currently being transported
02269   //
02270   Double_t ptot=fGctrak->vect[6];
02271   xyz[0]=fGctrak->vect[3]*ptot;
02272   xyz[1]=fGctrak->vect[4]*ptot;
02273   xyz[2]=fGctrak->vect[5]*ptot;
02274   xyz[3]=fGctrak->getot;
02275 }
02276 
02277 //______________________________________________________________________
02278 void TGeant3::TrackMomentum(Double_t &px, Double_t &py, Double_t &pz, 
02279                             Double_t &etot) const
02280 {
02281   //
02282   // Return the direction and the momentum (GeV/c) of the track
02283   // currently being transported
02284   //
02285   Double_t ptot=fGctrak->vect[6];
02286   px  =fGctrak->vect[3]*ptot;
02287   py  =fGctrak->vect[4]*ptot;
02288   pz  =fGctrak->vect[5]*ptot;
02289   etot=fGctrak->getot;
02290 }
02291 
02292 //______________________________________________________________________
02293 Double_t TGeant3::TrackCharge() const
02294 {
02295   //
02296   // Return charge of the track currently transported
02297   //
02298   return fGckine->charge;
02299 }
02300 
02301 //______________________________________________________________________
02302 Double_t TGeant3::TrackMass() const
02303 {
02304   //
02305   // Return the mass of the track currently transported
02306   //
02307   return fGckine->amass;
02308 }
02309 
02310 //______________________________________________________________________
02311 Int_t TGeant3::TrackPid() const
02312 {
02313   //
02314   // Return the id of the particle transported
02315   //
02316   return PDGFromId(fGckine->ipart);
02317 }
02318 
02319 //______________________________________________________________________
02320 Double_t TGeant3::TrackStep() const
02321 {
02322   //
02323   // Return the length in centimeters of the current step
02324   //
02325   return fGctrak->step;
02326 }
02327 
02328 //______________________________________________________________________
02329 Double_t TGeant3::TrackLength() const
02330 {
02331   //
02332   // Return the length of the current track from its origin
02333   //
02334   return fGctrak->sleng;
02335 }
02336 
02337 //______________________________________________________________________
02338 Bool_t TGeant3::IsNewTrack() const
02339 {
02340   //
02341   // True if the track is not at the boundary of the current volume
02342   //
02343   return (fGctrak->sleng==0);
02344 }
02345 
02346 //______________________________________________________________________
02347 Bool_t TGeant3::IsTrackInside() const
02348 {
02349   //
02350   // True if the track is not at the boundary of the current volume
02351   //
02352   return (fGctrak->inwvol==0);
02353 }
02354 
02355 //______________________________________________________________________
02356 Bool_t TGeant3::IsTrackEntering() const
02357 {
02358   //
02359   // True if this is the first step of the track in the current volume
02360   //
02361   return (fGctrak->inwvol==1);
02362 }
02363 
02364 //______________________________________________________________________
02365 Bool_t TGeant3::IsTrackExiting() const
02366 {
02367   //
02368   // True if this is the last step of the track in the current volume
02369   //
02370   return (fGctrak->inwvol==2);
02371 }
02372 
02373 //______________________________________________________________________
02374 Bool_t TGeant3::IsTrackOut() const
02375 {
02376   //
02377   // True if the track is out of the setup
02378   //
02379   return (fGctrak->inwvol==3);
02380 }
02381 
02382 //______________________________________________________________________
02383 Bool_t TGeant3::IsTrackStop() const
02384 {
02385   //
02386   // True if the track energy has fallen below the threshold
02387   //
02388   return (fGctrak->istop==2);
02389 }
02390 
02391 //______________________________________________________________________
02392 Int_t   TGeant3::NSecondaries() const
02393 {
02394   //
02395   // Number of secondary particles generated in the current step
02396   //
02397   return fGcking->ngkine;
02398 }
02399 
02400 //______________________________________________________________________
02401 Int_t   TGeant3::CurrentEvent() const
02402 {
02403   //
02404   // Number of the current event
02405   //
02406   return fGcflag->idevt;
02407 }
02408 
02409 //______________________________________________________________________
02410 TMCProcess TGeant3::ProdProcess(Int_t ) const
02411 {
02412   //
02413   // Name of the process that has produced the secondary particles
02414   // in the current step
02415   //
02416 
02417 //sk:begin
02418 //    Modified: S. Kasahara  2007/09/11 Method rewritten to make
02419 //    use of GCKING/KCASE variable for determining the production 
02420 //    mechanism of the secondaries.  The old method was to pick the first
02421 //    active process from the current step's list of active processes 
02422 //    that had the capability of generating secondaries.  This occasionally 
02423 //    picked the wrong secondary production mechanism.
02424 //    Revised: S. Kasahara 2007/09/22 to improve performance.
02425 
02426   if ( fGcking->ngkine <= 0 ) return kPNoProcess;
02427 
02428   // Secondaries generated, determine production mechanism hollerith  
02429   std::string casestr((const char*)(&(fGcking->kcase)));
02430   casestr.resize(4);
02431     
02432   int imech = -1;
02433   for ( Int_t km = fGctrak->nmec - 1; km >= 0; km-- ) {
02434     // Use the list of active mechanisms to narrow down the choices.
02435     // Start from the end of the list because usually the last mechanism is
02436     // the one resulting in the production of secondaries.
02437     Int_t proclmec = fGctrak->lmec[km] - 1;
02438     std::string namestr((const char*)(&(fGctrak->namec[proclmec])));
02439     namestr.resize(4);
02440     if ( casestr == namestr ) {
02441       imech = proclmec;
02442       break;
02443     }
02444   }
02445   
02446   if ( imech < 0 ) {
02447     // Failure to find matching process in active mechanism list.  This rarely
02448     // happens, but when it does try to find a match for the kcase mechanism 
02449     // using full list of possibilities.
02450     for ( Int_t km = 0; km < MAXMEC; km++ ) {
02451       std::string namestr((const char*)(&(fGctrak->namec[km])));
02452       namestr.resize(4);
02453       if ( casestr == namestr ) {
02454         imech = km;
02455         break;
02456       }
02457     }
02458   }
02459   
02460   if ( imech < 0 ) {
02461     // failure to find matching process
02462     cerr << "* TGeant3::ProdProcess secondaries present, kcase is "
02463          << casestr.c_str() << " but no matching process!*" << endl;
02464     abort();
02465   }
02466   TMCProcess vmcmech = G3toVMC(imech+1);
02467   
02468   return vmcmech;
02469 //sk:end
02470 
02471 }
02472 
02473 //______________________________________________________________________
02474 Int_t TGeant3::StepProcesses(TArrayI &proc) const
02475 {
02476   //
02477   // Return processes active in the current step
02478   //
02479   Int_t i;
02480   Int_t nproc=Gctrak()->nmec;
02481   
02482   // Set no active process if there are no processes
02483   if (nproc==0) {
02484     proc.Set(1);
02485     proc[0] = kPNull;
02486     return 1;
02487   }  
02488   
02489   //
02490   proc.Set(nproc);
02491   Int_t nvproc=0;
02492   //
02493   for (i=0; i<nproc; ++i)
02494     if((proc[nvproc]=G3toVMC(Gctrak()->lmec[i]))!=kPNoProcess) nvproc++;
02495   //
02496   proc.Set(nvproc);
02497   //
02498   return nvproc;
02499 }
02500 
02501 //______________________________________________________________________
02502 TMCProcess TGeant3::G3toVMC(Int_t iproc) const
02503 {
02504   //
02505   // Conversion between GEANT and TMC processes
02506   //
02507 
02508   const TMCProcess kPG2MC1[30] = {
02509     kPTransportation, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL, kPDecay,
02510     kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
02511     kPAnnihilation, kPHadronic, kPHCElastic, kPEvaporation, kPNuclearFission,
02512     kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHIElastic, 
02513     kPHInhelastic, kPMuonNuclear, kPTOFlimit, kPPhotoFission, kPNoProcess, 
02514     kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop};
02515 
02516   const TMCProcess kPG2MC2[9] = {
02517       kPLightAbsorption, kPLightScattering, kStepMax, kPNoProcess, kPCerenkov,
02518       kPLightReflection, kPLightRefraction, kPSynchrotron, kPNoProcess};
02519 
02520   TMCProcess proc=kPNoProcess;
02521   if(0<iproc && iproc<=30) proc= kPG2MC1[iproc-1];
02522   else if(101<=iproc && iproc<=109) proc= kPG2MC2[iproc-100-1];
02523 
02524   //sk:begin
02525   // Modified 2007/10/23 S. Kasahara to print error message when failure
02526   // to find matching VMC process for input G3 process code.
02527   if ( proc == kPNoProcess ) {
02528     cerr << "* TGeant3::G3toVMC failed to find matching TMCProcess "
02529          << "for G3 iproc " << iproc << "!*" << endl;
02530   }
02531   //sk:end
02532 
02533   return proc;
02534 }
02535 
02536 
02537 //______________________________________________________________________
02538 void    TGeant3::GetSecondary(Int_t isec, Int_t& ipart,
02539                               TLorentzVector &x, TLorentzVector &p)
02540 {
02541   //
02542   // Get the parameters of the secondary track number isec produced
02543   // in the current step
02544   //
02545   Int_t i;
02546   if(-1<isec && isec<fGcking->ngkine) {
02547     ipart=Int_t (fGcking->gkin[isec][4] +0.5);
02548     for(i=0;i<3;i++) {
02549       x[i]=fGckin3->gpos[isec][i];
02550       p[i]=fGcking->gkin[isec][i];
02551     }
02552     x[3]=fGcking->tofd[isec];
02553     p[3]=fGcking->gkin[isec][3];
02554   } else {
02555     printf(" * TGeant3::GetSecondary * Secondary %d does not exist\n",isec);
02556     x[0]=x[1]=x[2]=x[3]=p[0]=p[1]=p[2]=p[3]=0;
02557     ipart=0;
02558   }
02559 }
02560 
02561 //______________________________________________________________________
02562 void TGeant3::InitLego()
02563 {
02564   //
02565   // Set switches for lego transport
02566   //
02567   SetSWIT(4,0);
02568   SetDEBU(0,0,0);  //do not print a message
02569 }
02570 
02571 //______________________________________________________________________
02572 Bool_t TGeant3::IsTrackDisappeared() const
02573 {
02574   //
02575   // True if the current particle has disappeared
02576   // either because it decayed or because it underwent
02577   // an inelastic collision
02578   //
02579   return (fGctrak->istop==1);
02580 }
02581 
02582 //______________________________________________________________________
02583 Bool_t TGeant3::IsTrackAlive() const
02584 {
02585   //
02586   // True if the current particle is alive and will continue to be
02587   // transported
02588   //
02589   return (fGctrak->istop==0);
02590 }
02591 
02592 //______________________________________________________________________
02593 void TGeant3::StopTrack()
02594 {
02595   //
02596   // Stop the transport of the current particle and skip to the next
02597   //
02598   fGctrak->istop=1;
02599 }
02600 
02601 //______________________________________________________________________
02602 void TGeant3::StopEvent()
02603 {
02604   //
02605   // Stop simulation of the current event and skip to the next
02606   //
02607   fGcflag->ieotri=1;
02608 }
02609 
02610 //______________________________________________________________________
02611 void TGeant3::StopRun()
02612 {
02613   //
02614   // Stop simulation of the current event and set the abort run flag to true
02615   //
02616 
02617   StopTrack();
02618   StopEvent();
02619   fStopRun = kTRUE;
02620 }
02621 
02622 //______________________________________________________________________
02623 Double_t TGeant3::MaxStep() const
02624 {
02625   //
02626   // Return the maximum step length in the current medium
02627   //
02628   return fGctmed->stemax;
02629 }
02630 
02631 //______________________________________________________________________
02632 void TGeant3::SetMaxStep(Double_t maxstep)
02633 {
02634   //
02635   // Set the maximum step allowed till the particle is in the current medium
02636   //
02637   fGctmed->stemax=maxstep;
02638 }
02639 
02640 //______________________________________________________________________
02641 void TGeant3::SetMaxNStep(Int_t maxnstp)
02642 {
02643   //
02644   // Set the maximum number of steps till the particle is in the current medium
02645   //
02646   fGctrak->maxnst=maxnstp;
02647 }
02648 
02649 void TGeant3::ForceDecayTime(Float_t time)
02650 {
02651     //
02652     // Force the decay time of the current particle
02653     //
02654     TLorentzVector p;
02655     TrackMomentum(p);
02656     Gcphys()->sumlif = time / p.Beta() / p.Gamma()  * 2.99792458e10;
02657 }
02658 
02659 //______________________________________________________________________
02660 Int_t TGeant3::GetMaxNStep() const
02661 {
02662   //
02663   // Maximum number of steps allowed in current medium
02664   //
02665   return fGctrak->maxnst;
02666 }
02667 
02668 //_______________________________________________________________________
02669 void TGeant3::G3Material(Int_t& kmat, const char* name, Double_t a, 
02670                          Double_t z, Double_t dens, Double_t radl, 
02671                          Double_t absl, Float_t* buf, Int_t nwbuf)
02672 {
02673   //
02674   // Defines a Material
02675   //
02676   //  kmat               number assigned to the material
02677   //  name               material name
02678   //  a                  atomic mass in au
02679   //  z                  atomic number
02680   //  dens               density in g/cm3
02681   //  absl               absorption length in cm
02682   //                     if >=0 it is ignored and the program
02683   //                     calculates it, if <0. -absl is taken
02684   //  radl               radiation length in cm
02685   //                     if >=0 it is ignored and the program
02686   //                     calculates it, if <0. -radl is taken
02687   //  buf                pointer to an array of user words
02688   //  nbuf               number of user words
02689   //
02690   Int_t jmate=fGclink->jmate;
02691   kmat=1;
02692   Int_t ns, i;
02693   if(jmate>0) {
02694     ns=fZiq[jmate-2];
02695     kmat=ns+1;
02696     for(i=1; i<=ns; i++) {
02697       if(fZlq[jmate-i]==0) {
02698         kmat=i;
02699         break;
02700       }
02701     }
02702   }
02703   Float_t fa = a;
02704   Float_t fz = z;
02705   Float_t fdens = dens;
02706   Float_t fradl = radl;
02707   Float_t fabsl = absl;
02708 
02709   g3smate(kmat,PASSCHARD(name), fa,  fz, fdens, fradl, fabsl, buf,
02710          nwbuf PASSCHARL(name));
02711 }
02712 
02713 //______________________________________________________________________
02714 void TGeant3::Material(Int_t& kmat, const char* name, Double_t a, Double_t z,
02715                        Double_t dens, Double_t radl, Double_t absl, Float_t* buf,
02716                        Int_t nwbuf)
02717 {
02718   //
02719   // Defines a Material
02720   //
02721   //  kmat               number assigned to the material
02722   //  name               material name
02723   //  a                  atomic mass in au
02724   //  z                  atomic number
02725   //  dens               density in g/cm3
02726   //  absl               absorption length in cm
02727   //                     if >=0 it is ignored and the program
02728   //                     calculates it, if <0. -absl is taken
02729   //  radl               radiation length in cm
02730   //                     if >=0 it is ignored and the program
02731   //                     calculates it, if <0. -radl is taken
02732   //  buf                pointer to an array of user words
02733   //  nbuf               number of user words
02734   //
02735 
02736   G3Material(kmat, name, a, z, dens, radl, absl, buf, nwbuf);
02737 }
02738 
02739 //______________________________________________________________________
02740 void TGeant3::Material(Int_t& kmat, const char* name, Double_t a, Double_t z,
02741                        Double_t dens, Double_t radl, Double_t absl, Double_t* buf,
02742                        Int_t nwbuf)
02743 {
02744   //
02745   // Defines a Material
02746   //
02747   //  kmat               number assigned to the material
02748   //  name               material name
02749   //  a                  atomic mass in au
02750   //  z                  atomic number
02751   //  dens               density in g/cm3
02752   //  absl               absorption length in cm
02753   //                     if >=0 it is ignored and the program
02754   //                     calculates it, if <0. -absl is taken
02755   //  radl               radiation length in cm
02756   //                     if >=0 it is ignored and the program
02757   //                     calculates it, if <0. -radl is taken
02758   //  buf                pointer to an array of user words
02759   //  nbuf               number of user words
02760   //
02761 
02762 
02763   Float_t* fbuf = CreateFloatArray(buf, nwbuf);
02764   G3Material(kmat, name, a, z, dens, radl, absl, fbuf, nwbuf);
02765   delete [] fbuf;
02766 }
02767 
02768 //______________________________________________________________________
02769 void TGeant3::G3Mixture(Int_t& kmat, const char* name, Float_t* a, Float_t* z,
02770                         Double_t dens, Int_t nlmat, Float_t* wmat)
02771 {
02772   //
02773   // Defines mixture OR COMPOUND IMAT as composed by
02774   // THE BASIC NLMAT materials defined by arrays A,Z and WMAT
02775   //
02776   // If NLMAT > 0 then wmat contains the proportion by
02777   // weights of each basic material in the mixture.
02778   //
02779   // If nlmat < 0 then WMAT contains the number of atoms
02780   // of a given kind into the molecule of the COMPOUND
02781   // In this case, WMAT in output is changed to relative
02782   // weights.
02783   //
02784 
02785   Int_t jmate=fGclink->jmate;
02786   kmat=1;
02787   Int_t ns, i;
02788   if(jmate>0) {
02789     ns=fZiq[jmate-2];
02790     kmat=ns+1;
02791     for(i=1; i<=ns; i++) {
02792       if(fZlq[jmate-i]==0) {
02793         kmat=i;
02794         break;
02795       }
02796     }
02797   }
02798   g3smixt(kmat,PASSCHARD(name),a,z,Float_t(dens),nlmat,wmat PASSCHARL(name));
02799 }
02800 
02801 //______________________________________________________________________
02802 void TGeant3::Mixture(Int_t& kmat, const char* name, Float_t* a, Float_t* z,
02803                       Double_t dens, Int_t nlmat, Float_t* wmat)
02804 {
02805   //
02806   // Defines mixture OR COMPOUND IMAT as composed by
02807   // THE BASIC NLMAT materials defined by arrays A,Z and WMAT
02808   //
02809   // If NLMAT > 0 then wmat contains the proportion by
02810   // weights of each basic material in the mixture.
02811   //
02812   // If nlmat < 0 then WMAT contains the number of atoms
02813   // of a given kind into the molecule of the COMPOUND
02814   // In this case, WMAT in output is changed to relative
02815   // weights.
02816   //
02817 
02818   Float_t* fa = CreateFloatArray(a, TMath::Abs(nlmat));
02819   Float_t* fz = CreateFloatArray(z, TMath::Abs(nlmat));
02820   Float_t* fwmat = CreateFloatArray(wmat, TMath::Abs(nlmat));
02821 
02822   G3Mixture(kmat, name, fa, fz, dens, nlmat, fwmat);
02823   Int_t i;
02824   for (i=0; i<TMath::Abs(nlmat); i++) {
02825     a[i] = fa[i]; z[i] = fz[i]; wmat[i] = fwmat[i];
02826   }
02827 
02828   delete [] fa;
02829   delete [] fz;
02830   delete [] fwmat;
02831 }
02832 
02833 //______________________________________________________________________
02834 void TGeant3::Mixture(Int_t& kmat, const char* name, Double_t* a, Double_t* z,
02835                       Double_t dens, Int_t nlmat, Double_t* wmat)
02836 {
02837   //
02838   // Defines mixture OR COMPOUND IMAT as composed by
02839   // THE BASIC NLMAT materials defined by arrays A,Z and WMAT
02840   //
02841   // If NLMAT > 0 then wmat contains the proportion by
02842   // weights of each basic material in the mixture.
02843   //
02844   // If nlmat < 0 then WMAT contains the number of atoms
02845   // of a given kind into the molecule of the COMPOUND
02846   // In this case, WMAT in output is changed to relative
02847   // weights.
02848   //
02849 
02850   Float_t* fa = CreateFloatArray(a, TMath::Abs(nlmat));
02851   Float_t* fz = CreateFloatArray(z, TMath::Abs(nlmat));
02852   Float_t* fwmat = CreateFloatArray(wmat, TMath::Abs(nlmat));
02853 
02854   G3Mixture(kmat, name, fa, fz, dens, nlmat, fwmat);
02855   Int_t i;
02856   for (i=0; i<TMath::Abs(nlmat); i++) {
02857     a[i] = fa[i]; z[i] = fz[i]; wmat[i] = fwmat[i];
02858   }
02859 
02860   delete [] fa;
02861   delete [] fz;
02862   delete [] fwmat;
02863 }
02864 
02865 //______________________________________________________________________
02866 void TGeant3::G3Medium(Int_t& kmed, const char* name, Int_t nmat, Int_t isvol,
02867                      Int_t ifield, Double_t fieldm, Double_t tmaxfd,
02868                      Double_t stemax, Double_t deemax, Double_t epsil,
02869                      Double_t stmin, Float_t* ubuf, Int_t nbuf)
02870 {
02871   //
02872   //  kmed      tracking medium number assigned
02873   //  name      tracking medium name
02874   //  nmat      material number
02875   //  isvol     sensitive volume flag
02876   //  ifield    magnetic field
02877   //  fieldm    max. field value (kilogauss)
02878   //  tmaxfd    max. angle due to field (deg/step)
02879   //  stemax    max. step allowed
02880   //  deemax    max. fraction of energy lost in a step
02881   //  epsil     tracking precision (cm)
02882   //  stmin     min. step due to continuous processes (cm)
02883   //
02884   //  ifield = 0 if no magnetic field; ifield = -1 if user decision in guswim;
02885   //  ifield = 1 if tracking performed with g3rkuta; ifield = 2 if tracking
02886   //  performed with g3helix; ifield = 3 if tracking performed with g3helx3.
02887   //
02888   Int_t jtmed=fGclink->jtmed;
02889   kmed=1;
02890   Int_t ns, i;
02891   if(jtmed>0) {
02892     ns=fZiq[jtmed-2];
02893     kmed=ns+1;
02894     for(i=1; i<=ns; i++) {
02895       if(fZlq[jtmed-i]==0) {
02896         kmed=i;
02897         break;
02898       }
02899     }
02900   }
02901   Float_t ffieldm = fieldm;
02902   Float_t ftmaxfd = tmaxfd;
02903   Float_t fstemax = stemax;
02904   Float_t fdeemax = deemax;
02905   Float_t fepsil  = epsil;
02906   Float_t fstmin =  stmin;
02907   g3stmed(kmed, PASSCHARD(name),nmat,isvol,ifield,ffieldm,ftmaxfd,fstemax,
02908           fdeemax, fepsil, fstmin, ubuf, nbuf PASSCHARL(name));
02909 
02910   fMedNames.AddAtAndExpand(new TObjString(name), kmed);           
02911 }
02912 
02913 //______________________________________________________________________
02914 void TGeant3::Medium(Int_t& kmed, const char* name, Int_t nmat, Int_t isvol,
02915                      Int_t ifield, Double_t fieldm, Double_t tmaxfd,
02916                      Double_t stemax, Double_t deemax, Double_t epsil,
02917                      Double_t stmin, Float_t* ubuf, Int_t nbuf)
02918 {
02919   //
02920   //  kmed      tracking medium number assigned
02921   //  name      tracking medium name
02922   //  nmat      material number
02923   //  isvol     sensitive volume flag
02924   //  ifield    magnetic field
02925   //  fieldm    max. field value (kilogauss)
02926   //  tmaxfd    max. angle due to field (deg/step)
02927   //  stemax    max. step allowed
02928   //  deemax    max. fraction of energy lost in a step
02929   //  epsil     tracking precision (cm)
02930   //  stmin     min. step due to continuous processes (cm)
02931   //
02932   //  ifield = 0 if no magnetic field; ifield = -1 if user decision in guswim;
02933   //  ifield = 1 if tracking performed with g3rkuta; ifield = 2 if tracking
02934   //  performed with g3helix; ifield = 3 if tracking performed with g3helx3.
02935   //
02936 
02937   G3Medium(kmed,name,nmat,isvol,ifield,fieldm,tmaxfd,stemax,deemax,epsil,
02938            stmin, ubuf, nbuf);
02939 
02940 }
02941 
02942 //______________________________________________________________________
02943 void TGeant3::Medium(Int_t& kmed, const char* name, Int_t nmat, Int_t isvol,
02944                      Int_t ifield, Double_t fieldm, Double_t tmaxfd,
02945                      Double_t stemax, Double_t deemax, Double_t epsil,
02946                      Double_t stmin, Double_t* ubuf, Int_t nbuf)
02947 {
02948   //
02949   //  kmed      tracking medium number assigned
02950   //  name      tracking medium name
02951   //  nmat      material number
02952   //  isvol     sensitive volume flag
02953   //  ifield    magnetic field
02954   //  fieldm    max. field value (kilogauss)
02955   //  tmaxfd    max. angle due to field (deg/step)
02956   //  stemax    max. step allowed
02957   //  deemax    max. fraction of energy lost in a step
02958   //  epsil     tracking precision (cm)
02959   //  stmin     min. step due to continuous processes (cm)
02960   //
02961   //  ifield = 0 if no magnetic field; ifield = -1 if user decision in guswim;
02962   //  ifield = 1 if tracking performed with g3rkuta; ifield = 2 if tracking
02963   //  performed with g3helix; ifield = 3 if tracking performed with g3helx3.
02964   //
02965 
02966   Float_t* fubuf = CreateFloatArray(ubuf, nbuf);
02967   G3Medium(kmed,name,nmat,isvol,ifield,fieldm,tmaxfd,stemax,deemax,epsil,
02968            stmin, fubuf, nbuf);
02969   delete [] fubuf;
02970 
02971 }
02972 
02973 //______________________________________________________________________
02974 void TGeant3::Matrix(Int_t& krot, Double_t thex, Double_t phix, Double_t they,
02975                      Double_t phiy, Double_t thez, Double_t phiz)
02976 {
02977   //
02978   //  krot     rotation matrix number assigned
02979   //  theta1   polar angle for axis i
02980   //  phi1     azimuthal angle for axis i
02981   //  theta2   polar angle for axis ii
02982   //  phi2     azimuthal angle for axis ii
02983   //  theta3   polar angle for axis iii
02984   //  phi3     azimuthal angle for axis iii
02985   //
02986   //  it defines the rotation matrix number irot.
02987   //
02988   krot = -1;
02989   Int_t jrotm=fGclink->jrotm;
02990   krot=1;
02991   Int_t ns, i;
02992   if(jrotm>0) {
02993     ns=fZiq[jrotm-2];
02994     krot=ns+1;
02995     for(i=1; i<=ns; i++) {
02996       if(fZlq[jrotm-i]==0) {
02997         krot=i;
02998         break;
02999       }
03000     }
03001   }
03002   g3srotm(krot, thex, phix, they, phiy, thez, phiz);
03003 }
03004 
03005 //______________________________________________________________________
03006 Int_t TGeant3::CurrentMedium() const
03007 {
03008   //
03009   // Return the number of the current medium
03010   //
03011 //#ifdef WITHROOT
03012 //  Int_t imed = 0;
03013 //  TGeoNode *node = gGeoManager->GetCurrentNode();
03014 //  if (!node) imed = gGeoManager->GetTopNode()->GetVolume()->
03015 //                                                 GetMedium()->GetId();
03016 //  else       imed = node->GetVolume()->GetMedium()->GetId();
03017   //printf("==GetMedium: ROOT id=%i  numed=%i\n", imed,fGctmed->numed);
03018 //#endif
03019   return fGctmed->numed;
03020 }
03021 
03022 //______________________________________________________________________
03023 Int_t TGeant3::GetMedium() const
03024 {
03025   //
03026   // Return the number of the current medium
03027   // Deprecated function - replaced with CurrentMedium()
03028   //
03029 
03030   Warning("GetMedium", 
03031           "Deprecated function - use CurrentMedium() instead");
03032 
03033   return CurrentMedium();
03034 }
03035  
03036 //______________________________________________________________________
03037 void  TGeant3::SetRootGeometry()
03038 {
03039 // Notify Geant3 about use of TGeo geometry.
03040 // The materials and tracking medias will be imported from
03041 // TGeo at FinishGeometry().
03042 
03043   Fatal("SetRootGeometry",
03044         "TGeant3 does not support Root geometry");
03045 
03046   fImportRootGeometry = kTRUE;
03047 }  
03048 
03049 //______________________________________________________________________
03050 const char *TGeant3::GetPath()
03051 {
03052 // Get current path inside G3 geometry
03053    Int_t i,j;
03054    if ((i=fGcvolu->nlevel-1)<0) {
03055       Warning("GetPath", "level null");
03056       return fPath;
03057    }
03058    fPath[0] = '/';
03059    char name[10];
03060    char *namcur = fPath+1;
03061    Int_t gname, copy;
03062    Int_t nch=0;
03063    for (j=0; j<i+1; j++) {
03064       gname = fGcvolu->names[j];
03065       copy = fGcvolu->number[j];
03066       memcpy(name, &gname, 4);
03067       name[4]=0;
03068       sprintf(namcur, "%s_%d/", name, copy);
03069       nch = strlen(fPath);
03070       namcur = fPath+nch;
03071    }
03072    fPath[nch-1]=0;
03073    return fPath;
03074 }
03075 
03076 //______________________________________________________________________
03077 const char *TGeant3::GetNodeName()
03078 {
03079 // Get name of current G3 node
03080    Int_t i=fGcvolu->nlevel-1;
03081    if (i<0) return "";
03082    Int_t gname = fGcvolu->names[i];
03083    Int_t copy = fGcvolu->number[i];
03084    char name[10];
03085    memcpy(name, &gname, 4);
03086    name[4] = 0;
03087    sprintf(fPath, "%s_%d", name, copy);
03088    return fPath;
03089 }
03090 
03091 //______________________________________________________________________
03092 Double_t TGeant3::Edep() const
03093 {
03094   //
03095   // Return the energy lost in the current step
03096   //
03097   return fGctrak->destep;
03098 }
03099 
03100 //______________________________________________________________________
03101 Double_t TGeant3::Etot() const
03102 {
03103   //
03104   // Return the total energy of the current track
03105   //
03106   return fGctrak->getot;
03107 }
03108 
03109 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03110 //
03111 //                        Functions from GBASE
03112 //
03113 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03114 
03115 //______________________________________________________________________
03116 void  TGeant3::Gfile(const char * /*filename*/, const char * /*option*/)
03117 {
03118   //
03119   //    Routine to open a GEANT/RZ data base.
03120   //
03121   //    LUN logical unit number associated to the file
03122   //
03123   //    CHFILE RZ file name
03124   //
03125   //    CHOPT is a character string which may be
03126   //        N  To create a new file
03127   //        U  to open an existing file for update
03128   //       " " to open an existing file for read only
03129   //        Q  The initial allocation (default 1000 records)
03130   //           is given in IQUEST(10)
03131   //        X  Open the file in exchange format
03132   //        I  Read all data structures from file to memory
03133   //        O  Write all data structures from memory to file
03134   //
03135   // Note:
03136   //      If options "I"  or "O" all data structures are read or
03137   //         written from/to file and the file is closed.
03138   //      See routine GRMDIR to create subdirectories
03139   //      See routines GROUT,GRIN to write,read objects
03140   //
03141   //g3rfile(21, PASSCHARD(filename), PASSCHARD(option) PASSCHARL(filename)
03142 //       PASSCHARL(option));
03143 }
03144 
03145 //______________________________________________________________________
03146 void  TGeant3::Gpcxyz()
03147 {
03148   //
03149   //    Print track and volume parameters at current point
03150   //
03151 
03152     g3pcxyz();
03153 }
03154 //______________________________________________________________________
03155 void  TGeant3::Ggclos()
03156 {
03157   //
03158   //   Closes off the geometry setting.
03159   //   Initializes the search list for the contents of each
03160   //   volume following the order they have been positioned, and
03161   //   inserting the content '0' when a call to GSNEXT (-1) has
03162   //   been required by the user.
03163   //   Performs the development of the JVOLUM structure for all
03164   //   volumes with variable parameters, by calling GGDVLP.
03165   //   Interprets the user calls to GSORD, through GGORD.
03166   //   Computes and stores in a bank (next to JVOLUM mother bank)
03167   //   the number of levels in the geometrical tree and the
03168   //   maximum number of contents per level, by calling GGNLEV.
03169   //   Sets status bit for CONCAVE volumes, through GGCAVE.
03170   //   Completes the JSET structure with the list of volume names
03171   //   which identify uniquely a given physical detector, the
03172   //   list of bit numbers to pack the corresponding volume copy
03173   //   numbers, and the generic path(s) in the JVOLUM tree,
03174   //   through the routine GHCLOS.
03175   //
03176   g3gclos();
03177   // Create internal list of volumes
03178   fVolNames = new char[fGcnum->nvolum+1][5];
03179   Int_t i;
03180   for(i=0; i<fGcnum->nvolum; ++i) {
03181     strncpy(fVolNames[i], (char *) &fZiq[fGclink->jvolum+i+1], 4);
03182     fVolNames[i][4]='\0';
03183   }
03184   strcpy(fVolNames[fGcnum->nvolum],"NULL");
03185 }
03186 
03187 //______________________________________________________________________
03188 void  TGeant3::Glast()
03189 {
03190   //
03191   // Finish a Geant run
03192   //
03193   g3last();
03194 }
03195 
03196 //______________________________________________________________________
03197 void  TGeant3::Gprint(const char *name)
03198 {
03199   //
03200   // Routine to print data structures
03201   // CHNAME   name of a data structure
03202   //
03203   char vname[5];
03204   Vname(name,vname);
03205   g3print(PASSCHARD(vname),0 PASSCHARL(vname));
03206 }
03207 
03208 //______________________________________________________________________
03209 void  TGeant3::Grun()
03210 {
03211   //
03212   // Steering function to process one run
03213   //
03214   g3run();
03215 }
03216 
03217 //______________________________________________________________________
03218 void  TGeant3::Gtrig()
03219 {
03220   //
03221   // Steering function to process one event
03222   //
03223   g3trig();
03224 
03225   //printf("count_gmedia= %8d\n",count_gmedia);
03226   //printf("count_gtmedi= %8d\n",count_gtmedi);
03227   //printf("count_ginvol= %8d\n",count_ginvol);
03228   //printf("count_gtnext= %8d\n",count_gtnext);
03229 }
03230 
03231 //______________________________________________________________________
03232 void  TGeant3::Gtrigc()
03233 {
03234   //
03235   // Clear event partition
03236   //
03237   g3trigc();
03238 }
03239 
03240 //______________________________________________________________________
03241 void  TGeant3::Gtrigi()
03242 {
03243   //
03244   // Initializes event partition
03245   //
03246   g3trigi();
03247 }
03248 
03249 //______________________________________________________________________
03250 void  TGeant3::Gwork(Int_t nwork)
03251 {
03252   //
03253   // Allocates workspace in ZEBRA memory
03254   //
03255   g3work(nwork);
03256 }
03257 
03258 //______________________________________________________________________
03259 void  TGeant3::Gzinit()
03260 {
03261   //
03262   // To initialize GEANT/ZEBRA data structures
03263   //
03264   g3zinit();
03265 }
03266 
03267 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03268 //
03269 //                        Functions from GCONS
03270 //
03271 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03272 
03273 //______________________________________________________________________
03274 void  TGeant3::Gfmate(Int_t imat, char *name, Float_t &a, Float_t &z,
03275                       Float_t &dens, Float_t &radl, Float_t &absl,
03276                       Float_t* ubuf, Int_t& nbuf)
03277 {
03278   //
03279   // Return parameters for material IMAT
03280   //
03281   g3fmate(imat, PASSCHARD(name), a, z, dens, radl, absl, ubuf, nbuf
03282          PASSCHARL(name));
03283 }
03284 
03285 //______________________________________________________________________
03286 void  TGeant3::Gfmate(Int_t imat, char *name, Double_t &a, Double_t &z,
03287                       Double_t &dens, Double_t &radl, Double_t &absl,
03288                       Double_t* ubuf, Int_t& nbuf)
03289 {
03290   //
03291   // Return parameters for material IMAT
03292   //
03293   Float_t fa = a;
03294   Float_t fz = z;
03295   Float_t fdens = dens;
03296   Float_t fradl = radl;
03297   Float_t fabsl = absl;
03298   Float_t* fubuf = CreateFloatArray(ubuf, nbuf);
03299 
03300   Gfmate(imat, name, fa, fz, fdens, fradl, fabsl, fubuf, nbuf);
03301 
03302   a = fa;
03303   z = fz;
03304   dens = fdens;
03305   radl = fradl;
03306   absl = fabsl;
03307   for (Int_t i=0; i<nbuf; i++) ubuf[i] = fubuf[i];
03308 
03309   delete [] fubuf;
03310 }
03311 
03312 //______________________________________________________________________
03313 void  TGeant3::Gfpart(Int_t ipart, char *name, Int_t &itrtyp,
03314                    Float_t &amass, Float_t &charge, Float_t &tlife) const
03315 {
03316   //
03317   // Return parameters for particle of type IPART
03318   //
03319   //Float_t *ubuf=0;
03320   Float_t ubuf[100];
03321   Int_t   nbuf;
03322   Int_t igpart = IdFromPDG(ipart);
03323   g3fpart(igpart, PASSCHARD(name), itrtyp, amass, charge, tlife, ubuf, nbuf
03324          PASSCHARL(name));
03325 }
03326 
03327 //sk:begin
03328 //    Modified: S. Kasahara  2007/07/24 Add method to print particles.
03329 //_____________________________________________________________________________
03330 void  TGeant3::Gppart(Int_t ipart)
03331 {
03332   // Print particle info for particle with pdg code ipart. 
03333   // If ipart = 0 (default), prints all particles.
03334   //
03335   // Note: ipart is a pdg code, not Geant3 particle code, to be consistent
03336   //       with Gfpart.
03337   
03338   Int_t igpart = 0;
03339   if ( ipart != 0 ) igpart = IdFromPDG(ipart);
03340   g3ppart(igpart);
03341 
03342 }
03343 //sk:end
03344 
03345 //______________________________________________________________________
03346 void  TGeant3::Gftmed(Int_t numed, char *name, Int_t &nmat, Int_t &isvol,
03347                    Int_t &ifield, Float_t &fieldm, Float_t &tmaxfd,
03348                     Float_t &stemax, Float_t &deemax, Float_t &epsil,
03349                     Float_t &stmin, Float_t *ubuf, Int_t *nbuf)
03350 {
03351   //
03352   // Return parameters for tracking medium NUMED
03353   //
03354   g3ftmed(numed, PASSCHARD(name), nmat, isvol, ifield, fieldm, tmaxfd, stemax,
03355          deemax, epsil, stmin, ubuf, nbuf PASSCHARL(name));
03356 }
03357 
03358 //sk:begin
03359 //    Modified: S. Kasahara  2006/05/21 Add method to print media.
03360 //_____________________________________________________________________________
03361 void  TGeant3::Gptmed(Int_t numed)
03362 {
03363   //
03364   // Print tracking medium NUMED. numed == 0 prints all media.
03365   //
03366   g3ptmed(numed);
03367 
03368 }
03369 //sk:end
03370 
03371 //______________________________________________________________________
03372  void  TGeant3::Gftmat(Int_t imate, Int_t ipart, char *chmeca, Int_t kdim,
03373                       Float_t* tkin, Float_t* value, Float_t* pcut,
03374                       Int_t &ixst)
03375 {
03376   //
03377   // Return parameters for material imate
03378   //
03379   g3ftmat(imate, ipart, PASSCHARD(chmeca), kdim,
03380          tkin, value, pcut, ixst PASSCHARL(chmeca));
03381 
03382 }
03383 
03384 //______________________________________________________________________
03385 Float_t TGeant3::Gbrelm(Float_t z, Float_t t, Float_t bcut)
03386 {
03387   //
03388   // To calculate energy loss due to soft muon BREMSSTRAHLUNG
03389   //
03390   return g3brelm(z,t,bcut);
03391 }
03392 
03393 //______________________________________________________________________
03394 Float_t TGeant3::Gprelm(Float_t z, Float_t t, Float_t bcut)
03395 {
03396   //
03397   // To calculate DE/DX in GeV*barn/atom for direct pair production by muons
03398   //
03399   return g3prelm(z,t,bcut);
03400 }
03401 
03402 //______________________________________________________________________
03403 void  TGeant3::Gmate()
03404 {
03405   //
03406   // Define standard GEANT materials
03407   //
03408   g3mate();
03409 }
03410 
03411 //______________________________________________________________________
03412 void  TGeant3::Gpart()
03413 {
03414   //
03415   //  Define standard GEANT particles plus selected decay modes
03416   //  and branching ratios.
03417   //
03418   g3part();
03419 }
03420 
03421 //______________________________________________________________________
03422 void  TGeant3::Gsdk(Int_t ipart, Float_t *bratio, Int_t *mode)
03423 {
03424 //  Defines branching ratios and decay modes for standard
03425 //  GEANT particles.
03426    g3sdk(ipart,bratio,mode);
03427 }
03428 
03429 //______________________________________________________________________
03430 void  TGeant3::Gsmate(Int_t imat, const char *name, Float_t a, Float_t z,
03431                    Float_t dens, Float_t radl, Float_t absl)
03432 {
03433   //
03434   // Defines a Material
03435   //
03436   //  kmat               number assigned to the material
03437   //  name               material name
03438   //  a                  atomic mass in au
03439   //  z                  atomic number
03440   //  dens               density in g/cm3
03441   //  absl               absorption length in cm
03442   //                     if >=0 it is ignored and the program
03443   //                     calculates it, if <0. -absl is taken
03444   //  radl               radiation length in cm
03445   //                     if >=0 it is ignored and the program
03446   //                     calculates it, if <0. -radl is taken
03447   //  buf                pointer to an array of user words
03448   //  nbuf               number of user words
03449   //
03450   Float_t *ubuf=0;
03451   Int_t   nbuf=0;
03452   if (dens <= 0 && a != 0 && z != 0) {
03453      Warning("Gsmate","Density was o, set to 0.01 for imat=%d, name=%s",
03454              imat,name);
03455      dens = 0.01;
03456   }
03457   g3smate(imat,PASSCHARD(name), a, z, dens, radl, absl, ubuf, nbuf
03458          PASSCHARL(name));
03459 }
03460 
03461 //______________________________________________________________________
03462 void  TGeant3::Gsmixt(Int_t imat, const char *name, Float_t *a, Float_t *z,
03463                    Float_t dens, Int_t nlmat, Float_t *wmat)
03464 {
03465   //
03466   //       Defines mixture OR COMPOUND IMAT as composed by
03467   //       THE BASIC NLMAT materials defined by arrays A,Z and WMAT
03468   //
03469   //       If NLMAT.GT.0 then WMAT contains the PROPORTION BY
03470   //       WEIGHTS OF EACH BASIC MATERIAL IN THE MIXTURE.
03471   //
03472   //       If NLMAT.LT.0 then WMAT contains the number of atoms
03473   //       of a given kind into the molecule of the COMPOUND
03474   //       In this case, WMAT in output is changed to relative
03475   //       weights.
03476   //
03477   g3smixt(imat,PASSCHARD(name), a, z,dens, nlmat,wmat PASSCHARL(name));
03478 }
03479 
03480 //______________________________________________________________________
03481 void  TGeant3::Gspart(Int_t ipart, const char *name, Int_t itrtyp,
03482                    Double_t amass, Double_t charge, Double_t tlife)
03483 {
03484   //
03485   // Store particle parameters
03486   //
03487   // ipart           particle code
03488   // name            particle name
03489   // itrtyp          transport method (see GEANT manual)
03490   // amass           mass in GeV/c2
03491   // charge          charge in electron units
03492   // tlife           lifetime in seconds
03493   //
03494   Float_t *ubuf=0;
03495   Int_t   nbuf=0;
03496   Float_t fmass = amass;
03497   Float_t fcharge = charge;
03498   Float_t flife = tlife;
03499 
03500   g3spart(ipart,PASSCHARD(name), itrtyp, fmass, fcharge, flife, ubuf, nbuf
03501          PASSCHARL(name));
03502 }
03503 
03504 //______________________________________________________________________
03505 void  TGeant3::Gstmed(Int_t numed, const char *name, Int_t nmat, Int_t isvol,
03506                       Int_t ifield, Float_t fieldm, Float_t tmaxfd,
03507                       Float_t stemax, Float_t deemax, Float_t epsil,
03508                       Float_t stmin)
03509 {
03510   //
03511   //  NTMED  Tracking medium number
03512   //  NAME   Tracking medium name
03513   //  NMAT   Material number
03514   //  ISVOL  Sensitive volume flag
03515   //  IFIELD Magnetic field
03516   //  FIELDM Max. field value (Kilogauss)
03517   //  TMAXFD Max. angle due to field (deg/step)
03518   //  STEMAX Max. step allowed
03519   //  DEEMAX Max. fraction of energy lost in a step
03520   //  EPSIL  Tracking precision (cm)
03521   //  STMIN  Min. step due to continuous processes (cm)
03522   //
03523   //  IFIELD = 0 if no magnetic field; IFIELD = -1 if user decision in GUSWIM;
03524   //  IFIELD = 1 if tracking performed with G3RKUTA; IFIELD = 2 if tracking
03525   //  performed with G3HELIX; IFIELD = 3 if tracking performed with G3HELX3.
03526   //
03527   Float_t *ubuf=0;
03528   Int_t   nbuf=0;
03529   g3stmed(numed,PASSCHARD(name), nmat, isvol, ifield, fieldm, tmaxfd, stemax,
03530          deemax, epsil, stmin, ubuf, nbuf PASSCHARL(name));
03531 }
03532 
03533 //______________________________________________________________________
03534 void  TGeant3::Gsckov(Int_t itmed, Int_t npckov, Float_t *ppckov,
03535                            Float_t *absco, Float_t *effic, Float_t *rindex)
03536 {
03537   //
03538   //    Stores the tables for UV photon tracking in medium ITMED
03539   //    Please note that it is the user's responsibility to
03540   //    provide all the coefficients:
03541   //
03542   //
03543   //       ITMED       Tracking medium number
03544   //       NPCKOV      Number of bins of each table
03545   //       PPCKOV      Value of photon momentum (in GeV)
03546   //       ABSCO       Absorption coefficients
03547   //                   dielectric: absorption length in cm
03548   //                   metals    : absorption fraction (0<=x<=1)
03549   //       EFFIC       Detection efficiency for UV photons
03550   //       RINDEX      Refraction index (if=0 metal)
03551   //
03552   g3sckov(itmed,npckov,ppckov,absco,effic,rindex);
03553 }
03554 
03555 //______________________________________________________________________
03556 void  TGeant3::SetCerenkov(Int_t itmed, Int_t npckov, Float_t *ppckov,
03557                            Float_t *absco, Float_t *effic, Float_t *rindex)
03558 {
03559   //
03560   //    Stores the tables for UV photon tracking in medium ITMED
03561   //    Please note that it is the user's responsibility to
03562   //    provide all the coefficients:
03563   //
03564   //
03565   //       ITMED       Tracking medium number
03566   //       NPCKOV      Number of bins of each table
03567   //       PPCKOV      Value of photon momentum (in GeV)
03568   //       ABSCO       Absorption coefficients
03569   //                   dielectric: absorption length in cm
03570   //                   metals    : absorption fraction (0<=x<=1)
03571   //       EFFIC       Detection efficiency for UV photons
03572   //       RINDEX      Refraction index (if=0 metal)
03573   //
03574   g3sckov(itmed,npckov,ppckov,absco,effic,rindex);
03575 }
03576 
03577 //______________________________________________________________________
03578 void  TGeant3::SetCerenkov(Int_t itmed, Int_t npckov, Double_t *ppckov,
03579                            Double_t *absco, Double_t *effic, Double_t *rindex)
03580 {
03581   //
03582   //    Stores the tables for UV photon tracking in medium ITMED
03583   //    Please note that it is the user's responsibility to
03584   //    provide all the coefficients:
03585   //
03586   //
03587   //       ITMED       Tracking medium number
03588   //       NPCKOV      Number of bins of each table
03589   //       PPCKOV      Value of photon momentum (in GeV)
03590   //       ABSCO       Absorption coefficients
03591   //                   dielectric: absorption length in cm
03592   //                   metals    : absorption fraction (0<=x<=1)
03593   //       EFFIC       Detection efficiency for UV photons
03594   //       RINDEX      Refraction index (if=0 metal)
03595   //
03596 
03597   Float_t* fppckov = CreateFloatArray(ppckov, npckov);
03598   Float_t* fabsco  = CreateFloatArray(absco, npckov);
03599   Float_t* feffic  = CreateFloatArray(effic, npckov);
03600   Float_t* frindex = CreateFloatArray(rindex, npckov);
03601 
03602   SetCerenkov(itmed, npckov, fppckov, fabsco, feffic, frindex);
03603 
03604   delete [] fppckov;
03605   delete [] fabsco;
03606   delete [] feffic;
03607   delete [] frindex;
03608 }
03609 
03610 //______________________________________________________________________
03611 void  TGeant3::DefineOpSurface(const char* /*name*/,
03612                 EMCOpSurfaceModel /*model*/, EMCOpSurfaceType /*surfaceType*/,
03613                 EMCOpSurfaceFinish /*surfaceFinish*/, Double_t /*sigmaAlpha*/) 
03614 {
03615    
03616    Warning("DefineOpSurface", 
03617            "Not applicable in Geant3 - setting is ignored.");
03618 }   
03619                 
03620 //______________________________________________________________________
03621 void  TGeant3::SetBorderSurface(const char* /*name*/,
03622                 const char* /*vol1Name*/, int /*vol1CopyNo*/,
03623                 const char* /*vol2Name*/, int /*vol2CopyNo*/,
03624                 const char* /*opSurfaceName*/) 
03625 {
03626    Warning("SetBorderSurface",
03627            "Not applicable in Geant3 - setting is ignored.");
03628 }   
03629                 
03630 //______________________________________________________________________
03631 void  TGeant3::SetSkinSurface(const char* /*name*/,
03632                 const char* /*volName*/,
03633                 const char* /*opSurfaceName*/) 
03634 {
03635    Warning("SetSkinSurface",
03636            "Not applicable in Geant3 - setting is ignored.");
03637 }   
03638                 
03639 //______________________________________________________________________
03640 void  TGeant3::SetMaterialProperty(
03641                 Int_t /*itmed*/, const char* /*propertyName*/, 
03642                 Int_t /*np*/, Double_t* /*pp*/, Double_t* /*values*/) 
03643 {
03644    Warning("SetMaterialProperty",
03645            "Not applicable in Geant3 - setting is ignored.");
03646 }   
03647                 
03648 //______________________________________________________________________
03649 void  TGeant3::SetMaterialProperty(
03650                 Int_t /*itmed*/, const char* /*propertyName*/, 
03651                 Double_t /*value*/) 
03652 {
03653    Warning("SetMaterialProperty",
03654            "Not applicable in Geant3 - setting is ignored.");
03655 }   
03656                 
03657 //______________________________________________________________________
03658 void  TGeant3::SetMaterialProperty(
03659                 const char* /*surfaceName*/, const char* /*propertyName*/, 
03660                 Int_t /*np*/, Double_t* /*pp*/, Double_t* /*values*/) 
03661                 {
03662    Warning("SetMaterialProperty",
03663            "Not applicable in Geant3 - setting is ignored.");
03664 }   
03665 
03666 //______________________________________________________________________
03667 void  TGeant3::Gstpar(Int_t itmed, const char *param, Double_t parval)
03668 {
03669   //
03670   //  To change the value of cut  or mechanism "CHPAR"
03671   //      to a new value PARVAL  for tracking medium ITMED
03672   //    The  data   structure  JTMED   contains  the   standard  tracking
03673   //  parameters (CUTS and flags to control the physics processes)  which
03674   //  are used  by default  for all  tracking media.   It is  possible to
03675   //  redefine individually  with GSTPAR  any of  these parameters  for a
03676   //  given tracking medium.
03677   //  ITMED     tracking medium number
03678   //  CHPAR     is a character string (variable name)
03679   //  PARVAL    must be given as a floating point.
03680   //
03681 
03682   Float_t fparval = parval;
03683   g3stpar(itmed,PASSCHARD(param), fparval PASSCHARL(param));
03684 }
03685 
03686 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03687 //
03688 //                        Functions from GCONS
03689 //
03690 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03691 
03692 //______________________________________________________________________
03693 void  TGeant3::Gfkine(Int_t itra, Float_t *vert, Float_t *pvert, 
03694                       Int_t &ipart, Int_t &nvert)
03695 {
03696   //           Storing/Retrieving Vertex and Track parameters
03697   //           ----------------------------------------------
03698   //
03699   //  Stores vertex parameters.
03700   //  VERT      array of (x,y,z) position of the vertex
03701   //  NTBEAM    beam track number origin of the vertex
03702   //            =0 if none exists
03703   //  NTTARG    target track number origin of the vertex
03704   //  UBUF      user array of NUBUF floating point numbers
03705   //  NUBUF
03706   //  NVTX      new vertex number (=0 in case of error).
03707   //  Prints vertex parameters.
03708   //  IVTX      for vertex IVTX.
03709   //            (For all vertices if IVTX=0)
03710   //  Stores long life track parameters.
03711   //  PLAB      components of momentum
03712   //  IPART     type of particle (see GSPART)
03713   //  NV        vertex number origin of track
03714   //  UBUF      array of NUBUF floating point user parameters
03715   //  NUBUF
03716   //  NT        track number (if=0 error).
03717   //  Retrieves long life track parameters.
03718   //  ITRA      track number for which parameters are requested
03719   //  VERT      vector origin of the track
03720   //  PVERT     4 momentum components at the track origin
03721   //  IPART     particle type (=0 if track ITRA does not exist)
03722   //  NVERT     vertex number origin of the track
03723   //  UBUF      user words stored in GSKINE.
03724   //  Prints initial track parameters.
03725   //  ITRA      for track ITRA
03726   //            (For all tracks if ITRA=0)
03727   //
03728   Float_t *ubuf=0;
03729   Int_t   nbuf;
03730   g3fkine(itra,vert,pvert,ipart,nvert,ubuf,nbuf);
03731 }
03732 
03733 //______________________________________________________________________
03734 void  TGeant3::Gfvert(Int_t nvtx, Float_t *v, Int_t &ntbeam, Int_t &nttarg,
03735                       Float_t &tofg)
03736 {
03737   //
03738   //       Retrieves the parameter of a vertex bank
03739   //       Vertex is generated from tracks NTBEAM NTTARG
03740   //       NVTX is the new vertex number
03741   //
03742   Float_t *ubuf=0;
03743   Int_t   nbuf;
03744   g3fvert(nvtx,v,ntbeam,nttarg,tofg,ubuf,nbuf);
03745 }
03746 
03747 //______________________________________________________________________
03748 Int_t TGeant3::Gskine(Float_t *plab, Int_t ipart, Int_t nv, Float_t *buf,
03749                       Int_t nwbuf)
03750 {
03751   //
03752   //       Store kinematics of track NT into data structure
03753   //       Track is coming from vertex NV
03754   //
03755   Int_t nt = 0;
03756   g3skine(plab, ipart, nv, buf, nwbuf, nt);
03757   return nt;
03758 }
03759 
03760 //______________________________________________________________________
03761 Int_t TGeant3::Gsvert(Float_t *v, Int_t ntbeam, Int_t nttarg, Float_t *ubuf,
03762                       Int_t nwbuf)
03763 {
03764   //
03765   //       Creates a new vertex bank
03766   //       Vertex is generated from tracks NTBEAM NTTARG
03767   //       NVTX is the new vertex number
03768   //
03769   Int_t nwtx = 0;
03770   g3svert(v, ntbeam, nttarg, ubuf, nwbuf, nwtx);
03771   return nwtx;
03772 }
03773 
03774 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03775 //
03776 //                        Functions from GPHYS
03777 //
03778 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03779 
03780 //______________________________________________________________________
03781 void  TGeant3::Gphysi()
03782 {
03783   //
03784   //       Initialize material constants for all the physics
03785   //       mechanisms used by GEANT
03786   //
03787   g3physi();
03788 }
03789 
03790 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03791 //
03792 //                        Functions from GTRAK
03793 //
03794 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03795 
03796 //______________________________________________________________________
03797 void  TGeant3::Gdebug()
03798 {
03799   //
03800   // Debug the current step
03801   //
03802   g3debug();
03803 }
03804 
03805 //______________________________________________________________________
03806 void  TGeant3::Gekbin()
03807 {
03808   //
03809   //       To find bin number in kinetic energy table
03810   //       stored in ELOW(NEKBIN)
03811   //
03812   g3ekbin();
03813 }
03814 
03815 //______________________________________________________________________
03816 void  TGeant3::Gfinds()
03817 {
03818   //
03819   //       Returns the set/volume parameters corresponding to
03820   //       the current space point in /GCTRAK/
03821   //       and fill common /GCSETS/
03822   //
03823   //       IHSET  user set identifier
03824   //       IHDET  user detector identifier
03825   //       ISET set number in JSET
03826   //       IDET   detector number in JS=LQ(JSET-ISET)
03827   //       IDTYPE detector type (1,2)
03828   //       NUMBV  detector volume numbers (array of length NVNAME)
03829   //       NVNAME number of volume levels
03830   //
03831   g3finds();
03832 }
03833 
03834 //______________________________________________________________________
03835 void  TGeant3::Gsking(Int_t igk)
03836 {
03837   //
03838   //   Stores in stack JSTAK either the IGKth track of /GCKING/,
03839   //    or the NGKINE tracks when IGK is 0.
03840   //
03841   g3sking(igk);
03842 }
03843 
03844 //______________________________________________________________________
03845 void  TGeant3::Gskpho(Int_t igk)
03846 {
03847   //
03848   //  Stores in stack JSTAK either the IGKth Cherenkov photon of
03849   //  /GCKIN2/, or the NPHOT tracks when IGK is 0.
03850   //
03851   g3skpho(igk);
03852 }
03853 
03854 //______________________________________________________________________
03855 void  TGeant3::Gsstak(Int_t iflag)
03856 {
03857   //
03858   //   Stores in auxiliary stack JSTAK the particle currently
03859   //    described in common /GCKINE/.
03860   //
03861   //   On request, creates also an entry in structure JKINE :
03862   //    IFLAG =
03863   //     0 : No entry in JKINE structure required (user)
03864   //     1 : New entry in JVERTX / JKINE structures required (user)
03865   //    <0 : New entry in JKINE structure at vertex -IFLAG (user)
03866   //     2 : Entry in JKINE structure exists already (from GTREVE)
03867   //
03868   g3sstak(iflag);
03869 }
03870 
03871 //______________________________________________________________________
03872 void  TGeant3::Gsxyz()
03873 {
03874   //
03875   //   Store space point VECT in banks JXYZ
03876   //
03877   g3sxyz();
03878 }
03879 
03880 //______________________________________________________________________
03881 void  TGeant3::Gtrack()
03882 {
03883   //
03884   //   Controls tracking of current particle
03885   //
03886   g3track();
03887 }
03888 
03889 //______________________________________________________________________
03890 void  TGeant3::Gtreve()
03891 {
03892   //
03893   //   Controls tracking of all particles belonging to the current event
03894   //
03895   g3treve();
03896 }
03897 
03898 //______________________________________________________________________
03899 void  TGeant3::GtreveRoot()
03900 {
03901   //
03902   //   Controls tracking of all particles belonging to the current event
03903   //
03904   gtreveroot();
03905 }
03906 
03907 //______________________________________________________________________
03908 void  TGeant3::Grndm(Float_t *rvec, Int_t len) const
03909 {
03910   //
03911   //  To set/retrieve the seed of the random number generator
03912   //
03913   TRandom* r=gMC->GetRandom();
03914   for(Int_t i=0; i<len; rvec[i++]=r->Rndm()) {};
03915 }
03916 
03917 //______________________________________________________________________
03918 void  TGeant3::Grndmq(Int_t &is1, Int_t &is2, Int_t /*iseq*/,
03919                       const Text_t */*chopt*/)
03920 {
03921   //
03922   //  To set/retrieve the seed of the random number generator
03923   //
03924   /*printf("Dummy grndmq called\n");*/
03925    is1 = gRandom->GetSeed();
03926    is2 = 0;
03927 }
03928 
03929 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03930 //
03931 //                        Functions from GDRAW
03932 //
03933 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03934 
03935 //______________________________________________________________________
03936 void  TGeant3::Gdxyz(Int_t /* it */)
03937 {
03938   //
03939   // Draw the points stored with Gsxyz relative to track it
03940   //
03941 }
03942 
03943 //______________________________________________________________________
03944 void  TGeant3::Gdcxyz()
03945 {
03946   //
03947   // Draw the position of the current track
03948   //
03949 }
03950 
03951 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03952 //
03953 //                        Functions from GGEOM
03954 //
03955 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03956 
03957 //______________________________________________________________________
03958 void  TGeant3::Gdtom(Float_t *xd, Float_t *xm, Int_t iflag)
03959 {
03960   //
03961   //  Computes coordinates XM (Master Reference System
03962   //  knowing the coordinates XD (Detector Ref System)
03963   //  The local reference system can be initialized by
03964   //    - the tracking routines and GDTOM used in GUSTEP
03965   //    - a call to GSCMED(NLEVEL,NAMES,NUMBER)
03966   //        (inverse routine is GMTOD)
03967   //
03968   //   If IFLAG=1  convert coordinates
03969   //      IFLAG=2  convert direction cosines
03970   //
03971   g3dtom(xd, xm, iflag);
03972 }
03973 
03974 //______________________________________________________________________
03975 void  TGeant3::Gdtom(Double_t *xd, Double_t *xm, Int_t iflag)
03976 {
03977   //
03978   //  Computes coordinates XM (Master Reference System
03979   //  knowing the coordinates XD (Detector Ref System)
03980   //  The local reference system can be initialized by
03981   //    - the tracking routines and GDTOM used in GUSTEP
03982   //    - a call to GSCMED(NLEVEL,NAMES,NUMBER)
03983   //        (inverse routine is GMTOD)
03984   //
03985   //   If IFLAG=1  convert coordinates
03986   //      IFLAG=2  convert direction cosines
03987   //
03988 
03989   Float_t* fxd = CreateFloatArray(xd, 3);
03990   Float_t* fxm = CreateFloatArray(xm, 3);
03991 
03992   Gdtom(fxd, fxm, iflag) ;
03993 
03994   for (Int_t i=0; i<3; i++) {
03995      xd[i] = fxd[i]; xm[i] = fxm[i];
03996   }
03997 
03998   delete [] fxd;
03999   delete [] fxm;
04000 }
04001 
04002 //______________________________________________________________________
04003 void  TGeant3::Glmoth(const char* iudet, Int_t iunum, Int_t &nlev, 
04004                       Int_t *lvols, Int_t *lindx)
04005 {
04006   //
04007   //   Loads the top part of the Volume tree in LVOLS (IVO's),
04008   //   LINDX (IN indices) for a given volume defined through
04009   //   its name IUDET and number IUNUM.
04010   //
04011   //   The routine stores only up to the last level where JVOLUM
04012   //   data structure is developed. If there is no development
04013   //   above the current level, it returns NLEV zero.
04014   Int_t *idum=0;
04015   g3lmoth(PASSCHARD(iudet), iunum, nlev, lvols, lindx, idum PASSCHARL(iudet));
04016 }
04017 
04018 //______________________________________________________________________
04019 void  TGeant3::Gmedia(Float_t *x, Int_t &numed)
04020 {
04021   //
04022   //   Finds in which volume/medium the point X is, and updates the
04023   //    common /GCVOLU/ and the structure JGPAR accordingly.
04024   //
04025   //   NUMED returns the tracking medium number, or 0 if point is
04026   //         outside the experimental setup.
04027   //
04028 
04029   static Int_t check = 0;
04030   g3media(x,numed,check);
04031 }
04032 
04033 //______________________________________________________________________
04034 void  TGeant3::Gmtod(Float_t *xm, Float_t *xd, Int_t iflag)
04035 {
04036   //
04037   //       Computes coordinates XD (in DRS)
04038   //       from known coordinates XM in MRS
04039   //       The local reference system can be initialized by
04040   //         - the tracking routines and GMTOD used in GUSTEP
04041   //         - a call to GMEDIA(XM,NUMED,CHECK)
04042   //         - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER)
04043   //             (inverse routine is GDTOM)
04044   //
04045   //        If IFLAG=1  convert coordinates
04046   //           IFLAG=2  convert direction cosines
04047   //
04048   g3mtod(xm, xd, iflag);
04049 }
04050 
04051 //______________________________________________________________________
04052 void  TGeant3::Gmtod(Double_t *xm, Double_t *xd, Int_t iflag)
04053 {
04054   //
04055   //       Computes coordinates XD (in DRS)
04056   //       from known coordinates XM in MRS
04057   //       The local reference system can be initialized by
04058   //         - the tracking routines and GMTOD used in GUSTEP
04059   //         - a call to GMEDIA(XM,NUMED,CHECK)
04060   //         - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER)
04061   //             (inverse routine is GDTOM)
04062   //
04063   //        If IFLAG=1  convert coordinates
04064   //           IFLAG=2  convert direction cosines
04065   //
04066 
04067 
04068   Float_t* fxm = CreateFloatArray(xm, 3);
04069   Float_t* fxd = CreateFloatArray(xd, 3);
04070 
04071   Gmtod(fxm, fxd, iflag) ;
04072 
04073   for (Int_t i=0; i<3; i++) {
04074      xm[i] = fxm[i]; xd[i] = fxd[i];
04075   }
04076 
04077   delete [] fxm;
04078   delete [] fxd;
04079 }
04080 
04081 //______________________________________________________________________
04082 void  TGeant3::Gsdvn(const char *name, const char *mother, Int_t ndiv,
04083                      Int_t iaxis)
04084 {
04085   //
04086   // Create a new volume by dividing an existing one
04087   //
04088   //  NAME   Volume name
04089   //  MOTHER Mother volume name
04090   //  NDIV   Number of divisions
04091   //  IAXIS  Axis value
04092   //
04093   //  X,Y,Z of CAXIS will be translated to 1,2,3 for IAXIS.
04094   //  It divides a previously defined volume.
04095   //
04096   char vname[5];
04097   Vname(name,vname);
04098   char vmother[5];
04099   Vname(mother,vmother);
04100 
04101   g3sdvn(PASSCHARD(vname), PASSCHARD(vmother), ndiv, iaxis PASSCHARL(vname)
04102         PASSCHARL(vmother));
04103 }
04104 
04105 //______________________________________________________________________
04106 void  TGeant3::Gsdvn2(const char *name, const char *mother, Int_t ndiv,
04107                       Int_t iaxis, Double_t c0i, Int_t numed)
04108 {
04109   //
04110   // Create a new volume by dividing an existing one
04111   //
04112   // Divides mother into ndiv divisions called name
04113   // along axis iaxis starting at coordinate value c0.
04114   // the new volume created will be medium number numed.
04115   //
04116   char vname[5];
04117   Vname(name,vname);
04118   char vmother[5];
04119   Vname(mother,vmother);
04120 
04121   Float_t fc0i = c0i;
04122   g3sdvn2(PASSCHARD(vname), PASSCHARD(vmother), ndiv, iaxis, fc0i, numed
04123          PASSCHARL(vname) PASSCHARL(vmother));
04124 }
04125 
04126 //______________________________________________________________________
04127 void  TGeant3::Gsdvs(const char *name, const char *mother, Float_t step,
04128                      Int_t iaxis, Int_t numed)
04129 {
04130   //
04131   // Create a new volume by dividing an existing one
04132   //
04133   char vname[5];
04134   Vname(name,vname);
04135   char vmother[5];
04136   Vname(mother,vmother);
04137 
04138   g3sdvs(PASSCHARD(vname), PASSCHARD(vmother), step, iaxis, numed
04139         PASSCHARL(vname) PASSCHARL(vmother));
04140 }
04141 
04142 //______________________________________________________________________
04143 void  TGeant3::Gsdvs2(const char *name, const char *mother, Float_t step,
04144                       Int_t iaxis, Float_t c0, Int_t numed)
04145 {
04146   //
04147   // Create a new volume by dividing an existing one
04148   //
04149   char vname[5];
04150   Vname(name,vname);
04151   char vmother[5];
04152   Vname(mother,vmother);
04153 
04154   g3sdvs2(PASSCHARD(vname), PASSCHARD(vmother), step, iaxis, c0, numed
04155          PASSCHARL(vname) PASSCHARL(vmother));
04156 }
04157 
04158 //______________________________________________________________________
04159 void  TGeant3::Gsdvt(const char *name, const char *mother, Double_t step,
04160                      Int_t iaxis, Int_t numed, Int_t ndvmx)
04161 {
04162   //
04163   // Create a new volume by dividing an existing one
04164   //
04165   //       Divides MOTHER into divisions called NAME along
04166   //       axis IAXIS in steps of STEP. If not exactly divisible
04167   //       will make as many as possible and will center them
04168   //       with respect to the mother. Divisions will have medium
04169   //       number NUMED. If NUMED is 0, NUMED of MOTHER is taken.
04170   //       NDVMX is the expected maximum number of divisions
04171   //          (If 0, no protection tests are performed)
04172   //
04173   char vname[5];
04174   Vname(name,vname);
04175   char vmother[5];
04176   Vname(mother,vmother);
04177 
04178   Float_t fstep = step;
04179   g3sdvt(PASSCHARD(vname), PASSCHARD(vmother), fstep, iaxis, numed, ndvmx
04180         PASSCHARL(vname) PASSCHARL(vmother));
04181 }
04182 
04183 //______________________________________________________________________
04184 void  TGeant3::Gsdvt2(const char *name, const char *mother, Double_t step,
04185                       Int_t iaxis, Double_t c0, Int_t numed, Int_t ndvmx)
04186 {
04187   //
04188   // Create a new volume by dividing an existing one
04189   //
04190   //           Divides MOTHER into divisions called NAME along
04191   //            axis IAXIS starting at coordinate value C0 with step
04192   //            size STEP.
04193   //           The new volume created will have medium number NUMED.
04194   //           If NUMED is 0, NUMED of mother is taken.
04195   //           NDVMX is the expected maximum number of divisions
04196   //             (If 0, no protection tests are performed)
04197   //
04198   char vname[5];
04199   Vname(name,vname);
04200   char vmother[5];
04201   Vname(mother,vmother);
04202 
04203   Float_t fstep = step;
04204   Float_t fc0 = c0;
04205   g3sdvt2(PASSCHARD(vname), PASSCHARD(vmother), fstep, iaxis, fc0,
04206          numed, ndvmx PASSCHARL(vname) PASSCHARL(vmother));
04207 }
04208 
04209 //______________________________________________________________________
04210 void  TGeant3::Gsord(const char *name, Int_t iax)
04211 {
04212   //
04213   //    Flags volume CHNAME whose contents will have to be ordered
04214   //    along axis IAX, by setting the search flag to -IAX
04215   //           IAX = 1    X axis
04216   //           IAX = 2    Y axis
04217   //           IAX = 3    Z axis
04218   //           IAX = 4    Rxy (static ordering only  -> GTMEDI)
04219   //           IAX = 14   Rxy (also dynamic ordering -> GTNEXT)
04220   //           IAX = 5    Rxyz (static ordering only -> GTMEDI)
04221   //           IAX = 15   Rxyz (also dynamic ordering -> GTNEXT)
04222   //           IAX = 6    PHI   (PHI=0 => X axis)
04223   //           IAX = 7    THETA (THETA=0 => Z axis)
04224   //
04225 
04226   char vname[5];
04227   Vname(name,vname);
04228   g3sord(PASSCHARD(vname), iax PASSCHARL(vname));
04229 }
04230 
04231 //______________________________________________________________________
04232 void  TGeant3::Gspos(const char *name, Int_t nr, const char *mother, 
04233                      Double_t x, Double_t y, Double_t z, Int_t irot, 
04234                      const char *konly)
04235 {
04236   //
04237   // Position a volume into an existing one
04238   //
04239   //  NAME   Volume name
04240   //  NUMBER Copy number of the volume
04241   //  MOTHER Mother volume name
04242   //  X      X coord. of the volume in mother ref. sys.
04243   //  Y      Y coord. of the volume in mother ref. sys.
04244   //  Z      Z coord. of the volume in mother ref. sys.
04245   //  IROT   Rotation matrix number w.r.t. mother ref. sys.
04246   //  ONLY   ONLY/MANY flag
04247   //
04248   //  It positions a previously defined volume in the mother.
04249   //
04250 
04251   TString only = konly;
04252   only.ToLower();
04253   Bool_t isOnly = kFALSE;
04254   if (only.Contains("only")) isOnly = kTRUE;
04255   char vname[5];
04256   Vname(name,vname);
04257   char vmother[5];
04258   Vname(mother,vmother);
04259 
04260   Float_t fx = x;
04261   Float_t fy = y;
04262   Float_t fz = z;
04263   g3spos(PASSCHARD(vname), nr, PASSCHARD(vmother), fx, fy, fz, irot,
04264         PASSCHARD(konly) PASSCHARL(vname) PASSCHARL(vmother)
04265         PASSCHARL(konly));
04266 }
04267 
04268 //______________________________________________________________________
04269 void  TGeant3::G3Gsposp(const char *name, Int_t nr, const char *mother,
04270                       Double_t x, Double_t y, Double_t z, Int_t irot,
04271                       const char *konly, Float_t *upar, Int_t np )
04272 {
04273   //
04274   //      Place a copy of generic volume NAME with user number
04275   //      NR inside MOTHER, with its parameters UPAR(1..NP)
04276   //
04277   TString only = konly;
04278   only.ToLower();
04279   Bool_t isOnly = kFALSE;
04280   if (only.Contains("only")) isOnly = kTRUE;
04281   char vname[5];
04282   Vname(name,vname);
04283   char vmother[5];
04284   Vname(mother,vmother);
04285 
04286   Float_t fx = x;
04287   Float_t fy = y;
04288   Float_t fz = z;
04289   g3sposp(PASSCHARD(vname), nr, PASSCHARD(vmother), fx, fy, fz, irot,
04290          PASSCHARD(konly), upar, np PASSCHARL(vname) PASSCHARL(vmother)
04291          PASSCHARL(konly));
04292 }
04293 
04294 //______________________________________________________________________
04295 void  TGeant3::Gsposp(const char *name, Int_t nr, const char *mother,
04296                       Double_t x, Double_t y, Double_t z, Int_t irot,
04297                       const char *konly, Float_t *upar, Int_t np )
04298 {
04299   //
04300   //      Place a copy of generic volume NAME with user number
04301   //      NR inside MOTHER, with its parameters UPAR(1..NP)
04302   //
04303 
04304   G3Gsposp(name, nr, mother, x, y, z, irot, konly, upar, np);
04305 }
04306 
04307 //______________________________________________________________________
04308 void  TGeant3::Gsposp(const char *name, Int_t nr, const char *mother,
04309                       Double_t x, Double_t y, Double_t z, Int_t irot,
04310                       const char *konly, Double_t *upar, Int_t np )
04311 {
04312   //
04313   //      Place a copy of generic volume NAME with user number
04314   //      NR inside MOTHER, with its parameters UPAR(1..NP)
04315   //
04316 
04317   Float_t* fupar = CreateFloatArray(upar, np);
04318   G3Gsposp(name, nr, mother, x, y, z, irot, konly, fupar, np);
04319   delete [] fupar;
04320 }
04321 
04322 //______________________________________________________________________
04323 void  TGeant3::Gsrotm(Int_t nmat, Float_t theta1, Float_t phi1, Float_t theta2,
04324                       Float_t phi2, Float_t theta3, Float_t phi3)
04325 {
04326   //
04327   //  nmat   Rotation matrix number
04328   //  THETA1 Polar angle for axis I
04329   //  PHI1   Azimuthal angle for axis I
04330   //  THETA2 Polar angle for axis II
04331   //  PHI2   Azimuthal angle for axis II
04332   //  THETA3 Polar angle for axis III
04333   //  PHI3   Azimuthal angle for axis III
04334   //
04335   //  It defines the rotation matrix number IROT.
04336   //
04337 
04338   g3srotm(nmat, theta1, phi1, theta2, phi2, theta3, phi3);
04339 }
04340 
04341 //______________________________________________________________________
04342 void  TGeant3::Gprotm(Int_t nmat)
04343 {
04344   //
04345   //    To print rotation matrices structure JROTM
04346   //     nmat     Rotation matrix number
04347   //
04348   g3protm(nmat);
04349  }
04350 
04351 //______________________________________________________________________
04352 Int_t TGeant3::G3Gsvolu(const char *name, const char *shape, Int_t nmed,
04353                       Float_t *upar, Int_t npar)
04354 {
04355   //
04356   //  NAME   Volume name
04357   //  SHAPE  Volume type
04358   //  NUMED  Tracking medium number
04359   //  NPAR   Number of shape parameters
04360   //  UPAR   Vector containing shape parameters
04361   //
04362   //  It creates a new volume in the JVOLUM data structure.
04363   //
04364   Int_t ivolu = 0;
04365   char vname[5];
04366   Vname(name,vname);
04367   char vshape[5];
04368   Vname(shape,vshape);
04369 
04370   g3svolu(PASSCHARD(vname), PASSCHARD(vshape), nmed, upar, npar, ivolu
04371          PASSCHARL(vname) PASSCHARL(vshape));
04372 
04373   return ivolu;
04374 }
04375 //______________________________________________________________________
04376 Int_t TGeant3::Gsvolu(const char *name, const char *shape, Int_t nmed,
04377                       Float_t *upar, Int_t npar)
04378 {
04379   //
04380   //  NAME   Volume name
04381   //  SHAPE  Volume type
04382   //  NUMED  Tracking medium number
04383   //  NPAR   Number of shape parameters
04384   //  UPAR   Vector containing shape parameters
04385   //
04386   //  It creates a new volume in the JVOLUM data structure.
04387   //
04388 
04389   Int_t ivolu = 0;
04390   ivolu = G3Gsvolu(name, shape, nmed, upar, npar);
04391   return ivolu;
04392 
04393 }
04394 
04395 //______________________________________________________________________
04396 Int_t TGeant3::Gsvolu(const char *name, const char *shape, Int_t nmed,
04397                       Double_t *upar, Int_t npar)
04398 {
04399   //
04400   //  NAME   Volume name
04401   //  SHAPE  Volume type
04402   //  NUMED  Tracking medium number
04403   //  NPAR   Number of shape parameters
04404   //  UPAR   Vector containing shape parameters
04405   //
04406   //  It creates a new volume in the JVOLUM data structure.
04407   //
04408 
04409 
04410   Int_t ivolu = 0;
04411   Float_t* fupar = CreateFloatArray(upar, npar);
04412   ivolu = G3Gsvolu(name, shape, nmed, fupar, npar);
04413   delete [] fupar;
04414   return ivolu;
04415 }
04416 
04417 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
04418 //
04419 //           T H E    D R A W I N G   P A C K A G E
04420 //           ======================================
04421 //  Drawing functions. These functions allow the visualization in several 
04422 //  ways of the volumes defined in the geometrical data structure. It is 
04423 //  possible to draw the logical tree of volumes belonging to the detector 
04424 //  (DTREE), to show their geometrical specification (DSPEC,DFSPC), to 
04425 //  draw them and their cut views (DRAW, DCUT). Moreover, it is possible 
04426 //  to execute these commands when the hidden line removal option is 
04427 //  activated; in this case, the volumes can be also either translated 
04428 //  in the space (SHIFT), or clipped by boolean operation (CVOL). In 
04429 //  addition, it is possible to fill the surfaces of the volumes
04430 //  with solid colors when the shading option (SHAD) is activated.
04431 //  Several tools (ZOOM, LENS) have been developed to zoom detailed parts
04432 //  of the detectors or to scan physical events as well.
04433 //  Finally, the command MOVE will allow the rotation, translation and 
04434 //  zooming on real time parts of the detectors or tracks and hits of a 
04435 //  simulated event. Ray-tracing commands. In case the command (DOPT RAYT 
04436 //  ON) is executed, the drawing is performed by the Geant ray-tracing;
04437 //  automatically, the color is assigned according to the tracking medium 
04438 //  of each volume and the volumes with a density lower/equal than the 
04439 //  air are considered transparent; if the option (USER) is set (ON) 
04440 //  (again via the command (DOPT)), the user can set color and visibility 
04441 //  for the desired volumes via the command (SATT), as usual, relatively 
04442 //  to the attributes (COLO) and (SEEN). The resolution can be set via 
04443 //  the command (SATT * FILL VALUE), where (VALUE) is the ratio between 
04444 //  the number of pixels drawn and 20 (user coordinates). Parallel view 
04445 //  and perspective view are possible (DOPT PROJ PARA/PERS); in the first 
04446 //  case, we assume that the first mother volume of the tree is a box with
04447 //  dimensions 10000 X 10000 X 10000 cm and the view point (infinitely far) 
04448 //  is 5000 cm far from the origin along the Z axis of the user coordinates; 
04449 //  in the second case, the distance between the observer and the origin 
04450 //  of the world reference system is set in cm by the command (PERSP NAME 
04451 //  VALUE); grand-angle or telescopic effects can be achieved changing the 
04452 //  scale factors in the command (DRAW). When the final picture does not 
04453 //  occupy the full window, mapping the space before tracing can speed up 
04454 //  the drawing, but can also produce less precise results; values from 1 
04455 //  to 4 are allowed in the command (DOPT MAPP VALUE), the mapping being 
04456 //  more precise for increasing (VALUE); for (VALUE = 0) no mapping is 
04457 //  performed (therefore max precision and lowest speed). The command 
04458 //  (VALCUT) allows the cutting of the detector by three planes orthogonal 
04459 //  to the x,y,z axis. The attribute (LSTY) can be set by the command
04460 //  SATT for any desired volume and can assume values from 0 to 7; it 
04461 //  determines the different light processing to be performed for different 
04462 //  materials:
04463 //  0 = dark-matt, 1 = bright-matt, 2 = plastic, 3 = ceramic, 4 = rough-metals,
04464 //  5 = shiny-metals, 6 = glass, 7 = mirror. The detector is assumed to 
04465 //  be in the dark, the ambient light luminosity is 0.2 for each basic 
04466 //  hue (the saturation is 0.9) and the observer is assumed to have a 
04467 //  light source (therefore he will produce parallel light in the case 
04468 //  of parallel view and point-like-source light in the case of perspective 
04469 //  view).
04470 //
04471 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
04472 
04473 //______________________________________________________________________
04474 void TGeant3::Gsatt(const char *name, const char *att, Int_t val)
04475 {
04476   //
04477   //  NAME   Volume name
04478   //  IOPT   Name of the attribute to be set
04479   //  IVAL   Value to which the attribute is to be set
04480   //
04481   //  name= "*" stands for all the volumes.
04482   //  iopt can be chosen among the following :
04483   //
04484   //     WORK   0=volume name is inactive for the tracking
04485   //            1=volume name is active for the tracking (default)
04486   //
04487   //     SEEN   0=volume name is invisible
04488   //            1=volume name is visible (default)
04489   //           -1=volume invisible with all its descendants in the tree
04490   //           -2=volume visible but not its descendants in the tree
04491   //
04492   //     LSTY   line style 1,2,3,... (default=1)
04493   //            LSTY=7 will produce a very precise approximation for
04494   //            revolution bodies.
04495   //
04496   //     LWID   line width -7,...,1,2,3,..7 (default=1)
04497   //            LWID<0 will act as abs(LWID) was set for the volume
04498   //            and for all the levels below it. When SHAD is 'ON', LWID
04499   //            represent the line width of the scan lines filling the surfaces
04500   //            (whereas the FILL value represent their number). Therefore
04501   //            tuning this parameter will help to obtain the desired
04502   //            quality/performance ratio.
04503   //
04504   //     COLO   color code -166,...,1,2,..166 (default=1)
04505   //            n=1=black
04506   //            n=2=red;    n=17+m, m=0,25, increasing luminosity according to 'm';
04507   //            n=3=green;  n=67+m, m=0,25, increasing luminosity according to 'm';
04508   //            n=4=blue;   n=117+m, m=0,25, increasing luminosity according to 'm';
04509   //            n=5=yellow; n=42+m, m=0,25, increasing luminosity according to 'm';
04510   //            n=6=violet; n=142+m, m=0,25, increasing luminosity according to 'm';
04511   //            n=7=light-blue; n=92+m, m=0,25, increasing luminosity according to 'm';
04512   //            color=n*10+m, m=1,2,...9, will produce the same color
04513   //            as 'n', but with increasing luminosity according to 'm';
04514   //            COLO<0 will act as if abs(COLO) was set for the volume
04515   //            and for all the levels below it.
04516   //            When for a volume the attribute FILL is > 1 (and the
04517   //            option SHAD is on), the ABS of its color code must be < 8
04518   //            because an automatic shading of its faces will be
04519   //            performed.
04520   //
04521   //     FILL  (1992) fill area  -7,...,0,1,...7 (default=0)
04522   //            when option SHAD is "on" the FILL attribute of any
04523   //            volume can be set different from 0 (normal drawing);
04524   //            if it is set to 1, the faces of such volume will be filled
04525   //            with solid colors; if ABS(FILL) is > 1, then a light
04526   //            source is placed along the observer line, and the faces of
04527   //            such volumes will be painted by colors whose luminosity
04528   //            will depend on the amount of light reflected;
04529   //            if ABS(FILL) = 1, then it is possible to use all the 166
04530   //            colors of the color table, because the automatic shading
04531   //            is not performed;
04532   //            for increasing values of FILL the drawing will be performed
04533   //            with higher and higher resolution improving the quality (the
04534   //            number of scan lines used to fill the faces increases with 
04535   //            FILL); it is possible to set different values of FILL
04536   //            for different volumes, in order to optimize at the same time
04537   //            the performance and the quality of the picture;
04538   //            FILL<0 will act as if abs(FILL) was set for the volume
04539   //            and for all the levels below it.
04540   //            This kind of drawing can be saved in 'picture files'
04541   //            or in view banks.
04542   //            0=drawing without fill area
04543   //            1=faces filled with solid colors and resolution = 6
04544   //            2=lowest resolution (very fast)
04545   //            3=default resolution
04546   //            4=.................
04547   //            5=.................
04548   //            6=.................
04549   //            7=max resolution
04550   //            Finally, if a colored background is desired, the FILL
04551   //            attribute for the first volume of the tree must be set
04552   //            equal to -abs(colo), colo being >0 and <166.
04553   //
04554   //     SET   set number associated to volume name
04555   //     DET   detector number associated to volume name
04556   //     DTYP  detector type (1,2)
04557   //
04558 
04559   char vname[5];
04560   Vname(name,vname);
04561   char vatt[5];
04562   Vname(att,vatt);
04563   g3satt(PASSCHARD(vname), PASSCHARD(vatt), val PASSCHARL(vname)
04564         PASSCHARL(vatt));
04565 }
04566 
04567 //______________________________________________________________________
04568 void TGeant3::Gfpara(const char *name, Int_t number, Int_t intext, Int_t& npar,
04569                          Int_t& natt, Float_t* par, Float_t* att)
04570 {
04571   //
04572   // Find the parameters of a volume
04573   //
04574   g3fpara(PASSCHARD(name), number, intext, npar, natt, par, att
04575          PASSCHARL(name));
04576 }
04577 
04578 //______________________________________________________________________
04579 void TGeant3::Gckpar(Int_t ish, Int_t npar, Float_t* par)
04580 {
04581   //
04582   // Check the parameters of a shape
04583   //
04584   gckpar(ish,npar,par);
04585 }
04586 
04587 //______________________________________________________________________
04588 void TGeant3::Gckmat(Int_t itmed, char* natmed)
04589 {
04590   //
04591   // Check the parameters of a tracking medium
04592   //
04593   g3ckmat(itmed, PASSCHARD(natmed) PASSCHARL(natmed));
04594 }
04595 
04596 //______________________________________________________________________
04597 Int_t TGeant3::Glvolu(Int_t nlev, Int_t *lnam,Int_t *lnum)
04598 {
04599   //
04600   //  nlev   number of levels deep into the volume tree
04601   //         size of the arrays lnam and lnum
04602   //  lnam   an integer array who's 4 bytes contain the ASCII code for the
04603   //         volume names
04604   //  lnum   an integer array containing the copy numbers for that specific
04605   //         volume
04606   //
04607   //  This routine fills the volume parameters in common /gcvolu/ for a
04608   //  physical tree, specified by the list lnam and lnum of volume names
04609   //  and numbers, and for all its ascendants up to level 1. This routine
04610   //  is optimized and does not re-compute the part of the history already
04611   //  available in GCVOLU. This means that if it is used in user programs
04612   //  outside the usual framework of the tracking, the user has to initialize
04613   //  to zero NLEVEL in the common GCVOLU. It return 0 if there were no
04614   //  problems in make the call.
04615   //
04616   Int_t ier;
04617   g3lvolu(nlev, lnam, lnum, ier);
04618   return ier;
04619 }
04620 
04621 //______________________________________________________________________
04622 void TGeant3::Gdelete(Int_t /* iview */)
04623 {
04624   //
04625   //  IVIEW  View number
04626   //
04627   //  It deletes a view bank from memory.
04628   //
04629 }
04630 
04631 //______________________________________________________________________
04632 void TGeant3::Gdopen(Int_t /* iview */)
04633 {
04634   //
04635   //  IVIEW  View number
04636   //
04637   //  When a drawing is very complex and requires a long time to be
04638   //  executed, it can be useful to store it in a view bank: after a
04639   //  call to DOPEN and the execution of the drawing (nothing will
04640   //  appear on the screen), and after a necessary call to DCLOSE,
04641   //  the contents of the bank can be displayed in a very fast way
04642   //  through a call to DSHOW; therefore, the detector can be easily
04643   //  zoomed many times in different ways. Please note that the pictures
04644   //  with solid colors can now be stored in a view bank or in 'PICTURE FILES'
04645   //
04646 }
04647 
04648 //______________________________________________________________________
04649 void TGeant3::Gdclose()
04650 {
04651   //
04652   //  It closes the currently open view bank; it must be called after the
04653   //  end of the drawing to be stored.
04654   //
04655 }
04656 
04657 //______________________________________________________________________
04658 void TGeant3::Gdshow(Int_t /* iview */)
04659 {
04660   //
04661   //  IVIEW  View number
04662   //
04663   //  It shows on the screen the contents of a view bank. It
04664   //  can be called after a view bank has been closed.
04665   //
04666 }
04667 
04668 //______________________________________________________________________
04669 void TGeant3::Gdopt(const char *name,const char *value)
04670 {
04671   //
04672   //  NAME   Option name
04673   //  VALUE  Option value
04674   //
04675   //  To set/modify the drawing options.
04676   //     IOPT   IVAL      Action
04677   //
04678   //     THRZ    ON       Draw tracks in R vs Z
04679   //             OFF (D)  Draw tracks in X,Y,Z
04680   //             180
04681   //             360
04682   //     PROJ    PARA (D) Parallel projection
04683   //             PERS     Perspective
04684   //     TRAK    LINE (D) Trajectory drawn with lines
04685   //             POIN       " " with markers
04686   //     HIDE    ON       Hidden line removal using the CG package
04687   //             OFF (D)  No hidden line removal
04688   //     SHAD    ON       Fill area and shading of surfaces.
04689   //             OFF (D)  Normal hidden line removal.
04690   //     RAYT    ON       Ray-tracing on.
04691   //             OFF (D)  Ray-tracing off.
04692   //     EDGE    OFF      Does not draw contours when shad is on.
04693   //             ON  (D)  Normal shading.
04694   //     MAPP    1,2,3,4  Mapping before ray-tracing.
04695   //             0   (D)  No mapping.
04696   //     USER    ON       User graphics options in the ray tracing.
04697   //             OFF (D)  Automatic graphics options.
04698   //
04699 
04700   char vname[5];
04701   Vname(name,vname);
04702   char vvalue[5];
04703   Vname(value,vvalue);
04704   //g3dopt(PASSCHARD(vname), PASSCHARD(vvalue) PASSCHARL(vname)
04705   //    PASSCHARL(vvalue));
04706 }
04707 
04708 //______________________________________________________________________
04709 void TGeant3::Gdraw(const char* /*name*/,Double_t /*theta*/, Double_t /*phi*/, 
04710                     Double_t /*psi*/, Double_t /*u0*/, Double_t /*v0*/, Double_t /*ul*/,
04711                     Double_t /*vl*/)
04712 {
04713   //
04714   //  NAME   Volume name
04715   //  +
04716   //  THETA  Viewing angle theta (for 3D projection)
04717   //  PHI    Viewing angle phi (for 3D projection)
04718   //  PSI    Viewing angle psi (for 2D rotation)
04719   //  U0     U-coord. (horizontal) of volume origin
04720   //  V0     V-coord. (vertical) of volume origin
04721   //  SU     Scale factor for U-coord.
04722   //  SV     Scale factor for V-coord.
04723   //
04724   //  This function will draw the volumes,
04725   //  selected with their graphical attributes, set by the Gsatt
04726   //  facility. The drawing may be performed with hidden line removal
04727   //  and with shading effects according to the value of the options HIDE
04728   //  and SHAD; if the option SHAD is ON, the contour's edges can be
04729   //  drawn or not. If the option HIDE is ON, the detector can be
04730   //  exploded (BOMB), clipped with different shapes (CVOL), and some
04731   //  of its parts can be shifted from their original
04732   //  position (SHIFT). When HIDE is ON, if
04733   //  the drawing requires more than the available memory, the program
04734   //  will evaluate and display the number of missing words
04735   //  (so that the user can increase the
04736   //  size of its ZEBRA store). Finally, at the end of each drawing (with 
04737   //  HIDE on), the program will print messages about the memory used and
04738   //  statistics on the volumes' visibility.
04739   //  The following commands will produce the drawing of a green
04740   //  volume, specified by NAME, without using the hidden line removal
04741   //  technique, using the hidden line removal technique,
04742   //  with different line width and color (red), with
04743   //  solid color, with shading of surfaces, and without edges.
04744   //  Finally, some examples are given for the ray-tracing. (A possible
04745   //  string for the NAME of the volume can be found using the command DTREE).
04746   //
04747 }
04748 
04749 //______________________________________________________________________
04750 void TGeant3::Gdrawc(const char* /*name*/,Int_t /*axis*/, Float_t /*cut*/, Float_t /*u0*/,
04751                      Float_t /*v0*/, Float_t /*ul*/, Float_t /*vl*/)
04752 {
04753   //
04754   //  NAME   Volume name
04755   //  CAXIS  Axis value
04756   //  CUTVAL Cut plane distance from the origin along the axis
04757   //  +
04758   //  U0     U-coord. (horizontal) of volume origin
04759   //  V0     V-coord. (vertical) of volume origin
04760   //  SU     Scale factor for U-coord.
04761   //  SV     Scale factor for V-coord.
04762   //
04763   //  The cut plane is normal to caxis (X,Y,Z), corresponding to iaxis (1,2,3),
04764   //  and placed at the distance cutval from the origin.
04765   //  The resulting picture is seen from the the same axis.
04766   //  When HIDE Mode is ON, it is possible to get the same effect with
04767   //  the CVOL/BOX function.
04768   //
04769 }
04770 
04771 //______________________________________________________________________
04772 void TGeant3::Gdrawx(const char* /*name*/, Float_t /*cutthe*/, Float_t /*cutphi*/,
04773                      Float_t /*cutval*/, Float_t /*theta*/, Float_t /*phi*/, Float_t /*u0*/,
04774                      Float_t /*v0*/,Float_t /*ul*/, Float_t /*vl*/)
04775 {
04776   //
04777   //  NAME   Volume name
04778   //  CUTTHE Theta angle of the line normal to cut plane
04779   //  CUTPHI Phi angle of the line normal to cut plane
04780   //  CUTVAL Cut plane distance from the origin along the axis
04781   //  +
04782   //  THETA  Viewing angle theta (for 3D projection)
04783   //  PHI    Viewing angle phi (for 3D projection)
04784   //  U0     U-coord. (horizontal) of volume origin
04785   //  V0     V-coord. (vertical) of volume origin
04786   //  SU     Scale factor for U-coord.
04787   //  SV     Scale factor for V-coord.
04788   //
04789   //  The cut plane is normal to the line given by the cut angles
04790   //  cutthe and cutphi and placed at the distance cutval from the origin.
04791   //  The resulting picture is seen from the viewing angles theta,phi.
04792   //
04793 }
04794 
04795 //______________________________________________________________________
04796 void TGeant3::Gdhead(Int_t /*isel*/, const char* /*name*/, Double_t /*chrsiz*/)
04797 {
04798   //
04799   //  Parameters
04800   //  +
04801   //  ISEL   Option flag  D=111110
04802   //  NAME   Title
04803   //  CHRSIZ Character size (cm) of title NAME D=0.6
04804   //
04805   //  ISEL =
04806   //   0      to have only the header lines
04807   //   xxxxx1 to add the text name centered on top of header
04808   //   xxxx1x to add global detector name (first volume) on left
04809   //   xxx1xx to add date on right
04810   //   xx1xxx to select thick characters for text on top of header
04811   //   x1xxxx to add the text 'EVENT NR x' on top of header
04812   //   1xxxxx to add the text 'RUN NR x' on top of header
04813   //  NOTE that ISEL=x1xxx1 or ISEL=1xxxx1 are illegal choices,
04814   //  i.e. they generate overwritten text.
04815   //
04816 }
04817 
04818 //______________________________________________________________________
04819 void TGeant3::Gdman(Double_t /*u*/, Double_t /*v*/, const char* /*type*/)
04820 {
04821   //
04822   //  Draw a 2D-man at position (U0,V0)
04823   //  Parameters
04824   //  U      U-coord. (horizontal) of the center of man' R
04825   //  V      V-coord. (vertical) of the center of man' R
04826   //  TYPE   D='MAN' possible values: 'MAN,WM1,WM2,WM3'
04827   //
04828   //   CALL GDMAN(u,v),CALL GDWMN1(u,v),CALL GDWMN2(u,v),CALL GDWMN2(u,v)
04829   //  It superimposes the picture of a man or of a woman, chosen among
04830   //  three different ones, with the same scale factors as the detector
04831   //  in the current drawing.
04832   //
04833 }
04834 
04835 //______________________________________________________________________
04836 void TGeant3::Gdspec(const char* /*name*/)
04837 {
04838   //
04839   //  NAME   Volume name
04840   //
04841   //  Shows 3 views of the volume (two cut-views and a 3D view), together with
04842   //  its geometrical specifications. The 3D drawing will
04843   //  be performed according the current values of the options HIDE and
04844   //  SHAD and according the current SetClipBox clipping parameters for that
04845   //  volume.
04846   //
04847 }
04848 
04849 //______________________________________________________________________
04850 void TGeant3::DrawOneSpec(const char* /*name*/)
04851 {
04852   //
04853   //  Function called when one double-clicks on a volume name
04854   //  in a TPavelabel drawn by Gdtree.
04855   //
04856 }
04857 
04858 //______________________________________________________________________
04859 void TGeant3::Gdtree(const char* /*name*/, Int_t /*levmax*/, Int_t /*isel*/)
04860 {
04861   //
04862   //  NAME   Volume name
04863   //  LEVMAX Depth level
04864   //  ISELT  Options
04865   //
04866   //  This function draws the logical tree,
04867   //  Each volume in the tree is represented by a TPaveTree object.
04868   //  Double-clicking on a TPaveTree draws the specs of the corresponding 
04869   //  volume.
04870   //  Use TPaveTree pop-up menu to select:
04871   //    - drawing specs
04872   //    - drawing tree
04873   //    - drawing tree of parent
04874   //
04875 }
04876 
04877 //______________________________________________________________________
04878 void TGeant3::GdtreeParent(const char* /*name*/, Int_t /*levmax*/, Int_t /*isel*/)
04879 {
04880   //
04881   //  NAME   Volume name
04882   //  LEVMAX Depth level
04883   //  ISELT  Options
04884   //
04885   //  This function draws the logical tree of the parent of name.
04886   //
04887 }
04888 
04889 //______________________________________________________________________
04890 void TGeant3::SetABAN(Int_t par)
04891 {
04892   //
04893   // par = 1 particles will be stopped according to their residual
04894   //         range if they are not in a sensitive material and are
04895   //         far enough from the boundary
04896   //       0 particles are transported normally
04897   //
04898   fGcphys->dphys1 = par;
04899   SetBit(kABAN);
04900 }
04901 
04902 
04903 //______________________________________________________________________
04904 void TGeant3::SetANNI(Int_t par)
04905 {
04906   //
04907   //   To control positron annihilation.
04908   //    par =0 no annihilation
04909   //        =1 annihilation. Decays processed.
04910   //        =2 annihilation. No decay products stored.
04911   //
04912   fGcphys->ianni = par;
04913 }
04914 
04915 
04916 //______________________________________________________________________
04917 void TGeant3::SetAUTO(Int_t par)
04918 {
04919   //
04920   //  To control automatic calculation of tracking medium parameters:
04921   //   par =0 no automatic calculation;
04922   //       =1 automatic calculation.
04923   //
04924   fGctrak->igauto = par;
04925   SetBit(kAUTO);
04926 }
04927 
04928 
04929 //______________________________________________________________________
04930 void TGeant3::SetBOMB(Float_t /*boom*/)
04931 {
04932   //
04933   //  BOOM  : Exploding factor for volumes position
04934   //
04935   //  To 'explode' the detector. If BOOM is positive (values smaller
04936   //  than 1. are suggested, but any value is possible)
04937   //  all the volumes are shifted by a distance
04938   //  proportional to BOOM along the direction between their center
04939   //  and the origin of the MARS; the volumes which are symmetric
04940   //  with respect to this origin are simply not shown.
04941   //  BOOM equal to 0 resets the normal mode.
04942   //  A negative (greater than -1.) value of
04943   //  BOOM will cause an 'implosion'; for even lower values of BOOM
04944   //  the volumes' positions will be reflected respect to the origin.
04945   //  This command can be useful to improve the 3D effect for very
04946   //  complex detectors. The following commands will make explode the
04947   //  detector:
04948   //
04949 }
04950 
04951 //______________________________________________________________________
04952 void TGeant3::SetBREM(Int_t par)
04953 {
04954   //
04955   //  To control bremsstrahlung.
04956   //   par =0 no bremsstrahlung
04957   //       =1 bremsstrahlung. Photon processed.
04958   //       =2 bremsstrahlung. No photon stored.
04959   //
04960   fGcphys->ibrem = par;
04961 }
04962 
04963 
04964 //______________________________________________________________________
04965 void TGeant3::SetCKOV(Int_t par)
04966 {
04967   //
04968   //  To control Cerenkov production
04969   //   par =0 no Cerenkov;
04970   //       =1 Cerenkov;
04971   //       =2 Cerenkov with primary stopped at each step.
04972   //
04973   fGctlit->itckov = par;
04974 }
04975 
04976 
04977 //______________________________________________________________________
04978 void  TGeant3::SetClipBox(const char* /*name*/, Double_t /*xmin*/, Double_t /*xmax*/,
04979                           Double_t /*ymin*/, Double_t /*ymax*/, Double_t /*zmin*/, Double_t /*zmax*/)
04980 {
04981   //
04982   //  The hidden line removal technique is necessary to visualize properly
04983   //  very complex detectors. At the same time, it can be useful to visualize
04984   //  the inner elements of a detector in detail. This function allows
04985   //  subtractions (via boolean operation) of BOX shape from any part of
04986   //  the detector, therefore showing its inner contents.
04987   //  If "*" is given as the name of the
04988   //  volume to be clipped, all volumes are clipped by the given box.
04989   //  A volume can be clipped at most twice.
04990   //  if a volume is explicitly clipped twice,
04991   //  the "*" will not act on it anymore. Giving "." as the name
04992   //  of the volume to be clipped will reset the clipping.
04993   //  Parameters
04994   //  NAME   Name of volume to be clipped
04995   //  +
04996   //  XMIN   Lower limit of the Shape X coordinate
04997   //  XMAX   Upper limit of the Shape X coordinate
04998   //  YMIN   Lower limit of the Shape Y coordinate
04999   //  YMAX   Upper limit of the Shape Y coordinate
05000   //  ZMIN   Lower limit of the Shape Z coordinate
05001   //  ZMAX   Upper limit of the Shape Z coordinate
05002   //
05003   //  This function performs a boolean subtraction between the volume
05004   //  NAME and a box placed in the MARS according the values of the given
05005   //  coordinates.
05006 
05007 }
05008 
05009 //______________________________________________________________________
05010 void TGeant3::SetCOMP(Int_t par)
05011 {
05012   //
05013   //  To control Compton scattering
05014   //   par =0 no Compton
05015   //       =1 Compton. Electron processed.
05016   //       =2 Compton. No electron stored.
05017   //
05018   //
05019   fGcphys->icomp = par;
05020 }
05021 
05022 //modified by Andrea Fontana and Alberto Rotondi - march 2007
05023 //added array of 5 user definable cuts (like in old Geant)
05024 //______________________________________________________________________
05025 void TGeant3::SetCUTS(Float_t cutgam,Float_t cutele,Float_t cutneu,
05026                       Float_t cuthad,Float_t cutmuo ,Float_t bcute ,
05027                       Float_t bcutm ,Float_t dcute ,Float_t dcutm ,
05028                       Float_t ppcutm, Float_t tofmax, Float_t *gcuts)
05029 {
05030   //
05031   //  CUTGAM   Cut for gammas              D=0.001
05032   //  CUTELE   Cut for electrons           D=0.001
05033   //  CUTHAD   Cut for charged hadrons     D=0.01
05034   //  CUTNEU   Cut for neutral hadrons     D=0.01
05035   //  CUTMUO   Cut for muons               D=0.01
05036   //  BCUTE    Cut for electron brems.     D=-1.
05037   //  BCUTM    Cut for muon brems.         D=-1.
05038   //  DCUTE    Cut for electron delta-rays D=-1.
05039   //  DCUTM    Cut for muon delta-rays     D=-1.
05040   //  PPCUTM   Cut for e+e- pairs by muons D=0.01
05041   //  TOFMAX   Time of flight cut          D=1.E+10
05042   //
05043   //   If the default values (-1.) for       BCUTE ,BCUTM ,DCUTE ,DCUTM
05044   //   are not modified, they will be set to CUTGAM,CUTGAM,CUTELE,CUTELE
05045   //   respectively.
05046   //  If one of the parameters from CUTGAM to PPCUTM included
05047   //  is modified, cross-sections and energy loss tables must be
05048   //  recomputed via the function Gphysi.
05049   //
05050   fGccuts->cutgam = cutgam;
05051   fGccuts->cutele = cutele;
05052   fGccuts->cutneu = cutneu;
05053   fGccuts->cuthad = cuthad;
05054   fGccuts->cutmuo = cutmuo;
05055   fGccuts->bcute  = bcute;
05056   fGccuts->bcutm  = bcutm;
05057   fGccuts->dcute  = dcute;
05058   fGccuts->dcutm  = dcutm;
05059   fGccuts->ppcutm = ppcutm;
05060   fGccuts->tofmax = tofmax;
05061 //sk:begin
05062 //  Modified 2007/11/04 S. Kasahara to protect against null gcuts argument
05063   if ( gcuts != 0 ) { 
05064     fGccuts->gcuts[0] = gcuts[0];
05065     fGccuts->gcuts[1] = gcuts[1];
05066     fGccuts->gcuts[2] = gcuts[2];
05067     fGccuts->gcuts[3] = gcuts[3];
05068     fGccuts->gcuts[4] = gcuts[4];
05069   }
05070 //sk:end
05071 }
05072 
05073 //added by Andrea Fontana and Alberto Rotondi - april 2007
05074 //______________________________________________________________________
05075 void TGeant3::SetECut(Float_t gcalpha)
05076 {
05077   fGcmore->gcalpha = gcalpha;
05078 }
05079 
05080 void TGeant3::SetClose(Int_t iclose,Float_t *pf,Float_t dstrt,
05081                        Float_t *w1, Float_t *w2,
05082                        Float_t *p1,Float_t *p2,Float_t *p3,Float_t *clen)
05083 {
05084   fGcmore->iclose = iclose;
05085   fGcmore->pfinal[0] = pf[0];
05086   fGcmore->pfinal[1] = pf[1];
05087   fGcmore->pfinal[2] = pf[2];
05088   fGcmore->dstrt = dstrt;
05089   fGcmore->wire1[0] = w1[0];
05090   fGcmore->wire1[1] = w1[1];
05091   fGcmore->wire1[2] = w1[2];
05092   fGcmore->wire2[0] = w2[0];
05093   fGcmore->wire2[1] = w2[1];
05094   fGcmore->wire2[2] = w2[2];
05095   fGcmore->p1[0] = p1[0];
05096   fGcmore->p1[1] = p1[1];
05097   fGcmore->p1[2] = p1[2];
05098   fGcmore->p2[0] = p2[0];
05099   fGcmore->p2[1] = p2[1];
05100   fGcmore->p2[2] = p2[2];
05101   fGcmore->p3[0] = p3[0];
05102   fGcmore->p3[1] = p3[1];
05103   fGcmore->p3[2] = p3[2];
05104   fGcmore->cleng[0] = clen[0];
05105   fGcmore->cleng[1] = clen[1];
05106   fGcmore->cleng[2] = clen[2];
05107 }
05108 
05109 void TGeant3::GetClose(Float_t *p1,Float_t *p2,Float_t *p3,Float_t *len)
05110 {
05111   p1[0] = fGcmore->p1[0];
05112   p1[1] = fGcmore->p1[1];
05113   p1[2] = fGcmore->p1[2];
05114   p2[0] = fGcmore->p2[0];
05115   p2[1] = fGcmore->p2[1];
05116   p2[2] = fGcmore->p2[2];
05117   p3[0] = fGcmore->p3[0];
05118   p3[1] = fGcmore->p3[1];
05119   p3[2] = fGcmore->p3[2];
05120   len[0] = fGcmore->cleng[0];
05121   len[1] = fGcmore->cleng[1];
05122   len[2] = fGcmore->cleng[2];
05123 }
05124 
05125 //______________________________________________________________________
05126 void TGeant3::SetDCAY(Int_t par)
05127 {
05128   //
05129   //  To control Decay mechanism.
05130   //   par =0 no decays.
05131   //       =1 Decays. secondaries processed.
05132   //       =2 Decays. No secondaries stored.
05133   //
05134   fGcphys->idcay = par;
05135 }
05136 
05137 
05138 //______________________________________________________________________
05139 void TGeant3::SetDEBU(Int_t emin, Int_t emax, Int_t emod)
05140 {
05141   //
05142   // Set the debug flag and frequency
05143   // Selected debug output will be printed from
05144   // event emin to even emax each emod event
05145   //
05146   fGcflag->idemin = emin;
05147   fGcflag->idemax = emax;
05148   fGcflag->itest  = emod;
05149   SetBit(kDEBU);
05150 }
05151 
05152 
05153 //______________________________________________________________________
05154 void TGeant3::SetDRAY(Int_t par)
05155 {
05156   //
05157   //  To control delta rays mechanism.
05158   //   par =0 no delta rays.
05159   //       =1 Delta rays. secondaries processed.
05160   //       =2 Delta rays. No secondaries stored.
05161   //
05162   fGcphys->idray = par;
05163 }
05164 
05165 //______________________________________________________________________
05166 void TGeant3::SetERAN(Float_t ekmin, Float_t ekmax, Int_t nekbin)
05167 {
05168   //
05169   //  To control cross section tabulations
05170   //   ekmin = minimum kinetic energy in GeV
05171   //   ekmax = maximum kinetic energy in GeV
05172   //   nekbin = number of logarithmic bins (<200)
05173   //
05174   fGcmulo->ekmin = ekmin;
05175   fGcmulo->ekmax = ekmax;
05176   fGcmulo->nekbin = nekbin;
05177   SetBit(kERAN);
05178 }
05179 
05180 //______________________________________________________________________
05181 void TGeant3::SetHADR(Int_t par)
05182 {
05183   //
05184   //  To control hadronic interactions.
05185   //   par =0 no hadronic interactions.
05186   //       =1 Hadronic interactions. secondaries processed.
05187   //       =2 Hadronic interactions. No secondaries stored.
05188   //
05189   fGcphys->ihadr = par;
05190 }
05191 
05192 //______________________________________________________________________
05193 void TGeant3::SetKINE(Int_t kine, Float_t xk1, Float_t xk2, Float_t xk3,
05194                       Float_t xk4, Float_t xk5, Float_t xk6, Float_t xk7,
05195                       Float_t xk8, Float_t xk9, Float_t xk10)
05196 {
05197   //
05198   // Set the variables in /GCFLAG/ IKINE, PKINE(10)
05199   // Their meaning is user defined
05200   //
05201   fGckine->ikine    = kine;
05202   fGckine->pkine[0] = xk1;
05203   fGckine->pkine[1] = xk2;
05204   fGckine->pkine[2] = xk3;
05205   fGckine->pkine[3] = xk4;
05206   fGckine->pkine[4] = xk5;
05207   fGckine->pkine[5] = xk6;
05208   fGckine->pkine[6] = xk7;
05209   fGckine->pkine[7] = xk8;
05210   fGckine->pkine[8] = xk9;
05211   fGckine->pkine[9] = xk10;
05212 }
05213 
05214 //______________________________________________________________________
05215 void TGeant3::SetLOSS(Int_t par)
05216 {
05217   //
05218   //  To control energy loss.
05219   //   par =0 no energy loss;
05220   //       =1 restricted energy loss fluctuations;
05221   //       =2 complete energy loss fluctuations;
05222   //       =3 same as 1;
05223   //       =4 no energy loss fluctuations.
05224   //  If the value ILOSS is changed, then cross-sections and energy loss
05225   //  tables must be recomputed via the command 'PHYSI'.
05226   //
05227   fGcphys->iloss = par;
05228 }
05229 
05230 
05231 //______________________________________________________________________
05232 void TGeant3::SetMULS(Int_t par)
05233 {
05234   //
05235   //  To control multiple scattering.
05236   //   par =0 no multiple scattering.
05237   //       =1 Moliere or Coulomb scattering.
05238   //       =2 Moliere or Coulomb scattering.
05239   //       =3 Gaussian scattering.
05240   //
05241   fGcphys->imuls = par;
05242 }
05243 
05244 
05245 //______________________________________________________________________
05246 void TGeant3::SetMUNU(Int_t par)
05247 {
05248   //
05249   //  To control muon nuclear interactions.
05250   //   par =0 no muon-nuclear interactions.
05251   //       =1 Nuclear interactions. Secondaries processed.
05252   //       =2 Nuclear interactions. Secondaries not processed.
05253   //
05254   fGcphys->imunu = par;
05255 }
05256 
05257 //______________________________________________________________________
05258 void TGeant3::SetOPTI(Int_t par)
05259 {
05260   //
05261   //  This flag controls the tracking optimization performed via the
05262   //  GSORD routine:
05263   //      1 no optimization at all; GSORD calls disabled;
05264   //      0 no optimization; only user calls to GSORD kept;
05265   //      1 all non-GSORDered volumes are ordered along the best axis;
05266   //      2 all volumes are ordered along the best axis.
05267   //
05268   fGcopti->ioptim = par;
05269   SetBit(kOPTI);
05270 }
05271 
05272 //______________________________________________________________________
05273 void TGeant3::SetPAIR(Int_t par)
05274 {
05275   //
05276   //  To control pair production mechanism.
05277   //   par =0 no pair production.
05278   //       =1 Pair production. secondaries processed.
05279   //       =2 Pair production. No secondaries stored.
05280   //
05281   fGcphys->ipair = par;
05282 }
05283 
05284 
05285 //______________________________________________________________________
05286 void TGeant3::SetPFIS(Int_t par)
05287 {
05288   //
05289   //  To control photo fission mechanism.
05290   //   par =0 no photo fission.
05291   //       =1 Photo fission. secondaries processed.
05292   //       =2 Photo fission. No secondaries stored.
05293   //
05294   fGcphys->ipfis = par;
05295 }
05296 
05297 //______________________________________________________________________
05298 void TGeant3::SetPHOT(Int_t par)
05299 {
05300   //
05301   //  To control Photo effect.
05302   //   par =0 no photo electric effect.
05303   //       =1 Photo effect. Electron processed.
05304   //       =2 Photo effect. No electron stored.
05305   //
05306   fGcphys->iphot = par;
05307 }
05308 
05309 //______________________________________________________________________
05310 void TGeant3::SetRAYL(Int_t par)
05311 {
05312   //
05313   //  To control Rayleigh scattering.
05314   //   par =0 no Rayleigh scattering.
05315   //       =1 Rayleigh.
05316   //
05317   fGcphys->irayl = par;
05318 }
05319 
05320 //______________________________________________________________________
05321 void TGeant3::SetSTRA(Int_t par)
05322 {
05323   //
05324   //  To control energy loss fluctuations
05325   //  with the Photo-Absorption Ionization model.
05326   //   par =0 no Straggling.
05327   //       =1 Straggling yes => no Delta rays.
05328   //
05329   fGcphlt->istra = par;
05330 }
05331 
05332 //______________________________________________________________________
05333 void TGeant3::SetSWIT(Int_t sw, Int_t val)
05334 {
05335   //
05336   //  sw    Switch number
05337   //  val   New switch value
05338   //
05339   //  Change one element of array ISWIT(10) in /GCFLAG/
05340   //
05341   if (sw <= 0 || sw > 10) return;
05342   fGcflag->iswit[sw-1] = val;
05343   SetBit(kSWIT);
05344 }
05345 
05346 
05347 //______________________________________________________________________
05348 void TGeant3::SetTRIG(Int_t nevents)
05349 {
05350   //
05351   // Set number of events to be run
05352   //
05353   fGcflag->nevent = nevents;
05354   SetBit(kTRIG);
05355 }
05356 
05357 //______________________________________________________________________
05358 void TGeant3::SetUserDecay(Int_t pdg)
05359 {
05360   //
05361   // Force the decays of particles to be done with Pythia
05362   // and not with the Geant routines.
05363   // just kill pointers doing mzdrop
05364   //
05365   Int_t ipart = IdFromPDG(pdg);
05366   if(ipart<0) {
05367     printf("Particle %d not in geant\n",pdg);
05368     return;
05369   }
05370   Int_t jpart=fGclink->jpart;
05371   Int_t jpa=fZlq[jpart-ipart];
05372   //
05373   if(jpart && jpa) {
05374     Int_t jpa1=fZlq[jpa-1];
05375     if(jpa1)
05376       mzdrop(fGcbank->ixcons,jpa1,PASSCHARD(" ") PASSCHARL(" "));
05377     Int_t jpa2=fZlq[jpa-2];
05378     if(jpa2)
05379       mzdrop(fGcbank->ixcons,jpa2,PASSCHARD(" ") PASSCHARL(" "));
05380   }
05381 }
05382 //______________________________________________________________________
05383 Bool_t TGeant3::SetDecayMode(Int_t pdg, Float_t bratio[6], Int_t mode[6][3])
05384 {
05385   //
05386   // Set user decay modes by calling Gsdk
05387   //
05388    if ( pdg == 0 ) {
05389      printf("Cannot define decay mode for particle with PDG=0");
05390      return false;
05391    }
05392 
05393    if ( IdFromPDG(pdg) < 0 ) {
05394      printf("Particle %d not in geant\n",pdg);
05395      return false;
05396    }
05397 
05398    SetUserDecay(pdg);
05399 
05400    Int_t g3mode[6];
05401    Int_t id1,id2,id3;
05402    for (Int_t k1=0; k1<6; k1++) g3mode[k1]=0;
05403    for (Int_t k=0; k<6; k++) {
05404 
05405       if(mode[k][0]!=0) {
05406         id1= IdFromPDG(mode[k][0]);
05407         if ( id1 < 0 ) {
05408           printf("Particle %d not in geant\n",mode[k][0]);
05409           return false;
05410         }
05411       }  
05412       else id1=0;
05413 
05414       if(mode[k][1]!=0) {
05415         id2= IdFromPDG(mode[k][1]);
05416         if ( id2 < 0 ) {
05417           printf("Particle %d not in geant\n",mode[k][1]);
05418           return false;
05419         }
05420       }  
05421       else id2=0;
05422       
05423       if(mode[k][2]!=0) {
05424         id3= IdFromPDG(mode[k][2]);
05425         if ( id3 < 0 ) {
05426           printf("Particle %d not in geant\n",mode[k][1]);
05427           return false;
05428         }
05429       }  
05430       else id3=0;
05431       g3mode[k]=id1 + id2* 100+ id3 * 10000 ;
05432       
05433    }                                      
05434    Gsdk(IdFromPDG(pdg), bratio, g3mode);  
05435    return kTRUE;
05436 }                                
05437 
05438 //______________________________________________________________________
05439 void TGeant3::Vname(const char *name, char *vname)
05440 {
05441   //
05442   //  convert name to upper case. Make vname at least 4 chars
05443   //
05444   Int_t l = strlen(name);
05445   Int_t i;
05446   l = l < 4 ? l : 4;
05447   for (i=0;i<l;i++) vname[i] = toupper(name[i]);
05448   for (i=l;i<4;i++) vname[i] = ' ';
05449   vname[4] = 0;
05450 }
05451 
05452 //______________________________________________________________________
05453 void TGeant3::Ertrgo()
05454 {
05455   //
05456   // Perform the tracking of the track Track parameters are in VECT
05457   //
05458   ertrgo();
05459 }
05460 
05461 //______________________________________________________________________
05462 void TGeant3::Ertrak(const Float_t *x1, const Float_t *p1,
05463                         const Float_t *x2, const Float_t *p2,
05464                         Int_t ipa,  Option_t *chopt)
05465 {
05466   //************************************************************************
05467   //*                                                                      *
05468   //*          Perform the tracking of the track from point X1 to          *
05469   //*                    point X2                                          *
05470   //*          (Before calling this routine the user should also provide   *
05471   //*                    the input informations in /EROPTS/ and /ERTRIO/   *
05472   //*                    using subroutine EUFIL(L/P/V)                     *
05473   //*                 X1       - Starting coordinates (Cartesian)          *
05474   //*                 P1       - Starting 3-momentum  (Cartesian)          *
05475   //*                 X2       - Final coordinates    (Cartesian)          *
05476   //*                 P2       - Final 3-momentum     (Cartesian)          *
05477   //*                 IPA      - Particle code (a la GEANT) of the track   *
05478   //*                                                                      *
05479   //*                 CHOPT                                                *
05480   //*                     'B'   'Backward tracking' - i.e. energy loss     *
05481   //*                                        added to the current energy   *
05482   //*                     'E'   'Exact' calculation of errors assuming     *
05483   //*                                        helix (i.e. path-length not   *
05484   //*                                        assumed as infinitesimal)     *
05485   //*                     'L'   Tracking up to prescribed Lengths reached  *
05486   //*                     'M'   'Mixed' prediction (not yet coded)         *
05487   //*                     'O'   Tracking 'Only' without calculating errors *
05488   //*                     'P'   Tracking up to prescribed Planes reached   *
05489   //*                     'V'   Tracking up to prescribed Volumes reached  *
05490   //*                     'X'   Tracking up to prescribed Point approached *
05491   //*                                                                      *
05492   //*                Interface with GEANT :                                *
05493   //*             Track parameters are in /CGKINE/ and /GCTRAK/            *
05494   //*                                                                      *
05495   //*          ==>Called by : USER                                         *
05496   //*             Authors   M.Maire, E.Nagy  ********//*                   *
05497   //*                                                                      *
05498   //************************************************************************
05499   ertrak(x1,p1,x2,p2,ipa,PASSCHARD(chopt) PASSCHARL(chopt));
05500 }
05501 
05502 void TGeant3::Eufill(Int_t n,Float_t *ein,Float_t *xlf){
05503 
05504 // C.    ******************************************************************
05505 // C.    *                                                                *
05506 // C.    *    User routine to fill the input values of the commons :      *
05507 // C.    *               /EROPTS/, /EROPTC/ and /ERTRIO/ for CHOPT = 'L'  *
05508 // C.    *         N     Number of predictions where to store results     *
05509 // C.    *         EIN   Input error matrix                               *
05510 // C.    *         XLF   Defines the tracklengths which if passed the     *
05511 // C.    *                      result should be stored                   *
05512 // C.    *                                                                *
05513 // C.    *                                                                *
05514 // C.    *    ==>Called by : USER (before calling ERTRAK)                 *
05515 // C.    *       Author    M.Maire, E.Nagy  *********                     *
05516 // C.    *                                                                *
05517 // C.    ******************************************************************
05518    for(Int_t i=0;i<15;i++) fErtrio->errin[i]=ein[i]; 
05519    const Int_t mxpred=10;
05520    if (n<mxpred) {
05521       fErtrio->nepred=n;
05522     } else {
05523      fErtrio->nepred=mxpred;
05524    } 
05525    for(Int_t i=0;i<15;i++) fErtrio->errin[i]=ein[i]; 
05526    for(Int_t i=0;i<fErtrio->nepred;i++) fEropts->erleng[i]=xlf[i]; 
05527 //  eufill(n,ein,xlf);
05528 }
05529 
05530 void TGeant3::Eufilp(const Int_t n, Float_t *ein,
05531                         Float_t *pli, Float_t *plf)
05532 {
05533   //    ******************************************************************
05534   //    *                                                                *
05535   //    *    User routine to fill the input values of the commons :      *
05536   //    *               /EROPTS/, /EROPTC/ and /ERTRIO/ for CHOPT = 'P'  *
05537   //    *         N     Number of predictions where to store results     *
05538   //    *         EIN   Input error matrix (in the 'Plane' system )      *
05539   //    *         PLI   Defines the start plane                          *
05540   //    *                      PLI(3,1) - and                            *
05541   //    *                      PLI(3,2) - 2 unit vectors in the plane    *
05542   //    *         PLF   Defines the end plane                            *
05543   //    *                      PLF(3,1,I) - and                          *
05544   //    *                      PLF(3,2,I) - 2 unit vectors in the plane  *
05545   //    *                      PLF(3,3,I) - point on the plane           *
05546   //    *                                   at intermediate point I      *
05547   //    *                                                                *
05548   //    *    ==>Called by : USER (before calling ERTRAK)                 *
05549   //    *       Author    M.Maire, E.Nagy  *********                     *
05550   //    *                                                                *
05551   //    ******************************************************************
05552    for(Int_t i=0;i<15;i++) fErtrio->errin[i]=ein[i]; 
05553    const Int_t mxpred=10;
05554    if (n<mxpred) {
05555       fErtrio->nepred=n;
05556     } else {
05557      fErtrio->nepred=mxpred;
05558    } 
05559    for(Int_t i=0;i<6;i++) fEropts->erpli[i]=pli[i]; 
05560 
05561    for (Int_t j=0;j<n;j++) {
05562      for(Int_t i=0;i<9;i++) {
05563        fEropts->erplo[i+12*j]=plf[i+12*j]; 
05564      }
05565      TVector3 v1(fEropts->erplo[0+12*j],fEropts->erplo[1+12*j],fEropts->erplo[2+12*j]);
05566      TVector3 v2(fEropts->erplo[3+12*j],fEropts->erplo[4+12*j],fEropts->erplo[5+12*j]);
05567      TVector3 v3=v1.Cross(v2);
05568      fEropts->erplo[9]=v3(0);
05569      fEropts->erplo[10]=v3(1);
05570      fEropts->erplo[11]=v3(2);
05571    }
05572 
05573 
05574 }
05575 void TGeant3::Eufilv(Int_t n, Float_t *ein,
05576                         Char_t *namv, Int_t *numv,Int_t *iovl)
05577 {
05578 
05579   //    ******************************************************************
05580   //    *                                                                *
05581   //    *    User routine to fill the input values of the commons :      *
05582   //    *               /EROPTS/, /EROPTC/ and /ERTRIO/ for CHOPT = 'V'  *
05583   //    *         N     Number of predictions where to store results     *
05584   //    *         EIN   Input error matrix                               *
05585   //    *        CNAMV  Volume name of the prediction                    *
05586   //    *        NUMV   Volume number (if 0 = all volumes)               *
05587   //    *        IOVL   = 1  prediction when entering in the volume      *
05588   //    *               = 2  prediction when leaving the volume          *
05589   //    *                                                                *
05590   //    *    ==>Called by : USER (before calling ERTRAK)                 *
05591   //    *       Author    M.Maire, E.Nagy  *********                     *
05592   //    *                                                                *
05593   //    ******************************************************************
05594 
05595   for(Int_t i=0;i<15;i++) fErtrio->errin[i]=ein[i]; 
05596    const Int_t mxpred=15;
05597    if (n<mxpred) {
05598       fErtrio->nepred=n;
05599     } else {
05600      fErtrio->nepred=mxpred;
05601    } 
05602    
05603    for(Int_t i=0;i<fErtrio->nepred;i++) {
05604      fEropts->nameer[i]=*((int*)namv);
05605      fEropts->iovler[i]=iovl[i];
05606      fEropts->numver[i]=numv[i];
05607    }
05608 }
05609 void TGeant3::Trscsd(Float_t *pc,Float_t *rc,Float_t *pd,Float_t *rd,Float_t *h,Float_t ch,Int_t ierr,Float_t spu,Float_t *dj,Float_t *dk){
05610 
05611 //       SUBROUTINE TRSCSD(PC,RC,PD,RD,H,CH,IERR,SPU,DJ,DK)
05612 // ******************************************************************
05613 //  *** TRANSFORMS ERROR MATRIX
05614 //    FROM   SC   VARIABLES (1/P,LAMBDA,PHI,YT,ZT)
05615 //       TO         VARIABLES (1/P,V',W',V,W)
05616 // 
05617 //      Authors: A. Haas and W. Wittek
05618 //  *** PC(3)     1/P,LAMBDA,PHI                          INPUT
05619 //      PD(3)     1/P,V',W'                              OUTPUT
05620 //      H(3)      MAGNETIC FIELD                          INPUT
05621 //      RC(15)    ERROR MATRIX IN   SC   VARIABLES        INPUT     (TRIANGLE)
05622 //      RD(15)    ERROR MATRIX IN 1/P,V',W',V,W          OUTPUT     (TRIANGLE)
05623 //      CH        CHARGE OF PARTICLE                      INPUT
05624 //                CHARGE AND MAGNETIC FIELD ARE NEEDED
05625 //                FOR CORRELATION TERMS (V',YT),(V',ZT),(W',YT),(W',ZT)
05626 //                THESE CORRELATION TERMS APPEAR BECAUSE RC IS ASSUMED
05627 //                TO BE THE ERROR MATRIX FOR FIXED S (PATH LENGTH)
05628 //                AND RD FOR FIXED U
05629 //      DJ(3)     UNIT VECTOR IN V-DIRECTION
05630 //      DK(3)     UNIT VECTOR IN W-DIRECTION    OF DETECTOR SYSTEM
05631 // 
05632 //      IERR  =   1       PARTICLE MOVES PERPENDICULAR TO U-AXIS
05633 //                       ( V',W' ARE NOT DEFINED )
05634 //      SPU       SIGN OF U-COMPONENT OF PARTICLE MOMENTUM   OUTPUT
05635 // ******************************************************************
05636   printf("%d\n",ierr);
05637   trscsd(pc,rc,pd,rd,h,ch,ierr,spu,dj,dk);
05638 }
05639 //______________________________________________________________________
05640 void TGeant3::Trsdsc(Float_t *pd,Float_t *rd,Float_t *pc,Float_t *rc,Float_t *h,Float_t *ch,Int_t *ierr,Float_t *spu,Float_t *dj,Float_t *dk) {
05641 // ******************************************************************
05642 //       SUBROUTINE TRSDSC(PD,RD,PC,RC,H,CH,IERR,SPU,DJ,DK)
05643 // 
05644 //  *** TRANSFORMS ERROR MATRIX
05645 //      FROM        VARIABLES (1/P,V',W',V,W)
05646 //       TO    SC   VARIABLES (1/P,LAMBDA,PHI,YT,ZT)
05647 //      Authors: A. Haas and W. Wittek
05648 //  *** PD(3)     1/P,V',W'                               INPUT
05649 //      PC(3)     1/P,LAMBDA,PHI                         OUTPUT
05650 //      H(3)      MAGNETIC FIELD                          INPUT
05651 //      RD(15)    ERROR MATRIX IN 1/P,V',W',V,W           INPUT      (TRIANGLE)
05652 //      RC(15)    ERROR MATRIX IN   SC   VARIABLES       OUTPUT      (TRIANGLE)
05653 //      CH        CHARGE OF PARTICLE                      INPUT
05654 //                CHARGE AND MAGNETIC FIELD ARE NEEDED
05655 //                FOR CORRELATION TERMS (LAMBDA,V),(LAMBDA,W),(PHI,V),(PHI,W)
05656 //                THESE CORRELATION TERMS APPEAR BECAUSE RC IS ASSUMED
05657 //                TO BE THE ERROR MATRIX FOR FIXED S (PATH LENGTH)
05658 //                AND RD FOR FIXED U
05659 //      DJ(3)     UNIT VECTOR IN V-DIRECTION
05660 //      DK(3)     UNIT VECTOR IN W-DIRECTION    OF DETECTOR SYSTEM
05661 // 
05662 //      IERR              NOT USED
05663 //      SPU       SIGN OF U-COMPONENT OF PARTICLE MOMENTUM    INPUT
05664 // ******************************************************************
05665  trsdsc(pd,rd,pc,rc,h,ch,ierr,spu,dj,dk);
05666 }
05667 //______________________________________________________________________
05668 void TGeant3::Trscsp(Float_t *pc,Float_t *rc,Float_t *ps,Float_t *rs,Float_t *h,Float_t *ch,Int_t *ierr, Float_t *spx){
05669 // ******************************************************************
05670 //       SUBROUTINE TRSCSP(PC,RC,PS,RS,H,CH,IERR,SPX)
05671 // 
05672 //  *** TRANSFORMS ERROR MATRIX
05673 //      FROM   SC   VARIABLES (1/P,LAMBDA,PHI,YT,ZT)
05674 //       TO  SPLINE VARIABLES (1/P,Y',Z',Y,Z)
05675 // 
05676 //      Authors: A. Haas and W. Wittek
05677 // 
05678 // 
05679 //  *** PC(3)     1/P,LAMBDA,PHI                          INPUT
05680 //      PS(3)     1/P,Y',Z'                              OUTPUT
05681 //      H(3)      MAGNETIC FIELD                          INPUT
05682 //      RC(15)    ERROR MATRIX IN   SC   VARIABLES        INPUT     (TRIANGLE)
05683 //      RS(15)    ERROR MATRIX IN SPLINE VARIABLES       OUTPUT     (TRIANGLE)
05684 //      CH        CHARGE OF PARTICLE                      INPUT
05685 //                CHARGE AND MAGNETIC FIELD ARE NEEDED
05686 //                FOR CORRELATION TERMS (Y',YT),(Y',ZT),(Z',YT),(Z',ZT)
05687 //                THESE CORRELATION TERMS APPEAR BECAUSE RC IS ASSUMED
05688 //                TO BE THE ERROR MATRIX FOR FIXED S (PATH LENGTH)
05689 //                AND RS FOR FIXED X
05690 // 
05691 //      IERR  =   1       PARTICLE MOVES PERPENDICULAR TO X-AXIS
05692 //                       ( Y',Z' ARE NOT DEFINED )
05693 //      SPX       SIGN OF X-COMPONENT OF PARTICLE MOMENTUM   OUTPUT
05694 // ******************************************************************
05695   trscsp(pc,rc,ps,rs,h,ch,ierr,spx);
05696 }
05697 void TGeant3::Trspsc(Float_t *ps,Float_t *rs,Float_t *pc,Float_t *rc,Float_t *h,Float_t *ch,Int_t *ierr,Float_t *spx) {
05698 
05699 //     ******************************************************************
05700 //       SUBROUTINE TRSPSC(PS,RS,PC,RC,H,CH,IERR,SPX)
05701 // 
05702 //  *** TRANSFORMS ERROR MATRIX
05703 //      FROM SPLINE VARIABLES (1/P,Y',Z',Y,Z)
05704 //       TO    SC   VARIABLES (1/P,LAMBDA,PHI,YT,ZT)
05705 // 
05706 //      Authors: A. Haas and W. Wittek
05707 // 
05708 // 
05709 //  *** PS(3)     1/P,Y',Z'                               INPUT
05710 //      PC(3)     1/P,LAMBDA,PHI                         OUTPUT
05711 //      H(3)      MAGNETIC FIELD                          INPUT
05712 //      RS(15)    ERROR MATRIX IN SPLINE VARIABLES        INPUT      (TRIANGLE)
05713 //      RC(15)    ERROR MATRIX IN   SC   VARIABLES       OUTPUT      (TRIANGLE)
05714 //      CH        CHARGE OF PARTICLE                      INPUT
05715 //                CHARGE AND MAGNETIC FIELD ARE NEEDED
05716 //                FOR CORRELATION TERMS (LAMBDA,Y),(LAMBDA,Z),(PHI,Y),(PHI,Z)
05717 //                THESE CORRELATION TERMS APPEAR BECAUSE RC IS ASSUMED
05718 //                TO BE THE ERROR MATRIX FOR FIXED S (PATH LENGTH)
05719 //                AND RS FOR FIXED X
05720 // 
05721 //      IERR              NOT USED
05722 //      SPX       SIGN OF X-COMPONENT OF PARTICLE MOMENTUM    INPUT
05723 // 
05724 //     ******************************************************************
05725 
05726  trspsc(ps,rs,pc,rc,h,ch,ierr,spx);
05727 
05728 }
05729 //sk:begin
05730 //    Modified: S. Kasahara  2006/05/07
05731 //    Add section for G3PTSim customization configuration
05732 //_____________________________________________________________________________
05733 void TGeant3::SetALTDEDX(Int_t par)
05734 {
05735   //
05736   //   Configure alternative dE/dX modeling on (default) or off.
05737   //   par =0 use standard Geant3 dE/dX modeling for density effect
05738   //       =1 use Mike Kordosky's alternative dE/dX modeling. (default)
05739   //
05740   fPtopts->use_alt_dedx = par;
05741 }
05742 
05743 //_____________________________________________________________________________
05744 void TGeant3::SetUserDecayProductStableMinLifetime(Double_t minlifetime)
05745 {
05746   // Configure user decay code to set minimum lifetime by which decay
05747   // products will be considered stable for kick back to transport mechanism.  
05748   // If lifetime is less than minimum, the particle will be decayed promptly 
05749   // and only its decay products (if in turn stable) will be passed back 
05750   // to transport.
05751   // Note: Only particle types defined to Geant3 can be kicked back.
05752   // Args: minlifetime (sec) (default = 1.E-15 sec)
05753 
05754   fUserDecayProductStableMinLifetime = minlifetime;
05755 }
05756 //sk:end
05757 
05758 //______________________________________________________________________
05759 void TGeant3::WriteEuclid(const char* filnam, const char* topvol,
05760                           Int_t number, Int_t nlevel)
05761 {
05762   //
05763   //
05764   //     ******************************************************************
05765   //     *                                                                *
05766   //     *  Write out the geometry of the detector in EUCLID file format  *
05767   //     *                                                                *
05768   //     *       filnam : will be with the extension .euc                 *
05769   //     *       topvol : volume name of the starting node                *
05770   //     *       number : copy number of topvol (relevant for gsposp)     *
05771   //     *       nlevel : number of  levels in the tree structure         *
05772   //     *                to be written out, starting from topvol         *
05773   //     *                                                                *
05774   //     *       Author : M. Maire                                        *
05775   //     *                                                                *
05776   //     ******************************************************************
05777   //
05778   //     File filnam.tme is written out with the definitions of tracking
05779   //     medias and materials.
05780   //     As to restore original numbers for materials and medias, program
05781   //     searches in the file euc_medi.dat and comparing main parameters of
05782   //     the mat. defined inside geant and the one in file recognizes them
05783   //     and is able to take number from file. If for any material or medium,
05784   //     this procedure fails, ordering starts from 1.
05785   //     Arrays IOTMED and IOMATE are used for this procedure
05786   //
05787   const char kShape[][5]={"BOX ","TRD1","TRD2","TRAP","TUBE","TUBS","CONE",
05788                          "CONS","SPHE","PARA","PGON","PCON","ELTU","HYPE",
05789                          "GTRA","CTUB"};
05790   Int_t i, end, itm, irm, jrm, k, nmed;
05791   Int_t imxtmed=0;
05792   Int_t imxmate=0;
05793   FILE *lun;
05794   char *filext, *filetme;
05795   char natmed[21], namate[21];
05796   char natmedc[21], namatec[21];
05797   char key[5], name[5], mother[5], konly[5];
05798   char card[133];
05799   Int_t iadvol, iadtmd, iadrot, nwtot, iret;
05800   Int_t mlevel, numbr, natt, numed, nin, ndata;
05801   Int_t iname, ivo, ish, jvo, nvstak, ivstak;
05802   Int_t jdiv, ivin, in, jin, jvin, irot;
05803   Int_t jtm, imat, jma, flag=0, imatc;
05804   Float_t az, dens, radl, absl, a, step, x, y, z;
05805   Int_t npar, ndvmx, left;
05806   Float_t zc, densc, radlc, abslc, c0, tmaxfd;
05807   Int_t nparc, numb;
05808   Int_t iomate[100], iotmed[100];
05809   Float_t par[100], att[20], ubuf[50];
05810   Float_t *qws;
05811   Int_t   *iws;
05812   Int_t level, ndiv, iaxe;
05813   Int_t itmedc, nmatc, isvolc, ifieldc, nwbufc, isvol, nmat, ifield, nwbuf;
05814   Float_t fieldmc, tmaxfdc, stemaxc, deemaxc, epsilc, stminc, fieldm;
05815   Float_t tmaxf, stemax, deemax, epsil, stmin;
05816   const char *k10000="!\n%s\n!\n";
05817   //Open the input file
05818   end=strlen(filnam);
05819   for(i=0;i<end;i++) if(filnam[i]=='.') {
05820     end=i;
05821     break;
05822   }
05823   filext=new char[end+5];
05824   filetme=new char[end+5];
05825   strncpy(filext,filnam,end);
05826   strncpy(filetme,filnam,end);
05827   //
05828   // *** The output filnam name will be with extension '.euc'
05829   strcpy(&filext[end],".euc");
05830   strcpy(&filetme[end],".tme");
05831   lun=fopen(filext,"w");
05832   //
05833   // *** Initialization of the working space
05834   iadvol=fGcnum->nvolum;
05835   iadtmd=iadvol+fGcnum->nvolum;
05836   iadrot=iadtmd+fGcnum->ntmed;
05837   if(fGclink->jrotm) {
05838     fGcnum->nrotm=fZiq[fGclink->jrotm-2];
05839   } else {
05840     fGcnum->nrotm=0;
05841   }
05842   nwtot=iadrot+fGcnum->nrotm;
05843   qws = new float[nwtot+1];
05844   for (i=0;i<nwtot+1;i++) qws[i]=0;
05845   iws = (Int_t*) qws;
05846   mlevel=nlevel;
05847   if(nlevel==0) mlevel=20;
05848   //
05849   // *** find the top volume and put it in the stack
05850   numbr = number>0 ? number : 1;
05851   Gfpara(topvol,numbr,1,npar,natt,par,att);
05852   if(npar <= 0) {
05853     printf(" *** GWEUCL *** top volume : %s number : %3d can not be "
05854            "a valid root\n", topvol, numbr);
05855     return;
05856   }
05857   //
05858   // ***  authorized shape ?
05859   strncpy((char *)&iname, topvol, 4);
05860   ivo=0;
05861   for(i=1; i<=fGcnum->nvolum; i++) if(fZiq[fGclink->jvolum+i]==iname) {
05862     ivo=i;
05863     break;
05864   }
05865   jvo = fZlq[fGclink->jvolum-ivo];
05866   ish = Int_t (fZq[jvo+2]);
05867   if(ish > 12) {
05868     printf(" *** GWEUCL *** top volume : %s number : %3d can not be "
05869            "a valid root\n",topvol, numbr);
05870   }
05871   //
05872   level = 1;
05873   nvstak = 1;
05874   iws[nvstak]     = ivo;
05875   iws[iadvol+ivo] = level;
05876   ivstak = 0;
05877   //
05878   //*** flag all volumes and fill the stack
05879   //
05880  L10:
05881   //
05882   //    pick the next volume in stack
05883   ivstak += 1;
05884   ivo   = TMath::Abs(iws[ivstak]);
05885   jvo   = fZlq[fGclink->jvolum - ivo];
05886   //
05887   //     flag the tracking medium
05888   numed =  Int_t (fZq[jvo + 4]);
05889   iws[iadtmd + numed] = 1;
05890   //
05891   //    get the daughters ...
05892   level = iws[iadvol+ivo];
05893   if (level < mlevel) {
05894     level +=  1;
05895     nin = Int_t (fZq[jvo + 3]);
05896     //
05897     //       from division ...
05898     if (nin < 0) {
05899       jdiv = fZlq[jvo  - 1];
05900       ivin =  Int_t (fZq[jdiv + 2]);
05901       nvstak += 1;
05902       iws[nvstak]      = -ivin;
05903       iws[iadvol+ivin] =  level;
05904       //
05905       //       from position ...
05906     } else if (nin > 0) {
05907       for(in=1; in<=nin; in++) {
05908         jin  = fZlq[jvo - in];
05909         ivin =  Int_t (fZq[jin + 2 ]);
05910         jvin = fZlq[fGclink->jvolum - ivin];
05911         ish  =  Int_t (fZq[jvin + 2]);
05912         //              authorized shape ?
05913         if (ish <= 12) {
05914           //                 not yet flagged ?
05915           if (iws[iadvol+ivin]==0) {
05916             nvstak += 1;
05917             iws[nvstak]      = ivin;
05918             iws[iadvol+ivin] = level;
05919           }
05920           //                 flag the rotation matrix
05921           irot = Int_t ( fZq[jin + 4 ]);
05922           if (irot > 0) iws[iadrot+irot] = 1;
05923         }
05924       }
05925     }
05926   }
05927   //
05928   //     next volume in stack ?
05929   if (ivstak < nvstak) goto L10;
05930   //
05931   // *** restore original material and media numbers
05932   // file euc_medi.dat is needed to compare materials and medias
05933   //
05934   FILE* luncor=fopen("euc_medi.dat","r");
05935   //
05936   if(luncor) {
05937     for(itm=1; itm<=fGcnum->ntmed; itm++) {
05938       if (iws[iadtmd+itm] > 0) {
05939         jtm = fZlq[fGclink->jtmed-itm];
05940         strncpy(natmed,(char *)&fZiq[jtm+1],20);
05941         imat =  Int_t (fZq[jtm+6]);
05942         jma  = fZlq[fGclink->jmate-imat];
05943         if (jma <= 0) {
05944           printf(" *** GWEUCL *** material not defined for tracking medium "
05945               "%5i %s\n",itm,natmed);
05946           flag=1;
05947         } else {
05948           strncpy(namate,(char *)&fZiq[jma+1],20);
05949         }
05950         //*
05951         //** find the material original number
05952         rewind(luncor);
05953       L23:
05954         iret=fscanf(luncor,"%4s,%130s",key,card);
05955         if(iret<=0) goto L26;
05956         flag=0;
05957         if(!strcmp(key,"MATE")) {
05958           sscanf(card,"%d %s %f %f %f %f %f %d",&imatc,namatec,&az,&zc,
05959               &densc,&radlc,&abslc,&nparc);
05960           Gfmate(imat,namate,a,z,dens,radl,absl,par,npar);
05961           if(!strcmp(namatec,namate)) {
05962             if(az==a && zc==z && densc==dens && radlc==radl
05963                && abslc==absl && nparc==nparc) {
05964               iomate[imat]=imatc;
05965               flag=1;
05966               printf("*** GWEUCL *** material : %3d '%s' restored as %3d\n",
05967                   imat,namate,imatc);
05968             } else {
05969               printf("*** GWEUCL *** different definitions for material: %s\n",
05970                   namate);
05971             }
05972           }
05973         }
05974         if(strcmp(key,"END") && !flag) goto L23;
05975         if (!flag) {
05976           printf("*** GWEUCL *** cannot restore original number for "
05977               "material: %s\n",namate);
05978         }
05979         //*
05980         //*
05981         //***  restore original tracking medium number
05982         rewind(luncor);
05983       L24:
05984         iret=fscanf(luncor,"%4s,%130s",key,card);
05985         if(iret<=0) goto L26;
05986         flag=0;
05987         if (!strcmp(key,"TMED")) {
05988           sscanf(card,"%d %s %d %d %d %f %f %f %f %f %f %d\n",
05989                  &itmedc,natmedc,&nmatc,&isvolc,&ifieldc,&fieldmc,
05990                  &tmaxfdc,&stemaxc,&deemaxc,&epsilc,&stminc,&nwbufc);
05991           Gftmed(itm,natmed,nmat,isvol,ifield,fieldm,tmaxf,stemax,deemax,
05992                         epsil,stmin,ubuf,&nwbuf);
05993           if(!strcmp(natmedc,natmed)) {
05994             if (iomate[nmat]==nmatc && nwbuf==nwbufc) {
05995               iotmed[itm]=itmedc;
05996               flag=1;
05997               printf("*** GWEUCL *** medium   : %3d '%20s' restored as %3d\n",
05998                      itm,natmed,itmedc);
05999             } else {
06000               printf("*** GWEUCL *** different definitions for tracking "
06001                   "medium: %s\n",natmed);
06002             }
06003           }
06004         }
06005         if(strcmp(key,"END") && !flag) goto L24;
06006         if(!flag) {
06007           printf("cannot restore original number for medium : %s\n",natmed);
06008           goto L27;
06009         }
06010       }
06011     }
06012     goto L29;
06013     //*
06014   }
06015  L26:   printf("*** GWEUCL *** cannot read the data file\n");
06016  L27:   flag=2;
06017  L29:   if(luncor) fclose (luncor);
06018   //
06019   //
06020   // *** write down the tracking medium definition
06021   //
06022   strcpy(card,"!       Tracking medium");
06023   fprintf(lun,k10000,card);
06024   //
06025   for(itm=1;itm<=fGcnum->ntmed;itm++) {
06026     if (iws[iadtmd+itm]>0) {
06027       jtm  = fZlq[fGclink->jtmed-itm];
06028       strncpy(natmed,(char *)&fZiq[jtm+1],20);
06029       natmed[20]='\0';
06030       imat =  Int_t (fZq[jtm+6]);
06031       jma  = fZlq[fGclink->jmate-imat];
06032       //*  order media from one, if comparing with database failed
06033       if (flag==2) {
06034         iotmed[itm]=++imxtmed;
06035         iomate[imat]=++imxmate;
06036       }
06037       //*
06038       if(jma<=0) {
06039         strcpy(namate,"                  ");
06040         printf(" *** GWEUCL *** material not defined for tracking "
06041             "medium %5d %s\n", itm,natmed);
06042       } else {
06043         strncpy(namate,(char *)&fZiq[jma+1],20);
06044         namate[20]='\0';
06045       }
06046       fprintf(lun,"TMED %3d '%20s' %3d '%20s'\n",iotmed[itm],natmed,
06047               iomate[imat],namate);
06048     }
06049   }
06050   //*
06051       //* *** write down the rotation matrix
06052   //*
06053   strcpy(card,"!       Reperes");
06054   fprintf(lun,k10000,card);
06055   //
06056   for(irm=1;irm<=fGcnum->nrotm;irm++) {
06057     if (iws[iadrot+irm]>0) {
06058       jrm  = fZlq[fGclink->jrotm-irm];
06059       fprintf(lun,"ROTM %3d",irm);
06060       for(k=11;k<=16;k++) fprintf(lun," %8.3f",fZq[jrm+k]);
06061       fprintf(lun,"\n");
06062     }
06063   }
06064   //*
06065   //* *** write down the volume definition
06066   //*
06067   strcpy(card,"!       Volumes");
06068   fprintf(lun,k10000,card);
06069   //*
06070   for(ivstak=1;ivstak<=nvstak;ivstak++) {
06071     ivo = iws[ivstak];
06072     if (ivo>0) {
06073       strncpy(name,(char *)&fZiq[fGclink->jvolum+ivo],4);
06074       name[4]='\0';
06075       jvo  = fZlq[fGclink->jvolum-ivo];
06076       ish   = Int_t (fZq[jvo+2]);
06077       nmed  = Int_t (fZq[jvo+4]);
06078       npar  = Int_t (fZq[jvo+5]);
06079       if (npar>0) {
06080         if (ivstak>1) for(i=0;i<npar;i++) par[i]=fZq[jvo+7+i];
06081         Gckpar (ish,npar,par);
06082         fprintf(lun,"VOLU '%4s' '%4s' %3d %3d\n",name,kShape[ish-1],
06083              iotmed[nmed],npar);
06084         for(i=0;i<(npar-1)/6+1;i++) {
06085           fprintf(lun,"     ");
06086           left=npar-i*6;
06087           for(k=0;k<(left<6?left:6);k++) fprintf(lun," %11.5f",par[i*6+k]);
06088           fprintf(lun,"\n");
06089         }
06090       } else {
06091         fprintf(lun,"VOLU '%4s' '%4s' %3d %3d\n",name,kShape[ish-1],
06092              iotmed[nmed],npar);
06093       }
06094     }
06095   }
06096   //*
06097   //* *** write down the division of volumes
06098   //*
06099   fprintf(lun,k10000,"!       Divisions");
06100   for(ivstak=1;ivstak<=nvstak;ivstak++) {
06101     ivo = TMath::Abs(iws[ivstak]);
06102     jvo  = fZlq[fGclink->jvolum-ivo];
06103     ish  = Int_t (fZq[jvo+2]);
06104     nin  = Int_t (fZq[jvo+3]);
06105     //*        this volume is divided ...
06106     if (nin<0) {
06107       jdiv = fZlq[jvo-1];
06108       iaxe = Int_t ( fZq[jdiv+1]);
06109       ivin = Int_t ( fZq[jdiv+2]);
06110       ndiv = Int_t ( fZq[jdiv+3]);
06111       c0   =  fZq[jdiv+4];
06112       step =  fZq[jdiv+5];
06113       jvin = fZlq[fGclink->jvolum-ivin];
06114       nmed = Int_t ( fZq[jvin+4]);
06115       strncpy(mother,(char *)&fZiq[fGclink->jvolum+ivo ],4);
06116       mother[4]='\0';
06117       strncpy(name,(char *)&fZiq[fGclink->jvolum+ivin],4);
06118       name[4]='\0';
06119       if ((step<=0.)||(ish>=11)) {
06120         //*              volume with negative parameter or gsposp or pgon ...
06121         fprintf(lun,"DIVN '%4s' '%4s' %3d %3d\n",name,mother,ndiv,iaxe);
06122       } else if ((ndiv<=0)||(ish==10)) {
06123         //*              volume with negative parameter or gsposp or para ...
06124         ndvmx = TMath::Abs(ndiv);
06125         fprintf(lun,"DIVT '%4s' '%4s' %11.5f %3d %3d %3d\n",
06126                 name,mother,step,iaxe,iotmed[nmed],ndvmx);
06127       } else {
06128         //*              normal volume : all kind of division are equivalent
06129         fprintf(lun,"DVT2 '%4s' '%4s' %11.5f %3d %11.5f %3d %3d\n",
06130                 name,mother,step,iaxe,c0,iotmed[nmed],ndiv);
06131       }
06132     }
06133   }
06134   //*
06135   //* *** write down the the positionnement of volumes
06136   //*
06137   fprintf(lun,k10000,"!       Positionnements\n");
06138   //
06139   for(ivstak = 1;ivstak<=nvstak;ivstak++) {
06140     ivo = TMath::Abs(iws[ivstak]);
06141     strncpy(mother,(char*)&fZiq[fGclink->jvolum+ivo ],4);
06142     mother[4]='\0';
06143     jvo  = fZlq[fGclink->jvolum-ivo];
06144     nin  = Int_t( fZq[jvo+3]);
06145     //*        this volume has daughters ...
06146     if (nin>0) {
06147       for (in=1;in<=nin;in++) {
06148         jin  = fZlq[jvo-in];
06149         ivin =  Int_t (fZq[jin +2]);
06150         numb =  Int_t (fZq[jin +3]);
06151         irot =  Int_t (fZq[jin +4]);
06152         x    =  fZq[jin +5];
06153         y    =  fZq[jin +6];
06154         z    =  fZq[jin +7];
06155         strcpy(konly,"ONLY");
06156         if (fZq[jin+8]!=1.) strcpy(konly,"MANY");
06157         strncpy(name,(char*)&fZiq[fGclink->jvolum+ivin],4);
06158         name[4]='\0';
06159         jvin = fZlq[fGclink->jvolum-ivin];
06160         ish  = Int_t (fZq[jvin+2]);
06161         //*              gspos or gsposp ?
06162         ndata = fZiq[jin-1];
06163         if (ndata==8) {
06164           fprintf(lun,"POSI '%4s' %4d '%4s' %11.5f %11.5f %11.5f %3d '%4s'\n",
06165                   name,numb,mother,x,y,z,irot,konly);
06166         } else {
06167           npar =  Int_t (fZq[jin+9]);
06168           for(i=0;i<npar;i++) par[i]=fZq[jin+10+i];
06169           Gckpar (ish,npar,par);
06170           fprintf(lun,"POSP '%4s' %4d '%4s' %11.5f %11.5f %11.5f %3d '%4s' %3d\n",
06171                   name,numb,mother,x,y,z,irot,konly,npar);
06172           fprintf(lun,"     ");
06173           for(i=0;i<npar;i++) fprintf(lun," %11.5f",par[i]);
06174           fprintf(lun,"\n");
06175         }
06176       }
06177     }
06178   }
06179   //*
06180   fprintf(lun,"END\n");
06181   fclose(lun);
06182   //*
06183   //****** write down the materials and medias *****
06184   //*
06185   lun=fopen(filetme,"w");
06186   //*
06187   for(itm=1;itm<=fGcnum->ntmed;itm++) {
06188     if (iws[iadtmd+itm]>0) {
06189       jtm  = fZlq[fGclink->jtmed-itm];
06190       strncpy(natmed,(char*)&fZiq[jtm+1],4);
06191       imat =  Int_t (fZq[jtm+6]);
06192       jma  =  Int_t (fZlq[fGclink->jmate-imat]);
06193       //*  material
06194       Gfmate (imat,namate,a,z,dens,radl,absl,par,npar);
06195       fprintf(lun,"MATE %4d '%20s'%11.5E %11.5E %11.5E %11.5E %11.5E %3d\n",
06196              iomate[imat],namate,a,z,dens,radl,absl,npar);
06197       //*
06198       if (npar>0) {
06199           fprintf(lun,"     ");
06200           for(i=0;i<npar;i++) fprintf(lun," %11.5f",par[i]);
06201           fprintf(lun,"\n");
06202       }
06203       //*  medium
06204       Gftmed(itm,natmed,nmat,isvol,ifield,fieldm,tmaxfd,stemax,deemax,
06205              epsil,stmin,par,&npar);
06206       fprintf(lun,"TMED %4d '%20s' %3d %1d %3d %11.5f %11.5f %11.5f "
06207               "%11.5f %11.5f %11.5f %3d\n",
06208               iotmed[itm],natmed,iomate[nmat],isvol,ifield,
06209               fieldm,tmaxfd,stemax,deemax,epsil,stmin,npar);
06210       //*
06211       if (npar>0) {
06212           fprintf(lun,"     ");
06213           for(i=0;i<npar;i++) fprintf(lun," %11.5f",par[i]);
06214           fprintf(lun,"\n");
06215       }
06216 
06217     }
06218   }
06219   fprintf(lun,"END\n");
06220   fclose(lun);
06221   printf(" *** GWEUCL *** file: %s is now written out\n",filext);
06222   printf(" *** GWEUCL *** file: %s is now written out\n",filetme);
06223   // Clean up
06224   delete [] filext;
06225   delete [] filetme;
06226   delete [] qws;
06227   iws=0;
06228   return;
06229 }
06230 
06231 //______________________________________________________________________
06232 Int_t  TGeant3::TransportMethod(TMCParticleType particleType) const
06233 {
06234 //
06235 // Returns G3 transport method code for the specified MCParticleType
06236 // ---
06237 
06238   switch (particleType) {
06239     case kPTGamma:    return 1;
06240     case kPTElectron: return 2;
06241     case kPTNeutron:  return 3;
06242     case kPTHadron:   return 4;
06243     case kPTMuon:     return 5;
06244     case kPTGeantino: return 6;
06245     case kPTOpticalPhoton: return 7;
06246     case kPTIon:      return 8;
06247     default:          return -1;
06248   }
06249 }
06250 
06251 //______________________________________________________________________
06252 TMCParticleType  TGeant3::ParticleType(Int_t itrtyp) const
06253 {
06254 //
06255 // Returns MCParticleType for the specified G3 transport method code
06256 // ---
06257 
06258   switch (itrtyp) {
06259     case 1:  return  kPTGamma;
06260     case 2:  return  kPTElectron;
06261     case 3:  return  kPTNeutron;
06262     case 4:  return  kPTHadron;
06263     case 5:  return  kPTMuon;
06264     case 6:  return  kPTGeantino;
06265     case 7:  return  kPTOpticalPhoton;
06266     case 8:  return  kPTIon;
06267     default: return  kPTUndefined;
06268   }
06269 }
06270 
06271 //______________________________________________________________________
06272 TString  TGeant3::ParticleClass(TMCParticleType particleType) const
06273 {
06274 //
06275 // Returns particle class name (used in TDatabasePDG) for
06276 // the specified MCParticleType
06277 // ---
06278 
06279   // CHECK
06280   switch (particleType) {
06281     case kPTGamma:    return TString("Photon");
06282     case kPTElectron: return TString("Lepton");
06283     case kPTNeutron:  return TString("Hadron");
06284     case kPTHadron:   return TString("Hadron");
06285     case kPTMuon:     return TString("Lepton");
06286     case kPTGeantino: return TString("Special");
06287     case kPTIon:      return TString("Ion");
06288     case kPTOpticalPhoton: return TString("Photon");
06289     default:          return TString("Unknown");
06290   }
06291 }
06292 
06293 //______________________________________________________________________
06294 void TGeant3::FinishGeometry()
06295 {
06296   //
06297   // Finalize geometry construction
06298   //
06299 
06300   //Close the geometry structure
06301   if (gDebug > 0) printf("FinishGeometry, calling ggclos\n");
06302   Ggclos();
06303 
06304 
06305   //  gROOT->GetListOfBrowsables()->Add(gGeoManager);
06306   if (gDebug > 0) printf("FinishGeometry, calling SetColors\n");
06307 
06308   //Create the color table
06309   SetColors();
06310   if (gDebug > 0) printf("FinishGeometry, returning\n");
06311 }
06312 
06313 //______________________________________________________________________
06314 void TGeant3::Init()
06315 {
06316     //
06317     //=================Create Materials and geometry
06318     //
06319 
06320     //  Some default settings, if not changed by user
06321     if (!TestBit(kTRIG)) SetTRIG(1);       // Number of events to be processed
06322     if (!TestBit(kSWIT)) SetSWIT(4, 10);   //
06323     if (!TestBit(kDEBU)) SetDEBU(0, 0, 1); //
06324     if (!TestBit(kAUTO)) SetAUTO(1);       // Select automatic STMIN etc... 
06325                                            // calc. (AUTO 1) or manual (AUTO 0)
06326     if (!TestBit(kABAN)) SetABAN(0);       // Restore 3.16 behaviour for 
06327                                            // abandoned tracks
06328     if (!TestBit(kOPTI)) SetOPTI(2);       // Select optimisation level for 
06329                                            // GEANT geometry searches (0,1,2)
06330     if (!TestBit(kERAN)) SetERAN(5.e-7);   //
06331 
06332     DefineParticles();
06333     fApplication->AddParticles();
06334     fApplication->AddIons();
06335     fApplication->ConstructGeometry();
06336     FinishGeometry();
06337 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,01,1)
06338     fApplication->ConstructOpGeometry();
06339 #endif
06340     fApplication->InitGeometry();
06341 }
06342 
06343 //____________________________________________________________________________
06344 Bool_t TGeant3::ProcessRun(Int_t nevent)
06345 {
06346   //
06347   // Process the run and return true if run has finished successfully,
06348   // return false in other cases (run aborted by user)
06349 
06350   Int_t todo = TMath::Abs(nevent);
06351   for (Int_t i=0; i<todo; i++) {
06352      // Process one run (one run = one event)
06353      fGcflag->idevt  = i;
06354      fGcflag->ievent = i+1;
06355      if (fStopRun) break;
06356      fApplication->BeginEvent();
06357      if (fStopRun) break;
06358      ProcessEvent();
06359      if (fStopRun) break;
06360      fApplication->FinishEvent();
06361      if (fStopRun) break;
06362   }
06363 
06364   if (fStopRun) printf(" **** Run stopped ***\n");
06365 
06366   Bool_t returnValue = !fStopRun;
06367   fStopRun = kFALSE;
06368 #ifdef STATISTICS
06369   printf("count_gmedia= %8d\n",count_gmedia);
06370   printf("count_gtmedi= %8d\n",count_gtmedi);
06371   printf("count_ginvol= %8d\n",count_ginvol);
06372   printf("count_gtnext= %8d\n",count_gtnext);
06373   stattree->AutoSave();
06374   statfile->Close();
06375   printf("Statistics tree saved.\n");
06376 #endif
06377   return returnValue;
06378 }
06379 
06380 //______________________________________________________________________
06381 void TGeant3::ProcessEvent()
06382 {
06383   //
06384   // Process one event
06385   //
06386   Gtrigi();
06387   Gtrigc();
06388   Gtrig();
06389 }
06390 
06391 //______________________________________________________________________
06392 void TGeant3::SetColors()
06393 {
06394   //
06395   // Set the colors for all the volumes
06396   // this is done sequentially for all volumes
06397   // based on the number of their medium
06398   //
06399 
06400   Int_t kv, icol;
06401   Int_t jvolum=fGclink->jvolum;
06402   //Int_t jtmed=fGclink->jtmed;
06403   //Int_t jmate=fGclink->jmate;
06404   Int_t nvolum=fGcnum->nvolum;
06405   char name[5];
06406   //
06407   //    Now for all the volumes
06408   for(kv=1;kv<=nvolum;kv++) {
06409     //     Get the tracking medium
06410     Int_t itm=Int_t (fZq[fZlq[jvolum-kv]+4]);
06411     //     Get the material
06412     //Int_t ima=Int_t (fZq[fZlq[jtmed-itm]+6]);
06413     //     Get z
06414     //Float_t z=fZq[fZlq[jmate-ima]+7];
06415     //     Find color number
06416     //icol = Int_t(z)%6+2;
06417     //icol = 17+Int_t(z*150./92.);
06418     //icol = kv%6+2;
06419     icol = itm%6+2;
06420     strncpy(name,(char*)&fZiq[jvolum+kv],4);
06421     name[4]='\0';
06422     Gsatt(name,"COLO",icol);
06423   }
06424 }
06425 
06426 //______________________________________________________________________
06427 void TGeant3::SetTrack(Int_t done, Int_t parent, Int_t pdg, Float_t *pmom,
06428                         Float_t *vpos, Float_t *polar, Float_t tof,
06429                         TMCProcess mech, Int_t &ntr, Float_t weight, Int_t is)
06430 {
06431   //
06432   // Load a track on the stack
06433   //
06434   // done     0 if the track has to be transported
06435   //          1 if not
06436   // parent   identifier of the parent track. -1 for a primary
06437   // pdg    particle code
06438   // pmom     momentum GeV/c
06439   // vpos     position
06440   // polar    polarization
06441   // tof      time of flight in seconds
06442   // mecha    production mechanism
06443   // ntr      on output the number of the track stored
06444   //
06445 
06446   //  const Float_t tlife=0;
06447 
06448   //
06449   // Here we get the static mass
06450   // For MC is ok, but a more sophisticated method could be necessary
06451   // if the calculated mass is required
06452   // also, this method is potentially dangerous if the mass
06453   // used in the MC is not the same of the PDG database
06454   //
06455   Float_t mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
06456   Float_t e=TMath::Sqrt(mass*mass+pmom[0]*pmom[0]+
06457                         pmom[1]*pmom[1]+pmom[2]*pmom[2]);
06458 
06459 //    printf("Loading  mass %f ene %f No %d ip %d parent %d done %d "
06460 //           "pos %f %f %f mom %f %f %f kS %d m \n",
06461 //              mass,e,fNtrack,pdg,parent,done,vpos[0],vpos[1],vpos[2],
06462 //           pmom[0],pmom[1],pmom[2],kS);
06463 
06464 
06465   GetStack()->PushTrack(done, parent, pdg, pmom[0], pmom[1], pmom[2], e,
06466                        vpos[0],vpos[1],vpos[2],tof,polar[0],polar[1],polar[2],
06467                        mech, ntr, weight, is);
06468 }
06469 
06470 
06471 //______________________________________________________________________
06472 Float_t* TGeant3::CreateFloatArray(Float_t* array, Int_t size) const
06473 {
06474 // Converts Double_t* array to Float_t*,
06475 // !! The new array has to be deleted by user.
06476 // ---
06477 
06478   Float_t* floatArray;
06479   if (size>0) {
06480     floatArray = new Float_t[size];
06481     for (Int_t i=0; i<size; i++)
06482       if (array[i] >= FLT_MAX ) 
06483         floatArray[i] = FLT_MAX/100.;
06484       else      
06485         floatArray[i] = array[i];
06486   }
06487   else {
06488     //floatArray = 0;
06489     floatArray = new Float_t[1];
06490   }
06491   return floatArray;
06492 }
06493 
06494 
06495 //______________________________________________________________________
06496 Float_t* TGeant3::CreateFloatArray(Double_t* array, Int_t size) const
06497 {
06498 // Converts Double_t* array to Float_t*,
06499 // !! The new array has to be deleted by user.
06500 // ---
06501 
06502   Float_t* floatArray;
06503   if (size>0) {
06504     floatArray = new Float_t[size];
06505     for (Int_t i=0; i<size; i++)
06506       if (array[i] >= FLT_MAX ) 
06507         floatArray[i] = FLT_MAX/100.;
06508       else      
06509         floatArray[i] = array[i];
06510   }
06511   else {
06512     //floatArray = 0;
06513     floatArray = new Float_t[1];
06514   }
06515   return floatArray;
06516 }
06517 
06518 
06519 //______________________________________________________________________
06520 void TGeant3::Streamer(TBuffer &R__b)
06521 {
06522   //
06523   // Stream an object of class TGeant3.
06524   //
06525   if (R__b.IsReading()) {
06526     Version_t R__v = R__b.ReadVersion(); if (R__v) { }
06527     TVirtualMC::Streamer(R__b);
06528     R__b >> fNextVol;
06529     R__b >> fNPDGCodes;
06530     //R__b.ReadStaticArray(fPDGCode);
06531     fPDGCode.Streamer(R__b);
06532   } else {
06533     R__b.WriteVersion(TGeant3::IsA());
06534     TVirtualMC::Streamer(R__b);
06535     R__b << fNextVol;
06536     R__b << fNPDGCodes;
06537     //R__b.WriteArray(fPDGCode, fNPDGCodes);
06538     fPDGCode.Streamer(R__b);
06539   }
06540 }
06541 
06542 //______________________________________________________________________
06543 //
06544 //                 Interfaces to Fortran
06545 //
06546 //______________________________________________________________________
06547 
06548 
06549 //______________________________________________________________________
06550 extern "C" void type_of_call  rxgtrak(Int_t &mtrack,Int_t &ipart,Float_t *pmom,
06551                                       Float_t &e,Float_t *vpos,Float_t *polar,
06552                                       Float_t &tof)
06553 {
06554   //
06555   //     Fetches next track from the ROOT stack for transport. Called by the
06556   //     modified version of GTREVE.
06557   //
06558   //              Track number in the ROOT stack. If MTRACK=0 no
06559   //      mtrack  more tracks are left in the stack to be
06560   //              transported.
06561   //      ipart   Particle code in the GEANT conventions.
06562   //      pmom[3] Particle momentum in GeV/c
06563   //      e       Particle energy in GeV
06564   //      vpos[3] Particle position
06565   //      tof     Particle time of flight in seconds
06566   //
06567 
06568   TParticle* track = gMC->GetStack()->PopNextTrack(mtrack);
06569 
06570   if (track) {
06571     // fill G3 arrays
06572     pmom[0] = track->Px();
06573     pmom[1] = track->Py();
06574     pmom[2] = track->Pz();
06575     e = track->Energy();
06576     vpos[0] = track->Vx();;
06577     vpos[1] = track->Vy();
06578     vpos[2] = track->Vz();
06579     tof = track->T();
06580     TVector3 pol;
06581     track->GetPolarisation(pol);
06582     polar[0] = pol.X();
06583     polar[1] = pol.Y();
06584     polar[2] = pol.Z();
06585     ipart = gMC->IdFromPDG(track->GetPdgCode());
06586   }
06587 
06588   mtrack++;
06589 }
06590 
06591 
06592 //______________________________________________________________________
06593 extern "C" void type_of_call  rxouth ()
06594 {
06595   //
06596   // Called by Gtreve at the end of each primary track
06597   //
06598   TVirtualMCApplication::Instance()->FinishPrimary();
06599 }
06600 
06601 //______________________________________________________________________
06602 extern "C" void type_of_call  rxinh ()
06603 {
06604   //
06605   // Called by Gtreve at the beginning of each primary track
06606   //
06607   TVirtualMCApplication::Instance()->BeginPrimary();
06608 }
06609 
06610 //______________________________________________________________________
06611 void ginvol(Float_t *x, Int_t &isame)
06612 {
06613    fginvol(x,isame);
06614 }
06615 
06616 
06617 //______________________________________________________________________
06618 void gtmedi(Float_t *x, Int_t &numed)
06619 {
06620    fgtmedi(x,numed);
06621 #ifdef STATISTICS
06622    statcode = 2;
06623    statsame = gcchan->lsamvl;
06624    for (int j=0;j<6;j++) if (j <3) oldvect[j] = x[j]; else oldvect[j]=0;
06625    oldsafety = gctrak->safety;
06626    oldstep   = gctrak->step;
06627    sprintf(statpath,"%s",geant3->GetPath());
06628    statsnext=gctrak->snext;
06629    statsafety=gctrak->safety;
06630    stattree->Fill();
06631    count_gtmedi++;
06632 #endif
06633 }
06634 
06635 
06636 //______________________________________________________________________
06637 void gmedia(Float_t *x, Int_t &numed, Int_t &check)
06638 {
06639    fgmedia(x,numed,check);
06640 #ifdef STATISTICS
06641   statcode = 1;
06642   statsame = 0;
06643   for (int j=0;j<6;j++) if (j <3) oldvect[j] = x[j]; else oldvect[j]=0;
06644   oldsafety = gctrak->safety;
06645   oldstep   = gctrak->step;
06646   sprintf(statpath,"%s",geant3->GetPath());
06647   statsnext=gctrak->snext;
06648   statsafety=gctrak->safety;
06649   stattree->Fill();
06650   count_gmedia++;
06651 #endif
06652 }
06653 
06654 //______________________________________________________________________
06655 void gtmany(Int_t &level1)
06656 {
06657    fgtmany(level1);
06658 }
06659 
06660 //______________________________________________________________________
06661 void gtonlyg3(Int_t &isOnly)
06662 {
06663    //with Geant3, return gonly(nlevel);
06664    isOnly = (Int_t)gcvolu->gonly[gcvolu->nlevel-1];
06665 }
06666 
06667 //______________________________________________________________________
06668 void gtonly(Int_t &isOnly)
06669 {
06670    //with Geant3, return gonly(nlevel);
06671    fgtonly(isOnly);
06672 }
06673 
06674 //______________________________________________________________________
06675 void glvolu(Int_t &nlev, Int_t *lnam,Int_t *lnum, Int_t &ier)
06676 {
06677   //
06678   //  nlev   number of levels deep into the volume tree
06679   //         size of the arrays lnam and lnum
06680   //  lnam   an integer array who's 4 bytes contain the ASCII code for the
06681   //         volume names
06682   //  lnum   an integer array containing the copy numbers for that specific
06683   //         volume
06684   //
06685   //  This routine fills the volume parameters in common /gcvolu/ for a
06686   //  physical tree, specified by the list lnam and lnum of volume names
06687   //  and numbers, and for all its ascendants up to level 1. This routine
06688   //  is optimized and does not re-compute the part of the history already
06689   //  available in GCVOLU. This means that if it is used in user programs
06690   //  outside the usual framework of the tracking, the user has to initialize
06691   //  to zero NLEVEL in the common GCVOLU. It return 0 if there were no
06692   //  problems in make the call.
06693   //
06694 // printf("glvolu called\n");
06695 
06696   fglvolu(nlev, lnam, lnum, ier);
06697 }
06698 
06699 
06700 //______________________________________________________________________
06701 void gtnext()
06702 {
06703 #ifdef STATISTICS
06704    count_gtnext++;
06705    statcode = 3;
06706    statsame = 1;
06707    for (int j=0;j<6;j++) oldvect[j] = gctrak->vect[j];
06708    oldsafety = gctrak->safety;
06709    oldstep   = gctrak->step;
06710    sprintf(statpath,"%s",geant3->GetPath());
06711 #endif
06712 
06713    fgtnext();
06714 
06715 #ifdef STATISTICS
06716   statsnext=gctrak->snext;
06717   statsafety=gctrak->safety;
06718   stattree->Fill();
06719 #endif
06720 }
06721 //______________________________________________________________________
06722 void ggperp(Float_t *x, Float_t *norm, Int_t &ierr){
06723 // Computes the normal to the next crossed surface, assuming that
06724 // FindNextBoundary() was already called.
06725 
06726     fggperp(x,norm,ierr);
06727 }
06728 //______________________________________________________________________
06729 Bool_t TGeant3::GetTransformation(const TString &volumePath,TGeoHMatrix &mat){
06730     // Returns the Transformation matrix between the volume specified
06731     // by the path volumePath and the Top or mater volume. The format
06732     // of the path volumePath is as follows (assuming ALIC is the Top volume)
06733     // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
06734     // or master volume which has only 1 instance of. Of all of the daughter
06735     // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
06736     // the daughter volume of DDIP is S05I copy #2 and so on.
06737     // Inputs:
06738     //   TString& volumePath  The volume path to the specific volume
06739     //                        for which you want the matrix. Volume name
06740     //                        hierarchy is separated by "/" while the
06741     //                        copy number is appended using a "_".
06742     // Outputs:
06743     //  TGeoHMatrix &mat      A matrix with its values set to those
06744     //                        appropriate to the Local to Master transformation
06745     // Return:
06746     //   A logical value if kFALSE then an error occurred and no change to
06747     //   mat was made.
06748     Int_t i,n,k,*lnam=0,*lnum=0;
06749     // Default rotation matrix, Unit
06750     Double_t m[9] = {1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0};
06751     Double_t s[3] = {1.0,1.0,1.0}; // Default scale, Unit
06752     Double_t t[3] = {0.0,0.0,0.0}; // Default translation, none.
06753 
06754     k =ConvertVolumePathString(volumePath,&lnam,&lnum);//Creates lnam, and lnum
06755     if(k<=0) { // Error from Convert volumePathString.
06756         delete[] lnam;
06757         delete[] lnum;
06758         return kFALSE;
06759     } // end if k<=0
06760     if(k==1){// only one volume listed, must be top most, return unit..
06761         delete[] lnam;
06762         delete[] lnum;
06763         mat.SetRotation(m);
06764         mat.SetTranslation(t);
06765         mat.SetScale(s);
06766         return kTRUE;
06767     } // end if k==1
06768     this->Gcvolu()->nlevel = 0;
06769     i = this->Glvolu(k,lnam,lnum);
06770     n = this->Gcvolu()->nlevel -1;
06771     delete[] lnam; // created in ConvertVolumePathString.
06772     delete[] lnum; // created in ConvertVolumePathString.
06773     if(i!=0) return kFALSE; // Error
06774     mat.SetScale(s); // Geant scale always 1.
06775     if(!((this->Gcvolu()->grmat[n][9])==0.0)) { // not Unit matrix
06776         for(i=0;i<9;i++) m[i] = (Double_t) this->Gcvolu()->grmat[n][i];
06777     } // end if
06778     mat.SetRotation(m);
06779     for(i=0;i<3;i++) t[i] = (Double_t) (this->Gcvolu()->gtran[n][i]);
06780     mat.SetTranslation(t);
06781     return kTRUE;
06782 }/*
06783 //______________________________________________________________________
06784 Bool_t TGeant3::GetShape(const TString &volumeName,TString &shapeType,
06785                          TArrayD &par){
06786     // Returns the shape and its parameters for the volume specified
06787     // by volumeName.
06788     // Inputs:
06789     //   TString& volumeName  The volume name
06790     // Outputs:
06791     //   TString &shapeType   Shape type
06792     //   TArrayD &par         A TArrayD of parameters with all of the
06793     //                        parameters of the specified shape.
06794     // Return:
06795     //   A logical indicating whether there was an error in getting this
06796     //   information
06797     const Int_t nshapes = 16;
06798     const Char_t *vname[nshapes] = {"BOX","TRD1","TRD2","TRAP","TUBE","TUBS",
06799                                    "CONE","CONS","SPHE","PARA","PGON","PCON",
06800                                    "ELTU","HYPE","GTRA","CTUB"};
06801     Int_t volid,i,jv0,ishape,npar;
06802     Float_t *qpar;
06803 
06804     volid = VolId(volumeName.Data());
06805     if(volid==0) return kFALSE; // Error.
06806     jv0 = this->Lq()[this->Gclink()->jvolum-volid];
06807     ishape = (Int_t)(this->Q()[jv0+2]);
06808     if(ishape<1||ishape>nshapes) return kFALSE; // error unknown shape
06809     npar   = (Int_t)(this->Q()[jv0+5]);
06810     qpar   = (this->Q())+jv0+7;
06811     par.Set(npar); // Resize TArrayD
06812     for(i=0;i<npar;i++) par.AddAt(((Double_t)qpar[i]),i);
06813     shapeType = vname[ishape-1];
06814     return kTRUE;
06815 }*/
06816 
06817 //______________________________________________________________________
06818 Bool_t TGeant3::GetShape(const TString &volumePath,TString &shapeType,
06819                          TArrayD &par){
06820     // Returns the shape and its parameters for the volume specified
06821     // by the path volumePath. The format of the path volumePath is as 
06822     // follows (assuming ALIC is the Top volume)
06823     // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
06824     // or master volume which has only 1 instance of. Of all of the daughter
06825     // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
06826     // the daughter volume of DDIP is S05I copy #2 and so on.
06827     // Inputs:
06828     //   TString& volumePath  The volume path to the specific volume
06829     //                        for which you want the matrix. Volume name
06830     //                        hierarchy is separated by "/" while the
06831     //                        copy number is appended using a "_".
06832     // Outputs:
06833     //   TString &shapeType   Shape type
06834     //   TArrayD &par         A TArrayD of parameters with all of the
06835     //                        parameters of the specified shape.
06836     // Return:
06837     //   A logical indicating whether there was an error in getting this
06838     //   information
06839     const Int_t nshapes = 16;
06840     const Char_t *vname[nshapes] = {"BOX","TRD1","TRD2","TRAP","TUBE","TUBS",
06841                                    "CONE","CONS","SPHE","PARA","PGON","PCON",
06842                                    "ELTU","HYPE","GTRA","CTUB"};
06843     Int_t volid,i,k,jv0,ishape,npar,*lnam=0,*lnum=0;
06844     Float_t *qpar;
06845 
06846     k=ConvertVolumePathString(volumePath,&lnam,&lnum);//Creates lnam, and lnum
06847     if(k<=0) { // Error from Convert volumePathString.
06848         delete[] lnam;
06849         delete[] lnum;
06850         return kFALSE;
06851     } // end if k<=0
06852     this->Gcvolu()->nlevel = 0;
06853     i = this->Glvolu(k,lnam,lnum);
06854     delete[] lnam;
06855     delete[] lnum;
06856     if(i!=0) {// error
06857         par.Set(0);
06858         return kFALSE;
06859     } // end if i!=1
06860     volid = this->Gcvolu()->lvolum[this->Gcvolu()->nlevel-1];
06861     jv0 = this->Lq()[this->Gclink()->jvolum-volid];
06862     ishape = (Int_t)(this->Q()[jv0+2]);
06863     if(ishape<1||ishape>nshapes) return kFALSE; // error unknown shape
06864     npar   = (Int_t)(this->Q()[jv0+5]);
06865     qpar   = (this->Q())+jv0+7;
06866     par.Set(npar); // Resize TArrayD
06867     for(i=0;i<npar;i++) par.AddAt((Double_t)qpar[i],i);
06868     shapeType = vname[ishape-1];
06869     shapeType = shapeType.Strip();
06870     return kTRUE;
06871 }
06872 //______________________________________________________________________
06873 Bool_t TGeant3::GetMaterial(const TString &volumeName,
06874                             TString &name,Int_t &imat,
06875                             Double_t &a,Double_t &z,Double_t &dens,
06876                             Double_t &radl,Double_t &inter,TArrayD &par){
06877     // Returns the Material and its parameters for the volume specified
06878     // by volumeName.
06879     // Note, Geant3 stores and uses mixtures as an element with an effective
06880     // Z and A. Consequently, if the parameter Z is not integer, then
06881     // this material represents some sort of mixture.
06882     // Inputs:
06883     //   TString& volumeName  The volume name
06884     // Outputs:
06885     //   TSrting   &name       Material name
06886     //   Int_t     &imat       Material index number
06887     //   Double_t  &a          Average Atomic mass of material
06888     //   Double_t  &z          Average Atomic number of material
06889     //   Double_t  &dens       Density of material [g/cm^3]
06890     //   Double_t  &radl       Average radiation length of material [cm]
06891     //   Double_t  &inter      Average interaction length of material [cm]
06892     //   TArrayD   &par        A TArrayD of user defined parameters.
06893     // Return:
06894     //   kTRUE if no errors
06895     Int_t i,volid,jma,nbuf;
06896     Float_t af,zf,densf,radlf,interf;
06897     Float_t *ubuf;
06898     Char_t *ch,namec[20] = {20*'\0'};
06899 
06900     volid = VolId(volumeName.Data());
06901     if(volid==0) return kFALSE; // Error
06902     if(volid>0){ // Get Material number, imat.
06903         Int_t imed = (Int_t) (this->Q()[this->Lq()[
06904                                             this->Gclink()->jvolum-volid]+4]);
06905         Int_t jtm  = this->Lq()[this->Gclink()->jtmed-imed];
06906         imat = (Int_t)(this->Q()[jtm+6]);
06907     } else {
06908         i = this->Gclink()->jvolum + volid;
06909         Int_t jdiv  = this->Lq()[i];
06910         Int_t ivin  = (Int_t) (this->Q()[jdiv+2]);
06911         i = this->Gclink()->jvolum - ivin;
06912         Int_t jvin  = this->Lq()[i];
06913         Int_t idmed = (Int_t)(this->Q()[jvin+4]);
06914         i = this->Gclink()->jtmed-idmed;
06915         Int_t jtm   = this->Lq()[i];
06916         imat = (Int_t)(this->Q()[jtm+6]);
06917     } // end if-else
06918     nbuf = jma = this->Lq()[this->Gclink()->jmate-imat];
06919     ubuf = new Float_t[nbuf];
06920     Gfmate(imat,namec,af,zf,densf,radlf,interf,ubuf,nbuf);
06921     // Problem with getting namec back from Gfmate, get it from 
06922     // the Zebra bank directly.
06923     ch = (char *)(this->Iq()+jma+1);
06924     for(i=0;i<20;i++) if(ch[i]!=' ') namec[i] = ch[i];
06925     name = namec;
06926     name = name.Strip();
06927     //
06928     par.Set(nbuf);
06929     for(i=0;i<nbuf;i++) par.AddAt(((Double_t)ubuf[i]),i);
06930     delete[] ubuf;
06931     a      = (Double_t) af;
06932     z      = (Double_t) zf;
06933     dens   = (Double_t) densf;
06934     radl   = (Double_t) radlf;
06935     inter  = (Double_t) interf;
06936     return kTRUE;
06937 }
06938 //______________________________________________________________________
06939 Bool_t TGeant3::GetMedium(const TString &volumeName,TString &name,
06940                           Int_t &imed,Int_t &nmat,Int_t &isvol,Int_t &ifield,
06941                           Double_t &fieldm,Double_t &tmaxfd,Double_t &stemax,
06942                           Double_t &deemax,Double_t &epsil, Double_t &stmin,
06943                           TArrayD &par){
06944     // Returns the Medium and its parameters for the volume specified
06945     // by volumeName.
06946     // Inputs:
06947     //   TString& volumeName  The volume name.
06948     // Outputs:
06949     //   TString  &name       Medium name
06950     //   Int_t    &nmat       Material number defined for this medium
06951     //   Int_t    &imed       The medium index number
06952     //   Int_t    &isvol      volume number defined for this medium
06953     //   Int_t    &iflield    Magnetic field flag
06954     //   Double_t &fieldm     Magnetic field strength
06955     //   Double_t &tmaxfd     Maximum angle of deflection per step
06956     //   Double_t &stemax     Maximum step size
06957     //   Double_t &deemax     Maximum fraction of energy allowed to be lost
06958     //                        to continuous process.
06959     //   Double_t &epsil      Boundary crossing precision
06960     //   Double_t &stmin      Minimum step size allowed
06961     //   TArrayD  &par        A TArrayD of user parameters with all of the
06962     //                        parameters of the specified medium.
06963     // Return:
06964     //   kTRUE if there where no errors
06965     Int_t i,volid,nbuf;
06966     Float_t fieldmf,tmaxfdf,stemaxf,deemaxf,epsilf,stminf;
06967     Float_t *buf;
06968     Char_t namec[25] = {25*'\0'};
06969 
06970     volid = VolId(volumeName.Data());
06971     if(volid==0) return kFALSE; // Error
06972     if(volid>0){ // Get Material number, imat.
06973         imed = (Int_t)(this->Q()[this->Lq()[this->Gclink()->jvolum-volid]+4]);
06974     } else {
06975         Int_t jdiv  = this->Lq()[this->Gclink()->jvolum + volid];
06976         Int_t ivin  = (Int_t) (this->Q()[jdiv+2]);
06977         Int_t jvin  = this->Lq()[this->Gclink()->jvolum - ivin];
06978         imed = (Int_t)(this->Q()[jvin+4]);
06979     } // end if-else
06980     nbuf = this->Lq()[this->Gclink()->jtmed-imed];
06981     buf  = new Float_t[nbuf];
06982     Gftmed(imed,namec,nmat,isvol,ifield,fieldmf,tmaxfdf,stemaxf,deemaxf,
06983            epsilf,stminf,buf,&nbuf);
06984     name = namec;
06985     name = name.Strip();
06986     par.Set(nbuf);
06987     for(i=0;i<nbuf;i++) par.AddAt(((Double_t)buf[i]),i);
06988     delete[] buf;
06989     fieldm = (Double_t) fieldmf;
06990     tmaxfd = (Double_t) tmaxfdf;
06991     stemax = (Double_t) stemaxf;
06992     deemax = (Double_t) deemaxf;
06993     epsil  = (Double_t) epsilf;
06994     stmin  = (Double_t) stminf;
06995     return kTRUE;
06996 }
06997 //____________________________private method____________________________
06998 Int_t TGeant3::ConvertVolumePathString(const TString &volumePath,
06999                                        Int_t **lnam,Int_t **lnum){
07000     // Parses the TString volumePath into an array of volume names 
07001     // (4 character long limit) and copy numbers in a form used
07002     // by Geant3.
07003     // Inputs:
07004     //   TString& volumePath  The volume path to the specific volume
07005     //                        for which you want the matrix. Volume name
07006     //                        hierarchy is separated by "/" while the
07007     //                        copy number is appended using a "_".
07008     // Outputs:
07009     //   Int_t lnam           An integer array, created by this routine,
07010     //                        containing the 4 character long volume names.
07011     //   Int_t lnum           An integer array, created by this routine,
07012     //                        containing the copy numbers.
07013     // Return:
07014     //   The size of the arrays lnam an lnum, the number of volumes down
07015     //   the geometry tree. Note, These arrays are allocated within this
07016     //   routine, but must be deleted outside of this routine.
07017     Int_t i,j=0,k=0,ireturn,ichar,*inam;
07018     Char_t *buf,**levels,**copies,nam[4];
07019 
07020     inam = (Int_t*)nam; // Setup to convert character string to integer.
07021     buf = new Char_t[volumePath.Length()+1];
07022     for(i=0;i<volumePath.Length();i++) {
07023         if(volumePath[i]!=' ')buf[j++] = volumePath[i]; // remove blanks
07024         if(volumePath[i]=='/') k++;
07025     } // end for i
07026     buf[j] = '\0';
07027     if(buf[j-1]=='/') {k--; buf[j-1]='\0';}// if path ends with '/' ignore 
07028                                             // it, remove it.
07029     levels = new Char_t*[k];
07030     copies = new Char_t*[k];
07031     (*lnam) = new Int_t[k]; // Allocate Geant3 volume name array
07032     (*lnum) = new Int_t[k]; // Allocate Geant3 copy number array
07033     ireturn = k;
07034     ichar = j;
07035     k = 0;
07036     j = 0;
07037     for(i=0;i<ichar;i++) {
07038         if(buf[i]=='/'){ 
07039             levels[k++] = &(buf[i+1]);
07040             buf[i] = '\0'; // Terminate this sub string.
07041         } // end if == '/'
07042         if(buf[i]=='_'){
07043             copies[j++] = &(buf[i+1]);
07044             buf[i] = '\0'; // Terminate this sub string.
07045         } // end if =='_'
07046     } // end for i
07047     if(k!=j){ // Error, different number of copy numbers and volume names.
07048         // clean up everything.
07049         delete[] buf;
07050         delete[] levels;
07051         delete[] copies;
07052         delete[] (*lnam);
07053         delete[] (*lnum);
07054         (*lnam) = 0;
07055         (*lnum) = 0;
07056         Error("ConvertVolumePathString","Different number of volume names %d"
07057               " and copy numbers %d in volumePath:%s",k,j,volumePath.Data());
07058         return 0;
07059     } // end if k!=j
07060     for(i=0;i<k;i++){
07061         *inam = 0;
07062         (*lnum)[i] = atoi(copies[i]);
07063         for(j=0;j<4;j++) {
07064             if(levels[i][j] == 0) break; // If at end of string exit loop
07065             nam[j] = levels[i][j];
07066         } // end for j
07067         (*lnam)[i] = *inam;
07068     } // end for i
07069     // clean up all but lnam and lnum
07070     delete[] buf;
07071     delete[] levels;
07072     delete[] copies;
07073     return ireturn; // return the size of lnam and lnum. 
07074 }
07075 
07076 //__________________________________________________________________
07077 void TGeant3::Gfang( Float_t* p, Float_t& costh, Float_t& sinth, 
07078                      Float_t& cosph, Float_t& sinph, Int_t& rotate) 
07079 {
07080 
07081   g3fang(p, costh, sinth, cosph, sinph, rotate );
07082 } 
07083 
07084 //__________________________________________________________________
07085 Int_t TGeant3::GetIonPdg(Int_t z, Int_t a, Int_t i) const
07086 {
07087 // Acording to
07088 // http://cepa.fnal.gov/psm/stdhep/pdg/montecarlorpp-2006.pdf
07089 
07090   return 1000000000 + 10*1000*z + 10*a + i;
07091 }  
07092                 
07093 //__________________________________________________________________
07094 Int_t TGeant3::GetSpecialPdg(Int_t number) const
07095 {
07096 // Numbering for special particles
07097 
07098   return 50000000 + number;
07099 }                
07100 

Generated on Mon Mar 16 23:00:15 2009 for loon by doxygen 1.3.5