Geant4 Cross Reference |
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 // Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch) 29 // 30 // History: 31 // ----------- 32 // 1 Aug 2001 MGP Created 33 // 09 Oct 2001 VI Add FindValue with 3 parameters 34 // + NumberOfComponents 35 // 19 Jul 2002 VI Create composite data set for material 36 // 21 Jan 2003 VI Cut per region 37 // 38 // 15 Jul 2009 Nicolas A. Karakatsanis 39 // 40 // - LoadNonLogData method was created to load only the non-logarithmic data from G4EMLOW 41 // dataset. It is essentially performing the data loading operations as in the past. 42 // 43 // - LoadData method was revised in order to calculate the logarithmic values of the data 44 // It retrieves the data values from the G4EMLOW data files but, then, calculates the 45 // respective log values and loads them to seperate data structures. 46 // The EM data sets, initialized this way, contain both non-log and log values. 47 // These initialized data sets can enhance the computing performance of data interpolation 48 // operations 49 // 50 // - BuildMeanFreePathForMaterials method was also revised in order to calculate the 51 // logarithmic values of the loaded data. 52 // It generates the data values and, then, calculates the respective log values which 53 // later load to seperate data structures. 54 // The EM data sets, initialized this way, contain both non-log and log values. 55 // These initialized data sets can enhance the computing performance of data interpolation 56 // operations 57 // 58 // - LoadShellData method was revised in order to eliminate the presence of a potential 59 // memory leak originally identified by Riccardo Capra. 60 // Riccardo Capra Original Comment 61 // Riccardo Capra <capra@ge.infn.it>: PLEASE CHECK THE FOLLOWING PIECE OF CODE 62 // "energies" AND "data" G4DataVector ARE ALLOCATED, FILLED IN AND NEVER USED OR 63 // DELETED. WHATSMORE LOADING FILE OPERATIONS WERE DONE BY G4ShellEMDataSet 64 // EVEN BEFORE THE CHANGES I DID ON THIS FILE. SO THE FOLLOWING CODE IN MY 65 // OPINION SHOULD BE USELESS AND SHOULD PRODUCE A MEMORY LEAK. 66 // 67 // 68 // ------------------------------------------------------------------- 69 70 #include "G4VCrossSectionHandler.hh" 71 #include "G4VDataSetAlgorithm.hh" 72 #include "G4LogLogInterpolation.hh" 73 #include "G4VEMDataSet.hh" 74 #include "G4EMDataSet.hh" 75 #include "G4CompositeEMDataSet.hh" 76 #include "G4ShellEMDataSet.hh" 77 #include "G4ProductionCutsTable.hh" 78 #include "G4Material.hh" 79 #include "G4Element.hh" 80 #include "Randomize.hh" 81 #include <map> 82 #include <vector> 83 #include <fstream> 84 #include <sstream> 85 86 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 87 88 G4VCrossSectionHandler::G4VCrossSectionHandler() 89 { 90 crossSections = 0; 91 interpolation = 0; 92 Initialise(); 93 ActiveElements(); 94 } 95 96 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 97 98 G4VCrossSectionHandler::G4VCrossSectionHandler(G4VDataSetAlgorithm* algorithm, 99 G4double minE, 100 G4double maxE, 101 G4int bins, 102 G4double unitE, 103 G4double unitData, 104 G4int minZ, 105 G4int maxZ) 106 : interpolation(algorithm), eMin(minE), eMax(maxE), 107 unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ), 108 nBins(bins) 109 { 110 crossSections = nullptr; 111 ActiveElements(); 112 } 113 114 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 115 116 G4VCrossSectionHandler::~G4VCrossSectionHandler() 117 { 118 delete interpolation; 119 interpolation = nullptr; 120 121 for (auto & pos : dataMap) 122 { 123 G4VEMDataSet* dataSet = pos.second; 124 delete dataSet; 125 } 126 127 if (crossSections != nullptr) 128 { 129 std::size_t n = crossSections->size(); 130 for (std::size_t i=0; i<n; i++) 131 { 132 delete (*crossSections)[i]; 133 } 134 delete crossSections; 135 crossSections = nullptr; 136 } 137 } 138 139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 140 141 void G4VCrossSectionHandler::Initialise(G4VDataSetAlgorithm* algorithm, 142 G4double minE, G4double maxE, 143 G4int numberOfBins, 144 G4double unitE, G4double unitData, 145 G4int minZ, G4int maxZ) 146 { 147 if (algorithm != nullptr) 148 { 149 delete interpolation; 150 interpolation = algorithm; 151 } 152 else 153 { 154 delete interpolation; 155 interpolation = CreateInterpolation(); 156 } 157 158 eMin = minE; 159 eMax = maxE; 160 nBins = numberOfBins; 161 unit1 = unitE; 162 unit2 = unitData; 163 zMin = minZ; 164 zMax = maxZ; 165 } 166 167 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 168 169 void G4VCrossSectionHandler::PrintData() const 170 { 171 for (auto & pos : dataMap) 172 { 173 G4int z = pos.first; 174 G4VEMDataSet* dataSet = pos.second; 175 G4cout << "---- Data set for Z = " 176 << z 177 << G4endl; 178 dataSet->PrintData(); 179 G4cout << "--------------------------------------------------" << G4endl; 180 } 181 } 182 183 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 184 185 void G4VCrossSectionHandler::LoadData(const G4String& fileName) 186 { 187 std::size_t nZ = activeZ.size(); 188 for (std::size_t i=0; i<nZ; ++i) 189 { 190 G4int Z = G4int(activeZ[i]); 191 192 // Build the complete string identifying the file with the data set 193 const char* path = G4FindDataDir("G4LEDATA"); 194 if (!path) 195 { 196 G4Exception("G4VCrossSectionHandler::LoadData", 197 "em0006",FatalException,"G4LEDATA environment variable not set"); 198 return; 199 } 200 201 std::ostringstream ost; 202 ost << path << '/' << fileName << Z << ".dat"; 203 std::ifstream file(ost.str().c_str()); 204 std::filebuf* lsdp = file.rdbuf(); 205 206 if (! (lsdp->is_open()) ) 207 { 208 G4String excep = "data file: " + ost.str() + " not found"; 209 G4Exception("G4VCrossSectionHandler::LoadData", 210 "em0003",FatalException,excep); 211 } 212 G4double a = 0; 213 G4int k = 0; 214 G4int nColumns = 2; 215 216 G4DataVector* orig_reg_energies = new G4DataVector; 217 G4DataVector* orig_reg_data = new G4DataVector; 218 G4DataVector* log_reg_energies = new G4DataVector; 219 G4DataVector* log_reg_data = new G4DataVector; 220 221 do 222 { 223 file >> a; 224 225 if (a==0.) a=1e-300; 226 227 // The file is organized into four columns: 228 // 1st column contains the values of energy 229 // 2nd column contains the corresponding data value 230 // The file terminates with the pattern: -1 -1 231 // -2 -2 232 // 233 if (a != -1 && a != -2) 234 { 235 if (k%nColumns == 0) 236 { 237 orig_reg_energies->push_back(a*unit1); 238 log_reg_energies->push_back(std::log10(a)+std::log10(unit1)); 239 } 240 else if (k%nColumns == 1) 241 { 242 orig_reg_data->push_back(a*unit2); 243 log_reg_data->push_back(std::log10(a)+std::log10(unit2)); 244 } 245 k++; 246 } 247 } 248 while (a != -2); // End of File 249 250 file.close(); 251 G4VDataSetAlgorithm* algo = interpolation->Clone(); 252 G4VEMDataSet* dataSet = new G4EMDataSet(Z,orig_reg_energies,orig_reg_data, 253 log_reg_energies,log_reg_data,algo); 254 dataMap[Z] = dataSet; 255 } 256 } 257 258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 259 260 void G4VCrossSectionHandler::LoadNonLogData(const G4String& fileName) 261 { 262 std::size_t nZ = activeZ.size(); 263 for (std::size_t i=0; i<nZ; ++i) 264 { 265 G4int Z = G4int(activeZ[i]); 266 267 // Build the complete string identifying the file with the data set 268 const char* path = G4FindDataDir("G4LEDATA"); 269 if (!path) 270 { 271 G4Exception("G4VCrossSectionHandler::LoadNonLogData", 272 "em0006",FatalException,"G4LEDATA environment variable not set"); 273 return; 274 } 275 276 std::ostringstream ost; 277 ost << path << '/' << fileName << Z << ".dat"; 278 std::ifstream file(ost.str().c_str()); 279 std::filebuf* lsdp = file.rdbuf(); 280 281 if (! (lsdp->is_open()) ) 282 { 283 G4String excep = "data file: " + ost.str() + " not found"; 284 G4Exception("G4VCrossSectionHandler::LoadNonLogData", 285 "em0003",FatalException,excep); 286 } 287 G4double a = 0; 288 G4int k = 0; 289 G4int nColumns = 2; 290 291 G4DataVector* orig_reg_energies = new G4DataVector; 292 G4DataVector* orig_reg_data = new G4DataVector; 293 294 do 295 { 296 file >> a; 297 298 // The file is organized into four columns: 299 // 1st column contains the values of energy 300 // 2nd column contains the corresponding data value 301 // The file terminates with the pattern: -1 -1 302 // -2 -2 303 // 304 if (a != -1 && a != -2) 305 { 306 if (k%nColumns == 0) 307 { 308 orig_reg_energies->push_back(a*unit1); 309 } 310 else if (k%nColumns == 1) 311 { 312 orig_reg_data->push_back(a*unit2); 313 } 314 k++; 315 } 316 } 317 while (a != -2); // End of File 318 319 file.close(); 320 G4VDataSetAlgorithm* algo = interpolation->Clone(); 321 322 G4VEMDataSet* dataSet = new G4EMDataSet(Z,orig_reg_energies,orig_reg_data,algo); 323 dataMap[Z] = dataSet; 324 } 325 } 326 327 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 328 329 void G4VCrossSectionHandler::LoadShellData(const G4String& fileName) 330 { 331 std::size_t nZ = activeZ.size(); 332 for (std::size_t i=0; i<nZ; ++i) 333 { 334 G4int Z = G4int(activeZ[i]); 335 336 G4VDataSetAlgorithm* algo = interpolation->Clone(); 337 G4VEMDataSet* dataSet = new G4ShellEMDataSet(Z, algo); 338 dataSet->LoadData(fileName); 339 dataMap[Z] = dataSet; 340 } 341 } 342 343 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 344 345 void G4VCrossSectionHandler::Clear() 346 { 347 // Reset the map of data sets: remove the data sets from the map 348 if(! dataMap.empty()) 349 { 350 for (auto & pos : dataMap) 351 { 352 G4VEMDataSet* dataSet = pos.second; 353 delete dataSet; 354 dataSet = nullptr; 355 G4int i = pos.first; 356 dataMap[i] = nullptr; 357 } 358 dataMap.clear(); 359 } 360 activeZ.clear(); 361 ActiveElements(); 362 } 363 364 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 365 366 G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy) const 367 { 368 G4double value = 0.; 369 370 auto pos = dataMap.find(Z); 371 if (pos!= dataMap.end()) 372 { 373 G4VEMDataSet* dataSet = (*pos).second; 374 value = dataSet->FindValue(energy); 375 } 376 else 377 { 378 G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find Z = " 379 << Z << G4endl; 380 } 381 return value; 382 } 383 384 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 385 386 G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy, 387 G4int shellIndex) const 388 { 389 G4double value = 0.; 390 auto pos = dataMap.find(Z); 391 if (pos!= dataMap.cend()) 392 { 393 G4VEMDataSet* dataSet = (*pos).second; 394 if (shellIndex >= 0) 395 { 396 G4int nComponents = (G4int)dataSet->NumberOfComponents(); 397 if(shellIndex < nComponents) 398 value = dataSet->GetComponent(shellIndex)->FindValue(energy); 399 else 400 { 401 G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find" 402 << " shellIndex= " << shellIndex 403 << " for Z= " 404 << Z << G4endl; 405 } 406 } else { 407 value = dataSet->FindValue(energy); 408 } 409 } 410 else 411 { 412 G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find Z = " 413 << Z << G4endl; 414 } 415 return value; 416 } 417 418 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 419 420 G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material, 421 G4double energy) const 422 { 423 G4double value = 0.; 424 const G4ElementVector* elementVector = material->GetElementVector(); 425 const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume(); 426 std::size_t nElements = material->GetNumberOfElements(); 427 428 for (std::size_t i=0 ; i<nElements ; ++i) 429 { 430 G4int Z = (G4int) (*elementVector)[i]->GetZ(); 431 G4double elementValue = FindValue(Z,energy); 432 G4double nAtomsVol = nAtomsPerVolume[i]; 433 value += nAtomsVol * elementValue; 434 } 435 436 return value; 437 } 438 439 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 440 441 G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4DataVector* energyCuts) 442 { 443 // Builds a CompositeDataSet containing the mean free path for each material 444 // in the material table 445 G4DataVector energyVector; 446 G4double dBin = std::log10(eMax/eMin) / nBins; 447 448 for (G4int i=0; i<nBins+1; i++) 449 { 450 energyVector.push_back(std::pow(10., std::log10(eMin)+i*dBin)); 451 } 452 453 // Factory method to build cross sections in derived classes, 454 // related to the type of physics process 455 456 if (crossSections != nullptr) 457 { // Reset the list of cross sections 458 if (! crossSections->empty()) 459 { 460 for (auto mat=crossSections->begin(); mat != crossSections->end(); ++mat) 461 { 462 G4VEMDataSet* set = *mat; 463 delete set; 464 set = nullptr; 465 } 466 crossSections->clear(); 467 delete crossSections; 468 crossSections = nullptr; 469 } 470 } 471 472 crossSections = BuildCrossSectionsForMaterials(energyVector,energyCuts); 473 474 if (crossSections == nullptr) 475 { 476 G4Exception("G4VCrossSectionHandler::BuildMeanFreePathForMaterials", 477 "em1010",FatalException,"crossSections = 0"); 478 return 0; 479 } 480 481 G4VDataSetAlgorithm* algo = CreateInterpolation(); 482 G4VEMDataSet* materialSet = new G4CompositeEMDataSet(algo); 483 484 G4DataVector* energies; 485 G4DataVector* data; 486 G4DataVector* log_energies; 487 G4DataVector* log_data; 488 489 const G4ProductionCutsTable* theCoupleTable= 490 G4ProductionCutsTable::GetProductionCutsTable(); 491 G4int numOfCouples = (G4int)theCoupleTable->GetTableSize(); 492 493 for (G4int mLocal=0; mLocal<numOfCouples; ++mLocal) 494 { 495 energies = new G4DataVector; 496 data = new G4DataVector; 497 log_energies = new G4DataVector; 498 log_data = new G4DataVector; 499 for (G4int bin=0; bin<nBins; bin++) 500 { 501 G4double energy = energyVector[bin]; 502 energies->push_back(energy); 503 log_energies->push_back(std::log10(energy)); 504 G4VEMDataSet* matCrossSet = (*crossSections)[mLocal]; 505 G4double materialCrossSection = 0.0; 506 G4int nElm = (G4int)matCrossSet->NumberOfComponents(); 507 for(G4int j=0; j<nElm; ++j) { 508 materialCrossSection += matCrossSet->GetComponent(j)->FindValue(energy); 509 } 510 511 if (materialCrossSection > 0.) 512 { 513 data->push_back(1./materialCrossSection); 514 log_data->push_back(std::log10(1./materialCrossSection)); 515 } 516 else 517 { 518 data->push_back(DBL_MAX); 519 log_data->push_back(std::log10(DBL_MAX)); 520 } 521 } 522 G4VDataSetAlgorithm* algoLocal = CreateInterpolation(); 523 G4VEMDataSet* dataSet = new G4EMDataSet(mLocal,energies,data,log_energies,log_data,algoLocal,1.,1.); 524 materialSet->AddComponent(dataSet); 525 } 526 return materialSet; 527 } 528 529 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 530 531 G4int G4VCrossSectionHandler::SelectRandomAtom(const G4MaterialCutsCouple* couple, 532 G4double e) const 533 { 534 // Select randomly an element within the material, according to the weight 535 // determined by the cross sections in the data set 536 const G4Material* material = couple->GetMaterial(); 537 G4int nElements = (G4int)material->GetNumberOfElements(); 538 539 // Special case: the material consists of one element 540 if (nElements == 1) 541 { 542 G4int Z = (G4int) material->GetZ(); 543 return Z; 544 } 545 546 // Composite material 547 const G4ElementVector* elementVector = material->GetElementVector(); 548 std::size_t materialIndex = couple->GetIndex(); 549 550 G4VEMDataSet* materialSet = (*crossSections)[materialIndex]; 551 G4double materialCrossSection0 = 0.0; 552 G4DataVector cross; 553 cross.clear(); 554 for ( G4int i=0; i < nElements; i++ ) 555 { 556 G4double cr = materialSet->GetComponent(i)->FindValue(e); 557 materialCrossSection0 += cr; 558 cross.push_back(materialCrossSection0); 559 } 560 561 G4double random = G4UniformRand() * materialCrossSection0; 562 for (G4int k=0 ; k < nElements ; k++ ) 563 { 564 if (random <= cross[k]) return (G4int) (*elementVector)[k]->GetZ(); 565 } 566 // It should never get here 567 return 0; 568 } 569 570 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 571 572 const G4Element* G4VCrossSectionHandler::SelectRandomElement(const G4MaterialCutsCouple* couple, 573 G4double e) const 574 { 575 // Select randomly an element within the material, according to the weight determined 576 // by the cross sections in the data set 577 const G4Material* material = couple->GetMaterial(); 578 G4Element* nullElement = 0; 579 G4int nElements = (G4int)material->GetNumberOfElements(); 580 const G4ElementVector* elementVector = material->GetElementVector(); 581 582 // Special case: the material consists of one element 583 if (nElements == 1) 584 { 585 return (*elementVector)[0]; 586 } 587 else 588 { 589 // Composite material 590 591 std::size_t materialIndex = couple->GetIndex(); 592 593 G4VEMDataSet* materialSet = (*crossSections)[materialIndex]; 594 G4double materialCrossSection0 = 0.0; 595 G4DataVector cross; 596 cross.clear(); 597 for (G4int i=0; i<nElements; ++i) 598 { 599 G4double cr = materialSet->GetComponent(i)->FindValue(e); 600 materialCrossSection0 += cr; 601 cross.push_back(materialCrossSection0); 602 } 603 604 G4double random = G4UniformRand() * materialCrossSection0; 605 606 for (G4int k=0 ; k < nElements ; ++k ) 607 { 608 if (random <= cross[k]) return (*elementVector)[k]; 609 } 610 // It should never end up here 611 G4cout << "G4VCrossSectionHandler::SelectRandomElement - no element found" << G4endl; 612 return nullElement; 613 } 614 } 615 616 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 617 618 G4int G4VCrossSectionHandler::SelectRandomShell(G4int Z, G4double e) const 619 { 620 // Select randomly a shell, according to the weight determined by the cross sections 621 // in the data set 622 // Note for later improvement: it would be useful to add a cache mechanism for already 623 // used shells to improve performance 624 G4int shell = 0; 625 626 G4double totCrossSection = FindValue(Z,e); 627 G4double random = G4UniformRand() * totCrossSection; 628 G4double partialSum = 0.; 629 630 G4VEMDataSet* dataSet = nullptr; 631 auto pos = dataMap.find(Z); 632 if (pos != dataMap.end()) 633 dataSet = (*pos).second; 634 else 635 { 636 G4Exception("G4VCrossSectionHandler::SelectRandomShell", 637 "em1011",FatalException,"unable to load the dataSet"); 638 return 0; 639 } 640 641 G4int nShells = (G4int)dataSet->NumberOfComponents(); 642 for (G4int i=0; i<nShells; ++i) 643 { 644 const G4VEMDataSet* shellDataSet = dataSet->GetComponent(i); 645 if (shellDataSet != nullptr) 646 { 647 G4double value = shellDataSet->FindValue(e); 648 partialSum += value; 649 if (random <= partialSum) return i; 650 } 651 } 652 // It should never get here 653 return shell; 654 } 655 656 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 657 658 void G4VCrossSectionHandler::ActiveElements() 659 { 660 const G4MaterialTable* materialTable = G4Material::GetMaterialTable(); 661 if (materialTable == nullptr) 662 G4Exception("G4VCrossSectionHandler::ActiveElements", 663 "em1001",FatalException,"no MaterialTable found"); 664 665 std::size_t nMaterials = G4Material::GetNumberOfMaterials(); 666 667 for (std::size_t mLocal2=0; mLocal2<nMaterials; ++mLocal2) 668 { 669 const G4Material* material= (*materialTable)[mLocal2]; 670 const G4ElementVector* elementVector = material->GetElementVector(); 671 const std::size_t nElements = material->GetNumberOfElements(); 672 673 for (std::size_t iEl=0; iEl<nElements; ++iEl) 674 { 675 G4double Z = (*elementVector)[iEl]->GetZ(); 676 if (!(activeZ.contains(Z)) && Z >= zMin && Z <= zMax) 677 { 678 activeZ.push_back(Z); 679 } 680 } 681 } 682 } 683 684 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 685 686 G4VDataSetAlgorithm* G4VCrossSectionHandler::CreateInterpolation() 687 { 688 G4VDataSetAlgorithm* algorithm = new G4LogLogInterpolation; 689 return algorithm; 690 } 691 692 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 693 694 G4int G4VCrossSectionHandler::NumberOfComponents(G4int Z) const 695 { 696 G4int n = 0; 697 698 auto pos = dataMap.find(Z); 699 if (pos!= dataMap.end()) 700 { 701 G4VEMDataSet* dataSet = (*pos).second; 702 n = (G4int)dataSet->NumberOfComponents(); 703 } 704 else 705 { 706 G4cout << "WARNING: G4VCrossSectionHandler::NumberOfComponents did not " 707 << "find Z = " 708 << Z << G4endl; 709 } 710 return n; 711 } 712 713 714