BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//_____________________________________________________________________________
// 			                                             
// The BrModuleMatchTrack class provides an interface to the BRAHMS  
// Tracking Combining of two detectors with a magnet in between.
// It is a general module combining any two tracking detectors
// surrounding a single dipole. eg. TPM1-D5-TPM2 or T1-D2-T2
//
// At present the module assumes the effective edge approximation 
// for the magnetic field. 
//
//  Initial track matching is done base on 3 cut parameters, namely
//  All the following cuts are sigmas in the variable. The actual cut
//  in done in MatchesCuts(dang, dy, daly, p)
//     SigmaMatchedDang : cut for difference in signed angle between tracks
//                 alpah1-alpha2. Good tracks have DAlpha=0. This cut
//                 is momentum and particle dependent. 
//     SigmaMatchedDy   : cut for vertical position difference on effective midplane.
//     SigmaMatchedDaly : cut for vertical slope difference (take as dy/dz for track
//                 front and back of magnet.
//     SigmaRange: The actual cut is SigmaRange*Sigmaparameter.
//
//     MatchDyOffset : Quite often small offset are present in the
//                     tracking matching. This is introduced in order to make
//                     symmetric cuts. The parameter is only used when
//                     checking for the cuts limits.
//
//  The calculations of tracks are now done in relative coordinates, and not
//  in global as before. This implies changes for the members of the content of
//  BrMatchedTrack. 
//

//____________________________________________________________________________
//
// $Id: BrModuleMatchTrack.cxx,v 1.16 2002/08/08 15:36:13 ufstasze Exp $
// $Author: ufstasze $
// $Date: 2002/08/08 15:36:13 $
//

#include "TH1.h"
#include "TH2.h"
#include "TMath.h"
#include "TDirectory.h"
#include "TClonesArray.h"
#include "TString.h"
#include "TNtuple.h"

#include "BrModuleMatchTrack.h"
#include "BrDetectorVolume.h"
#include "BrMagnetVolume.h"
#include "BrEventNode.h"
#include "BrDataTable.h"
#include "BrDetectorTrack.h"
#include "BrSpectrometerTracks.h"
#include "BrGeometryDbManager.h"
#include <BrCoordinateSystem.h>
#include <BrUnits.h>
#include <BrIostream.h>

#include <vector>

//___________________________________________________________________
ClassImp(BrModuleMatchTrack);
  
  
//___________________________________________________________________
 Char_t* BrModuleMatchTrack::GetSourceVersion() const {
  return Form("$Source: /afs/rhic/brahms/BRAHMS_CVS/brat/modules"
	      "/track/combine/BrModuleMatchTrack.cxx,v $ $Revision: 1.16 $");
}


//___________________________________________________________________
 BrModuleMatchTrack::BrModuleMatchTrack() :
  BrModule()
{
  // Default Constructor. Do not use - Is only here for the purpose
  // of various ROOT functionality.

  fFrontVolume  = 0;
  fBackVolume   = 0;
  fMagnetVolume = 0;
  fTracksFrontBack = 0;
}

//___________________________________________________________________
 BrModuleMatchTrack::BrModuleMatchTrack(const Char_t *Name, const Char_t *Title)
  : BrModule(Name,Title)
{
  //Set volume parameters to null, 
  //Create clones arrays for internal use
  //Read simulation parameters from default file (simpar.dat) in current directory
  
  fFrontVolume  = 0;
  fBackVolume   = 0;
  fMagnetVolume = 0;
  fTracksFrontBack = 0;
  CreateClonesArrays();
  fFieldParametersRead = kFALSE;
  
  SetDefaultParameters();

}

//___________________________________________________________________
 BrModuleMatchTrack::BrModuleMatchTrack(const Char_t *Name, const Char_t *Title,
				       const Char_t *tfront, const Char_t *tback, 
				       const Char_t* tmagnet) 
  : BrModule(Name,Title) 
{
  //
  // Constructor; Setup module.
  //
  // Get volume parameters from BrGeometryDbManager. This removes any 
  // need for the application to deal with the geometry. This module 
  // do not need to know where the Db information comes from. Please 
  // note that the geometry db objects are owned by the
  // Geometry Manager and MUST not be deleted by the module.
  //
  // Create clones arrays for internal use
  // Set default matching parameters.
  //
  fFrontVolume  = 0;
  fBackVolume   = 0;
  fMagnetVolume = 0;
  fFrontName    = tfront;
  fBackName     = tback;
  fMagnetName   = tmagnet;
  fTracksFrontBack = 0;
  CreateClonesArrays();
  SetDefaultParameters();

}

//___________________________________________________________________
 void BrModuleMatchTrack::Init()
{

  // initialize geometry

  BrGeometryDbManager* gGeomDb = BrGeometryDbManager::Instance();
  fFrontVolume  = (BrDetectorVolume*) 
    gGeomDb->GetDetectorVolume("BrDetectorVolume", fFrontName); 
  if(!fFrontVolume)
    Abort("Init","No Back Detector Volume : %s", fFrontName.Data());

  fBackVolume  = (BrDetectorVolume*) 
    gGeomDb->GetDetectorVolume("BrDetectorVolume", fBackName);
  if(!fBackVolume)
    Abort("Init","No Back Detector Volume : %s", fBackName.Data());

  fMagnetVolume  = (BrMagnetVolume*) 
    gGeomDb->GetDetectorVolume("BrMagnetVolume", fMagnetName); 
  if(!fMagnetVolume)
    Abort("Init","No Magnet Volume : %s", fMagnetName.Data());
}

