Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/molecules/management/src/G4MolecularConfiguration.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 //
 27 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) 
 28 //
 29 // History:
 30 // -----------
 31 // 10 Oct 2011 M.Karamitros created
 32 //
 33 // -------------------------------------------------------------------
 34 
 35 #include "G4MolecularConfiguration.hh"
 36 #include "G4MoleculeDefinition.hh"
 37 #include "G4UIcommand.hh"
 38 #include "G4AllocatorList.hh"
 39 #include "G4AutoLock.hh"
 40 #include "G4MoleculeTable.hh"
 41 #include "G4Serialize.hh"
 42 #include <fstream>
 43 
 44 using CLHEP::m2;
 45 using CLHEP::s;
 46 using CLHEP::kelvin;
 47 
 48 using namespace std;
 49 
 50 #if defined ( WIN32 )
 51 #define __func__ __FUNCTION__
 52 #endif
 53 
 54 /*G4ThreadLocal*/G4double G4MolecularConfiguration::fgTemperature = 298; // 310*kelvin;
 55 // 25°C, used to shoot an energy
 56 
 57 //______________________________________________________________________________
 58 // G4MolecularConfigurationManager
 59 using MolecularConfigurationManager = G4MolecularConfiguration::G4MolecularConfigurationManager;
 60 
 61 MolecularConfigurationManager* G4MolecularConfiguration::fgManager = nullptr;
 62 
 63 G4Mutex MolecularConfigurationManager::fManagerCreationMutex;
 64 
 65 int G4MolecularConfiguration::GetNumberOfSpecies()
 66 {
 67   return GetManager()->GetNumberOfCreatedSpecies();
 68 }
 69 
 70 double G4MolecularConfiguration::ReturnDefaultDiffCoeff(const G4Material*,
 71                                      double,
 72                                      const G4MolecularConfiguration*
 73                                      molConf)
 74 {
 75   return molConf->fDynDiffusionCoefficient;
 76 }
 77 
 78 G4MolecularConfiguration::G4MolecularConfiguration(const G4MoleculeDefinition* moleculeDef,
 79                                                    const G4String& label,
 80                                                    int charge)
 81 {
 82   fMoleculeDefinition = moleculeDef;
 83 
 84   fLabel = new G4String(label);
 85 
 86   fMoleculeID = GetManager()->Insert(moleculeDef,
 87                                      label,
 88                                      this);
 89   fElectronOccupancy = nullptr;
 90 
 91   fDynCharge = charge;
 92 
 93   fDynMass = fMoleculeDefinition->GetMass();
 94 
 95   fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
 96   fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
 97   fDynDecayTime = fMoleculeDefinition->GetDecayTime();
 98 
 99   fName = fMoleculeDefinition->GetName();
100   fName += "^";
101   fName += G4UIcommand::ConvertToString(fDynCharge);
102 
103   fFormatedName = fMoleculeDefinition->GetFormatedName();
104   fFormatedName += "^";
105   fFormatedName += "{";
106   fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
107   fFormatedName += "}";
108 
109   fDiffParam = &G4MolecularConfiguration::ReturnDefaultDiffCoeff;
110   fIsFinalized = false;
111 }
112 
113 void G4MolecularConfiguration::MakeExceptionIfFinalized()
114 {
115   if(fIsFinalized)
116   {
117     G4ExceptionDescription errMsg;
118     errMsg << "This molecular configuration " << GetName()
119            << " is already finalized. Therefore its "
120            " properties cannot be changed.";
121     G4Exception("G4MolecularConfiguration::MakeExceptionIfFinalized",
122                 "CONF_FINALIZED",FatalException,errMsg);
123   }
124 }
125 
126 //______________________________________________________________________________
127 
128 G4MolecularConfiguration::G4MolecularConfigurationManager*
129 G4MolecularConfiguration::GetManager()
130 {
131   if (fgManager == nullptr)
132   {
133     G4AutoLock lock(&MolecularConfigurationManager::fManagerCreationMutex);
134     if (fgManager == nullptr) // double check for MT
135     {
136       fgManager = new G4MolecularConfiguration::
137           G4MolecularConfigurationManager();
138     }
139     lock.unlock();
140   }
141 
142   return fgManager;
143 }
144 
145 //______________________________________________________________________________
146 
147 G4MolecularConfiguration::
148 G4MolecularConfigurationManager::~G4MolecularConfigurationManager()
149 {
150 //  G4cout << "Does G4AllocatorList exists= ";
151 //  G4cout << (G4AllocatorList::GetAllocatorListIfExist() ? "true":"false")
152 //      << G4endl;
153 
154   G4MolecularConfigurationManager::MolElectronConfTable::iterator it1;
155   G4MolecularConfigurationManager::ElectronOccupancyTable::
156     iterator it2;
157 
158   for (it1 = fElecOccTable.begin(); it1 != fElecOccTable.end(); it1++)
159   {
160     for (it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
161     {
162       
163       
164         delete it2->second;
165       
166     }
167   }
168   fElecOccTable.clear();
169   fgManager = nullptr;
170 }
171 
172 //______________________________________________________________________________
173 // G4MolecularConfigurationManager
174 G4int G4MolecularConfiguration::
175 G4MolecularConfigurationManager::
176 Insert(const G4MoleculeDefinition* molDef,
177                              const G4ElectronOccupancy& eOcc,
178                              G4MolecularConfiguration* molConf)
179 {
180   //G4AutoLock lock(&fMoleculeCreationMutex);
181 
182   ElectronOccupancyTable& table2 = fElecOccTable[molDef];
183   auto it = table2.find(eOcc);
184 
185   if(it == table2.end())
186   {
187     table2[eOcc] = molConf;
188   }
189   else
190   {
191     G4ExceptionDescription errMsg;
192     errMsg << "The same molecular configuration seemed to be recorded twice";
193     G4Exception("G4MolecularConfigurationManager::"
194                 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
195                 "const G4ElectronOccupancy& eOcc,"
196                 "G4MolecularConfiguration* molConf)",
197                 "",
198                 FatalException,
199                 errMsg
200                 );
201   }
202 
203   fLastMoleculeID++;
204 
205   fMolConfPerID.push_back(molConf);
206 
207   //lock.unlock();
208   return fLastMoleculeID;
209 }
210 
211 //______________________________________________________________________________
212 
213 const G4ElectronOccupancy*
214 G4MolecularConfiguration::G4MolecularConfigurationManager::
215 FindCommonElectronOccupancy(const G4MoleculeDefinition* molDef,
216                             const G4ElectronOccupancy& eOcc)
217 {
218   //G4AutoLock lock(&fMoleculeCreationMutex);
219 
220   auto it1 = fElecOccTable.find(molDef);
221 
222   if(it1 == fElecOccTable.end())
223   {
224     // TODO = handle exception ?
225     return nullptr;
226   }
227 
228   ElectronOccupancyTable& table2 = it1->second;
229   auto it2 = table2.find(eOcc);
230 
231   //lock.unlock();
232 
233   if (it2 == table2.end())
234   {
235     // TODO = handle exception ?
236     return nullptr;
237   }
238 
239   return &(it2->first);
240 }
241 
242 //______________________________________________________________________________
243 
244 G4MolecularConfiguration*
245 G4MolecularConfiguration::G4MolecularConfigurationManager::
246 GetMolecularConfiguration(const G4MoleculeDefinition* molDef,
247                           const G4ElectronOccupancy& eOcc)
248 {
249   auto it1 = fElecOccTable.find(molDef);
250 
251   if(it1 == fElecOccTable.end()) return nullptr;
252 
253   ElectronOccupancyTable& table2 = it1->second;
254   auto it = table2.find(eOcc);
255 
256   if(it == table2.end())
257   {
258     return nullptr;
259   }
260   
261   return it->second;
262 }
263 
264 //______________________________________________________________________________
265 
266 G4int G4MolecularConfiguration::G4MolecularConfigurationManager::
267 Insert(const G4MoleculeDefinition* molDef,
268        int charge,
269        G4MolecularConfiguration* molConf)
270 {
271 
272   //G4AutoLock lock(&fMoleculeCreationMutex);
273   ChargeTable& table2 = fChargeTable[molDef];
274   auto it = table2.find(charge);
275 
276   if(it == table2.end())
277   {
278     table2[charge] = molConf;
279   }
280   else
281   {
282     //lock.unlock();
283     G4ExceptionDescription errMsg;
284     errMsg << "The same molecular configuration seemed to be recorded twice";
285     G4Exception("G4MolecularConfigurationManager::"
286                 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
287                 "int charge,"
288                 "G4MolecularConfiguration* molConf)",
289                 "", FatalException, errMsg);
290   }
291 
292   fLastMoleculeID++;
293   fMolConfPerID.push_back(molConf);
294   //lock.unlock();
295   return fLastMoleculeID;
296 }
297 
298 //______________________________________________________________________________
299 
300 G4MolecularConfiguration*
301 G4MolecularConfiguration::G4MolecularConfigurationManager::
302 GetMolecularConfiguration(const G4MoleculeDefinition* molDef,
303                           int charge)
304 {
305   //G4AutoLock lock(&fMoleculeCreationMutex);
306 
307   auto it1 = fChargeTable.find(molDef);
308 
309   if(it1 == fChargeTable.end()) return nullptr;
310 
311   ChargeTable& table2 = it1->second;
312   auto it = table2.find(charge);
313 
314   if(it == table2.end())
315   {
316     return nullptr;
317   }
318   
319   return it->second;
320  
321 }
322 
323 //______________________________________________________________________________
324 // Static method in G4MolecularConfiguration
325 G4MolecularConfiguration*
326 G4MolecularConfiguration::
327 GetOrCreateMolecularConfiguration(const G4MoleculeDefinition* molDef)
328 {
329   if (molDef->GetGroundStateElectronOccupancy() != nullptr)
330   {
331     const G4ElectronOccupancy& elecOcc =
332         *molDef->GetGroundStateElectronOccupancy();
333     G4MolecularConfiguration* molConf =
334         GetManager()->GetMolecularConfiguration(molDef, elecOcc);
335 
336     if (molConf != nullptr)
337     {
338       return molConf;
339     }
340     
341     auto  newConf =
342         new G4MolecularConfiguration(molDef,
343                                      elecOcc);
344     newConf->SetUserID(molDef->GetName());
345     return newConf;
346   }
347   
348   G4MolecularConfiguration* molConf =
349       GetManager()->GetMolecularConfiguration(molDef, molDef->GetCharge());
350   if(molConf != nullptr)
351   {
352     return molConf;
353   }
354     
355   auto  newConf =
356       new G4MolecularConfiguration(molDef, molDef->GetCharge());
357   newConf->SetUserID(molDef->GetName());
358   return newConf;
359 }
360 
361 //______________________________________________________________________________
362 
363 G4MolecularConfiguration*
364 G4MolecularConfiguration::
365 GetOrCreateMolecularConfiguration(const G4MoleculeDefinition* molDef,
366                                   const G4ElectronOccupancy& elecOcc)
367 {
368   return GetManager()->GetOrCreateMolecularConfiguration(molDef, elecOcc);
369 
370 //  G4MolecularConfiguration* molConf =
371 //      GetManager()->GetMolecularConfiguration(molDef, elecOcc);
372 //
373 //  if (molConf)
374 //  {
375 //    return molConf;
376 //  }
377 //  else
378 //  {
379 //    G4MolecularConfiguration* newConf =
380 //        new G4MolecularConfiguration(molDef, elecOcc);
381 //    return newConf;
382 //  }
383 }
384 
385 //______________________________________________________________________________
386 
387 G4MolecularConfiguration*
388 G4MolecularConfiguration::
389 GetOrCreateMolecularConfiguration(const G4MoleculeDefinition* molDef,
390                                   int charge)
391 {
392   G4MolecularConfiguration* molConf =
393       GetManager()->GetMolecularConfiguration(molDef, charge);
394 
395   if(molConf != nullptr)
396   {
397     return molConf;
398   }
399   
400   auto  newConf =
401       new G4MolecularConfiguration(molDef, charge);
402   return newConf;
403 }
404 
405 //______________________________________________________________________________
406 
407 void G4MolecularConfiguration::DeleteManager()
408 {
409   G4AutoLock lock(&MolecularConfigurationManager::fManagerCreationMutex);
410   delete fgManager;
411   fgManager = nullptr;
412   lock.unlock();
413 }
414 
415 //______________________________________________________________________________
416 // G4MolecularConfiguration
417 G4MolecularConfiguration::
418 G4MolecularConfiguration(const G4MoleculeDefinition* moleculeDef,
419                          const G4ElectronOccupancy& elecOcc,
420                          const G4String& label)
421 {
422   fMoleculeDefinition = moleculeDef;
423 
424   fMoleculeID = GetManager()->Insert(moleculeDef,
425                                      elecOcc,
426                                      this);
427   fElectronOccupancy = GetManager()->FindCommonElectronOccupancy(moleculeDef,
428                                                                  elecOcc);
429 
430   /*
431    fgManager->fTable[fMoleculeDefinition][elecOcc] = this;
432    std::map<G4ElectronOccupancy, G4MolecularConfiguration*, comparator>::iterator it ;
433    it = fgManager->fTable[moleculeDef].find(elecOcc);
434    fElectronOccupancy = &(it->first);
435    */
436 
437   fDynCharge = fMoleculeDefinition->GetNbElectrons()
438       - fElectronOccupancy->GetTotalOccupancy()
439                + moleculeDef->GetCharge();
440   fDynMass = fMoleculeDefinition->GetMass();
441 
442   fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
443   fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
444   fDynDecayTime = fMoleculeDefinition->GetDecayTime();
445 
446   fName = fMoleculeDefinition->GetName();
447   fName += "^";
448   fName += G4UIcommand::ConvertToString(fDynCharge);
449 
450   fFormatedName = fMoleculeDefinition->GetFormatedName();
451   fFormatedName += "^";
452   fFormatedName += "{";
453   fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
454   fFormatedName += "}";
455 
456   fLabel = nullptr; // let it here
457 
458   if(!label.empty())
459   {
460     SetLabel(label);
461   }
462 
463   fDiffParam = &G4MolecularConfiguration::ReturnDefaultDiffCoeff;
464 
465   fIsFinalized = false;
466 }
467 
468 //______________________________________________________________________________
469 
470 G4MolecularConfiguration::
471 G4MolecularConfiguration(const G4MoleculeDefinition* moleculeDef,
472                          int charge)
473 {
474   fMoleculeDefinition = moleculeDef;
475 
476   fMoleculeID = GetManager()->Insert(moleculeDef,
477                                      charge,
478                                      this);
479   fElectronOccupancy = nullptr;
480 
481   fDynCharge = charge;
482   fDynMass = fMoleculeDefinition->GetMass();
483 
484   fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
485   fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
486   fDynDecayTime = fMoleculeDefinition->GetDecayTime();
487 
488   fName = fMoleculeDefinition->GetName();
489   fName += "^";
490   fName += G4UIcommand::ConvertToString(fDynCharge);
491 
492   fFormatedName = fMoleculeDefinition->GetFormatedName();
493   fFormatedName += "^";
494   fFormatedName += "{";
495   fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
496   fFormatedName += "}";
497 
498   fLabel = nullptr;
499 
500   fDiffParam = &G4MolecularConfiguration::ReturnDefaultDiffCoeff;
501 
502   fIsFinalized = false;
503 }
504 
505 //______________________________________________________________________________
506 
507 G4MolecularConfiguration::~G4MolecularConfiguration()
508 {
509   if (fgManager != nullptr) fgManager->RemoveMolecularConfigurationFromTable(this);
510 
511 //  if (G4AllocatorList::GetAllocatorListIfExist())
512 //  {
513 //    if (fElectronOccupancy)
514 //    {
515 //      delete fElectronOccupancy;
516 //      fElectronOccupancy = 0;
517 //    }
518 //  }
519 }
520 
521 //______________________________________________________________________________
522 
523 G4MolecularConfiguration*
524 G4MolecularConfiguration::
525 ChangeConfiguration(const G4ElectronOccupancy& newElectronOccupancy) const
526 {
527   G4MolecularConfiguration* output =
528       GetManager()->GetMolecularConfiguration(fMoleculeDefinition,
529                                               newElectronOccupancy);
530 
531   if (output == nullptr)
532   {
533     output = new G4MolecularConfiguration(fMoleculeDefinition,
534                                           newElectronOccupancy);
535   }
536   return output;
537 }
538 
539 //______________________________________________________________________________
540 
541 G4MolecularConfiguration*
542 G4MolecularConfiguration::ChangeConfiguration(int charge) const
543 {
544   G4MolecularConfiguration* output =
545       GetManager()->GetMolecularConfiguration(fMoleculeDefinition, charge);
546 
547   if (output == nullptr)
548   {
549     output = new G4MolecularConfiguration(fMoleculeDefinition, charge);
550   }
551   return output;
552 }
553 
554 //______________________________________________________________________________
555 
556 G4MolecularConfiguration&
557 G4MolecularConfiguration::operator=(G4MolecularConfiguration& /*right*/)
558 {
559 //  if (&right == this) return *this;
560   return *this;
561 }
562 
563 //______________________________________________________________________________
564 
565 /** Method used in Geant4-DNA to excite water molecules
566  */
567 G4MolecularConfiguration*
568 G4MolecularConfiguration::ExciteMolecule(G4int ExcitedLevel) const
569 {
570 //  MakeExceptionIfFinalized();
571   CheckElectronOccupancy(__func__);
572   G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
573 
574   newElectronOccupancy.RemoveElectron(ExcitedLevel, 1);
575   newElectronOccupancy.AddElectron(5, 1);
576 
577   return ChangeConfiguration(newElectronOccupancy);
578 }
579 
580 //______________________________________________________________________________
581 
582 /** Method used in Geant4-DNA to ionize water molecules
583  */
584 G4MolecularConfiguration*
585 G4MolecularConfiguration::IonizeMolecule(G4int IonizedLevel) const
586 {
587 //  MakeExceptionIfFinalized();
588   CheckElectronOccupancy(__func__);
589   G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
590 
591   if (newElectronOccupancy.GetOccupancy(IonizedLevel) != 0)
592   {
593     newElectronOccupancy.RemoveElectron(IonizedLevel, 1);
594   }
595   else
596   {
597     G4String errMsg = "There is no electron on the orbit "
598         + G4UIcommand::ConvertToString(IonizedLevel)
599         + " you want to free. The molecule's name you want to ionized is "
600         + GetName();
601     G4Exception("G4MolecularConfiguration::IonizeMolecule",
602                 "",
603                 FatalErrorInArgument,
604                 errMsg);
605     PrintState();
606   }
607 
608   // DEBUG
609   // PrintState();
610 
611   return ChangeConfiguration(newElectronOccupancy);
612 }
613 
614 //______________________________________________________________________________
615 
616 G4MolecularConfiguration* G4MolecularConfiguration::AddElectron(G4int orbit,
617                                                                 G4int number) const
618 {
619 //  MakeExceptionIfFinalized();
620   CheckElectronOccupancy(__func__);
621   G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
622   newElectronOccupancy.AddElectron(orbit, number);
623   return ChangeConfiguration(newElectronOccupancy);
624 }
625 
626 //______________________________________________________________________________
627 
628 G4MolecularConfiguration*
629 G4MolecularConfiguration::RemoveElectron(G4int orbit,
630                                          G4int number) const
631 {
632 //  MakeExceptionIfFinalized();
633   CheckElectronOccupancy(__func__);
634   G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
635 
636   if (newElectronOccupancy.GetOccupancy(orbit) != 0)
637   {
638     newElectronOccupancy.RemoveElectron(orbit, number);
639   }
640   else
641   {
642     G4String errMsg = "There is already no electron into the orbit "
643         + G4UIcommand::ConvertToString(orbit)
644         + " you want to free. The molecule's name is " + GetName();
645     G4Exception("G4MolecularConfiguration::RemoveElectron",
646                 "",
647                 JustWarning,
648                 errMsg);
649     PrintState();
650   }
651 
652   return ChangeConfiguration(newElectronOccupancy);
653 }
654 
655 //______________________________________________________________________________
656 
657 G4MolecularConfiguration*
658 G4MolecularConfiguration::MoveOneElectron(G4int orbitToFree,
659                                           G4int orbitToFill) const
660 {
661 //  MakeExceptionIfFinalized();
662   CheckElectronOccupancy(__func__);
663   G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
664 
665   if (newElectronOccupancy.GetOccupancy(orbitToFree) >= 1)
666   {
667     newElectronOccupancy.RemoveElectron(orbitToFree, 1);
668     newElectronOccupancy.AddElectron(orbitToFill, 1);
669   }
670   else
671   {
672     G4String errMsg = "There is no electron on the orbit "
673         + G4UIcommand::ConvertToString(orbitToFree)
674         + " you want to free. The molecule's name is " + GetName();
675     G4Exception("G4MolecularConfiguration::MoveOneElectron",
676                 "",
677                 FatalErrorInArgument,
678                 errMsg);
679     PrintState();
680   }
681 
682   return ChangeConfiguration(newElectronOccupancy);
683 }
684 
685 //______________________________________________________________________________
686 
687 const G4String& G4MolecularConfiguration::GetName() const
688 {
689   return fName;
690 }
691 
692 //______________________________________________________________________________
693 
694 const G4String& G4MolecularConfiguration::GetFormatedName() const
695 {
696   return fFormatedName;
697 }
698 
699 //______________________________________________________________________________
700 
701 G4int G4MolecularConfiguration::GetAtomsNumber() const
702 {
703   return fMoleculeDefinition->GetAtomsNumber();
704 }
705 
706 //______________________________________________________________________________
707 
708 G4double G4MolecularConfiguration::GetNbElectrons() const
709 {
710   CheckElectronOccupancy(__func__);
711   return fElectronOccupancy->GetTotalOccupancy();
712 }
713 
714 //______________________________________________________________________________
715 
716 void G4MolecularConfiguration::PrintState() const
717 {
718   G4cout << "-------------- Start Printing State " << GetName()
719          << " ---------------" << G4endl;
720 
721   if (fElectronOccupancy != nullptr)
722   {
723     G4cout << "--------------Print electronic state of " << GetName()
724            << "---------------" << G4endl;
725     fElectronOccupancy->DumpInfo();
726     if(fElectronOccupancy==fMoleculeDefinition->GetGroundStateElectronOccupancy())
727     {
728       G4cout<<"At ground state"<<G4endl;
729     }
730   }
731   else
732   {
733     G4cout << "--- No electron occupancy set up ---" << G4endl;
734   }
735 
736   G4cout << "Charge :"
737          << fDynCharge
738          << G4endl;
739 
740   if(fLabel != nullptr)
741   {
742     G4cout << "Label :"
743            << GetLabel()
744            << G4endl;
745   }
746   G4cout  << "-------------- End Of State " << GetName()
747           << " -----------------------" << G4endl;
748 }
749 
750 //______________________________________________________________________________
751 
752 // added - to be transformed in a "Decay method"
753 const vector<const G4MolecularDissociationChannel*>*
754   G4MolecularConfiguration::GetDissociationChannels() const
755 {
756   // if (fElectronOccupancy == 0) return 0;
757   return fMoleculeDefinition->GetDecayChannels(this);
758 }
759 
760 //______________________________________________________________________________
761 
762 G4int G4MolecularConfiguration::GetFakeParticleID() const
763 {
764   if(fMoleculeDefinition != nullptr) return fMoleculeDefinition->GetPDGEncoding();
765   G4Exception("G4MolecularConfiguration::GetMoleculeID",
766                    "",
767                    FatalErrorInArgument,
768                    "You should first enter a molecule definition");
769 
770   return INT_MAX;
771 }
772 
773 //______________________________________________________________________________
774 
775 const char* removePath(const char* path)
776 {
777   const char* pDelimeter = strrchr(path, '\\');
778   if (pDelimeter != nullptr) path = pDelimeter + 1;
779 
780   pDelimeter = strrchr(path, '/');
781   if (pDelimeter != nullptr) path = pDelimeter + 1;
782 
783   return path;
784 }
785 
786 //______________________________________________________________________________
787 
788 void G4MolecularConfiguration::CheckElectronOccupancy(const char* function) const
789 {
790   if (fElectronOccupancy == nullptr)
791   {
792     G4String functionName(function);
793     G4ExceptionDescription description;
794     description
795         << "No G4ElectronOccupancy was defined for molecule definition : "
796         << fMoleculeDefinition->GetName()
797         << ". The definition was probably defined using the charge state, "
798             "rather than electron state.";
799 
800     G4Exception(functionName, "", FatalErrorInArgument, description);
801   }
802 }
803 
804 //______________________________________________________________________________
805 
806 void G4MolecularConfiguration::G4MolecularConfigurationManager::
807 RecordNewlyLabeledConfiguration(G4MolecularConfiguration* molConf)
808 {
809   //G4AutoLock lock(&fMoleculeCreationMutex);
810 
811   LabelTable& tmpMap = fLabelTable[molConf->fMoleculeDefinition];
812 
813   auto it = tmpMap.find(*molConf->fLabel);
814 
815   if(it == tmpMap.end())
816   {
817     tmpMap[*(molConf->fLabel)] = molConf;
818   }
819   else
820   {
821     G4ExceptionDescription errMsg;
822     errMsg << "The same molecular configuration seemed to be recorded twice";
823     G4Exception("G4MolecularConfigurationManager::"
824                 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
825                 "const G4String& label,"
826                 "G4MolecularConfiguration* molConf)",
827                 "", FatalException, errMsg);
828   }
829 
830   //lock.unlock();
831 }
832 
833 void G4MolecularConfiguration::G4MolecularConfigurationManager::AddUserID(const G4String& userID,
834                                                                           G4MolecularConfiguration* molecule)
835 {
836   auto it = fUserIDTable.find(userID);
837 
838   if(it == fUserIDTable.end())
839   {
840     fUserIDTable[userID] = molecule;
841   }
842   else if(molecule != it->second)
843   {
844     // TODO improve exception
845     // exception
846     G4ExceptionDescription description;
847     description << "The user identifier " << userID
848                 << " was already given in another configuration in the table"
849                 << G4endl;
850   G4Exception("G4MolecularConfiguration::G4MolecularConfigurationManager::AddUserID",
851                 "CONF_ALREADY_RECORDED",
852                 FatalException,
853                 description);
854   }
855 }
856 
857 //______________________________________________________________________________
858 
859 void G4MolecularConfiguration::G4MolecularConfigurationManager::
860 RemoveMolecularConfigurationFromTable(G4MolecularConfiguration* configuration)
861 {
862   auto it1 =
863       fElecOccTable.find(configuration->GetDefinition());
864   auto end = fElecOccTable.end();
865 
866   if (it1 == end) return;
867 
868   auto it2 =
869       it1->second.find(*configuration->GetElectronOccupancy());
870 
871   if (it2 == it1->second.end()) return;
872 
873   it2->second = 0;
874 //  it1->second.erase(it2);
875 
876   configuration->fElectronOccupancy = nullptr;
877 }
878 
879 //______________________________________________________________________________
880 
881 G4MolecularConfiguration*
882 G4MolecularConfiguration::G4MolecularConfigurationManager::
883 GetMolecularConfiguration(const G4MoleculeDefinition* molDef,
884                           const G4String& label)
885 {
886   //G4AutoLock lock(&fMoleculeCreationMutex);
887 
888   auto it1 = fLabelTable.find(molDef);
889 
890   if(it1 == fLabelTable.end()) return nullptr;
891 
892   LabelTable& table2 = it1->second;
893 
894   auto it2 = table2.find(label);
895 
896   //lock.unlock();
897 
898   if(it2 == table2.end()) return nullptr;
899   return it2->second;
900 }
901 
902 //______________________________________________________________________________
903 
904 G4MolecularConfiguration*
905 G4MolecularConfiguration::G4MolecularConfigurationManager::
906 GetMolecularConfiguration(int moleculeID)
907 {
908   if(moleculeID > (int) fMolConfPerID.size() ||
909      moleculeID < 0) return nullptr;
910 
911   return fMolConfPerID[moleculeID];
912 }
913 
914 //______________________________________________________________________________
915 
916 G4int
917 G4MolecularConfiguration::G4MolecularConfigurationManager::
918 Insert(const G4MoleculeDefinition* molDef,
919                              const G4String& label,
920                              G4MolecularConfiguration* molConf)
921 {
922   G4AutoLock lock(&fMoleculeCreationMutex);
923   LabelTable& tmpMap = fLabelTable[molDef];
924   auto it = tmpMap.find(label);
925 
926   if(it == tmpMap.end())
927   {
928     fLastMoleculeID++;
929     tmpMap[label] = molConf;
930     lock.unlock();
931   }
932   else
933   {
934     lock.unlock();
935     G4ExceptionDescription errMsg;
936     errMsg << "The same molecular configuration seemed to be recorded twice";
937     G4Exception("G4MolecularConfigurationManager::"
938                 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
939                 "const G4String& label,"
940                 "G4MolecularConfiguration* molConf)",
941                 "", FatalException, errMsg);
942   }
943 
944   fMolConfPerID.push_back(molConf);
945 
946   return fLastMoleculeID;
947 }
948 
949 //______________________________________________________________________________
950 
951 G4MolecularConfiguration*
952 G4MolecularConfiguration::GetMolecularConfiguration(const G4MoleculeDefinition* molDef,
953                                                     const G4String& label)
954 {
955   return GetManager()->GetMolecularConfiguration(molDef, label);
956 }
957 
958 //______________________________________________________________________________
959 
960 G4MolecularConfiguration*
961 G4MolecularConfiguration::GetMolecularConfiguration(int moleculeID)
962 {
963   return GetManager()->GetMolecularConfiguration(moleculeID);
964 }
965 
966 //______________________________________________________________________________
967 
968 G4MolecularConfiguration*
969 G4MolecularConfiguration::CreateMolecularConfiguration(const G4String& userIdentifier,
970                                                        const G4MoleculeDefinition* molDef,
971                                                        int charge,
972                                                        const G4String& label,
973                                                        bool& wasAlreadyCreated)
974 {
975   wasAlreadyCreated = false;
976   G4MolecularConfiguration* molConf =
977       GetManager()->GetMolecularConfiguration(molDef, charge);
978 
979   if (molConf != nullptr)
980   {
981     if(molConf->fLabel == nullptr)
982     {
983       molConf->SetLabel(label);
984       G4ExceptionDescription wMsg ;
985       wMsg << "The molecular configuration for the definition named "
986              << molDef->GetName()
987              << " with charge " << charge << " has already been created "
988                  "but with NO label";
989       G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
990                   "DOUBLE_CREATION",
991                   JustWarning,
992                   wMsg);
993     }
994     else if(molConf->fLabel->empty() )
995     {
996       molConf->SetLabel(label);
997     }
998     else if(*(molConf->fLabel) != label)
999     {
1000       G4ExceptionDescription errMsg ;
1001       errMsg << "The molecular configuration for the definition named "
1002              << molDef->GetName()
1003              << " with charge " << charge << " has already been created "
1004                  "but with a different label :"
1005              << molConf->GetLabel();
1006       G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1007                   "DOUBLE_CREATION",
1008                   FatalErrorInArgument,
1009                   errMsg);
1010       // KILL APP
1011     }
1012 
1013     if(molConf->fUserIdentifier.empty())
1014     {
1015       molConf->fUserIdentifier = userIdentifier;
1016 
1017       G4ExceptionDescription wMsg ;
1018       wMsg << "The molecular configuration for the definition named "
1019              << molDef->GetName()
1020              << " with label " << label << " has already been created.";
1021       G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1022                   "DOUBLE_CREATION",
1023                   JustWarning,
1024                   wMsg);
1025     }
1026     else if(molConf->fUserIdentifier != userIdentifier)
1027     {
1028       G4ExceptionDescription errMsg ;
1029       errMsg << "The molecular configuration for the definition named "
1030              << molDef->GetName()
1031              << " with label " << label << " has already been created "
1032                  "BUT with a different user ID :"
1033              << molConf->fUserIdentifier;
1034       G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1035                   "DOUBLE_CREATION",
1036                   FatalErrorInArgument,
1037                   errMsg);
1038       // KILL APP
1039     }
1040 
1041     wasAlreadyCreated = true;
1042     return molConf;
1043   }
1044   
1045   auto  newConf =
1046       new G4MolecularConfiguration(molDef, label, charge);
1047   newConf->fUserIdentifier = userIdentifier;
1048 
1049   GetManager()->AddUserID(userIdentifier, newConf);
1050 
1051 //    G4MoleculeTable::Instance()->RecordMolecularConfiguration(userIdentifier,
1052 //                                                              newConf);
1053   return newConf;
1054 }
1055 
1056 //______________________________________________________________________________
1057 
1058 G4MolecularConfiguration*
1059 G4MolecularConfiguration::
1060 CreateMolecularConfiguration(const G4String& userIdentifier,
1061                              const G4MoleculeDefinition* molDef,
1062                              bool& wasAlreadyCreated)
1063 {
1064   wasAlreadyCreated = false;
1065   G4MolecularConfiguration* preRegisteredMolConf =
1066       GetManager()->GetMolecularConfiguration(userIdentifier);
1067 
1068   if(preRegisteredMolConf != nullptr)
1069   {
1070     if(preRegisteredMolConf->GetDefinition() == molDef)
1071     {
1072       wasAlreadyCreated = true;
1073       return preRegisteredMolConf;
1074     }
1075   }
1076 
1077   if(molDef->GetGroundStateElectronOccupancy() != nullptr)
1078   {
1079     const G4ElectronOccupancy& elecOcc = *molDef
1080         ->GetGroundStateElectronOccupancy();
1081     G4MolecularConfiguration* molConf =
1082         GetManager()->GetMolecularConfiguration(molDef, elecOcc);
1083 
1084     if(molConf != nullptr)
1085     {
1086       if(molConf->fUserIdentifier.empty())
1087       {
1088         molConf->fUserIdentifier = userIdentifier;
1089       }
1090       else if(molConf->fUserIdentifier != userIdentifier)
1091       {
1092         G4ExceptionDescription errMsg;
1093         errMsg << "A molecular configuration for the definition named "
1094                << molDef->GetName() << " has already been created "
1095                "and recorded with a different user ID "
1096                << molConf->fUserIdentifier;
1097         G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1098                     "DOUBLE_CREATION",
1099                     FatalErrorInArgument,
1100                     errMsg);
1101       }
1102 // TODO exception
1103       G4ExceptionDescription errMsg;
1104       errMsg << "A molecular configuration for the definition named "
1105              << molDef->GetName() << " has already been created.";
1106       G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1107                   "DOUBLE_CREATION",
1108                   JustWarning,
1109                   errMsg);
1110       wasAlreadyCreated = true;
1111       return molConf;
1112     }
1113     
1114     // G4cout << "Create molConf for " << molDef->GetName() << G4endl;
1115     auto  newConf = new G4MolecularConfiguration(molDef,
1116                                                                     elecOcc);
1117     newConf->fUserIdentifier = userIdentifier;
1118 
1119     GetManager()->AddUserID(userIdentifier, newConf);
1120 
1121 //      G4MoleculeTable::Instance()->RecordMolecularConfiguration(userIdentifier,
1122 //                                                                newConf);
1123     return newConf;
1124   }
1125   
1126   return CreateMolecularConfiguration(userIdentifier,
1127                                       molDef,
1128                                       molDef->GetName(),
1129                                       molDef->GetCharge(),
1130                                       wasAlreadyCreated);
1131 }
1132 
1133 //______________________________________________________________________________
1134 
1135 G4MolecularConfiguration*
1136 G4MolecularConfiguration::
1137 CreateMolecularConfiguration(const G4String& userIdentifier,
1138                              const G4MoleculeDefinition* molDef,
1139                              const G4String& label,
1140                              bool& wasAlreadyCreated)
1141 {
1142   assert(label != "");
1143   wasAlreadyCreated = false;
1144 
1145   G4MolecularConfiguration* molConf =
1146       GetManager()->GetMolecularConfiguration(molDef, label);
1147   if(molConf != nullptr)
1148   {
1149     if((molConf->fLabel != nullptr)
1150        && *molConf->fLabel == label)
1151     {
1152       wasAlreadyCreated = true;
1153       return molConf;
1154     }
1155     if(molConf->fLabel == nullptr)
1156     {
1157       wasAlreadyCreated = true;
1158       molConf->SetLabel(label);
1159       return molConf;
1160     }
1161     if(molConf->fLabel->empty())
1162     {
1163       wasAlreadyCreated = true;
1164       molConf->SetLabel(label);
1165       return molConf;
1166     }
1167 
1168     molConf->PrintState();
1169     G4ExceptionDescription errMsg ;
1170     errMsg << "A molecular configuration for the definition named "
1171            << molDef->GetName()
1172            << " has already been created "
1173               "with user ID "
1174            << molConf->fUserIdentifier << " and label "
1175            << molConf->GetLabel();
1176     G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1177                 "DOUBLE_CREATION",
1178                 FatalErrorInArgument,
1179                 errMsg);
1180     // KILL APP
1181   }
1182   else
1183   {
1184     auto  newConf =
1185       new G4MolecularConfiguration(molDef,
1186                                    label,
1187                                    molDef->GetCharge());
1188     newConf->fUserIdentifier = userIdentifier;
1189 
1190     GetManager()->AddUserID(userIdentifier, newConf);
1191 
1192 //    G4MoleculeTable::Instance()->
1193 //        RecordMolecularConfiguration(userIdentifier, newConf);
1194     return newConf;
1195   }
1196   return molConf;
1197 }
1198 
1199 //______________________________________________________________________________
1200 
1201 G4MolecularConfiguration*
1202 G4MolecularConfiguration::
1203 CreateMolecularConfiguration(const G4String& userIdentifier,
1204                              const G4MoleculeDefinition* molDef,
1205                              const G4String& label,
1206                              const G4ElectronOccupancy& eOcc,
1207                              bool& wasAlreadyCreated)
1208 {
1209   assert(label != "");
1210   wasAlreadyCreated = false;
1211 
1212   G4MolecularConfiguration* molConf =
1213       GetManager()->GetMolecularConfiguration(molDef, eOcc);
1214 
1215   if(molConf != nullptr)
1216   {
1217     if(molConf->GetElectronOccupancy() != nullptr)
1218     {
1219       if(*molConf->GetElectronOccupancy() == eOcc)
1220       {
1221         if((molConf->fLabel != nullptr) && *molConf->fLabel == label)
1222         {
1223           wasAlreadyCreated = true;
1224           return molConf;
1225         }
1226         if(molConf->fLabel == nullptr)
1227         {
1228           wasAlreadyCreated = true;
1229           molConf->SetLabel(label);
1230           return molConf;
1231         }
1232         if(molConf->fLabel->empty())
1233         {
1234           wasAlreadyCreated = true;
1235           molConf->SetLabel(label);
1236           return molConf;
1237         }
1238       }
1239     }
1240 
1241 
1242     molConf->PrintState();
1243     G4ExceptionDescription errMsg ;
1244     errMsg << "A molecular configuration for the definition named "
1245            << molDef->GetName()
1246            << " has already been created "
1247               "with user ID "
1248            << molConf->fUserIdentifier
1249            << " and possible different electronic state";
1250     G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1251                 "DOUBLE_CREATION",
1252                 FatalErrorInArgument,
1253                 errMsg);
1254   }
1255   else
1256   {
1257     auto  newConf =
1258       new G4MolecularConfiguration(molDef,
1259                                    eOcc,
1260                                    label);
1261     newConf->fUserIdentifier = userIdentifier;
1262 
1263     GetManager()->AddUserID(userIdentifier, newConf);
1264 
1265 //    G4MoleculeTable::Instance()->
1266 //        RecordMolecularConfiguration(userIdentifier, newConf);
1267     return newConf;
1268   }
1269   return molConf;
1270 }
1271 
1272 
1273 //______________________________________________________________________________
1274 
1275 G4MolecularConfiguration*
1276 G4MolecularConfiguration::G4MolecularConfigurationManager::
1277 GetOrCreateMolecularConfiguration(const G4MoleculeDefinition* molDef,
1278                                   const G4ElectronOccupancy& eOcc)
1279 {
1280   auto it1 = fElecOccTable.find(molDef);
1281 
1282   if(it1 == fElecOccTable.end())
1283   {
1284     return new G4MolecularConfiguration(molDef, eOcc);
1285   }
1286 
1287   ElectronOccupancyTable& table2 = it1->second;
1288   auto it = table2.find(eOcc);
1289 
1290   if(it == table2.end())
1291   {
1292     auto  molConf =
1293         new G4MolecularConfiguration(molDef, eOcc);
1294 //    molConf->Finalize();
1295     return molConf;
1296   }
1297   
1298   return it->second;
1299 }
1300 
1301 //______________________________________________________________________________
1302 
1303 G4MolecularConfiguration*
1304 G4MolecularConfiguration::G4MolecularConfigurationManager::
1305 GetOrCreateMolecularConfiguration(const G4MoleculeDefinition* molDef,
1306                                   int charge)
1307 {
1308   auto it1 = fChargeTable.find(molDef);
1309 
1310   if(it1 == fChargeTable.end())
1311   {
1312     G4AutoLock lock(&fMoleculeCreationMutex);
1313 
1314     auto  newConf = new G4MolecularConfiguration(molDef, charge);
1315     return newConf ;
1316   }
1317 
1318   ChargeTable& table2 = it1->second;
1319   auto it = table2.find(charge);
1320 
1321   if(it == table2.end())
1322   {
1323     G4AutoLock lock(&fMoleculeCreationMutex);
1324 
1325     auto  newConf =
1326         new G4MolecularConfiguration(molDef, charge);
1327 //    newConf->Finalize();
1328     return newConf ;
1329   }
1330   
1331   return it->second;
1332 }
1333 
1334 //______________________________________________________________________________
1335 
1336 void G4MolecularConfiguration::Serialize(std::ostream& out)
1337 {
1338   G4String moleculeName = fMoleculeDefinition->GetName();
1339   WRITE(out, moleculeName);
1340 
1341 //  if(fLabel)
1342 //   out << fLabel;
1343 //  else
1344 //    out << "";
1345   WRITE(out,fDynDiffusionCoefficient);
1346   WRITE(out,fDynVanDerVaalsRadius);
1347   WRITE(out,fDynDecayTime);
1348   WRITE(out,fDynMass);
1349   WRITE(out,fDynCharge);
1350   WRITE(out,fMoleculeID);
1351   WRITE(out,fFormatedName);
1352   WRITE(out,fName);
1353   WRITE(out,fIsFinalized);
1354 }
1355 
1356 //______________________________________________________________________________
1357 
1358 void G4MolecularConfiguration::Unserialize(std::istream& in)
1359 {
1360   G4String moleculeName;
1361   READ(in, moleculeName);
1362   fMoleculeDefinition =
1363       G4MoleculeTable::Instance()->GetMoleculeDefinition(moleculeName);
1364 
1365 //  G4String label;
1366 //
1367 //  in.read((char*)(&label), sizeof(label));
1368 //
1369 //  if(label)
1370 //   fLabel = new G4String(label);
1371 //  else
1372 //    fLabel = 0;
1373   READ(in,fDynDiffusionCoefficient);
1374   READ(in,fDynVanDerVaalsRadius);
1375   READ(in,fDynDecayTime);
1376   READ(in,fDynMass);
1377   READ(in,fDynCharge);
1378   READ(in,fMoleculeID);
1379   READ(in,fFormatedName);
1380   READ(in,fName);
1381   READ(in,fIsFinalized);
1382 }
1383 
1384 //______________________________________________________________________________
1385 
1386 G4MolecularConfiguration* G4MolecularConfiguration::Load(std::istream& in)
1387 {
1388   return new G4MolecularConfiguration(in);
1389 }
1390 
1391 //______________________________________________________________________________
1392 
1393 G4MolecularConfiguration::G4MolecularConfiguration(std::istream& in)
1394 {
1395   fLabel = nullptr; // TODO: for now not serialized
1396   Unserialize(in);
1397   fMoleculeDefinition = nullptr;
1398   fElectronOccupancy = nullptr;
1399   if(fElectronOccupancy != nullptr)
1400   {
1401     GetManager()->Insert(fMoleculeDefinition, *fElectronOccupancy, this);
1402     fElectronOccupancy =
1403         GetManager()->FindCommonElectronOccupancy(fMoleculeDefinition,
1404                                                   *fElectronOccupancy);
1405 
1406     if(fLabel != nullptr)
1407     {
1408       GetManager()->RecordNewlyLabeledConfiguration(this);
1409     }
1410   }
1411   else if(fLabel != nullptr)
1412   {
1413     fMoleculeID = GetManager()->Insert(fMoleculeDefinition, *fLabel, this);
1414   }
1415   else if(fDynCharge != 0)
1416   {
1417     fMoleculeID = GetManager()->Insert(fMoleculeDefinition, fDynCharge, this);
1418   }
1419 }
1420 
1421 //______________________________________________________________________________
1422 
1423 void G4MolecularConfiguration::SetUserID(const G4String& userID)
1424 {
1425   fUserIdentifier = userID;
1426   GetManager()->AddUserID(userID, this);
1427 //  G4MoleculeTable::Instance()->RecordMolecularConfiguration(userID, this);
1428 }
1429 
1430 //______________________________________________________________________________
1431 
1432 double G4MolecularConfiguration::DiffCoeffWater(double temperature_K)
1433 {
1434   return pow(10, 4.311
1435              - 2.722e3/temperature_K
1436              + 8.565e5/(temperature_K *temperature_K)
1437              - 1.181e8/(temperature_K*temperature_K*temperature_K ))*1e-9*m2/s;
1438 }
1439 
1440 //______________________________________________________________________________
1441 
1442 void
1443 G4MolecularConfiguration::
1444 ScaleAllDiffusionCoefficientsOnWater(double temperature_K)
1445 {
1446   double D_water_0 = DiffCoeffWater(fgTemperature);
1447   double D_water_f = DiffCoeffWater(temperature_K);
1448 
1449   G4cout << "Scaling factor = " << D_water_f/D_water_0 << G4endl;
1450 
1451   G4ConfigurationIterator it =
1452       G4MoleculeTable::Instance()->GetConfigurationIterator();
1453 
1454   while(it())
1455   {
1456     G4MolecularConfiguration* conf = it.value();
1457     double D_0 = conf->GetDiffusionCoefficient() ;
1458     double D_f = D_water_f * D_0 /D_water_0;
1459     conf->SetDiffusionCoefficient(D_f);
1460   };
1461 }
1462 
1463 //______________________________________________________________________________
1464 
1465 void G4MolecularConfiguration::CreateDefaultDiffCoeffParam()
1466 {
1467   if(!static_cast<bool>(fDiffParam))
1468   {
1469     fDiffParam = &G4MolecularConfiguration::ReturnDefaultDiffCoeff;
1470   }
1471 }
1472 
1473 //______________________________________________________________________________
1474 
1475 void G4MolecularConfiguration::SetGlobalTemperature(G4double temperature)
1476 {
1477   ScaleAllDiffusionCoefficientsOnWater(temperature);
1478   fgTemperature = temperature;
1479 }
1480 
1481 //______________________________________________________________________________
1482 
1483 G4double G4MolecularConfiguration::GetGlobalTemperature()
1484 {
1485   return fgTemperature;
1486 }
1487 
1488 //______________________________________________________________________________
1489 
1490 G4MolecularConfiguration*
1491 G4MolecularConfiguration::
1492 G4MolecularConfigurationManager::GetMolecularConfiguration(const G4String& userID)
1493 {
1494   for(auto it : fMolConfPerID)
1495   {
1496     if(it->GetUserID() == userID) return it;
1497   }
1498   return nullptr;
1499 }
1500 
1501 //______________________________________________________________________________
1502 
1503 G4MolecularConfiguration*
1504 G4MolecularConfiguration::GetMolecularConfiguration(const G4String& userID)
1505 {
1506   return GetManager()->GetMolecularConfiguration(userID);
1507 }
1508 
1509 //______________________________________________________________________________
1510 
1511 void G4MolecularConfiguration::FinalizeAll()
1512 {
1513   const std::vector<G4MolecularConfiguration*>& species =
1514       GetManager()->GetAllSpecies();
1515 
1516   for(auto specie : species)
1517   {
1518     specie->Finalize();
1519   }
1520 
1521 }
1522 
1523 void G4MolecularConfiguration::PrintAll() //hoang added
1524 {
1525   const std::vector<G4MolecularConfiguration*>& species =
1526     GetManager()->GetAllSpecies();
1527   G4cout<<G4endl;
1528   G4cout<<"Molecular Config"<<std::setw(25)<<" | Diffusion Coefficient (m2 / s) "<<std::setw(20)<<" | Radius (nm) "<<G4endl;
1529   G4cout<<"__________________________________________"
1530             "___________________________________"<<G4endl;
1531   for(auto specie : species)
1532   {
1533     G4cout<<specie->GetName()
1534            <<std::setw(G4int(30 - specie->GetName().length()))
1535            <<right<<specie->GetDiffusionCoefficient() * 1.0e3<<std::setw(30)
1536            <<specie->GetVanDerVaalsRadius()/CLHEP::nm<<G4endl;
1537     G4cout<<"__________________________________________"
1538               "___________________________________"<<G4endl;
1539   }
1540 
1541 }
1542