BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//____________________________________________________________________
// 
// Class BrTpcPadStatusCalModule
//
// This module estimates the error in x and y for hits in the Tpc
//
// INPUT : The module needs raw TPC data as input
//
// IDEA  : Inspired bu JIJ tpc online monitor
// 
// HOW TO USE MODULE : 
//

//____________________________________________________________________
//
// $Id: BrTpcPadStatusCalModule.cxx,v 1.5 2002/08/19 09:47:30 pchristi Exp $
// $Author: pchristi $
// $Date: 2002/08/19 09:47:30 $
// $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

#ifndef BRAT_BrTableNames
#include "BrTableNames.h"
#endif
#ifndef BRAT_BrTpcPadStatusCalModule
#include "BrTpcPadStatusCalModule.h"
#endif
#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef BRAT_BrDataTable
#include "BrDataTable.h"
#endif
#ifndef BRAT_BrRunInfoManager
#include "BrRunInfoManager.h"
#endif
#ifndef BRAT_BrCalibration
#include "BrCalibration.h"
#endif
#ifndef BRAT_BrException
#include "BrException.h"
#endif
#ifndef BRAT_BrTpcSequence
#include "BrTpcSequence.h"
#endif

//____________________________________________________________________

ClassImp(BrTpcPadStatusCalModule);

//____________________________________________________________________
 BrTpcPadStatusCalModule::BrTpcPadStatusCalModule()
  : BrTpcCalModule()
{
  // Default constructor. DO NOT USE
  SetState(kSetup);

  // Set default parameters
  SetColdAdc();
  SetHotAdc();
  SetPadEdgeCut();
  SetTimeLowCut();
  SetTimeHighCut();
}

