This commit was generated by cvs2svn to compensate for changes in r1461,
[u/mrichter/AliRoot.git] / TGeant4 / TG4SpecialFlags.cxx
1 // $Id$ //
2 // Category: physics
3 //
4 // See the class description in the header file.
5
6 #include "TG4SpecialFlags.h"
7 #include "TG4Limits.h"
8
9 #include <G4StepStatus.hh>
10 #include <G4ProcessManager.hh>
11 #include <G4ProcessVector.hh>
12
13 TG4SpecialFlags::TG4SpecialFlags(const G4String& aName)
14   : G4VProcess(aName),
15     fSwitchFlags(kUnswitch)
16 {
17    // verboseLevel = 1;
18    if (verboseLevel>0) {
19      G4cout << GetProcessName() << " is created "<< endl;
20    }
21 }
22
23 TG4SpecialFlags::TG4SpecialFlags(const TG4SpecialFlags& right) {
24 // 
25   TG4Globals::Exception(
26     "TG4SpecialFlags is protected from copying.");
27 }
28
29 TG4SpecialFlags::~TG4SpecialFlags() {
30 //
31 }
32
33 // operators
34
35 TG4SpecialFlags& TG4SpecialFlags::operator=(const TG4SpecialFlags& right)
36 {
37   // check assignement to self
38   if (this == &right) return *this;
39
40   TG4Globals::Exception(
41     "TG4SpecialFlags is protected from assigning.");
42     
43   return *this;  
44
45
46 // public methods   
47           
48 G4double TG4SpecialFlags::PostStepGetPhysicalInteractionLength(
49                            const G4Track& track, G4double previousStepSize,
50                            G4ForceCondition* condition)
51 {
52 // Returns the Step-size (actual length) which is allowed 
53 // by this process.
54 // ---
55
56   *condition = NotForced;
57
58   G4double proposedStep = DBL_MAX;
59   G4double minStep = (1.0e-9)*m;
60     // must be greater than DBL_MIN - so that particle can get out of
61     // the boundary 
62     // proposedStep = 0.; causes navigator to fall into panic 
63   
64   G4StepStatus status     
65     = track.GetStep()->GetPreStepPoint()->GetStepStatus();
66   TG4Limits* limits 
67     = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
68
69   if (fSwitchFlags != kUnswitch) {
70     if (status == fGeomBoundary) {
71       if  ((limits) && (limits->IsFlag())) {
72         // particle is exiting a logical volume with special flags
73         // and entering another logical volume with special flags 
74         proposedStep = minStep;
75         fSwitchFlags = kReswitch;
76         if (verboseLevel>0) G4cout << "kReswitch" << endl;
77       }
78       else {
79         // particle is exiting a logical volume with special flags
80         // and entering a logical volume without special flags 
81         proposedStep = minStep;
82         fSwitchFlags = kUnswitch;
83         if (verboseLevel>0) G4cout << "kUnswitch" << endl;
84       }
85     }
86   }
87   else if ((limits) && (limits->IsFlag())) {
88        // particle is entering a logical volume with special flags
89        // that have not yet been set
90        proposedStep = minStep;
91        fSwitchFlags = kSwitch;
92        if (verboseLevel>0) G4cout << "kSwitch" << endl;
93   }  
94   return proposedStep;
95 }
96
97 G4VParticleChange* TG4SpecialFlags::PostStepDoIt(
98                       const G4Track& track, const G4Step& step)
99 {
100 // Changes processes activation of the current track
101 // according to the current user limits.
102 // ---
103
104   TG4Limits* limits 
105     = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
106
107   G4ProcessManager* processManager
108     = track.GetDefinition()->GetProcessManager();
109   G4ProcessVector* processVector = processManager->GetProcessList();
110   // processManager->DumpInfo();
111
112   if ((fSwitchFlags==kUnswitch) || (fSwitchFlags==kReswitch)) {
113     // set processes activation back
114     for (G4int i=0; i<fSwitchedProcesses.entries(); i++) {
115       if (verboseLevel>0) {
116         G4cout << "Reset process activation back in" 
117                << track.GetVolume()->GetName() 
118                << endl;
119       }
120       processManager
121         ->SetProcessActivation(fSwitchedProcesses[i],fSwitchedFlags[i]);
122     }
123     fSwitchedProcesses.clear();
124     fSwitchedFlags.clear();
125   }
126
127   if ((fSwitchFlags==kSwitch) ||  (fSwitchFlags==kReswitch)) {
128     // set TG4Limits processes flags
129     for (G4int i=0; i<processManager->GetProcessListLength(); i++) {
130       G4int flag = limits->GetFlag((*processVector)[i]);
131       if (flag != kUnset) {
132         // store the current processes flags;
133         fSwitchedProcesses.insert((*processVector)[i]);
134         //fSwitchedFlags.insert(processManager->GetProcessActivation(i));
135         fSwitchedFlags.push_back(processManager->GetProcessActivation(i));
136         if (flag == kInActivate) {
137           if (verboseLevel>0) {
138             G4cout << "Set process inactivation for " 
139                    << (*processVector)[i]->GetProcessName() << " in " 
140                    << track.GetVolume()->GetName() 
141                    << endl;
142           }
143           processManager->SetProcessActivation(i,false);
144         }  
145         else {
146           // ((flag == kActivate) || (flag == kActivate2)) 
147           if (verboseLevel>0) {
148             G4cout << "Set process activation for " 
149                    << (*processVector)[i]->GetProcessName() << " in " 
150                    << track.GetVolume()->GetName() 
151                    << endl;
152           }
153           processManager->SetProcessActivation(i,true);
154         }
155       }  
156     }
157   }  
158   // processManager->DumpInfo();        
159   aParticleChange.Initialize(track);
160   aParticleChange.SetStatusChange(fAlive);
161   return &aParticleChange;
162 }
163