BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//____________________________________________________________________
// 
// BrTofTimeOffsetCalModule: module for Tof Time correction
//
// The assumptiom made here is that all particles are pions with beta = 1
// This means that the tof not calibrated will be aligned with
// t = L/c with L path length of the associated track
//
//    t_not_cal = t + off => off = t_not_cal - off
//
// Select hits matcing tracks (X and Y)
// Cut in energy (from 0.8 to 2 MIP energy) - This cut is stiil on as default
// but can be disabled.
// It really does not make any significant differences and means that all Tof slats can be
// time-offset calibrated assuming the slats have been calibrated.
// Fill histograms with off for each tube and fit with gaussian 
// around histo-max +/- fit window 
// Cut in momentum is also needed (for MRS you do not want to contaminate with kaon's
// and protons). Such cut would also mean it can be used in FS without Cherenkov cut.
//
//____________________________________________________________________
//
// $Id: BrTofTimeOffsetCalModule.cxx,v 1.16 2002/08/30 16:16:40 hagel Exp $
// $Author: hagel $
// $Date: 2002/08/30 16:16:40 $
// $Copyright: (C) 2001 BRAHMS Collaboration <brahmlib@rhic.bnl.gov>
//____________________________________________________________________
//

#ifndef WIN32
#include <iostream>
#include <iomanip>
#include <fstream>
#else
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#endif

#include <vector.h>

#ifndef BRAT_BrTofTimeOffsetCalModule
#include "BrTofTimeOffsetCalModule.h"
#endif
#ifndef ROOT_TDirectory
#include "TDirectory.h"
#endif
#ifndef ROOT_TF1
#include "TF1.h"
#endif
#ifndef BRAT_BrDataTable
#include "BrDataTable.h"
#endif
#ifndef BRAT_BrTofDig
#include "BrTofDig.h"
#endif
#ifndef BRAT_BrBbVertex
#include "BrBbVertex.h"
#endif
#ifndef BRAT_BrRunInfoManager
#include "BrRunInfoManager.h"
#endif
#ifndef BRAT_BrUnits
#include "BrUnits.h"
#endif
#ifndef BRAT_BrCalibration
#include "BrCalibration.h"
#endif
#ifndef BRAT_BrTofTrackMatch
#include "BrTofTrackMatch.h"
#endif
#ifndef BRAT_BrSpectrometerTracks
#include "BrSpectrometerTracks.h"
#endif
#ifndef BRAT_BrPid
#include "BrPid.h"
#endif
#ifndef BRAT_BrC1Pid
#include "BrC1Pid.h"
#endif
#ifndef BRAT_BrRichPid
#include "BrRichPid.h"
#endif
#ifndef BRAT_BrTd1TrackMatch
#include "BrTd1TrackMatch.h"
#endif
#ifndef BRAT_BrTMrsFTrackMatch
#include "BrTMrsFTrackMatch.h"
#endif

//____________________________________________________________________
ClassImp(BrTofTimeOffsetCalModule);

//____________________________________________________________________
 BrTofTimeOffsetCalModule::BrTofTimeOffsetCalModule()
  : BrTofCalModule()
{
  // Default constructor. DO NOT USE
  SetState(kSetup);
  SetDefaultParameters();
}