//___________________________________________________________________
 void BrModuleMatchTrack::DefineHistograms()
{
  //
  // define diagnostics histograms for track combination module   //
  // Book histograms (called from BrModule::Book)
  //
  TDirectory* savdir = gDirectory;
  Char_t Dirname[32];
  sprintf(Dirname,"Match_%s",GetName());
  TDirectory* hdir = savdir->mkdir(Dirname);
  if (!hdir) {
    Warning("DefineHistograms","Could not create histogram subdirectory");
    return;
  }

  hdir->cd();
  
  Char_t Title[132];
  Char_t Name[32];

 sprintf(Title, "%s Front Tracks per event",GetName());
 sprintf(Name, "hFrontTracks_%s",GetName());
 hFrontTracks = new TH1F(Name, Title, 40, -0.5, 39.5);

 sprintf(Title, "%s Back Tracks per event",GetName());
 sprintf(Name, "hBackTracks_%s",GetName());
 hBackTracks  = new TH1F(Name, Title, 40, -0.5, 39.5);

 sprintf(Title, "%s Good Matched  Tracks per event",GetName());
 sprintf(Name, "hGoodMatchedTracks_%s",GetName());
 hGoodMatchedTracks  = new TH1F(Name, Title, 40, -0.5, 39.5);

 sprintf(Title, "%s MatchedTracks per event",GetName());
 sprintf(Name, "hMatchedTracks_%s",GetName());
 hMatchedTracks  = new TH1F(Name, Title, 40, -0.5, 39.5);

 sprintf(Title, "%s Dy Midplane matching (front - Back) ",GetName());
 sprintf(Name, "hDyAll_%s",GetName());
 hMatchDyAll  = new TH1F(Name, Title, 100, -5., 5.);

 sprintf(Title, "%s X Midplane Acpt Tracks",GetName());
 sprintf(Name, "hXAcpt_%s",GetName());
 hMatchMidX  = new TH1F(Name, Title, 100, -25., 25.);

 sprintf(Title, "%s Y Midplane Acpt Tracks (front-back)", GetName());
 sprintf(Name, "hYAcpt_%s",GetName());
 hMatchMidY  = new TH1F(Name, Title, 80, -20., 20.);

 sprintf(Title, "%s X Midplane All Back Tracks",GetName());
 sprintf(Name, "hXAll_%s",GetName());
 hAllMidX  = new TH1F(Name, Title, 100, -25., 25.);

 sprintf(Title, "%s Y Midplane All Back Tracks",GetName());
 sprintf(Name, "hYAll_%s",GetName());
 hAllMidY  = new TH1F(Name, Title, 80, -20., 20.);

 sprintf(Title, "%s Dy Midplane matching Acpt",GetName());
 sprintf(Name, "hDyAcpt_%s",GetName());
 hMatchDyAcpt  = new TH1F(Name, Title, 100, -5., 5.);

 sprintf(Title, "%s Dx Midplane matching",GetName());
 sprintf(Name, "hDxAll_%s",GetName());
 hMatchDxAll  = new TH1F(Name, Title, 100, -5., 5.);

 sprintf(Title, "%s Dx Dy Midplane matching Acpt",GetName());
 sprintf(Name, "hDxDyAcpt_%s",GetName());
 hMatchDxDyAcpt  = new TH2F(Name, Title, 50, -5., 5., 50, -5., 5.);

 sprintf(Title, "%s Dx Dy Midplane matching All",GetName());
 sprintf(Name, "hDxDyAll_%s",GetName());
 hMatchDxDyAll  = new TH2F(Name, Title, 50, -5., 5., 50, -5., 5.);

 sprintf(Title, "%s Dx Midplane matching Acpt",GetName());
 sprintf(Name, "hDxAcpt_%s",GetName());
 hMatchDxAcpt  = new TH1F(Name, Title, 100, -5., 5.);

 sprintf(Title, "%s Dalx Midplane matching",GetName());
 sprintf(Name, "hDalxAll_%s",GetName());
 hMatchDalxAll  = new TH1F(Name, Title, 300, -.1, .1);

 sprintf(Title, "%s Daly Midplane matching",GetName());
 sprintf(Name, "hDalyAll_%s",GetName());
 hMatchDalyAll  = new TH1F(Name, Title, 300, -.1, .1);

 sprintf(Title, "%s Daly Dy Midplane matching All",GetName());
 sprintf(Name, "hDalyDyAll_%s",GetName());
 hMatchDalyDyAll  = new TH2F(Name, Title, 50, -.1, .1, 50, -5., 5.);
 
 sprintf(Title, "%s Daly Dy Midplane matching Acpt",GetName());
 sprintf(Name, "hDalyDyAcpt_%s",GetName());
 hMatchDalyDyAcpt  = new TH2F(Name, Title, 50, -.1, .1, 50, -5., 5.);
 
 sprintf(Title, "%s Dalx Midplane matching Accepted",GetName());
 sprintf(Name, "hDalxAcpt_%s",GetName());
 hMatchDalxAcpt  = new TH1F(Name, Title, 300, -.1, .1);

 sprintf(Title, "%s DslAngx Midplane matching Accepted [deg]",GetName());
 sprintf(Name, "hDslAngxAcpt_%s",GetName());
 hMatchDslAngxAcpt  = new TH1F(Name, Title, 300, -1, 1);

 sprintf(Title, "%s Daly Midplane matching Accepted",GetName());
 sprintf(Name, "hDalyAcpt_%s",GetName());
 hMatchDalyAcpt  = new TH1F(Name, Title, 300, -.1, .1);
 
 sprintf(Title, "%s Dang Midplane matching",GetName());
 sprintf(Name, "hDangAll_%s",GetName());
 hMatchDangAll  = new TH1F(Name, Title, 300, -.1, .1);

 sprintf(Title, "%s Dang Midplane matching Accepted",GetName());
 sprintf(Name, "hDangAcpt_%s",GetName());
 hMatchDangAcpt  = new TH1F(Name, Title, 300, -.1, .1);

 sprintf(Title, "%s Dang - Dx Midplane matching All",GetName());
 sprintf(Name, "hDangDxAall_%s",GetName());
 hMatchDangDxAll  = new TH2F(Name, Title, 50, -.05, .05,  50, -5, 5);

 sprintf(Title, "%s Dang - Dx Midplane matching Accepted",GetName());
 sprintf(Name, "hDangDxAcpt_%s",GetName());
 hMatchDangDxAcpt  = new TH2F(Name, Title, 50, -.05, .05,  50, -5, 5);

 sprintf(Title, "%s Dang - BackTrackangle",GetName());
 sprintf(Name, "hDangTrack_%s",GetName());
 hMatchDangTrack  = new TH2F(Name, Title, 50, -.05, .05,  50, -.5, .5);



 sprintf(Title, "%s Matching P (GeV/c) ",GetName());
 sprintf(Name, "hMatchP_%s",GetName());
 hMatchP  = new TH1F(Name, Title, 100, 
		     -fHistMomentumRange*BrUnits::GeV, 
		     fHistMomentumRange*BrUnits::GeV);

 sprintf(Title, "%s Matching P (GeV/c) Good Tracks",GetName());
 sprintf(Name, "hMatchPGood_%s",GetName());
 hMatchPGood  = new TH1F(Name, Title, 100, 
		     -fHistMomentumRange*BrUnits::GeV, 
		     fHistMomentumRange*BrUnits::GeV);
 
 sprintf(Title, "%s Matching P (GeV/c) ",GetName());
 sprintf(Name, "hPl_%s",GetName());
 hMatchPl = new TH1F(Name, Title, 100, 
		     -fHistMomentumRange*0.4*BrUnits::GeV, 
		     fHistMomentumRange*0.4*BrUnits::GeV );


 sprintf(Title, "%s Dang vs  P (MeV/c) ",GetName());
 sprintf(Name, "hDangVsP_%s",GetName());
 hMatchDangVsP  = new TH2F(Name, Title, 160, 
			   -fHistMomentumRange*BrUnits::GeV, 
			   fHistMomentumRange*BrUnits::GeV,
			   60, -0.03, 0.03);

 sprintf(Title, "%s Dy vs  P (MeV/c) ",GetName());
 sprintf(Name, "hDyVsP_%s",GetName());
 hMatchDyVsP  = new TH2F(Name, Title, 100,
			 -fHistMomentumRange*BrUnits::GeV, 
			 fHistMomentumRange*BrUnits::GeV,
			 20, -2, 2);

 sprintf(Title, "%s #matched front tracks per backtrack ",GetName());
 sprintf(Name, "hNoFrontMatch_%s",GetName());
 hNoFrontMatch  = new TH1F(Name, Title, 10, -0.5, 9.5);

 sprintf(Title, "%s Chisq for matching all tracks",GetName());
 sprintf(Name, "hMatchChisqAll_%s",GetName());
 hMatchChisqAll  = new TH1F(Name, Title, 100, 0., 20);

 sprintf(Title, "%s Chisq for matching best tracks",GetName());
 sprintf(Name,  "hMatchChisq_%s",GetName());
 hMatchChisq  = new TH1F(Name, Title, 100, 0., 20);

 

 if (fNtuple)
    fMatchInfo = new TNtuple("MatchInfo", "Module Match info",
			     "xf:xb:yf:yb:"
			     "axf:axb:ayf:ayb:"
			     "thf:thb");
 
 // Restore directory

  savdir->cd();
  

}

