HOWTO Project a charged track to a radius or plane

From GlueXWiki
Jump to: navigation, search

Matching a charged track with a TOF hit or a calorimeter cluster requires projecting a reconstructed track to the appropriate detector by swimming it through the magnetic field. The tracking code provides some mechanism by which to do this as is documented here.

There are 2 ways to do this. The first will work with legacy code (which happens to include the code in the main trunk of the tree at the time of this writing!) and a newer way which will make this feature a little simpler and will be committed to the repository in the near future.

Limitations

The methods described below both use the same underlying mechanism which has some limitations. Namely:

  • Energy loss is not taken into account. This will affect low-momentum protons mostly
  • Multiple scattering is not taken into account (tracks are swum from vertex, but true tracks may have a kink in them)
  • The track will be swum a maximum of 20 meters along the trajectory after which, it will return an error.
  • Errors on the position at the surface are not made available

Classic Method

This method is required for releases up to and including release-2009-05-27.

The method uses the SwimToRadius and SwimToPlane methods of the DMagneticFieldStepper class. Here, you must create a new DMagneticFieldStepper object using the charge, position, and momentum information from a point on the track. You must also get a pointer to the current DMagneticFieldMap object which DMagneticFieldStepper uses to access the magnetic field information. Here is an example code snippet of how one might create a DMagneticFieldStepper object:

// Get the pointer to the DMagneticFieldMap using the JEventLoop pointer
DApplication* dapp = dynamic_cast<DApplication*>(loop->GetJApplication());
if(!dapp){
   _DBG_<<"Cannot get DApplication from JEventLoop! (are you using a JApplication based program?)"<<endl;
   return;
}
DMagneticFieldMap *bfield = dapp->GetBfield();

// Get the charge, momentum and position information from the DParticle object
double q = part->charge(); // part is of type DParticle*
DVector3 pos = part->position();
DVector3 mom = part->momentum();

// Create DMagneticFieldStepper object
DMagneticFieldStepper *stepper = new DMagneticFieldStepper(bfield, q, &pos, &mom);

Now the stepper object can be used to swim to a radius ...

DVector3 pos_bcal = pos; // The DVector3 we pass in will be used for both input and output
DVector3 mom_bcal = mom; // The DVector3 we pass in will be used for both input and output
if( stepper->SwimToRadius(pos_bcal, mom_bcal, 65.0)){
   // An error was encountered. Probably the track never hits the plane
}else{
   // If we get here then the values in pos_bcal and mom_bcal represent the track at the specified radius.
   //     .... use pos_bcal ....
}

... or a plane ...

DVector3 pos_fcal = pos; // The DVector3 we pass in will be used for both input and output
DVector3 mom_fcal = mom; // The DVector3 we pass in will be used for both input and output

// Define the plane by giving a point on the plane an a vector normal to the plane
DVector3 origin(0.0, 0.0, 625.3); // point on upstream face of FCAL
DVector3 norm(0.0, 0.0, 1.0); // Direction normal to FCAL 

if( stepper->SwimToPlane(pos_fcal, mom_fcal, origin, norm)){
   // An error was encountered. Probably the track never makes it out to the specified plane
}else{
   // If we get here then the values in pos_fcal and mom_fcal represent the track at the specified plane.
   //     .... use pos_fcal ....
}

Modern Method

This method will just use a wrapper method in the DReferenceTrajectory class that calls the DMagneticFieldStepper methods automatically. Since the DReferenceTrajectory already knows about the B-field there's no need to jump through hoops to get a pointer to it as described above. Similarly for the track parameters. Also, since the DReferenceTrajectory object keeps a list of lots of steps along the trajectory, the swimming can be initiated at a much later point rather than starting at the vertex making it faster.

Radius:

DVector3 pos_bcal, mom_bcal;
if(part->rt->SwimToRadius(pos_bcal, mom_bcal, 65.0) )
   // An error was encountered. Probably the track never makes it out to the specified radius
}else{
    // If we get here then the values in pos_bcal and mom_bcal represent the track at the specified radius.
    //     .... use pos_bcal ....
}

Plane:

// Define the plane by giving a point on the plane an a vector normal to the plane
DVector3 origin(0.0, 0.0, 625.3); // point on upstream face of FCAL
DVector3 norm(0.0, 0.0, 1.0); // Direction normal to FCAL 

DVector3 pos_fcal, mom_fcal;
if(part->rt->SwimToPlane(pos_fcal, mom_fcal, origin, norm) )
   // An error was encountered. Probably the track never makes it out to the specified plane
}else{
    // If we get here then the values in pos_fcal and mom_fcal represent the track at the specified plane.
    //     .... use pos_fcal ....
}