BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//____________________________________________________________________
// 
// Class BrBfsTofMatchingModule
//
// Module scanning the FS track table and picking up those
// matching valid tof hits.
// Selected tracks saved into a table of BrTofTrackMatch named 
// "BFS Matching"
//
// Algorithm (Event method):
// -------------------------
//
// 1- pick up tables of H2 hits and FS tracks
//    if one of them missing, return
//
// 2- Call method MatchTof(...)
//    a- Select tof hits by checking the TDCs and ADCs of both tubes
//   
//    b- loop over tracks and sub-loop over hits
//          i - evaluate the dX between track projection and hit position 
//         ii - minimize this distance and store the "winner" hit 
//              slat number in an array that has the dimension of 
//              the track table. It might be that the minimal dX is
//              beyond the matching criterium, then, the hit id is -1
//
//    c- check "multiple hits" when more than 1 track share the same
//       hit. In that case, ignore these tracks (it doesn't remove
//       completely multiple hits since there might be one track
//       only pointing to such hits - the other tracks having not
//       been reconstructed)
//
//    d- loop over remaining matchings and store result into table
//       of BrTofTrackMatch object (cf class implementation file)
//
// 3- If FFS and BFS are aligned and if there are some matchings in
//    H2 (a bit strict but ...), try the same game with H1 hits
//

//____________________________________________________________________
//
// $Id: BrBfsTofMatchingModule.cxx,v 1.11 2002/04/09 02:10:07 ouerdane Exp $
// $Author: ouerdane $
// $Date: 2002/04/09 02:10:07 $
// $Copyright: (C) 2001 BRAHMS Collaboration <brahmlib@rhic.bnl.gov>
//
#ifndef BRAT_BrBfsTofMatchingModule
#include "BrBfsTofMatchingModule.h"
#endif
#ifndef WIN32
#include <iostream>
#include <iomanip>
#include <fstream>
#else
#include <iomanip.h>
#include <fstream.h>
#include <iostream.h>
#endif
#ifndef BRAT_BrDataTable
#include "BrDataTable.h"
#endif
#ifndef BRAT_BrDetectorTrack
#include "BrDetectorTrack.h"
#endif
#ifndef BRAT_BrRunInfoManager
#include "BrRunInfoManager.h"
#endif
#ifndef BRAT_BrParameterDbManager
#include "BrParameterDbManager.h"
#endif
#ifndef BRAT_BrCalibrationManager
#include "BrCalibrationManager.h"
#endif
#ifndef BRAT_BrGeometryDbManager
#include "BrGeometryDbManager.h"
#endif
#ifndef BRAT_BrSpectrometerTracks
#include "BrSpectrometerTracks.h"
#endif
#ifndef BRAT_BrLine3D
#include "BrLine3D.h"
#endif
#ifndef BRAT_BrPlane3D
#include "BrPlane3D.h"
#endif

//____________________________________________________________________
ClassImp(BrBfsTofMatchingModule);

//____________________________________________________________________
 BrBfsTofMatchingModule::BrBfsTofMatchingModule()
  : BrModule()
{
  // Default constructor. DO NOT USE
  SetState(kSetup);

  fCalib[kH1]  = 0;
  fCalib[kH2]  = 0;
  fTofPar[kH1] = 0;
  fTofPar[kH2] = 0;
  
  SetDefaultParameters();
}

