source: trunk/source/processes/electromagnetic/lowenergy/src/G4DNACrossSectionDataSet.cc @ 1347

Last change on this file since 1347 was 1347, checked in by garnier, 13 years ago

geant4 tag 9.4

File size: 14.5 KB
Line 
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
28// $Id: G4DNACrossSectionDataSet.cc,v 1.11 2009/11/12 10:05:30 sincerti Exp $
29// GEANT4 tag $Name: geant4-09-04-ref-00 $
30//
31// Author: Riccardo Capra <capra@ge.infn.it>
32// Code review by MGP October 2007: removed inheritance from concrete class
33//                                  more improvements needed
34//
35// History:
36// -----------
37// 30 Jun 2005  RC           Created
38// 14 Oct 2007  MGP          Removed inheritance from concrete class G4ShellEMDataSet
39//
40// 15 Jul 2009   N.A.Karakatsanis
41//
42//                           - LoadNonLogData method was created to load only the non-logarithmic data from G4EMLOW
43//                             dataset. It is essentially performing the data loading operations as in the past.
44//
45//                           - LoadData method was revised in order to calculate the logarithmic values of the data
46//                             It retrieves the data values from the G4EMLOW data files but, then, calculates the
47//                             respective log values and loads them to seperate data structures.
48//
49//                           - SetLogEnergiesData method was cretaed to set logarithmic values to G4 data vectors.
50//                             The EM data sets, initialized this way, contain both non-log and log values.
51//                             These initialized data sets can enhance the computing performance of data interpolation
52//                             operations
53//
54//
55// -------------------------------------------------------------------
56
57
58#include "G4DNACrossSectionDataSet.hh"
59#include "G4VDataSetAlgorithm.hh"
60#include "G4EMDataSet.hh"
61#include <vector>
62#include <fstream>
63#include <sstream>
64
65
66G4DNACrossSectionDataSet::G4DNACrossSectionDataSet(G4VDataSetAlgorithm* argAlgorithm, 
67                                                   G4double argUnitEnergies, 
68                                                   G4double argUnitData)
69  :
70   algorithm(argAlgorithm), unitEnergies(argUnitEnergies), unitData(argUnitData)
71{
72  z = 0;
73
74}
75
76
77G4DNACrossSectionDataSet::~G4DNACrossSectionDataSet()
78{
79  CleanUpComponents();
80 
81  if (algorithm)
82    delete algorithm;
83}
84
85G4bool G4DNACrossSectionDataSet::LoadData(const G4String & argFileName)
86{
87  CleanUpComponents();
88
89  G4String fullFileName(FullFileName(argFileName));
90  std::ifstream in(fullFileName, std::ifstream::binary|std::ifstream::in);
91
92  if (!in.is_open())
93    {
94      G4String message("G4DNACrossSectionDataSet::LoadData - data file \"");
95      message+=fullFileName;
96      message+="\" not found";
97      G4Exception(message);
98      return false;
99    }
100
101  std::vector<G4DataVector *> columns;
102  std::vector<G4DataVector *> log_columns;
103
104  std::stringstream *stream(new std::stringstream);
105  char c;
106  G4bool comment(false);
107  G4bool space(true);
108  G4bool first(true);
109
110  try
111    {
112      while (!in.eof())
113        {
114          in.get(c);
115   
116          switch (c)
117            {
118            case '\r':
119            case '\n':
120              if (!first)
121                {
122                  unsigned long i(0);
123                  G4double value;
124     
125                  while (!stream->eof())
126                    {
127                      (*stream) >> value;
128       
129                      while (i>=columns.size())
130                        {
131                         columns.push_back(new G4DataVector);
132                         log_columns.push_back(new G4DataVector);
133                        }
134     
135                      columns[i]->push_back(value);
136
137// N. A. Karakatsanis
138// A condition is applied to check if negative or zero values are present in the dataset.
139// If yes, then a near-zero value is applied to allow the computation of the logarithmic value
140// If a value is zero, this simplification is acceptable
141// If a value is negative, then it is not acceptable and the data of the particular column of
142// logarithmic values should not be used by interpolation methods.
143//
144// Therefore, G4LogLogInterpolation and G4LinLogLogInterpolation should not be used if negative values are present.
145// Instead, G4LinInterpolation is safe in every case
146// SemiLogInterpolation is safe only if the energy columns are non-negative
147// G4LinLogInterpolation is safe only if the cross section data columns are non-negative
148
149                      if (value <=0.) value = 1e-300;
150                      log_columns[i]->push_back(std::log10(value));
151       
152                      i++;
153                    }
154     
155                  delete stream;
156                  stream=new std::stringstream;
157                }
158     
159              first=true;
160              comment=false;
161              space=true;
162              break;
163     
164            case '#':
165              comment=true;
166              break;
167     
168            case '\t':
169              c=' ';
170            case ' ':
171              if (space)
172                break;
173            default:
174              if (comment)
175                break;
176     
177              if (c==' ')
178                space=true;
179              else
180                {
181                  if (space && (!first))
182                    (*stream) << ' ';
183     
184                  first=false;
185                  (*stream) << c;
186                  space=false;
187                }
188            }
189        }
190    }
191  catch(const std::ios::failure &e)
192    {
193      // some implementations of STL could throw a "failture" exception
194      // when read wants read characters after end of file
195    }
196 
197  delete stream;
198 
199  std::vector<G4DataVector *>::size_type maxI(columns.size());
200 
201  if (maxI<2)
202    {
203      G4String message("G4DNACrossSectionDataSet::LoadData - data file \"");
204      message+=fullFileName;
205      message+="\" should have at least two columns";
206      G4Exception(message);
207      return false;
208    }
209 
210  std::vector<G4DataVector*>::size_type i(1);
211  while (i<maxI)
212    {
213      G4DataVector::size_type maxJ(columns[i]->size());
214
215      if (maxJ!=columns[0]->size())
216        {
217          G4String message("G4DNACrossSectionDataSet::LoadData - data file \"");
218          message+=fullFileName;
219          message+="\" has lines with a different number of columns";
220          G4Exception(message);
221          return false;
222        }
223
224      G4DataVector::size_type j(0);
225
226      G4DataVector *argEnergies=new G4DataVector;
227      G4DataVector *argData=new G4DataVector;
228      G4DataVector *argLogEnergies=new G4DataVector;
229      G4DataVector *argLogData=new G4DataVector;
230
231      while(j<maxJ)
232        {
233          argEnergies->push_back(columns[0]->operator[] (j)*GetUnitEnergies());
234          argData->push_back(columns[i]->operator[] (j)*GetUnitData());
235          argLogEnergies->push_back(log_columns[0]->operator[] (j) + std::log10(GetUnitEnergies()));
236          argLogData->push_back(log_columns[i]->operator[] (j) + std::log10(GetUnitData()));
237          j++;
238        }
239
240      AddComponent(new G4EMDataSet(i-1, argEnergies, argData, argLogEnergies, argLogData, GetAlgorithm()->Clone(), GetUnitEnergies(), GetUnitData()));
241 
242      i++;
243    }
244
245  i=maxI;
246  while (i>0)
247    {
248      i--;
249      delete columns[i];
250      delete log_columns[i];
251    }
252
253  return true;
254}
255
256
257G4bool G4DNACrossSectionDataSet::LoadNonLogData(const G4String & argFileName)
258{
259  CleanUpComponents();
260
261  G4String fullFileName(FullFileName(argFileName));
262  std::ifstream in(fullFileName, std::ifstream::binary|std::ifstream::in);
263
264  if (!in.is_open())
265    {
266      G4String message("G4DNACrossSectionDataSet::LoadData - data file \"");
267      message+=fullFileName;
268      message+="\" not found";
269      G4Exception(message);
270      return false;
271    }
272
273  std::vector<G4DataVector *> columns;
274
275  std::stringstream *stream(new std::stringstream);
276  char c;
277  G4bool comment(false);
278  G4bool space(true);
279  G4bool first(true);
280
281  try
282    {
283      while (!in.eof())
284        {
285          in.get(c);
286   
287          switch (c)
288            {
289            case '\r':
290            case '\n':
291              if (!first)
292                {
293                  unsigned long i(0);
294                  G4double value;
295     
296                  while (!stream->eof())
297                    {
298                      (*stream) >> value;
299       
300                      while (i>=columns.size())
301                        {
302                         columns.push_back(new G4DataVector);
303                        }
304     
305                      columns[i]->push_back(value);
306       
307                      i++;
308                    }
309     
310                  delete stream;
311                  stream=new std::stringstream;
312                }
313     
314              first=true;
315              comment=false;
316              space=true;
317              break;
318     
319            case '#':
320              comment=true;
321              break;
322     
323            case '\t':
324              c=' ';
325            case ' ':
326              if (space)
327                break;
328            default:
329              if (comment)
330                break;
331     
332              if (c==' ')
333                space=true;
334              else
335                {
336                  if (space && (!first))
337                    (*stream) << ' ';
338     
339                  first=false;
340                  (*stream) << c;
341                  space=false;
342                }
343            }
344        }
345    }
346  catch(const std::ios::failure &e)
347    {
348      // some implementations of STL could throw a "failture" exception
349      // when read wants read characters after end of file
350    }
351 
352  delete stream;
353 
354  std::vector<G4DataVector *>::size_type maxI(columns.size());
355 
356  if (maxI<2)
357    {
358      G4String message("G4DNACrossSectionDataSet::LoadData - data file \"");
359      message+=fullFileName;
360      message+="\" should have at least two columns";
361      G4Exception(message);
362      return false;
363    }
364 
365  std::vector<G4DataVector*>::size_type i(1);
366  while (i<maxI)
367    {
368      G4DataVector::size_type maxJ(columns[i]->size());
369
370      if (maxJ!=columns[0]->size())
371        {
372          G4String message("G4DNACrossSectionDataSet::LoadData - data file \"");
373          message+=fullFileName;
374          message+="\" has lines with a different number of columns";
375          G4Exception(message);
376          return false;
377        }
378
379      G4DataVector::size_type j(0);
380
381      G4DataVector *argEnergies=new G4DataVector;
382      G4DataVector *argData=new G4DataVector;
383
384      while(j<maxJ)
385        {
386          argEnergies->push_back(columns[0]->operator[] (j)*GetUnitEnergies());
387          argData->push_back(columns[i]->operator[] (j)*GetUnitData());
388          j++;
389        }
390
391      AddComponent(new G4EMDataSet(i-1, argEnergies, argData, GetAlgorithm()->Clone(), GetUnitEnergies(), GetUnitData()));
392 
393      i++;
394    }
395
396  i=maxI;
397  while (i>0)
398    {
399      i--;
400      delete columns[i];
401    }
402
403  return true;
404}
405
406
407G4bool G4DNACrossSectionDataSet::SaveData(const G4String & argFileName) const
408{
409  const size_t n(NumberOfComponents());
410 
411  if (n==0)
412    {
413      G4Exception("G4EMDataSet::SaveData - expected at least one component");
414      return false;
415    }
416 
417  G4String fullFileName(FullFileName(argFileName));
418  std::ofstream out(fullFileName);
419
420  if (!out.is_open())
421    {
422      G4String message("G4EMDataSet::SaveData - cannot open \"");
423      message+=fullFileName;
424      message+="\"";
425      G4Exception(message);
426      return false;
427    }
428 
429  G4DataVector::const_iterator iEnergies(GetComponent(0)->GetEnergies(0).begin());
430  G4DataVector::const_iterator iEnergiesEnd(GetComponent(0)->GetEnergies(0).end());
431  G4DataVector::const_iterator * iData(new G4DataVector::const_iterator[n]);
432 
433  size_t k(n);
434 
435  while (k>0)
436    {
437      k--;
438      iData[k]=GetComponent(k)->GetData(0).begin();
439    }
440 
441  while (iEnergies!=iEnergiesEnd)
442    {
443      out.precision(10);
444      out.width(15);
445      out.setf(std::ofstream::left);
446      out << ((*iEnergies)/GetUnitEnergies());
447 
448      k=0;
449 
450      while (k<n)
451        {
452          out << ' ';
453          out.precision(10);
454          out.width(15);
455          out.setf(std::ofstream::left);
456          out << ((*(iData[k]))/GetUnitData());
457
458          iData[k]++;
459          k++;
460        }
461 
462      out << std::endl;
463 
464      iEnergies++;
465    }
466 
467  delete[] iData;
468
469  return true;
470}
471
472
473G4String G4DNACrossSectionDataSet::FullFileName(const G4String& argFileName) const
474{
475  char* path = getenv("G4LEDATA");
476  if (!path)
477    G4Exception("G4DNACrossSectionDataSet::FullFileName - G4LEDATA environment variable not set");
478 
479  std::ostringstream fullFileName;
480 
481  fullFileName << path << "/" << argFileName << ".dat";
482                     
483  return G4String(fullFileName.str().c_str());
484}
485
486
487G4double G4DNACrossSectionDataSet::FindValue(G4double argEnergy, G4int /* argComponentId */) const
488{
489  // Returns the sum over the shells corresponding to e
490  G4double value = 0.;
491
492  std::vector<G4VEMDataSet *>::const_iterator i(components.begin());
493  std::vector<G4VEMDataSet *>::const_iterator end(components.end());
494
495  while (i!=end)
496    {
497      value+=(*i)->FindValue(argEnergy);
498      i++;
499    }
500
501  return value;
502}
503
504
505void G4DNACrossSectionDataSet::PrintData(void) const
506{
507  const size_t n(NumberOfComponents());
508
509  G4cout << "The data set has " << n << " components" << G4endl;
510  G4cout << G4endl;
511 
512  size_t i(0);
513 
514  while (i<n)
515    {
516      G4cout << "--- Component " << i << " ---" << G4endl;
517      GetComponent(i)->PrintData();
518      i++;
519    }
520}
521
522
523void G4DNACrossSectionDataSet::SetEnergiesData(G4DataVector* argEnergies, 
524                                         G4DataVector* argData, 
525                                         G4int argComponentId)
526{
527  G4VEMDataSet * component(components[argComponentId]);
528 
529  if (component)
530    {
531      component->SetEnergiesData(argEnergies, argData, 0);
532      return;
533    }
534
535  std::ostringstream message;
536  message << "G4DNACrossSectionDataSet::SetEnergiesData - component " << argComponentId << " not found";
537 
538  G4Exception(message.str().c_str());
539}
540
541
542void G4DNACrossSectionDataSet::SetLogEnergiesData(G4DataVector* argEnergies, 
543                                         G4DataVector* argData,
544                                         G4DataVector* argLogEnergies,
545                                         G4DataVector* argLogData, 
546                                         G4int argComponentId)
547{
548  G4VEMDataSet * component(components[argComponentId]);
549 
550  if (component)
551    {
552      component->SetLogEnergiesData(argEnergies, argData, argLogEnergies, argLogData, 0);
553      return;
554    }
555
556  std::ostringstream message;
557  message << "G4DNACrossSectionDataSet::SetLogEnergiesData - component " << argComponentId << " not found";
558 
559  G4Exception(message.str().c_str());
560}
561
562
563void G4DNACrossSectionDataSet::CleanUpComponents()
564{
565  while (!components.empty())
566    {
567      if (components.back()) delete components.back();
568      components.pop_back();
569    }
570}
571
572
Note: See TracBrowser for help on using the repository browser.