//____________________________________________________________________
 BrTpcPadStatusCalModule::BrTpcPadStatusCalModule(const Char_t* name, 
						 const Char_t* title)
  : BrTpcCalModule(name, title)
{
  // Named Constructor
  SetState(kSetup);

  // Set default parameters
  SetColdAdc();
  SetHotAdc();
  SetPadEdgeCut();
  SetTimeLowCut();
  SetTimeHighCut();
}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::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;  
  }
  
  TDirectory* saveDir = gDirectory; 
  
  fHistDir = gDirectory->mkdir(Form("%sPadStatus",GetName())); 
  fHistDir->cd();
  
  const Int_t nPads    = fParamsTpc-> GetPadsprow();
  const Int_t nRows    = fParamsTpc->GetNumberOfRows();
  const Int_t nBuckets = fParamsTpc->GetNoBuckets();
  
  hAverageAdcVsTimeHelp = new TH1F(Form("hHelp%s", GetName()),
				   "Dummy histogram",
				   nBuckets, 0, nBuckets);

  hAverageAdcVsTime = new TProfile(Form("hAverageAdcVsTime%s", GetName()),
				   "Dummy histogram",
				   nBuckets, 0, nBuckets);
  
  hAverageAdc     = new TProfile*[nRows];
  hAverageAdcHelp = new TH1F*[nRows];
  hMaxAdc         = new TProfile*[nRows];
  hMaxAdcHelp     = new TH1F*[nRows];
  
  for(Int_t i = 0; i < nRows; i++) {
    
    hAverageAdc[i] = new TProfile(Form("hAverageAdc_row%d%s", i+1, GetName()), 
				  Form("%s: Average ADC. Row %d", 
				       GetName(), i+1),
				  nPads, 0, nPads);
    hAverageAdc[i]->SetXTitle( "Average ADC" );
    hAverageAdc[i]->SetYTitle( "Pad" );
    
    hAverageAdcHelp[i] = new TH1F(Form("hAverageAdc_row%d%shelp", 
				       i+1, GetName()), 
				  "Dummy", nPads, 0, nPads);
    
    hMaxAdc[i] = new TProfile(Form("hMaxAdc_row%d%s", i+1, GetName()), 
			      Form("%s: Max ADC. Row %d", 
				   GetName(), i+1),
			      nPads, 0, nPads);
    hMaxAdc[i]->SetXTitle( "Max ADC" );
    hMaxAdc[i]->SetYTitle( "Pad" );
    
    hMaxAdcHelp[i] = new TH1F(Form("hMaxAdc_row%d%shelp", 
				   i+1, GetName()), 
			      "Dummy", nPads, 0, nPads);
  }
  
  // Histograms
  gDirectory = saveDir;
}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::Init()
{
  // Job-level initialisation
  SetState(kInit);
  
  // base class initialization (register calibration parameters)
  BrTpcCalModule::Init();
  
  BrCalibration::EAccessMode mode = BrCalibration::kRead;
  
  try{
    // check if we want to load adc gain cal from ascii file
    if (fLoadAscii) {
      
      mode = BrCalibration::kTransitional;
    } else {
      
      mode = BrCalibration::kWrite;
    }
    
    const Int_t nPads = fParamsTpc-> GetPadsprow();
    const Int_t nRows = fParamsTpc->GetNumberOfRows();
    
    fCalibration->Use(BrTpcCalibration::kInstrumentedRows, mode, nRows);
    fCalibration->Use(BrTpcCalibration::kPadStatus,        mode, nPads*nRows);
  }
  catch(BrException* e) {
    cerr << "BrTpcPadStatusCalModule::Init : " << *e << endl;
    e->Execute();
  }

}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::Begin()
{
  // Run-level initialisation
  SetState(kBegin);
  
  if (fLoadAscii) {
    ReadAscii();
    SetPadStatus();
    return;
  }
  
  if (!HistBooked())
    if (!fCommitAscii) {
      Abort("Begin", "Need histos for calibration");
      return;
    }
  
  // check if we got parameter revisions:
  if (!fCalibration->RevisionExists(BrTpcCalibration::kInstrumentedRows) || 
      !fCalibration->RevisionExists(BrTpcCalibration::kPadStatus)) {
    Abort("Begin", 
	  "Some calibration revision are missing! BrDbUpdateModule ?");
    return;
  }
  
}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::Event(BrEventNode* inNode, BrEventNode* outNode)
{
  // Per event method
  SetState(kEvent);
  
  if (fCommitAscii || fLoadAscii)
    return;
  
  // Get the data table with the tpc tracks
  BrDataTable *inputTable = 
    inNode->GetDataTable(Form("%s %s", BRTABLENAMES kTPCSequence, GetName()));
  
  if(!inputTable) {
    
    if(DebugLevel())
      Warning("Event", "Table was not found : %s %s ", BRTABLENAMES kTPCSequence, GetName());
    return;
  }
  
  //
  // reset the help histograms
  //
  hAverageAdcVsTimeHelp->Reset();
  
  const Int_t nRows = fParamsTpc->GetNumberOfRows();
  
  for(Int_t i = 0; i < nRows; i++) {
    
    hAverageAdcHelp[i]->Reset();
    hMaxAdcHelp[i]->Reset();
  }
  
  //
  // loop over tpc sequences
  //
  const Int_t nSeqs = inputTable->GetEntries();
  
  if(DebugLevel())
    cout << "Number of sequences : " << nSeqs << endl;
  
  if(nSeqs==0)
    return;
  
  // Fill the help histograms
  // remember that pads are 0-based!!!!!
  
  for(Int_t i = 0; i < nSeqs; i++) {
    
    BrTpcSequence *seq = (BrTpcSequence*)inputTable->At(i);
    
    const Int_t row  = seq->GetRow();
    const Int_t pad  = seq->GetPad();
    const Int_t startTime = seq->GetTime();
    const Int_t nBuckets = seq->GetNseq();

    for(Int_t j = 0; j < nBuckets; j++) {
      
      Int_t time = startTime + j;
      const Float_t adc = seq->GetAdc(j);
      
      hAverageAdcVsTimeHelp->Fill(time, adc);

      if(time < fTimeLowCut || time > fTimeHighCut)
      	continue;

      hAverageAdcHelp[row-1]->Fill(pad+0.5, adc);

      if(adc > hMaxAdcHelp[row-1]->GetBinContent(pad+1))
	hMaxAdcHelp[row-1]->SetBinContent(pad+1, adc);
    }

  }

  // Fill the real histograms using the help histograms 

  const Int_t nPads = fParamsTpc->GetPadsprow();

  for(Int_t i = 0; i < nRows; i++) {
    
    for(Int_t j = 0; j < nPads; j++) {
      
      hAverageAdc[i]->Fill(Float_t(j)+0.5, 
			   hAverageAdcHelp[i]->GetBinContent(j+1));
      hMaxAdc[i]->Fill(Float_t(j)+0.5,
		       hMaxAdcHelp[i]->GetBinContent(j+1));
    }
  }

  for(Int_t j = 0; j < nPads; j++)
    hAverageAdcVsTime->Fill(Float_t(j)+0.5,
			    hAverageAdcVsTimeHelp->GetBinContent(j+1));
  
}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::Finish()
{
  // Job-level finalisation
  // This is very the fit to the histograms are done and the output
  // and commit is done
  SetState(kFinish);
  
  // if load ascii mode
  if (fLoadAscii) 
    return;
  
  // if commit mode
  if (fCommitAscii) {
    ReadAscii();
    return;
  }
  
  if (fSaveAscii) {
    const Int_t nPads = fParamsTpc-> GetPadsprow();
    const Int_t nRows = fParamsTpc->GetNumberOfRows();

    // loop over average histograms and find non instrumented rows
    Int_t   nInstrumented = 0;
    Float_t averageSum    = 0;
    Float_t maxSum        = 0;
    
    for(Int_t i = 0; i < nRows; i++) {
      
      const Int_t row = i + 1;
      Bool_t isInstrumented = kFALSE;
      
      // delete the dummy histograms
      delete hAverageAdcHelp[i]; 
      hAverageAdcHelp[i] = 0;
      delete hMaxAdcHelp[i]; 
      hMaxAdcHelp[i] = 0;
      
      for(Int_t j = 0; j < nPads; j++) {
	
	if(hAverageAdc[i]->GetBinContent(j+1) == 0) {
	  
	  fCalibration->SetPadStatus(row, j, 
				     BrDetectorParamsTPC::kPadNotInstrumented);
	} else {
	  
	  fCalibration->SetPadStatus(row, j, 
				     BrDetectorParamsTPC::kPadActive);
	  isInstrumented = kTRUE;

	  nInstrumented++;
	  averageSum += hAverageAdc[i]->GetBinContent(j+1);
	  maxSum     += hMaxAdc[i]->GetBinContent(j+1);
	}
      }
	
      if(isInstrumented)
	fCalibration->SetInstrumentedRows(row, 1);
      else
	fCalibration->SetInstrumentedRows(row, 0);
    }

    // delete dummy histogram arrays
    delete [] hAverageAdcHelp; 
    hAverageAdcHelp = 0;
    delete [] hMaxAdcHelp; 
    hMaxAdcHelp = 0;
    delete hAverageAdcVsTimeHelp;
    hAverageAdcVsTimeHelp = 0;
    
    // Now scale histograms with one over the overall average 
    // of instrumented pads
    Float_t meanAverageScale = Float_t(nInstrumented)/averageSum; 
    Float_t meanMaxScale     = Float_t(nInstrumented)/maxSum;

    // In the next step we scale the histograms with the calculated weight 
    // and makes a secons step where we remove outliers from the weight factor 
    // to make sure that they have no influence on the level of the histograms 

    Int_t nAverage = 0;
    Int_t nMax     = 0;
    averageSum     = 0;
    maxSum         = 0;

    for(Int_t i = 0; i < nRows; i++) {
      
      const Int_t row = i+1;

      if(!fCalibration->GetInstrumentedRows(row))
	continue;

      hAverageAdc[i]->Scale(meanAverageScale);
      hMaxAdc[i]->Scale(meanMaxScale);
      
      // Now loop to remove thos pads with very large signals
      // from the average scaling
      
      for(Int_t j = 0; j < nPads; j++) {

	if(hAverageAdc[i]->GetBinContent(j+1) > 0.0 &&
	   hAverageAdc[i]->GetBinContent(j+1) < 2.0) {

	  nAverage++;
	  averageSum += hAverageAdc[i]->GetBinContent(j+1);
	}

	if(hMaxAdc[i]->GetBinContent(j+1) > 0.0 &&
	   hMaxAdc[i]->GetBinContent(j+1) < 2.0) {

	  nMax++;
	  maxSum += hMaxAdc[i]->GetBinContent(j+1);
	}
      }
    }

    meanAverageScale = Float_t(nAverage)/averageSum; 
    meanMaxScale     = Float_t(nMax)/maxSum;
 
    for(Int_t i = 0; i < nRows; i++) {
      
      const Int_t row = i+1;

      if(!fCalibration->GetInstrumentedRows(row))
	continue;

      hAverageAdc[i]->Scale(meanAverageScale);
      hMaxAdc[i]->Scale(meanMaxScale);

      // Now loop to find cold or dead pads defined as
      // cold : AverageAdc(normalised) < fColdAdc (default = 0.2)
      // hot  : AverageAdc(normalised) > fHotAdc  (default = 3)
      
      for(Int_t j = 0; j < nPads; j++) {
	
	if(fCalibration->GetPadStatus(row, j) ==
	   BrDetectorParamsTPC::kPadNotInstrumented) 
	  continue;
	
	// note that cuts are defined like this because pads
	// are 0 based, i.e., numbered starting from 0
	if(j < fPadEdgeCut || nPads-(j+1) < fPadEdgeCut) {

	  fCalibration->SetPadStatus(row, j,
				     BrDetectorParamsTPC::kPadDead);
	  continue;
	}

	const Double_t maxAdcNorm = hMaxAdc[i]->GetBinContent(j+1);
	
	if(maxAdcNorm < fColdAdc)
	  fCalibration->SetPadStatus(row, j,
				     BrDetectorParamsTPC::kPadDead);
	else if (maxAdcNorm > fHotAdc)
	      fCalibration->SetPadStatus(row, j,
					 BrDetectorParamsTPC::kPadDead);
      }
    }
    
    SaveAscii();
  }
}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::SaveAscii() 
{
  // save pedestal to ascii file
  
  BrRunInfoManager* runMan = BrRunInfoManager::Instance();
  const BrRunInfo*     run = runMan->GetCurrentRun();
  if (run->GetRunNo() == -1) {
    Stop("SaveAscii", "RunInfo has run number = -1");
    return;
  }
  
  BrTpcCalModule::SaveAscii();
  
  ofstream file(fCalibFileName.Data(), ios::out);
  
  file << "****************************************** " << endl;
  file << "*  Calibration for Tpc detector " << GetName() << endl;
  file << "*  Hit Width calibration         " << endl;
  file << "*  Used events from run " << run->GetRunNo() << endl;
  file << "****************************************** " <<endl;
  file << "*" << endl;    
  file << "* Instrumented Rows and Pad status" << endl;
  file << "* --------------------------------" << endl << endl;
  
  const Int_t nRows = fParamsTpc->GetNumberOfRows();
  const Int_t nPads = fParamsTpc->GetPadsprow();
  
  // write instrumented rows
  
  for (Int_t i = 0; i < nRows; i++) {
    
    const Int_t row = i + 1;
    file << setw(3)  << row 
	 << setw(10) << fCalibration->GetInstrumentedRows(row) << endl;
  }
  
  // write pad status
  
  for (Int_t i = 0; i < nRows; i++) {
    
    const Int_t row = i+1;
    file << setw(3)  << row;
      
      for(Int_t j = 0; j < nPads; j++) {
	
	file << setw(2) << fCalibration->GetPadStatus(row, j);
      }
    
    file << endl;
  }
  
  file << "* ------------------------------------" << endl << endl;
}


