ROOT logo
/*

  //
  // Macro to compare  tracks used 2 different reconstruction algorithms (Offline and HLT)
  // (In general the approach  can be used for any pair of the esds - track containers)
  //   
  // Main functions - Dump  content of HLT and OFFLINE esd files  - full esd tracks 
  //  1. Dump to the tree the pair of close tracks ( n sigma distance at the TPC entrance)
  //  2. Dump to the tree the track and corrsponding counter of tracks from other container 
  //    Compare two events - track by track comparison
  //       0. Filter "Good" tpc tracks - see function IsSelected(track)
  //       1. Dump OFFline -> HLT tracks into trees  
  //           a.) tree "offhlt"  - counters+ Ofline track + corresponding  Hlt track
  //           b.) tree "offhlt0" - offline track + hlt track counter 
  //       2. HLT and offline
  //     
  //  3. To save the CPU and disk space the input tracks to compare are pt downscaled
  //      see function IsDownscaled();
  //
  //  Visualization part is currently work in progress
  //  
  // Responsible:
  // dumping part:         marian.ivanov@cern.ch
  // visualization part:   
  // 
  Example usage:
  aliroot -b -q $ALICE_ROOT/TPC/macros/compareTracks.C+
  //
  //
  .x $HOME/rootlogon.C
  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libPWG0base");
  gSystem->Load("libPWG0dep");
  gSystem->Load("libPWG0selectors");
  .L $ALICE_ROOT/PWGPP/TPC/macros/compareTracks.C+
  //
  compareTracks("compare.list");
  //
  TFile f("dump.root");
*/
#include <exception>
#include <fstream>
#include "TFile.h"
#include "TTree.h"
#include "TChain.h"
#include "TCut.h"
#include "TStopwatch.h"
#include "TSystem.h"
#include "AliESDEvent.h"
#include "TTreeStream.h"
#include "TRandom.h"
#include "AliXRDPROOFtoolkit.h"
#include "AliSysInfo.h"

//
//
//
void CompareFile(TTreeSRedirector *pcstream,  TFile *fOff, TFile *fHLT);
void CompareEvents(AliESDEvent *evoff, AliESDEvent *evhlt, TTreeSRedirector *pcstream);
Bool_t AreTracksCloseFast(AliESDtrack *track1, AliESDtrack *track2, AliESDEvent * event, AliExternalTrackParam &inner2);
Bool_t IsSelected(AliESDtrack *track);
Bool_t IsDownscaled(AliESDtrack *track);
//
Double_t gptdownscale=100;  //pt downscale parameter
//
TTree * chainOFFHLT=0;
TTree * chainOFFHLT0=0;
TTree * chainHLTOFF=0;
TTree * chainHLTOFF0=0;

void compareTracks(const char * flistOFF="compareOFF.list", const char * flistHLT="compareHLT.list", Double_t downscale=10000){
    //
    // Compare HLT and OFFLINE esd files 
    // Input: 
    //   flist - the ascii files with the filename - ESD form the offline
    //         - hlt path constructed  from the offline ESD file repalcing the OFFLINE with HLT
    //
    gptdownscale=downscale;
    TTreeSRedirector *pcstream = new TTreeSRedirector("dump.root");
    ifstream inOFF;
    inOFF.open(flistOFF);
    ifstream inHLT;
    inHLT.open(flistHLT);


    // Read the input list of files and add them to the chain
    TString currentFileOff;
    TString currentFileHlt;
    {  while( (inOFF.good()) && (inHLT.good())) {
		        inOFF >> currentFileOff;
			inHLT >> currentFileHlt;
	                //currentFileHlt=currentFileOff;
	                //currentFileHlt.ReplaceAll("/OFFLINE/","/HLT/");
	                printf("%s\n%s\n\n",currentFileOff.Data(), currentFileHlt.Data());
	                TFile *fOff = TFile::Open(currentFileOff.Data(),"READ");
		        TFile *fHlt = TFile::Open(currentFileHlt.Data(),"READ");
	                if ( fOff && fHlt){
		           CompareFile(pcstream, fOff, fHlt);
		        }
		      delete fOff;
		      delete fHlt;
    }}
    delete pcstream;
		        /* 
			 *      TTreeSRedirector *pcstream = new TTreeSRedirector("dump.root");
			 *           TFile *fOff = TFile::Open("/lustre/alice/mknichel/cpass1/2011-12-13_0154/OFFLINE/167693/11000167693001.11/AliESDs.root","READ");
			 *                TFile *fHLT = TFile::Open("/lustre/alice/mknichel/cpass1/2011-12-13_0154/HLT/167693/11000167693001.11/AliESDs.root","READ");
			 *                     CompareFile(pcstream, fOff, fHLT);
			 *                          delete pcstream;
			 *                            */
}

