Geant4  10.02.p01
G4NuclearLevelStore.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: G4NuclearLevelStore.cc 88406 2015-02-18 09:13:29Z gcosmo $
27 //
28 // 06-10-2010 M. Kelsey -- Drop static data members.
29 // 17-11-2010 V. Ivanchenko - make as a classical singleton.
30 // 17-10-2011 V. L. Desorgher - allows to define separate datafile for
31 // given isotope
32 // 06-01-2012 V. Ivanchenko - cleanup the code; new method GetLevelManager
33 // 19-11-2014 M. Asai - protection against reading the same file from
34 // more than one worker threads
35 //
36 
37 #include "G4NuclearLevelStore.hh"
38 #include <sstream>
39 #include <fstream>
40 
42 #ifdef G4MULTITHREADED
43 G4NuclearLevelStore* G4NuclearLevelStore::theShadowInstance = 0;
44 G4Mutex G4NuclearLevelStore::nuclearLevelStoreMutex = G4MUTEX_INITIALIZER;
45 #endif
46 
48 {
49  if(!theInstance) {
51  theInstance = inst.Instance();
52  }
53 #ifdef G4MULTITHREADED
54  if(!theShadowInstance) {
55  static G4NuclearLevelStore shadowInst;
56  theShadowInstance = &shadowInst;
57  }
58 #endif
59  return theInstance;
60 }
61 
63 {
64  userFiles = false;
65  char* env = getenv("G4LEVELGAMMADATA");
66  if (env == 0)
67  {
68  G4cout << "G4NuclarLevelStore: please set the G4LEVELGAMMADATA environment variable\n";
69  dirName = "";
70  }
71  else
72  {
73  dirName = env;
74  dirName += '/';
75  }
76 }
77 
79 {
80 #ifdef G4MULTITHREADED
81  if(this==theShadowInstance) // G4NuclearLevelManager object should be deleted only by the master
82  {
83 #endif
84  ManagersMap::iterator i;
85  for (i = theManagers.begin(); i != theManagers.end(); ++i)
86  { delete i->second; }
87 #ifdef G4MULTITHREADED
88  }
89 #endif
90 }
91 
92 void
94  const G4String& filename)
95 {
96  if (Z<1 || A<2) {
97  G4cout<<"G4NuclearLevelStore::AddUserEvaporationDataFile "
98  <<" Z= " << Z << " and A= " << A << " not valid!"<<G4endl;
99  }
100 
101  std::ifstream DecaySchemeFile(filename);
102  if (DecaySchemeFile){
103  G4int ID_ion=Z*1000+A;//A*1000+Z;
104  theUserDataFiles[ID_ion]=filename;
105  userFiles = true;
106  }
107  else {
108  G4cout<<"The file "<<filename<<" does not exist!"<<G4endl;
109  }
110 }
111 
112 G4String
114 {
115  std::ostringstream streamName;
116  streamName << 'z' << Z << ".a" << A;
117  G4String name(streamName.str());
118  return name;
119 }
120 
123 {
124  G4NuclearLevelManager * result = 0;
125  if (A < 1 || Z < 1 || A < Z)
126  {
127  //G4cout << "G4NuclearLevelStore::GetManager: Wrong values Z = " << Z
128  // << " A = " << A << '\n';
129  return result;
130  }
131 
132  // Generate the key = filename
133  G4int key = Z*1000+A; //GenerateKey(Z,A);
134 
135  // Check if already exists that key
136  ManagersMap::iterator idx = theManagers.find(key);
137 
138 #ifdef G4MULTITHREADED
139  // If doesn't exists then check the master
140  if ( idx == theManagers.end() )
141  {
142  G4MUTEXLOCK(&G4NuclearLevelStore::nuclearLevelStoreMutex);
143  ManagersMap::iterator idxS = theShadowInstance->theManagers.find(key);
144  if ( idxS == theShadowInstance->theManagers.end() )
145  {
146  // If doesn't exists then create it
147  G4String file = dirName + GenerateFileName(Z,A);
148 
149  //Check if data have been provided by the user
150  if(userFiles) {
151  G4String file1 = theUserDataFiles[key];//1000*A+Z];
152  if (file1 != "") { file = file1; }
153  }
154  result = new G4NuclearLevelManager(Z,A,file);
155  theShadowInstance->theManagers.insert(std::make_pair(key,result));
156  }
157  else
158  {
159  // if it exists in the master
160  result = idxS->second;
161  }
162  // register to the local map
163  theManagers.insert(std::make_pair(key,result));
164  G4MUTEXUNLOCK(&G4NuclearLevelStore::nuclearLevelStoreMutex);
165  }
166 #else
167  // If doesn't exists then create it
168  if ( idx == theManagers.end() )
169  {
170  G4String file = dirName + GenerateFileName(Z,A);
171 
172  //Check if data have been provided by the user
173  if(userFiles) {
174  G4String file1 = theUserDataFiles[key];//1000*A+Z];
175  if (file1 != "") { file = file1; }
176  }
177  result = new G4NuclearLevelManager(Z,A,file);
178  theManagers.insert(std::make_pair(key,result));
179  }
180 #endif
181  else
182  // But if it exists...
183  {
184  result = idx->second;
185  }
186 
187  return result;
188 }
#define G4MUTEXUNLOCK
Definition: G4Threading.hh:180
std::map< G4int, G4String > theUserDataFiles
G4String name
Definition: TRTMaterials.hh:40
static G4NuclearLevelStore * GetInstance()
#define G4ThreadLocal
Definition: tls.hh:89
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
static G4ThreadLocal G4NuclearLevelStore * theInstance
void AddUserEvaporationDataFile(G4int Z, G4int A, const G4String &filename)
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
#define G4MUTEXLOCK
Definition: G4Threading.hh:179
G4NuclearLevelManager * GetManager(G4int Z, G4int A)
G4int G4Mutex
Definition: G4Threading.hh:173
#define G4endl
Definition: G4ios.hh:61
G4String GenerateFileName(G4int Z, G4int A) const