Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/utils/src/G4DNAMolecularReactionTable.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 // WARNING : This class is released as a prototype.
 30 // It might strongly evolve or even disapear in the next releases.
 31 //
 32 // History:
 33 // -----------
 34 // 10 Oct 2011 M.Karamitros created
 35 //
 36 // -------------------------------------------------------------------
 37 
 38 #include <iomanip>
 39 
 40 #include "G4DNAMolecularReactionTable.hh"
 41 #include "G4PhysicalConstants.hh"
 42 #include "G4SystemOfUnits.hh"
 43 #include "G4UIcommand.hh"
 44 #include "G4VDNAReactionModel.hh"
 45 #include "G4MoleculeHandleManager.hh"
 46 #include "G4MoleculeTable.hh"
 47 #include "G4MolecularConfiguration.hh"
 48 #include "G4ReactionTableMessenger.hh"
 49 #include "G4IosFlagsSaver.hh"
 50 #include "G4Exp.hh"
 51 
 52 using namespace std;
 53 
 54 G4DNAMolecularReactionTable* G4DNAMolecularReactionTable::fpInstance(nullptr);
 55 
 56 G4DNAMolecularReactionData::G4DNAMolecularReactionData()
 57     : fpReactant1(nullptr)
 58     , fpReactant2(nullptr)
 59     , fObservedReactionRate(0.)
 60     , fActivationRate(0.)
 61     , fDiffusionRate(0.)
 62     , fOnsagerRadius(0.)
 63     , fReactionRadius(0.)
 64     , fEffectiveReactionRadius(0.)
 65     , fProbability(0.)
 66     , fType(0)
 67     , fReactionID(0)
 68 {
 69 }
 70 
 71 G4DNAMolecularReactionData::G4DNAMolecularReactionData(G4double reactionRate,
 72                                                        Reactant* pReactant1,
 73                                                        Reactant* pReactant2)
 74     : fpReactant1(pReactant1)
 75     , fpReactant2(pReactant2)
 76     , fObservedReactionRate(reactionRate)
 77     , fActivationRate(0.)
 78     , fDiffusionRate(0.)
 79     , fOnsagerRadius(0.)
 80     , fReactionRadius(0.)
 81     , fEffectiveReactionRadius(0.)
 82     , fProbability(0.)
 83     , fType(0)
 84     , fReactionID(0)
 85 {
 86     ComputeEffectiveRadius();
 87 }
 88 
 89 G4DNAMolecularReactionData::G4DNAMolecularReactionData(G4double reactionRate,
 90                                                        const G4String& reactant1,
 91                                                        const G4String& reactant2)
 92     : fpReactant1(nullptr)
 93     , fpReactant2(nullptr)
 94     , fObservedReactionRate(reactionRate)
 95     , fActivationRate(0.)
 96     , fDiffusionRate(0.)
 97     , fOnsagerRadius(0.)
 98     , fReactionRadius(0.)
 99     , fEffectiveReactionRadius(0.)
