ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4BlineTracer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4BlineTracer.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
28 //
29 //
30 //
31 //
32 // --------------------------------------------------------------------
33 //
34 // G4BlineTracer implementation
35 //
36 // --------------------------------------------------------------------
37 // Author: Laurent Desorgher (desorgher@phim.unibe.ch)
38 // Created - 2003-10-06
39 // --------------------------------------------------------------------
40 
41 #include "G4BlineTracer.hh"
44 #include "G4BlineEventAction.hh"
45 #include "G4BlineSteppingAction.hh"
46 #include "G4BlineEquation.hh"
47 
48 #include "G4RunManager.hh"
50 #include "G4FieldManager.hh"
51 #include "G4PropagatorInField.hh"
52 #include "G4MagIntegratorDriver.hh"
53 #include "G4CashKarpRKF45.hh"
54 #include "G4LogicalVolumeStore.hh"
55 #include "G4ChordFinder.hh"
56 #include "G4SystemOfUnits.hh"
57 
59 
61 {
64  fEventAction = new G4BlineEventAction(this);
66  fMaxTrackingStep =1000.*m;
68 }
69 
71 
73 {
74  delete fMessenger;
75  delete fSteppingAction;
76  delete fEventAction;
78  for (size_t i=0; i< fVecEquationOfMotion.size();i++)
79  {
81  if (fVecChordFinders[i]) delete fVecChordFinders[i];
82  }
83 }
84 
86 
88 {
89 }
90 
92 
94 {
95 }
96 
98 
100 {
101  //the first time ResetChordFinders should be called
102  //
104  {
107  }
108 
109  // Replace the user action by the ad-hoc actions for Blines
110 
111  G4RunManager* theRunManager = G4RunManager::GetRunManager();
112  G4UserRunAction* user_run_action =
113  (G4UserRunAction*)theRunManager->GetUserRunAction();
114  theRunManager->SetUserAction(this);
115 
116  G4UserSteppingAction* user_stepping_action =
117  (G4UserSteppingAction*)theRunManager->GetUserSteppingAction();
118  theRunManager->SetUserAction(fSteppingAction);
119 
120  G4VUserPrimaryGeneratorAction* userPrimaryAction =
122  if (userPrimaryAction)
123  fPrimaryGeneratorAction->SetUserPrimaryAction(userPrimaryAction);
124  theRunManager->SetUserAction(fPrimaryGeneratorAction);
125 
126  G4UserEventAction* user_event_action =
127  (G4UserEventAction*)theRunManager->GetUserEventAction();
128  theRunManager->SetUserAction(fEventAction);
129 
130  G4UserTrackingAction* user_tracking_action =
131  (G4UserTrackingAction*)theRunManager->GetUserTrackingAction();
132  G4UserTrackingAction* aNullTrackingAction = 0;
133  theRunManager->SetUserAction(aNullTrackingAction);
134 
135  G4UserStackingAction* user_stacking_action =
136  (G4UserStackingAction*)theRunManager->GetUserStackingAction();
137  G4UserStackingAction* aNullStackingAction = 0;
138  theRunManager->SetUserAction(aNullStackingAction);
139 
140  // replace the user defined chordfinder by the element of fVecChordFinders
141 
142  std::vector<G4ChordFinder*> user_chord_finders;
143  std::vector<G4double> user_largest_acceptable_step;
144  for (size_t i=0;i<fVecChordFinders.size();i++)
145  {
146  user_largest_acceptable_step.push_back(-1.);
147  if (fVecChordFinders[i])
148  {
149  user_chord_finders.push_back(fVecFieldManagers[i]->GetChordFinder());
150  fVecChordFinders[i]->SetDeltaChord(user_chord_finders[i]->GetDeltaChord());
151  fVecFieldManagers[i]->SetChordFinder(fVecChordFinders[i]);
152  }
153  else user_chord_finders.push_back(0);
154  }
155 
156  // I have tried to use the smooth line filter ability but I could not obtain
157  // a smooth trajectory in the G4TrajectoryContainer after an event
158  // Another solution for obtaining a smooth trajectory is to limit
159  // the LargestAcceptableStep in the G4PropagatorInField object.
160  // This is the solution I used.
161 
162  // Old solution:
163  // G4TransportationManager::GetTransportationManager()
164  // ->GetPropagatorInField()->SetTrajectoryFilter(fTrajectoryFilter);
165 
166  // New solution:
167  // set the largest_acceptable_step to max_step:length
168 
169  G4TransportationManager* tmanager =
171  G4double previous_largest_acceptable_step =
173 
174  tmanager->GetPropagatorInField()
176 
177  // Start the integration of n_of_lines different magnetic field lines
178 
179  for (G4int il=0; il<n_of_lines;il++)
180  {
181  // for each magnetic field line we integrate once backward and once
182  // forward from the same starting point
183 
184  // backward integration
185 
186  for (size_t i=0; i< fVecEquationOfMotion.size();i++)
187  {
188  if (fVecEquationOfMotion[i])
189  fVecEquationOfMotion[i]->SetBackwardDirectionOfIntegration(true);
190  }
191  theRunManager->BeamOn(1);
192 
193  // forward integration
194 
195  for (size_t i=0; i < fVecEquationOfMotion.size();i++)
196  {
197  if (fVecEquationOfMotion[i])
198  fVecEquationOfMotion[i]->SetBackwardDirectionOfIntegration(false);
199  }
200  theRunManager->BeamOn(1);
201  }
202 
203  // Remove trajectory filter to PropagatorInField
204  // It was for old solution when using smooth trajectory filter
205 
206  // tmanager->GetPropagatorInField()->SetTrajectoryFilter(0);
207 
208  // back to User defined actions and other parameters
209  // -------------------------------------------------
210 
211  tmanager->GetPropagatorInField()
212  ->SetLargestAcceptableStep(previous_largest_acceptable_step);
213 
214  // return to User actions
215 
216  theRunManager->SetUserAction(user_run_action);
217  theRunManager->SetUserAction(user_event_action);
218  theRunManager->SetUserAction(userPrimaryAction);
219  theRunManager->SetUserAction(user_stepping_action);
220  theRunManager->SetUserAction(user_tracking_action);
221  theRunManager->SetUserAction(user_stacking_action);
222 
223  // set user defined chord finders and largest acceptable step
224 
225  for (size_t i=0;i<fVecFieldManagers.size();i++)
226  {
227  if (user_chord_finders[i])
228  fVecFieldManagers[i]->SetChordFinder(user_chord_finders[i]);
229  }
230 }
231 
233 
234 /*
235 G4bool G4BlineTracer::CheckMagneticFields()
236 {
237  // Check FieldManagers
238 
239  G4TransportationManager* tmanager =
240  G4TransportationManager::GetTransportationManager();
241 
242  if (fVecFieldManagers[0] != tmanager->GetFieldManager())
243  return false;
244  if (fVecMagneticFields[0] != tmanager->GetFieldManager()->GetDetectorField())
245  return false;
246  G4LogicalVolumeStore* theVolumeStore = G4LogicalVolumeStore::GetInstance();
247 
248  std::vector<G4FieldManagers*> LogicalVolumeFields;
249  size_t j=0;
250  for (size_t i=0; i<theVolumeStore.size();i++)
251  {
252  if (theVolumeStore[i]->GetFieldManager())
253  {
254  j++;
255  if (j >= fVecFieldManagers.size()) return false;
256  if (fVecFieldManagers[j] != theVolumeStore[i]->GetFieldManager())
257  return false;
258  if (fVecMagneticFields[j] !=
259  theVolumeStore[i]->GetFieldManager()->GetDetectorField())
260  return false;
261  }
262  }
263  if (j<fVecFieldManagers.size()) return false;
264 
265  return true;
266 }
267 */
268 
270 
272 {
273  for (size_t i=0; i<fVecEquationOfMotion.size();i++)
274  {
275  delete fVecEquationOfMotion[i];
276  delete fVecChordFinders[i];
277  }
278 
279  fVecChordFinders.clear();
280  fVecFieldManagers.clear();
281  fVecMagneticFields.clear();
282  fVecEquationOfMotion.clear();
283 
284  // global field
285 
286  fVecChordFinders.push_back(0);
287  fVecMagneticFields.push_back(0);
288  fVecEquationOfMotion.push_back(0);
290  ->GetFieldManager());
291  if (fVecFieldManagers[0])
292  {
293  fVecMagneticFields[0] =
294  (G4MagneticField*) fVecFieldManagers[0]->GetDetectorField();
295  if (fVecMagneticFields[0])
296  {
299  G4MagInt_Driver* pIntgrDriver =
300  new G4MagInt_Driver(0.01*mm,pStepper,pStepper->GetNumberOfVariables());
301  fVecChordFinders[0] = new G4ChordFinder(pIntgrDriver);
302  }
303  }
304 
305  // local fields
306 
308 
309  size_t j=0;
310  for (size_t i=0; i<theVolumeStore->size();i++)
311  {
312  if ((*theVolumeStore)[i]->GetFieldManager())
313  {
314  j++;
315  fVecFieldManagers.push_back(((*theVolumeStore)[i])->GetFieldManager());
317  fVecFieldManagers[j]->GetDetectorField());
318  fVecEquationOfMotion.push_back(0);
319  fVecChordFinders.push_back(0);
320  if (fVecMagneticFields[j])
321  {
324  G4MagInt_Driver* pIntgrDriver =
325  new G4MagInt_Driver(.01*mm,pStepper,pStepper->GetNumberOfVariables());
326  fVecChordFinders[j] = new G4ChordFinder(pIntgrDriver);
327  }
328  }
329  }
330 }