//___________________________________________________________________
 void BrModuleMatchTrack::SetDefaultParameters()
{
  // Set/Reset internal tracking parameters, cuts
  // to default values.
  //
  fFiducialCutdx   = 0.5;
  fFiducialCutdy   = 0.5;
  fMatchDangOffset = 0.0;
  fMatchDyOffset   = 0.0;
  fMatchDalyOffset = 0.0;

  fSigmaMatchedDang = 0.006;
  fSigmaMatchedDaly = 0.004;
  fSigmaMatchedDy   = 0.5;
  fSigmaRange       = 4.0;
  fSigmaCut         = 3.0;

  SetHistMomentumRange();    // default is 20.0 GeV/c
  SetNtuple();               // default is false.

  fNoEvents        = 0;
  fMatchedTrackSum = 0;

  fNewFiducialCuts = kTRUE;

  SetRotationFactors();
}

//___________________________________________________________________
 void BrModuleMatchTrack::CreateClonesArrays()
{
  //Create the clones arrays used for internal structures.
  if(!fTracksFrontBack)
    fTracksFrontBack = new TClonesArray("BrMatchedTrack",200);
}

//___________________________________________________________________
 void BrModuleMatchTrack::Clear(){
  // Clear event structures.
  ClearClonesArrays();
}

//___________________________________________________________________
 void BrModuleMatchTrack::ClearClonesArrays()
{
  //
  // Clear the clones arrays used for internal structures.
  //
  if((fTracksFrontBack->GetLast()) >= 0) {
    fTracksFrontBack->Clear();
    if(DebugLevel() > 2)
      cout << "BrModuleMatchTrack::ClearClonesArray() " 
	   << fTracksFrontBack->GetLast()+1 << endl;
  }
}

//___________________________________________________________________
 BrModuleMatchTrack::~BrModuleMatchTrack()
{
  //Destructor
  //
 
  if(fTracksFrontBack) 
    delete fTracksFrontBack;
   
}

//___________________________________________________________________
 void BrModuleMatchTrack::Event(BrEventNode* InputNode, BrEventNode* OutputNode)
{
  // Normal Event Method for BrModule. The local detectortracks for the front and back
  // chamber must be found in the InputNode. If matching is succesfull a table of 
  // BrMatchedTrack are added are added to Outputnode as well as a table for
  
  // First check whether volumenames are setup correctly 
  // (for that matter, set up at all!!)
  //

  if(!fFrontVolume || !fBackVolume || !fMagnetVolume){
    Error("Event","Module not properly setup");
    return;
  }

  fNoEvents++;

  CombineFrontBack(InputNode);

  //
  // Add selected tracks to the OutputNode
  // In fact since there are several uses for this it will make more sense to let the
  // calling application 'ask' for the result and decide what to actually 'store' 
  // persistently
  // in the output node. E.g for t3,t4,t5 tracking we will like not keep all tracks.    
  //
}