//____________________________________________________________________
 void BrTpcPadStatusCalModule::ReadAscii() 
{
  // read calibration from file created by this module
  
  BrTpcCalModule::ReadAscii();
  
  ifstream file(fCalibFileName.Data(), ios::in);
  
  if (!file) {
    Stop("ReadAscii", "File %s was not found", fCalibFileName.Data());
    return;
  }
  
  Char_t comment[256];
  
  file.getline(comment, 256);
  while(comment[0] == '*') {
    file.getline(comment, 256);
    if (DebugLevel() > 5)
      cout << comment << endl;
  } 
  
  const Int_t nRows = fParamsTpc->GetNumberOfRows();
  const Int_t nPads = fParamsTpc->GetPadsprow();
  
  // write instrumented rows
  
  Int_t row, dummy;

  for (Int_t i = 0; i < nRows; i++) {
    
    file >> row >> dummy;
    fCalibration->SetInstrumentedRows(row, dummy);
    //    cout << "Row, Dummy : " << row << ", " << dummy << endl;
  }
  
  // write pad status

  for (Int_t i = 0; i < nRows; i++) {
    
    file >> row; 
    //    cout << "Row : " << row;
    
    for(Int_t j = 0; j < nPads; j++) {
      
      file >> dummy;
      //      cout << setw(3) << i << "/ " << nPads << " : " << dummy << endl;
      fCalibration->SetPadStatus(row, j, dummy);
    }
  }

  fCalibration->SetComment(BrTpcCalibration::kInstrumentedRows,
			   "Generated by BrTpcPadStatusCalModule: "
			   "Some pads in row have non-zero ADC values");
  fCalibration->SetComment(BrTpcCalibration::kPadStatus,
			   "Generated by BrTpcPadStatusCalModule: "
			   "Determined by comparing pad to Tpc average");
}