//____________________________________________________________________
 BrTofTimeOffsetCalModule::BrTofTimeOffsetCalModule(const Char_t* name, 
						 const Char_t* title)
  : BrTofCalModule(name, title)
{
  // Named Constructor
  SetState(kSetup);
  SetDefaultParameters();
}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::SetDefaultParameters()
{
  // default parameters

  SetMaxDY();        // default is 1 cm
  SetMaxEnergy();    // default is 1.5
  SetFitWindow();    // default is 0.5 ns 

  SetC1Threshold();  // default is 1
  SetRichPionMass(); // default is theoretical pion mass
  SetRichMassCut();  // default is 0.05 GeV/c^2 

  SetTrkCuts(3, 3, 1000); // dx, dy, dz in cm (should correspond to sigma cuts)
  SetTrkOffsets(0, 0, 0); // x, y, z in cm
  SetMomentumCut();
  SetUseBbVertex();
  SetUseTd1Time();   // default is false (pp only)
  SetUseTMrsTime();  // default is false (pp only)
  SetRequireAdc();   // default ifs TRUE
}

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

  if (GetState() != kInit) {
    Stop("DefineHistograms", "Must be called after Init"); 
    return;  
  }

  if (fLoadAscii || fCommitAscii) {
    if (Verbose() > 5)
      Warning("DefineHistograms", "No need to declare histos "
              "since we only load calibration from ascii file"); 
    return;  
  }

  const Int_t nSlats = fParamsTof->GetNoSlats();

  TDirectory* saveDir = gDirectory; 
  fHistDir = gDirectory->mkdir(Form("%s_Offsets",GetName())); 
  fHistDir->cd();
  

  // Make histograms here
  fHistDir->mkdir("Slats");
  
  // --------------  histos for calib:
  
  Float_t tmin = -50;
  Float_t tmax = -10;
  if(fUseTMrsTime){
    tmin = -60;
    tmax =  00;
  }
  
  if (fInBfs && fFsLined) {
    tmin = -100;
    tmax = -60;
  }

  fHistDir->cd("Slats");
  fOffset  = new TH1F* [nSlats];
  for (Int_t i = 1; i <= nSlats; i++)
    fOffset[i-1] =
      new TH1F(Form("offset%03d", i), "", 1600, tmin, tmax);

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

  fHistDir->cd();
  fOffsetSummary = new TH1F("offsetSummary", 
			    Form("%s Time Offsets", GetName()),
			    nSlats, 0.5, nSlats + 0.5); 
  fSigmaSummary = new TH1F("sigmaSummary", 
			   Form("%s Time sigmas", GetName()),
			   nSlats, 0.5, nSlats + 0.5); 

  fDeltaY    = new TH1F("deltaY", "#DeltaY (Track - tof Hit)", 400, -5, 5);
  fDeltaYCut = new TH2F("deltaYCut", "#DeltaY (Track - tof Hit) vs Slat", 
			nSlats, 0.5, nSlats + 0.5, 400, -5, 5);

  fhVtxCutX  = new TH1F("vtxcutX","Accepted relative X-vertex values",80, -4, 4);
  fhVtxCutY  = new TH1F("vtxcutY","Accepted relative Y-vertex values",80, -4, 4);
  fhVtxCutZ  = new TH1F("vtxcutZ","Accepted relative Z-vertex values",80, -10, 10);

  gDirectory = saveDir;
}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::Init()
{
  // Job-level initialisation
  SetState(kInit);
  
  //---------------
  // base class initialization (register calibration parameters)
  BrTofCalModule::Init();
  
  Int_t nSlats = fParamsTof->GetNoSlats();
  BrCalibration::EAccessMode mode = BrCalibration::kTransitional;

  // check if we want to load timing offset from file
  // 

  if (fLoadAscii)
    fCalibration->Use("timeOffset", mode, nSlats);
  
  else {
    // check if need calibration already loaded 
    // if not, try to get them from DB
    // 

    if (!fCalibration->GetAccessMode("topPedestal")  ||
	!fCalibration->GetAccessMode("botPedestal")) {
      mode = BrCalibration::kRead;
      fCalibration->Use("topPedestal", mode, nSlats);
      fCalibration->Use("botPedestal", mode, nSlats);
    }

    if(fRequireAdc) {
      if (!fCalibration->GetAccessMode("topAdcGain")  ||
	  !fCalibration->GetAccessMode("botAdcGain")) {
	mode = BrCalibration::kRead;
	fCalibration->Use("topAdcGain", mode, nSlats);
	fCalibration->Use("botAdcGain", mode, nSlats);
      }
    }

    if (!fCalibration->GetAccessMode("topTdcGain")  ||
	!fCalibration->GetAccessMode("botTdcGain")) {
      mode = BrCalibration::kRead;
      fCalibration->Use("topTdcGain", mode, nSlats);
      fCalibration->Use("botTdcGain", mode, nSlats);
    }

    if (!fCalibration->GetAccessMode("deltaDelay")  ||
	!fCalibration->GetAccessMode("")) {
      mode = BrCalibration::kRead;
      fCalibration->Use("deltaDelay", mode, nSlats);
      fCalibration->Use("effSpeedOfLight", mode, nSlats);
    }
  }
  
  // if we want to save calibration (ascii or DB)
  if (fSaveAscii || fCommitAscii) {
    mode = BrCalibration::kWrite;
    fCalibration->Use("timeOffset", mode, nSlats);
  }
  
  
  // geometry
  if (!fCommitAscii && !fLoadAscii)
    if (fInMrs)
      BrTofCalModule::InitGeo();
  
}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::Begin()
{
  // Run-level initialisation
  SetState(kBegin);
   
  if (fLoadAscii) {
    ReadAscii();
    return;
  }
  
  if (!HistBooked()) 
    if (!fCommitAscii) {
      Abort("Begin", "You cannot perform a calibration without histograms!!");
      return;
    }

  // check if we got parameter revisions:
  if (!fCalibration->RevisionExists("*")) {
    Abort("Begin", "Some TOF calibration revisions are missing!");
    return;
  }
  
  for (Int_t s = 1; s <= fParamsTof->GetNoSlats(); s++) {
    fCalibration->SetTimeOffset(s, BrTofCalibration::kCalException);
    fValidSlat[s-1] = kTRUE;
    Float_t tag0, bag0;    
    Float_t tped, bped;

    if(fRequireAdc){
      tped = fCalibration->GetTopPedestal(s);
      bped = fCalibration->GetBotPedestal(s);
      tag0 = fCalibration->GetTopAdcGain(s);
      bag0 = fCalibration->GetBotAdcGain(s);
    }

    Float_t ttg  = fCalibration->GetTopTdcGain(s);
    Float_t btg  = fCalibration->GetBotTdcGain(s);
    Float_t effc = fCalibration->GetEffSpeedOfLight(s);
    Float_t del  = fCalibration->GetDeltaDelay(s);
    
    if (
	(fRequireAdc &&	(!IsValid(tped) || !IsValid(bped) || !IsValid(tag0) || !IsValid(bag0))) ||
	!IsValid(ttg)  || !IsValid(btg)  ||
	!IsValid(effc) || !IsValid(del)) {
      fValidSlat[s - 1] = kFALSE;
      if(Verbose()){
	cout << "Not valid Slat from DB " << setw(8) << s << endl;
	if(fRequireAdc){
	  if(!IsValid(tped)) cout << "   Top Pedestal" << endl;
	  if(!IsValid(bped)) cout << "   Bot Pedestal" << endl;
	  if(!IsValid(tag0)) cout << "   Top AdcGain" << endl;
	  if(!IsValid(bag0)) cout << "   Bot AdcGain" << endl;
	}
	if(!IsValid(ttg))  cout << "    Top TdcGain" << endl;
	if(!IsValid(btg))  cout << "    Bot TdcGain" << endl;
	if(!IsValid(effc)) cout << "   Eff Speed" << endl;
	if(!IsValid(del))  cout << "    Delta Up down" << endl;
      }
    }
  }
}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::Event(BrEventNode* inNode, BrEventNode* outNode)
{
  // Per event method
  // Note the algortimh actually used is different if the t0 comes from either
  // BB vertex or from the pp trigger start counters.
  //
  SetState(kEvent);
  

  // ---- get BB stuff

  if (fCommitAscii || fLoadAscii)
    return;
  
  // get the the matched tracks and hits table
  BrDataTable* match = 
    inNode->GetDataTable(fMatchName.Data());
  if (!match)
    match = outNode->GetDataTable(fMatchName.Data());
  
  if (!match) {
    if (Verbose() > 20) Warning("Event", "No tracks matching hits");
    return;
  }
  
  // ------ beam beam vertex  

  BrBbVertex* vertex = (BrBbVertex*)inNode->GetObject("BB Vertex");
  if (!vertex) 
    vertex = (BrBbVertex*)outNode->GetObject("BB Vertex");

  if(fUseBbVertex && !vertex)
    {
      Info(10,"Event", " No beam beam stuff");
      return;
    }
  
  
  Float_t Z0 = 0;
  Float_t T0 = 0;
  Int_t method = 2;

  if(fUseBbVertex){
    Z0 = vertex->GetZ0();
    T0 = vertex->GetTime0();
    method = vertex->GetMethod();

    // ------ select only small tube vertex
    if (method != 2){
      Info(10,"Event","No method 2 BB");
      return;
    }
  }
  
  
  
  BrVector3D primVtx(0, 0, Z0);

  // get hit table
  BrDataTable* hits = inNode->GetDataTable(Form("DigTof %s", GetName()));
  if (!hits)
    hits = outNode->GetDataTable(Form("DigTof %s", GetName()));
  
  if (!hits) {
    if (Verbose() > 10) Warning("Event", "No global tof hits at all");
    return;
  }
  
  // get track table(s)
  BrDataTable* tracks  = 0;
  
  if (fInFfs) tracks = inNode->GetDataTable("FfsTracks");
  if (fInBfs) tracks = inNode->GetDataTable("FsTracks"); // need the full FS tracks
  if (fInMrs) tracks = inNode->GetDataTable("MrsTracks");
  
  if (!tracks) {
    if (fInFfs) tracks = outNode->GetDataTable("FfsTracks");
    if (fInBfs) tracks = outNode->GetDataTable("FsTracks");
    if (fInMrs) tracks = outNode->GetDataTable("MrsTracks");
  }
  
  if (!tracks) {
    if (Verbose() > 10) Warning("Event", "No tracks at all");
    return;
  }

  BrDataTable* td1tab = 0;
  td1tab = inNode->GetDataTable("FfsMatchTd1");

  BrDataTable* tmrstab = 0;
  tmrstab = inNode->GetDataTable("MrsFMatch");
  if(Verbose()>50)
    inNode->ListObjects();

  
  // ------ get Cherenkov pid table 
  BrDataTable* chkTab = 0;
  if (fInFfs) chkTab = inNode->GetDataTable("C1Pid");
  if (fInBfs) chkTab = inNode->GetDataTable("RichPid");
  
  if (!chkTab) {
    if (fInFfs) chkTab = outNode->GetDataTable("C1Pid");
    if (fInBfs) chkTab = outNode->GetDataTable("RichPid");
  }
  
  if (!fInMrs && !chkTab) {
    if (Verbose() > 30) Warning("Event", "No cherenkov PID at all");
    return;
  }

  Int_t ntd1 = 0;
  if (fUseTd1Time) {
    if (td1tab)
      ntd1 = td1tab->GetEntries();
    if (Verbose() > 10)
      for(Int_t k = 0; k < ntd1; k++) {
	BrTd1TrackMatch* td1m = (BrTd1TrackMatch*)td1tab->At(k);
	td1m->Print();
      }
  }

  Int_t ntmrs = 0;
  if (fUseTMrsTime) {
    if (tmrstab)
      ntmrs = tmrstab->GetEntries();
    if (Verbose() > 10)
      for(Int_t k = 0; k < ntmrs; k++) {
	BrTMrsFTrackMatch* tmrsm = (BrTMrsFTrackMatch*)tmrstab->At(k);
	tmrsm->Print();
      }
  }



  if (Verbose() > 10) {
    cout << " -------------------------- " << endl
	 << " Number of tracks         : " << tracks->GetEntries() << endl
         << " Number of tof digits     : " << hits->GetEntries() << endl
	 << " Number of matching pairs : " << match->GetEntries() << endl;
    if(tmrstab)
      cout << " Number of TMrs Matched   : " << tmrstab->GetEntries() << endl;
    if (!fInMrs)
      cout << " Number of Cherenkov Pid  : " << chkTab->GetEntries() << endl;
  }

  // --------------------------------------------------------
  
  Int_t nhit  = hits->GetEntries();   // number of tof hits in event
  Int_t ntrk  = tracks->GetEntries(); // number of tracks in event
  Int_t nchk  = 0;
  if (!fInMrs)
    nchk = chkTab->GetEntries(); // number of chk pid elements
  
  Int_t nmch  = match->GetEntries();  // number matching pairs
  
  BrTofDig*   tofHit[nmch];  // array of good hits
  TObject*    track [nmch];  // array of spectrometer tracks
  BrPid*      chkPid[nmch];  // array of chk pid objects
  vector <BrTd1TrackMatch*>    td1hit(nmch);   // array of possible Td1Hits
  vector <BrTMrsFTrackMatch*>    tmrshit(nmch);   // array of possible TMrsFhits


  
  for (Int_t m = 0; m < nmch; m++) {
    tofHit[m]  = 0;
    track [m]  = 0;
    chkPid[m]  = 0;
    td1hit[m] = 0;
    tmrshit[m] = 0;

 
    BrTofTrackMatch* pair = (BrTofTrackMatch*)match->At(m);
    
    // now select right hit thanks to the match object
    // we are now sure that the hit will correspond to a valid track  
    for (Int_t h = 0; h < nhit; h++) {
      BrTofDig* hit = (BrTofDig*)hits->At(h);
      if (hit->GetSlatno() != pair->GetHitId())
	continue;
      tofHit[m] = hit;
    }

    // now select right track proj thanks to the match object
    for (Int_t t = 0; t < ntrk; t++) {
      TObject* trk = tracks->At(t);
      if (trk->GetUniqueID() != pair->GetTrackId())
	continue;
      track[m] = trk;
    }

    //
    // Lookup the Td1Hit corresponding to this track
    //
    
    if(fUseTd1Time){
      if (td1tab){       
	for (Int_t p = ntd1-1; p >=0; p--) {
	  BrTd1TrackMatch* chk = (BrTd1TrackMatch*)td1tab->At(p);
	  if (chk->GetTrackId() != pair->GetTrackId())
	    continue;
	  td1hit[m] = chk;
	}
      }
    }
    //
    // Lookup the TMrsFHit corresponding to this track
    //

    if(fUseTMrsTime){
      if (tmrstab){       
	for (Int_t p = ntmrs-1; p >=0; p--) {
	  BrTMrsFTrackMatch* chk = (BrTMrsFTrackMatch*)tmrstab->At(p);
	  if (chk->GetTrackId() != pair->GetTrackId())
	    continue;
	  tmrshit[m] = chk;
	}
      }
    }


    if (fInMrs)
      continue;

    // now select right chk pid objects
    for (Int_t p = 0; p < nchk; p++) {
      BrPid* pid = (BrPid*)chkTab->At(p);
      if (pid->GetTrackId() != pair->GetTrackId())
	continue;
      chkPid[m] = pid;
    }
  } // end of loop over tof-track match
  
  //------------------------------------------   
  //    can now proceed with calibration
  //------------------------------------------
  
  for(Int_t h = 0; h < nmch; h++) {
    if (tofHit[h] == 0 || track[h] == 0)
      continue;
    
    BrTofTrackMatch* pair = (BrTofTrackMatch*)match->At(h);
    if (fValidSlat[pair->GetHitId() - 1] == kFALSE)
      continue;
    
    // ------ check if we have a valid PID in cherenkov det.
    if (!fInMrs && !chkPid[h])
      continue;

    // --- track info
    Float_t length;
    Float_t moverp;
    Float_t chksig = 0;
    BrVector3D trkVtx;
    BrVector3D proj;

    if (fInFfs) {
      BrFfsTrack* t = (BrFfsTrack*)track[h];
      if (!t->GetD1SwimStatus())
	continue;
      proj   = t->GetProjOnTof(); 
      length = t->GetPathLength();
      moverp = 0.1395679/t->GetMomentum();
      trkVtx = t->GetTrackVertex();
      chksig = ((BrC1Pid*)chkPid[h])->GetBlobEnergy();

      if(fUseTd1Time) {
         //Need to redefine length and T0 if we are using TD1 time
         if(td1hit[h]) {
	    T0       = td1hit[h]->GetTime();
	    length = t->GetPartialPath() + td1hit[h]->GetLength();
	    //td1slat  = td1hit[h]->GetSlat();
            }
         }
      }
    
    if (fInMrs) {
      BrMrsTrack* t = (BrMrsTrack*)track[h];
      length = t->GetPathLength();

      Int_t tmrsslat = 0;
      if (fUseTMrsTime)
	if (tmrshit[h]) {
	  T0       = tmrshit[h]->GetTime();
	  length   = ((BrMrsTrack*)track[h])->GetPartialPath() + tmrshit[h]->GetLength();
	  tmrsslat  = 1;
	}
	else
	  continue;
      
      Info(10,"Event","track length = %f, Momentum = %f, cut = %fn",length,t->GetMomentum(),fMomentumCut);
      if(TMath::Abs(t->GetMomentum()) > fMomentumCut) 
	continue;
      moverp = 0.1395679/t->GetMomentum();
      trkVtx = t->GetTrackVertex();
      Int_t panel = pair->GetPanelId();
      fPanelVol[panel]->GlobalToLocal(t->GetProjOnTof(), proj, 0);
    }
    
    Double_t ffsTrackLength = 0;
    Double_t bfsTrackLength = 0;
    Double_t td1TrackLength = 0;
    Int_t td1slat = 0;
    if (fInBfs) {
       BrFsTrack* t = (BrFsTrack*)track[h];
       if (!t->GetD1SwimStatus()) continue;
       proj = t->GetProjOnTof2(); 

       if(fUseTd1Time) {
          if(td1hit[h]) {
             BrFfsTrack *ffsTrack = ((BrFsTrack*)t)->GetFfsTrack();
             BrBfsTrack *bfsTrack = ((BrFsTrack*)t)->GetBfsTrack();

//We have to do following this way because there are some events
//in which there is no ffsTrack in the BrFsTrack.  I don't understand
//that.  Needs investigation. KH 25-APR-2002.  In any case,
//don't set td1slat if either track is missing.
             if(ffsTrack) ffsTrackLength = ffsTrack->GetPartialPath();
             if(bfsTrack) bfsTrackLength = bfsTrack->GetPathLength();
             td1TrackLength = td1hit[h]->GetLength();
             length = ffsTrackLength + bfsTrackLength + td1TrackLength;
             if(ffsTrack && bfsTrack) td1slat  = td1hit[h]->GetSlat();
             T0 = td1hit[h]->GetTime();
             }
          }
       else {
          length = t->GetPathLength();
          }
      moverp = 0.1395679/t->GetMomentum();
      trkVtx = t->GetTrackVertex();
      chksig = ((BrRichPid*)chkPid[h])->GetMass();
      if (TMath::Abs(chksig - fRichPionMass) > fRichMassCut) continue;
    }

    // check track vertex (want only primary tracks)
    // (only if vertex from Bb available.
    //
    Float_t x = (trkVtx(0) - fTrkOffset[0])/fTrkCut[0];
    Float_t y = (trkVtx(1) - fTrkOffset[1])/fTrkCut[1];
    Float_t z = (trkVtx(2) - Z0 - fTrkOffset[2])/fTrkCut[2];
    if (fUseBbVertex && (x*x + y*y + z*z > 1))
      continue;

    if(HistOn()){
      fhVtxCutY->Fill(x);
      fhVtxCutY->Fill(y);
      fhVtxCutZ->Fill(z);
    }

    // --------------------------------------------
    Int_t   slat = tofHit[h]->GetSlatno();
    Float_t ttg  = fCalibration->GetTopTdcGain(slat);
    Float_t btg  = fCalibration->GetBotTdcGain(slat);
    Float_t effc = fCalibration->GetEffSpeedOfLight(slat);
    Float_t del  = fCalibration->GetDeltaDelay(slat);

    if(fRequireAdc){
      Float_t tped = fCalibration->GetTopPedestal(slat);
      Float_t bped = fCalibration->GetBotPedestal(slat);
      Float_t tag0 = fCalibration->GetTopAdcGain(slat);
      Float_t bag0 = fCalibration->GetBotAdcGain(slat);
      Float_t  tener = (tofHit[h]->GetAdcUp() - tped)/tag0;
      Float_t  bener = (tofHit[h]->GetAdcDown() - bped)/bag0;
      Info(10,"Event","tener = %f, bener = %f, thresh = %f, top max = %f",tener,bener,fEnergyThreshold,fMaxEnergy);
      if (tener < fEnergyThreshold || bener < fEnergyThreshold ||
	  tener > fMaxEnergy       || bener > fMaxEnergy)
	continue;
    }
    
    Double_t tTime = tofHit[h]->GetTdcUp()*ttg;
    Double_t bTime = tofHit[h]->GetTdcDown()*btg;

    // hit position along y
    
    Double_t yHit = (bTime - tTime - del)*effc/2.;
    Double_t yTrk = proj(1);
    
    fDeltaY->Fill(yTrk - yHit);

    if (TMath::Abs(yHit - yTrk) > fMaxDy)
      continue;
    
    fDeltaYCut->Fill(slat, yTrk - yHit);
    
    // fill histos for time offset
    
    // will align all the stuff to beta = p/sqrt(p^2 + m^2) with 
    // p = momentum, m = pion mass. This means that their 
    // tof will be aligned with t = L/(c beta), L being the path length
    //
    // t_not_cal = t + off  => off = t_not_cal - t 
 
    Double_t tTheor = length/BrUnits::c_light * TMath::Sqrt(moverp*moverp+1);

    if (DebugLevel() > 10)
      cout << " Track path length + Z0: " << length + Z0 << endl;

    Float_t tnc = 0.5*(tTime+bTime) - T0;
    fOffset[slat-1]->Fill(tnc - tTheor);

    if(DebugLevel()>10){
      cout << "Vtx" << trkVtx << endl;
      cout << "Slat " << slat << " " << length << endl;
      cout << 0.5*(tTime+bTime) << " " << T0 << " " << tnc <<" "<<tTheor;
      cout <<" " << tnc-tTheor<<endl;
    }
    


  }
}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::Finish()
{
  //-----------------------------------------------------------
  // Fit histos with gaus
  //-----------------------------------------------------------

  // Job-level finalisation
  SetState(kFinish);
  
  // if load ascii mode
  if (fLoadAscii) 
    return;

  // if commit mode
  if (fCommitAscii) {
    ReadAscii();
    return;
  }

  // -------------------
  
  TF1* f = new TF1("fit", "gaus", -100, 0);
  cout << GetName() << ": Fitting time with gaus..." << endl;
  
  if (Verbose())
    cout << " Tube   |   Slat   |   Offset   |   Sigma  " << endl;
  
  for(Int_t i = 1; i <= fParamsTof->GetNoSlats() ; i++) {
    if (!fValidSlat[i-1])
      continue;

    if(fOffset[i-1]->GetEntries() < 20 )
      continue;

    // ---- top tubes 
    Int_t binAtMax  = fOffset[i-1]->GetMaximumBin(); // bin number at max
    Axis_t tofAtMax = fOffset[i-1]->GetBinCenter(binAtMax);
    
    f->SetParameters(fOffset[i-1]->GetMaximum(), tofAtMax, 
		     fOffset[i-1]->GetRMS());
    
    fOffset[i-1]->Fit("fit", "Q0L", "", 
		      tofAtMax - fFitWindow, tofAtMax + fFitWindow);
    
    Double_t offset = f->GetParameter(1);    
    Double_t sigma  = f->GetParameter(2);
    
    if (Verbose())
      cout << "  top " << setw(8) << i << " " 
	   << setw(10) << setprecision(4) << offset << " "
	   << setw(10) << setprecision(4) << sigma  << endl;

    if(TMath::IsNaN(offset)){
      fOffsetSummary->Fill(i, -1111);
      fSigmaSummary->Fill(i, -1111);
    }
    else{
      fOffsetSummary->Fill(i, offset);
      fSigmaSummary->Fill(i, sigma);
    }
    
    // set parameters for eventual commit into DB
    fCalibration->SetTimeOffset(i, offset);
    
    //-----------------------------------------------------------------------
  }
  
  // save calibration to ascii file
  if (fSaveAscii)
    SaveAscii();
}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::SaveAscii() 
{
  
  // save pedestal to ascii file
  
  BrRunInfoManager* runMan = BrRunInfoManager::Instance();
  Int_t* runs = runMan->GetRunNumbers();
  Int_t  nrun = runMan->GetNumberOfRuns();

  
  BrTofCalModule::SaveAscii();
  
  ofstream file(fCalibFile.Data(), ios::out);
  
  file << "****************************************** " << endl;
  file << "*  Calibration for Tof detector " << GetName() << endl;
  file << "*  Time Offsets           " << endl;
  file << "*     Used events from run(s) ";
  for (Int_t r = 0; r < nrun; r++) file << runs[r] << " ";
  file << endl;
  file << "****************************************** " <<endl;
  file << "*" << endl;    
  file << "* slat  |  time offset " << endl;
  file << "* ---------------------" << endl << endl;
  
  for (Int_t i = 0; i < fParamsTof->GetNoSlats(); i++) {
    Int_t slat = i + 1;
    file << setw(4) << slat 
	 << setw(15) << fCalibration->GetTimeOffset(slat) 
	 << endl;
  }
  
  file << "* ------------------------------------" << endl << endl;
  
}


