Geant4  10.01.p02
G4DNAChemistryManager.cc
Go to the documentation of this file.
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 //
26 // $Id: G4DNAChemistryManager.cc 90900 2015-06-11 08:06:17Z gcosmo $
27 //
28 // Author: Mathieu Karamitros (kara@cenbg.in2p3.fr)
29 //
30 // WARNING : This class is released as a prototype.
31 // It might strongly evolve or even disapear in the next releases.
32 //
33 // History:
34 // -----------
35 // 10 Oct 2011 M.Karamitros created
36 //
37 // -------------------------------------------------------------------
38 
39 #include "G4DNAChemistryManager.hh"
40 
41 #include "G4Scheduler.hh"
42 #include "G4SystemOfUnits.hh"
43 #include "G4Molecule.hh"
44 #include "G4VITTrackHolder.hh"
45 #include "G4H2O.hh"
49 #include "G4Electron_aq.hh"
51 #include "G4MoleculeCounter.hh"
52 #include "G4VUserChemistryList.hh"
53 #include "G4AutoLock.hh"
54 #include "G4UIcmdWithABool.hh"
56 #include "G4GeometryManager.hh"
57 #include "G4StateManager.hh"
58 #include "G4MoleculeFinder.hh"
59 
60 using namespace std;
61 
66 //bool G4DNAChemistryManager::fActiveChemistry = false;
67 
70 {
71 //==============================================================================
72 /* M.K: 24/11/2014
73  * To work properly, the chemistry manager should be created and initialized on
74  * the master thread only. If the static flag fActiveChemistry is on but the
75  * chemistry manager singleton
76  */
77 //==============================================================================
78 
79 // if (/*fActiveChemistry &&*/ G4Threading::IsWorkerThread()
80 // && G4Threading::IsMultithreadedApplication())
81 // {
82 // G4Exception("G4DNAChemistryManager::G4DNAChemistryManager",
83 // "G4DNAChemistryManager_MASTER_CREATION", FatalException,
84 // "The chemistry manager should be created and initialized on the "
85 // "master thread only");
86 // }
87 
90  fWriteFile = false;
92  fMasterInitialized = false;
93  fpChemDNADirectory = new G4UIdirectory("/process/em/dna/chem/");
94  fpActivateChem = new G4UIcmdWithABool("/process/em/dna/chem/activate", this);
95  fpRunChem = new G4UIcmdWithoutParameter("/process/em/dna/chem/run", this);
96  fBuildPhysicsTable = false;
97  fGeometryClosed = false;
98  fPhysicsTableBuilt = false;
100  fFileInitialized = false;
101  fVerbose = 0;
102  fActiveChemistry = false;
103 }
104 
107 {
108  if (fgInstance == 0)
109  {
111  if (fgInstance == 0) // MT : double check at initialisation
112  {
114  }
115  lock.unlock();
116  }
117  return fgInstance;
118 }
119 
122 {
123  return fgInstance;
124 }
125 
127 {
128 // G4cout << "Deleting G4DNAChemistryManager" << G4endl;
129  Clear();
130  fgInstance = 0;
131  /*
132  * DEBUG : check that the chemistry manager has well been deregistered
133  * assert(G4StateManager::GetStateManager()->
134  * DeregisterDependent(this) == true);
135  */
136 }
137 
139 {
140  if (fpIonisationLevel)
141  {
142  delete fpIonisationLevel;
143  fpIonisationLevel = 0;
144 
145  }
146  if (fpExcitationLevel)
147  {
148  delete fpExcitationLevel;
149  fpExcitationLevel = 0;
150  }
152  {
154  {
155  delete fpUserChemistryList;
156  }
157 // else
158 // {
159 // G4cout << "G4DNAChemistryManager will not delete the chemistry list "
160 // "since it inherits from G4VPhysicsConstructor and it is then "
161 // "expected to be the responsability to the G4VModularPhysics to handle"
162 // " the chemistry list." << G4endl;
163 // }
165  }
166 
167  if (fpChemDNADirectory)
168  {
169  delete fpChemDNADirectory;
170  fpChemDNADirectory = 0;
171  }
172  if (fpActivateChem)
173  {
174  delete fpActivateChem;
175  fpActivateChem = 0;
176  }
177 
178  if(fpRunChem)
179  {
180  delete fpRunChem;
181  fpRunChem = 0;
182  }
183 
185  //G4MoleculeHandleManager::DeleteInstance();
188 }
189 
191 {
192  //G4cout << "G4DNAChemistryManager::DeleteInstance" << G4endl;
193 
195 
196  if(fgInstance)
197  {
198  G4DNAChemistryManager* deleteMe = fgInstance;
199  fgInstance = 0;
200  lock.unlock();
201  delete deleteMe;
202  }
203  else
204  {
205  G4cout << "G4DNAChemistryManager already deleted" << G4endl;
206  }
207  lock.unlock();
208 }
209 
211 {
212  if (requestedState == G4State_Quit)
213  {
214  if(fVerbose)
215  G4cout << "G4DNAChemistryManager::Notify ---> received G4State_Quit"
216  << G4endl;
217  //DeleteInstance();
218  Clear();
219  }
220 
221  else if(requestedState == G4State_GeomClosed)
222  {
223  fGeometryClosed = true;
224  }
225 
226  return true;
227 }
228 
230 {
231  if (command == fpActivateChem)
232  {
234  }
235  else if (command == fpRunChem)
236  {
237  Run();
238  }
239 }
240 
242 {
243  if (command == fpActivateChem)
244  {
246  }
247 
248  return "";
249 }
250 
252 {
253  if (fActiveChemistry)
254  {
256 
257  if (fMasterInitialized == false)
258  {
259  G4ExceptionDescription description;
260  description << "Global components were not initialized.";
261  G4Exception("G4DNAChemistryManager::Run", "MASTER_INIT", FatalException,
262  description);
263  }
264 
265  if (fpgThreadInitialized_tl == 0)
266  {
267  G4ExceptionDescription description;
268  description << "Thread local components were not initialized.";
269  G4Exception("G4DNAChemistryManager::Run", "THREAD_INIT", FatalException,
270  description);
271  }
272 
274  CloseFile();
275  }
276 }
277 
278 void G4DNAChemistryManager::Gun(G4ITGun* gun, bool physicsTableToBuild)
279 {
280  fBuildPhysicsTable = physicsTableToBuild;
282 }
283 
285 {
286  //===========================================================================
287  // MT MODE
288  //===========================================================================
290  {
291  //==========================================================================
292  // ON WORKER THREAD
293  //==========================================================================
295  {
296  InitializeThread(); // Will create and initialize G4ITScheduler
297  return;
298  }
299  //==========================================================================
300  // ON MASTER THREAD
301  //==========================================================================
302  else
303  {
305  return;
306  }
307  }
308  //===========================================================================
309  // IS NOT IN MT MODE
310  //===========================================================================
311  else
312  {
314  // In this case: InitializeThread is called when Run() is called
315  return;
316  }
317 
318 }
319 
321 {
322  if (fMasterInitialized == false)
323  {
324  if(fVerbose)
325  {
326  G4cout << "G4DNAChemistryManager::InitializeMaster() is called" << G4endl;
327  }
328 
330  // creates a concrete object of the scheduler
331  // and track container
332 
334  {
338  fMasterInitialized = true;
339  }
340  else
341  {
342  if (fActiveChemistry)
343  {
344  G4ExceptionDescription description;
345  description << "No user chemistry list has been provided.";
346  G4Exception("G4DNAChemistryManager::InitializeMaster", "NO_CHEM_LIST",
347  FatalException, description);
348  }
349  }
350  }
351 }
352 
354 {
356  {
358  {
359  if(fVerbose)
360  {
361  G4cout << "G4DNAChemistryManager::InitializeThread() is called"
362  << G4endl;
363  }
364 
365  if (fBuildPhysicsTable && fPhysicsTableBuilt == false)
366  {
367  if(fVerbose)
368  {
369  G4cout << "G4DNAChemistryManager: Build the physics tables for "
370  "molecules."
371  << G4endl;
372  }
373 
375  if (fGeometryClosed == false)
376  {
377  if(fVerbose)
378  {
379  G4cout << "G4DNAChemistryManager: Close geometry"
380  << G4endl;
381  }
382 
384  // G4cout << "Start closing geometry." << G4endl;
385  geomManager->OpenGeometry();
386  geomManager->CloseGeometry(true, true);
387  fGeometryClosed = true;
388  }
389 
390  fPhysicsTableBuilt = true;
391  }
395 
396  fpgThreadInitialized_tl = new G4bool(true);
397  }
398  else
399  {
400  G4ExceptionDescription description;
401  description << "No user chemistry list has been provided.";
402  G4Exception("G4DNAChemistryManager::InitializeThread", "NO_CHEM_LIST",
403  FatalException, description);
404  }
405 
407  }
408 
409  InitializeFile();
410 }
411 
413 {
414  if (fpgOutput_tl == 0 || fWriteFile == false || fFileInitialized)
415  {
416  return;
417  }
418 
419  if(fVerbose)
420  {
421  G4cout << "G4DNAChemistryManager::InitializeFile() is called"
422  << G4endl;
423  }
424 
425  *fpgOutput_tl << std::setprecision(6) << std::scientific;
426  *fpgOutput_tl << setw(11) << left << "#Parent ID" << setw(10) << "Molecule"
427  << setw(14) << "Elec Modif" << setw(13) << "Energy (eV)"
428  << setw(22) << "X pos of parent [nm]" << setw(22)
429  << "Y pos of parent [nm]" << setw(22) << "Z pos of parent [nm]"
430  << setw(14) << "X pos [nm]" << setw(14) << "Y pos [nm]"
431  << setw(14) << "Z pos [nm]" << G4endl<< setw(21) << "#"
432  << setw(13) << "1)io/ex=0/1"
433  << G4endl
434  << setw(21) << "#"
435  << setw(13) << "2)level=0...5"
436  << G4endl;
437 
438  fFileInitialized = true;
439 }
440 
442 {
443  return Instance()->fActiveChemistry;
444 }
445 
447 {
448  Instance()->fActiveChemistry = flag;
449 }
450 
452 {
453  return fActiveChemistry;
454 }
455 
457 {
458  fActiveChemistry = flag;
459 }
460 
462  ios_base::openmode mode)
463 {
464  if (fVerbose)
465  {
466  G4cout << "G4DNAChemistryManager: Write chemical stage into "
467  << output.data() << G4endl;
468  }
469 
470  fpgOutput_tl = new std::ofstream();
471  fpgOutput_tl->open(output.data(), mode);
472  fWriteFile = true;
473  fFileInitialized = false;
474 }
475 
477 {
478  if (fWriteFile)
479  {
480  *fpgOutput_tl << G4endl;
481  }
482 }
483 
485 {
486  if (fpgOutput_tl == 0) return;
487 
488  if (fpgOutput_tl->is_open())
489  {
490  if (fVerbose)
491  {
492  G4cout << "G4DNAChemistryManager: Close File" << G4endl;
493  }
494  fpgOutput_tl->close();
495  }
496 }
497 
500 {
501  if (!fpExcitationLevel)
502  {
504  }
505  return fpExcitationLevel;
506 }
507 
510 {
511  if (!fpIonisationLevel)
512  {
514  }
515  return fpIonisationLevel;
516 }
517 
519  G4int electronicLevel,
520  const G4Track* theIncomingTrack)
521 {
522  if (fWriteFile)
523  {
525 
526  G4double energy = -1.;
527 
528  switch (modification)
529  {
531  energy = 0;
532  break;
533  case eExcitedMolecule:
534  energy = GetExcitationLevel()->ExcitationEnergy(electronicLevel);
535  break;
536  case eIonizedMolecule:
537  energy = GetIonisationLevel()->IonisationEnergy(electronicLevel);
538  break;
539  }
540 
541  *fpgOutput_tl << setw(11) << left << theIncomingTrack->GetTrackID()
542  << setw(10) << "H2O" << left << modification << internal
543  << ":" << right << electronicLevel << left << setw(11) << ""
544  << std::setprecision(2) << std::fixed << setw(13)
545  << energy / eV << std::setprecision(6) << std::scientific
546  << setw(22)
547  << (theIncomingTrack->GetPosition().x()) / nanometer
548  << setw(22)
549  << (theIncomingTrack->GetPosition().y()) / nanometer
550  << setw(22)
551  << (theIncomingTrack->GetPosition().z()) / nanometer
552  << G4endl;
553  }
554 
555  if(fActiveChemistry)
556  {
557  G4Molecule * H2O = new G4Molecule (G4H2O::Definition());
558 
559  switch (modification)
560  {
562  H2O -> AddElectron(5,1);
563  break;
564  case eExcitedMolecule :
565  H2O -> ExciteMolecule(electronicLevel);
566  break;
567  case eIonizedMolecule :
568  H2O -> IonizeMolecule(electronicLevel);
569  break;
570  }
571 
572  G4Track * H2OTrack = H2O->BuildTrack(1*picosecond,
573  theIncomingTrack->GetPosition());
574 
575  H2OTrack -> SetParentID(theIncomingTrack->GetTrackID());
576  H2OTrack -> SetTrackStatus(fStopButAlive);
577  H2OTrack -> SetKineticEnergy(0.);
578  G4VITTrackHolder::Instance()->Push(H2OTrack);
579  }
580 // else
581 // abort();
582 }
583 
585  G4ThreeVector* finalPosition)
586 // finalPosition is a pointer because this argument is optional
587 {
588  if (fWriteFile)
589  {
591 
592  *fpgOutput_tl << setw(11) << theIncomingTrack->GetTrackID() << setw(10)
593  << "e_aq" << setw(14) << -1 << std::setprecision(2)
594  << std::fixed << setw(13)
595  << theIncomingTrack->GetKineticEnergy() / eV
596  << std::setprecision(6) << std::scientific << setw(22)
597  << (theIncomingTrack->GetPosition().x()) / nanometer
598  << setw(22)
599  << (theIncomingTrack->GetPosition().y()) / nanometer
600  << setw(22)
601  << (theIncomingTrack->GetPosition().z()) / nanometer;
602 
603  if (finalPosition != 0)
604  {
605  *fpgOutput_tl << setw(14) << (finalPosition->x()) / nanometer << setw(14)
606  << (finalPosition->y()) / nanometer << setw(14)
607  << (finalPosition->z()) / nanometer;
608  }
609 
610  *fpgOutput_tl << G4endl;
611  }
612 
613  if(fActiveChemistry)
614  {
616  G4Track * e_aqTrack(0);
617  if(finalPosition)
618  {
619  e_aqTrack = e_aq->BuildTrack(picosecond,*finalPosition);
620  }
621  else
622  {
623  e_aqTrack = e_aq->BuildTrack(picosecond,theIncomingTrack->GetPosition());
624  }
625  e_aqTrack -> SetTrackStatus(fAlive);
626  e_aqTrack -> SetParentID(theIncomingTrack->GetTrackID());
627  G4VITTrackHolder::Instance()->Push(e_aqTrack);
628  }
629 }
630 
632  double time,
633  const G4ThreeVector& position,
634  int parentID)
635 {
636  if (fWriteFile)
637  {
639 
640  *fpgOutput_tl << setw(11) << parentID << setw(10) << molecule->GetName()
641  << setw(14) << -1 << std::setprecision(2) << std::fixed
642  << setw(13) << -1 << std::setprecision(6) << std::scientific
643  << setw(22) << (position.x()) / nanometer << setw(22)
644  << (position.y()) / nanometer << setw(22)
645  << (position.z()) / nanometer;
646  *fpgOutput_tl << G4endl;
647  }
648 
649  if(fActiveChemistry)
650  {
651  G4Track* track = molecule->BuildTrack(time,position);
652  track -> SetTrackStatus(fAlive);
653  track -> SetParentID(parentID);
655  }
656  else
657  {
658  delete molecule;
659  molecule = 0;
660  }
661 }
662 
664  const G4Track* theIncomingTrack)
665 {
666  if (fWriteFile)
667  {
669 
670  *fpgOutput_tl << setw(11) << theIncomingTrack->GetTrackID() << setw(10)
671  << molecule->GetName() << setw(14) << -1
672  << std::setprecision(2) << std::fixed << setw(13)
673  << theIncomingTrack->GetKineticEnergy() / eV
674  << std::setprecision(6) << std::scientific << setw(22)
675  << (theIncomingTrack->GetPosition().x()) / nanometer
676  << setw(22)
677  << (theIncomingTrack->GetPosition().y()) / nanometer
678  << setw(22)
679  << (theIncomingTrack->GetPosition().z()) / nanometer;
680  *fpgOutput_tl << G4endl;
681  }
682 
683  if(fActiveChemistry)
684  {
685  G4Track* track = molecule->BuildTrack(theIncomingTrack->GetGlobalTime(),
686  theIncomingTrack->GetPosition());
687  track -> SetTrackStatus(fAlive);
688  track -> SetParentID(theIncomingTrack->GetTrackID());
690  }
691  else
692  {
693  delete molecule;
694  molecule = 0;
695  }
696 }
void WriteInto(const G4String &, std::ios_base::openmode mode=std::ios_base::out)
Tells the chemMan to write into a file the position and electronic state of the water molecule and th...
void Process()
Definition: G4Scheduler.cc:363
static G4VITTrackHolder * Instance()
void PushMoleculeAtParentTimeAndPlace(G4Molecule *&molecule, const G4Track *)
WARNING : In case chemistry is not activated, PushMoleculeAtParentTimeAndPlace will take care of dele...
virtual void ConstructReactionTable(G4DNAMolecularReactionTable *reactionTable)=0
static G4Electron_aq * Definition()
static G4H2O * Definition()
Definition: G4H2O.cc:46
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
CLHEP::Hep3Vector G4ThreeVector
virtual bool IsPhysicsConstructor()
void CreateSolvatedElectron(const G4Track *, G4ThreeVector *finalPosition=0)
On the same idea as the previous method but for solvated electron.
static const double nanometer
Definition: G4SIunits.hh:91
WARNING: THIS CLASS IS A PROTOTYPE G4DNAChemistryManager is called from the physics models...
const G4ThreeVector & GetPosition() const
virtual void Push(G4Track *)
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:371
G4DNAWaterIonisationStructure * fpIonisationLevel
ElectronicModification
#define G4ThreadLocal
Definition: tls.hh:89
int G4int
Definition: G4Types.hh:78
static G4Scheduler * Instance()
Definition: G4Scheduler.cc:118
static G4bool GetNewBoolValue(const char *paramString)
static G4DNAMolecularReactionTable * GetReactionTable()
G4DNAWaterExcitationStructure * GetExcitationLevel()
const G4String & GetName() const
Returns the name of the molecule.
Definition: G4Molecule.cc:303
G4Mutex chemManExistence
static G4DNAChemistryManager * fgInstance
G4double GetKineticEnergy() const
#define position
Definition: xmlparse.cc:605
G4GLOB_DLL std::ostream G4cout
virtual G4bool Notify(G4ApplicationState requestedState)
virtual void SetNewValue(G4UIcommand *, G4String)
G4VUserChemistryList * fpUserChemistryList
void PushMolecule(G4Molecule *&molecule, double time, const G4ThreeVector &position, int parentID)
WARNING : In case chemistry is not activated, PushMolecule will take care of deleting the transfered ...
bool G4bool
Definition: G4Types.hh:79
void SetGun(G4ITGun *)
Definition: G4Scheduler.hh:416
virtual void ConstructDissociationChannels()
static void DeleteInstance()
You should rather use DeleteInstance than the destructor of this class.
G4int GetTrackID() const
G4double GetGlobalTime() const
static G4GeometryManager * GetInstance()
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:134
virtual G4String GetCurrentValue(G4UIcommand *command)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool IsWorkerThread()
Definition: G4Threading.cc:128
G4Track * BuildTrack(G4double globalTime, const G4ThreeVector &Position)
Definition: G4Molecule.cc:328
const char * data() const
static G4DNAChemistryManager * Instance()
static const double eV
Definition: G4SIunits.hh:194
G4UIcmdWithoutParameter * fpRunChem
G4int G4Mutex
Definition: G4Threading.hh:173
G4DNAWaterExcitationStructure * fpExcitationLevel
G4double energy(const ThreeVector &p, const G4double m)
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
Method used by DNA physics model to create a water molecule.
void CloseFile()
Close the file specified with WriteInto.
static void InitializeInstance()
#define G4endl
Definition: G4ios.hh:61
static void Activated(G4bool flag=true)
void OpenGeometry(G4VPhysicalVolume *vol=0)
Class Description The dynamic molecule holds all the data that change for a molecule It has a pointer...
Definition: G4Molecule.hh:93
void Gun(G4ITGun *, bool physicsTableToBuild=true)
static const double picosecond
Definition: G4SIunits.hh:142
double G4double
Definition: G4Types.hh:76
virtual void ConstructTimeStepModel(G4DNAMolecularReactionTable *reactionTable)=0
static G4DNAChemistryManager * GetInstanceIfExists()
void Initialize()
Definition: G4Scheduler.cc:299
G4bool CloseGeometry(G4bool pOptimise=true, G4bool verbose=false, G4VPhysicalVolume *vol=0)
G4DNAWaterIonisationStructure * GetIonisationLevel()
G4ApplicationState
G4UIdirectory * fpChemDNADirectory
static G4ThreadLocal std::ofstream * fpgOutput_tl
G4UIcmdWithABool * fpActivateChem
static G4ThreadLocal G4bool * fpgThreadInitialized_tl
static void DeleteInstance()