//___________________________________________________________________
 void BrModuleMatchTrack::CombineFrontBack(BrEventNode *InputNode) 
{
  // Loop over tracks in TFront / TBack and see how well they match and 
  // create candidates for tracks
  // This algorithm is the effective edge.
  // For tracks matched they are added to the
  // Clones array for matched BrTracksFrontBack (i.e. front back)
  //

  BrDataTable *FrontDetectorTracks = 
    InputNode->GetDataTable(Form("DetectorTrack %s", fFrontVolume->GetName()));
  
  BrDataTable *BackDetectorTracks = 
    InputNode->GetDataTable(Form("DetectorTrack %s", fBackVolume->GetName()));

  if (!FrontDetectorTracks) { 
    if (DebugLevel() > 2)
      cout << " Could not find detector Tracks " 
	   << fFrontVolume->GetName() << ", can not combine..." << endl;
    return;
  }
  
  if (!BackDetectorTracks) { 
    if (DebugLevel() > 2)
      cout << " Could not find detector Tracks " 
	   << fBackVolume->GetName() << ", can not combine..." << endl;
    return;
  }

  //--------------------------

  Int_t NumFrontTr = FrontDetectorTracks->GetEntries();
  Int_t NumBackTr  = BackDetectorTracks->GetEntries();
  
  if (HistOn()) {
    hFrontTracks->Fill(NumFrontTr);
    hBackTracks->Fill(NumBackTr);
  }

  if (!NumBackTr || !NumFrontTr) 
    return;
  
  // -------------------------

  BrMatchedTrack* track12_p;
  BrVector3D xgtback, agtback;
  Float_t t;

  ClearClonesArrays();

  vector <BrVector3D> xLocalBack(NumBackTr);
  vector <BrVector3D> aLocalBack(NumBackTr);


  vector <BrVector3D> xOut(NumBackTr);
  vector <Int_t>      trackUsed(NumBackTr);

  BrCoordinateSystem backInMagnetSystem;
  backInMagnetSystem = 
    BrCoordinateSystem::SetRelativeSystem(*fMagnetVolume->GetCoordinateSystem(),
					  *fBackVolume->GetCoordinateSystem());
  BrCoordinateSystem frontInMagnetSystem;
  frontInMagnetSystem = 
    BrCoordinateSystem::SetRelativeSystem(
					  *fMagnetVolume->GetCoordinateSystem(),
					  *fFrontVolume->GetCoordinateSystem());
  //
  // This simple version will loop over the tracks found in Back and
  // convert the local to global coordinates, project the track to 
  // the center of the magnet.
  // It will project the tracks in T1 forward to the center plane of
  // the magnet.  It will do the calculation in the local coordinate
  // system of D2 which is most useful for this purpose.
  // It will make simple corrections due to path length differences.
  
  Double_t m0x = fMagnetVolume->GetSize()[0] / (Double_t)2.0;
  Double_t m0y = fMagnetVolume->GetSize()[1] / (Double_t)2.0;
  Double_t m0l = fMagnetVolume->GetSize()[2] / (Double_t)2.0;

  Double_t backEdge  = fMagnetVolume->GetEdgeBack();
  Double_t frontEdge = fMagnetVolume->GetEdgeFront();

  BrPlane3D magnetBackEdge   = fMagnetVolume->GetEffectiveEdgeExitPlane();
  BrPlane3D magnetFrontEdge  = fMagnetVolume->GetEffectiveEdgeEntrancePlane();

  if (DebugLevel() > 5)
    cout << " m0x: " << m0x << " m0y: " << m0y << " m0l: " << m0l << endl;

  //
  // Loop over tracks from tback
  //
  // Note: There is in fact no need to setup the local tables for
  // tback tracks. They are only scanned through once. The Front tracks though
  // are scanned as many times as there are back tracks. 
  // It might be that a prescan and making an itarator over back tracks
  // would be a nice simple way of doing this rather than going the Sonata
  // fortran way for this coding.
  //

  fTracksFrontBack->Clear();

  if (DebugLevel() > 1)
    cout << "Matching for #Back tracks = "<< NumBackTr << endl; 

  for (Int_t i = 0; i < NumBackTr; i++) {
    BrDetectorTrack *BackTrack_p = (BrDetectorTrack*)BackDetectorTracks->At(i);

    //
    // Convert into system for magnet. Setup a coordinate system that goes directly from
    // detector to magnet rather than via global system
    //

    xLocalBack[i] = backInMagnetSystem.TransformToMaster(BackTrack_p->GetPos());
  
    // ugly fix. rotate back tracks to avoid p dependence of dang
    if (fBackRot!=1) {
      BrVector3D tpcAngleBack;    
      
      // rotation angle
      Double_t angle = BackTrack_p->GetAlpha().Theta()*(1 - fBackRot);
      Double_t s = TMath::Sin(angle);
      Double_t c = TMath::Cos(angle);
      Double_t xx = BackTrack_p->GetAlpha()[0];
      Double_t zz = BackTrack_p->GetAlpha()[2];
      tpcAngleBack.SetX(c*xx + s*zz);
      tpcAngleBack.SetZ(c*zz - s*xx);
      tpcAngleBack.SetY(BackTrack_p->GetAlpha()[1]);
      aLocalBack[i] = backInMagnetSystem.RotateToMaster(tpcAngleBack);
    }
    else
      aLocalBack[i] = backInMagnetSystem.RotateToMaster(BackTrack_p->GetAlpha());
  

    if (DebugLevel() > 1)
      cout << i << " : " << BackTrack_p->GetPos()   << xLocalBack[i] << endl
	   << "    "     << BackTrack_p->GetAlpha() << aLocalBack[i] << endl;

    // Track to center of effective edge of magnet M0

    BrLine3D backTrack(xLocalBack[i], aLocalBack[i]);
    xOut[i] = magnetBackEdge.GetIntersectionWithLine(backTrack);
 
    if (DebugLevel() > 1)
      cout << " BackEdge position " << i << ": "
	   <<  xOut[i] << endl;

    trackUsed[i]=0;
  }
 
  // ----------- Loop over tracks from tFront
  //
 
  if (DebugLevel() > 1)
    cout << "Matching for #Front tracks = "<<NumFrontTr << endl;  
 
  BrVector3D xgtfront, agtfront;
  BrVector3D xLocalFront, aLocalFront;

  
  Int_t NumTrFrontBack = 0;
  for (Int_t it1 = 0; it1 < NumFrontTr; it1++) {
    BrDetectorTrack *FrontTrack_p = (BrDetectorTrack*) FrontDetectorTracks->At(it1);

    xLocalFront = frontInMagnetSystem.TransformToMaster(FrontTrack_p->GetPos());

    if (fFrontRot!=1) {
      BrVector3D tpcAngleFront;    
      
      // rotation angle
      Double_t angle = FrontTrack_p->GetAlpha().Theta()*(1 - fFrontRot);
      Double_t s = TMath::Sin(angle);
      Double_t c = TMath::Cos(angle);
      Double_t xx = FrontTrack_p->GetAlpha()[0];
      Double_t zz = FrontTrack_p->GetAlpha()[2];
      tpcAngleFront.SetX(c*xx + s*zz);
      tpcAngleFront.SetZ(c*zz - s*xx);
      tpcAngleFront.SetY(FrontTrack_p->GetAlpha()[1]);
      aLocalFront = frontInMagnetSystem.RotateToMaster(tpcAngleFront);
    }
    else 
      aLocalFront = frontInMagnetSystem.RotateToMaster(FrontTrack_p->GetAlpha());
      
    if (DebugLevel() > 1)
      cout << " : "  << FrontTrack_p->GetPos()   << xLocalFront << endl
	   <<"    "  << FrontTrack_p->GetAlpha() << aLocalFront << endl;
    
    BrLine3D frontTrack(xLocalFront, aLocalFront);
    BrVector3D xIn = magnetFrontEdge.GetIntersectionWithLine(frontTrack);

    if(DebugLevel() > 1)
      cout << " FrontEdge position " << ": "
	   <<  xIn << endl;

    Bool_t inMagnet = TMath::Abs(xIn[0]) < m0x && TMath::Abs(xIn[1]) < m0y;

    if (!inMagnet) 
      continue;

    // ----- Loop over Back tracks
    
    for (Int_t it2 = 0; it2 < NumBackTr; it2++) {
      BrDetectorTrack* BackTrack_p = 
	(BrDetectorTrack*) BackDetectorTracks->At(it2);

      if (DebugLevel() > 1)
	cout << " Back  projected to gap: " 
	     <<  xOut[it2][0] << ", " << xOut[it2][1] << endl;

      if (TMath::Abs(xOut[it2][0]) > m0x || TMath::Abs(xOut[it2][1]) > m0y)
	continue;

      // Calculate the approximate momentum (to be used for dx,dy cuts)
      
      Double_t cs1 = 0;
      Double_t cs2 = 0;

      // unit vectors in magnet x,z plane
      for (Int_t j = 0; j < 3; j += 2) {
	cs1 += aLocalFront[j] * aLocalFront[j];
	cs2 += aLocalBack[it2][j] * aLocalBack[it2][j];
      }
      cs1 = TMath::Sqrt(cs1);
      cs2 = TMath::Sqrt(cs2);

      Double_t sin1 = aLocalFront[0] / cs1;
      Double_t sin2 = aLocalBack[it2][0] / cs2;

      // xz momentum 
      Double_t p_xz = 9999;

      if (fMagnetVolume->GetBdl() != 0)
	p_xz = fMagnetVolume->GetBdl() / ((Double_t)3335.6*(sin1-sin2))
	  * BrUnits::GeV;

      // angles in and out relative to the magnet Z axis
      Double_t theta_enter = TMath::ASin(sin1);
      Double_t theta_exit  = TMath::ASin(sin2);
      Double_t alx  = theta_exit-theta_enter;
	
      // Obtain angles used for cuts; 
      // angle between z azis and line linking both tracks
      Double_t theta_link = TMath::ATan((xOut[it2][0]-xIn[0])/(backEdge-frontEdge));
      Double_t ang_enter = theta_enter - theta_link;
      Double_t ang_exit  = theta_link  - theta_exit;
      Double_t dang      = ang_enter - ang_exit;


      // project to actual midplane for these two points

      BrVector3D centerp = 0.5*(xIn+xOut[it2]);
      BrVector3D normal(xOut[it2][0]-xIn[0], 0, xOut[it2][2] - xIn[2]); 
      BrPlane3D  centerPlane(centerp, normal);
      BrLine3D   backTrack(xLocalBack[it2], aLocalBack[it2]);
      BrVector3D cBack   = centerPlane.GetIntersectionWithLine(backTrack);
      BrVector3D cFront  = centerPlane.GetIntersectionWithLine(frontTrack);
      
      Double_t dy  = cFront[1] -cBack[1];
      Double_t dx  = cFront[0] -cBack[0];
      Double_t aly = aLocalBack[it2][1] - aLocalFront[1];

      Double_t slAngx_deg = alx * 57.295779;
      
      if (HistOn()) {
	hMatchDangTrack->Fill(dang, theta_exit);
	hMatchDyAll->Fill(dy);
	hMatchDalxAll->Fill(alx);
	hMatchDalyAll->Fill(aly);
	hMatchDalyDyAll->Fill(aly,dy);
	hMatchDxAll->Fill(dx);
	hMatchDxDyAll->Fill(dx,dy);
	hMatchDangAll->Fill(dang);
	hMatchDangDxAll->Fill(dang,dx);
	hAllMidX->Fill(cBack[0]);
	hAllMidY->Fill(cBack[1]);
      }
	
      if (DebugLevel() > 1)
	cout << "Pos at center for Candidates: " 
	     << dy << ", " << aly << ", " << dang << endl;
	 
      // Match tracks in theta1-theta2 and then perform the
      // match in the other plane
      
      // Should it take the weighted value of front and back 
      // aLocalFront aLocalBack
      
      Double_t p = p_xz / TMath::Sqrt(1.0-aLocalFront[1]*aLocalBack[it2][1]);

      // Match tracks and calculate momentum
      if (!MatchesCuts(dang, dy, aly, p))
	continue;

      // ------------------------

      if(HistOn()) {
	hMatchDyAcpt->Fill(dy);
	hMatchDalxAcpt->Fill(alx);
	hMatchDslAngxAcpt->Fill(slAngx_deg);
	hMatchDalyAcpt->Fill(aly);
	hMatchDalyDyAcpt->Fill(aly,dy);
	hMatchDxAcpt->Fill(dx);
	hMatchDangAcpt->Fill(dang);
	hMatchDangDxAcpt->Fill(dang, dx);
	hMatchDxDyAcpt->Fill(dx,dy);
	hMatchMidX->Fill(cBack[0]);
	hMatchMidY->Fill(cBack[1]);
	hMatchDyVsP->Fill(p, dy);
	hMatchP->Fill(p);
	hMatchPl->Fill(p);
	hMatchDangVsP->Fill(p, dang);

	if(fNtuple){
	  const Float_t ntVar[] = {
	    cFront[0], cBack[0],
	      cFront[1], cBack[1],
	      aLocalFront[0], aLocalBack[it2][0],
	      aLocalFront[1], aLocalBack[it2][1],
	      theta_enter, theta_exit
	  };
	
	  fMatchInfo->Fill(ntVar);
	}

      }

      fMatchedTrackSum++;
      
      trackUsed[it2]++;

      Int_t status_t1t2 = 0;
      if(fNewFiducialCuts){
	if(!GetFiducialStatus(FrontTrack_p,BackTrack_p))
	  status_t1t2= BrMatchedTrack::kFiducialCut;
      }else{
	if ((TMath::Abs(xOut[it2][0]) > (m0x-fFiducialCutdx)) ||
	    (TMath::Abs(xOut[it2][1]) > (m0y-fFiducialCutdy)))
	  status_t1t2= BrMatchedTrack::kFiducialCut;
	if ((TMath::Abs(xIn[0]) > (m0x-fFiducialCutdx))||
	    (TMath::Abs(xIn[1]) > (m0y-fFiducialCutdy)))
	  status_t1t2= BrMatchedTrack::kFiducialCut;
      }
      

      //  We now have a good track matching This has to be added to the
      //  Output node. We still have to make a choice between 
      //  Clones arrays
      //  and the regular structure. Certainly for

      TClonesArray &track12 = *fTracksFrontBack;
      track12_p = new(track12[NumTrFrontBack++]) BrMatchedTrack();
      
      track12_p->SetP(p);
      track12_p->SetDang(dang);
      track12_p->SetDy(dy);
      track12_p->SetDaly(aly);
      track12_p->SetFrontTrack(FrontTrack_p);
      track12_p->SetBackTrack(BackTrack_p);
      track12_p->SetID((Int_t)track12_p);
      track12_p->SetStatus(status_t1t2);

      // Evaluate track lengths
      
      Double_t length = normal.Norm();
      Double_t u = (ang_enter+ang_exit)/2.;
      length = length/(1-u*u/6.)*p / p_xz;
      track12_p->SetExit(xOut[it2]);
      track12_p->SetEntrance(xIn);
      Double_t l1 = (xLocalFront - xIn).Norm();
      Double_t l2 = (xLocalBack[it2]  - xOut[it2]).Norm();
      track12_p->SetMatchedTrackLength(l1+l2+length);

      if (DebugLevel() > 1)
	cout << track12_p << endl;
    }
  }

  CleanUpTracks();

  if (HistOn()){
    for(Int_t it2 = 0; it2 < NumBackTr; it2++)
      hNoFrontMatch->Fill(trackUsed[it2]);
    Int_t numTracks = fTracksFrontBack->GetEntries();
    for(int i=0;i< numTracks;i++){
      BrMatchedTrack* matchedTrack = (BrMatchedTrack*) fTracksFrontBack->At(i);
      if(matchedTrack->GetStatus()== BrMatchedTrack::kOk){
	hMatchPGood->Fill(matchedTrack->GetP());
      }
    }  
  }
}

