BLManager.hh

Go to the documentation of this file.
00001 //      BLManager.hh
00002 /*
00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com
00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved.
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 http://www.gnu.org/copyleft/gpl.html
00017 */
00018 
00019 #ifndef BLMANAGER_HH
00020 #define BLMANAGER_HH
00021 
00022 #include <vector>
00023 #include <map>
00024 #include <set>
00025 #include "G4VUserDetectorConstruction.hh"
00026 #include "G4SteppingManager.hh"
00027 #include "G4Step.hh"
00028 #include "G4Track.hh"
00029 #include "G4Run.hh"
00030 #include "G4Event.hh"
00031 #include "G4VPhysicalVolume.hh"
00032 #include "G4VExceptionHandler.hh"
00033 
00034 #include "BLCallback.hh"
00035 #include "BLRunManager.hh"
00036 #include "BLPhysics.hh"
00037 #include "BLZStep.hh"
00038 #include "BLUserCode.hh"
00039 
00040 class BLBeam;
00041 
00042 
00043 // State SPECIAL is used for pre-tracking in collective mode -- all
00044 // entries into NTuples should be omitted in SPECIAL mode.
00045 enum BLManagerState { IDLE, VISUAL, TUNE, REFERENCE, BEAM, SPECIAL };
00046 enum VerboseFormat { TAG,NSTEP,GLOBAL,CL,CLX,KE,STEP,VOL,PROCESS,B,E,MAT,
00047                      P, ID, PART, SEG, WT, NEWLINE, EXT };
00048 enum PRNGSeedMethod { EVENT_NUMBER, NO_SEED, TIME_US };
00049 
00050 /**     BLManager is the overall manager for g4beamline, managing all aspects
00051  *      of the run.
00052  *
00053  *      Note it is uses all the G4 user action classes, implemented as classes
00054  *      under BLManager.
00055  *
00056  *      TrackID-s: It is non-trivial to preserve TrackID-s from input files,
00057  *      because Geant4 considers TrackID to be an internal variable, and it
00058  *      assigns them in a non-customizable manner. So BLManager keeps a
00059  *      trackIDMap[] that converts from internal (Geant4) to external (User)
00060  *      TrackID-s. It also uses BLTrackInfo to associate the external IDs
00061  *      with the track -- the external trackID is determined either in BLBeam
00062  *      (when the track is created), or in BLManager::PreUserTrackingAction
00063  *      for secondaries.
00064  **/
00065 class BLManager : public G4VUserDetectorConstruction, 
00066                         G4VExceptionHandler {
00067 public: // user Action classes
00068         class RunAction {
00069         public: virtual void BeginOfRunAction(const G4Run *run) = 0;
00070         public: virtual void EndOfRunAction(const G4Run *run) = 0;
00071         };
00072         class EventAction {
00073         public: virtual void BeginOfEventAction(const G4Event* event) = 0;
00074         public: virtual void EndOfEventAction(const G4Event* event) = 0;
00075         };
00076         class TrackingAction {
00077         protected: G4TrackingManager *fpTrackingManager;
00078         public: void SetTrackingManagerPointer(G4TrackingManager *p) 
00079                 {fpTrackingManager=p;}
00080         public: virtual void PreUserTrackingAction(const G4Track *track) = 0;
00081         public: virtual void PostUserTrackingAction(const G4Track *track) = 0;
00082         };
00083         class SteppingAction {
00084         public: virtual void UserSteppingAction(const G4Step *step) = 0;
00085         };
00086         class ZSteppingAction {
00087         public: virtual void UserZSteppingAction(const G4Track *track) = 0;
00088         };
00089         class PrimaryGeneratorAction {
00090         public: virtual void GeneratePrimaries(G4Event *event) = 0;
00091         };
00092         class StackingAction {
00093         // returns only fUrgent or fKill.
00094         public: virtual G4ClassificationOfNewTrack 
00095                                         ClassifyNewTrack(const G4Track*) = 0;
00096         public: virtual void NewStage() { }
00097         public: virtual void PrepareNewEvent() { }
00098         };
00099 private:
00100         struct ZStep {
00101                 G4double z;
00102                 ZSteppingAction *action;
00103                 ZStep(G4double _z, ZSteppingAction *a) { z=_z; action=a; }
00104         };
00105         static BLManager *blManager;
00106         static bool initialized;
00107         BLRunManager *runManager;
00108         BLManagerState state;
00109         G4int steppingVerbose;
00110         unsigned int  beamIndex;
00111         G4int histoUpdate;
00112         time_t startRun;
00113         time_t startEvent;
00114         G4int eventTimeLimit;
00115         BLPhysics *physics;
00116         G4VPhysicalVolume *worldPhysicalVolume;
00117         G4int eventID;
00118         G4int trackID;
00119         G4ParticleDefinition *trackParticleDef;
00120         G4int fatalExceptions;
00121         G4int eventsAborted;
00122         G4int tracksAborted;
00123         G4int warnings;
00124         G4int prevEventID;
00125         G4int eventsProcessed;
00126         bool endRun;
00127         PRNGSeedMethod seedMethod;
00128         G4String eventCutFile;
00129         std::set<int> eventList;
00130         G4SteppingManager *fpSteppingManager;
00131         G4TrackingManager *fpTrackingManager;
00132         std::vector<BLBeam*> beamVector;
00133         std::vector<BLBeam*> referenceVector;
00134         std::vector<RunAction*> runActionVector;
00135         std::vector<RunAction*> beamRunActionVector;
00136         std::vector<EventAction*> eventActionVector;
00137         std::vector<EventAction*> beamEventActionVector;
00138         std::vector<TrackingAction*> trackingActionVector;
00139         std::vector<BLCallback*> preReferenceCallbackVector;
00140         std::vector<BLCallback*> postReferenceCallbackVector;
00141         std::vector<BLCallback*> postTrackingCallbackVector;
00142         std::vector<BLCallback*> replaceMainLoopCallbackVector;
00143         std::vector<BLCallback*> visualizationCallbackVector;
00144         std::vector<SteppingAction*> allStepVector;
00145         std::map<G4VPhysicalVolume*,SteppingAction*> allStepMap;
00146         std::map<G4VPhysicalVolume*,SteppingAction*> tpStepMap;
00147         std::map<G4VPhysicalVolume*,SteppingAction*> rpStepMap;
00148         std::vector<SteppingAction*> tpStepVector;
00149         std::vector<SteppingAction*> rpStepVector;
00150         std::map<G4VPhysicalVolume*,SteppingAction*> beamStepMap;
00151         std::vector<SteppingAction*> beamStepVector;
00152         std::vector<int> verboseFormat;
00153         G4double zTolerance;
00154         std::vector<ZStep> tuneZStep;
00155         std::vector<ZStep> referenceZStep;
00156         std::vector<ZStep> beamZStep;
00157         std::vector<ZStep> *currentZStep;
00158         unsigned indexZStep;
00159         G4double prevZ;
00160         G4int nStuck;
00161         std::vector<StackingAction*> stackingActionVector;
00162         int nextSecondaryTrackID;
00163         std::map<G4int,G4int> trackIDMap;
00164         int primaryTrackID;
00165         int primaryParentID;
00166         std::vector<BLUserCode*> userCodeVector;
00167         std::map<G4String,int> exceptionCount;
00168         /// private constructor -- immediate construction only.
00169         BLManager();
00170         void insertZStep(std::vector<ZStep>& vector, G4double z, ZSteppingAction *action);
00171         void readEventCutFile();
00172 public:
00173         /// getObject() will return a pointer to the single BLManager object,
00174         /// creating it if necessary. Does only the immediate constructor, not
00175         /// delayedConstruction(). that means it is Ok to register capabilities,
00176         /// but not much else.
00177         static BLManager *getObject();
00178 
00179         /// delayedConstruction() performs things which must wait until all
00180         /// static initializers have executed (e.g. in Geant4 routines).
00181         void delayedConstruction();
00182 
00183         /// Destructor.
00184         ~BLManager();
00185 
00186         /// getState() returns the current state.
00187         BLManagerState getState() { return state; }
00188 
00189         /// setState sets the state
00190         void setState(BLManagerState _state) { state = _state; }
00191 
00192         /// getSteppingVerbose() returns steppingVerbose. NOTE: use this
00193         /// during tracking instead of Param.getInt("steppingVerbose");
00194         int getSteppingVerbose() { return steppingVerbose; }
00195 
00196         /// setSteppingVerbose() updates steppingVerbose. -- NOTE: many
00197         /// other classes relay on the Parameter, not the valud in this class.
00198         void setSteppingVerbose(int v) { steppingVerbose = v; }
00199 
00200         /// getEventTimeLimit() returns the CPU time limit for events (seconds).
00201         /// -1 mean infinite.
00202         int getEventTimeLimit() { return eventTimeLimit; }
00203 
00204         /// setEventTimeLimit() sets the CPU time limit for events (seconds).
00205         /// -1 mean infinite.
00206         void setEventTimeLimit(int sec) { eventTimeLimit = sec; }
00207 
00208         /// getEventID() gets the current eventID;
00209         G4int getEventID() const { return eventID; }
00210 
00211         /// setEventID() sets the current eventID;
00212         void setEventID(int evId) { eventID=evId; prevEventID=evId-1; }
00213 
00214         /// skipEvent() will check the eventList vector (which comes from
00215         /// the eventCut file).
00216         bool skipEvent(int EventID)
00217             { return eventList.size() > 0 && eventList.count(eventID) == 0; }
00218 
00219         /// incrEventsProcessed() will increment eventsProcessed.
00220         /// For special uses only (e.g.MPI).
00221         void incrEventsProcessed(int eventID);
00222 
00223         /// registerSteppingAction() registers a SteppingAction to
00224         /// be called for each step (regardless of state).
00225         void registerSteppingAction(SteppingAction *sa)
00226                 { allStepVector.push_back(sa); }
00227 
00228         /// registerSteppingAction() registers a SteppingAction to
00229         /// be called for each step (regardless of state), for every step
00230         /// involving the physicalVol.
00231         /// The callback will be called if physicalVol is either
00232         /// the pre- or post-step physical volume (once if both).
00233         /// If physicalVol==0 it is called every reference particle step.
00234         /// LIMITATION: only one callback can be registered for a given 
00235         /// physicalVol (except 0).
00236         void registerSteppingAction(G4VPhysicalVolume *physicalVol,
00237                                                 SteppingAction *sa)
00238                 { if(physicalVol != 0) allStepMap[physicalVol] = sa;
00239                   else allStepVector.push_back(sa); }
00240 
00241         /// registerTuneParticleStep() registers a SteppingAction to
00242         /// be called for every tune particle step involving the physicalVol.
00243         /// The callback will be called if physicalVol is either
00244         /// the pre- or post-step physical volume (once if both).
00245         /// If physicalVol==0 it is called every tune particle step.
00246         /// LIMITATION: only one callback can be registered for a given 
00247         /// physicalVol (except 0).
00248         void registerTuneParticleStep(G4VPhysicalVolume *physicalVol,
00249                                         SteppingAction *sa)
00250                 { if(physicalVol != 0) tpStepMap[physicalVol] = sa; 
00251                   else tpStepVector.push_back(sa); }
00252 
00253         /// registerReferenceParticleStep() registers a SteppingAction to
00254         /// be called for every reference particle step involving the
00255         /// physicalVol.
00256         /// The callback will be called if physicalVol is either
00257         /// the pre- or post-step physical volume (once if both).
00258         /// If physicalVol==0 it is called every reference particle step.
00259         /// LIMITATION: only one callback can be registered for a given 
00260         /// physicalVol (except 0).
00261         void registerReferenceParticleStep(G4VPhysicalVolume *physicalVol,
00262                                         SteppingAction *sa)
00263                 { if(physicalVol != 0) rpStepMap[physicalVol] = sa; 
00264                   else rpStepVector.push_back(sa); }
00265 
00266         /// registerBeamStep() registers a SteppingAction to
00267         /// be called for every beam step involving the physicalVol.
00268         /// (beam particles are everything except reference and tune.)
00269         /// The callback will be called if physicalVol is either
00270         /// the pre- or post-step physical volume (once if both). 
00271         /// if physicalVol==0 it is called every beam step.
00272         /// LIMITATION: only one callback can be registered for a given 
00273         /// physicalVol (except 0).
00274         void registerBeamStep(G4VPhysicalVolume *physicalVol,
00275                                         SteppingAction *sa)
00276                 { if(physicalVol != 0) beamStepMap[physicalVol] = sa; 
00277                   else beamStepVector.push_back(sa); }
00278 
00279         /// registerZStep() will force a step to occur near the given z
00280         /// position, and will call the ZSteppingAction for it, interpolating
00281         /// to the desired z value (Centerline coords).
00282         /// when is a bitwise OR of 1=tune, 2=reference, 4=beam.
00283         void registerZStep(G4double z, ZSteppingAction *sa, G4int when=7);
00284 
00285         /// registerStackingAction() registers a StackingAction to be called
00286         /// by the Geant4 stacking manager.
00287         void registerStackingAction(StackingAction *sa)
00288                 { stackingActionVector.push_back(sa); }
00289 
00290         /// setSteppingFormat() sets the verbose printing format according
00291         /// to parameter "steppingFormat".
00292         void setSteppingFormat();
00293 
00294         /// getFormatHelp() returns a string with help text about valid format 
00295         /// items.
00296         G4String getFormatHelp();
00297 
00298         /// appendVerboseFormat() appends fmt to the format for printing when
00299         /// param steppingVerbose is nonzero
00300         void appendVerboseFormat(G4String fmt);
00301 
00302         /// steppingVerbosePrint() will print this step according to the current
00303         /// verboseFormat.
00304         /// Prints header if header != 0).
00305         void steppingVerbosePrint(const G4Step *step, const G4Track *track, int
00306                                                                 header=0);
00307 
00308         /// setSteppingManager() sets the pointer to the current
00309         /// G4SteppingManager.
00310         void setSteppingManager(G4SteppingManager *p) { fpSteppingManager = p; }
00311 
00312         /// getSteppingManager() returns a pointer to the current
00313         /// G4SteppingManager.
00314         G4SteppingManager *getSteppingManager() { return fpSteppingManager; }
00315 
00316         /// setTrackingManager() sets the pointer to the current
00317         /// G4TrackingManager.
00318         void setTrackingManager(G4TrackingManager *p) { fpTrackingManager = p; }
00319 
00320         /// initialize() will initialize the BLManager object, and the 
00321         /// geant4 kernel, thus constructing the geometry in the
00322         /// world group. Note that registerPhysics() must be called
00323         /// before initialize() (normally done by a "physics" command
00324         /// in the input file).
00325         void initialize();
00326 
00327         /// isInitialized() returns true if the BLManager has been initialized.
00328         static bool isInitialized() { return initialized; }
00329 
00330         /// trackTuneAndReferenceParticles() will generate and track the tune
00331         /// particle and then the reference particle.
00332         void trackTuneAndReferenceParticles();
00333 
00334         /// trackBeam() will generate the defined beam and track each event.
00335         void trackBeam();
00336 
00337         /// displayVisual() will display the detector visually.
00338         void displayVisual();
00339 
00340         /// displayGeometry() will display the geant4 geometry.
00341         /// This is a hierarchical ASCII listing of all volumes.
00342         /// if phys==0 then use the worldPhysicalVolume.
00343         void displayGeometry(G4VPhysicalVolume *phys=0, int level=0);
00344 
00345         /// registerPhysics() registers the BLPhysics object.
00346         /// It also sets the physics list to the BLRunManager, so following
00347         /// commands can find particle by name.
00348         void registerPhysics(BLPhysics *_physics)
00349                 { physics = _physics;
00350                   runManager->SetUserInitialization(physics->getPhysicsList());
00351                 }
00352         
00353         /// getPhysics returns the registered BLPhysics object.
00354         BLPhysics *getPhysics() { return physics; }
00355 
00356         /// registerBeam() registers a BLBeam object for beam generation.
00357         /// Multiple BLBeam objects can be registered, used in order.
00358         void registerBeam(BLBeam *_beam) { beamVector.push_back(_beam); }
00359 
00360         /// registerReference() registers a BLBeam object for reference 
00361         /// particle generation.
00362         /// Multiple BLBeam objects can be registered, used in order.
00363         void registerReference(BLBeam *_beam)
00364                 { referenceVector.push_back(_beam); }
00365 
00366         /// nReference() returns the number of reference particles registered.
00367         int nReference() { return referenceVector.size(); }
00368 
00369         /// registerRunAction() registers a UserRunAction.
00370         /// If beamOnly is true (the default), the callback is made only
00371         /// if state==BEAM.
00372         void registerRunAction(RunAction *a, G4bool beamOnly=true)
00373                 { if(beamOnly)
00374                         beamRunActionVector.push_back(a);
00375                   else
00376                         runActionVector.push_back(a);
00377                 }
00378 
00379         /// registerEventAction() registers a UserEventAction.
00380         /// If beamOnly is true (the default), the callback is made only
00381         /// if state==BEAM.
00382         void registerEventAction(EventAction *a, G4bool beamOnly=true)
00383                 { if(beamOnly)
00384                         beamEventActionVector.push_back(a);
00385                   else
00386                         eventActionVector.push_back(a);
00387                 }
00388 
00389         /// registerTrackingAction() registers a UserTackingAction.
00390         void registerTrackingAction(TrackingAction *a)
00391                 { trackingActionVector.push_back(a); }
00392 
00393         /// registerUserCode() registers a BLUserCode instance.
00394         void registerUserCode(BLUserCode *instance)
00395                 { userCodeVector.push_back(instance); }
00396 
00397         /// getUserCodeInstances() returns a vector of all registered
00398         /// instances of BLUserCode with the specified type.
00399         std::vector<BLUserCode*> getUserCodeInstances(G4String type)
00400                 { std::vector<BLUserCode*> ret;
00401                   for(unsigned i=0; i<userCodeVector.size(); ++i) {
00402                         if(type == userCodeVector[i]->getType())
00403                                 ret.push_back(userCodeVector[i]);
00404                   }
00405                   return ret;
00406                 }
00407 
00408 
00409         /// registerCallback() registers a BLCallback.
00410         /// type=0 for pre-Tune particle,
00411         /// type=1 for post-Reference (pre-beam tracking),
00412         /// type=2 for post-beam tracking.
00413         /// type=3 for replacing the main program loop.
00414         /// type=4 for visualization.
00415         /// NOTE: if there are type=3 callbacks, when the last one returns
00416         /// the closes up by summarizing NTuples and callng handleCallbacks(2),
00417         /// and then the program exits. This prevents the main program loop from
00418         /// executing. type=3 callbacks are called just after the type=1
00419         /// callbacks (i.e. after the post-Reference callbacks).
00420         void registerCallback(BLCallback *cb, int type) {
00421                 if(type==0) preReferenceCallbackVector.push_back(cb);
00422                 else if(type==1) postReferenceCallbackVector.push_back(cb);
00423                 else if(type==2) postTrackingCallbackVector.push_back(cb);
00424                 else if(type==3) replaceMainLoopCallbackVector.push_back(cb);
00425                 else if(type==4) visualizationCallbackVector.push_back(cb);
00426         }
00427 
00428         /// handleCallbacks() calls all applicable registered callbacks.
00429         /// type=0 for pre-reference particle,
00430         /// type=1 for post-center (pre-beam tracking),
00431         /// type=2 for post-beam tracking (just before program exit).
00432         /// type=3 for replacing the main program loop.
00433         /// type=4 for visualization.
00434         void handleCallbacks(int type);
00435 
00436         /// getWorldPhysicalVolume() returns a pointer to the world PV.
00437         /// Note that it must already have been consructed, so this function
00438         /// returns NULL before construct() is called (by main).
00439         G4VPhysicalVolume *getWorldPhysicalVolume()
00440                 { return worldPhysicalVolume; }
00441 
00442         /// setPRNGSeedMethod() will set the method used to seed the
00443         /// pseudo random number generator at the start of each event.
00444         void setPRNGSeedMethod(PRNGSeedMethod method)
00445                 { seedMethod = method; }
00446 
00447         /// getPRNGSeedMethod() will return the method used to seed the
00448         /// pseudo random number generator at the start of each event.
00449         PRNGSeedMethod getPRNGSeedMethod() { return seedMethod; }
00450 
00451         /// setEventCutFile() will set the file containing event #s for cutting.
00452         /// The file is ASCII, with one event number per line; lines beginning
00453         /// with # are ignored.
00454         void setEventCutFile(G4String &f) { eventCutFile = f; }
00455 
00456         // virtual functions from the geant4 base classes. All of them
00457         // call the registered actions, as appropriate for state and
00458         // the current physical volume (if applicable). Due to the design
00459         // of the Geant4 callback classes, these are mediated by classes of
00460         // the form BLManager_name.
00461 
00462         /// UserSteppingAction() from G4UserSteppingAction.
00463         void UserSteppingAction(const G4Step *step);
00464 
00465         /// Construct() from G4VUserDetectorConstruction.
00466         G4VPhysicalVolume *Construct();
00467 
00468         /// PreUserTrackingAction() from G4UserTrackingAction.
00469         void PreUserTrackingAction(const G4Track *track);
00470 
00471         /// PostUserTrackingAction() from G4UserTrackingAction.
00472         void PostUserTrackingAction(const G4Track *track);
00473 
00474         /// BeginOfRunAction() from G4UserRunAction.
00475         void BeginOfRunAction(const G4Run *run);
00476 
00477         /// EndOfRunAction() from G4UserRunAction.
00478         void EndOfRunAction(const G4Run *run);
00479 
00480         /// BeginOfEventAction() from G4UserEventAction.
00481         void BeginOfEventAction(const G4Event* event);
00482 
00483         /// EndOfEventAction() from G4UserEventAction.
00484         void EndOfEventAction(const G4Event* event);
00485 
00486         /// GeneratePrimaries() from G4VUserPrimaryGeneratorAction.
00487         void GeneratePrimaries(G4Event *event);
00488 
00489         /// ClassifyNewTrack() from G4UserStackingAction.
00490         G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track*);
00491 
00492         /// NewStage() from G4userStackingAction.
00493         void NewStage();
00494 
00495         /// PrepareNewEvent() from G4StackingAction.
00496         void PrepareNewEvent();
00497 
00498         /// clearTrackIDMap() clears the TrackID map.
00499         void clearTrackIDMap() { trackIDMap.clear(); }
00500 
00501         /// setNextSecondaryTrackID() sets the external TrackID for the
00502         /// next secondary track. Automatically incremented for subsequent
00503         /// secondaries.
00504         void setNextSecondaryTrackID(int next) { nextSecondaryTrackID = next; }
00505         int getNextSecondaryTrackID() { return nextSecondaryTrackID; }
00506 
00507         /// getExternalTrackID() returns the external TrackID for the given
00508         /// track.
00509         /// In collective mode, internal and external trackID-s are the same.
00510         int getExternalTrackID(const G4Track *track);
00511 
00512         /// getExternalParentID() returns the external ParentID for the given
00513         /// track.
00514         /// In collective mode, internal and external trackID-s are the same.
00515         int getExternalParentID(const G4Track *track);
00516 
00517         /// setExternalTrackID() will set the external trackID and parentID.
00518         /// if trackID<0 uses nextSecondarTrackID++.
00519         void setExternalTrackID(G4Track *track, int trackID, int parentID);
00520 
00521         /// getPrimaryTrackID() returns the primaryTrackID set by the beam command
00522         int getPrimaryTrackID() { return primaryTrackID; }
00523 
00524         /// getPrimaryParentID() returns the primaryParentID set by the beam command
00525         int getPrimaryParentID() { return primaryParentID; }
00526 
00527         /// setPrimaryTrackID() sets track and parent IDs for a primary track.
00528         void setPrimaryTrackID(int t, int p)
00529                 { primaryTrackID = t; primaryParentID = p; }
00530 
00531         /// Notify() from G4VExceptionHandler.
00532         G4bool Notify(const char* originOfException, const char* exceptionCode,
00533                         G4ExceptionSeverity severity, const char* description);
00534 
00535         /// exceptionSummary() prints a summary of all exceptions
00536         void exceptionSummary();
00537 };
00538 
00539 #endif // BLMANAGER_HH
g4beamline