File indexing completed on 2026-10-15 08:17:25
0001 #ifndef CROSSINGCORRECT_H
0002 #define CROSSINGCORRECT_H
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <iostream>
0013 #include <cmath>
0014 #include <cstdlib>
0015 #include "TH2D.h"
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 inline int CrossingDirtySide(double field, double chg1, double chg2){
0027 if (chg1==0. || chg2==0.) return 0;
0028 if (field==0.){ std::cout<<"CrossingDirtySide .. field is zero or not set! exit...."<<std::endl; exit(0); }
0029 return (field>0.) ? -1 : +1;
0030 }
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 inline void CrossingCorrect(TH2D* h, int dirtySide, const TH2D* hden){
0050 if (!h || !hden){ std::cout<<"CrossingCorrect .. null histogram! exit...."<<std::endl; exit(0); }
0051 if (hden->GetNbinsX()!=h->GetNbinsX() || hden->GetNbinsY()!=h->GetNbinsY()){
0052 std::cout<<"CrossingCorrect .. "<<h->GetName()<<": denominator binning differs. exit...."<<std::endl; exit(0);
0053 }
0054 TAxis* ax = h->GetYaxis();
0055 int nphi = ax->GetNbins();
0056 double lo = ax->GetXmin();
0057 double w = ax->GetBinWidth(1);
0058 if (nphi%4!=0 || std::fabs(ax->GetXmax()-lo-360.)>1e-6 || ax->GetXbins()->GetSize()>0){
0059 std::cout<<"CrossingCorrect .. "<<h->GetName()<<": need uniform dphi binning over 360 deg with nbins%4==0, have "
0060 <<nphi<<" bins ["<<lo<<","<<ax->GetXmax()<<"). exit...."<<std::endl; exit(0);
0061 }
0062 if (dirtySide<-1 || dirtySide>1){
0063 std::cout<<"CrossingCorrect .. dirtySide must be -1, 0 or +1, have "<<dirtySide<<". exit...."<<std::endl; exit(0);
0064 }
0065 if (dirtySide==0) return;
0066 for (int iy=1;iy<=nphi;iy++){
0067 double c = ax->GetBinCenter(iy);
0068 double cw = c;
0069 while (cw>= 180.) cw -= 360.;
0070 while (cw< -180.) cw += 360.;
0071 double cm = -cw;
0072 while (cm< lo ) cm += 360.;
0073 while (cm>= lo+360. ) cm -= 360.;
0074 int jy = ax->FindFixBin(cm);
0075 if (jy<1 || jy>nphi || std::fabs(ax->GetBinCenter(jy)-cm)>1e-6*w || jy==iy){
0076 std::cout<<"CrossingCorrect .. "<<h->GetName()<<": dphi bin "<<iy<<" has no distinct mirror bin. exit...."<<std::endl; exit(0);
0077 }
0078 if (jy<iy) continue;
0079 bool nearSide = std::fabs(cw)<90.;
0080 for (int ix=1;ix<=h->GetNbinsX();ix++){
0081 double vi = h->GetBinContent(ix,iy), ei = h->GetBinError(ix,iy);
0082 double vj = h->GetBinContent(ix,jy), ej = h->GetBinError(ix,jy);
0083 bool oki = hden->GetBinContent(ix,iy)>0., okj = hden->GetBinContent(ix,jy)>0.;
0084 if (nearSide){
0085 bool iDirty = (cw*dirtySide>0.);
0086 if (iDirty){ h->SetBinContent(ix,iy,vj); h->SetBinError(ix,iy,ej); }
0087 else { h->SetBinContent(ix,jy,vi); h->SetBinError(ix,jy,ei); }
0088 } else {
0089 double v,e;
0090 if (oki && okj){ v = 0.5*(vi+vj); e = 0.5*std::sqrt(ei*ei+ej*ej); }
0091 else if (oki) { v = vi; e = ei; }
0092 else if (okj) { v = vj; e = ej; }
0093 else { continue; }
0094 h->SetBinContent(ix,iy,v); h->SetBinError(ix,iy,e);
0095 h->SetBinContent(ix,jy,v); h->SetBinError(ix,jy,e);
0096 }
0097 }
0098 }
0099 }
0100
0101
0102
0103
0104
0105 inline int CrossingAsymmetry(TH2D* h, double tol=1e-9){
0106 TAxis* ax = h->GetYaxis();
0107 int nphi = ax->GetNbins();
0108 double lo = ax->GetXmin();
0109 int nasym= 0;
0110 for (int iy=1;iy<=nphi;iy++){
0111 double cm = -ax->GetBinCenter(iy);
0112 while (cm< lo ) cm += 360.;
0113 while (cm>= lo+360. ) cm -= 360.;
0114 int jy = ax->FindFixBin(cm);
0115 for (int ix=1;ix<=h->GetNbinsX();ix++){
0116 double vi = h->GetBinContent(ix,iy), vj = h->GetBinContent(ix,jy);
0117 double ei = h->GetBinError(ix,iy), ej = h->GetBinError(ix,jy);
0118 if (std::fabs(vi-vj)>tol*(std::fabs(vi)+std::fabs(vj)) || std::fabs(ei-ej)>tol*(ei+ej)) ++nasym;
0119 }
0120 }
0121 return nasym;
0122 }
0123
0124 #endif