//___________________________________________________________________
 Bool_t BrModuleMatchTrack::GetFiducialStatus(BrDetectorTrack* front,BrDetectorTrack* back)
{
  // This method provides fiducial cuts base on BrMagnetVolume::GetSwimStatus
  BrLine3D frontLine = fFrontVolume->LocalToGlobal(front->GetTrackLine());
  BrLine3D magnetEnLine = fMagnetVolume->GlobalToLocal(frontLine);
  BrLine3D backLine = fBackVolume->LocalToGlobal(back->GetTrackLine());
  BrLine3D magnetExLine = fMagnetVolume->GlobalToLocal(backLine);

  return fMagnetVolume->GetSwimStatus(magnetEnLine,magnetExLine,
				      fFiducialCutdx,fFiducialCutdy);
}

//___________________________________________________________________
 void BrModuleMatchTrack::Finish(){
  // Finish
  // Summarize performance
  cout << "Module Match Track  " << GetName() << " Summary" << endl;
  cout << " No Events         : " << setw(8) << fNoEvents << endl;
  cout << " No Matched Tracks : " << setw(8) << fMatchedTrackSum << endl;
}


//__________________________________________________________________
 void BrModuleMatchTrack::CleanUpTracks()
{
  // This cleanup method calls the two methods:
  // CleanUpSharedBackTracks() and CleanUpSharedFrontTracks()
  //
  // CleanUpSharedBackTracks() finds mathced tracks that shares back
  // tracks, find the best by looking at overall chisq in matching
  // parameter, and set the status of the tracks (kOk for the best
  // one, ...) - this is the old CleanUpTracks() method.
  //
  // CleanUpSharedFrontTracks() does the same as CleanUpSharedBackTracks()
  // just for the front tracks. The only difference is that this method
  // checks that the status is kOk before it compares the front tracks.

  if (DebugLevel())
    cout << " CleanUpTracks" << endl;

  CleanUpSharedBackTracks();
  CleanUpSharedFrontTracks();

  if (HistOn()) {
    // count the number of tracks and good tracks (status = kOk).
    Int_t numTracks = fTracksFrontBack->GetEntries();
    Int_t nGoodTracks = 0;
    
    for (Int_t i=0; i<numTracks; i++){
      BrMatchedTrack* matchedTrack = (BrMatchedTrack*) fTracksFrontBack->At(i);
      if (matchedTrack->GetStatus()==BrMatchedTrack::kOk)
	nGoodTracks++;
    }
    hGoodMatchedTracks->Fill(nGoodTracks);
    hMatchedTracks->Fill(numTracks);
  }
}

