bool TProtoSerial::operator() (TMatrixD& m, int protoField) { CHECK_FIELD(); switch (Mode) { case ESerialMode::IN: { const NGroundProto::TMatrixD* mat = GetEmbedMessage<NGroundProto::TMatrixD>(protoField); m = TMatrixD(mat->n_rows(), mat->n_cols()); for (size_t rowIdx=0; rowIdx < m.n_rows; ++rowIdx) { const NGroundProto::TVectorD& row = mat->row(rowIdx); for (size_t colIdx=0; colIdx < m.n_cols; ++colIdx) { m(rowIdx, colIdx) = row.x(colIdx); } } } break; case ESerialMode::OUT: { NGroundProto::TMatrixD* mat = GetEmbedMutMessage<NGroundProto::TMatrixD>(protoField); mat->set_n_rows(m.n_rows); mat->set_n_cols(m.n_cols); for (size_t rowIdx=0; rowIdx < m.n_rows; ++rowIdx) { NGroundProto::TVectorD* row = mat->add_row(); for (size_t colIdx=0; colIdx < m.n_cols; ++colIdx) { row->add_x(m(rowIdx, colIdx)); } } } break; } return true; }
Asymmetry estimateAsymmetry( const TH1* hist, const TH2* cov, const char * minName = "Minuit2", const char *algoName = "" ) { TH1* normHist=(TH1*)hist->Clone("normHist"); TH2* normCov=(TH2*)cov->Clone("normCov"); normHist->Scale(1.0/hist->Integral()); normCov->Scale(1.0/hist->Integral()/hist->Integral()); const int N = hist->GetNbinsX(); TMatrixD covMatrix(N,N); for (int i=0; i<N;++i) { for (int j=0; j<N;++j) { covMatrix[i][j]=normCov->GetBinContent(i+1,j+1); } } TMatrixD invCovMatrix = TMatrixD(TMatrixD::kInverted,covMatrix); ROOT::Math::Minimizer* min = ROOT::Math::Factory::CreateMinimizer(minName, algoName); // set tolerance , etc... min->SetMaxFunctionCalls(1000000); // for Minuit/Minuit2 min->SetMaxIterations(10000); // for GSL min->SetTolerance(0.001); min->SetPrintLevel(1); //const double xx[1] = {0.5}; std::function<double(const TH1*, const TMatrixD*, const double*)> unboundFct = chi2A; std::function<double(const double*)> boundFct = std::bind(unboundFct,normHist, &invCovMatrix, std::placeholders::_1); //boundFct(xx); ROOT::Math::Functor fct(boundFct,1); min->SetFunction(fct); min->SetVariable(0,"A",0.2, 0.01); min->Minimize(); const double *xs = min->X(); const double *error = min->Errors(); log(INFO,"min: %f\n",xs[0]); log(INFO,"err: %f\n",error[0]); Asymmetry res; res.mean=xs[0]; res.uncertainty=error[0]; return res; }
HHV4Vector::HHV4Vector(Double_t e, Double_t eta, Double_t phi, Double_t m) : m_e(e), m_eta(eta), m_phi(phi), m_m(m), m_dE(0), m_dEta(0), m_dPhi(0), m_id(HHPID::undef), m_id2(HHPID::undef), m_mother(-1), m_nDaughter(0), m_name("init"), m_cov_manually_set(false), m_cov_transversal(TMatrixD(2,2)) { m_cov_transversal(0,0)=0; m_cov_transversal(0,1)=0; m_cov_transversal(1,0)=0; m_cov_transversal(1,1)=0; }
void NeutrinoEllipseCalculator::labSystemTransform() { //rotate Htilde to H TMatrixD R(3,3); R.Zero(); TMatrixD Rz=rotationMatrix(2,-lepton_.Phi()); TMatrixD Ry=rotationMatrix(1,0.5*M_PI-lepton_.Theta()); double bJetP[3]={bJet_.Px(),bJet_.Py(), bJet_.Pz()}; TMatrixD bJet_xyz(3,1,bJetP); TMatrixD rM(Ry,TMatrixD::kMult,TMatrixD(Rz,TMatrixD::kMult,bJet_xyz)); double* rA=rM.GetMatrixArray(); double phi=-TMath::ATan2(rA[2],rA[1]); TMatrixD Rx=rotationMatrix(0,phi); R=TMatrixD(Rz,TMatrixD::kTransposeMult,TMatrixD(Ry,TMatrixD::kTransposeMult,Rx.T())); H_=TMatrixD(R,TMatrixD::kMult,Htilde_); //calculate Hperp double Hvalues[9]={H_[0][0],H_[0][1],H_[0][2],H_[1][0],H_[1][1],H_[1][2],0,0,1}; TArrayD Harray(9,Hvalues); Hperp_.SetMatrixArray(Harray.GetArray()); //calculate Nperp TMatrixD HperpInv(Hperp_); HperpInv.Invert(); TMatrixD U(3,3); U.Zero(); U[0][0]=1; U[1][1]=1; U[2][2]=-1; Nperp_=TMatrixD(HperpInv,TMatrixD::kTransposeMult,TMatrixD(U,TMatrixD::kMult,HperpInv)); }
HHKinFit2::HHKinFitMasterSingleHiggs::HHKinFitMasterSingleHiggs(TLorentzVector const& tauvis1, TLorentzVector const& tauvis2, TVector2 const& met, TMatrixD const& met_cov, bool istruth, TLorentzVector const& higgsgen) :m_MET_COV(TMatrixD(4,4)) { m_tauvis1 = HHLorentzVector(tauvis1.Px(), tauvis1.Py(), tauvis1.Pz(), tauvis1.E()); m_tauvis2 = HHLorentzVector(tauvis2.Px(), tauvis2.Py(), tauvis2.Pz(), tauvis2.E()); m_tauvis1.SetMkeepE(1.77682); m_tauvis2.SetMkeepE(1.77682); m_MET = met; m_MET_COV = met_cov; m_chi2_best = pow(10,10); m_bestHypo = 0; // if (istruth){ // TRandom3 r(0); // // HHLorentzVector recoil; // if(heavyhiggsgen != NULL){ // Double_t pxRecoil = r.Gaus(-(heavyhiggsgen->Px() ), 10.0); // Double_t pyRecoil = r.Gaus(-(heavyhiggsgen->Py() ), 10.0); // // recoil = HHLorentzVector(pxRecoil, pyRecoil, 0, // sqrt(pxRecoil*pxRecoil+pyRecoil*pyRecoil)); // } // else{ // recoil = HHLorentzVector(0,0,0,0); // std::cout << "WARNING! Truthinput mode active but no Heavy Higgs gen-information given! Setting Recoil to Zero!" << std::endl; // } // // TMatrixD recoilCov(2,2); // recoilCov(0,0)=100; recoilCov(0,1)=0; // recoilCov(1,0)=0; recoilCov(1,1)=100; // // HHLorentzVector recoHH = m_bjet1 + m_bjet2 + m_tauvis1 + m_tauvis2 + recoil; // m_MET = TVector2(-recoHH.Px(), -recoHH.Py() ); // // m_MET_COV = TMatrixD(2,2); // m_MET_COV = recoilCov + bjet1Cov + bjet2Cov; // // } }
TMatrixD Chol (TVectorD& covV, TVectorD& newSig) { int nCov = covV.GetNrows(); int n = newSig.GetNrows(); std::cout << nCov << " " << n << std::endl; if ( nCov != n*(n+1)/2. ) { std::cout << "vecTest: mismatch in inputs" << std::endl; return TMatrixD(); } // // create modified vector (replacing std.dev.s) // TVectorD newCovV(covV); int ind(0); for ( int i=0; i<n; ++i ) { for ( int j=0; j<=i; ++j ) { if ( j==i ) newCovV[ind] = newSig(i); ++ind; } } return Chol(newCovV,newSig); }
TMatrixD Chol (TVectorD& covV) { int nCov = covV.GetNrows(); int n = int((sqrt(8*nCov+1.)-1.)/2.+0.5); if ( nCov != n*(n+1)/2. ) { std::cout << "Chol: length of vector " << nCov << " is not n*(n+1)/2" << std::endl; return TMatrixD(); } // get diagonal elements int ind(0); TVectorD sigmas(n); for ( int i=0; i<n; ++i ) { for ( int j=0; j<=i; ++j ) { if ( j == i ) sigmas[i] = covV(ind); ++ind; } } // fill cov matrix (could be more elegant ...) ind = 0; TMatrixDSym covMatrix(n); for ( int i=0; i<n; ++i ) { for ( int j=0; j<=i; ++j ) { if ( j == i ) covMatrix(i,i) = sigmas(i)*sigmas(i); else covMatrix(i,j) = covMatrix(j,i) = covV(ind)*sigmas(i)*sigmas(j); ++ind; } } covMatrix.Print(); TDecompChol tdc(covMatrix); bool worked = tdc.Decompose(); if ( !worked ) { std::cout << "Decomposition failed" << std::endl; return TMatrixD(); } TMatrixD matU = tdc.GetU(); return matU; // // // // cross check with random generation // // // double sum0(0.); // TVectorD sum1(n); // TMatrixDSym sum2(n); // TRandom2 rgen; // TVectorD xrnd(n); // TVectorD xrndRot(n); // for ( unsigned int i=0; i<1000000; ++i ) { // for ( unsigned int j=0; j<n; ++j ) xrnd(j) = 0.; // for ( unsigned int j=0; j<n; ++j ) { // TVectorD aux(n); // for ( int k=0; k<n; ++k ) aux(k) = matU(j,k); // xrnd += rgen.Gaus(0.,1.)*aux; // } // // xrnd *= matUT; // sum0 += 1.; // for ( unsigned int j0=0; j0<n; ++j0 ) { // sum1(j0) += xrnd(j0); // for ( unsigned int j1=0; j1<n; ++j1 ) { // sum2(j0,j1) += xrnd(j0)*xrnd(j1); // } // } // } // for ( unsigned int j0=0; j0<n; ++j0 ) { // printf("%10.3g",sum1(j0)/sum0); // } // printf(" sum1 \n"); // printf("\n"); // for ( unsigned int j0=0; j0<n; ++j0 ) { // for ( unsigned int j1=0; j1<n; ++j1 ) { // printf("%10.3g",sum2(j0,j1)/sum0); // } // printf(" sum2 \n"); // } // return matU; }
ScanResult scanTau(TH2* responseMatrix, TH1* input, bool writeCanvas=true) { const int N = 2000; const int NBINS = responseMatrix->GetNbinsX(); double* tau = new double[N]; double* pmean = new double[N]; double pmean_min=1.0; double pmean_min_tau=0.0; double* pmax = new double[N]; double pmax_min=1.0; double pmax_min_tau=0.0; double** rho_avg = new double*[NBINS]; for (int i = 0; i < NBINS; ++i) { rho_avg[i]=new double[N]; } TH2D error("errorMatrixTauScan","",NBINS,0,NBINS,NBINS,0,NBINS); TUnfoldSys tunfold(responseMatrix,TUnfold::kHistMapOutputHoriz,TUnfold::kRegModeCurvature); for (int iscan=0;iscan< N;++iscan) { tau[iscan]=TMath::Power(10.0,1.0*(iscan/(1.0*N)*5.0-7.0)); tunfold.DoUnfold(tau[iscan],input); error.Scale(0.0); tunfold.GetEmatrix(&error); TMatrixD cov_matrix = convertHistToMatrix(error); TMatrixD inv_cov_matrix=TMatrixD(TMatrixD::kInverted,cov_matrix); TMatrixD diag_cov_halfs(NBINS,NBINS); for (int i=0; i<NBINS; ++i) { for (int j=0; j<NBINS; ++j) { if (i==j) { diag_cov_halfs[i][j]=1.0/TMath::Sqrt((cov_matrix)[i][j]); } else { diag_cov_halfs[i][j]=0.0; } } } //correlations of the unfolded dist TMatrixD rho = diag_cov_halfs*(cov_matrix)*diag_cov_halfs; //calculate the average per bin correlation; will be used in the "subway" plot for (int offrow = 1; offrow<NBINS; ++offrow) { double sum=0.0; for (int entry = 0; entry < NBINS-offrow; ++entry) { sum+=rho[offrow+entry][entry]; } rho_avg[offrow][iscan]=sum/(NBINS-offrow); } double* p = new double[NBINS]; pmean[iscan]=0.0; //will store the average global correlation over bins pmax[iscan]=0.0; //will store the max global correlation over bins for (int i=0; i<NBINS; ++i) { //calculate the global correlations p[i]=sqrt(1.0-1.0/(inv_cov_matrix[i][i]*(cov_matrix)[i][i])); pmean[iscan]+=p[i]; if (p[i]>pmax[iscan]) { pmax[iscan]=p[i]; } } pmean[iscan]=pmean[iscan]/(1.0*NBINS); //check if this is the minimum if (pmean[iscan]<pmean_min) { pmean_min=pmean[iscan]; pmean_min_tau=tau[iscan]; } //check if this is the minimum if (pmax[iscan]<pmax_min) { pmax_min=pmax[iscan]; pmax_min_tau=tau[iscan]; } } TCanvas cv_subway("cv_subway","",800,600); cv_subway.SetRightMargin(0.27); TH2F axes("axes",";#tau;#rho",50,tau[0],tau[N-1],50,-1.1,1.1); axes.Draw("AXIS"); cv_subway.SetLogx(1); double Red[5] = {0.00, 0.00, 0.83, 0.90, 0.65}; double Green[5] = { 0.00, 0.71, 0.90, 0.15, 0.00}; double Blue[5] ={ 0.71, 1.00, 0.12, 0.00, 0.00}; double Length[5] = { 0.00, 0.34, 0.61, 0.84, 1.00 }; int start = TColor::CreateGradientColorTable(5,Length,Red,Green,Blue,(NBINS)*2); TLegend legend(0.74,0.9,0.99,0.2); legend.SetFillColor(kWhite); legend.SetBorderSize(0); legend.SetTextFont(42); for (int i=1; i<NBINS; ++i) { TGraph* graph = new TGraph(N,tau,rho_avg[i]); graph->SetLineColor(start+(i-1)*2+1); graph->SetLineWidth(2); graph->Draw("SameL"); char* graphName= new char[50]; sprintf(graphName,"#LT #rho(i,i+%i) #GT",i); legend.AddEntry(graph,graphName,"L"); } legend.AddEntry("","",""); TGraph* graph_globalrho_avg = new TGraph(N,tau,pmean); graph_globalrho_avg->SetLineColor(kBlack); graph_globalrho_avg->SetLineStyle(2); graph_globalrho_avg->SetLineWidth(3); graph_globalrho_avg->Draw("SameL"); legend.AddEntry(graph_globalrho_avg,"avg. global #rho","L"); char* globalrho_mean= new char[50]; sprintf(globalrho_mean,"#rho|min=%4.3f",pmean_min); legend.AddEntry("",globalrho_mean,""); char* globalrho_mean_tau= new char[50]; sprintf(globalrho_mean_tau,"#tau|min=%3.2e",pmean_min_tau); legend.AddEntry("",globalrho_mean_tau,""); legend.AddEntry("","",""); TGraph* graph_globalrho_max = new TGraph(N,tau,pmax); graph_globalrho_max->SetLineColor(kBlack); graph_globalrho_max->SetLineWidth(3); graph_globalrho_max->SetLineStyle(3); graph_globalrho_max->Draw("SameL"); legend.AddEntry(graph_globalrho_max,"max. global #rho","L"); char* globalrho_max= new char[50]; sprintf(globalrho_max,"#rho|min=%4.3f",pmax_min); legend.AddEntry("",globalrho_max,""); char* globalrho_max_tau= new char[50]; sprintf(globalrho_max_tau,"#tau|min=%3.2e",pmax_min_tau); legend.AddEntry("",globalrho_max_tau,""); legend.Draw("Same"); if (writeCanvas) { cv_subway.Write(); } ScanResult scanResult; scanResult.taumean=pmean_min_tau; scanResult.pmean=pmean_min; scanResult.taumax=pmax_min_tau; scanResult.pmax=pmax_min; return scanResult; }
HHKinFitMaster::HHKinFitMaster(TLorentzVector* bjet1, TLorentzVector* bjet2, TLorentzVector* tauvis1, TLorentzVector* tauvis2, Bool_t truthinput, TLorentzVector* heavyhiggsgen): m_mh1(std::vector<Int_t>()), m_mh2(std::vector<Int_t>()), m_bjet1(bjet1), m_bjet2(bjet2), m_tauvis1(tauvis1), m_tauvis2(tauvis2), m_MET(NULL), m_MET_COV(TMatrixD(2,2)), m_truthInput(truthinput), m_advancedBalance(false), m_simpleBalancePt(0.0), m_simpleBalanceUncert(10.0), m_fullFitResultChi2(std::map< std::pair<Int_t,Int_t> , Double_t>()), m_fullFitResultMH(std::map< std::pair<Int_t,Int_t> , Double_t>()), m_bestChi2FullFit(999), m_bestMHFullFit(-1), m_bestHypoFullFit(std::pair<Int_t, Int_t>(-1,-1) ) { if (m_truthInput){ TRandom3 r(0); m_bjet1Smear = GetBjetResolution(bjet1->Eta(), bjet1->Et()); Double_t bjet1_E = r.Gaus(bjet1->E(), m_bjet1Smear); Double_t bjet1_P = sqrt(pow(bjet1_E,2) - pow(bjet1->M(),2)); Double_t bjet1_Pt = sin(bjet1->Theta())*bjet1_P; std::cout << "Jet1 smeared by: " << (bjet1_E - bjet1->E())/m_bjet1Smear << std::endl; bjet1->SetPtEtaPhiE(bjet1_Pt, bjet1->Eta(), bjet1->Phi(), bjet1_E); TMatrixD bjet1Cov(2,2); Double_t bjet1_dpt = sin(bjet1->Theta())*bjet1->E()/bjet1->P()*m_bjet1Smear; // error propagation p=sqrt(e^2-m^2) bjet1Cov(0,0) = pow(cos(bjet1->Phi())*bjet1_dpt,2); bjet1Cov(0,1) = sin(bjet1->Phi())*cos(bjet1->Phi())*bjet1_dpt*bjet1_dpt; bjet1Cov(1,0) = sin(bjet1->Phi())*cos(bjet1->Phi())*bjet1_dpt*bjet1_dpt; bjet1Cov(1,1) = pow(sin(bjet1->Phi())*bjet1_dpt,2); Double_t bjet2_res = GetBjetResolution(bjet2->Eta(), bjet2->Et()); m_bjet2Smear = GetBjetResolution(bjet2->Eta(), bjet2->Et()); Double_t bjet2_E = r.Gaus(bjet2->E(), m_bjet2Smear); Double_t bjet2_P = sqrt(pow(bjet2_E,2) - pow(bjet2->M(),2)); Double_t bjet2_Pt = sin(bjet2->Theta())*bjet2_P; std::cout << "Jet1 smeared by: " << (bjet2_E - bjet2->E())/m_bjet2Smear << std::endl; bjet2->SetPtEtaPhiE(bjet2_Pt, bjet2->Eta(), bjet2->Phi(), bjet2_E); TMatrixD bjet2Cov(2,2); Double_t bjet2_dpt = sin(bjet2->Theta())*bjet2->E()/bjet2->P()*m_bjet2Smear; // error propagation p=sqrt(e^2-m^2) bjet2Cov(0,0) = pow(cos(bjet2->Phi())*bjet2_dpt,2); bjet2Cov(0,1) = sin(bjet2->Phi())*cos(bjet2->Phi())*bjet2_dpt*bjet2_dpt; bjet2Cov(1,0) = sin(bjet2->Phi())*cos(bjet2->Phi())*bjet2_dpt*bjet2_dpt; bjet2Cov(1,1) = pow(sin(bjet2->Phi())*bjet2_dpt,2); TLorentzVector* recoil; if(heavyhiggsgen != NULL){ Double_t pxRecoil = r.Gaus(-(heavyhiggsgen->Px() ), 10.0); Double_t pyRecoil = r.Gaus(-(heavyhiggsgen->Py() ), 10.0); std::cout << "Higgs Recoil X smeared by: " << pxRecoil + heavyhiggsgen->Px() << std::endl; std::cout << "Higgs Recoil Y smeared by: " << pyRecoil + heavyhiggsgen->Py() << std::endl; recoil = new TLorentzVector(pxRecoil,pyRecoil,0,sqrt(pxRecoil*pxRecoil+pyRecoil*pyRecoil)); } else{ recoil = new TLorentzVector(0,0,0,0); std::cout << "WARNING! Truthinput mode active but no Heavy Higgs gen-information given! Setting Recoil to Zero!" << std::endl; } TMatrixD recoilCov(2,2); recoilCov(0,0)=100; recoilCov(0,1)=0; recoilCov(1,0)=0; recoilCov(1,1)=100; TLorentzVector* met = new TLorentzVector(-(*bjet1 + *bjet2 + *tauvis1 + *tauvis2 + *recoil)); TMatrixD metCov(2,2); metCov = recoilCov + bjet1Cov + bjet2Cov; setAdvancedBalance(met, metCov); m_bjet1_smeared = *bjet1; m_bjet2_smeared = *bjet2; m_met_smeared = *met; delete recoil; } }
//############################################################################# double* TrTrackA::PredictionStraightLine(int index){ static double pred[7]; #pragma omp threadprivate (pred) int _Nhit = _Hit.size(); // Consistency check on the number of hits if (_Nhit<3) return NULL; // Get hit positions and uncertainties // Scale errors (we will use sigmas in microns) double hits[_Nhit][3]; double sigma[_Nhit][3]; for (int i=0;i<_Nhit;i++){ for (int j=0;j<3;j++){ hits[i][j] = _Hit[i].Coo[j]; sigma[i][j] = 1.e4*_Hit[i].ECoo[j]; if (i==index) sigma[i][j] *= 1.e2; } } // Lenghts double lenz[_Nhit]; for (int i=0;i<_Nhit;i++) lenz[i] = hits[i][2] - _Hit[0].Coo[2]; // F and G matrices const int idim = 4; double d[2*_Nhit][idim]; for (int i=0;i<_Nhit;i++) { int ix = i; int iy = i+_Nhit; for (int j=0;j<idim;j++) { d[ix][j] = 0; d[iy][j] = 0;} d[ix][0] = 1.; d[iy][1] = 1.; d[ix][2] = lenz[i]; d[iy][3] = lenz[i]; } // F*S_x*x + G*S_y*y double dx[idim]; for (int j=0;j<idim;j++) { dx[j] = 0.; for (int l=0;l<_Nhit;l++) { dx[j] += d[l][j]/sigma[l][0]/sigma[l][0]*hits[l][0]; dx[j] += d[l+_Nhit][j]/sigma[l][1]/sigma[l][1]*hits[l][1]; } } // (F*S_x*F + G*S_y*G) double Param[idim]; double InvCov[idim][idim]; for (int j=0;j<idim;j++) { for (int k=0;k<idim;k++) { InvCov[j][k] = 0.; for (int l=0;l<_Nhit;l++) { InvCov[j][k] += d[l][j]/sigma[l][0]/sigma[l][0]*d[l][k]; InvCov[j][k] += d[l+_Nhit][j]/sigma[l][1]/sigma[l][1]*d[l+_Nhit][k]; } } } // (F*S_x*F + G*S_y*G)**{-1} double determ = 0.0; TMatrixD ParaCovariance = TMatrixD(idim,idim,(Double_t*)InvCov," "); ParaCovariance = ParaCovariance.Invert(&determ); if (determ<=0) return NULL; // Solution for (int k=0;k<idim;k++) { Param[k] = 0.; for (int i=0;i<idim;i++) { Param[k] += ParaCovariance(k,i)*dx[i]; } } // Chi2 (xl and yl in microns, since sigmas are in microns too) pred[0] = 0; pred[1] = 0; pred[2] = _Hit[index].Coo[2]; pred[3] = acos(-sqrt(1-Param[2]*Param[2]-Param[3]*Param[3])); pred[4] = atan2(Param[3],Param[2]); pred[5] = 0.; pred[6] = 0.; for (int k=0;k<idim;k++) { pred[0] += d[index][k]*Param[k]; pred[1] += d[index+_Nhit][k]*Param[k]; for (int l=0;l<idim;l++) { pred[5] += d[index][k]*d[index][l]*ParaCovariance(k,l); pred[6] += d[index+_Nhit][k]*d[index+_Nhit][l]*ParaCovariance(k,l); } } if (pred[5]>0.) pred[5] = 1.e-4*sqrt(pred[5]); else pred[5]=0.; if (pred[6]>0.) pred[6] = 1.e-4*sqrt(pred[6]); else pred[6]=0.; return pred; }
//############################################################################# double* TrTrackA::Prediction(int index){ static double pred[7]; #pragma omp threadprivate (pred) int _Nhit = _Hit.size(); // Consistency check on the number of hits if (_Nhit<4) return NULL; // Scale errors (we will use sigmas in microns) double hits[_Nhit][3]; double sigma[_Nhit][3]; for (int i=0;i<_Nhit;i++){ for (int j=0;j<3;j++){ hits[i][j] = _Hit[i].Coo[j]; sigma[i][j] = 1.e4*_Hit[i].ECoo[j]; if (i==index) sigma[i][j] *= 1.e2; } } if (!_PathIntExist) SetPathInt(); // F and G matrices const int idim = 5; double d[2*_Nhit][idim]; for (int i=0;i<_Nhit;i++) { int ix = i; int iy = i+_Nhit; for (int j=0;j<idim;j++) { d[ix][j] = 0; d[iy][j] = 0;} d[ix][0] = 1.; d[iy][1] = 1.; for (int k=0;k<=i;k++) { d[ix][2] += _PathLength[k]; d[iy][3] += _PathLength[k]; d[ix][4] += _PathLength[k]*_PathLength[k]*_PathIntegral_x[0][k]; d[iy][4] += _PathLength[k]*_PathLength[k]*_PathIntegral_x[1][k]; for (int l=k+1;l<=i;l++) { d[ix][4] += _PathLength[k]*_PathLength[l]*_PathIntegral_u[0][k]; d[iy][4] += _PathLength[k]*_PathLength[l]*_PathIntegral_u[1][k]; } } } // F*S_x*x + G*S_y*y double dx[idim]; for (int j=0;j<idim;j++) { dx[j] = 0.; for (int l=0;l<_Nhit;l++) { dx[j] += d[l][j]/sigma[l][0]/sigma[l][0]*hits[l][0]; dx[j] += d[l+_Nhit][j]/sigma[l][1]/sigma[l][1]*hits[l][1]; } } // (F*S_x*F + G*S_y*G) double Param[idim]; double InvCov[idim][idim]; for (int j=0;j<idim;j++) { for (int k=0;k<idim;k++) { InvCov[j][k] = 0.; for (int l=0;l<_Nhit;l++) { InvCov[j][k] += d[l][j]/sigma[l][0]/sigma[l][0]*d[l][k]; InvCov[j][k] += d[l+_Nhit][j]/sigma[l][1]/sigma[l][1]*d[l+_Nhit][k]; } } } // (F*S_x*F + G*S_y*G)**{-1} double determ = 0.0; TMatrixD ParaCovariance = TMatrixD(idim,idim,(Double_t*)InvCov," "); ParaCovariance = ParaCovariance.Invert(&determ); if (determ<=0) return NULL; // Solution //printf(">>>>>>>>>>>>> Cov AFTER:\n"); for (int k=0;k<idim;k++) { Param[k] = 0.; for (int i=0;i<idim;i++) { Param[k] += ParaCovariance[k][i]*dx[i]; //printf(" %f", ParaCovariance[k][i]); } //printf("\n"); } // Chi2 (xl and yl in microns, since sigmas are in microns too) pred[0] = 0; pred[1] = 0; pred[2] = hits[index][2]; pred[3] = acos(-sqrt(1-Param[2]*Param[2]-Param[3]*Param[3])); pred[4] = atan2(Param[3],Param[2]); pred[5] = 0.; pred[6] = 0.; for (int k=0;k<idim;k++) { pred[0] += d[index][k]*Param[k]; pred[1] += d[index+_Nhit][k]*Param[k]; for (int l=0;l<idim;l++) { pred[5] += d[index][k]*d[index][l]*ParaCovariance(k,l); pred[6] += d[index+_Nhit][k]*d[index+_Nhit][l]*ParaCovariance(k,l); } } if (pred[5]>0.) pred[5] = 1.e-4*sqrt(pred[5]); else pred[5]=0.; if (pred[6]>0.) pred[6] = 1.e-4*sqrt(pred[6]); else pred[6]=0.; return pred; }
//############################################################################# int TrTrackA::StraightLineFit(){ int _Nhit = _Hit.size(); // Reset fit values Chi2 = FLT_MAX; Ndof = 2*_Nhit-4; Theta = 0.0; Phi = 0.0; U[0] = 0.0; U[1] = 0.0; U[2] = 1.0; P0[0] = 0.0; P0[1] = 0.0; P0[2] = 0.0; Rigidity = FLT_MAX; // Consistency check on the number of hits if (_Nhit<3) return -2; P0[2] = _Hit[0].Coo[2]; // Get hit positions and uncertainties // Scale errors (we will use sigmas in microns) double hits[_Nhit][3]; double sigma[_Nhit][3]; for (int i=0;i<_Nhit;i++){ for (int j=0;j<3;j++){ hits[i][j] = _Hit[i].Coo[j]; sigma[i][j] = 1.e4*_Hit[i].ECoo[j]; } } // Lenghts double lenz[_Nhit]; for (int i=0;i<_Nhit;i++) lenz[i] = hits[i][2] - P0[2]; // F and G matrices const int idim = 4; double d[2*_Nhit][idim]; for (int i=0;i<_Nhit;i++) { int ix = i; int iy = i+_Nhit; for (int j=0;j<idim;j++) { d[ix][j] = 0; d[iy][j] = 0;} d[ix][0] = 1.; d[iy][1] = 1.; d[ix][2] = lenz[i]; d[iy][3] = lenz[i]; } // F*S_x*x + G*S_y*y double dx[idim]; for (int j=0;j<idim;j++) { dx[j] = 0.; for (int l=0;l<_Nhit;l++) { dx[j] += d[l][j]/sigma[l][0]/sigma[l][0]*hits[l][0]; dx[j] += d[l+_Nhit][j]/sigma[l][1]/sigma[l][1]*hits[l][1]; } } // (F*S_x*F + G*S_y*G) double Param[idim]; double InvCov[idim][idim]; for (int j=0;j<idim;j++) { for (int k=0;k<idim;k++) { InvCov[j][k] = 0.; for (int l=0;l<_Nhit;l++) { InvCov[j][k] += d[l][j]/sigma[l][0]/sigma[l][0]*d[l][k]; InvCov[j][k] += d[l+_Nhit][j]/sigma[l][1]/sigma[l][1]*d[l+_Nhit][k]; } } } // (F*S_x*F + G*S_y*G)**{-1} double determ = 0.0; TMatrixD ParaCovariance = TMatrixD(idim,idim,(Double_t*)InvCov," "); ParaCovariance = ParaCovariance.Invert(&determ); if (determ<=0) return -1; // Solution for (int k=0;k<idim;k++) { Param[k] = 0.; for (int i=0;i<idim;i++) { Param[k] += ParaCovariance(k,i)*dx[i]; } } // Chi2 (xl and yl in microns, since sigmas are in microns too) Chi2 = 0.; for (int l=0;l<_Nhit;l++) { double xl = hits[l][0]*1.e4; double yl = hits[l][1]*1.e4; for (int k=0;k<idim;k++) { xl -= d[l][k]*Param[k]*1.e4; yl -= d[l+_Nhit][k]*Param[k]*1.e4; } Chi2 += xl/sigma[l][0]/sigma[l][0]*xl + yl/sigma[l][1]/sigma[l][1]*yl; } // Final result P0[0] = Param[0]; P0[1] = Param[1]; Phi = atan2(Param[3],Param[2]); Theta = acos(-sqrt(1-Param[2]*Param[2]-Param[3]*Param[3])); U[0] = sin(Theta)*cos(Phi); U[1] = sin(Theta)*sin(Phi); U[2] = cos(Theta); return 0; }