//____________________________________________________________________
 void BrTpcPadStatusCalModule::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: pchristi $" << endl  
         << "    $Date: 2002/08/19 09:47:30 $"   << endl 
         << "    $Revision: 1.5 $ " << endl  
         << endl 
         << "-------------------------------------------------" << endl;
}

//____________________________________________________________________
//
// $Log: BrTpcPadStatusCalModule.cxx,v $
// Revision 1.5  2002/08/19 09:47:30  pchristi
// Added old changes to calibration modules.
//
// Revision 1.4  2002/04/11 12:27:53  pchristi
// Moved annoying cout statements to a DebugLevel() > 10 statement.
//
// Revision 1.3  2002/01/03 19:51:11  cholm
// Prepared to use BrTableNames class (or perhaps BrDetectorList) for table names
//
// Revision 1.2  2001/11/02 13:38:54  pchristi
// Added new module for calibrating drift velocities using the fibres behind
// T2 and in front of T1.
// Updated old modules with small changes.
//
// Revision 1.1  2001/10/12 11:08:50  pchristi
// Added new directory tpc. Added the first calibration modules. They
// have all been tested and found to work. The algorithms might not be
// optimal, but are at least fully automatic and to some extent
// documented.  CVS:
// ----------------------------------------------------------------------
// BrTpcCalModule.cxx BrTpcCalModule.h CVS: BrTpcHitWidthCalModule.cxx
// BrTpcHitWidthCalModule.h CVS: BrTpcPadStatusCalModule.cxx
// BrTpcPadStatusCalModule.h CVS: BrTpcTimeCalModule.cxx
// BrTpcTimeCalModule.h Include.h CVS: LinkDef.h Makefile.am CVS:
// ----------------------------------------------------------------------
//
// Revision 1.3  2001/10/11 11:27:25  pchristi
// Near final version
//
// Revision 1.2  2001/10/11 09:13:52  pchristi
// Almost finished Pad status
//
// Revision 1.1  2001/10/10 21:12:26  pchristi
// Added pad status module
//
// Revision 1.2  2001/10/10 16:52:16  pchristi
// New module ready for testing
//

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