void CompareFile(TTreeSRedirector *pcstream,  TFile *fOff, TFile *fHLT){
  //
  // Compare 2 esd files - fOff and fHLT
  // Pairs of tracks dumpt in the trees - stored in the filee connected to the pcstream
  // 
  TTree *tOff = (TTree*)fOff->Get("esdTree");
  TTree *tHLT = (TTree*)fHLT->Get("esdTree");
  //    
  Int_t nevents=tOff->GetEntries();
  //
  AliESDEvent *evoff = new AliESDEvent();
  AliESDEvent *evhlt = new AliESDEvent();  
  evoff->ReadFromTree(tOff);
  evhlt->ReadFromTree(tHLT);
  //
  for(Long64_t iev = 0; iev < nevents; iev++){
    tOff->GetEvent(iev);
    tHLT->GetEvent(iev);
    CompareEvents(evoff,evhlt,pcstream);    
    AliSysInfo::AddStamp(fOff->GetName(),iev);
  }
  delete evoff;
  delete evhlt;
}



void CompareEvents(AliESDEvent *evoff, AliESDEvent *evhlt, TTreeSRedirector *pcstream){
  //
  // Main function to dump events:
  //
  // compare two events - track by track comparison
  // 0. Filter "Good" tpc tracks - see function IsSelected(track)
  // 1. Dump OFFline -> HLT tracks into trees  
  //    a.) tree "offhlt" - counters+ Ofline track + corresponding  Hlt track
  //    b.) tree "offhlt" - counters +Offline track
  // 2. HLT and offline
  //
  // 3. To save the CPU and disk space the input tracks to compare are pt downscaled
  //    see function Isdownscaled();

  Int_t nOffTracks = evoff->GetNumberOfTracks();
  Int_t nHLTTracks = evhlt->GetNumberOfTracks();
  Int_t iev= evoff->GetEventNumberInFile();
  if (nOffTracks==0) return;
  AliESDtrack *offlinetrack=0, *hlttrack=0;
  Double_t predchi2 = 0;  
  //for(Long64_t iev = 120; iev < 125; iev++)
  TObjArray arrayOFF(20000);
  TObjArray arrayHLT(20000);
  AliExternalTrackParam  inner2; //working track ref
  //
  //
  //
  Int_t nselOFF = 0;
  Int_t nselHLT = 0;
  // filter offline
  for(Int_t ioff = 0; ioff < nOffTracks; ioff++){
    offlinetrack = evoff->GetTrack(ioff);
    if (!IsSelected(offlinetrack)) continue;
    arrayOFF.AddAt(offlinetrack,nselOFF);	
    nselOFF++;
  }
  //filter hlt
  for(Int_t ihlt = 0; ihlt< nHLTTracks; ihlt++){
    hlttrack = evhlt->GetTrack(ihlt);
    if (!IsSelected(hlttrack)) continue;
    arrayHLT.AddAt(hlttrack,nselHLT);	
    nselHLT++;
  }
  printf("%d\t%d\t%d\t%d\n", nOffTracks, nselOFF,  nHLTTracks, nselHLT);
  //
  // - compare offline - hlt
  TStopwatch timer;
  //
  for (Int_t ioff = 0; ioff < nselOFF; ioff++){
    offlinetrack = (AliESDtrack*)arrayOFF.At(ioff);
    Float_t ncl21off= offlinetrack->GetTPCClusterInfo(2,1);
    Float_t ncl20off= offlinetrack->GetTPCClusterInfo(2,0);
    if (IsDownscaled(offlinetrack)) continue;
    Int_t counter=0;
    //
    for(Int_t ihlt = 0; ihlt < nselHLT; ihlt++){
      hlttrack = (AliESDtrack*)arrayHLT.At(ihlt);
      Bool_t close = AreTracksCloseFast(offlinetrack,hlttrack,evhlt,inner2);	   
      if (close){
	Float_t ncl21hlt= hlttrack->GetTPCClusterInfo(2,1);
	Float_t ncl20hlt= hlttrack->GetTPCClusterInfo(2,0);
	counter++;
	predchi2=offlinetrack->GetInnerParam()->GetPredictedChi2(&inner2);
	(*pcstream)<<"offhlt"<<
	  //multiplicity
	  "nHLT="<<nselHLT<<
	  "nOFF="<<nselOFF<<
	  "ncl20off="<<ncl20off<<
	  "ncl21off="<<ncl21off<<	
	  "ncl20hlt="<<ncl20hlt<<
	  "ncl21hlt="<<ncl21hlt<<	       
	  "counter="<<counter<<
	  //
	  "chi2="<<predchi2<<
	  "track1.="<<offlinetrack<<
	  "track2.="<<hlttrack<<
	  "inner2.="<<&inner2<<
	  "\n";
      }
    }
    Bool_t isDownscaled=IsDownscaled(offlinetrack);	
    (*pcstream)<<"offhlt0"<<
      "iev="<<iev<<	       
      "nHLT="<<nselHLT<<
      "nOFF="<<nselOFF<<
      //
      "ncl20="<<ncl20off<<
      "ncl21="<<ncl21off<<
      "track.="<<offlinetrack<<
      "counter="<<counter<<
      "isDownscaled="<<isDownscaled<<
      "\n";
  }
  timer.Print();
  //
  for(Int_t ihlt = 0; ihlt < nselHLT; ihlt++){
    Int_t counter=0;      
    hlttrack = (AliESDtrack*)arrayHLT.At(ihlt);	
    Float_t ncl21hlt= hlttrack->GetTPCClusterInfo(2,1);
    Float_t ncl20hlt= hlttrack->GetTPCClusterInfo(2,0);
    if (IsDownscaled(hlttrack)) continue;      
    for (Int_t ioff = 0; ioff < nselOFF; ioff++){
      offlinetrack = (AliESDtrack*)arrayOFF.At(ioff);	
      Bool_t close = AreTracksCloseFast(hlttrack,offlinetrack,evhlt,inner2);	   
      if (close){
	Float_t ncl21off= offlinetrack->GetTPCClusterInfo(2,1);
	Float_t ncl20off= offlinetrack->GetTPCClusterInfo(2,0);
	predchi2=hlttrack->GetInnerParam()->GetPredictedChi2(&inner2);
	counter++;
	(*pcstream)<<"hltoff"<<
	  //multiplicity
	  "nHLT="<<nselHLT<<
	  "nOFF="<<nselOFF<<
	  "ncl20off="<<ncl20off<<
	  "ncl21off="<<ncl21off<<
	  "ncl20hlt="<<ncl20hlt<<
	  "ncl21hlt="<<ncl21hlt<<	       
	  "counter="<<counter<<
	  //
	  "chi2="<<predchi2<<
	  "track2.="<<offlinetrack<<
	  "track1.="<<hlttrack<<
	  "inner2.="<<&inner2<<
	  "\n";
      }
    }
    Bool_t isDownscaled=IsDownscaled(hlttrack);	
    (*pcstream)<<"hltoff0"<<
      "iev="<<iev<<	       
      "nHLT="<<nselHLT<<
      "nOFF="<<nselOFF<<
      //
      "ncl20="<<ncl20hlt<<
      "ncl21="<<ncl21hlt<<
      "track.="<<hlttrack<<
      "counter="<<counter<<
      "isDownscaled="<<isDownscaled<<
      "\n";
  } 
  timer.Print();
}