//____________________________________________________________________
 BrBfsTofMatchingModule::BrBfsTofMatchingModule(const Char_t* name, 
					       const Char_t* title)
  : BrModule(name, title)
{

  // Named Constructor
  SetState(kSetup);
  

  fCalib[kH1]  = 0;
  fCalib[kH2]  = 0;
  fTofPar[kH1] = 0;
  fTofPar[kH2] = 0;

  fTofName[kH2] = "TOF2";
  fTofName[kH1] = "TOF1";

  SetDefaultParameters();
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::SetDefaultParameters()
{ 
  // default parameters
  SetMaxH1DX(0.5); 
  SetMaxH2DX(0.75);
  SetT2H1XOffset(0.);
  SetT3H1XOffset(0.);
  SetT5H2XOffset(0.);
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::DefineHistograms()
{
  // Define histograms. They are:
  // <fill in here>

  if (GetState() != kInit) {
    Stop("DefineHistograms", "Must be called after Init"); 
    return;  
  }
  
  TDirectory* saveDir = gDirectory; 
  fHistDir[kH2] = gDirectory->mkdir("BFS_TofMatch"); 
  fHistDir[kH1] = 0;
  
  fHistDir[kH2]->cd();
  
  // list of histograms
  if (fNtuple)
    fNtMatch[kH2] = 
      new TNtuple("hH2Match", "Matched BFS Tracks - H2 Hits",
		  "nTrack:yTrack:xTrack:tTime:bTime:slat:tEner:bEner"
		  ":xHit:momentum");
  
  fSlatCheck = new TH1F("hSlatCheck", "Pointed slat - hit Slat number for pairs matching",
			10, -4.5, 5.5);
  
  fDxAll[kH2] = 
    new TH1F("hH2dXAll", "H2: #DeltaX BFS Track - H2 hit, "
	     "all combinations", 200, -20, 20);
  fDxMatch[kH2] = 
    new TH1F("hH2dXMatch", "H2: #DeltaX BFS Track - H2 hit "
	     "within matching condition", 200, -20, 20);

  fHistDir[kH2]->mkdir("Efficiency");
  fHistDir[kH2]->cd("Efficiency");
  fTopEff = new TH1F* [fTofPar[kH2]->GetNoSlats()];
  fBotEff = new TH1F* [fTofPar[kH2]->GetNoSlats()]; 

  for (Int_t s = 0; s < fTofPar[kH2]->GetNoSlats(); s++) { 
    fTopEff[s] = 
      new TH1F(Form("topEff%02d", s+1), Form("Efficiency, top tube %d", s+1), 30, -0.5, 2.5); 
    fBotEff[s] = 
      new TH1F(Form("botEff%02d", s+1), Form("Efficiency, bot tube %d", s+1), 30, -0.5, 2.5); 
  }

  fTrkEff = 
    new TH1F("hMatchEff", "Track-Hit eff - 0: at least a bad sig., "
	     "1: all signals OK", 20, -0.5, 1.5);

  fHistDir[kH2]->cd();

  fMatchStat[kH2] = 
    new TH1F("hH2Stat", "Number of matchings per event in H2", 
	     21, -0.5, 20.5);
  f2dXAll[kH2] = 
    new TH2F("hT5H2XAll", "X correlation T5 vs H2, all combinations",
	     51, -25.5, 25.5, 510, -25.5, 25.5);
  f2dXMatch[kH2] = 
    new TH2F("hT5H2XMatch", "X correlation T5 vs H2, matching pairs",
	     51, -25.5, 25.5, 510, -25.5, 25.5);

  // ----- H1 stuff
  if (fUseFfs) {
    fHistDir[kH1] = fHistDir[kH2]->mkdir("H1");
    fHistDir[kH1]->cd();
    
    fDxAll[kH1]    = new TH1F("hH1dXAll", "H1: #DeltaX BFS Track - H1 hit, "
			      "all combinations", 250, -25, 25);
    fDxMatch[kH1]  = new TH1F("hH1dXMatch", "H1: #DeltaX BFS Track - H1 hit "
			      "within matching condition", 250, -25, 25);
    f2dXAll[kH1]   = new TH2F("hH1X2dAll", "X correlation, all combinations",
			      51, -25.5, 25.5, 400, -25, 25);
    f2dXMatch[kH1] = new TH2F("hH1X2dMatch", "X correlation, matching pairs",
			      51, -25.5, 25.5, 400, -25, 25);
    
    fMatchStat[kH1] = 
      new TH1F("hH1Stat", "Number of matchings per event in H1",
	       21, -0.5, 20.5);
    if (fNtuple)
      fNtMatch[kH1] = 
	new TNtuple("hH1Match", "Matched BFS Tracks - H1 Hits",
		    "nTrack:yTrack:xTrack:tTime:bTime:slat:tEner:bEner"
		    ":xHit:momentum");
  }
  
  gDirectory = saveDir;
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::Init()
{
  // Job-level initialisation
  SetState(kInit);
  
  //-------------------------------------------------------
  // first check if fs is aligne to check if H1 can be used

  fUseFfs = kTRUE;

  BrRunInfoManager* runMan = BrRunInfoManager::Instance();
  const BrRunInfo* run = runMan->GetCurrentRun();
  if (run->GetRunNo() == -1) {
    Abort("Init", "Run number is -1, check it out");
    return;
  }

  if (run->GetFFSAngle() != run->GetBFSAngle()) {
    Warning("Init", "FFS and BFS are not aligned, disabling the use of H1");
    fUseFfs = kFALSE; 
  }

  // Detector parameters and calibrations
  InitParams();

  // check tof pedestal calibration
  CheckTofCal();

}

//____________________________________________________________________
 void BrBfsTofMatchingModule::InitParams()
{

  // private

  // -------------------------------
  // initialize detector parameters
  // -------------------------------

  BrParameterDbManager* parDb = BrParameterDbManager::Instance();
  BrCalibrationManager* calDb = 
    BrCalibrationManager::Instance();
  
  fCalib[kH2] = (BrTofCalibration*)calDb->
    Register("BrTofCalibration", fTofName[kH2].Data());
  fTofPar[kH2]   = (BrDetectorParamsTof*)parDb->
    GetDetectorParameters("BrDetectorParamsTof", fTofName[kH2].Data());

  // initialize all slat to good (let's be optimistic :)
  fValidSlat[kH2] = new Bool_t [fTofPar[kH2]->GetNoSlats()];
  for (Int_t s = 0; s < fTofPar[kH2]->GetNoSlats(); s++)
    fValidSlat[kH2][s] = kTRUE;

  if (!fUseFfs)
    return;

  fCalib[kH1] = (BrTofCalibration*)calDb->
    Register("BrTofCalibration", fTofName[kH1].Data());
  fTofPar[kH1]   = (BrDetectorParamsTof*)parDb->
    GetDetectorParameters("BrDetectorParamsTof", fTofName[kH1].Data());

  fValidSlat[kH1] = new Bool_t [fTofPar[kH1]->GetNoSlats()];
  for (Int_t s = 0; s < fTofPar[kH1]->GetNoSlats(); s++)
    fValidSlat[kH1][s] = kTRUE;
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::CheckTofCal()
{
  
  // private

  // ---------------------------
  // check pedestal calibration
  // ---------------------------

  Int_t nSlats = fTofPar[kH2]->GetNoSlats();
  
  // use pedestals and widths
  BrCalibration::EAccessMode mode = BrCalibration::kRead;  
  
  // check needed calibration, if already loaded (ascii file)
  // by the tof pedestal module (cf brat guide)
  // if not, try to get them from DB
  
  if (!fCalib[kH2]->GetAccessMode("topPedestal") ||
      !fCalib[kH2]->GetAccessMode("botPedestal") ||
      !fCalib[kH2]->GetAccessMode("topPedestalWidth") ||
      !fCalib[kH2]->GetAccessMode("botPedestalWidth")) {
    mode = BrCalibration::kRead;
    fCalib[kH2]->Use("topPedestal" ,mode, nSlats);
    fCalib[kH2]->Use("botPedestal", mode, nSlats);
    fCalib[kH2]->Use("topPedestalWidth", mode, nSlats);
    fCalib[kH2]->Use("botPedestalWidth", mode, nSlats);
  }

  // ----

  if (!fUseFfs)
    return;
  
  nSlats = fTofPar[kH1]->GetNoSlats();
  
  // use pedestals and widths
  mode = BrCalibration::kRead;  
  
  // check needed calibration, if already loaded (ascii file)
  // by the tof pedestal module (cf brat guide)
  // if not, try to get them from DB
  
  if (!fCalib[kH1]->GetAccessMode("topPedestal") ||
      !fCalib[kH1]->GetAccessMode("botPedestal") ||
      !fCalib[kH1]->GetAccessMode("topPedestalWidth") ||
      !fCalib[kH1]->GetAccessMode("botPedestalWidth")) {
    mode = BrCalibration::kRead;
    fCalib[kH1]->Use("topPedestal" ,mode, nSlats);
    fCalib[kH1]->Use("botPedestal", mode, nSlats);
    fCalib[kH1]->Use("topPedestalWidth", mode, nSlats);
    fCalib[kH1]->Use("botPedestalWidth", mode, nSlats);
  }
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::Begin()
{
  // Run-level initialisation
  SetState(kBegin);
  
  // ---------------------------
  // check pedestal revisions
  // ---------------------------

  // -------- check H2

  if (!fCalib[kH2]->RevisionExists("*")) {
    Abort("Begin", "Could not find H2 pedestal revision. Aborting...");
    return;
  }
  
  // check calibrated slats
  for(Int_t s = 0; s < fTofPar[kH2]->GetNoSlats(); s++) {
    fValidSlat[kH2][s] = kTRUE;
    if (!IsValid(fCalib[kH2]->GetBotPedestal(s+1))       ||
	!IsValid(fCalib[kH2]->GetTopPedestal(s+1))       ||
        !IsValid(fCalib[kH2]->GetBotPedestalWidth(s+1))  ||
	!IsValid(fCalib[kH2]->GetTopPedestalWidth(s+1)))
      fValidSlat[kH2][s] = kFALSE;
  }
  
  // -------- check H1
  fUseFfs = kTRUE;
  
  BrRunInfoManager* runMan = BrRunInfoManager::Instance();
  const BrRunInfo* run = runMan->GetCurrentRun();
  if (run->GetRunNo() == -1) {
    Abort("Begin", "Run number is -1, check it out");
    return;
  }
  
  if (run->GetFFSAngle() != run->GetBFSAngle()) {
    Warning("Begin", "FFS and BFS are not aligned, disabling the use of H1");
    fUseFfs = kFALSE;
    return;
  }

  if (!fCalib[kH1]->RevisionExists("*")) {
    Warning("Begin", "Could not find H1 pedestal revision. "
	    "Proceeding without...");
    fUseFfs = kFALSE;
  }
  
  
  // check calibrated slats
  if (fUseFfs) 
    for(Int_t s = 0; s < fTofPar[kH1]->GetNoSlats(); s++) {
      fValidSlat[kH1][s] = kTRUE;
      if (!IsValid(fCalib[kH1]->GetBotPedestal(s+1))       ||
	  !IsValid(fCalib[kH1]->GetTopPedestal(s+1))       ||
	  !IsValid(fCalib[kH1]->GetBotPedestalWidth(s+1))  ||
	  !IsValid(fCalib[kH1]->GetTopPedestalWidth(s+1)))
	fValidSlat[kH1][s] = kFALSE;
    }
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::Event(BrEventNode* inNode, BrEventNode* outNode)
{
  // Per event method
  SetState(kEvent);
  
  // ----------------------------------------------------------------
  // Event method:
  // 1- pick up tables of H2 hits and FS tracks
  //    if one of them missing, return
  //
  // 2- Call method MatchTof(...)
  //    a- Select tof hits by checking the TDCs and ADCs of both tubes
  //   
  //    b- loop over tracks and sub-loop over hits
  //          i - evaluate the dX between track projection and hit position 
  //         ii - minimize this distance and store the "winner" hit 
  //              slat number in an array that has the dimension of 
  //              the track table. It might be that the minimal dX is
  //              beyond the matching criterium, then, the hit id is -1
  //
  //    c- check "multiple hits" when more than 1 track share the same
  //       hit. In that case, ignore these tracks (it doesn't remove
  //       completely multiple hits since there might be one track
  //       only pointing to such hits - the other tracks having not
  //       been reconstructed)
  //
  //    d- loop over remaining matchings and store result into table
  //       of BrTofTrackMatch object (cf class implementation file)
  //
  // 3- If FFS and BFS are aligned and if there are some matchings in
  //    H2 (a bit strict but ...), try the same game with H1 hits
  // -------------------------------------------------------------------

  // ------- pick up fs tracks 
  
  BrDataTable* fsTracks = inNode->GetDataTable("FsTracks");
  if (!fsTracks)
    fsTracks = outNode->GetDataTable("FsTracks");
  
  if (!fsTracks) {
    if (Verbose() > 25)
      Warning("Event", "No FS tracks in this event");
    return;
  }    
  
  // ------- pick up tof digits
  BrDataTable* h2Hits = inNode->GetDataTable("DigTof TOF2");
  if (!h2Hits)
    h2Hits = outNode->GetDataTable("DigTof TOF2");
  
  if (!h2Hits) {
    if (Verbose() > 25)
      Warning("Event", "No TOF2 hits in this event");
    return;
  }
  
  // ------- check efficiency:
  if (HistOn()) CheckEfficiency(fsTracks, h2Hits);

  // ------- call matching method
  Int_t ntrk = fsTracks->GetEntries();
  Int_t matchId1[ntrk]; // array of track indexes matching tof2 hits

  BrTofDig* accHit1[h2Hits->GetEntries()];
  Int_t nH2Match = MatchTof(kH2, h2Hits, fsTracks, matchId1, accHit1);

  // ------- if no H2 matching, return here. 
  if (!nH2Match)
    return;
  

  // -------------------------------------------------------------------------  
  // try matching with H1
  Bool_t            h1Ok = fUseFfs;
  BrDataTable*    h1Hits = 0;

  //  TOF1 hits (if no H1 hits, never mind)
  if (fUseFfs) {
    h1Hits = inNode->GetDataTable("DigTof TOF1");
    if (!h1Hits) h1Ok = kFALSE;
  }
  
  Int_t nh = 0; // number of h1 hits
  Int_t nt = 0; // number of track

  if (h1Ok) {
    nh = h1Hits->GetEntries();  // number of TOF1 hits
    nt = ntrk;                  // number of FS tracks
  }
  
  // these arrays are in the Event scope since there will be some other checks later on
  // These are should not be defined like this- Works only on gcc not valid ANSI C++
  //
  BrTofDig* accHit2[nh]; // accepted H1 hits
  Int_t matchId2[nt];    // array of track indexes matching tof1 hits
  Int_t nH1Match = 0;
  
  if (h1Ok)
    nH1Match = MatchTof(kH1, h1Hits, fsTracks, matchId2, accHit2, matchId1);
  
  // -------------------------------------------------------------------------
  // prepare output

  BrDataTable* matchTab = new BrDataTable("BFS Matching");
  
  // ------- loop over pairs
  for (Int_t t = 0; t < ntrk; t++) {
    if (matchId1[t] == -1)
      continue;
    
    BrTofDig* hit1 = accHit1[matchId1[t]];
    Int_t    slat1 = hit1->GetSlatno();
    BrFsTrack* trk = (BrFsTrack*)fsTracks->At(t);
    Int_t    ffsId = trk->GetFfsTrackId();

    // H1 stuff
    BrTofDig* hit2 = 0;
    Int_t    slat2 = 0;
    if (nH1Match)
      if (matchId2[t] > -1) {
        hit2  = accHit2[matchId2[t]];
        slat2 = hit2->GetSlatno();
      }

    if (HistOn())
      fSlatCheck->Fill(trk->GetTof2Slat() - slat1);
    
    // create object
    BrTofTrackMatch* tt = new BrTofTrackMatch();
    tt->SetMatching(trk->GetId(), slat1, 0, slat2); // 0 is for H2 panel id
    matchTab->Add(tt);
    
    if (DebugLevel() > 10)
      tt->Print("B");
    
    // -------------------------------------------------
    if (!HistOn())
      continue;
    
    Double_t ttdc = hit1->GetTdcUp();
    Double_t tadc = hit1->GetAdcUp() - fCalib[kH2]->GetTopPedestal(slat1);
    Double_t btdc = hit1->GetTdcDown();
    Double_t badc = hit1->GetAdcDown() - fCalib[kH2]->GetBotPedestal(slat1);
    
    Double_t xHit = fTofPar[kH2]->GetSlatPos(slat1)[0] + fXOffset[kH2];
    
    BrVector3D proj = trk->GetTof2Proj();
    fDxMatch[kH2]->Fill(proj(0) - xHit);
    f2dXMatch[kH2]->Fill(xHit, proj(0));

    if (fNtuple)
      fNtMatch[kH2]->Fill(nH2Match, proj(1), proj(0), ttdc, btdc, slat1, 
			  tadc, badc, xHit, trk->GetMomentum());
    
    if (hit2) {
      ttdc = hit2->GetTdcUp();
      tadc = hit2->GetAdcUp() - fCalib[kH1]->GetTopPedestal(slat2);
      btdc = hit2->GetTdcDown();
      badc = hit2->GetAdcDown() - fCalib[kH1]->GetBotPedestal(slat2);
      
      xHit = fTofPar[kH1]->GetSlatPos(slat2)[0] + fXOffset[kH1];
      
      proj = trk->GetProjOnTof1();
      
      fDxMatch[kH1]->Fill(proj(0) - xHit);
      f2dXMatch[kH1]->Fill(xHit, proj(0));
      
      if (fNtuple)
        fNtMatch[kH1]->Fill(nH1Match, proj(1), proj(0), ttdc, btdc, slat2, 
			    tadc, badc, xHit, trk->GetMomentum());
      
    }
  }
  
  // check match table
  if (matchTab->GetEntries()) 
    outNode->AddDataTable(matchTab);
  else
    delete matchTab;
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::CheckEfficiency(BrDataTable* trks, BrDataTable* hits) 
{
  // private

  // ----------------------------------------------------------------
  // check that when a track points a slat, there's a valid signal 
  // in top and bot tubes
  // ----------------------------------------------------------------
  
  for (Int_t t = 0; t < trks->GetEntries(); t++) {
    BrVector3D proj = ((BrFsTrack*)trks->At(t))->GetProjOnTof2();
    BrVector3D off(fXOffset[kH2], 0, 0);
    proj -= off;
    
    Int_t psl = fTofPar[kH2]->GetSlatNo(proj(0));
    if (psl < 1 || psl > fTofPar[kH2]->GetNoSlats())
      continue;
    
    Bool_t good = kFALSE;
    
    for (Int_t h = 0; h < hits->GetEntries(); h++) {
      BrTofDig* hit = (BrTofDig*)hits->At(h);
      if (psl != hit->GetSlatno())
	continue;
      
      Int_t slat = hit->GetSlatno();
      
      // pedestals    
      Float_t  tPed   = fCalib[kH2]->GetTopPedestal(slat);
      Float_t  bPed   = fCalib[kH2]->GetBotPedestal(slat);
      Float_t  tWid   = fCalib[kH2]->GetTopPedestalWidth(slat);
      Float_t  bWid   = fCalib[kH2]->GetBotPedestalWidth(slat);
      
      // hit info    
      Double_t tadc = hit->GetAdcUp() - tPed;
      Double_t badc = hit->GetAdcDown() - bPed;
      Double_t ttdc = hit->GetTdcUp();
      Double_t btdc = hit->GetTdcDown();
      
      // top adc and tdc checks
      if (tadc > fNoPedWidth*tWid) {
	fTopEff[slat-1]->Fill(1.);
	if (ttdc < 4000 && ttdc > 10) {
	  fTopEff[slat-1]->Fill(2.);
	  good = kTRUE;
	}
      }
      else 
	fTopEff[slat-1]->Fill(0.);
      
      // bot adc and tdc checks
      if (badc > fNoPedWidth*tWid) {
	fBotEff[slat-1]->Fill(1.);
	if (btdc < 4000 && btdc > 10)
	  fBotEff[slat-1]->Fill(2.);
	else
	  good = kFALSE;
      }
      else {
	fBotEff[slat-1]->Fill(0.);
	good = kFALSE;
      }
    }
    
    if (good)
      fTrkEff->Fill(1.);
    else
      fTrkEff->Fill(0.);
  }
}

//____________________________________________________________________
 Int_t BrBfsTofMatchingModule::MatchTof(ETofId id, 
				       BrDataTable* hitTab, 
				       BrDataTable* trkTab,
				       Int_t*       matchId,
				       BrTofDig**   hits,
				       Int_t*       h2Id)
{
  
  Int_t ntrk = trkTab->GetEntries(); // number of fs tracks in event
  Int_t nhit = hitTab->GetEntries(); // number of tof hits in event
  
  // -------------------------------------------------------
  
  // ------ 1st: selection of tof hits   ------
  
  // array of accepted hits
  for (Int_t i = 0; i < nhit; i++)
    hits[i] = 0;

  Int_t nacc = SelectHits(id, hitTab, hits);
  if (Verbose() > 30)
    cout << " Number of selected hits in " << fTofName[id].Data() 
	 << " : " << nacc << endl;
  if (!nacc) return 0;

  // ------ 2nd match tracks to hits ------

  // ----------------------------------------------------------------  
  // loop over tracks and tof hits to find best hit for given track
  // ----------------------------------------------------------------
  
  Bool_t goOn = kFALSE;

  for (Int_t t = 0; t < ntrk; t++) { // loop for track projection
    matchId[t] = -1; // initialize matching index
    
    // if H1, check if this track already matches with H2:
    if (id == kH1 && h2Id)
      if (h2Id[t] == -1) continue;
    
    BrFsTrack* trk = (BrFsTrack*)trkTab->At(t);
    Double_t dX     = 999999.; // dX between hit and back track proj
    BrVector3D proj = trk->GetProjOnTof2();
    if (id == kH1) proj = trk->GetProjOnTof1();

    // ---- loop over hits
    for(Int_t h = 0; h < nacc; h++) {
      
      // determine x pos. of tof hit (middle of a slat)
      Int_t slat        = hits[h]->GetSlatno();
      BrVector3D hitPos = fTofPar[id]->GetSlatPos(slat);
      
      // have now X hit position on tof plane
      // gonna minimize the difference with track proj X cut 
      
      Double_t diffX = proj(0) - hitPos(0);
      
      if (HistOn()) {
	fDxAll[id]->Fill(diffX);
        f2dXAll[id]->Fill(hitPos(0), proj(0));
      }
      // correct for the offset in X between T5 and H2 (or T3/T2 and H1)
      // when evaluating cuts.
      if (id == kH1) {
	fXOffset[id] = fT3H1XOffset;
	if (trk->GetFfsTrackId() >= 0)
	  fXOffset[id] = fT2H1XOffset;
      }

      diffX -= fXOffset[id];
      
      // ignore cases where we are too far off
      if (TMath::Abs(diffX) > fMaxDX[id])
	continue;
      
      if (TMath::Abs(diffX) < TMath::Abs(dX)) {
	dX = diffX;
	matchId[t] = h;
      }
    }
    
    if (matchId[t] > -1) 
      goOn = kTRUE;

    if (Verbose() > 10) {
      cout << "FS track " << t << " : dX = " << dX; 
      if (matchId[t] > -1)
	cout << " with TOF" << 2-id << " hit at slat " 
	     << hits[matchId[t]]->GetSlatno()   << endl; 
      else
	cout << " ---> no hits in TOF" << 2-id 
	     << " within matching conditions " << endl;
    }
  }

  if (!goOn)
    return 0;

  // ------- check multiple hits
  for (Int_t t = 0; t < ntrk - 1; t++)
    for (Int_t i = t + 1; i < ntrk; i++) {
      if (matchId[i] == -1 || matchId[t] == -1) 
	continue; 
      if (matchId[i] == matchId[t]) { // multiple hit (?) 
	matchId[i] = -1;
	matchId[t] = -1;
      } 
    } 
  
  
  // -------  evaluate the number of matchings and return it
  Int_t nMatch = 0;
  
  for (Int_t t = 0; t < ntrk; t++) {
    if (matchId[t] == -1)
      continue;
    nMatch++;
  }
  
  if (HistOn())
    fMatchStat[id]->Fill(nMatch);
  
  if (Verbose() > 10)
    cout << " Found " << nMatch 
	 << " FS tracks matching " << fTofName[id].Data() << " hits" 
	 << " within a matching limit of " 
	 << fMaxDX[id] << " cm " << endl;
  
  return nMatch;
}
    
//_____________________________________________________________
 Int_t BrBfsTofMatchingModule::SelectHits(ETofId id, 
					 BrDataTable* hits,
					 BrTofDig** sel)
{

  // private

  // --------------------------------
  // tof hit selection: 
  //     1- check ADCs and TDCs 
  //     2- Fill array of good hits
  //     3- return their number 
  // --------------------------------
  
  Int_t hitOk = 0;
  for(Int_t h = 0; h < hits->GetEntries(); h++) {
    BrTofDig* hit = (BrTofDig*)hits->At(h);
    Int_t    slat = hit->GetSlatno();
    
    // check if slat ok
    if (!fValidSlat[id][slat-1])
      continue;
    
    // pedestals    
    Float_t  tPed   = fCalib[id]->GetTopPedestal(slat);
    Float_t  bPed   = fCalib[id]->GetBotPedestal(slat);
    Float_t  tWid   = fCalib[id]->GetTopPedestalWidth(slat);
    Float_t  bWid   = fCalib[id]->GetBotPedestalWidth(slat);
    
    // hit info    
    Double_t tadc = hit->GetAdcUp() - tPed;
    Double_t badc = hit->GetAdcDown() - bPed;
    Double_t ttdc = hit->GetTdcUp();
    Double_t btdc = hit->GetTdcDown();
    
    // adc and tdc checks
    if (tadc < fNoPedWidth*tWid  || badc < fNoPedWidth*bWid  || 
	ttdc > fMaxTdc || btdc > fMaxTdc || ttdc < fMinTdc || btdc < fMinTdc) 
      continue;
    
    sel[hitOk] = hit;
    hitOk++;
  }

  return hitOk;
}

//____________________________________________________________________
 void BrBfsTofMatchingModule::Print(Option_t* option) const
{
  // Print module information
  // See BrModule::Print for options.
  // In addition this module defines the Option:
  // <fill in here>

  TString opt(option);
  opt.ToLower(); 
  
  BrModule::Print(option); 
  if (opt.Contains("d")) 
   cout << endl 
         << "  Original author: Djamel Ouerdane" << endl
         << "  Last Modifications: " << endl 
         << "    $Author: ouerdane $" << endl  
         << "    $Date: 2002/04/09 02:10:07 $"   << endl 
         << "    $Revision: 1.11 $ " << endl  
         << endl 
         << "-------------------------------------------------" << endl;
}

//____________________________________________________________________
//
// $Log: BrBfsTofMatchingModule.cxx,v $
// Revision 1.11  2002/04/09 02:10:07  ouerdane
// updated to reflect latest changes in BrBfsTrack
//
// Revision 1.10  2002/03/08 20:01:16  videbaek
// Changed order of execution such that the track-tof position in histogramming is
// the absolute difference - not subtracted by the code offset.:
//
// Revision 1.9  2001/12/20 15:57:02  ouerdane
// removed a bug that made the correlation with FFS really bad
//
// Revision 1.8  2001/12/13 13:42:22  ouerdane
// fixed small bugs and cleaned a bit
//
// Revision 1.7  2001/11/07 10:32:14  ouerdane
// updated matching module for H2 recontruction and PID
//
// Revision 1.6  2001/11/05 07:11:39  ouerdane
// changed FFS to Ffs, BFS to Bfs, MRS to Mrs. Fixed bugs in BFS module
//
// Revision 1.5  2001/10/19 15:52:48  ouerdane
// fixed some logic in Init()
//
// Revision 1.4  2001/10/08 11:29:43  cholm
// Changed to use new DB access classes
//
// Revision 1.3  2001/10/07 13:36:49  ouerdane
// Allowed to set true or false the use of H1 even if the arms are aligned
//
// Revision 1.2  2001/10/02 20:20:38  ouerdane
// remove member fNoPanels and setter method since it is now part of the
// tof detector parameter class.
// Corrected errors due to fast rewriting of the modules. should be ok now.
//
// Revision 1.1  2001/10/02 02:05:24  ouerdane
// Added modules combining and saving Tracks and Tof hits
//
//

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