34   #define _USE_MATH_DEFINES // for C++ 
   41 #define DBG( msg ) G4cout<< msg <<G4endl; 
   42 #define DUMP() G4cout<< <<G4endl; 
   48 using namespace G4FastPathHadronicCrossSection;
 
   57     int  simplify_function(
G4double tolerance,
 
   58                        std::vector<Point_t> & raw_data,
 
   59                        std::vector<Point_t>  & simplified_data);
 
   60     void RemoveBias( std::vector <Point_t> &,
 
   61             std::vector <Point_t> &,
 
   62             std::vector <Point_t> &);
 
   66         particle(part),
material(mat),min_cutoff(min),physicsVector(nullptr)
 
   68     DBG(
"Initializing a fastPathEntry");
 
   81     DBG(
"Deleting fastPathEntry");
 
   84           <<
" count:"<<count<<
" slowpath_sum:"<<slowpath_sum<<
" max_delta:"<<max_delta\
 
   85           <<
" min_delta"<<min_delta<<
" sum_delta"<<sum_delta<<
" sum_delta_squared:"<<sum_delta_square);
 
  102     std::vector<Point_t> data_in;
 
  139     auto exp10 = [](
G4double x){ 
return std::exp( M_LN10*
x); };
 
  140     for(
G4double log_currEnergy = log_min; log_currEnergy < log_max; log_currEnergy += log_step){
 
  141         currEnergy = exp10(log_currEnergy) - shift;
 
  146         if (xs > max_xs) max_xs = xs;
 
  147         data_in.push_back({currEnergy,xs});
 
  151     data_in.push_back({max-shift,xs});
 
  154     std::vector<Point_t> decimated_data;
 
  155     simplify_function(tol,  data_in,  decimated_data);
 
  156     std::vector<Point_t> debiased_data;
 
  157     RemoveBias( data_in,  decimated_data,  debiased_data);
 
  160     G4int physicsVectorIndex = 0;
 
  161     for(
size_t i = 0; i < decimated_data.size(); i++){
 
  168         particle(pname),
material(mat),fastPath(nullptr),
 
  169         energy(-1.),crossSection(-1.)
 
  171     DBG(
"Initializing cache entry");
 
  174     initCyclesFastPath=0;
 
  175     invocationCountSlowPath=0;
 
  176     totalCyclesSlowPath=0;
 
  177     invocationCountFastPath=0;
 
  178     totalCyclesFastPath=0;
 
  179     invocationCountTriedOneLineCache=0;
 
  180     invocationCountOneLineCache=0;
 
  186     DBG(
"Deleting cache entry");
 
  189             <<cacheHitCount<<
" "<<initCyclesFastPath<<
" "<<invocationCountSlowPath<<
" "\
 
  190             <<totalCyclesSlowPath<<
" "<<invocationCountFastPath<<
" "<<totalCyclesFastPath<<
" "\
 
  191             <<invocationCountTriedOneLineCache<<
" "<<invocationCountOneLineCache);
 
  196     static inline unsigned long long rdtsc() {
 
  198 #if defined(__GNUC__) &&( defined(__i386__)|| defined(__x86_64__) ) 
  199         __asm__ __volatile__ (
"rdtsc":
"=a"(lo),
"=d"(hi));
 
  201         return ((
unsigned long long)lo) | ((
unsigned long long)hi<<32 );
 
  244 int  simplify_function(
G4double tolerance,
 
  245                        std::vector<Point_t> & raw_data,
 
  246                        std::vector<Point_t>  & simplified_data)
 
  249   int  gap_left, gap_right;  
 
  251   G4double tolsq = tolerance*tolerance;  
 
  253   std::vector<int> working_stack;
 
  257   gap_right = raw_data.size() - 1;  
 
  261   DBG(
"First and last elements  " << gap_left <<
"  " <<gap_right);
 
  263   simplified_data.push_back(raw_data[0]); 
 
  265   DBG(
"first point ( 0  " 
  266               <<simplified_data[0].e  <<
",  "<<simplified_data[0].xs <<
" )");
 
  268   working_stack.push_back(gap_right); 
 
  270   while ( !working_stack.empty() )
 
  275       gap_right = working_stack.back();  
 
  279       if ( (gap_left +1) < gap_right )  
 
  282           slope =  (raw_data[gap_right].xs - raw_data[gap_left].xs) /
 
  283             (raw_data[gap_right].e - raw_data[gap_left].e);
 
  284           a = raw_data[gap_left].xs - slope * raw_data[gap_left].e;
 
  286           for ( 
int i = gap_left +1; i <gap_right;  i++) {
 
  287             delta = raw_data[i].xs - a - slope * raw_data[i].e;
 
  288             if ( delta * delta > deltasq_max){
 
  289               deltasq_max = delta * delta;
 
  294             DBG(
"      Less than 3 point interval at [ "<< gap_left <<
", " <<gap_right<< 
" ]");
 
  297       if(i_max < gap_right) {  
 
  298     working_stack.push_back(i_max);
 
  299     DBG(
"         pushing point " << i_max);
 
  303     simplified_data.push_back(raw_data[gap_right]);
 
  304     DBG(
"inserting point (" 
  305                <<gap_right  <<
",  "<<raw_data[gap_right].e <<
", " 
  306                << raw_data[gap_right].xs <<
" )");
 
  307     gap_left = gap_right;
 
  308     working_stack.pop_back();
 
  309     gap_right = working_stack.back();
 
  310     DBG(
"      new gap_right " << gap_right);
 
  314   DBG(
"Simplified curve size "<< simplified_data.size());
 
  315   return (simplified_data.size());
 
  330 void RemoveBias(std::vector<Point_t> &  original, std::vector<Point_t> & simplified,
 
  331         std::vector<Point_t> & 
result){
 
  334   const size_t originalSize = original.size();
 
  335   const size_t simplifiedSize = simplified.size();
 
  338   std::vector<G4int>  xindex(simplifiedSize,0);
 
  343   DBG(
"   original and simplified vector sizes  " << originalSize <<
"  "<<simplifiedSize);
 
  345   for (
size_t k = 0; k <simplifiedSize; k++) {
 
  346     for (
size_t i = lastmatch; i < originalSize; i++) {
 
  347       if (original[i].e == simplified[k].e) {
 
  354   DBG(
"Matched  " << j << 
" values of the simplified vector");
 
  358   std::vector<G4double> GArea(m-1,0);
 
  363   for(
int i = 0; i < m-1; i++){
 
  366     for(j = xindex[i]; j< xindex[i+1]; j++){
 
  367       G4double trap = (original[j+1].xs + original[j].xs) * (original[j+1].e - original[j].e)/2.0;
 
  368       GAreatemp = GAreatemp + trap;
 
  370     GArea[i] = GAreatemp;
 
  371     GAreatotal = GAreatotal + GAreatemp;
 
  374   DBG(
"   Area under the original curve " << GAreatotal);
 
  379   std::vector<G4double> aleph(m-1,0);
 
  381   for(
int i = 0; i< m-1; i++){
 
  382     aleph[i] = (simplified[i+1].e - simplified[i].e)/2.0;
 
  386   std::vector<G4double> adjustedy(m-1,0);
 
  388   adjustedy[m-1] = simplified[m-1].xs;
 
  389   for(
int i = 2; i < m+1; i++) {
 
  390     adjustedy[m-i] = (GArea[m-i]/aleph[m-i]) - adjustedy[m-i+1];
 
  391     if (adjustedy[m-i] <0.0) {
 
  392       adjustedy[m-i] = 0.0;
 
  393       DBG(
"   Fixing negative cross section at index " << (m-i));
 
  398   std::vector<G4double> difference(m,0.);
 
  403   for(
int i = 0; i < m-1; i++){
 
  405     trap = (adjustedy[i+1]+adjustedy[i])*(simplified[i+1].e-simplified[i].e)/2.0;
 
  406     adjustedarea = adjustedarea+trap;
 
  407     trap = (simplified[i+1].xs+simplified[i].xs)*(simplified[i+1].e-simplified[i].e)/2.0;
 
  408     simplifiedarea = simplifiedarea + trap;
 
  411   DBG(
"   Area:  Simplified curve = " <<simplifiedarea);
 
  412   DBG(
"    Area:  Debiased curve  = " << adjustedarea);
 
  414   for(
int i = 0; i <
m; i++) {
 
  415     difference[i] = simplified[i].xs-adjustedy[i];
 
  417   for(
int i = 0; i <
m; i++){
 
  418     if(std::fabs(difference[i]) > maxdiff) {
 
  419       maxdiff = std::fabs(difference[i]);
 
  424   for(
size_t i = 0; i < simplifiedSize; i++){
 
  425     result.push_back( {simplified[i].e , adjustedy[i] } );
 
G4double G4ParticleHPJENDLHEData::G4double result
const G4FastPathHadronicCrossSection::controlFlag & GetFastPathControlFlags() const 
fastPathEntry(const G4ParticleDefinition *par, const G4Material *mat, G4double min_cutoff)
void Initialize(G4CrossSectionDataStore *)
std::vector< ExP01TrackerHit * > a
const G4String & particle
const G4String & GetName() const 
void PutValue(size_t index, G4double energy, G4double dataValue)
const G4ParticleDefinition *const particle
const G4double min_cutoff
const G4Material *const material
const G4Material *const material
const G4String & GetParticleName() const 
const G4FastPathHadronicCrossSection::fastPathParameters & GetFastPathParameters() const 
void logStartCountCycles(timing &)
G4bool useFastPathIfAvailable
static constexpr double m
cycleCountEntry(const G4String &pname, const G4Material *mat)
G4PhysicsFreeVector XSParam
G4double GetCrossSection(const G4DynamicParticle *, const G4Material *)
void SetKineticEnergy(G4double aEnergy)
unsigned long long rdtsc_start
T max(const T t1, const T t2)
brief Return the largest of the two arguments 
G4double energy(const ThreeVector &p, const G4double m)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments 
G4bool initializationPhase
unsigned long long rdtsc_stop
void logStopCountCycles(timing &)