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