//__________________________________________________________________
 void BrModuleMatchTrack::CleanUpSharedBackTracks()
{
  //
  // The cleanup process implemented here is reasonably simple
  // and incorporates the ideas used in the first analysis of
  // the 2000 MRS data. The initial matching applies rather
  // wide cuts in matching tracks. It can therefor well happen
  // that e.g. the same backtrack is matched up with more than one
  // front track. This happened in about 2-5% of the cases. The present
  // algorithm sorts those out, or rather set the status after having selected
  // the better one.
  //
  // The check for vertex cuts are not done here. It was deemed better to
  // do so in a specific filter module.
  // a) Identify tracks tracks that have multiple usage
  // b) Identify best tracks by looking at overall chisq in matching
  //    parameter.
  // c) at this time an overall estimat based on cut parameters and
  //    fidicual cuts are done.

  if (DebugLevel())
    cout << " CleanUpSharedBackTracks" << endl;
  
  Int_t numTracks = fTracksFrontBack->GetEntries();
  if (numTracks == 0)
    return;

  vector <Bool_t> trackNotUsed(numTracks);
  
  for (Int_t i = 0; i < numTracks; i++)
    trackNotUsed[i] = kTRUE;

  Int_t groupNo=0;
  // trackList will contain a set of matchtracks that share back tracks
  TObjArray trackList;
  
  // loop over matched track candidates
  //
  for (Int_t i = 0; i < numTracks; i++) {
    if (!trackNotUsed[i]) 
      continue;
    
    groupNo++;
    BrMatchedTrack* matchedTrack = (BrMatchedTrack*) fTracksFrontBack->At(i);
    BrDetectorTrack *backTrack   = matchedTrack->GetBackTrack();
    BrDetectorTrack *frontTrack  = matchedTrack->GetFrontTrack();
    trackList.Add(matchedTrack);
    
    // pick up matched tracks with same back track 
    for (Int_t k = i + 1; k < numTracks; k++) {
      if (!trackNotUsed[k]) 
	continue;
      
      BrMatchedTrack* nextTrack = (BrMatchedTrack*) fTracksFrontBack->At(k);
      BrDetectorTrack *nextBackTrack  = nextTrack->GetBackTrack();
	
      if ((nextBackTrack->GetID()) == (backTrack->GetID())) {
	trackNotUsed[k] = kFALSE;
	trackList.Add(nextTrack);
      }
    }

    if (DebugLevel()) {
      cout << " Ghost Track (Shared Back) Group. # " << groupNo << " with " 
	   << trackList.GetEntries()   << endl;
	
      BrMatchedTrack* object = 0;
      TIter next(&trackList);
      while ((object = (BrMatchedTrack*)next()))
	cout << object->GetBackTrack()->GetID() << endl
	     << object->GetFrontTrack()->GetID() << endl;
    }
      
    //
    // trackList now contains a set of matchtracks that share back tracks
    // It has a minimum length of 1.
    // Iterate over this group of tracks, calculate the chisq for matching and pick the 
    // best one.
      
    BrMatchedTrack* selectedTrack = 0;
    Double_t chisq = -1;
    TIter next(&trackList);
      
    while ((matchedTrack = (BrMatchedTrack*)next())) {
      Double_t d1 = (matchedTrack->GetDang() - fMatchDangOffset) / fSigmaMatchedDang;
      Double_t d2 = (matchedTrack->GetDaly() - fMatchDalyOffset) / fSigmaMatchedDaly;
      Double_t d3 = (matchedTrack->GetDy()   - fMatchDyOffset)   / fSigmaMatchedDy;
      Double_t newchisq = d1*d1 + d2*d2 + d3*d3;
	
      matchedTrack->SetMatchChisq(newchisq/3.);
      matchedTrack->SetTrackGroup(groupNo);
	
      if ((chisq < 0) || (newchisq < chisq)) {
	chisq = newchisq;
	selectedTrack = matchedTrack;
      }
	
      if(DebugLevel() > 1)
	cout << matchedTrack << " " << newchisq/3.0 << endl;
    }
      
    // Set status for selected and others
      
    next.Reset();
    while ((matchedTrack = (BrMatchedTrack*)next())) {
      if (matchedTrack == selectedTrack)
	matchedTrack->SetStatus(BrMatchedTrack::kOk);
      else
	matchedTrack->SetStatus(BrMatchedTrack::kGhostCandidate);
	
      Double_t d1 = (matchedTrack->GetDang() - fMatchDangOffset) / fSigmaMatchedDang;
      Double_t d2 = (matchedTrack->GetDaly() - fMatchDalyOffset) / fSigmaMatchedDaly;
      Double_t d3 = (matchedTrack->GetDy()   - fMatchDyOffset)   / fSigmaMatchedDy;
	
      if (d1 > fSigmaCut || d2 > fSigmaCut || d3 > fSigmaCut)
	matchedTrack->SetStatus(BrMatchedTrack::kSigmaCut);
	
      if (HistOn()) { 
	if(matchedTrack == selectedTrack)
	  hMatchChisq->Fill(matchedTrack->GetMatchChisq());
	  hMatchChisqAll->Fill(matchedTrack->GetMatchChisq());
      }
    }
      
    // Clear trackList since the objects should not be deleted.      
    trackList.Clear();
      
  } // trackNotUsed  
}

//__________________________________________________________________
 void BrModuleMatchTrack::CleanUpSharedFrontTracks()
{
  if (DebugLevel())
    cout << " CleanUpSharedFrontTracks" << endl;
  
  Int_t numTracks = fTracksFrontBack->GetEntries();
  if (numTracks == 0)
    return;

  vector <Bool_t> trackNotUsed(numTracks);
  
  for (Int_t i = 0; i < numTracks; i++)
    trackNotUsed[i] = kTRUE;

  Int_t groupNo=0;
  // trackList will contain a set of matchtracks that share front tracks
  TObjArray trackList;
  
  // loop over matched track candidates
  //
  for (Int_t i = 0; i < numTracks; i++) {
    if (!trackNotUsed[i]) 
      continue;    
    BrMatchedTrack* matchedTrack = (BrMatchedTrack*) fTracksFrontBack->At(i);
    if (matchedTrack->GetStatus()!=BrMatchedTrack::kOk)
      continue;
    
    groupNo++;
    BrDetectorTrack *backTrack   = matchedTrack->GetBackTrack();
    BrDetectorTrack *frontTrack  = matchedTrack->GetFrontTrack();
    trackList.Add(matchedTrack);
    
    // pick up matched tracks with same front track 
    for (Int_t k = i + 1; k < numTracks; k++) {
      if (!trackNotUsed[k]) 
	continue;
      
      BrMatchedTrack* nextTrack = (BrMatchedTrack*) fTracksFrontBack->At(k);
      BrDetectorTrack *nextFrontTrack  = nextTrack->GetFrontTrack();
	
      if ((nextFrontTrack->GetID()) == (frontTrack->GetID())) {
	trackNotUsed[k] = kFALSE;
	// check if the status is OK!!! 
	if (nextTrack->GetStatus()==BrMatchedTrack::kOk)
	  trackList.Add(nextTrack);
      }
    }
    
    if (DebugLevel()) {
      cout << " Ghost Track (Shared Front) Group. # " << groupNo << " with " 
	   << trackList.GetEntries()   << endl;
      
      BrMatchedTrack* object = 0;
      TIter next(&trackList);
      while ((object = (BrMatchedTrack*)next()))
	cout << object->GetBackTrack()->GetID() << endl
	     << object->GetFrontTrack()->GetID() << endl;
    }
      
    //
    // trackList now contains a set of matchtracks that share front track
    // It has a minimum length of 1.
    // Iterate over this group of tracks, calculate the chisq for matching and pick the 
    // best one.
      
    BrMatchedTrack* selectedTrack = 0;
    Double_t chisq = -1;
    TIter next(&trackList);
      
    while ((matchedTrack = (BrMatchedTrack*)next())) {
      Double_t d1 = (matchedTrack->GetDang() - fMatchDangOffset) / fSigmaMatchedDang;
      Double_t d2 = (matchedTrack->GetDaly() - fMatchDalyOffset) / fSigmaMatchedDaly;
      Double_t d3 = (matchedTrack->GetDy()   - fMatchDyOffset)   / fSigmaMatchedDy;
      Double_t newchisq = d1*d1 + d2*d2 + d3*d3;
	
      matchedTrack->SetMatchChisq(newchisq/3.);
      matchedTrack->SetTrackGroup(groupNo);
	
      if ((chisq < 0) || (newchisq < chisq)) {
	chisq = newchisq;
	selectedTrack = matchedTrack;
      }
	
      if(DebugLevel() > 1)
	cout << matchedTrack << " " << newchisq/3.0 << endl;
    }
      
    // Set status for selected and others
      
    next.Reset();
    while ((matchedTrack = (BrMatchedTrack*)next())) {
      if (matchedTrack == selectedTrack)
	matchedTrack->SetStatus(BrMatchedTrack::kOk);
      else 
	matchedTrack->SetStatus(BrMatchedTrack::kGhostCandidate);

      Double_t d1 = (matchedTrack->GetDang() - fMatchDangOffset) / fSigmaMatchedDang;
      Double_t d2 = (matchedTrack->GetDaly() - fMatchDalyOffset) / fSigmaMatchedDaly;
      Double_t d3 = (matchedTrack->GetDy()   - fMatchDyOffset)   / fSigmaMatchedDy;
	
      if (d1 > fSigmaCut || d2 > fSigmaCut || d3 > fSigmaCut)
	matchedTrack->SetStatus(BrMatchedTrack::kSigmaCut);
	
      if (HistOn()) { 
	if(matchedTrack == selectedTrack)
	  hMatchChisq->Fill(matchedTrack->GetMatchChisq());
	  hMatchChisqAll->Fill(matchedTrack->GetMatchChisq());
      }
    }
      
    // Clear trackList since the objects should not be deleted.      
    trackList.Clear();
      
  } // trackNotUsed
}


