20 inline constexpr
T square(
T x ) {
return x*
x; }
24 inline constexpr
T get_bound_angle(
T phi )
26 while( phi < 0 ) phi += 2*M_PI;
27 while( phi >= 2*M_PI ) phi -= 2*M_PI;
32 constexpr
double get_sector_phi(
int isec ) {
return isec*M_PI/6; }
38 static constexpr
double isec_ref = 9;
39 static constexpr
double phi_ref = get_sector_phi(isec_ref);
42 static constexpr
double r_ref = 85.1;
52 static constexpr
double zextrap_min = 53.2 - 5.0;
53 static constexpr
double zextrap_max = 56.6 + 5.0;
63 const int phibin_ref = hin->GetXaxis()->FindBin( phi_ref );
66 for(
int ir = 0; ir < hin->GetYaxis()->GetNbins(); ++ir )
70 const auto r = hin->GetYaxis()->GetBinCenter( ir+1 );
73 const auto zextrap_min_loc = zextrap_min *
r/r_ref;
74 const auto zextrap_max_loc = zextrap_max *
r/r_ref;
77 const int zbin_min[2] = { hin->GetZaxis()->FindBin( -zextrap_max_loc ), hin->GetZaxis()->FindBin( zextrap_min_loc ) };
78 const int zbin_max[2] = { hin->GetZaxis()->FindBin( -zextrap_min_loc ), hin->GetZaxis()->FindBin( zextrap_max_loc ) };
80 for(
int isign = 0; isign < 2; ++isign )
83 const auto z_min = hin->GetZaxis()->GetBinCenter( zbin_min[isign] );
84 const auto z_max = hin->GetZaxis()->GetBinCenter( zbin_max[isign] );
87 const auto content_min = hin->GetBinContent( phibin_ref, ir+1, zbin_min[isign] );
88 const auto content_max = hin->GetBinContent( phibin_ref, ir+1, zbin_max[isign] );
89 const auto error_min = hin->GetBinError( phibin_ref, ir+1, zbin_min[isign] );
90 const auto error_max = hin->GetBinError( phibin_ref, ir+1, zbin_max[isign] );
93 for(
int iz = zbin_min[isign]+1; iz < zbin_max[isign]; ++iz )
96 const auto z = hin->GetZaxis()->GetBinCenter( iz );
99 const auto alpha_min = (z_max-
z)/(z_max-z_min);
100 const auto alpha_max = (
z-z_min)/(z_max-z_min);
102 const auto content = alpha_min*content_min + alpha_max*content_max;
103 const auto error = std::sqrt(
square( alpha_min * error_min ) +
square( alpha_max*error_max));
105 hin->SetBinContent( phibin_ref, ir+1, iz, content );
106 hin->SetBinError( phibin_ref, ir+1, iz,
error );
118 auto get_phibin_range = []( TH3* hin,
int isec )
122 const double phi = get_sector_phi( isec );
123 const double phi_min = get_bound_angle( phi - M_PI/12 );
124 const double phi_max = get_bound_angle( phi + M_PI/12 );
127 const int phibin_min = hin->GetXaxis()->FindBin( phi_min );
128 const int phibin_max = hin->GetXaxis()->FindBin( phi_max );
129 return std::make_pair( phibin_min, phibin_max );
133 const auto [phibin_min_ref, phibin_max_ref] = get_phibin_range( hin, isec_ref );
136 const int nphibins = hin->GetNbinsX();
139 auto copy_phi_bin = []( TH3* hin,
int phibin_ref,
int phibin_dest )
143 for(
int ir = 0; ir < hin->GetYaxis()->GetNbins(); ++ir )
147 for(
int iz = 0; iz < hin->GetZaxis()->GetNbins(); ++iz )
149 const auto content_ref = hin->GetBinContent( phibin_ref, ir+1, iz+1 );
150 const auto error_ref = hin->GetBinError( phibin_ref, ir+1, iz+1 );
153 const auto scale = 1;
156 hin->SetBinContent( phibin_dest, ir+1, iz+1, content_ref*scale );
157 hin->SetBinError( phibin_dest, ir+1, iz+1, error_ref*std::abs(scale) );
164 for(
int isec = 0; isec < 12; ++isec )
167 if( isec == isec_ref )
continue;
169 const auto [phibin_min,
phibin_max] = get_phibin_range( hin, isec );
172 for(
int ibin = 0;
ibin < phibin_max_ref - phibin_min_ref; ++
ibin )
174 int phibin_ref = (phibin_min_ref +
ibin);
175 if( phibin_ref > nphibins ) phibin_ref -= nphibins;
177 int phibin = (phibin_min +
ibin);
178 if( phibin > nphibins ) phibin -= nphibins;
180 copy_phi_bin( hin, phibin_ref, phibin );
192 for(
int isec = 0; isec < 12; ++isec )
195 const double phi_min = get_sector_phi(isec)+delta_phi_mm/2;
196 const double phi_max = get_sector_phi(isec+1)-delta_phi_mm/2;
199 const int phibin_min = hin->GetXaxis()->FindBin(get_bound_angle(phi_min));
200 const int phibin_max = hin->GetXaxis()->FindBin(get_bound_angle(phi_max));
203 for(
int ir = 0; ir < hin->GetYaxis()->GetNbins(); ++ir )
207 for(
int iz = 0; iz < hin->GetZaxis()->GetNbins(); ++iz )
209 const auto content_min = hin->GetBinContent( phibin_min, ir+1, iz+1 );
210 const auto content_max = hin->GetBinContent( phibin_max, ir+1, iz+1 );
211 const auto error_min = hin->GetBinError( phibin_min, ir+1, iz+1 );
212 const auto error_max = hin->GetBinError( phibin_max, ir+1, iz+1 );
215 for(
int iphi = phibin_min+1; iphi <
phibin_max; ++iphi )
218 const auto phi = hin->GetXaxis()->GetBinCenter( iphi );
221 const auto alpha_min = (phi_max-
phi)/(phi_max-phi_min);
222 const auto alpha_max = (phi-
phi_min)/(phi_max-phi_min);
224 const auto content = alpha_min*content_min + alpha_max*content_max;
225 const auto error = std::sqrt(
square( alpha_min * error_min ) +
square( alpha_max*error_max));
227 hin->SetBinContent( iphi, ir+1, iz+1, content );
228 hin->SetBinError( iphi, ir+1, iz+1,
error );
239 if( !hin )
return std::make_tuple<TH3*, TH3*>(
nullptr, nullptr );
241 auto xaxis = hin->GetXaxis();
242 auto yaxis = hin->GetYaxis();
243 auto zaxis = hin->GetZaxis();
244 auto ibin = zaxis->FindBin( (
double) 0 );
247 auto hneg =
new TH3F(
248 Form(
"%s_negz", hin->GetName() ), Form(
"%s_negz", hin->GetTitle() ),
249 xaxis->GetNbins(), xaxis->GetXmin(), xaxis->GetXmax(),
250 yaxis->GetNbins(), yaxis->GetXmin(), yaxis->GetXmax(),
251 ibin-1, zaxis->GetXmin(), zaxis->GetBinUpEdge(
ibin-1 ) );
253 auto hpos =
new TH3F(
254 Form(
"%s_posz", hin->GetName() ), Form(
"%s_posz", hin->GetTitle() ),
255 xaxis->GetNbins(), xaxis->GetXmin(), xaxis->GetXmax(),
256 yaxis->GetNbins(), yaxis->GetXmin(), yaxis->GetXmax(),
257 zaxis->GetNbins() - (
ibin-1), zaxis->GetBinLowEdge(
ibin), zaxis->GetXmax() );
260 for(
int ix = 0; ix < xaxis->GetNbins(); ++ix )
261 for(
int iy = 0; iy < yaxis->GetNbins(); ++iy )
262 for(
int iz = 0; iz < zaxis->GetNbins(); ++iz )
264 const auto content = hin->GetBinContent( ix+1, iy+1, iz+1 );
265 const auto error = hin->GetBinError( ix+1, iy+1, iz+1 );
269 hneg->SetBinContent( ix+1, iy+1, iz+1, content );
270 hneg->SetBinError( ix+1, iy+1, iz+1,
error );
272 hpos->SetBinContent( ix+1, iy+1, iz - (
ibin-1) + 1, content );
273 hpos->SetBinError( ix+1, iy+1, iz - (
ibin-1) + 1,
error );
278 for(
const auto h: {hneg, hpos} )
280 h->GetXaxis()->SetTitle( hin->GetXaxis()->GetTitle() );
281 h->GetYaxis()->SetTitle( hin->GetYaxis()->GetTitle() );
282 h->GetZaxis()->SetTitle( hin->GetZaxis()->GetTitle() );
291 std::array<int, 3>
bins;
292 std::array<double, 3> x_min;
293 std::array<double, 3> x_max;
296 for(
const auto axis:{ hin->GetXaxis(), hin->GetYaxis(), hin->GetZaxis() } )
299 const auto bin_width = (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
302 bins[
index] = axis->GetNbins()+2;
305 x_min[
index] = axis->GetXmin()-bin_width;
306 x_max[
index] = axis->GetXmax()+bin_width;
311 auto hout =
new TH3F( name, name,
312 bins[0], x_min[0], x_max[0],
313 bins[1], x_min[1], x_max[1],
314 bins[2], x_min[2], x_max[2] );
317 hout->GetXaxis()->SetTitle( hin->GetXaxis()->GetTitle() );
318 hout->GetYaxis()->SetTitle( hin->GetYaxis()->GetTitle() );
319 hout->GetZaxis()->SetTitle( hin->GetZaxis()->GetTitle() );
322 const auto phibins = hin->GetXaxis()->GetNbins();
323 const auto rbins = hin->GetYaxis()->GetNbins();
324 const auto zbins = hin->GetZaxis()->GetNbins();
327 for(
int iphi = 0; iphi <
phibins; ++iphi )
328 for(
int ir = 0; ir < rbins; ++ir )
329 for(
int iz = 0; iz < zbins; ++iz )
331 hout->SetBinContent( iphi+2, ir+2, iz+2, hin->GetBinContent( iphi+1, ir+1, iz+1 ) );
332 hout->SetBinError( iphi+2, ir+2, iz+2, hin->GetBinError( iphi+1, ir+1, iz+1 ) );
341 for(
int ir = 0; ir < rbins+2; ++ir )
342 for(
int iz = 0; iz < zbins+2; ++iz )
345 hout->SetBinContent( 1, ir+1, iz+1, hout->GetBinContent( phibins+1, ir+1, iz+1 ) );
346 hout->SetBinError( 1, ir+1, iz+1, hout->GetBinError( phibins+1, ir+1, iz+1 ) );
349 hout->SetBinContent( phibins+2, ir+1, iz+1, hout->GetBinContent( 2, ir+1, iz+1 ) );
350 hout->SetBinError( phibins+2, ir+1, iz+1, hout->GetBinError( 2, ir+1, iz+1 ) );
354 for(
int iphi = 0; iphi < phibins+2; ++iphi )
355 for(
int iz = 0; iz < zbins+2; ++iz )
357 hout->SetBinContent( iphi+1, 1, iz+1, hout->GetBinContent( iphi+1, 2, iz+1 ) );
358 hout->SetBinError( iphi+1, 1, iz+1, hout->GetBinError( iphi+1, 2, iz+1 ) );
360 hout->SetBinContent( iphi+1, rbins+2, iz+1, hout->GetBinContent( iphi+1, rbins+1, iz+1 ) );
361 hout->SetBinError( iphi+1, rbins+2, iz+1, hout->GetBinError( iphi+1, rbins+1, iz+1 ) );
365 for(
int iphi = 0; iphi < phibins+2; ++iphi )
366 for(
int ir = 0; ir < rbins+2; ++ir )
368 hout->SetBinContent( iphi+1, ir+1, 1, hout->GetBinContent( iphi+1, ir+1, 2 ) );
369 hout->SetBinError( iphi+1, ir+1, 1, hout->GetBinError( iphi+1, ir+1, 2 ) );
371 hout->SetBinContent( iphi+1, ir+1, zbins+2, hout->GetBinContent( iphi+1, ir+1, zbins+1 ) );
372 hout->SetBinError( iphi+1, ir+1, zbins+2, hout->GetBinError( iphi+1, ir+1, zbins+1 ) );