Example #1
0
//*****************************************************************************
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;
}
Example #2
0
//*****************************************************************************
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);
  
}