//____________________________________________________________________________
 void BrModuleMatchTrack::ListMatchingParameters() const
{
  //
  cout << " ---- Parameters for BrModuleMatchTrack " <<  GetName() << "n";
  cout << " SigmaDang   : " << setw(8) << fSigmaMatchedDang 
       << " ( " << setw(8)  << fMatchDangOffset << ")n";
  cout << " SigmaDy     : " << setw(8) << fSigmaMatchedDy   
       << " ( " << setw(8)  << fMatchDyOffset << ")n";
  cout << " SigmaDaly   : " << setw(8) << fSigmaMatchedDaly  
       << " ( " << setw(8)  << fMatchDalyOffset << ")n";
  cout << " SigmaRange    " << setw(8) << fSigmaRange <<"n";
  cout << " SigmaCut      " << setw(8) << fSigmaCut <<"n";
  cout << " FiducialDx : "  << setw(8) << fFiducialCutdx << "n";
  cout << " FiducialDy : "  << setw(8) << fFiducialCutdy << "n";
}

//___________________________________________________________________________
 Bool_t BrModuleMatchTrack::MatchesCuts(Double_t dang, Double_t dy, 
				       Double_t daly, Double_t p)
{
  // Function to check if a matching fit is found between 
  // calculated parameters for deviate in angle, y and slopes. 
  // The (estimated) momentum is also a parameter to allow for better 
  // criteri with time.
  // The cuts are detector, magnet and momentum dependent due to multiple 
  // scattering and detector resolution.
  // The offset evaluation is applied here, as the only place in the code.

  dang -= fMatchDangOffset;
  dy   -= fMatchDyOffset;
  daly -= fMatchDalyOffset;

  if(TMath::Abs(dang) < fSigmaMatchedDang*fSigmaRange &&
     TMath::Abs(dy)   < fSigmaMatchedDy*fSigmaRange  &&
     TMath::Abs(daly) < fSigmaMatchedDaly*fSigmaRange ) 
    return kTRUE;
  
  return kFALSE;
}

//_____________________________________________________________________________
 void BrModuleMatchTrack::Print(Option_t* option) const
{
  // Print info on module
  BrModule::Print(option);
  TString opt(option);
  opt.ToLower();
  
  if (opt.Contains("d")) {
    ListMatchingParameters();
    cout 
    << "  Original author: Flemming Videbaek" << endl
    << "  Revisted by:     $Author: ufstasze $" << endl
    << "  Revision date:   $Date: 2002/08/08 15:36:13 $$"   << endl
    << "  Revision number: $Revision: 1.16 $ " << endl
    << endl
    << "*************************************************" << endl;
    
  }
}