100     , fProbability(0.)
101     , fType(0)
102     , fReactionID(0)
103 {
104     SetReactant1(reactant1);
105     SetReactant2(reactant2);
106     ComputeEffectiveRadius();
107 }
108 
109 G4DNAMolecularReactionData::~G4DNAMolecularReactionData()
110 {
111      fProducts.clear();
112 }
113 
114 void G4DNAMolecularReactionData::ComputeEffectiveRadius()
115 {
116     G4double sumDiffCoeff = 0.;
117 
118     if (fpReactant1 == fpReactant2)
119     {
120         sumDiffCoeff = fpReactant1->GetDiffusionCoefficient();
121         fEffectiveReactionRadius = fObservedReactionRate / (4. * CLHEP::pi * sumDiffCoeff * CLHEP::Avogadro);
122     }
123     else
124     {
125         sumDiffCoeff = fpReactant1->GetDiffusionCoefficient()
126                      + fpReactant2->GetDiffusionCoefficient();
127         fEffectiveReactionRadius = fObservedReactionRate / (4. * CLHEP::pi * sumDiffCoeff * CLHEP::Avogadro);
128     }
129 
130     fReactionID = 0;
131     fReactionRadius = fEffectiveReactionRadius;
132     fOnsagerRadius = (fpReactant1->GetCharge() * fpReactant2->GetCharge())/(4*pi*epsilon0*k_Boltzmann) / (293.15 * 80.1) ;
133     fProbability = 1;
134 
135 }
136 
137 int G4DNAMolecularReactionData::GetReactionID() const
138 {
139     return fReactionID;
140 }
141 
142 void G4DNAMolecularReactionData::SetReactionID(int ID)
143 {
144     fReactionID = ID;
145 }
146 
147 void G4DNAMolecularReactionData::SetReactant1(Reactant* pReactive)
148 {
149     fpReactant1 = pReactive;
150 }
151 
152 void G4DNAMolecularReactionData::SetReactant2(Reactant* pReactive)
153 {
154     fpReactant2 = pReactive;
155 }
156 
157 void G4DNAMolecularReactionData::SetReactants(Reactant* pReactant1,
158                                               Reactant* pReactant2)
159 {
160     fpReactant1 = pReactant1;
161     fpReactant2 = pReactant2;
162 }
163 
164 void G4DNAMolecularReactionData::AddProduct(Reactant* pMolecule)
165 {
166     fProducts.push_back(pMolecule);
167 }
168 
169 G4int G4DNAMolecularReactionData::GetNbProducts() const
170 {
171     return (G4int)fProducts.size();
172 }
173 
174 G4DNAMolecularReactionData::Reactant* G4DNAMolecularReactionData::GetProduct(G4int i) const
175 {
176     return fProducts[i];
177 }
178 
179 const G4DNAMolecularReactionData::ReactionProducts* G4DNAMolecularReactionData::GetProducts() const
180 {
181     return &fProducts;
182 }
183 
184 void G4DNAMolecularReactionData::RemoveProducts()
185 {
186     fProducts.clear();
187 }
188 
189 void G4DNAMolecularReactionData::SetReactant1(const G4String& reactive)
190 {
191     fpReactant1 = G4MoleculeTable::Instance()->GetConfiguration(reactive);
192 }
193 void G4DNAMolecularReactionData::SetReactant2(const G4String& reactive)
194 {
195     fpReactant2 = G4MoleculeTable::Instance()->GetConfiguration(reactive);
196 }
197 void G4DNAMolecularReactionData::SetReactants(const G4String& reactant1,
198                                               const G4String& reactant2)
199 {
200     fpReactant1 = G4MoleculeTable::Instance()->GetConfiguration(reactant1);
201     fpReactant2 = G4MoleculeTable::Instance()->GetConfiguration(reactant2);
202 }
203 
204 G4DNAMolecularReactionData::ReactantPair G4DNAMolecularReactionData::GetReactants()
205 {
206     return std::make_pair(fpReactant1, fpReactant2);
207 }
208 
209 G4DNAMolecularReactionData::Reactant* G4DNAMolecularReactionData::GetReactant1() const
210 {
211     return fpReactant1;
212 }
213 
214 G4DNAMolecularReactionData::Reactant* G4DNAMolecularReactionData::GetReactant2() const
215 {
216     return fpReactant2;
217 }
218 
219 void G4DNAMolecularReactionData::SetObservedReactionRateConstant(G4double rate)
220 {
221     fObservedReactionRate = rate;
222 }
223 
224 G4double G4DNAMolecularReactionData::GetObservedReactionRateConstant() const
225 {
226     return fObservedReactionRate;
227 }
228 
229 G4double G4DNAMolecularReactionData::GetActivationRateConstant() const
230 {
231     return fActivationRate;
232 }
233 
234 G4double G4DNAMolecularReactionData::GetDiffusionRateConstant() const
235 {
236     return fDiffusionRate;
237 }
238 
239 void G4DNAMolecularReactionData::SetReactionRadius(G4double radius)
240 {
241     fReactionRadius = radius;
242     fEffectiveReactionRadius = -fOnsagerRadius / (1-exp(fOnsagerRadius / fReactionRadius));
243 }
244 
245 G4double G4DNAMolecularReactionData::GetReactionRadius() const
246 {
247     return fReactionRadius;
248 }
249 
250 void G4DNAMolecularReactionData::SetEffectiveReactionRadius(G4double radius)
251 {
252     fEffectiveReactionRadius = radius;
253 }
254 
255 G4double G4DNAMolecularReactionData::GetEffectiveReactionRadius() const
256 {
257     return fEffectiveReactionRadius;
258 }
259 
260 G4double G4DNAMolecularReactionData::GetOnsagerRadius() const
261 {
262     return fOnsagerRadius;
263 }
264 
265 G4double G4DNAMolecularReactionData::GetProbability() const
266 {
267     return fProbability;
268 }
269 
270 void G4DNAMolecularReactionData::SetProbability(G4double prob)
271 {
272     fProbability = prob;
273 }
274 
275 void G4DNAMolecularReactionData::SetReactionType(G4int type)
276 {
277     G4double sumDiffCoeff = 0.;
278 
279     if(type == 1)
280     {
281 
282         sumDiffCoeff = fpReactant1->GetDiffusionCoefficient() + 
283                        fpReactant2->GetDiffusionCoefficient();
284 
285         fReactionRadius = fpReactant1->GetVanDerVaalsRadius() +
286                           fpReactant2->GetVanDerVaalsRadius();
287 
288         G4double Rs = 0.29 * nm;
289         if(fOnsagerRadius == 0) // Type II
290         {
291             fEffectiveReactionRadius = fReactionRadius;
292             fDiffusionRate = 4 * pi * sumDiffCoeff * fReactionRadius * Avogadro;
293             if (fpReactant1 == fpReactant2) fDiffusionRate/=2;
294             fActivationRate = fDiffusionRate * fObservedReactionRate / (fDiffusionRate - fObservedReactionRate);
295             fProbability =  Rs / (Rs + (fDiffusionRate / fActivationRate) * (fReactionRadius + Rs));
296 
297         }else{ // Type IV
298             fEffectiveReactionRadius = -fOnsagerRadius/(1-exp(fOnsagerRadius/fReactionRadius));
299             fDiffusionRate = 4 * pi * sumDiffCoeff * fEffectiveReactionRadius * Avogadro;
300             if (fpReactant1 == fpReactant2) fDiffusionRate/=2;
301 
302             fActivationRate = fDiffusionRate * fObservedReactionRate / (fDiffusionRate - fObservedReactionRate);
303             fProbability = Rs / (Rs + (fDiffusionRate / fActivationRate) * (fEffectiveReactionRadius + Rs));
304         }
305     }
306 
307     fType = type;
308 }
309 
310 G4int G4DNAMolecularReactionData::GetReactionType() const
311 {
312     return fType;
313 }
314 
315 void G4DNAMolecularReactionData::AddProduct(const G4String& molecule)
316 {
317     fProducts.push_back(G4MoleculeTable::Instance()->GetConfiguration(molecule));
318 }
319 
320 double G4DNAMolecularReactionData::PolynomialParam(double temp_K, std::vector<double> P)
321 {
322     double inv_temp = 1. / temp_K;
323 
324     return pow(10,
325                P[0] + P[1] * inv_temp + P[2] * pow(inv_temp, 2)
326                + P[3] * pow(inv_temp, 3) + P[4] * pow(inv_temp, 4))
327         * (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s));
328 }
329 
330 double G4DNAMolecularReactionData::ArrehniusParam(double temp_K, std::vector<double> P)
331 {
332     return P[0] * G4Exp(P[1] / temp_K)*
333         (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s));
334 }
335 
336 double G4DNAMolecularReactionData::ScaledParameterization(double temp_K,
337                                                           double temp_init,
338                                                           double rateCste_init)
339 {
340     double D0 = G4MolecularConfiguration::DiffCoeffWater(temp_init);
341     double Df = G4MolecularConfiguration::DiffCoeffWater(temp_K);
342     return Df * rateCste_init / D0;
343 }
344 
345 //==============================================================================
346 // REACTION TABLE
347 //==============================================================================
348 
349 G4DNAMolecularReactionTable* G4DNAMolecularReactionTable::GetReactionTable()
350 {
351     if (fpInstance == nullptr)
352     {
353         fpInstance = new G4DNAMolecularReactionTable();
354     }
355     return fpInstance;
356 }
357 
358 //_____________________________________________________________________________________
359 
360 G4DNAMolecularReactionTable* G4DNAMolecularReactionTable::Instance()
361 {
362     if (fpInstance == nullptr)
363     {
364         fpInstance = new G4DNAMolecularReactionTable();
365     }
366     return fpInstance;
367 }
368 
369 //_____________________________________________________________________________________
370 
371 void G4DNAMolecularReactionTable::DeleteInstance()
372 {
373     
374     
375         delete fpInstance;
376     
377     fpInstance = nullptr;
378 }
379 
380 //_____________________________________________________________________________________
381 
382 G4DNAMolecularReactionTable::G4DNAMolecularReactionTable()
383     : 
384      fpMessenger(new G4ReactionTableMessenger(this))
385 {
386 }
387 
388 G4DNAMolecularReactionTable::~G4DNAMolecularReactionTable() = default;
389 
390 void G4DNAMolecularReactionTable::SetReaction(G4DNAMolecularReactionData* pReactionData)
391 {
392     const auto pReactant1 = pReactionData->GetReactant1();
393     const auto pReactant2 = pReactionData->GetReactant2();
394 
395     fReactionData[pReactant1][pReactant2] = pReactionData;
396     fReactantsMV[pReactant1].push_back(pReactant2);
397     fReactionDataMV[pReactant1].push_back(pReactionData);
398 
399     if (pReactant1 != pReactant2)
400     {
401         fReactionData[pReactant2][pReactant1] = pReactionData;
402         fReactantsMV[pReactant2].push_back(pReactant1);
403         fReactionDataMV[pReactant2].push_back(pReactionData);
404     }
405 
406     fVectorOfReactionData.emplace_back(pReactionData);
407     pReactionData->SetReactionID((G4int)fVectorOfReactionData.size());
408 }
409 
410 //_____________________________________________________________________________________
411 
412 void G4DNAMolecularReactionTable::SetReaction(G4double reactionRate,
413                                               Reactant* pReactant1,
414                                               Reactant* pReactant2)
415 {
416     auto reactionData = new G4DNAMolecularReactionData(reactionRate, pReactant1, pReactant2);
417     SetReaction(reactionData);
418 }
419 
420 //_____________________________________________________________________________________
421 
422 void G4DNAMolecularReactionTable::PrintTable(G4VDNAReactionModel* pReactionModel)
423 {
424     // Print Reactions and Interaction radius for jump step = 3ps
425 
426     G4IosFlagsSaver iosfs(G4cout);
427 
428    if ((pReactionModel != nullptr) && ((pReactionModel->GetReactionTable()) == nullptr))
429    {
430        pReactionModel->SetReactionTable(this);
431    }
432 
433     ReactivesMV::iterator itReactives;
434 
435     std::map<Reactant*, std::map<Reactant*, G4bool>> alreadyPrint;
436 
437     G4cout << "Number of chemical species involved in reactions = "
438            << fReactantsMV.size() << G4endl;
439 
440     std::size_t nbPrintable = fReactantsMV.size() * fReactantsMV.size();
441 
442     auto  outputReaction = new G4String[nbPrintable];
443     auto  outputReactionRate = new G4String[nbPrintable];
444     auto  outputRange = new G4String[nbPrintable];
445     G4int n = 0;
446 
447     for (itReactives = fReactantsMV.begin(); itReactives != fReactantsMV.end();
448          ++itReactives)
449     {
450         auto  moleculeA = (Reactant*)itReactives->first;
451         const vector<Reactant*>* reactivesVector = CanReactWith(moleculeA);
452 
453         if (pReactionModel != nullptr) pReactionModel->InitialiseToPrint(moleculeA);
454 
455         auto  nbReactants = (G4int)fReactantsMV[itReactives->first].size();
456 
457         for (G4int iReact = 0; iReact < nbReactants; iReact++)
458         {
459             auto moleculeB = (Reactant*)(*reactivesVector)[iReact];
460 
461             Data* reactionData = fReactionData[moleculeA][moleculeB];
462 
463             //-----------------------------------------------------------
464             // Name of the reaction
465             if (!alreadyPrint[moleculeA][moleculeB])
466             {
467                 outputReaction[n] = moleculeA->GetName() + " + " + moleculeB->GetName();
468 
469                 G4int nbProducts = reactionData->GetNbProducts();
470 
471                 if (nbProducts != 0)
472                 {
473                     outputReaction[n] += " -> " + reactionData->GetProduct(0)->GetName();
474 
475                     for (G4int j = 1; j < nbProducts; j++)
476                     {
477                         outputReaction[n] += " + " + reactionData->GetProduct(j)->GetName();
478                     }
479                 }
480                 else
481                 {
482                     outputReaction[n] += " -> No product";
483                 }
484 
485                 //-----------------------------------------------------------
486                 // Interaction Rate
487                 outputReactionRate[n] = G4UIcommand::ConvertToString(
488                     reactionData->GetObservedReactionRateConstant() / (1e-3 * m3 / (mole * s)));
489 
490                 //-----------------------------------------------------------
491                 // Calculation of the Interaction Range
492                 G4double interactionRange = -1;
493                 if (pReactionModel != nullptr) interactionRange =
494                     pReactionModel->GetReactionRadius(iReact);
495 
496                 if (interactionRange != -1)
497                 {
498                     outputRange[n] = G4UIcommand::ConvertToString(
499                         interactionRange / nanometer);
500                 }
501                 else
502                 {
503                     outputRange[n] = "";
504                 }
505 
506                 alreadyPrint[moleculeB][moleculeA] = TRUE;
507                 n++;
508             }
509         }
510     }
511     // G4cout<<"Number of possible reactions: "<< n << G4endl;
512 
513     ////////////////////////////////////////////////////////////////////
514     // Tableau dynamique en fonction du nombre de caractere maximal dans
515     // chaque colonne
516     ////////////////////////////////////////////////////////////////////
517 
518     G4int maxlengthOutputReaction = -1;
519     G4int maxlengthOutputReactionRate = -1;
520 
521     for (G4int i = 0; i < n; ++i)
522     {
523         if (maxlengthOutputReaction < (G4int)outputReaction[i].length())
524         {
525             maxlengthOutputReaction = (G4int)outputReaction[i].length();
526         }
527         if (maxlengthOutputReactionRate < (G4int)outputReactionRate[i].length())
528         {
529             maxlengthOutputReactionRate = (G4int)outputReactionRate[i].length();
530         }
531     }
532 
533     maxlengthOutputReaction += 2;
534     maxlengthOutputReactionRate += 2;
535 
536     if (maxlengthOutputReaction < 10) maxlengthOutputReaction = 10;
537     if (maxlengthOutputReactionRate < 30) maxlengthOutputReactionRate = 30;
538 
539     G4String* title;
540 
541     if (pReactionModel != nullptr) title = new G4String[3];
542     else title = new G4String[2];
543 
544     title[0] = "Reaction";
545     title[1] = "Reaction Rate [dm3/(mol*s)]";
546 
547     if (pReactionModel != nullptr) title[2] =
548         "Interaction Range for chosen reaction model [nm]";
549 
550     G4cout << setfill(' ') << setw(maxlengthOutputReaction) << left << title[0]
551         << setw(maxlengthOutputReactionRate) << left << title[1];
552 
553     if (pReactionModel != nullptr) G4cout << setw(2) << left << title[2];
554 
555     G4cout << G4endl;
556 
557     G4cout.fill('-');
558     if (pReactionModel != nullptr) G4cout.width(
559         maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
560         + (G4int)title[2].length());
561     else G4cout.width(maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
562     G4cout << "-" << G4endl;
563     G4cout.fill(' ');
564 
565     for (G4int i = 0; i < n; i++)
566     {
567         G4cout << setw(maxlengthOutputReaction) << left << outputReaction[i]
568                << setw(maxlengthOutputReactionRate) << left
569                << outputReactionRate[i];
570 
571         if (pReactionModel != nullptr) G4cout << setw(2) << left << outputRange[i];
572 
573         G4cout << G4endl;
574 
575         G4cout.fill('-');
576         if (pReactionModel != nullptr) G4cout.width(
577             maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
578             + (G4int)title[2].length());
579         else G4cout.width(
580             maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
581         G4cout << "-" << G4endl;
582         G4cout.fill(' ');
583     }
584 
585     delete[] title;
586     delete[] outputReaction;
587     delete[] outputReactionRate;
588     delete[] outputRange;
589 }
590 
591 //______________________________________________________________________________
592 // Get/Set methods
593 
594 G4VDNAMolecularGeometry* G4DNAMolecularReactionTable::GetGeometry() const
595 {
596   return fGeometry;
597 }
598 
599 G4DNAMolecularReactionTable::Data*
600 G4DNAMolecularReactionTable::GetReactionData(Reactant* pReactant1,
601                                              Reactant* pReactant2) const
602 {
603     if (fReactionData.empty())
604     {
605         G4String errMsg = "No reaction table was implemented";
606         G4Exception("G4MolecularInteractionTable::GetReactionData", "",
607                     FatalErrorInArgument, errMsg);
608     }
609 
610     auto it1 = fReactionData.find(pReactant1);
611 
612     if (it1 == fReactionData.end())
613     {
614         G4String errMsg =
615             "No reaction table was implemented for this molecule Definition : " + pReactant1
616             ->GetName();
617         G4Exception("G4MolecularInteractionTable::GetReactionData", "",
618                     FatalErrorInArgument, errMsg);
619         // Though the above is Fatal and will terminate program, put return in to quieten Coverity
620         return nullptr;
621     }
622 
623     auto it2 = it1->second.find(pReactant2);
624 
625     if (it2 == it1->second.end())
626     {
627         G4cout << "Name : " << pReactant2->GetName() << G4endl;
628         G4String errMsg = "No reaction table was implemented for this molecule : "
629             + pReactant2->GetName();
630         G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
631     }
632 
633     return (it2->second);
634 }
635 
636 const G4DNAMolecularReactionTable::ReactionDataMap& G4DNAMolecularReactionTable::GetAllReactionData()
637 {
638     return fReactionData;
639 }
640 
641 G4DNAMolecularReactionTable::DataList G4DNAMolecularReactionTable::GetVectorOfReactionData()
642 {
643     DataList dataList;
644 
645     for (const auto& pData : fVectorOfReactionData)
646     {
647         dataList.emplace_back(pData.get());
648     }
649 
650     return dataList;
651 }
652 
653 //______________________________________________________________________________
654 
655 const G4DNAMolecularReactionTable::ReactantList*
656 G4DNAMolecularReactionTable::CanReactWith(Reactant* pMolecule) const
657 {
658     if (fReactantsMV.empty())
659     {
660         G4String errMsg = "No reaction table was implemented";
661         G4Exception("G4MolecularInteractionTable::CanReactWith", "",
662                     FatalErrorInArgument, errMsg);
663         return nullptr;
664     }
665 
666     auto itReactivesMap = fReactantsMV.find(pMolecule);
667 
668     if (itReactivesMap == fReactantsMV.end())
669     {
670 #ifdef G4VERBOSE
671         if (fVerbose)
672         {
673             G4String errMsg = "No reaction table was implemented for this molecule : "
674                 + pMolecule->GetName();
675             //          G4Exception("G4MolecularInteractionTable::CanReactWith","",FatalErrorInArgument, errMsg);
676             G4cout << "--- G4MolecularInteractionTable::GetReactionData ---" << G4endl;
677             G4cout << errMsg << G4endl;
678         }
679 #endif
680         return nullptr;
681     }
682 
683     if (fVerbose)
684     {
685         G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
686         G4cout << "You are checking reactants for : " << pMolecule->GetName() << G4endl;
687         G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
688 
689         auto itProductsVector = itReactivesMap->second.cbegin();
690 
691         for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
692         {
693             G4cout << (*itProductsVector)->GetName() << G4endl;
694         }
695     }
696     return &(itReactivesMap->second);
697 }
698 
699 //______________________________________________________________________________
700 
701 const G4DNAMolecularReactionTable::SpecificDataList*
702 G4DNAMolecularReactionTable::GetReativesNData(const G4MolecularConfiguration* molecule) const
703 {
704     if (fReactionData.empty())
705     {
706         G4String errMsg = "No reaction table was implemented";
707         G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
708                     FatalErrorInArgument, errMsg);
709     }
710 
711     auto itReactivesMap = fReactionData.find(molecule);
712 
713     if (itReactivesMap == fReactionData.end())
714     {
715         return nullptr;
716     }
717 
718     if (fVerbose)
719     {
720         G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
721         G4cout << "You are checking reactants for : " << molecule->GetName() << G4endl;
722         G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
723 
724         auto itProductsVector = itReactivesMap->second.begin();
725 
726         for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
727         {
728             G4cout << itProductsVector->first->GetName() << G4endl;
729         }
730     }
731     return &(itReactivesMap->second);
732 }
733 
734 //______________________________________________________________________________
735 
736 const G4DNAMolecularReactionTable::DataList*
737 G4DNAMolecularReactionTable::GetReactionData(const G4MolecularConfiguration* molecule) const
738 {
739     if (fReactionDataMV.empty())
740     {
741         G4String errMsg = "No reaction table was implemented";
742         G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
743                     FatalErrorInArgument, errMsg);
744     }
745     auto it = fReactionDataMV.find(molecule);
746 
747     if (it == fReactionDataMV.end())
748     {
749         G4String errMsg = "No reaction table was implemented for this molecule Definition : "
750             + molecule->GetName();
751         G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
752         // Though the above is Fatal and will terminate program, put return in to quieten Coverity
753         return nullptr;
754     }
755 
756     return &(it->second);
757 }
758 
759 //______________________________________________________________________________
760 
761 G4DNAMolecularReactionTable::Data* G4DNAMolecularReactionTable::GetReactionData(const G4String& mol1,
762                                                                                 const G4String& mol2) const
763 {
764     const auto pConf1 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol1);
765     const auto pConf2 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol2);
766     return GetReactionData(pConf1, pConf2);
767 }
768 
769 //______________________________________________________________________________
770 
771 void
772 G4DNAMolecularReactionData::SetPolynomialParameterization(const std::vector<double>& P)
773 {
774     fRateParam = std::bind(PolynomialParam, std::placeholders::_1, P);
775 }
776 
777 //______________________________________________________________________________
778 
779 void G4DNAMolecularReactionData::SetArrehniusParameterization(double A0,
780                                                               double E_R)
781 {
782     std::vector<double> P = { A0, E_R };
783     fRateParam = std::bind(ArrehniusParam, std::placeholders::_1, P);
784 }
785 
786 //______________________________________________________________________________
787 
788 void G4DNAMolecularReactionData::SetScaledParameterization(double temperature_K,
789                                                            double rateCste)
790 {
791     fRateParam = std::bind(ScaledParameterization,
792                            std::placeholders::_1,
793                            temperature_K,
794                            rateCste);
795 }
796 
797 //______________________________________________________________________________
798 
799 void G4DNAMolecularReactionTable::ScaleReactionRateForNewTemperature(double temp_K)
800 {
801     for (const auto& pData : fVectorOfReactionData)
802     {
803         const_cast<G4DNAMolecularReactionData*>(pData.get())->ScaleForNewTemperature(temp_K);
804     }
805 }
806 
807 //______________________________________________________________________________
808 
809 void G4DNAMolecularReactionData::ScaleForNewTemperature(double temp_K)
810 {
811     if (fRateParam)
812     {
813         SetObservedReactionRateConstant(fRateParam(temp_K));
814     }
815 }
816 
817 //______________________________________________________________________________
818 
819 G4DNAMolecularReactionTable::Data*
820 G4DNAMolecularReactionTable::GetReaction(int reactionID) const
821 {
822     for (auto& pData : fVectorOfReactionData)
823     {
824         if (pData->GetReactionID() == reactionID)
825         {
826             return pData.get();
827         }
828     }
829     return nullptr;
830 }
831 
832 size_t G4DNAMolecularReactionTable::GetNReactions() const
833 {
834     return fVectorOfReactionData.size();
835 }
836 
837 void G4DNAMolecularReactionTable::Reset()
838 {
839     fReactionData.clear();
840     fReactantsMV.clear();
841     fReactionDataMV.clear();
842     fVectorOfReactionData.clear();
843 }
844