//____________________________________________________________________
 void BrTofTimeOffsetCalModule::ReadAscii() 
{
  
  BrTofCalModule::ReadAscii();
  
  ifstream file(fCalibFile.Data(), ios::in);
  
  if (!file) {
    Stop("ReadAscii", "File %s was not found", fCalibFile.Data());
    return;
  }
  
  Float_t tp1, tp2, bp1, bp2, toff, boff;
  Int_t slat;
  Char_t comment[256];
  
  file.getline(comment, 256);
  while(comment[0] == '*') {
    file.getline(comment, 256);
    if (DebugLevel() > 5)
      cout << comment << endl;
  } 

  for (Int_t i = 1; i <= fParamsTof->GetNoSlats(); i++) {
    file >> slat >> toff;
    fCalibration->SetTimeOffset(slat, toff);
    
    if (DebugLevel() > 5)
      cout << setw(4)  << slat 
	   << setw(12) << toff << setw(12) << boff << endl;
    
  }

  fCalibration->SetComment("timeOffset", fComment.Data());

}

//____________________________________________________________________
 void BrTofTimeOffsetCalModule::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 $" << endl  
         << "    $Date $"   << endl 
         << "    $Revision $ " << endl  
         << endl 
         << "-------------------------------------------------" << endl;
}

