Geant4  10.01.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 86986 2014-11-21 13:00:05Z 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  MapForHEP::iterator j;
88  for (j = managersForHEP.begin(); j != managersForHEP.end(); ++j)
89  { delete j->second; }
90 #ifdef G4MULTITHREADED
91  }
92 #endif
93 }
94 
95 void
97  const G4String& filename)
98 {
99  if (Z<1 || A<2) {
100  G4cout<<"G4NuclearLevelStore::AddUserEvaporationDataFile "
101  <<" Z= " << Z << " and A= " << A << " not valid!"<<G4endl;
102  }
103 
104  std::ifstream DecaySchemeFile(filename);
105  if (DecaySchemeFile){
106  G4int ID_ion=Z*1000+A;//A*1000+Z;
107  theUserDataFiles[ID_ion]=filename;
108  userFiles = true;
109  }
110  else {
111  G4cout<<"The file "<<filename<<" does not exist!"<<G4endl;
112  }
113 }
114 
115 G4String
117 {
118  std::ostringstream streamName;
119  streamName << 'z' << Z << ".a" << A;
120  G4String name(streamName.str());
121  return name;
122 }
123 
126 {
127  G4NuclearLevelManager * result = 0;
128  if (A < 1 || Z < 1 || A < Z)
129  {
130  //G4cerr << "G4NuclearLevelStore::GetManager: Wrong values Z = " << Z
131  // << " A = " << A << '\n';
132  return result;
133  }
134 
135  // Generate the key = filename
136  G4int key = Z*1000+A; //GenerateKey(Z,A);
137 
138  // Check if already exists that key
139  ManagersMap::iterator idx = theManagers.find(key);
140 
141 #ifdef G4MULTITHREADED
142  // If doesn't exists then check the master
143  if ( idx == theManagers.end() )
144  {
145  G4MUTEXLOCK(&G4NuclearLevelStore::nuclearLevelStoreMutex);
146  ManagersMap::iterator idxS = theShadowInstance->theManagers.find(key);
147  if ( idxS == theShadowInstance->theManagers.end() )
148  {
149  // If doesn't exists then create it
150  G4String file = dirName + GenerateFileName(Z,A);
151 
152  //Check if data have been provided by the user
153  if(userFiles) {
154  G4String file1 = theUserDataFiles[key];//1000*A+Z];
155  if (file1 != "") { file = file1; }
156  }
157  result = new G4NuclearLevelManager(Z,A,file);
158  theShadowInstance->theManagers.insert(std::make_pair(key,result));
159  }
160  else
161  {
162  // if it exists in the master
163  result = idxS->second;
164  }
165  // register to the local map
166  theManagers.insert(std::make_pair(key,result));
167  G4MUTEXUNLOCK(&G4NuclearLevelStore::nuclearLevelStoreMutex);
168  }
169 #else
170  // If doesn't exists then create it
171  if ( idx == theManagers.end() )
172  {
173  G4String file = dirName + GenerateFileName(Z,A);
174 
175  //Check if data have been provided by the user
176  if(userFiles) {
177  G4String file1 = theUserDataFiles[key];//1000*A+Z];
178  if (file1 != "") { file = file1; }
179  }
180  result = new G4NuclearLevelManager(Z,A,file);
181  theManagers.insert(std::make_pair(key,result));
182  }
183 #endif
184  else
185  // But if it exists...
186  {
187  result = idx->second;
188  }
189 
190  return result;
191 }
192 
195 {
196  G4LevelManager * result = 0;
197  // Generate the key = filename
198  G4int key = Z*1000+A;
199 
200  // Check if already exists that key
201  MapForHEP::iterator idx = managersForHEP.find(key);
202 
203 #ifdef G4MULTITHREADED
204  // If doesn't exists check the master
205  if ( idx == managersForHEP.end() ) {
206  G4MUTEXLOCK(&G4NuclearLevelStore::nuclearLevelStoreMutex);
207  MapForHEP::iterator idxS = theShadowInstance->managersForHEP.find(key);
208  if ( idxS == theShadowInstance->managersForHEP.end() ) {
209  // If doesn't exists create it
210  result = new G4LevelManager(Z,A,reader,
211  dirName + GenerateFileName(Z,A));
212  theShadowInstance->managersForHEP.insert(std::make_pair(key,result));
213  }
214  else
215  { result = idxS->second; }
216  // register to the local map
217  managersForHEP.insert(std::make_pair(key,result));
218  G4MUTEXUNLOCK(&G4NuclearLevelStore::nuclearLevelStoreMutex);
219  }
220 #else
221  // If doesn't exists then create it
222  if ( idx == managersForHEP.end() ) {
223  result = new G4LevelManager(Z,A,reader,
224  dirName + GenerateFileName(Z,A));
225  managersForHEP.insert(std::make_pair(key,result));
226  }
227 #endif
228  else
229  // it exists
230  {
231  result = idx->second;
232  }
233 
234  return result;
235 }
#define G4MUTEXUNLOCK
Definition: G4Threading.hh:176
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:171
static G4ThreadLocal G4NuclearLevelStore * theInstance
void AddUserEvaporationDataFile(G4int Z, G4int A, const G4String &filename)
G4GLOB_DLL std::ostream G4cout
G4LevelManager * GetLevelManager(G4int Z, G4int A)
#define G4MUTEXLOCK
Definition: G4Threading.hh:175
static const G4double A[nN]
G4NuclearLevelManager * GetManager(G4int Z, G4int A)
G4int G4Mutex
Definition: G4Threading.hh:169
#define G4endl
Definition: G4ios.hh:61
G4String GenerateFileName(G4int Z, G4int A) const