ATLAS Offline Software
Loading...
Searching...
No Matches
CaloGpuGeneral_fnc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
9
10#define M_PI 3.14159265358979323846
11#define M_2PI 6.28318530717958647692
12
13# define __DEVICE__ __device__
14
16 __DEVICE__ long long getDDE( GeoGpu* geo, int sampling, float eta, float phi ) {
17
18 float* distance = 0;
19 int* steps = 0;
20
21 int MAX_SAMPLING = geo->max_sample;
22 Rg_Sample_Index* SampleIdx = geo->sample_index;
23 GeoRegion* regions_g = geo->regions;
24
25 if ( sampling < 0 ) return -1;
26 if ( sampling >= MAX_SAMPLING ) return -1;
27
28 int sample_size = SampleIdx[sampling].size;
29 unsigned int sample_index = SampleIdx[sampling].index;
30
31 GeoRegion* gr = regions_g;
32 if ( sample_size == 0 ) return -1;
33 float dist{};
34 long long bestDDE = -1;
35 if ( !distance ) distance = &dist;
36 *distance = +10000000;
37 int intsteps;
38 int beststeps;
39 if ( steps )
40 beststeps = ( *steps );
41 else
42 beststeps = 0;
43
44 if ( sampling < 21 ) {
45 for ( int skip_range_check = 0; skip_range_check <= 1; ++skip_range_check ) {
46 for ( unsigned int j = sample_index; j < sample_index + sample_size; ++j ) {
47 if ( !skip_range_check ) {
48 if ( eta < gr[j].mineta() ) continue;
49 if ( eta > gr[j].maxeta() ) continue;
50 }
51 if ( steps )
52 intsteps = ( *steps );
53 else
54 intsteps = 0;
55 float newdist;
56 long long newDDE = gr[j].getDDE( eta, phi, &newdist, &intsteps );
57 if ( newdist < *distance ) {
58 bestDDE = newDDE;
59 *distance = newdist;
60 if ( steps ) beststeps = intsteps;
61 if ( newdist < -0.1 ) break; // stop, we are well within the hit cell
62 }
63 }
64 if ( bestDDE >= 0 ) break;
65 }
66 } else {
67 return -3;
68 }
69 if ( steps ) *steps = beststeps;
70
71 return bestDDE;
72 }
73
74 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
75
76 __DEVICE__ int find_index_f( float* array, int size, float value ) {
77
78 int low = 0;
79 int high = size - 1;
80 int m_index = ( high - low ) / 2;
81 while ( high != low ) {
82 if ( value >= array[m_index] )
83 low = m_index + 1;
84 else
85 high = m_index;
86 m_index = ( high + low ) / 2;
87 }
88 return m_index;
89 }
90
91 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
92
93 __DEVICE__ int find_index_uint32( uint32_t* array, int size, uint32_t value ) {
94 // find the first index of element which has vaule > value
95 int low = 0;
96 int high = size - 1;
97 int m_index = ( high - low ) / 2;
98 while ( high != low ) {
99 if ( value > array[m_index] )
100 low = m_index + 1;
101 else if ( value == array[m_index] ) {
102 return m_index + 1;
103 } else
104 high = m_index;
105 m_index = ( high - low ) / 2 + low;
106 }
107 return m_index;
108 }
109
110 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
111
112 __DEVICE__ void rnd_to_fct2d( float& valuex, float& valuey, float rnd0, float rnd1, FH2D* hf2d ) {
113
114 int nbinsx = ( *hf2d ).nbinsx;
115 int nbinsy = ( *hf2d ).nbinsy;
116 float* HistoContents = ( *hf2d ).h_contents;
117 float* HistoBorders = ( *hf2d ).h_bordersx;
118 float* HistoBordersy = ( *hf2d ).h_bordersy;
119
120 int ibin = find_index_f( HistoContents, nbinsx * nbinsy, rnd0 );
121
122 int biny = ibin / nbinsx;
123 int binx = ibin - nbinsx * biny;
124
125 float basecont = 0;
126 if ( ibin > 0 ) basecont = HistoContents[ibin - 1];
127
128 float dcont = HistoContents[ibin] - basecont;
129 if ( dcont > 0 ) {
130 valuex = HistoBorders[binx] + ( HistoBorders[binx + 1] - HistoBorders[binx] ) * ( rnd0 - basecont ) / dcont;
131 } else {
132 valuex = HistoBorders[binx] + ( HistoBorders[binx + 1] - HistoBorders[binx] ) / 2;
133 }
134 valuey = HistoBordersy[biny] + ( HistoBordersy[biny + 1] - HistoBordersy[biny] ) * rnd1;
135 }
136
137 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
138
139 __DEVICE__ float rnd_to_fct1d( float rnd, uint32_t* contents, float* borders, int nbins, uint32_t s_MaxValue ) {
140
141 uint32_t int_rnd = s_MaxValue * rnd;
142
143 int ibin = find_index_uint32( contents, nbins, int_rnd );
144
145 int binx = ibin;
146
147 uint32_t basecont = 0;
148 if ( ibin > 0 ) basecont = contents[ibin - 1];
149
150 uint32_t dcont = contents[ibin] - basecont;
151 if ( dcont > 0 ) {
152 return borders[binx] + ( ( borders[binx + 1] - borders[binx] ) * ( int_rnd - basecont ) ) / dcont;
153 } else {
154 return borders[binx] + ( borders[binx + 1] - borders[binx] ) / 2;
155 }
156 }
157
158 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
159
161
162 hit.setCenter_r( ( 1. - args.extrapWeight ) * args.extrapol_r_ent + args.extrapWeight * args.extrapol_r_ext );
163 hit.setCenter_z( ( 1. - args.extrapWeight ) * args.extrapol_z_ent + args.extrapWeight * args.extrapol_z_ext );
164 hit.setCenter_eta( ( 1. - args.extrapWeight ) * args.extrapol_eta_ent + args.extrapWeight * args.extrapol_eta_ext );
165 hit.setCenter_phi( ( 1. - args.extrapWeight ) * args.extrapol_phi_ent + args.extrapWeight * args.extrapol_phi_ext );
166 }
167
168 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
169
170 __DEVICE__ void HistoLateralShapeParametrization_d( Hit& hit, unsigned long t, Chain0_Args args, bool reweight ) {
171
172 // int pdgId = args.pdgId;
173 float charge = args.charge;
174
175 // int cs=args.charge;
176 float center_eta = hit.center_eta();
177 float center_phi = hit.center_phi();
178 float center_r = hit.center_r();
179 float center_z = hit.center_z();
180
181 float alpha, r, rnd1, rnd2;
182 rnd1 = args.rand[t];
183 rnd2 = args.rand[t + args.nhits];
184
185 if ( args.is_phi_symmetric ) {
186 if ( rnd2 >= 0.5 ) { // Fill negative phi half of shape
187 rnd2 -= 0.5;
188 rnd2 *= 2;
189 rnd_to_fct2d( alpha, r, rnd1, rnd2, args.fh2d );
190 alpha = -alpha;
191 } else { // Fill positive phi half of shape
192 rnd2 *= 2;
193 rnd_to_fct2d( alpha, r, rnd1, rnd2, args.fh2d );
194 }
195 } else {
196 rnd_to_fct2d( alpha, r, rnd1, rnd2, args.fh2d );
197 }
198
199 float delta_eta_mm = r * cos( alpha );
200 float delta_phi_mm = r * sin( alpha );
201
202 // Particles with negative eta are expected to have the same shape as those with positive eta after transformation:
203 // delta_eta --> -delta_eta
204 if ( center_eta < 0. ) delta_eta_mm = -delta_eta_mm;
205 // Particle with negative charge are expected to have the same shape as positively charged particles after
206 // transformation: delta_phi --> -delta_phi
207 if ( charge < 0. ) delta_phi_mm = -delta_phi_mm;
208
209 float dist000 = sqrt( center_r * center_r + center_z * center_z );
210 float eta_jakobi = abs( 2.0 * exp( -center_eta ) / ( 1.0 + exp( -2 * center_eta ) ) );
211
212 float delta_eta = delta_eta_mm / eta_jakobi / dist000;
213 float delta_phi = delta_phi_mm / center_r;
214
215 if( reweight ){
216 float* histocontents = ( args.fh1d)->h_contents;
217 float* histoborders = ( args.fh1d)->h_borders;
218 float* histoerrors= ( args.fh1d)->h_errors;
219 int nbins = args.fh1d->nbins ;
220 float delta_r_mm = sqrt( delta_eta_mm * delta_eta_mm + delta_phi_mm * delta_phi_mm );
221 int ibin = find_index_f( histoborders, nbins + 1, delta_r_mm);
222 if( ibin < 1 ) ibin = 1 ;
223 if( ibin > nbins ) ibin = nbins ;
224 float weight = histocontents[ibin];
225 float rms = histoerrors[ibin];
226 if(rms>0){
227 float rnd1 = args.rand[t + 2 * args.nhits -100 ];
228 float rnd2 = args.rand[t + 2 * args.nhits -10 ];
229 float logweight= sqrt( r-2. * log(rnd1) )*cos( M_2PI * rnd2) * rms - 0.5 * rms * rms;
230 weight *= exp( logweight );
231 }
232 hit.E() *= weight;
233 }
234
235 hit.setEtaPhiZE( center_eta + delta_eta, center_phi + delta_phi, center_z, hit.E() );
236 }
237
238 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
239
240 __DEVICE__ void HitCellMapping_d( Hit& hit, unsigned long /*t*/, Chain0_Args args ) {
241
242 long long cellele = getDDE( args.geo, args.cs, hit.eta(), hit.phi() );
243
244 if ( cellele < 0 ) printf( "cellele not found %lld \n", cellele );
245
246 atomicAdd( &args.cells_energy[cellele], hit.E() );
247 }
248
249 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
250
251 __DEVICE__ void HitCellMappingWiggle_d( Hit& hit, Chain0_Args args, unsigned long t ) {
252
253 int nhist = ( *( args.fhs ) ).nhist;
254 float* bin_low_edge = ( *( args.fhs ) ).low_edge;
255
256 float eta = fabs( hit.eta() );
257 if ( eta < bin_low_edge[0] || eta > bin_low_edge[nhist] ) { HitCellMapping_d( hit, t, args ); }
258
259 int bin = nhist;
260 for ( int i = 0; i < nhist + 1; ++i ) {
261 if ( bin_low_edge[i] > eta ) {
262 bin = i;
263 break;
264 }
265 }
266
267 bin -= 1;
268
269 unsigned int mxsz = args.fhs->mxsz;
270 uint32_t* contents = &( args.fhs->d_contents1D[bin * mxsz] );
271 float* borders = &( args.fhs->d_borders1D[bin * mxsz] );
272 int h_size = ( *( args.fhs ) ).h_szs[bin];
273 uint32_t s_MaxValue = ( *( args.fhs ) ).s_MaxValue;
274
275 float rnd = args.rand[t + 2 * args.nhits];
276
277 float wiggle = rnd_to_fct1d( rnd, contents, borders, h_size, s_MaxValue );
278
279 float hit_phi_shifted = hit.phi() + wiggle;
280 hit.phi() = Phi_mpi_pi( hit_phi_shifted );
281
282 HitCellMapping_d( hit, t, args );
283 }
284} // namespace CaloGpuGeneral_fnc
285
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
double charge(const T &p)
Definition AtlasPID.h:997
#define M_2PI
#define __DEVICE__
#define gr
__HOSTDEV__ double Phi_mpi_pi(double)
Definition GeoRegion.cxx:10
static TRandom * rnd
CUDA_HOSTDEV void setEtaPhiZE(float eta, float phi, float z, float E)
void contents(std::vector< std::string > &keys, TDirectory *td, const std::string &directory, const std::string &pattern, const std::string &path)
int r
Definition globals.cxx:22
__DEVICE__ void rnd_to_fct2d(float &valuex, float &valuey, float rnd0, float rnd1, FH2D *hf2d)
__DEVICE__ int find_index_f(float *array, int size, float value)
__DEVICE__ void HitCellMappingWiggle_d(Hit &hit, Chain0_Args args, unsigned long t)
__DEVICE__ long long getDDE(GeoGpu *geo, int sampling, float eta, float phi)
__DEVICE__ void HistoLateralShapeParametrization_d(Hit &hit, unsigned long t, Chain0_Args args, bool reweight)
__DEVICE__ int find_index_uint32(uint32_t *array, int size, uint32_t value)
__DEVICE__ void HitCellMapping_d(Hit &hit, unsigned long, Chain0_Args args)
__DEVICE__ void CenterPositionCalculation_d(Hit &hit, const Chain0_Args args)
__DEVICE__ float rnd_to_fct1d(float rnd, uint32_t *contents, float *borders, int nbins, uint32_t s_MaxValue)