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] } );
T max(const T t1, const T t2)
brief Return the largest of the two arguments
std::vector< ExP01TrackerHit * > a
void SetKineticEnergy(G4double aEnergy)
void logStopCountCycles(timing &)
const G4FastPathHadronicCrossSection::controlFlag & GetFastPathControlFlags() const
const G4String & GetParticleName() const
const G4ParticleDefinition *const particle
G4PhysicsFreeVector XSParam
G4bool initializationPhase
const G4FastPathHadronicCrossSection::fastPathParameters & GetFastPathParameters() const
void Initialize(G4CrossSectionDataStore *)
const G4String & GetName() const
static constexpr double m
const G4double min_cutoff
G4bool useFastPathIfAvailable
G4double G4ParticleHPJENDLHEData::G4double result
unsigned long long rdtsc_stop
fastPathEntry(const G4ParticleDefinition *par, const G4Material *mat, G4double min_cutoff)
cycleCountEntry(const G4String &pname, const G4Material *mat)
const G4Material *const material
G4double GetCrossSection(const G4DynamicParticle *, const G4Material *)
void PutValue(size_t index, G4double energy, G4double dataValue)
unsigned long long rdtsc_start
void logStartCountCycles(timing &)
const G4String & particle
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
const G4Material *const material