3 #ifdef STANDALONE_FITTER 14 #include "TRobustEstimator.h" 34 static const double cgaus = 0.5 *
log( 2.*
M_PI );
35 return (-
pow(residual - center, 2) *0.5 / sigma / sigma) - cgaus -
log(sigma);
48 sx = fabs(sx); sy = fabs(sy);
49 static const double c2gaus =
log( 2.*
M_PI );
50 double one_r2 = 1. - r*
r;
53 return -0.5/one_r2 * (
pow(dx/sx, 2) +
pow(dy/sy, 2) - 2.*r*dx/sx*dy/
sy ) - c2gaus -
log(sx*sy*
sqrt(one_r2));
59 if (gammaoversigma == 0.)
return (-toversigma*toversigma/2.) -
log(
sqrt(2*
M_PI));
63 double integrandplus_last = 0.;
64 double integrandminus_last = 0.;
65 for (
double inc = 0.; uplus <
max; inc +=
step)
67 double uplus_last = uplus;
68 uplus =
pow(inc, power);
70 double integrandplus =
exp(-
pow(uplus - toversigma, 2)/2.) / (uplus*uplus/gammaoversigma + gammaoversigma) /
M_PI /
sqrt(2.*
M_PI);
71 double integrandminus =
exp(-
pow(-uplus - toversigma, 2)/2.) / (uplus*uplus/gammaoversigma + gammaoversigma) /
M_PI /
sqrt(2.*
M_PI);
73 sum += integrandplus * (uplus - uplus_last);
74 sum += 0.5 * fabs(integrandplus_last - integrandplus) * (uplus - uplus_last);
76 sum += integrandminus * (uplus - uplus_last);
77 sum += 0.5 * fabs(integrandminus_last - integrandminus) * (uplus - uplus_last);
79 integrandplus_last = integrandplus;
80 integrandminus_last = integrandminus;
89 double gammaoversigma = fabs(gamma / sigma);
90 double toversigma = fabs((residual - center) / sigma);
100 if (gsisbad || tsisbad)
102 return log(gammaoversigma/
M_PI) -
log(toversigma*toversigma + gammaoversigma*gammaoversigma) -
log(sigma);
116 return val -
log(sigma);
130 return log(TMath::Voigt(residual - center, fabs(sigma), fabs(gamma)*2.));
136 return par[0] * TMath::Voigt(xvec[0] - par[1], fabs(par[2]), fabs(par[3])*2.);
141 double x = residual-center;
142 double s = fabs(sigma);
146 double n = sqerf*s + 2.*a*
pow(m,-3)/3.;
148 if (fabs(x)<m)
return -x*x/(2.*s*
s) -
log(n);
149 else return log(a) -4.*
log(fabs(x)) -
log(n);
161 static const double isqr2 = 1./
sqrt(2.);
162 return (erf((high + center) * isqr2 / sigma) - erf((low + center) * isqr2 / sigma)) *
exp(0.5/sigma/sigma) * 0.5;
166 m_residualsModel(residualsModel)
168 , m_useResiduals(useResiduals)
169 , m_weightAlignment(weightAlignment)
173 , m_loglikelihood(0.)
177 throw cms::Exception(
"MuonResidualsFitter") <<
"unrecognized residualsModel";
184 delete [] (*residual);
191 assert(0 <= parNum && parNum <
npar());
199 assert(0 <= parNum && parNum <
npar());
200 if (
m_fixed.empty())
return false;
214 assert(0 <= parNum1 && parNum1 <
npar());
215 assert(0 <= parNum2 && parNum2 <
npar());
235 std::ifstream convolution_table(
"convolution_table.txt");
236 if (convolution_table.is_open())
240 double tsbinsize = 0.;
241 double gsbinsize = 0.;
243 convolution_table >> numgsbins >> numtsbins >> tsbinsize >> gsbinsize;
247 throw cms::Exception(
"MuonResidualsFitter") <<
"convolution_table.txt has the wrong bin width/bin size. Throw it away and let the fitter re-create the file.\n";
258 convolution_table >> read_gsbin >> read_tsbin >>
val;
259 if (read_gsbin != gsbin || read_tsbin != tsbin)
261 throw cms::Exception(
"MuonResidualsFitter") <<
"convolution_table.txt is out of order. Throw it away and let the fitter re-create the file.\n";
266 convolution_table.close();
270 std::ofstream convolution_table2(
"convolution_table.txt");
272 if (!convolution_table2.is_open())
throw cms::Exception(
"MuonResidualsFitter") <<
"Couldn't write to file convolution_table.txt\n";
276 std::cout <<
"Initializing convolution look-up table (takes a few minutes)..." << std::endl;
281 std::cout <<
" gsbin " << gsbin <<
"/" << MuonResidualsFitter_numgsbins << std::endl;
295 convolution_table2.close();
296 std::cout <<
"Initialization done!" << std::endl;
302 std::vector<double> &
start, std::vector<double> &
step, std::vector<double> &low, std::vector<double> &high)
313 std::vector<int>::const_iterator iNum = parNum.begin();
314 std::vector<std::string>::const_iterator iName = parName.begin();
315 std::vector<double>::const_iterator istart = start.begin();
316 std::vector<double>::const_iterator istep = step.begin();
317 std::vector<double>::const_iterator ilow = low.begin();
318 std::vector<double>::const_iterator ihigh = high.begin();
322 for (; iNum != parNum.end(); ++iNum, ++iName, ++istart, ++istep, ++ilow, ++ihigh)
333 for (
int i = 0;
i < 10;
i++) arglist[
i] = 0.;
341 for (
int i = 0;
i < 10;
i++) arglist[
i] = 0.;
347 bool try_again =
false;
350 for (
int i = 0;
i < 10;
i++) arglist[
i] = 0.;
354 if (ierflg != 0) try_again =
true;
359 for (
int i = 0;
i < 10;
i++) arglist[
i] = 0.;
364 Double_t fmin, fedm, errdef;
365 Int_t npari, nparx, istat;
370 for (
int i = 0;
i < 10;
i++) arglist[
i] = 0.;
380 for (
int i = 0;
i <
npar();
i++)
392 if (smierflg != 0)
return false;
401 int whichcopy =
which;
403 fwrite(&rows,
sizeof(
long), 1, file);
404 fwrite(&cols,
sizeof(
int), 1, file);
405 fwrite(&whichcopy,
sizeof(
int), 1, file);
407 double *likeAChecksum =
new double[cols];
408 double *likeAChecksum2 =
new double[cols];
409 for (
int i = 0;
i < cols;
i++)
411 likeAChecksum[
i] = 0.;
412 likeAChecksum2[
i] = 0.;
417 fwrite((*residual),
sizeof(
double), cols, file);
418 for (
int i = 0;
i < cols;
i++)
420 if (fabs((*residual)[
i]) > likeAChecksum[i]) likeAChecksum[
i] = fabs((*residual)[i]);
421 if (fabs((*residual)[i]) < likeAChecksum2[i]) likeAChecksum2[
i] = fabs((*residual)[i]);
427 fwrite(likeAChecksum,
sizeof(
double), cols, file);
428 fwrite(likeAChecksum2,
sizeof(
double), cols, file);
430 delete [] likeAChecksum;
431 delete [] likeAChecksum2;
438 int readwhich = -100;
440 fread(&rows,
sizeof(
long), 1, file);
441 fread(&cols,
sizeof(
int), 1, file);
442 fread(&readwhich,
sizeof(
int), 1, file);
444 if (cols !=
ndata() || rows < 0 || readwhich != which)
446 throw cms::Exception(
"MuonResidualsFitter") <<
"temporary file is corrupted (which = " << which <<
" readwhich = " << readwhich <<
" rows = " << rows <<
" cols = " << cols <<
")\n";
449 double *likeAChecksum =
new double[cols];
450 double *likeAChecksum2 =
new double[cols];
451 for (
int i = 0;
i < cols;
i++)
453 likeAChecksum[
i] = 0.;
454 likeAChecksum2[
i] = 0.;
458 for (
long row = 0; row <
rows; row++)
460 double *residual =
new double[cols];
461 fread(residual,
sizeof(
double), cols, file);
463 for (
int i = 0;
i < cols;
i++)
465 if (fabs(residual[
i]) > likeAChecksum[i]) likeAChecksum[
i] = fabs(residual[i]);
466 if (fabs(residual[i]) < likeAChecksum2[i]) likeAChecksum2[
i] = fabs(residual[i]);
470 double *readChecksum =
new double[cols];
471 double *readChecksum2 =
new double[cols];
472 fread(readChecksum,
sizeof(
double), cols, file);
473 fread(readChecksum2,
sizeof(
double), cols, file);
475 for (
int i = 0;
i < cols;
i++)
477 if (fabs(likeAChecksum[
i] - readChecksum[
i]) > 1
e-10 || fabs(1./likeAChecksum2[i] - 1./readChecksum2[i]) > 1e10)
479 throw cms::Exception(
"MuonResidualsFitter") <<
"temporary file is corrupted (which = " << which <<
" rows = " << rows <<
" likeAChecksum " << likeAChecksum[
i] <<
" != readChecksum " << readChecksum[
i] <<
" " <<
" likeAChecksum2 " << likeAChecksum2[
i] <<
" != readChecksum2 " << readChecksum2[
i] <<
")\n";
485 delete [] likeAChecksum;
486 delete [] likeAChecksum2;
493 if (which == 0) window = 2.*30.;
494 else if (which == 1) window = 2.*30.;
495 else if (which == 2) window = 2.*20.;
496 else if (which == 3) window = 2.*50.;
506 if (which == 0) window = 2.*30.;
507 else if (which == 1) window = 2.*30.;
508 else if (which == 2) window = 2.*20.;
509 else if (which == 3) window = 2.*50.;
514 double weight = 1./(*r)[whichredchi2];
515 if (TMath::Prob(1./weight*12, 12) < 0.99) hist->Fill(multiplier * (*
r)[which], weight);
526 if (fabs((*
r)[which])<50.)
533 const int n_quantiles = 7;
534 double probabilities[n_quantiles] = {0.00135, 0.02275, 0.25, 0.5, 0.75, 0.97725, 0.99865};
536 double quantiles[n_quantiles];
537 std::sort(data, data + n);
538 TMath::Quantiles(n, n_quantiles, data, quantiles, probabilities,
true,
nullptr, 7);
540 double iqr = quantiles[4] - quantiles[2];
543 double hbin = 2 * iqr /
pow( n, 1./3);
547 nbins = (
int) ( (b - a) / hbin + 3. );
552 std::cout<<
" optimal h="<<hbin<<
" nbins="<<nbins<<std::endl;
561 if (a==b || a > b) { fit_mean =
a; fit_sigma = 0;
return; }
563 TH1D *
hist =
new TH1D(
"htmp",
"", nbins, a, b);
567 TF1 *
f1=
new TF1(
"f1",
"gaus", a, b);
568 f1->SetParameter(0, hist->GetEntries());
569 f1->SetParameter(1, 0);
570 f1->SetParameter(2, hist->GetRMS());
571 hist->Fit(
"f1",
"RQ");
574 fit_mean = f1->GetParameter(1);
575 fit_sigma = f1->GetParameter(2);
576 std::cout<<
" h("<<nbins<<
","<<a<<
","<<b<<
") mu="<<fit_mean<<
" sig="<<fit_sigma<<std::endl;
597 for (
int v = 0;
v<nvar;
v++)
608 double ellipsoid_sum = 0;
609 for (
int v = 0;
v<nvar;
v++)
612 if (
m_radii[which] == 0.)
continue;
615 if (ellipsoid_sum <= 1.) ++
r;
644 assert(nvar<=10 && nvar>0);
653 double *
data =
new double[nbefore];
657 re.EvaluateUni(nbefore, data, peak, sigma);
662 double distance = fabs( ((*r)[ vars[0] ] - peak)/sigma );
663 if (distance <= nsigma) ++
r;
678 TRobustEstimator re(nbefore+1, nvar);
679 std::cout <<
"nbefore " << nbefore <<
" nvar " << nvar << std::endl;
681 std::cout <<
"+++++ JUST before loop while (r != m_residuals.end())" << std::endl;
685 double *row =
new double[nvar];
686 for (
int v = 0;
v<nvar;
v++) row[
v] = (*r)[ vars[
v] ];
692 std::cout <<
"counter1 " << counter1 << std::endl;
693 std::cout <<
"+++++ JUST after loop while (r != m_residuals.end())" << std::endl;
695 std::cout <<
"+++++ JUST after re.Evaluate()" << std::endl;
700 TMatrixDSym Cov(nvar);
701 re.GetCovariance(Cov);
705 double conf_1d = TMath::Erf(nsigma/
sqrt(2));
706 double surf_radius =
sqrt(TMath::ChisquareQuantile(conf_1d, nvar));
713 for (
int v = 0;
v<nvar;
v++) res[
v] = (*r)[ vars[
v] ];
715 if (distance <= surf_radius) ++
r;
736 double positionX=9999.;
737 double positionY=9999.;
746 if( (*
r)[15]>0.0001 ) {
747 n_station = (*r)[12];
756 n_station = (*r)[10];
767 if (positionX >= xMax || positionX <= xMin)
m_residuals_ok[iResidual] =
false;
768 if (positionY >= yMax || positionY <= yMin)
m_residuals_ok[iResidual] =
false;
773 double dtrkchamx = (chambw/2.) - positionX;
774 double dtrkchamy = (chambl/2.) - positionY;
780 if( (n_wheel==-1 && n_sector==3) || (n_wheel==1 && n_sector==4)){
781 if( (n_sector==1 || n_sector==2 || n_sector==3 || n_sector==5 || n_sector==6 || n_sector==7 || n_sector==8 || n_sector==12) && ( (dtrkchamx<40 || dtrkchamx>380) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
782 if( (n_sector==4 || n_sector==13) && ( (dtrkchamx<40 || dtrkchamx>280) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
783 if( (n_sector==9 || n_sector==11) && ( (dtrkchamx<40 || dtrkchamx>180) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
784 if( (n_sector==10 || n_sector==14) && ( (dtrkchamx<40 || dtrkchamx>220) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
787 if( (n_sector==1 || n_sector==2 || n_sector==3 || n_sector==5 || n_sector==6 || n_sector==7 || n_sector==8 || n_sector==12) && ( (dtrkchamx<40 || dtrkchamx>380) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
788 if( (n_sector==4 || n_sector==13) && ( (dtrkchamx<40 || dtrkchamx>280) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
789 if( (n_sector==9 || n_sector==11) && ( (dtrkchamx<40 || dtrkchamx>180) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
790 if( (n_sector==10 || n_sector==14) && ( (dtrkchamx<40 || dtrkchamx>220) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
794 if( (n_wheel==-1 && n_sector==3) || (n_wheel==1 && n_sector==4)){
795 if(n_station==1 && ( (dtrkchamx<30.0 || dtrkchamx>190.0) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
796 if(n_station==2 && ( (dtrkchamx<30.0 || dtrkchamx>240.0) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
797 if(n_station==3 && ( (dtrkchamx<30.0 || dtrkchamx>280.0) || (dtrkchamy<40.0 || dtrkchamy>170.0)) )
m_residuals_ok[iResidual] =
false;
800 if(n_station==1 && ( (dtrkchamx<30.0 || dtrkchamx>190.0) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
801 if(n_station==2 && ( (dtrkchamx<30.0 || dtrkchamx>240.0) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
802 if(n_station==3 && ( (dtrkchamx<30.0 || dtrkchamx>280.0) || (dtrkchamy<40.0 || dtrkchamy>210.0)) )
m_residuals_ok[iResidual] =
false;
817 double pt = fabs((*
r)[idx_momentum]);
818 if (pt < min_pt) min_pt =
pt;
821 const double bin_width = 1./min_pt/Nbin;
824 std::vector<size_t>
pos[Nbin], neg[Nbin], to_erase;
830 else neg[
bin].push_back(i);
834 for (
int j = 0; j < Nbin; j++)
836 size_t psize = pos[j].size();
837 size_t nsize = neg[j].size();
838 if (psize == nsize)
continue;
840 std::set<int> idx_set;
843 while (idx_set.size() < psize - nsize) idx_set.insert( gRandom->Integer(psize) );
844 for (std::set<int>::iterator it = idx_set.begin() ; it != idx_set.end(); it++ ) to_erase.push_back(pos[j][*it]);
848 while (idx_set.size() < nsize - psize) idx_set.insert( gRandom->Integer(nsize) );
849 for (std::set<int>::iterator it = idx_set.begin() ; it != idx_set.end(); it++ ) to_erase.push_back(neg[j][*it]);
853 std::sort(to_erase.begin(), to_erase.end(), std::greater<int>() );
854 for (std::vector<size_t>::const_iterator
e = to_erase.begin();
e != to_erase.end(); ++
e)
861 std::vector<size_t> apos[Nbin], aneg[Nbin];
867 else aneg[
bin].push_back(i);
869 for (
int j = 0; j < Nbin; j++)
std::cout <<
"bin " << j <<
": [pos,neg] sizes before & after: [" 870 << pos[j].
size() <<
","<< neg[j].size()<<
"] -> [" << apos[j].size() <<
","<< aneg[j].size() <<
"]" << std::endl;
879 std::vector<double*>
tmp(n_ok,
nullptr);
889 std::vector<bool> tmp_ok(n_ok,
true);
double MuonResidualsFitter_logROOTVoigt(double residual, double center, double sigma, double gamma)
void histogramChi2GaussianFit(int which, double &fit_mean, double &fit_sigma)
virtual void inform(TMinuit *tMinuit)=0
void computeHistogramRangeAndBinning(int which, int &nbins, double &a, double &b)
void selectPeakResiduals(double nsigma, int nvar, int *vars)
const int MuonResidualsFitter_numgsbins
double MuonResidualsFitter_integrate_pureGaussian(double low, double high, double center, double sigma)
void write(FILE *file, int which=0)
long numResiduals() const
double covarianceElement(int parNum1, int parNum2)
void eraseNotSelectedResiduals()
int parNum2parIdx(int parNum)
std::vector< double > m_error
void read(FILE *file, int which=0)
void fill(double *residual)
int residualsModel() const
Double_t MuonResidualsFitter_powerLawTails_TF1(Double_t *xvec, Double_t *par)
bool dofit(void(*fcn)(int &, double *, double &, double *, int), std::vector< int > &parNum, std::vector< std::string > &parName, std::vector< double > &start, std::vector< double > &step, std::vector< double > &low, std::vector< double > &high)
std::vector< double > m_value
std::vector< double * > m_residuals
Double_t MuonResidualsFitter_pureGaussian_TF1(Double_t *xvec, Double_t *par)
const int MuonResidualsFitter_numtsbins
MuonResidualsFitter(int residualsModel, int minHits, int useResiduals, bool weightAlignment=true)
const double MuonResidualsFitter_gsbinsize
std::vector< bool > m_residuals_ok
void fix(int parNum, bool dofix=true)
def window(xmin, xmax, ymin, ymax, x=0, y=0, width=100, height=100, xlogbase=None, ylogbase=None, minusInfinity=-1000, flipx=False, flipy=True)
T * make(const Args &...args) const
make new ROOT object
Double_t MuonResidualsFitter_GaussPowerTails_TF1(Double_t *xvec, Double_t *par)
virtual void correctBField()=0
const double MuonResidualsFitter_tsbinsize
static TMinuit * MuonResidualsFitter_TMinuit
bin
set the eta bin as selection string.
double MuonResidualsFitter_logGaussPowerTails(double residual, double center, double sigma)
void plotsimple(std::string name, TFileDirectory *dir, int which, double multiplier)
double MuonResidualsFitter_logPureGaussian2D(double x, double y, double x0, double y0, double sx, double sy, double r)
void fcn(int &, double *, double &, double *, int)
double MuonResidualsFitter_logPureGaussian(double residual, double center, double sigma)
void fiducialCuts(double xMin=-80.0, double xMax=80.0, double yMin=-80.0, double yMax=80.0, bool fidcut1=false)
std::vector< double * >::const_iterator residuals_end() const
double MuonResidualsFitter_logPowerLawTails(double residual, double center, double sigma, double gamma)
std::vector< std::vector< double > > tmp
char data[epos_bytes_allocation]
double MuonResidualsFitter_compute_log_convolution(double toversigma, double gammaoversigma, double max, double step, double power)
void plotweighted(std::string name, TFileDirectory *dir, int which, int whichredchi2, double multiplier)
bool MuonResidualsFitter_table_initialized
double MuonResidualsFitter_lookup_table[MuonResidualsFitter_numgsbins][MuonResidualsFitter_numtsbins]
virtual ~MuonResidualsFitter()
void selectPeakResiduals_simple(double nsigma, int nvar, int *vars)
std::vector< bool > m_fixed
std::vector< double * >::const_iterator residuals_begin() const
Double_t MuonResidualsFitter_ROOTVoigt_TF1(Double_t *xvec, Double_t *par)
Power< A, B >::type pow(const A &a, const B &b)