//____________________________________________________________________
//
// $Log: BrTofTimeOffsetCalModule.cxx,v $
// Revision 1.16  2002/08/30 16:16:40  hagel
// Added more verbose diagnostics
//
// Revision 1.15  2002/08/06 19:05:39  hagel
// Re-implement offset calibration for TOF2
//
// Revision 1.14  2002/07/01 16:01:38  hagel
// Implement td1 timing ala pp for H2 calibration
//
// Revision 1.13  2002/06/19 17:33:12  videbaek
// Add abs for momentumcut (mrs) and incease bin size
//
// Revision 1.12  2002/06/13 21:57:54  brahmlib
// Include declaration of vector.h at top
//
// Revision 1.11  2002/06/13 19:24:15  videbaek
// mny modification to timeoffset and slewing modules.
// a) Offset module modified to deal with pp running and Td1, TMrsF start counters.
// b) The  slewing and offset mdoule now has similar cuts in pid, vertex cuts
//    and momentmu cut.
// c) The mrs code had a momentum cut introduced to not contaminate dt spectra with
//    the kaon's and protons.
// d) The slewing modules have added the method to fit  the hits using minuit rather than
//    2D histograms. the old method is kept for consistency (at least a while). As for
//    all slwing data correction rather large statistics is needed.
// e) Note that when using slewing the timeoffsets are still important!!! the first term in the
//    slweing is only a relative term taking into account the offsets created by the 1/sqrt(A) terms.
//    This implies that the same offsets are valid w and /wo slewing being done.
//
// Revision 1.10  2002/04/09 02:03:10  ouerdane
// use BrFsTrack instead of BrBfsTrack for H2 calibration
//
// Revision 1.9  2002/03/21 15:04:25  ouerdane
// added fComment member to base class module and method SetComment so that 
// the user can set comments about the calibration at commit time. 
// Removed mean momentum stuff in slewing cal module
//
// Revision 1.8  2002/02/13 17:15:35  ouerdane
// Removed something conceptually wrong that in practice didn't matter so much
// in the FS but did in the MRS: all reference to a mean momentum and therefore
// a mean beta alignement has been removed.
//
// The idea is to evaluate from the real momentum, track length and 
// assuming the track to be a pion, the theoretical time of flight and 
// substract the experimental one to this value. since a large fraction of 
// particles are pions, the result is a sharp peak corresponding to the offset.
// In the FS, the cherenkov pid is done prior to this calibration to minimize 
// the contamination with other particle species. In the MRS, we still have a 
// tail but doesn't really make any problem.
// This procedure was compared with the previous and gives much better results 
// for slats in the outer panels (low momentum particles).
//
// Revision 1.7  2001/12/20 15:32:36  ouerdane
// modified module for H2 according to the changes in the BfsTrack class
//
// Revision 1.6  2001/11/12 18:47:24  ouerdane
// modified the time offset module so that there's only one single offset per slat
//
// Revision 1.5  2001/11/07 10:30:55  ouerdane
// updated module for H2 cal. and PID
//
// Revision 1.4  2001/11/05 06:59:17  ouerdane
// added new classes for time offsets (without slewing)
//




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