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         G4int eventsAborted;
00120         G4int warnings;
00121         G4int prevEventID;
00122         G4int eventsProcessed;
00123         bool endRun;
00124         PRNGSeedMethod seedMethod;
00125         G4String eventCutFile;
00126         std::set<int> eventList;
00127         G4SteppingManager *fpSteppingManager;
00128         G4TrackingManager *fpTrackingManager;
00129         std::vector<BLBeam*> beamVector;
00130         std::vector<BLBeam*> referenceVector;
00131         std::vector<RunAction*> runActionVector;
00132         std::vector<RunAction*> beamRunActionVector;
00133         std::vector<EventAction*> eventActionVector;
00134         std::vector<EventAction*> beamEventActionVector;
00135         std::vector<TrackingAction*> trackingActionVector;
00136         std::vector<BLCallback*> preReferenceCallbackVector;
00137         std::vector<BLCallback*> postReferenceCallbackVector;
00138         std::vector<BLCallback*> postTrackingCallbackVector;
00139         std::vector<BLCallback*> replaceMainLoopCallbackVector;
00140         std::vector<BLCallback*> visualizationCallbackVector;
00141         std::vector<SteppingAction*> allStepVector;
00142         std::map<G4VPhysicalVolume*,SteppingAction*> allStepMap;
00143         std::map<G4VPhysicalVolume*,SteppingAction*> tpStepMap;
00144         std::map<G4VPhysicalVolume*,SteppingAction*> rpStepMap;
00145         std::vector<SteppingAction*> tpStepVector;
00146         std::vector<SteppingAction*> rpStepVector;
00147         std::map<G4VPhysicalVolume*,SteppingAction*> beamStepMap;
00148         std::vector<SteppingAction*> beamStepVector;
00149         std::vector<int> verboseFormat;
00150         G4double zTolerance;
00151         std::vector<ZStep> tuneZStep;
00152         std::vector<ZStep> referenceZStep;
00153         std::vector<ZStep> beamZStep;
00154         std::vector<ZStep> *currentZStep;
00155         unsigned indexZStep;
00156         G4double prevZ;
00157         G4int nStuck;
00158         std::vector<StackingAction*> stackingActionVector;
00159         int nextSecondaryTrackID;
00160         std::map<G4int,G4int> trackIDMap;
00161         int primaryTrackID;
00162         int primaryParentID;
00163         std::vector<BLUserCode*> userCodeVector;
00164         /// private constructor -- immediate construction only.
00165         BLManager();
00166         void insertZStep(std::vector<ZStep>& vector, G4double z, ZSteppingAction *action);
00167         void readEventCutFile();
00168 public:
00169         /// getObject() will return a pointer to the single BLManager object,
00170         /// creating it if necessary. Does only the immediate constructor, not
00171         /// delayedConstruction(). that means it is Ok to register capabilities,
00172         /// but not much else.
00173         static BLManager *getObject();
00174 
00175         /// delayedConstruction() performs things which must wait until all
00176         /// static initializers have executed (e.g. in Geant4 routines).
00177         void delayedConstruction();
00178 
00179         /// Destructor.
00180         ~BLManager();
00181 
00182         /// getState() returns the current state.
00183         BLManagerState getState() { return state; }
00184 
00185         /// setState sets the state
00186         void setState(BLManagerState _state) { state = _state; }
00187 
00188         /// getSteppingVerbose() returns steppingVerbose. NOTE: use this
00189         /// during tracking instead of Param.getInt("steppingVerbose");
00190         int getSteppingVerbose() { return steppingVerbose; }
00191 
00192         /// setSteppingVerbose() updates steppingVerbose. -- NOTE: many
00193         /// other classes relay on the Parameter, not the valud in this class.
00194         void setSteppingVerbose(int v) { steppingVerbose = v; }
00195 
00196         /// getEventTimeLimit() returns the CPU time limit for events (seconds).
00197         /// -1 mean infinite.
00198         int getEventTimeLimit() { return eventTimeLimit; }
00199 
00200         /// setEventTimeLimit() sets the CPU time limit for events (seconds).
00201         /// -1 mean infinite.
00202         void setEventTimeLimit(int sec) { eventTimeLimit = sec; }
00203 
00204         /// getEventID() gets the current eventID;
00205         G4int getEventID() const { return eventID; }
00206 
00207         /// setEventID() sets the current eventID;
00208         void setEventID(int evId) { eventID=evId; prevEventID=evId-1; }
00209 
00210         /// skipEvent() will check the eventList vector (which comes from
00211         /// the eventCut file).
00212         bool skipEvent(int EventID)
00213             { return eventList.size() > 0 && eventList.count(eventID) == 0; }
00214 
00215         /// incrEventsProcessed() will increment eventsProcessed.
00216         /// For special uses only (e.g.MPI).
00217         void incrEventsProcessed(int eventID);
00218 
00219         /// registerSteppingAction() registers a SteppingAction to
00220         /// be called for each step (regardless of state).
00221         void registerSteppingAction(SteppingAction *sa)
00222                 { allStepVector.push_back(sa); }
00223 
00224         /// registerSteppingAction() registers a SteppingAction to
00225         /// be called for each step (regardless of state), for every step
00226         /// involving the physicalVol.
00227         /// The callback will be called if physicalVol is either
00228         /// the pre- or post-step physical volume (once if both).
00229         /// If physicalVol==0 it is called every reference particle step.
00230         /// LIMITATION: only one callback can be registered for a given 
00231         /// physicalVol (except 0).
00232         void registerSteppingAction(G4VPhysicalVolume *physicalVol,
00233                                                 SteppingAction *sa)
00234                 { if(physicalVol != 0) allStepMap[physicalVol] = sa;
00235                   else allStepVector.push_back(sa); }
00236 
00237         /// registerTuneParticleStep() registers a SteppingAction to
00238         /// be called for every tune particle step involving the physicalVol.
00239         /// The callback will be called if physicalVol is either
00240         /// the pre- or post-step physical volume (once if both).
00241         /// If physicalVol==0 it is called every tune particle step.
00242         /// LIMITATION: only one callback can be registered for a given 
00243         /// physicalVol (except 0).
00244         void registerTuneParticleStep(G4VPhysicalVolume *physicalVol,
00245                                         SteppingAction *sa)
00246                 { if(physicalVol != 0) tpStepMap[physicalVol] = sa; 
00247                   else tpStepVector.push_back(sa); }
00248 
00249         /// registerReferenceParticleStep() registers a SteppingAction to
00250         /// be called for every reference particle step involving the
00251         /// physicalVol.
00252         /// The callback will be called if physicalVol is either
00253         /// the pre- or post-step physical volume (once if both).
00254         /// If physicalVol==0 it is called every reference particle step.
00255         /// LIMITATION: only one callback can be registered for a given 
00256         /// physicalVol (except 0).
00257         void registerReferenceParticleStep(G4VPhysicalVolume *physicalVol,
00258                                         SteppingAction *sa)
00259                 { if(physicalVol != 0) rpStepMap[physicalVol] = sa; 
00260                   else rpStepVector.push_back(sa); }
00261 
00262         /// registerBeamStep() registers a SteppingAction to
00263         /// be called for every beam step involving the physicalVol.
00264         /// (beam particles are everything except reference and tune.)
00265         /// The callback will be called if physicalVol is either
00266         /// the pre- or post-step physical volume (once if both). 
00267         /// if physicalVol==0 it is called every beam step.
00268         /// LIMITATION: only one callback can be registered for a given 
00269         /// physicalVol (except 0).
00270         void registerBeamStep(G4VPhysicalVolume *physicalVol,
00271                                         SteppingAction *sa)
00272                 { if(physicalVol != 0) beamStepMap[physicalVol] = sa; 
00273                   else beamStepVector.push_back(sa); }
00274 
00275         /// registerZStep() will force a step to occur near the given z
00276         /// position, and will call the ZSteppingAction for it, interpolating
00277         /// to the desired z value (Centerline coords).
00278         /// when is a bitwise OR of 1=tune, 2=reference, 4=beam.
00279         void registerZStep(G4double z, ZSteppingAction *sa, G4int when=7);
00280 
00281         /// registerStackingAction() registers a StackingAction to be called
00282         /// by the Geant4 stacking manager.
00283         void registerStackingAction(StackingAction *sa)
00284                 { stackingActionVector.push_back(sa); }
00285 
00286         /// setSteppingFormat() sets the verbose printing format according
00287         /// to parameter "steppingFormat".
00288         void setSteppingFormat();
00289 
00290         /// getFormatHelp() returns a string with help text about valid format 
00291         /// items.
00292         G4String getFormatHelp();
00293 
00294         /// appendVerboseFormat() appends fmt to the format for printing when
00295         /// param steppingVerbose is nonzero
00296         void appendVerboseFormat(G4String fmt);
00297 
00298         /// steppingVerbosePrint() will print this step according to the current
00299         /// verboseFormat.
00300         /// Prints header if header != 0).
00301         void steppingVerbosePrint(const G4Step *step, const G4Track *track, int
00302                                                                 header=0);
00303 
00304         /// setSteppingManager() sets the pointer to the current
00305         /// G4SteppingManager.
00306         void setSteppingManager(G4SteppingManager *p) { fpSteppingManager = p; }
00307 
00308         /// getSteppingManager() returns a pointer to the current
00309         /// G4SteppingManager.
00310         G4SteppingManager *getSteppingManager() { return fpSteppingManager; }
00311 
00312         /// setTrackingManager() sets the pointer to the current
00313         /// G4TrackingManager.
00314         void setTrackingManager(G4TrackingManager *p) { fpTrackingManager = p; }
00315 
00316         /// initialize() will initialize the BLManager object, and the 
00317         /// geant4 kernel, thus constructing the geometry in the
00318         /// world group. Note that registerPhysics() must be called
00319         /// before initialize() (normally done by a "physics" command
00320         /// in the input file).
00321         void initialize();
00322 
00323         /// isInitialized() returns true if the BLManager has been initialized.
00324         static bool isInitialized() { return initialized; }
00325 
00326         /// trackTuneAndReferenceParticles() will generate and track the tune
00327         /// particle and then the reference particle.
00328         void trackTuneAndReferenceParticles();
00329 
00330         /// trackBeam() will generate the defined beam and track each event.
00331         void trackBeam();
00332 
00333         /// displayVisual() will display the detector visually.
00334         void displayVisual();
00335 
00336         /// displayGeometry() will display the geant4 geometry.
00337         /// This is a hierarchical ASCII listing of all volumes.
00338         /// if phys==0 then use the worldPhysicalVolume.
00339         void displayGeometry(G4VPhysicalVolume *phys=0, int level=0);
00340 
00341         /// registerPhysics() registers the BLPhysics object.
00342         /// It also sets the physics list to the BLRunManager, so following
00343         /// commands can find particle by name.
00344         void registerPhysics(BLPhysics *_physics)
00345                 { physics = _physics;
00346                   runManager->SetUserInitialization(physics->getPhysicsList());
00347                 }
00348         
00349         /// getPhysics returns the registered BLPhysics object.
00350         BLPhysics *getPhysics() { return physics; }
00351 
00352         /// registerBeam() registers a BLBeam object for beam generation.
00353         /// Multiple BLBeam objects can be registered, used in order.
00354         void registerBeam(BLBeam *_beam) { beamVector.push_back(_beam); }
00355 
00356         /// registerReference() registers a BLBeam object for reference 
00357         /// particle generation.
00358         /// Multiple BLBeam objects can be registered, used in order.
00359         void registerReference(BLBeam *_beam)
00360                 { referenceVector.push_back(_beam); }
00361 
00362         /// nReference() returns the number of reference particles registered.
00363         int nReference() { return referenceVector.size(); }
00364 
00365         /// registerRunAction() registers a UserRunAction.
00366         /// If beamOnly is true (the default), the callback is made only
00367         /// if state==BEAM.
00368         void registerRunAction(RunAction *a, G4bool beamOnly=true)
00369                 { if(beamOnly)
00370                         beamRunActionVector.push_back(a);
00371                   else
00372                         runActionVector.push_back(a);
00373                 }
00374 
00375         /// registerEventAction() registers a UserEventAction.
00376         /// If beamOnly is true (the default), the callback is made only
00377         /// if state==BEAM.
00378         void registerEventAction(EventAction *a, G4bool beamOnly=true)
00379                 { if(beamOnly)
00380                         beamEventActionVector.push_back(a);
00381                   else
00382                         eventActionVector.push_back(a);
00383                 }
00384 
00385         /// registerTrackingAction() registers a UserTackingAction.
00386         void registerTrackingAction(TrackingAction *a)
00387                 { trackingActionVector.push_back(a); }
00388 
00389         /// registerUserCode() registers a BLUserCode instance.
00390         void registerUserCode(BLUserCode *instance)
00391                 { userCodeVector.push_back(instance); }
00392 
00393         /// getUserCodeInstances() returns a vector of all registered
00394         /// instances of BLUserCode with the specified type.
00395         std::vector<BLUserCode*> getUserCodeInstances(G4String type)
00396                 { std::vector<BLUserCode*> ret;
00397                   for(unsigned i=0; i<userCodeVector.size(); ++i) {
00398                         if(type == userCodeVector[i]->getType())
00399                                 ret.push_back(userCodeVector[i]);
00400                   }
00401                   return ret;
00402                 }
00403 
00404 
00405         /// registerCallback() registers a BLCallback.
00406         /// type=0 for pre-Tune particle,
00407         /// type=1 for post-Reference (pre-beam tracking),
00408         /// type=2 for post-beam tracking.
00409         /// type=3 for replacing the main program loop.
00410         /// type=4 for visualization.
00411         /// NOTE: if there are type=3 callbacks, when the last one returns
00412         /// the closes up by summarizing NTuples and callng handleCallbacks(2),
00413         /// and then the program exits. This prevents the main program loop from
00414         /// executing. type=3 callbacks are called just after the type=1
00415         /// callbacks (i.e. after the post-Reference callbacks).
00416         void registerCallback(BLCallback *cb, int type) {
00417                 if(type==0) preReferenceCallbackVector.push_back(cb);
00418                 else if(type==1) postReferenceCallbackVector.push_back(cb);
00419                 else if(type==2) postTrackingCallbackVector.push_back(cb);
00420                 else if(type==3) replaceMainLoopCallbackVector.push_back(cb);
00421                 else if(type==4) visualizationCallbackVector.push_back(cb);
00422         }
00423 
00424         /// handleCallbacks() calls all applicable registered callbacks.
00425         /// type=0 for pre-reference particle,
00426         /// type=1 for post-center (pre-beam tracking),
00427         /// type=2 for post-beam tracking (just before program exit).
00428         /// type=3 for replacing the main program loop.
00429         /// type=4 for visualization.
00430         void handleCallbacks(int type);
00431 
00432         /// getWorldPhysicalVolume() returns a pointer to the world PV.
00433         /// Note that it must already have been consructed, so this function
00434         /// returns NULL before construct() is called (by main).
00435         G4VPhysicalVolume *getWorldPhysicalVolume()
00436                 { return worldPhysicalVolume; }
00437 
00438         /// setPRNGSeedMethod() will set the method used to seed the
00439         /// pseudo random number generator at the start of each event.
00440         void setPRNGSeedMethod(PRNGSeedMethod method)
00441                 { seedMethod = method; }
00442 
00443         /// getPRNGSeedMethod() will return the method used to seed the
00444         /// pseudo random number generator at the start of each event.
00445         PRNGSeedMethod getPRNGSeedMethod() { return seedMethod; }
00446 
00447         /// setEventCutFile() will set the file containing event #s for cutting.
00448         /// The file is ASCII, with one event number per line; lines beginning
00449         /// with # are ignored.
00450         void setEventCutFile(G4String &f) { eventCutFile = f; }
00451 
00452         // virtual functions from the geant4 base classes. All of them
00453         // call the registered actions, as appropriate for state and
00454         // the current physical volume (if applicable). Due to the design
00455         // of the Geant4 callback classes, these are mediated by classes of
00456         // the form BLManager_name.
00457 
00458         /// UserSteppingAction() from G4UserSteppingAction.
00459         void UserSteppingAction(const G4Step *step);
00460 
00461         /// Construct() from G4VUserDetectorConstruction.
00462         G4VPhysicalVolume *Construct();
00463 
00464         /// PreUserTrackingAction() from G4UserTrackingAction.
00465         void PreUserTrackingAction(const G4Track *track);
00466 
00467         /// PostUserTrackingAction() from G4UserTrackingAction.
00468         void PostUserTrackingAction(const G4Track *track);
00469 
00470         /// BeginOfRunAction() from G4UserRunAction.
00471         void BeginOfRunAction(const G4Run *run);
00472 
00473         /// EndOfRunAction() from G4UserRunAction.
00474         void EndOfRunAction(const G4Run *run);
00475 
00476         /// BeginOfEventAction() from G4UserEventAction.
00477         void BeginOfEventAction(const G4Event* event);
00478 
00479         /// EndOfEventAction() from G4UserEventAction.
00480         void EndOfEventAction(const G4Event* event);
00481 
00482         /// GeneratePrimaries() from G4VUserPrimaryGeneratorAction.
00483         void GeneratePrimaries(G4Event *event);
00484 
00485         /// ClassifyNewTrack() from G4UserStackingAction.
00486         G4ClassificationOfNewTrack ClassifyNewTrack(const G4Track*);
00487 
00488         /// NewStage() from G4userStackingAction.
00489         void NewStage();
00490 
00491         /// PrepareNewEvent() from G4StackingAction.
00492         void PrepareNewEvent();
00493 
00494         /// clearTrackIDMap() clears the TrackID map.
00495         void clearTrackIDMap() { trackIDMap.clear(); }
00496 
00497         /// setNextSecondaryTrackID() sets the external TrackID for the
00498         /// next secondary track. Automatically incremented for subsequent
00499         /// secondaries.
00500         void setNextSecondaryTrackID(int next) { nextSecondaryTrackID = next; }
00501         int getNextSecondaryTrackID() { return nextSecondaryTrackID; }
00502 
00503         /// getExternalTrackID() returns the external TrackID for the given
00504         /// track.
00505         /// In collective mode, internal and external trackID-s are the same.
00506         int getExternalTrackID(const G4Track *track);
00507 
00508         /// getExternalParentID() returns the external ParentID for the given
00509         /// track.
00510         /// In collective mode, internal and external trackID-s are the same.
00511         int getExternalParentID(const G4Track *track);
00512 
00513         /// setExternalTrackID() will set the external trackID and parentID.
00514         /// if trackID<0 uses nextSecondarTrackID++.
00515         void setExternalTrackID(G4Track *track, int trackID, int parentID);
00516 
00517         /// getPrimaryTrackID() returns the primaryTrackID set by the beam command
00518         int getPrimaryTrackID() { return primaryTrackID; }
00519 
00520         /// getPrimaryParentID() returns the primaryParentID set by the beam command
00521         int getPrimaryParentID() { return primaryParentID; }
00522 
00523         /// setPrimaryTrackID() sets track and parent IDs for a primary track.
00524         void setPrimaryTrackID(int t, int p)
00525                 { primaryTrackID = t; primaryParentID = p; }
00526 
00527         /// Notify() from G4VExceptionHandler.
00528         G4bool Notify(const char* originOfException, const char* exceptionCode,
00529                         G4ExceptionSeverity severity, const char* description);
00530 };
00531 
00532 #endif // BLMANAGER_HH
g4beamline