Bool_t IsSelected(AliESDtrack *track){
  //
  // modified by:
  // philipp.luettig@cern.ch
  // 
  //
  if (track->IsOn(0x40)==0) return kFALSE;                // Refit
  if (TMath::Abs(track->GetTgl())>1.1)  return kFALSE;    // tangent lambda
  if (track->GetTPCClusterInfo(2,1)<50) return kFALSE;    // cluster information number of crossed rows >50
  return kTRUE;
}

Bool_t IsDownscaled(AliESDtrack *track){
  //
  // Downscale randomly low pt tracks
  //
  //return kFALSE;
  Double_t scalempt= TMath::Min(1./TMath::Abs(track->GetParameter()[4]),10.);
  if (TMath::Exp(2*scalempt)<gptdownscale*gRandom->Rndm()) return kTRUE;
  return kFALSE;
}


Bool_t AreTracksCloseFast(AliESDtrack *track1, AliESDtrack *track2, AliESDEvent * event, AliExternalTrackParam &inner2){
  //
  // 
  // Fast comparison uning track param close to the prim vertex and at the inner wall of the TPC
  //
  // 1. Fast cut on the invariant (under rotation) variable P3 and P4 (means pz/pt and 1/pt)
  // 2. Slower cuts - parameters at the entrance of the TPC (tracks to be propagated)
  //
  // In case the tracks are relativelaly close -the inner2 parameters are created
  //                                           -track 2 propagated and rotated to the same position as the track1 
  // 
  const Double_t absCut[5] ={5,10, 0.02,0.02,1};   // abs cut values  
  const Double_t pullCut[5]={6,100,6,   100,6};    // pull cut values
  //   *              "External" track parametrisation class                       *
  //   *                                                                           *
  //   *      external param0:   local Y-coordinate of a track (cm)                *
  //   *      external param1:   local Z-coordinate of a track (cm)                *
  //   *      external param2:   local sine of the track momentum azimuthal angle  *
  //   *      external param3:   tangent of the track momentum dip angle           *
  //   *      external param4:   1/pt (1/(GeV/c))                                  *

  //
  // 
  const Double_t kTglCut=0.1;    
  const Double_t k1PtCut=0.5;
  //  const Double_t kAlphaCut=0.2;
  const Double_t kTglCutSigma=10;
  const Double_t k1PtCutSigma=10;
  //
  //
  if(!track1) return kFALSE;
  if(!track2) return kFALSE;  
  const Double_t *param1 = track1->GetParameter();
  const Double_t *param2 = track2->GetParameter();
  const Double_t *param1I = track1->GetInnerParam()->GetParameter();
  const Double_t *param2I = track2->GetInnerParam()->GetParameter();
  const Double_t *covar1 = track1->GetCovariance();
  const Double_t *covar2 = track2->GetCovariance();
  const Double_t *covar1I = track1->GetInnerParam()->GetCovariance();
  const Double_t *covar2I = track2->GetInnerParam()->GetCovariance();
  //
  if (TMath::Abs(param1[3]-param2[3])>kTglCut) return kFALSE;	
  //if (TMath::Abs(param1[4]-param2[4])>k1PtCut) return kFALSE;	
  if (TMath::Abs(param1I[3]-param2I[3])>kTglCut) return kFALSE;	
  if (TMath::Abs(param1I[4]-param2I[4])>k1PtCut) return kFALSE;	
  Double_t dalpha = TMath::Abs(track1->GetAlpha()-track2->GetAlpha());
  if (dalpha>TMath::Pi()) dalpha-=TMath::Abs(dalpha-TMath::TwoPi());
  //if (dalpha > kAlphaCut) return kFALSE;

  //
  Int_t index22=track1->GetIndex(2,2);	       
  Int_t index33=track1->GetIndex(3,3);	       
  Int_t index44=track1->GetIndex(4,4);	       
  if (TMath::Abs(param1[3]-param2[3])/TMath::Sqrt(TMath::Max(covar1[index33],covar2[index33]))>kTglCutSigma) return kFALSE;
  //if (TMath::Abs(param1[4]-param2[4])/TMath::Sqrt(TMath::Max(covar1[index44],covar2[index44]))>k1PtCutSigma) return kFALSE;  
  if (TMath::Abs(param1I[3]-param2I[3])/TMath::Sqrt(TMath::Max(covar1I[index33],covar2I[index33]))>kTglCutSigma) return kFALSE;
  if (TMath::Abs(param1I[4]-param2I[4])/TMath::Sqrt(TMath::Max(covar1I[index44],covar2I[index44]))>k1PtCutSigma) return kFALSE;  
  if (TMath::Abs(dalpha)/TMath::Sqrt(TMath::Max(covar1[index22],covar2[index22]))>k1PtCutSigma) return kFALSE;  
  //
  // 2. Slow cuts on the paramters at the entrance of the TPC
  //
  inner2=*(track2->GetInnerParam());
  inner2.Rotate(track1->GetInnerParam()->GetAlpha());
  inner2.PropagateTo(track1->GetInnerParam()->GetX(),  event->GetMagneticField());
  const Double_t *pinner2  = inner2.GetParameter();
  const Double_t *pcovar2  = inner2.GetCovariance();
  //
  Bool_t isOK = kTRUE;
  for (Int_t ipar=0; ipar<5; ipar++){
    // 
    Int_t index=track1->GetIndex(ipar,ipar);	      
    if (TMath::Abs(pinner2[ipar]-param1I[ipar])>absCut[ipar]) isOK=kFALSE;
    if (TMath::Abs(pinner2[ipar]-param1I[ipar])>pullCut[ipar]*TMath::Sqrt(TMath::Max(covar1I[index],pcovar2[index]))) isOK=kFALSE;
  }
  if (!isOK) return kFALSE; 
  return kTRUE;
}