//____________________________________________________________________________
//
// $Log: BrModuleMatchTrack.cxx,v $
// Revision 1.16  2002/08/08 15:36:13  ufstasze
// Added fiducial cuts that are impose by using SetSwimStatus
//
// Revision 1.15  2002/04/10 17:25:11  ekman
// Fixed a bad mistake (introduced in the previos update) - in the rotation of the tracks.
//
// Revision 1.14  2002/04/10 11:17:25  ekman
// Added fBackRot and fFrontRot members (and corresponding setter method SetRotationFactors(f,b)).
// The local tracks are rotated by these factors. This is done to avoid momentum dependence of dang.
// The default is set to 1.0.
// Added CleanUpSharedBackTracks() and CleanUpSharedFrontTracks(). These methods make sure that
// only one matched track of all the matched tracks sharing the same front/back track has status kOk.
//
// Revision 1.13  2002/04/02 20:43:27  videbaek
// increase no bins to better see dang vs p deviations
//
// Revision 1.12  2002/01/25 17:04:23  videbaek
// Add Abort errors in Init if volumes not there
//
// Revision 1.11  2001/12/07 21:06:49  videbaek
// Added Finish method for printing statistics.
// Added Ntuple diagnostics - off by default. Use SetNtuple(kTRUE) to turn on
// Change alx difference to be proper angular difference in plane.
//
// Revision 1.10  2001/11/24 17:20:50  videbaek
// Added histogram for goo matched tracks
//
// Revision 1.9  2001/11/13 23:05:26  ouerdane
// bumped version number to 2.1.32
//
// Revision 1.8  2001/11/05 06:45:41  ouerdane
// cleaned up this module
//
// Revision 1.7  2001/10/19 15:50:33  ouerdane
// increased binning by factor 3 in match dAng histo
//
// Revision 1.6  2001/10/18 21:41:58  videbaek
// Add method to be able to set momentum range for matching plots
// This is set by default to by 20 geV for FS.
// MRSTracking modules ets range to something more appropriate (5)
//
// Revision 1.5  2001/08/29 00:59:09  videbaek
// Add more diagnostic histograms
//
// Revision 1.4  2001/08/22 18:31:03  ejkim
// *** empty log message ***
//
// Revision 1.3  2001/08/13 11:59:20  staszel
// Some diagnostic histograms added.
//
// Revision 1.2  2001/06/28 15:15:52  videbaek
// Fixed serious error in constructor.
// The pointer holding the clones array was not proper initialized to
// 0.
//
// Revision 1.1.1.1  2001/06/21 14:55:11  hagel
// Initial revision of brat2
//
// Revision 1.43  2001/06/07 20:36:42  videbaek
// remove non-used defined flags (OBSOLETE USE_RELATIVE)
//
// Revision 1.42  2001/06/05 20:13:39  videbaek
// Added print method. Changed ListParameters to const.
//
// Revision 1.41  2001/06/01 17:20:21  videbaek
// This is an update of BrModuleMatchTrack to fix the error for infinite loops in
// the Ghostbusting. By looking at code as well as trine's comments I decided
// to do a complete re-write of CleanUpTracks(), and works according to specs.
// In addition the BrMatchedTracks have added members to save important info
// on the CleanUp procedure (chisq, and trackgroup) in case one wants to go back
// and redo, ghostbusting etc.
//
// Revision 1.40  2001/05/22 16:54:38  videbaek
// added fct GetSourceVersion() Changed Name to Source
//
// Revision 1.39  2001/05/22 16:53:29  videbaek
// added fct GetSourceVersion()
//
// Revision 1.37  2001/05/09 01:37:19  videbaek
// Imporved tracking in the magnet matching. See e-mail for further
// comments. There are also comments in the code.
// Changed members in BrMatchedTrack. May affect reading of old files.
//
// Revision 1.36  2001/03/19 22:01:14  videbaek
// Added offsets in matching
//
// Revision 1.35  2001/03/01 16:06:20  bramreco
// add offsets to matchings
//
// Revision 1.34  2001/01/28 22:35:20  videbaek
// remove unused varaible
//
// Revision 1.33  2001/01/25 19:46:09  videbaek
//  remove unused fMagnetField
//
// Revision 1.32  2001/01/01 20:45:21  bramreco
// Add directories to TrackingModule and ModuleMatchTrack
//
// Revision 1.31  2000/12/22 18:37:23  bramreco
// Add a few more histograms.
// and
// USE proper effective edge rather than magnet lenght. Could have caused a small error
// in the momentum calculation.
//
// Revision 1.30  2000/12/21 14:58:54  videbaek
// added histograms and setting of track variables
//
// Revision 1.29  2000/12/18 21:54:04  ouerdane
// Made fHelix a pointer to BrHelix,
// Removed private members fEntranceX, Y, Z etc. Use now BrVector3D fEntrance,
// etc. Replaced removed members in Getters and Setters by fEntrance.GetX(), etc.
//
// Revision 1.28  2000/12/16 01:10:24  videbaek
// Add more diagnostic histograms.
// Some code clean in loacl track - no code change.
//
// Revision 1.27  2000/12/06 22:21:41  videbaek
// Several modification to the BrMRSTrackingModule, particluar logic for finding TOF panel
// position and slat. Tracks are only assigned a hit if inside 'area in x. The logic also takes care (in an not
// optimal way of the 20-21-21-21 slat configuration.
// The TrackToVertex now calculate tx,Ty and Tz in IP system rather than MIDS local.
// Tracklength from TPM1 to this vertex is added to track.
// The streamer method is included for the bRMRSTrack (since added members)
//
// Revision 1.26  2000/11/23 01:36:46  brahmlib
// Cleaned up code a bit.
//
// Revision 1.25  2000/11/22 21:20:41  videbaek
// Modification to handle Init() calls properly.
// Also changes for detector/Magnetvolumes.
//
// Revision 1.24  2000/10/31 19:38:39  ouerdane
// A few changes in the matching and global tracking classes:
// Matching:
// ---------
//   BrModuleMatchTrack now calculates the length from the track position
//   in the front tracking chamber to the track position to the back
//   tracking chamber. It calculates the helix branch inside the intermediate
//   magnetic field, the entrance and exit points at the magnetic gap front and
//   back planes (in global coordinates).
//   Note that it uses the local track positions given by
//                     BrDetectorTrack::GetPos()
//   The result is stored in a private member of BrMatchedTrack, namely
//   fMatchedTrackLength that a user can get thanks to
// 	            BrMtachedTrack::GetMatchedTrackLength()
//   (the corresponding setter method exists too).
//   the helix object is also stored as a private member of the matched track
//   and is accessible via BrMatchedTrack::GetHelix()
//
// Global tracking:
// ---------------
//   BrMRSTrackingModule and BrFFSTrackingModule now calculate:
//     FFS: track length from front plane of D1 to TOF1 plane
//     MRS: track length from TPM1 track position to TOFW panel
//          (gets the matched track length and add the piece from TPM2 to TOFW)
//   The methods are called:
//     FFS: EvalD1ToTOFWTrackLength()
//     MRS: EvalTPM1ToTOFWTrackLength()
//
//   Both of these modules calculate the number of the pointed slat on the
//   time of flight detector (TOFW or TOF1) as well as the coordinates
//   of the track projection on these TOF detectors.
//   The results are stored in private members of BrMRSTrack and BrFFTrack,
//   namely fPointedSlat, fProjOnTOF1 and fProjOnTOFW, fD1ToTOF1TrackLength
//   fTPM1ToTOFWTrackLength. These values are accessible with the getter methods
//   (setters exist too).
//
// ---------------
// The previous TrackLength methods have been removed (they were not appropriate
// because of their location and the assumption concerning the vertex at (0,0,0))
// Also removed the cxx files BrMRSTrack.cxx and BrFFSTrack.cxx (useless).
//
// All the points (entrance and exit points in a magnet detector) are accessible.
// The coordinates are calculated in the global c.s.
//
// Revision 1.23  2000/09/28 16:04:56  videbaek
// add safeguard for maxtracks, changed hist limits
//
// Revision 1.22  2000/09/12 20:51:30  brahmlib
// Fix typo's
//
// Revision 1.21  2000/09/12 17:35:16  videbaek
// Added histograms for mid-plane tracking
//
// Revision 1.20  2000/09/12 16:03:12  videbaek
// Add more diagnostic histograms to matching code.
//
// Revision 1.19  2000/09/08 18:34:44  videbaek
// Change layout of histograms. Mainly concerned with multiple p-ranges
// one for low p (i.e. MRS) and high P (FS).
//
// Revision 1.18  2000/09/07 20:45:17  videbaek
// Move cvs log. Change histogram limits.
//
// Revision 1.17  2000/09/04 14:55:29  videbaek
// Fix stupid typo introduced last commit.
//
// Revision 1.16  2000/09/02 19:29:32  videbaek
// Move cvs comments and chenge histo limits
//
// Revision 1.15  2000/07/17 19:51:12  videbaek
// Change to GeV as unit for momentum and energy.
//
// Revision 1.14  2000/06/21 21:23:10  trine
// Modified CombineFrontback() - if no magnetic field, just set P to some
// large value (hardcoded 99999 for the moment.)
//
// Revision 1.13  2000/06/17 22:02:33  nbi
// Removed BrUnits::GeV in the evaluation of p_xz since it's already in GeV
// (got a factor 1000 too high with BrUnits)
//
// Revision 1.12  2000/05/05 21:19:51  videbaek
// Use units in matchP histogram
//
// Revision 1.11  2000/04/28 21:18:59  videbaek
// Updates to BrLocalTrack. Added fit method; Status is changed. Uses
// MarkAsBad, IsBad instead of fixed 999.
// Cleanup of BrModuleMatchtrack. Added histohgrams.
// Changed LocalTrack and LocalTracking to use IsBad etc.
//
// Revision 1.9  1999/04/22 17:20:40  videbaek
// Add include guards.
//
// Revision 1.8  1999/04/09 16:25:46  hagel
// Set fHistOn = kTRUE in DefineHistograms so that arrays get incremented
//
// Revision 1.7  1999/03/07 22:38:04  videbaek
// Added DetectorHit and BrLocalTrackingModule as a more general way to
// deal with local tracks and hits. Initial insertion. Not fully debugged.
// Cosmetic changes to other modules.
//
// Revision 1.6  1999/02/26 23:01:25  hagel
// Minor changes to fix mysterious problems that arose in last checking
//
// Revision 1.5  1999/02/26 21:14:41  hagel
// Minor changes to make compatible with BrFSTrackingModule
//
// Revision 1.4  1999/02/25 17:55:58  videbaek
// Fix typos - extra parentasis
//
// Revision 1.3  1999/02/25 14:55:34  videbaek
// Changed a few debug staement, and layout.
//
// Revision 1.2  1999/01/15 16:37:28  videbaek
// Working version of MRS tracking of mtp1,mtp2 and new general track
// classes. Changes also added to BrModuleMatchTrack for this reason.
// Updated makeNt for non-cygnus win95 systems
//
// Revision 1.1  1998/12/21 20:26:15  videbaek
// Part of the MRS and general tracking modules
//
//  


// Changes:
//  April 24. Important Change
//            Modified code to return momentum in MeV/c as is the
//            standard (but should we keep this??)
//
//
// July 17,2000 /fv
// reintroduce BrUnits::GeV to ensure is done is units of
// agreed upon basic units.
// April 2001 /fv
// Replace fixed length arrays with STL vector classes for float, BrVector3D
// This was really trivial. - more to come.
//

This page automatically generated by script docBrat by Christian Holm

Copyright ; 2002 BRAHMS Collaboration <brahmlib@rcf.rhic.bnl.gov>
Last Update on by

Validate HTML
Validate CSS