10 template<
class T>
T square(
T x ) {
return x*
x; }
15 static constexpr
double isec_ref = 3;
16 static constexpr
double phi_ref = isec_ref*
M_PI/6 +
M_PI/12;
19 static constexpr
double r_ref = 82;
22 static constexpr
double zextrap_min = 48;
23 static constexpr
double zextrap_max = 58;
26 static constexpr
double zref = 33.25;
27 static constexpr
double length = 50 - 5;
28 static constexpr
double zref_min = zref - length/2;
29 static constexpr
double zref_max = zref + length/2;
39 const int phibin_ref = hin->GetXaxis()->FindBin( phi_ref );
42 for(
int ir = 0; ir < hin->GetYaxis()->GetNbins(); ++ir )
46 const auto r = hin->GetYaxis()->GetBinCenter( ir+1 );
49 const auto zextrap_min_loc = zextrap_min *
r/r_ref;
50 const auto zextrap_max_loc = zextrap_max *
r/r_ref;
53 const int zbin_min[2] = { hin->GetZaxis()->FindBin( -zextrap_max_loc ), hin->GetZaxis()->FindBin( zextrap_min_loc ) };
54 const int zbin_max[2] = { hin->GetZaxis()->FindBin( -zextrap_min_loc ), hin->GetZaxis()->FindBin( zextrap_max_loc ) };
56 for(
int isign = 0; isign < 2; ++isign )
59 const auto z_min = hin->GetZaxis()->GetBinCenter( zbin_min[isign] );
60 const auto z_max = hin->GetZaxis()->GetBinCenter( zbin_max[isign] );
63 const auto content_min = hin->GetBinContent( phibin_ref, ir+1, zbin_min[isign] );
64 const auto content_max = hin->GetBinContent( phibin_ref, ir+1, zbin_max[isign] );
65 const auto error_min = hin->GetBinError( phibin_ref, ir+1, zbin_min[isign] );
66 const auto error_max = hin->GetBinError( phibin_ref, ir+1, zbin_max[isign] );
69 for(
int iz = zbin_min[isign]+1; iz < zbin_max[isign]; ++iz )
72 const auto z = hin->GetZaxis()->GetBinCenter( iz );
78 const auto content = alpha_min*content_min + alpha_max*content_max;
79 const auto error = std::sqrt(
square( alpha_min * error_min ) +
square( alpha_max*error_max));
81 hin->SetBinContent( phibin_ref, ir+1, iz, content );
82 hin->SetBinError( phibin_ref, ir+1, iz,
error );
90 {
return std::make_tuple( zref_min * r/r_ref, zref_max * r/r_ref ); }
98 const int phibin_ref = hin->GetXaxis()->FindBin( phi_ref );
101 for(
int isec = 0; isec < 12; ++isec )
105 if( isec == isec_ref )
continue;
109 const int phibin = hin->GetXaxis()->FindBin( phi );
112 for(
int ir = 0; ir < hin->GetYaxis()->GetNbins(); ++ir )
116 const auto r = hin->GetYaxis()->GetBinCenter( ir+1 );
119 double zref_min_loc, zref_max_loc;
123 const std::array<int,2> zbin_min = {{ hin->GetZaxis()->FindBin( -zref_max_loc ), hin->GetZaxis()->FindBin( zref_min_loc ) }};
124 const std::array<int,2> zbin_max = {{ hin->GetZaxis()->FindBin( -zref_min_loc ), hin->GetZaxis()->FindBin( zref_max_loc ) }};
127 auto safe_ratio = [](
double numerator,
double denominator ) ->
double {
return denominator == 0 ? 1. : numerator / denominator; };
128 const std::array<double,2> scale_factor =
130 safe_ratio( hin->Integral( phibin, phibin, ir+1, ir+1, zbin_min[0], zbin_max[0] ), hin->Integral( phibin_ref, phibin_ref, ir+1, ir+1, zbin_min[0], zbin_max[0] ) ),
131 safe_ratio( hin->Integral( phibin, phibin, ir+1, ir+1, zbin_min[1], zbin_max[1] ), hin->Integral( phibin_ref, phibin_ref, ir+1, ir+1, zbin_min[1], zbin_max[1] ) )
135 for(
int iz = 0; iz < hin->GetZaxis()->GetNbins(); ++iz )
137 const auto content_ref = hin->GetBinContent( phibin_ref, ir+1, iz+1 );
138 const auto error_ref = hin->GetBinError( phibin_ref, ir+1, iz+1 );
141 const auto z = hin->GetZaxis()->GetBinCenter( iz+1 );
142 const auto scale = (
z > 0) ? scale_factor[1]:scale_factor[0];
145 hin->SetBinContent( phibin, ir+1, iz+1, content_ref*
scale );
146 hin->SetBinError( phibin, ir+1, iz+1, error_ref*
std::abs(scale) );
157 for(
int iphi = 0; iphi < hin->GetXaxis()->GetNbins(); ++iphi )
161 const auto phi = hin->GetXaxis()->GetBinCenter( iphi+1 );
162 const int isec = std::floor( (phi -
M_PI/12)/(
M_PI/6) );
163 double phi_min = isec*
M_PI/6 +
M_PI/12;
164 double phi_max = phi_min +
M_PI/6;
166 if( phi_min < 0 ) phi_min += 2*
M_PI;
167 if( phi_max >= 2*
M_PI ) phi_max -= 2*
M_PI;
169 const auto phibin_min = hin->GetXaxis()->FindBin( phi_min );
170 if( phibin_min == iphi+1 )
continue;
172 const auto phibin_max = hin->GetXaxis()->FindBin( phi_max );
173 if( phibin_max == iphi+1 )
continue;
176 for(
int ir = 0; ir < hin->GetYaxis()->GetNbins(); ++ir )
180 for(
int iz = 0; iz < hin->GetZaxis()->GetNbins(); ++iz )
182 const auto content_min = hin->GetBinContent( phibin_min, ir+1, iz+1 );
183 const auto content_max = hin->GetBinContent( phibin_max, ir+1, iz+1 );
184 const auto error_min = hin->GetBinError( phibin_min, ir+1, iz+1 );
185 const auto error_max = hin->GetBinError( phibin_max, ir+1, iz+1 );
188 const auto alpha_min = (phi_max-
phi)/(phi_max-phi_min);
189 const auto alpha_max = (phi-phi_min)/(phi_max-phi_min);
191 const auto content = alpha_min*content_min + alpha_max*content_max;
192 const auto error = std::sqrt(
square( alpha_min * error_min ) +
square( alpha_max*error_max));
194 hin->SetBinContent( iphi+1, ir+1, iz+1, content );
195 hin->SetBinError( iphi+1, ir+1, iz+1,
error );
205 if( !hin )
return std::make_tuple<TH3*, TH3*>(
nullptr, nullptr );
207 auto xaxis = hin->GetXaxis();
208 auto yaxis = hin->GetYaxis();
209 auto zaxis = hin->GetZaxis();
210 auto ibin = zaxis->FindBin( (
double) 0 );
213 auto hneg =
new TH3F(
214 Form(
"%s_negz", hin->GetName() ), Form(
"%s_negz", hin->GetTitle() ),
215 xaxis->GetNbins(), xaxis->GetXmin(), xaxis->GetXmax(),
216 yaxis->GetNbins(), yaxis->GetXmin(), yaxis->GetXmax(),
217 ibin-1, zaxis->GetXmin(), zaxis->GetBinUpEdge( ibin-1 ) );
219 auto hpos =
new TH3F(
220 Form(
"%s_posz", hin->GetName() ), Form(
"%s_posz", hin->GetTitle() ),
221 xaxis->GetNbins(), xaxis->GetXmin(), xaxis->GetXmax(),
222 yaxis->GetNbins(), yaxis->GetXmin(), yaxis->GetXmax(),
223 zaxis->GetNbins() - (ibin-1), zaxis->GetBinLowEdge(ibin), zaxis->GetXmax() );
226 for(
int ix = 0; ix < xaxis->GetNbins(); ++ix )
227 for(
int iy = 0; iy < yaxis->GetNbins(); ++iy )
228 for(
int iz = 0; iz < zaxis->GetNbins(); ++iz )
230 const auto content = hin->GetBinContent( ix+1, iy+1, iz+1 );
231 const auto error = hin->GetBinError( ix+1, iy+1, iz+1 );
235 hneg->SetBinContent( ix+1, iy+1, iz+1, content );
236 hneg->SetBinError( ix+1, iy+1, iz+1,
error );
238 hpos->SetBinContent( ix+1, iy+1, iz - (ibin-1) + 1, content );
239 hpos->SetBinError( ix+1, iy+1, iz - (ibin-1) + 1,
error );
244 for(
const auto h: {hneg, hpos} )
246 h->GetXaxis()->SetTitle( hin->GetXaxis()->GetTitle() );
247 h->GetYaxis()->SetTitle( hin->GetYaxis()->GetTitle() );
248 h->GetZaxis()->SetTitle( hin->GetZaxis()->GetTitle() );
251 return std::make_tuple( hneg, hpos );
257 std::array<int, 3> bins;
258 std::array<double, 3>
x_min;
259 std::array<double, 3>
x_max;
262 for(
const auto axis:{ hin->GetXaxis(), hin->GetYaxis(), hin->GetZaxis() } )
265 const auto bin_width = (axis->GetXmax() - axis->GetXmin())/axis->GetNbins();
268 bins[index] = axis->GetNbins()+2;
271 x_min[index] = axis->GetXmin()-bin_width;
272 x_max[index] = axis->GetXmax()+bin_width;
277 auto hout =
new TH3F( name, name,
278 bins[0], x_min[0], x_max[0],
279 bins[1], x_min[1], x_max[1],
280 bins[2], x_min[2], x_max[2] );
283 hout->GetXaxis()->SetTitle( hin->GetXaxis()->GetTitle() );
284 hout->GetYaxis()->SetTitle( hin->GetYaxis()->GetTitle() );
285 hout->GetZaxis()->SetTitle( hin->GetZaxis()->GetTitle() );
288 const auto phibins = hin->GetXaxis()->GetNbins();
289 const auto rbins = hin->GetYaxis()->GetNbins();
290 const auto zbins = hin->GetZaxis()->GetNbins();
293 for(
int iphi = 0; iphi <
phibins; ++iphi )
294 for(
int ir = 0; ir < rbins; ++ir )
295 for(
int iz = 0; iz < zbins; ++iz )
297 hout->SetBinContent( iphi+2, ir+2, iz+2, hin->GetBinContent( iphi+1, ir+1, iz+1 ) );
298 hout->SetBinError( iphi+2, ir+2, iz+2, hin->GetBinError( iphi+1, ir+1, iz+1 ) );
307 for(
int ir = 0; ir < rbins+2; ++ir )
308 for(
int iz = 0; iz < zbins+2; ++iz )
311 hout->SetBinContent( 1, ir+1, iz+1, hout->GetBinContent( phibins+1, ir+1, iz+1 ) );
312 hout->SetBinError( 1, ir+1, iz+1, hout->GetBinError( phibins+1, ir+1, iz+1 ) );
315 hout->SetBinContent( phibins+2, ir+1, iz+1, hout->GetBinContent( 2, ir+1, iz+1 ) );
316 hout->SetBinError( phibins+2, ir+1, iz+1, hout->GetBinError( 2, ir+1, iz+1 ) );
320 for(
int iphi = 0; iphi < phibins+2; ++iphi )
321 for(
int iz = 0; iz < zbins+2; ++iz )
323 hout->SetBinContent( iphi+1, 1, iz+1, hout->GetBinContent( iphi+1, 2, iz+1 ) );
324 hout->SetBinError( iphi+1, 1, iz+1, hout->GetBinError( iphi+1, 2, iz+1 ) );
326 hout->SetBinContent( iphi+1, rbins+2, iz+1, hout->GetBinContent( iphi+1, rbins+1, iz+1 ) );
327 hout->SetBinError( iphi+1, rbins+1, iz+1, hout->GetBinError( iphi+1, rbins+1, iz+1 ) );
331 for(
int iphi = 0; iphi < phibins+2; ++iphi )
332 for(
int ir = 0; ir < rbins+2; ++ir )
334 hout->SetBinContent( iphi+1, ir+1, 1, hout->GetBinContent( iphi+1, ir+1, 2 ) );
335 hout->SetBinError( iphi+1, ir+1, 1, hout->GetBinError( iphi+1, ir+1, 2 ) );
337 hout->SetBinContent( iphi+1, ir+1, zbins+2, hout->GetBinContent( iphi+1, ir+1, zbins+1 ) );
338 hout->SetBinError( iphi+1, ir+1, zbins+2, hout->GetBinError( iphi+1, ir+1, zbins+1 ) );