void MakeChain(){
  //
  //
  AliXRDPROOFtoolkit toolkit;
  chainOFFHLT= toolkit.MakeChainRandom("dumpHLTOFFLINE.list","offhlt",0,100);
  chainOFFHLT0=toolkit.MakeChainRandom("dumpHLTOFFLINE.list","offhlt0",0,100);
  chainHLTOFF=toolkit.MakeChainRandom("dumpHLTOFFLINE.list","hltoff",0,100);
  chainHLTOFF0=toolkit.MakeChainRandom("dumpHLTOFFLINE.list","hltoff0",0,100);

 
}

void DrawDiffPt(){
  //
  // Draw difference between the HLT and offline tracks
  //
  TCut cut="sqrt(chi2)<10&&ncl21off>120";
  TCut cutNoiseEvent = "abs(nHLT/nOFF-1)<0.2";   //mainly laser events
  //
  // 1. check the edge effect 1/pt resolution TPC only pull
  // ...
  chainOFFHLT->Draw("(track1.fIp.fP[4]-track2.fIp.fP[4])/sqrt(max(track1.fIp.fC[14],track2.fIp.fC[14])):sign(inner2.fP[4])*inner2.fP[0]/inner2.fX>>hisTPCEdge(50,-0.18,0.18,100,-6,6)",cut+"abs(track1.fP[4])<0.25","colz",200000);
  /*
    hisTPCEdge->FitSlicesY();
    hisTPCEdge_2->GetXaxis()->SetTitle("q*ly/lx");
    hisTPCEdge_2->GetYaxis()->SetTitle("#Delta_{1/pt}/#sigma_{1/pt}");
    hisTPCEdge_2->Draw();
  */
  // 2. check the edge effect 1/pt resolution combined 
  chainOFFHLT->Draw("(track1.fP[4]-track2.fP[4])/sqrt(max(track1.fC[14],track2.fC[14])):sign(inner2.fP[4])*inner2.fP[0]/inner2.fX>>hisCombEdge(50,-0.18,0.18,100,-6,6)",cut+"abs(track1.fP[4])<0.25","colz",200000);
  /*
    hisCombEdge->FitSlicesY();
    hisCombEdge_2->Draw();
  */
  // 3. Combined momentum resolution as function of the inverse moment
  chainOFFHLT->Draw("(track1.fIp.fP[4]-track2.fIp.fP[4])/sqrt(max(track1.fIp.fC[14],track2.fIp.fC[14])):abs(track1.fP[4])>>hisTPCP4(20,-0.0,1,100,-6,6)",cut+"abs(track1.fP[4])<1","colz",200000);
  /*
    hisTPCP4->FitSlicesY();  
    hisTPCP4_2->GetXaxis()->SetTitle("1/p_{t} (1/GeV))");
    hisTPCP4_2->GetYaxis()->SetTitle("#Delta_{1/pt}/#sigma_{1/pt}");
    hisTPCP4_2->Draw();
  */
  // 4. Combined momentum resolution as function of the inverse moment
  chainOFFHLT->Draw("(track1.fP[4]-track2.fP[4])/sqrt(max(track1.fC[14],track2.fC[14])):abs(track1.fP[4])>>hisCombP4(20,-0.0,1,100,-6,6)",cut+"abs(track1.fP[4])<1","colz",200000);
  /*
    hisCombP4->FitSlicesY();
    hisCombP4_2->Draw();
  */

}
//
void DrawDiffEff(){
  //
  //
  //
  TCut cutEff = "abs(track.fIp.fP[4])<5&&abs(track.fIp.fP[1])<90";
  TCut cutNoiseEvent = "abs(nHLT/nOFF-1)<0.2"; // HLT cluster finder more sensitive to the noise
  //
  // 
  //
  chainOFFHLT0->Draw("counter==0:(nOFF+nHLT)/2.>>effOccuOFFHLT(20,0,8000)",cutNoiseEvent+cutEff+"abs(track.fP[4])<1&&ncl21>120","prof",50000);
  chainHLTOFF0->Draw("counter==0:(nOFF+nHLT)/2.>>effOccuHLTOFF(20,0,8000)",cutNoiseEvent+cutEff+"abs(track.fP[4])<1&&ncl21>120","prof",50000);

 chainOFFHLT0->Draw("counter==0:track.fTPCncls>>effNCLOFFHLT(40,0,160)",cutNoiseEvent+cutEff+"abs(track.fP[4])<1","prof",50000);
 chainHLTOFF0->Draw("counter==0:track.fTPCncls>>effNCLHLTOFF(40,0,160)",cutNoiseEvent+cutEff+"abs(track.fP[4])<1","prof",50000);
 /*
   effNCLOFFHLT->SetMarkerStyle(25);
   effNCLHLTOFF->SetMarkerStyle(25);
   effNCLOFFHLT->SetMarkerColor(2);
   effNCLHLTOFF->SetMarkerColor(4);
   effNCLOFFHLT->Draw();
   effNCLHLTOFF->Draw("same");
  */


  chainHLTOFF0->Draw("counter==0:sign(track.fIp.fP[4])*track.fIp.fP[0]/track.fIp.fX>>profTPCEdge(50,-0.18,0.18)",cutNoiseEvent+cutEff+"abs(track.fP[4])<0.25","prof",50000);

  chainOFFHLT0->Draw("counter==0:sign(track.fIp.fP[4])*track.fIp.fP[0]/track.fIp.fX>>profTPCEdge(50,-0.18,0.18)",cutNoiseEvent+cutEff+"abs(track.fP[4])<1","prof",50000);

  chainOFFHLT0->Draw("track.fTPCncls:sign(track.fIp.fP[4])*track.fIp.fP[0]/track.fIp.fX>>profTPCEdge(50,-0.18,0.18)",cutNoiseEvent+cutEff+"abs(track.fP[4])<1","prof",50000);


}

