//***************************************************************************** void fitter::ComputeMomFromParabola(const Trajectory& traj, int nplanes, int firsthit, EVector& V){ //***************************************************************************** //Some catchers for pointless returns. int fitcatch; // int nfit, sign; int fitRange[3]; const int fitpoints = nplanes - firsthit; double xpos[fitpoints], ypos[fitpoints], zpos[fitpoints]; double upos[fitpoints], vpos[fitpoints]; int pos = 0; EVector currentpos = EVector(3,0); EVector currentB = EVector(3,0); EVector z = EVector(3,0); z[2] = 1; double Bmean=0; for( int ipoint=firsthit; ipoint < nplanes; ipoint ++ ){ xpos[pos] = traj.node(ipoint).measurement().position()[0]; ypos[pos] = traj.node(ipoint).measurement().position()[1]; zpos[pos] = traj.node(ipoint).measurement().position()[2] - traj.node(firsthit).measurement().position()[2]; currentpos[0] = traj.node(ipoint).measurement().position()[0]; currentpos[1] = traj.node(ipoint).measurement().position()[1]; currentpos[2] = 0.; currentB = _geom.getBField(currentpos); upos[pos] = xpos[pos] > 0 ? asin(ypos[pos]/currentpos.norm()) : -asin(ypos[pos]/currentpos.norm()); vpos[pos] = dot(currentpos,crossprod(z,currentB))/currentB.norm(); Bmean += currentB.norm(); ++pos; } Bmean /= pos; Bmean /= tesla; if (fitpoints <= 15) { nfit = 1; fitRange[0] = fitpoints;} else if (fitpoints <= 40) { nfit = 2; fitRange[0] = 15; fitRange[1] = (int)(0.7*fitpoints); } else if (fitpoints > 40) { nfit = 3; fitRange[0] = 15; fitRange[1] = (int)(fitpoints/2); fitRange[2] = (int)(0.7*fitpoints); } for (int ifit = 0;ifit < nfit;ifit++) { TGraph *trajFitXZ = new TGraph(fitRange[ifit],zpos, xpos); TGraph *trajFitYZ = new TGraph(fitRange[ifit],zpos, ypos); TGraph *trajFitUZ = new TGraph(fitRange[ifit],zpos, upos); TGraph *trajFitVZ = new TGraph(fitRange[ifit],zpos, vpos); TF1 *func = new TF1("fit",fitf2,-3,3,3); func->SetParameters(0.,0.,0.001,0.0001,0.0001); func->SetParNames("a", "b", "c", "d", "e"); TF1 *func2 = new TF1("fit2",fitf2,-3,3,3); func2->SetParameters(0.,0.,0.001,0.0001,0.0001); func2->SetParNames("f", "g", "h", "i", "j"); TF1 *func3 = new TF1("fit3",fitf2,-3,3,3); func->SetParameters(0.,0.,0.001,0.0001,0.0001); func->SetParNames("a1", "b1", "c1", "d1", "e1"); TF1 *func4 = new TF1("fit4",fitf2,-3,3,3); func2->SetParameters(0.,0.,0.001,0.0001,0.0001); func2->SetParNames("f1", "g1", "h1", "i1", "j1"); fitcatch = trajFitXZ->Fit("fit", "QN"); fitcatch = trajFitYZ->Fit("fit2", "QN"); fitcatch = trajFitUZ->Fit("fit3", "QN"); fitcatch = trajFitVZ->Fit("fit4", "QN"); double b = func->GetParameter(1); double c = func->GetParameter(2); double g = func2->GetParameter(1); /*double f = func2->GetParameter(0); double a = func->GetParameter(0); double h = func2->GetParameter(2); double a1 = func3->GetParameter(0); double b1 = func3->GetParameter(1); double c1 = func3->GetParameter(2); double f1 = func4->GetParameter(0);*//// double g1 = func4->GetParameter(1); double h1 = func4->GetParameter(2); if (ifit == 0) { V[4] = g; //func2->GetParameter(1); V[3] = b; if (h1!=0) { V[5] = 1./(-0.3*Bmean*pow((1+g1*g1),3./2.)/ (2*h1)*0.01); V[5] /= GeV; sign = (int)( V[5]/fabs( V[5] )); } else V[5] = 0; } else { if ((int)(-c/fabs(c)) == sign) { V[4] = g; V[3] = b; V[5] = 1/(-0.3*Bmean*pow((1+g1*g1),3./2.)/(2*h1)*0.01); V[5] /= GeV; } else break; } delete trajFitXZ; delete trajFitYZ; delete trajFitUZ; delete trajFitVZ; delete func; delete func2; delete func3; delete func4; } //std::cout<<"Momentum guess from polynomial fit: p/q = "<<1./V[5]<<std::endl; }
//***************************************************************************** void fitter::ComputeMomFromRange(const Trajectory& traj, int nplanes, int firsthit, EVector& V){ //***************************************************************************** //Some catchers for pointless returns. int fitcatch; // /// int nfit; /// int fitRange[3]; const int fitpoints = nplanes - firsthit; ///double meanchange = 0; double xpos[fitpoints], ypos[fitpoints], zpos[fitpoints]; double upos[fitpoints];/// wpos[fitpoints]; std::vector<EVector> dr; std::vector<EVector> B; bool isContained = true, cuspfound = false; double Xmax = _geom.getPlaneX() - 1*cm; double Ymax = _geom.getPlaneY() - 1*cm; /// double Zmax = _geom.getPlaneZ() - 1*cm; //double dx[fitpoints-1], dy[fitpoints-1], dz[fitpoints-1]; // double ax[fitpoints-2], ay[fitpoints-2], az[fitpoints-2]; // double bx[fitpoints-2], by[fitpoints-2], bz[fitpoints-2]; ///double ds0=0, ds1=0; double Bmean=0; double pathlength=0; int Npts=0; ///double initR = 0; double sumDR = 0; int minindex = nplanes - firsthit; ///double minR = 999999.9999; double pdR = 0.0; EVector Z = EVector(3,0); Z[2] = 1; for (int ipoint=firsthit;ipoint < nplanes;ipoint++){ xpos[ipoint-firsthit] = traj.node(ipoint).measurement().position()[0]; ypos[ipoint-firsthit] = traj.node(ipoint).measurement().position()[1]; zpos[ipoint-firsthit] = traj.node(ipoint).measurement().position()[2] - traj.node(firsthit).measurement().position()[2]; if(fabs(xpos[ipoint-firsthit]) > Xmax || fabs(ypos[ipoint-firsthit]) > Ymax) isContained = false; else if(fabs(ypos[ipoint-firsthit]) > (1 + tan(atan(1.)/2.)) * Xmax - fabs(xpos[ipoint-firsthit])) isContained = false; EVector pos0 = EVector(3,0); pos0[0] = xpos[ipoint-firsthit]; pos0[1] = ypos[ipoint-firsthit]; pos0[2] = zpos[ipoint-firsthit]; EVector B0 = _geom.getBField(pos0); B.push_back(B0); Bmean += B0.norm(); upos[ipoint-firsthit] = // sqrt(pos0[0]*pos0[0] + pos0[1]*pos0[1]); dot(pos0,crossprod(Z, B0))/crossprod(Z, B0).norm(); //if(!cuspfound) // if(ipoint == firsthit) initR = upos[ipoint-firsthit]; // else { //sumDR += initR - upos[ipoint-firsthit]; //initR = upos[ipoint - firsthit]; // } Npts++; if ( ipoint > firsthit){ EVector drtemp = EVector(3,0); drtemp[0] = xpos[ipoint-firsthit] - xpos[ipoint-firsthit-1]; drtemp[1] = ypos[ipoint-firsthit] - ypos[ipoint-firsthit-1]; drtemp[2] = zpos[ipoint-firsthit] - zpos[ipoint-firsthit-1]; dr.push_back(drtemp); pathlength += drtemp.norm(); if ( ipoint > firsthit + 1 ) { int k = ipoint-firsthit-1; EVector dr0 = dr[k-1]; EVector dr1 = dr[k]; EVector ddr = dr1 + dr0; EVector Ddr = dr1 - dr0; EVector pos = EVector(3,0); pos[0] = xpos[k-1]; pos[1] = ypos[k-1]; pos[2] = zpos[k-1]; EVector B = _geom.getBField(pos); double dR = dot(ddr, crossprod(Z, B0))/ (crossprod(Z,B0).norm()); double DR = dot(Ddr, crossprod(Z, B0))/ (crossprod(Z,B0).norm()); if(pdR != 0.0){ if(!cuspfound && DR/fabs(DR) == pdR/fabs(pdR)){ // sumDR += fabs(dR) > 0.0 ? dR/fabs(dR):0.0; sumDR += dR; // pdR = dR; pdR = dR; } else if(dR/fabs(dR) != pdR/fabs(pdR)){ // cuspfound = true; minindex = ipoint - firsthit - 1; pdR = dR; // std::cout<<"At cusp, sumDR = "<<sumDR<<std::endl; } } else if(!cuspfound && fabs(dR) > 0){ // sumDR += fabs(DR) > 0.0 ? DR/fabs(DR) : 0.0; sumDR += dR; pdR = dR; } /* if(pdR != 0){ if(minR < upos[ipoint - firsthit - 1] && (xpos[ipoint-firsthit]/fabs(xpos[ipoint-firsthit]) != xpos[ipoint-firsthit-1]/fabs(xpos[ipoint-firsthit-1])) || (ypos[ipoint-firsthit]/fabs(ypos[ipoint-firsthit]) != ypos[ipoint-firsthit-1]/fabs(ypos[ipoint-firsthit-1])) && !cuspfound){ minR = upos[ipoint - firsthit - 1]; minindex = ipoint - firsthit - 1; cuspfound = true; } }*/ } } } Bmean /=Npts; double wFe = _geom.get_Fe_prop(); double p = (wFe*(0.017143*GeV/cm * pathlength - 1.73144*GeV) + (1- wFe)*(0.00277013*GeV/cm * pathlength + 1.095511*GeV)); double meansign = 1; if(sumDR != 0) { //std::cout<<"sumDR = "<<sumDR<<std::endl; meansign = sumDR/fabs(sumDR); } ///double planesep = fabs(zpos[1] - zpos[0]); // Assume that the magnetic field does not change very much over 1 metre // (terrible assumption by the way) const int sample = minindex < 20 ? (const int)minindex: 20; int pi3=0, pi4=0; while(dr.at(pi3)[2] == 0.0) pi3++; while(dr.at(pi4)[2] == 0.0) pi4++; V[3] = dr.at(pi3)[0]/dr.at(pi3)[2]; V[4] = dr.at(pi4)[1]/dr.at(pi4)[2]; if(isContained && p != 0) V[5] = meansign/fabs(p); else{ // meansign = 0; // Consider a fit to a subset of points at the begining of the track //for(int j=0; j<fitpoints-2; j++){ TGraph* localcurveUW = new TGraph(sample, zpos, upos); TF1 *func = new TF1("fit",fitf2,-30,30,4); func->SetParameters(0.,0.,0.001,0.0001,0.0001); func->SetParNames("a", "b", "c", "d", "e"); fitcatch = localcurveUW->Fit("fit", "QN"); double b = func->GetParameter(1); double c = func->GetParameter(2); p = 300.0 * B[1].norm() * pow(1. + b*b,3./2.) /2./c; //double wt = TMath::Gaus(fabs(pt), p, 0.25*p, true); // std::cout<<pt<<std::endl; // meansign += wt * pt/fabs(pt); delete localcurveUW; delete func; if(p!=0){ meansign = p/fabs(p); V[5] = 1./p; } } int sign = 1; if(meansign==meansign){ if(meansign!=0) sign = int(meansign/fabs(meansign)); else sign = 0; } else sign = 1; // std::cout<<"Pathlength is "<<pathlength // <<" or "<<pathlength0 // <<" with charge "<<meansign<<std::endl; _initialqP = V[5]; // _m.message("_initialqP ="<<_initialqP,bhep::VERBOSE); }