]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4SpecialControls.cxx
Format() method added; changed Print() - usage of Format()
[u/mrichter/AliRoot.git] / TGeant4 / TG4SpecialControls.cxx
1 // $Id$ //
2 // Category: physics
3 //
4 // Author: I. Hrivnacova
5 //
6 // Class TG4VSpecialControls
7 // -------------------------
8 // See the class description in the header file.
9
10 #include "TG4SpecialControls.h"
11 #include "TG4GeometryServices.h"
12 #include "TG4Limits.h"
13
14 #include <G4StepStatus.hh>
15 #include <G4ProcessManager.hh>
16 #include <G4ProcessVector.hh>
17
18 //_____________________________________________________________________________
19 TG4SpecialControls::TG4SpecialControls(const G4String& processName)
20   : G4VProcess(processName),
21     TG4Verbose("specialControls"),
22     fSwitchControls(kUnswitch),
23     fLastTrackID(0) {
24 //    
25    verboseLevel = VerboseLevel();
26    if (VerboseLevel() >0 ) {
27      G4cout << GetProcessName() << " is created "<< G4endl;
28    }
29 }
30
31 //_____________________________________________________________________________
32 TG4SpecialControls::TG4SpecialControls(const TG4SpecialControls& right)     
33   : TG4Verbose("specialControls") {
34 // 
35   TG4Globals::Exception(
36     "TG4SpecialControls is protected from copying.");
37 }
38
39 //_____________________________________________________________________________
40 TG4SpecialControls::~TG4SpecialControls() {
41 //
42 }
43
44 // operators
45
46 //_____________________________________________________________________________
47 TG4SpecialControls& TG4SpecialControls::operator=(
48                                           const TG4SpecialControls& right)
49 {
50   // check assignement to self
51   if (this == &right) return *this;
52
53   TG4Globals::Exception(
54     "TG4SpecialControls is protected from assigning.");
55     
56   return *this;  
57
58
59 // private methods   
60
61 //_____________________________________________________________________________
62 void TG4SpecialControls::Reset()
63 {
64 // Resets the buffers to the initial state.
65 // ---
66                         
67   fSwitchControls = kUnswitch;
68
69   // clear buffers
70   fSwitchedProcesses.clear();
71   fSwitchedControls.clear();
72 }
73
74 // public methods   
75           
76 //_____________________________________________________________________________
77 G4double TG4SpecialControls::PostStepGetPhysicalInteractionLength(
78                            const G4Track& track, G4double previousStepSize,
79                            G4ForceCondition* condition)
80 {
81 // Returns the Step-size (actual length) which is allowed 
82 // by this process.
83 // ---
84
85   *condition = NotForced;
86
87   if (track.GetTrackID() != fLastTrackID) {
88     // new track
89     Reset();
90     fLastTrackID = track.GetTrackID();
91   }  
92
93   G4double proposedStep = DBL_MAX;
94   //G4double minStep = (1.0e-9)*m;
95   G4double minStep = 0.;
96     // must be greater than DBL_MIN - so that particle can get out of
97     // the boundary 
98     // proposedStep = 0.; causes navigator to fall into panic 
99   
100   G4StepStatus status     
101     = track.GetStep()->GetPreStepPoint()->GetStepStatus();
102
103   // get limits
104 #ifdef TGEANT4_DEBUG
105   TG4Limits* limits 
106      = TG4GeometryServices::Instance()
107          ->GetLimits(track.GetVolume()->GetLogicalVolume()->GetUserLimits()); 
108
109   if (!limits) {
110     G4String text = "TG4VSpecialControls::PostStepGetPhysicalInteractionLength:\n";
111     text = text + "    " + track.GetVolume()->GetLogicalVolume()->GetName();
112     text = text + " has not limits.";
113     TG4Globals::Exception(text);
114   }  
115 #else  
116   TG4Limits* limits 
117     = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
118 #endif    
119
120   if (fSwitchControls != kUnswitch) {
121     if (status == fGeomBoundary) {
122       if  (limits->IsControl()) {
123         // particle is exiting a logical volume with special controls
124         // and entering another logical volume with special controls 
125         proposedStep = minStep;
126         fSwitchControls = kReswitch;
127         if (VerboseLevel() > 1) { 
128           G4cout << "kReswitch" << G4endl;
129         }  
130       }
131       else {
132         // particle is exiting a logical volume with special controls
133         // and entering a logical volume without special controls 
134         proposedStep = minStep;
135         fSwitchControls = kUnswitch;
136         if (VerboseLevel() > 1) { 
137           G4cout << "kUnswitch" << G4endl;
138         }  
139       }
140     }
141   }
142   else if (limits->IsControl()) {
143        // particle is entering a logical volume with special controls
144        // that have not yet been set
145        proposedStep = minStep;
146        fSwitchControls = kSwitch;
147        if (VerboseLevel() > 1) { 
148          G4cout << "kSwitch" << G4endl;
149        }         
150   }  
151   return proposedStep;
152 }
153
154 //_____________________________________________________________________________
155 G4VParticleChange* TG4SpecialControls::PostStepDoIt(
156                       const G4Track& track, const G4Step& step)
157 {
158 // Changes processes activation of the current track
159 // according to the current user limits.
160 // ---
161
162   G4ProcessManager* processManager
163     = track.GetDefinition()->GetProcessManager();
164   G4ProcessVector* processVector = processManager->GetProcessList();
165
166   if ((fSwitchControls==kUnswitch) || (fSwitchControls==kReswitch)) {
167   
168     // set processes activation back
169     for (G4int i=0; i<fSwitchedProcesses.length(); i++) {
170       if (VerboseLevel() > 1) {
171         G4cout << "Reset process activation back in " 
172                << track.GetVolume()->GetName() 
173                << G4endl;
174       }
175       processManager
176         ->SetProcessActivation(fSwitchedProcesses[i],fSwitchedControls[i]);
177     }
178     fSwitchedProcesses.clear();
179     fSwitchedControls.clear();
180   }
181
182   if ((fSwitchControls==kSwitch) ||  (fSwitchControls==kReswitch)) {
183
184     // set TG4Limits processes controls
185     TG4Limits* limits 
186     = (TG4Limits*) track.GetVolume()->GetLogicalVolume()->GetUserLimits();
187
188     for (G4int i=0; i<processVector->length(); i++) {
189
190       TG4G3ControlValue control = limits->GetControl((*processVector)[i]);
191       G4bool activation = processManager->GetProcessActivation(i);
192
193       if (control != kUnset && ! TG4Globals::Compare(activation, control)) {
194
195         // store the current processes controls
196         if (VerboseLevel() > 1) {
197           G4cout << "Something goes to fSwitchedProcesses" << G4endl;
198         }  
199         fSwitchedProcesses.insert((*processVector)[i]);
200         fSwitchedControls.push_back(activation);
201
202         // set new process activation
203         if (control == kInActivate) {
204           if (VerboseLevel() > 1) {
205             G4cout << "Set process inactivation for " 
206                    << (*processVector)[i]->GetProcessName() << " in " 
207                    << track.GetVolume()->GetName() 
208                    << G4endl;
209           }
210           processManager->SetProcessActivation(i,false);
211         }  
212         else {
213           // ((control == kActivate) || (control == kActivate2)) 
214           if (VerboseLevel() > 1) {
215             G4cout << "Set process activation for " 
216                    << (*processVector)[i]->GetProcessName() << " in " 
217                    << track.GetVolume()->GetName() 
218                    << G4endl;
219           }
220           processManager->SetProcessActivation(i,true);
221         }
222       }  
223     }
224   }
225     
226   // processManager->DumpInfo();        
227   aParticleChange.Initialize(track);
228   aParticleChange.SetStatusChange(fAlive);
229   return &aParticleChange;
230 }
231