/*
  This is  shell script real example  to submit jobs for the track comparison: 
  //
  //
  rm -rf list*
  rm -rf dirlist*
  wdir=`pwd`
  split offline.list --lines=50 list -d
  for a in `ls list*`; do
    mkdir dir$a
    cd dir$a
    mv ../$a compare.list
    bsub -q proof -oo outcompare.log aliroot -b -q $ALICE_ROOT/PWGPP/TPC/macroscompareTracks.C+
    cd $wdir
  done;

  find  `pwd`/  | grep .root > dumpHLTOFFLINE.list

*/
 compareTracks.C:1
 compareTracks.C:2
 compareTracks.C:3
 compareTracks.C:4
 compareTracks.C:5
 compareTracks.C:6
 compareTracks.C:7
 compareTracks.C:8
 compareTracks.C:9
 compareTracks.C:10
 compareTracks.C:11
 compareTracks.C:12
 compareTracks.C:13
 compareTracks.C:14
 compareTracks.C:15
 compareTracks.C:16
 compareTracks.C:17
 compareTracks.C:18
 compareTracks.C:19
 compareTracks.C:20
 compareTracks.C:21
 compareTracks.C:22
 compareTracks.C:23
 compareTracks.C:24
 compareTracks.C:25
 compareTracks.C:26
 compareTracks.C:27
 compareTracks.C:28
 compareTracks.C:29
 compareTracks.C:30
 compareTracks.C:31
 compareTracks.C:32
 compareTracks.C:33
 compareTracks.C:34
 compareTracks.C:35
 compareTracks.C:36
 compareTracks.C:37
 compareTracks.C:38
 compareTracks.C:39
 compareTracks.C:40
 compareTracks.C:41
 compareTracks.C:42
 compareTracks.C:43
 compareTracks.C:44
 compareTracks.C:45
 compareTracks.C:46
 compareTracks.C:47
 compareTracks.C:48
 compareTracks.C:49
 compareTracks.C:50
 compareTracks.C:51
 compareTracks.C:52
 compareTracks.C:53
 compareTracks.C:54
 compareTracks.C:55
 compareTracks.C:56
 compareTracks.C:57
 compareTracks.C:58
 compareTracks.C:59
 compareTracks.C:60
 compareTracks.C:61
 compareTracks.C:62
 compareTracks.C:63
 compareTracks.C:64
 compareTracks.C:65
 compareTracks.C:66
 compareTracks.C:67
 compareTracks.C:68
 compareTracks.C:69
 compareTracks.C:70
 compareTracks.C:71
 compareTracks.C:72
 compareTracks.C:73
 compareTracks.C:74
 compareTracks.C:75
 compareTracks.C:76
 compareTracks.C:77
 compareTracks.C:78
 compareTracks.C:79
 compareTracks.C:80
 compareTracks.C:81
 compareTracks.C:82
 compareTracks.C:83
 compareTracks.C:84
 compareTracks.C:85
 compareTracks.C:86
 compareTracks.C:87
 compareTracks.C:88
 compareTracks.C:89
 compareTracks.C:90
 compareTracks.C:91
 compareTracks.C:92
 compareTracks.C:93
 compareTracks.C:94
 compareTracks.C:95
 compareTracks.C:96
 compareTracks.C:97
 compareTracks.C:98
 compareTracks.C:99
 compareTracks.C:100
 compareTracks.C:101
 compareTracks.C:102
 compareTracks.C:103
 compareTracks.C:104
 compareTracks.C:105
 compareTracks.C:106
 compareTracks.C:107
 compareTracks.C:108
 compareTracks.C:109
 compareTracks.C:110
 compareTracks.C:111
 compareTracks.C:112
 compareTracks.C:113
 compareTracks.C:114
 compareTracks.C:115
 compareTracks.C:116
 compareTracks.C:117
 compareTracks.C:118
 compareTracks.C:119
 compareTracks.C:120
 compareTracks.C:121
 compareTracks.C:122
 compareTracks.C:123
 compareTracks.C:124
 compareTracks.C:125
 compareTracks.C:126
 compareTracks.C:127
 compareTracks.C:128
 compareTracks.C:129
 compareTracks.C:130
 compareTracks.C:131
 compareTracks.C:132
 compareTracks.C:133
 compareTracks.C:134
 compareTracks.C:135
 compareTracks.C:136
 compareTracks.C:137
 compareTracks.C:138
 compareTracks.C:139
 compareTracks.C:140
 compareTracks.C:141
 compareTracks.C:142
 compareTracks.C:143
 compareTracks.C:144
 compareTracks.C:145
 compareTracks.C:146
 compareTracks.C:147
 compareTracks.C:148
 compareTracks.C:149
 compareTracks.C:150
 compareTracks.C:151
 compareTracks.C:152
 compareTracks.C:153
 compareTracks.C:154
 compareTracks.C:155
 compareTracks.C:156
 compareTracks.C:157
 compareTracks.C:158
 compareTracks.C:159
 compareTracks.C:160
 compareTracks.C:161
 compareTracks.C:162
 compareTracks.C:163
 compareTracks.C:164
 compareTracks.C:165
 compareTracks.C:166
 compareTracks.C:167
 compareTracks.C:168
 compareTracks.C:169
 compareTracks.C:170
 compareTracks.C:171
 compareTracks.C:172
 compareTracks.C:173
 compareTracks.C:174
 compareTracks.C:175
 compareTracks.C:176
 compareTracks.C:177
 compareTracks.C:178
 compareTracks.C:179
 compareTracks.C:180
 compareTracks.C:181
 compareTracks.C:182
 compareTracks.C:183
 compareTracks.C:184
 compareTracks.C:185
 compareTracks.C:186
 compareTracks.C:187
 compareTracks.C:188
 compareTracks.C:189
 compareTracks.C:190
 compareTracks.C:191
 compareTracks.C:192
 compareTracks.C:193
 compareTracks.C:194
 compareTracks.C:195
 compareTracks.C:196
 compareTracks.C:197
 compareTracks.C:198
 compareTracks.C:199
 compareTracks.C:200
 compareTracks.C:201
 compareTracks.C:202
 compareTracks.C:203
 compareTracks.C:204
 compareTracks.C:205
 compareTracks.C:206
 compareTracks.C:207
 compareTracks.C:208
 compareTracks.C:209
 compareTracks.C:210
 compareTracks.C:211
 compareTracks.C:212
 compareTracks.C:213
 compareTracks.C:214
 compareTracks.C:215
 compareTracks.C:216
 compareTracks.C:217
 compareTracks.C:218
 compareTracks.C:219
 compareTracks.C:220
 compareTracks.C:221
 compareTracks.C:222
 compareTracks.C:223
 compareTracks.C:224
 compareTracks.C:225
 compareTracks.C:226
 compareTracks.C:227
 compareTracks.C:228
 compareTracks.C:229
 compareTracks.C:230
 compareTracks.C:231
 compareTracks.C:232
 compareTracks.C:233
 compareTracks.C:234
 compareTracks.C:235
 compareTracks.C:236
 compareTracks.C:237
 compareTracks.C:238
 compareTracks.C:239
 compareTracks.C:240
 compareTracks.C:241
 compareTracks.C:242
 compareTracks.C:243
 compareTracks.C:244
 compareTracks.C:245
 compareTracks.C:246
 compareTracks.C:247
 compareTracks.C:248
 compareTracks.C:249
 compareTracks.C:250
 compareTracks.C:251
 compareTracks.C:252
 compareTracks.C:253
 compareTracks.C:254
 compareTracks.C:255
 compareTracks.C:256
 compareTracks.C:257
 compareTracks.C:258
 compareTracks.C:259
 compareTracks.C:260
 compareTracks.C:261
 compareTracks.C:262
 compareTracks.C:263
 compareTracks.C:264
 compareTracks.C:265
 compareTracks.C:266
 compareTracks.C:267
 compareTracks.C:268
 compareTracks.C:269
 compareTracks.C:270
 compareTracks.C:271
 compareTracks.C:272
 compareTracks.C:273
 compareTracks.C:274
 compareTracks.C:275
 compareTracks.C:276
 compareTracks.C:277
 compareTracks.C:278
 compareTracks.C:279
 compareTracks.C:280
 compareTracks.C:281
 compareTracks.C:282
 compareTracks.C:283
 compareTracks.C:284
 compareTracks.C:285
 compareTracks.C:286
 compareTracks.C:287
 compareTracks.C:288
 compareTracks.C:289
 compareTracks.C:290
 compareTracks.C:291
 compareTracks.C:292
 compareTracks.C:293
 compareTracks.C:294
 compareTracks.C:295
 compareTracks.C:296
 compareTracks.C:297
 compareTracks.C:298
 compareTracks.C:299
 compareTracks.C:300
 compareTracks.C:301
 compareTracks.C:302
 compareTracks.C:303
 compareTracks.C:304
 compareTracks.C:305
 compareTracks.C:306
 compareTracks.C:307
 compareTracks.C:308
 compareTracks.C:309
 compareTracks.C:310
 compareTracks.C:311
 compareTracks.C:312
 compareTracks.C:313
 compareTracks.C:314
 compareTracks.C:315
 compareTracks.C:316
 compareTracks.C:317
 compareTracks.C:318
 compareTracks.C:319
 compareTracks.C:320
 compareTracks.C:321
 compareTracks.C:322
 compareTracks.C:323
 compareTracks.C:324
 compareTracks.C:325
 compareTracks.C:326
 compareTracks.C:327
 compareTracks.C:328
 compareTracks.C:329
 compareTracks.C:330
 compareTracks.C:331
 compareTracks.C:332
 compareTracks.C:333
 compareTracks.C:334
 compareTracks.C:335
 compareTracks.C:336
 compareTracks.C:337
 compareTracks.C:338
 compareTracks.C:339
 compareTracks.C:340
 compareTracks.C:341
 compareTracks.C:342
 compareTracks.C:343
 compareTracks.C:344
 compareTracks.C:345
 compareTracks.C:346
 compareTracks.C:347
 compareTracks.C:348
 compareTracks.C:349
 compareTracks.C:350
 compareTracks.C:351
 compareTracks.C:352
 compareTracks.C:353
 compareTracks.C:354
 compareTracks.C:355
 compareTracks.C:356
 compareTracks.C:357
 compareTracks.C:358
 compareTracks.C:359
 compareTracks.C:360
 compareTracks.C:361
 compareTracks.C:362
 compareTracks.C:363
 compareTracks.C:364
 compareTracks.C:365
 compareTracks.C:366
 compareTracks.C:367
 compareTracks.C:368
 compareTracks.C:369
 compareTracks.C:370
 compareTracks.C:371
 compareTracks.C:372
 compareTracks.C:373
 compareTracks.C:374
 compareTracks.C:375
 compareTracks.C:376
 compareTracks.C:377
 compareTracks.C:378
 compareTracks.C:379
 compareTracks.C:380
 compareTracks.C:381
 compareTracks.C:382
 compareTracks.C:383
 compareTracks.C:384
 compareTracks.C:385
 compareTracks.C:386
 compareTracks.C:387
 compareTracks.C:388
 compareTracks.C:389
 compareTracks.C:390
 compareTracks.C:391
 compareTracks.C:392
 compareTracks.C:393
 compareTracks.C:394
 compareTracks.C:395
 compareTracks.C:396
 compareTracks.C:397
 compareTracks.C:398
 compareTracks.C:399
 compareTracks.C:400
 compareTracks.C:401
 compareTracks.C:402
 compareTracks.C:403
 compareTracks.C:404
 compareTracks.C:405
 compareTracks.C:406
 compareTracks.C:407
 compareTracks.C:408
 compareTracks.C:409
 compareTracks.C:410
 compareTracks.C:411
 compareTracks.C:412
 compareTracks.C:413
 compareTracks.C:414
 compareTracks.C:415
 compareTracks.C:416
 compareTracks.C:417
 compareTracks.C:418
 compareTracks.C:419
 compareTracks.C:420
 compareTracks.C:421
 compareTracks.C:422
 compareTracks.C:423
 compareTracks.C:424
 compareTracks.C:425
 compareTracks.C:426
 compareTracks.C:427
 compareTracks.C:428
 compareTracks.C:429
 compareTracks.C:430
 compareTracks.C:431
 compareTracks.C:432
 compareTracks.C:433
 compareTracks.C:434
 compareTracks.C:435
 compareTracks.C:436
 compareTracks.C:437
 compareTracks.C:438
 compareTracks.C:439
 compareTracks.C:440
 compareTracks.C:441
 compareTracks.C:442
 compareTracks.C:443
 compareTracks.C:444
 compareTracks.C:445
 compareTracks.C:446
 compareTracks.C:447
 compareTracks.C:448
 compareTracks.C:449
 compareTracks.C:450
 compareTracks.C:451
 compareTracks.C:452
 compareTracks.C:453
 compareTracks.C:454
 compareTracks.C:455
 compareTracks.C:456
 compareTracks.C:457
 compareTracks.C:458
 compareTracks.C:459
 compareTracks.C:460
 compareTracks.C:461
 compareTracks.C:462
 compareTracks.C:463
 compareTracks.C:464
 compareTracks.C:465
 compareTracks.C:466
 compareTracks.C:467
 compareTracks.C:468
 compareTracks.C:469
 compareTracks.C:470
 compareTracks.C:471
 compareTracks.C:472
 compareTracks.C:473
 compareTracks.C:474
 compareTracks.C:475
 compareTracks.C:476
 compareTracks.C:477
 compareTracks.C:478
 compareTracks.C:479
 compareTracks.C:480
 compareTracks.C:481
 compareTracks.C:482
 compareTracks.C:483
 compareTracks.C:484
 compareTracks.C:485
 compareTracks.C:486
 compareTracks.C:487
 compareTracks.C:488