BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
//____________________________________________________________________
//
// Module to create reduce data objects form detector digits for the
// silicon strip detectors in the multiplicity array. 
//
// The calculations is based on what Steve Sanders and Hiro Ito wrote
// in BAN26
// However, the centrality calculations are seperated out in a special
// module BrSiCentModule, as outline in BAN22
//

//____________________________________________________________________
// $Id: BrSiRdoModule.cxx,v 1.18 2002/05/08 16:30:59 cholm Exp $
// $Author: cholm $
// $Date: 2002/05/08 16:30:59 $
// $Copyright: 2001 BRAHMS Collaboration <brahmlib@rhic.bnl.gov>
//
#ifndef ROOT_TDirectory
#include "TDirectory.h"
#endif
#ifndef BRAT_BrSiRdoModule
#include "BrSiRdoModule.h"
#endif
#ifndef BRAT_BrSiDig
#include "BrSiDig.h"
#endif
#ifndef BRAT_BrEventNode
#include "BrEventNode.h"
#endif
#ifndef BRAT_BrTableNames
#include "BrTableNames.h"
#endif
#ifndef BRAT_BrBbRdo
#include "BrBbRdo.h"
#endif
#ifndef BRAT_BrZdcRdo
#include "BrZdcRdo.h"
#endif
#ifndef BRAT_BrVertex
#include "BrVertex.h"
#endif
#ifndef BRAT_BrParameterDbManager
#include "BrParameterDbManager.h"
#endif
#ifndef BRAT_BrCalibrationManager
#include "BrCalibrationManager.h"
#endif
#ifndef BRAT_BrDetectorList
#include "BrDetectorList.h"
#endif
#ifndef BRAT_BrSiParameters
#include "BrSiParameters.h"
#endif
#ifndef BRAT_BrSiCalibration
#include "BrSiCalibration.h"
#endif
#include <iostream.h>
#include <iomanip.h>
#include <limits.h>
#include <float.h>
#include <math.h>
//____________________________________________________________________
ClassImp (BrSiRdoModule);

//____________________________________________________________________
 BrSiRdoModule::BrSiRdoModule (const Char_t *name,
			      const Char_t *title)
  : BrMultRdoModule(name, title)
{
  // Everyhting is done in BrMultRdoModule CTOR
  SetState(kSetup);
  SetThresholdFactor();
  SetSaturationChannel();
  SetUsePathLengthCor();
  fSingleAdcLow = 0;
  fSingleAdcHigh = 2000;
  fSingleAdcComp = 10;
  fBaseCalAdc = 400;
  fBaseMult   = 200;
  fBaseEnergy = .0006;
}

//____________________________________________________________________
 void BrSiRdoModule::Init() 
{
  // 
  SetState(kInit);
  
  // Detector paramters 
  BrParameterDbManager* paramManager = BrParameterDbManager::Instance();
  fParameters = (BrSiParameters*) 
    paramManager->GetDetectorParameters("BrSiParameters",
					GetName());
  if(!fParameters)
    Failure("Init", "no DetectortParameters");

  // Calibrations 
#ifdef BR_MULT_CAL_TMP
  fCalibration = BrSiTmpCalibration::Instance();
#else 
  BrCalibrationManager *manager = 
    BrCalibrationManager::Instance();

  fCalibration = static_cast<BrSiCalibration*>
    (manager->Register("BrSiCalibration", 
		       BrDetectorList::GetDetectorName(kBrSi)));
#endif 
  if (!fCalibration) 
    Failure("Init", "didn't get calibration from manager");

  fCalibration->Use("pedestal");
  fCalibration->Use("pedestalWidth");
  // I think we need to flag this parameter, but I'm not really sure. 
  fCalibration->Use("adcGap");
  fCalibration->Use("adcGain");
  fCalibration->Use("conversionFunc");
  // These are geometry things proper, but put here for now, until a
  // concensus  of how to do the geometry database. 
  fCalibration->Use("ringMap");
  fCalibration->Use("rowMap");
  fCalibration->Use("ringPostion");
  fCalibration->Use("tilt");
}

//____________________________________________________________________
 void BrSiRdoModule::Event(BrEventNode *inNode, BrEventNode *outNode)
{
  // 
  // 
  // 
  SetStatus(kOk);
  SetState(kEvent);
  if (Verbose() > 20) 
    cout << "Entering BrSiRdoModule::Event" << endl;
    
  TString tableName;
  tableName = "Dig";
  tableName += BrDetectorList::GetDetectorName(kBrSi);
  BrSiDig* dig = (BrSiDig*)inNode->GetObject(BRTABLENAMES kDigSi);
  if(!dig) {
    if (Verbose() > 0) // kShowFailures)
      Warning("Event", "couldn't get Si digits '%s'", tableName.Data());
    return;
  }

  // Try to make a Rdo in output node 
  tableName = "Rdo";
  tableName += BrDetectorList::GetDetectorName(kBrSi);
  BrMultRdo* rdo = new BrMultRdo(tableName.Data(), "RDO data for Sis");
  if (!rdo) {
    Abort("Event", "couldn't make a BrSiRdo object!");
    return;
  }
  // Add to output node
  outNode->AddObject(rdo);

  // Some temporary variables for bookkeeping and so on 
  Int_t     nRings           = fParameters->GetNoRings(); 

  // A loop variable, must be decalered here so that MSVC++/KCC
  // doesn't get confused - poor sods, they should stick to ANSI/ISO
  // standard, alias they don't! 
  Int_t     i                = 0;

  // Try to get a vertex. 
  fCurrentVtxZ = FindVertex(inNode, outNode);

  // For each ring, set the psuedo-rapidity 
  for (i = 0; i < nRings; i++) {
    fCurrentRing = i;
    BrMultRdo::BrRing* ring = rdo->AddRing(fCurrentRing);
    fCurrentRingZ  = fCalibration->GetRingPosition(fCurrentRing);         
    fCurrentRingR  = fCalibration->GetRingRadius(fCurrentRing);
    Double_t ringScale;
    ring->SetEta(CalibrateAvgEta(ringScale));
    ring->SetHits(0);
    ring->SetCalibratedAdc(0);
    ring->SetEnergy(0);
    ring->SetMultiplicity(0);
  }
  
  // Calibrate the individual si data 
  CalibrateIndividual(dig, rdo);
  

  //__________________________________________________________________
  //
  // End of basic calibrations 
  // 
  // If we didn't get a vertex, we might as well drop the rest,
  // since it depends on the vertex. 
  if (fCurrentVtxZ == FLT_MAX) {
    if (Verbose() > 10) 
      Warning("Event", "exiting halfways through because no vertex");
    return;
  }

  //__________________________________________________________________
  //
  // Calibrate the ring energies and multiplicities 
  CalibrateRings(rdo);
  


  //__________________________________________________________________
  //
  // Calibrate the array energy and multiplicity 
  //
  CalibrateArray(rdo); 

  if (DebugLevel() > 25) 
    rdo->Print("air");  
  else if (DebugLevel() > 10 || Verbose() > 20) 
    rdo->Print("a");  
}

//__________________________________________________________________
 void BrSiRdoModule::CalibrateIndividual(BrSiDig*   dig, 
					BrMultRdo* rdo)
{
  // PRIVATE METHOD:
  // Make the caibrated data for the individual detector elements
  // i.e., each si. 
  //
  // Please note, that the digit data is currently passed as a
  // TObject, rather than a BrSiDig. This is so that we may read old
  // files with BrDigSis objects in them. It will soon disappear. 

  // A loop variable, must be decalered here so that MSVC++/KCC
  // doesn't get confused - poor sods, they should stick to ANSI/ISO
  // standard, alias they don't! 
  Int_t i = 0;
  
  // Get some parameters on this detector
  Int_t     nRows            = fParameters->GetNoRows(); 
  Int_t     nRings           = fParameters->GetNoRings(); 
  Int_t     nSingles         = fParameters->GetNoModules();

  // For each si, calibrate the ADC 
  for (i = 0; i < nSingles; i++) {
    fCurrentSingle   = i;
    fCurrentRing   = fCalibration->GetRingMap(fCurrentSingle) ;         
    fCurrentRing   = fCalibration->GetRingMap(fCurrentSingle) ;         

    // If the ring map says this si is bad, skip to next
    if (fCurrentRing < 0 || fCurrentRing > nRings || fCurrentRing > 100) {
      if (DebugLevel() > 15) 
	Warning("Event", "Ring map says si %d isn't on", 
		fCurrentSingle);
      continue;
    }
    BrMultRdo::BrSingle* single = rdo->AddSingle(fCurrentSingle);
    single->SetMultiplicity(0);
    // Some geometry 
    fCurrentRingZ  = fCalibration->GetRingPosition(fCurrentRing);         
    fCurrentRingR  = fCalibration->GetRingRadius(fCurrentRing);
    BrMultRdo::BrRing* ring = rdo->FindRing(fCurrentRing);
    if (!ring) {
      Failure("CalibrateSingle", "No ring for this single"); 
      return;
    }
    
    // Read the raw ADC value from digit 
    Int_t adc =dig->GetAdc(i + 1);

    // Fill ADC histogram 
    if (HistOn())
      fSingleAdcHisto->Fill(fCurrentSingle+1, adc);

    // If si is saturated, flag it as such. 
    // If single is saturated, flag it as such. 
    if (adc > fSaturationChannel) {
      // Maybe we should skip this single here? 
      if (DebugLevel() > 5) 
	Warning("CalibrateSingle", "channel %d is saturated (%d > %d)", 
		fCurrentSingle, adc, fSaturationChannel);
      single->SetSaturated(kTRUE);
    }
    
    //_______________________________________________________________
    // 
    // ADC calibrations 
    //
    // Calculate the calibrated ADC value 
    Bool_t   belowThreshold = kFALSE;
    Double_t singleCalAdc = CalibrateAdc(adc, belowThreshold);
    // Set the calibrated ADC in output. 
    single->SetCalibratedAdc(Int_t(singleCalAdc));
    // Fill CalAdc histogram 
    if (HistOn())
      fSingleCalAdcHisto->Fill(fCurrentSingle+1, singleCalAdc);
    if(!belowThreshold) {
      // Count total hist;
      rdo->SetArrayHits(rdo->GetArrayHits() + 1);
      // Count hits in ring
      ring->SetHits(ring->GetHits() + 1);
      // Accumelate sum calibrated ADC's 
      rdo->SetArrayCalibratedAdc(Int_t(rdo->GetArrayCalibratedAdc() +
				       singleCalAdc));
      // accumelate sum of calibrated ADCs in ring 
      ring->SetCalibratedAdc(Int_t(ring->GetCalibratedAdc() +
				   singleCalAdc)); 
    }
    //_______________________________________________________________
    //
    // End of basic calibrations 
    // 
    // If we didn't get a vertex, we might as well drop the rest,
    // since it depends on the vertex. 
    if (fCurrentVtxZ == FLT_MAX) {
      if (DebugLevel() > 10) 
      	cout << "Skipping Mult for si" << endl;
      continue; 
    }
    
    //_______________________________________________________________
    //
    // Energy calibrations 
    // 
    // correct for non-linear pulse shapers 
    Double_t singlePulser = CalibratePulser(singleCalAdc);
    if (singlePulser <= 0) {
      if (DebugLevel() > 5)
	Warning("CalibrateSingle", "channel %d has zero pulser, skipping", 
		fCurrentSingle);
      singlePulser = 0;
    }
      
    // Calculate the energy deposited in the si 
    Double_t singleEnergy = CalibrateEnergy(singlePulser);
    
      
    // Correction factor for vertex position with the factor
    // sin(theta). 
    Double_t distZ = fCurrentVtxZ - fCurrentRingZ; 
    Double_t singleEnergyCor = singleEnergy;
    if (fUsePathLengthCor) 
      singleEnergyCor *= fCurrentRingR /
	TMath::Sqrt(distZ * distZ + fCurrentRingR * fCurrentRingR);
    // Set the calibrated Energy in output. 
    single->SetEnergy(singleEnergyCor); 
    // Fill Energy histogram 
    if (HistOn()) 
      fSingleEnergyHisto->Fill(fCurrentSingle+1, singleEnergyCor);
    // accumelate sum of calibrated energy in ring 
    // Please note, that this is not the final energy. We need to do
    // outlier and vertex corrections, but we store the value in the
    // RDO module to save memory 
    ring->SetEnergy(ring->GetEnergy() + singleEnergyCor);
    // Dispite the misleading name, we store the sum square of the
    // energy over the rings, in the member
    // BrSingleRdo::fRingMultiplicity, so that we may save some space. 
    if (DebugLevel() > 30) 
      {
	cout << "  SMA "
	   << "Ch: " << setw(4) << fCurrentSingle << "  " 
	   << "ADC: " << setw(5) << adc << "  " 
	   << "CalADC: " << setw(7) << singleCalAdc << "  " 
	   << "E: " << setw(8) << 1E6*singleEnergyCor << "  " 
	   << "R: " << setw(7)<<fCurrentRingR<<" "
	   << "V: " << setw(7)<<fCurrentVtxZ<<" "
	   << "Z: " << distZ<<endl;
      }
    if(belowThreshold) 
      {
	singleEnergyCor = 0;
	singleEnergy = 0;
      }
    
    ring->SetMultiplicity(ring->GetMultiplicity() + 
			  singleEnergyCor * singleEnergyCor);

    //_______________________________________________________________
    //
    // Multiplicity calibrations 
    // 
    Double_t ringEta = ring->GetEta();
    Double_t singleMult = TMath::Max(0., singleEnergy *
				     CalibrateMultiplicity(ringEta));
    single->SetMultiplicity(singleMult);

    if (HistOn()) 
      fSingleMultHisto->Fill(fCurrentSingle+1, singleMult);

    
    if (DebugLevel() > 30) 
	cout << "  SMA "
	     << "Ch: " << setw(4) << fCurrentSingle << "  " 
	     << "ADC: " << setw(5) << adc << "  " 
	     << "CalADC: " << setw(5) << singleCalAdc << "  " 
	     << "E: " << setw(8) << singleEnergyCor << "  " 
	     << "M: " << setw(8) << singleMult << " "
	     << "R: " << fCurrentRingR<<" "
	     << "V: " << fCurrentVtxZ<<" "
	     << "Z: " << distZ<<endl;
  }
  
  // Fill histograms 
  if (HistOn()) {
    fArrayCalAdcHisto->Fill(rdo->GetArrayCalibratedAdc());
    fArrayHitsHisto->Fill(rdo->GetArrayHits());
    fVtxVsCalAdcHisto->Fill(fCurrentVtxZ, rdo->GetArrayCalibratedAdc());

    // Fill out hits and calibrated ADCs
    for (i = 0; i < nRings; i++) {
      fRingCalAdcHisto->Fill(i+1, rdo->GetRingCalibratedAdc(i));
      fRingHitsHisto->Fill(i+1, rdo->GetRingHits(i));
    }
  }
}

//__________________________________________________________________
 Double_t BrSiRdoModule::CalibratePulser(Double_t calAdc) 
{
  // This function was modified for the year 2 runs by allowing for
  // a zero offset of the pulser calibration.  This seems strange, but
  // is found necessary to get a good fit for low pulser signals.
  //
  //Year 1:
  // Correct for the non-linearity of the silicon pulse shapers. 
  // This is done be applying the following piecewise (fork) function 
  // 
  //
  //         / f1(x) = a*x+bx^2                           for x < l1
  //         | 
  //  f(x) = + f2(x) = f1(l1)+f1'(l1)*(x-l1) + c*(x-l1)^2 for x < l2
  //         |
  //          f3(x) = f2(l2)+f2'(l2)*(x-l2)              for x >= l2  
  // 
  // where a, b, c are calibration parameters. 
  // 
  //Year 2:
  // Correct for the non-linearity of the silicon pulse shapers. 
  // This is done be applying the following piecewise (fork) function 
  // 
  //
  //         / f1(x) = a + b*x+cx^2                       for x < l1
  //         | 
  //  f(x) = + f2(x) = f1(l1)+f1'(l1)*(x-l1) + d*(x-l1)^2 for x < l2
  //         |
  //          f3(x) = f2(l2)+f2'(l2)*(x-l2)              for x >= l2  
  // 
  // where a, b, c,d  are calibration parameters. 
  // 

  
  if (fCurrentSingle < 0) {
    if (DebugLevel() > 5)
      Warning("CalibratePulser","A null si %d", fCurrentSingle);
    return 0;
  }  
  Int_t order = fCalibration->GetPulserFuncOrder();
  if (order < 0) {
    if (DebugLevel() > 5)
      Warning("CalibratePulser","A null function");
    return 0;
  }

  // The pulser calibrations for the 130 GeV run 
  if(fCurrentRun && 
     fCurrentRun->GetRunNo() > 0 && 
     fCurrentRun->GetRunNo() < 3700) {
    
    // Limits of fits 
    Double_t limit1 = 25;
    Double_t limit2 = 400; 
    
    if (calAdc < limit1) {
      Double_t result = 
	fCalibration->GetPulserFuncPar(fCurrentSingle, 0) * calAdc
	+ fCalibration->GetPulserFuncPar(fCurrentSingle, 1) * calAdc *
	calAdc;
      if (DebugLevel() > 15) 
	cout << "Channel " << fCurrentSingle << " has pulser value (1) " 
	     << result << " (" << calAdc << ")" <<  endl;
      return result;
    }
      
      
    // Calculate first coefficient 
    Double_t a = 
      fCalibration->GetPulserFuncPar(fCurrentSingle, 0) * limit1 
      + fCalibration->GetPulserFuncPar(fCurrentSingle, 1) *
	TMath::Power(limit1, 2);  
    // Calculate second coefficient - looks like a derivative 
    Double_t b = 
      fCalibration->GetPulserFuncPar(fCurrentSingle, 0)
      + 2 * fCalibration->GetPulserFuncPar(fCurrentSingle, 1) * limit1;
    
    if (calAdc < limit2) {
      // return the corrected number 
      Double_t result = a + b * (calAdc - limit1) 
	+ fCalibration->GetPulserFuncPar(fCurrentSingle, 2) 
	* TMath::Power(calAdc - limit1,2);
      if (DebugLevel() > 15) 
	cout << "Channel " << fCurrentSingle << " has pulser value (1) " 
	     << result << " (" << calAdc << ")" <<  endl;
      return result;
    }
      
    // Calculate third coefficient - looks like a derivative
    Double_t c = b + 2 * fCalibration->GetPulserFuncPar(fCurrentSingle, 2) *
      (limit2 - limit1);
    // Calculate fourth coefficient - looks like a derivative
    Double_t d = a + b * (limit2 - limit1) +
      fCalibration->GetPulserFuncPar(fCurrentSingle, 2) * 
      TMath::Power(limit2 - limit1, 2);
    
    // return the corrected number 
    Double_t result = d  + c * (calAdc - limit2);
    if (DebugLevel() > 15) 
      cout << "Channel " << fCurrentSingle << " has pulser value (2) " 
	   << result << " (" << calAdc << ")" << endl;
    return result;
  }
  // The pulser calibrations for the 200GeV run in 2000

  // Limits of fits 
  Double_t limit1 = 25;
  Double_t limit2 = 250; 
  //cout<<"200 GeV analysis "<<fCurrentSingle<<" "
  //    <<fCalibration->GetPulserFuncPar(fCurrentSingle,0)<<" "
  //    <<fCalibration->GetPulserFuncPar(fCurrentSingle,1)<<" "
  //    <<fCalibration->GetPulserFuncPar(fCurrentSingle,2)<<" "
  //    <<fCalibration->GetPulserFuncPar(fCurrentSingle,3)<<" "
  //    <<endl;

  if (calAdc < limit1) {
    Double_t result = 
      fCalibration->GetPulserFuncPar(fCurrentSingle, 0) +
      fCalibration->GetPulserFuncPar(fCurrentSingle, 1) * calAdc
      + fCalibration->GetPulserFuncPar(fCurrentSingle, 2) * calAdc *
      calAdc;
    if (DebugLevel() > 15) 
      cout << "Channel " << fCurrentSingle << " has pulser value (1) " 
	   << result << " (" << calAdc << ")" <<  endl;
    return result;
  }
  
  
  // Calculate first coefficient 
  Double_t a = 
    fCalibration->GetPulserFuncPar(fCurrentSingle, 0) + 
    fCalibration->GetPulserFuncPar(fCurrentSingle, 1) * limit1 
    + fCalibration->GetPulserFuncPar(fCurrentSingle, 2) *
    TMath::Power(limit1, 2);  
  // Calculate second coefficient - looks like a derivative 
  Double_t b = 
    fCalibration->GetPulserFuncPar(fCurrentSingle, 1)
    + 2 * fCalibration->GetPulserFuncPar(fCurrentSingle, 2) * limit1;
  
  if (calAdc < limit2) {
    // return the corrected number 
    Double_t result = a + b * (calAdc - limit1) 
      + fCalibration->GetPulserFuncPar(fCurrentSingle, 3) 
      * TMath::Power(calAdc - limit1,2);
    if (DebugLevel() > 15) 
      cout << "Channel " << fCurrentSingle << " has pulser value (1) " 
	   << result << " (" << calAdc << ")" <<  endl;
    return result;
  }
      
  // Calculate third coefficient - looks like a derivative
  Double_t c = b + 2 * fCalibration->GetPulserFuncPar(fCurrentSingle, 3) *
    (limit2 - limit1);
  // Calculate fourth coefficient - looks like a derivative
  Double_t d = a + b * (limit2 - limit1) +
    fCalibration->GetPulserFuncPar(fCurrentSingle, 3) * 
    TMath::Power(limit2 - limit1, 2);
      
    // return the corrected number 
  Double_t result = d  + c * (calAdc - limit2);
  if (DebugLevel() > 15) 
    cout << "Channel " << fCurrentSingle << " has pulser value (2) " 
	 << result << " (" << calAdc << ")" << endl;
  return result;
}

//__________________________________________________________________
 Double_t BrSiRdoModule::CalibrateArrayMultiplicity()
{
  // PRIVATE METHOD:
  // Correct the sum multiplicity for the vertex position. 
  // This is based in on fits from GEANT, as far as I gather. 
  if (fCurrentVtxZ == FLT_MAX) {
    if (DebugLevel() > 25)
      Warning("CalibrateArrayMultiplicity","A null vertex");
    return 0;
  }
  
  // Get the order of the correcction function
  Int_t order = fCalibration->GetCorrectionFuncOrder();
  if (order < 0) {
    if (DebugLevel() > 25)
      Warning("CalibrateArrayMultiplicity","A null function");
    return 0;
  }

  // Get the valid vertex Z range for the correction function
  Float_t cut = fCalibration->GetCorrectionFuncCut();
  if (cut < 0) {
    if (DebugLevel() > 25)
      Warning("CalibrateArrayMultiplicity", "a null range");
    return 0;
  }
  
  // If we are outside of the valid range in Z, return 0
  if (cut < TMath::Abs(fCurrentVtxZ)) {
    if (DebugLevel() > 25)
      Warning("CalibrateArrayMultiplicity", 
	      "outside range: abs(%f) > %f", 
	      fCurrentVtxZ, cut);
    return 0;
  }

#if 0
  // Calculate the correction 
  Double_t corr = fCalibration->GetCorrectionFuncPar(0);
  for (Int_t i = 1; i < order + 1; i++) 
    corr += fCalibration->GetCorrectionFuncPar(i) 
      * TMath::Power(fCurrentVtxZ, i); 
#endif

  if (order != 9) {
    Warning("CalibrateArrayMultiplicity",
	    "bad function parameters");
    return 0;
  }
  
  Double_t corr = 0;

  // Limits of fits 

  Double_t limit1 = -22; 
  Double_t limit2 =  18;
  const BrRunInfo* runInfo = BrRunInfoManager::Instance()->GetCurrentRun();
  if(runInfo && runInfo->GetRunNo() >= 3700)   limit2 = 10; 
 
  Double_t a2 = fCalibration->GetCorrectionFuncPar(0);
  Double_t b2 = fCalibration->GetCorrectionFuncPar(1);
  Double_t c2 = fCalibration->GetCorrectionFuncPar(2);
  Double_t d2 = fCalibration->GetCorrectionFuncPar(3);
  Double_t e2 = fCalibration->GetCorrectionFuncPar(4);
  Double_t c1 = fCalibration->GetCorrectionFuncPar(5);
  Double_t d1 = fCalibration->GetCorrectionFuncPar(6);
  Double_t c3 = fCalibration->GetCorrectionFuncPar(7);
  Double_t d3 = fCalibration->GetCorrectionFuncPar(8);
  Double_t e3 = fCalibration->GetCorrectionFuncPar(9);  

  // Show the calibration 
  if (DebugLevel() > 25) {
    cout << GetName() << " Correction function parameters: " << endl 
	 << a2 << " " 
	 << b2 << " " 
	 << c2 << " " 
	 << d2 << " " 
	 << e2 << " " 
	 << c1 << " " 
	 << d1 << " " 
	 << c3 << " " 
	 << d3 << " " 
	 << e3 << endl;
  }

  if (fCurrentVtxZ < limit1) {
    // Calculate the second ceofficient - looks like some kind of
    // dervivative 
    // b1 = b2 + 2 * (c2 - c1) * x0 + 3 * (d2 - d1) * pow(x0,2) + 4 * e2
    //   * pow(x0,3); 
    Double_t b1 = b2 
      + 2 * (c2 - c1) * limit1 
      + 3 * (d2 - d1) * TMath::Power(limit1, 2) 
      + 4 * e2 * TMath::Power(limit1, 3);
    // Calcualte first coefficenet - looks like some kind of
    // dervivative 
    // a1 = a2 + (b2 - b1) * x0 + (c2 - c1) * pow(x0,2) + (d2 - d1) *
    //   pow(x0,3) + e2 * pow(x0,4);
    Double_t a1 = a2 
      + (b2 - b1) * limit1 
      + (c2 - c1) * TMath::Power(limit1, 2)
      + (d2 - d1) * TMath::Power(limit1, 3) 
      + e2 * TMath::Power(limit1, 4);
    // The actual correction 
    corr = a1 
      + b1 * fCurrentVtxZ 
      + c1 * TMath::Power(fCurrentVtxZ, 2)
      + d1 * TMath::Power(fCurrentVtxZ, 3);
  } 
  else if (fCurrentVtxZ < limit2)
    // The actual correction 
    corr = a2 
      + b2 * fCurrentVtxZ 
      + c2 * TMath::Power(fCurrentVtxZ, 2)
      + d2 * TMath::Power(fCurrentVtxZ, 3)
      + e2 * TMath::Power(fCurrentVtxZ, 4);
  else {
    // Calcualte first coefficenet - looks like some kind of
    // dervivative 
    // a3 = a2 + (c3 - c2) * pow(x1,2) + 2 * (d3 - d2) * pow(x1,3)
    //   + 3 * (e3 - e2) * pow(x1,4);
    Double_t a3 = a2 
      + (c3 - c2) * TMath::Power(limit2, 2) 
      + 2 * (d3 - d2) * TMath::Power(limit2, 3) 
      + 3 * (e3 - e2) * TMath::Power(limit2, 4);
    // Calculate the second ceofficient - looks like some kind of
    // dervivative 
    // b3 = b2 + 2 * (c2 - c3)* x1 + 3 * (d2 - d3) * pow(x1,2) + 4 
    //   * (e2 - e3) * pow(x1,3); 
    Double_t b3 = b2 
      + 2 * (c2 - c3) * limit2
      + 3 * (d2 - d3) * TMath::Power(limit2, 2) 
      + 4 * (e2 - e3) * TMath::Power(limit2, 3);
    // The actual correction 
    corr = a3 
      + b3 * fCurrentVtxZ 
      + c3 * TMath::Power(fCurrentVtxZ, 2)
      + d3 * TMath::Power(fCurrentVtxZ, 3)
      + e3 * TMath::Power(fCurrentVtxZ, 4);
  }
    
  // if the correction is very small, return 0;
  if (TMath::Abs(corr) < 1e-6)
    return 0;
  
  return 1. / corr;
}

  
//____________________________________________________________________
 void BrSiRdoModule::Print(Option_t* option) const
{ 
  // Module Information method
  //
  // Options: (see also BrModule::Print)
  //  
  TString opt(option);
  opt.ToLower();
  
  BrMultRdoModule::Print(option);
  if (opt.Contains("d"))
    cout << endl
         << "  Original author: Christian Holm Christensen" << endl
         << "  Last Modifications: " << endl 
         << "    $Author: cholm $" << endl 
         << "    $Date: 2002/05/08 16:30:59 $"   << endl
         << "    $Revision: 1.18 $ " << endl 
         << "-------------------------------------------------" << endl
	 << "  Using pathlength correction: " 
	 << (fUsePathLengthCor ? "yes" : "no" ) << endl 
         << endl;
} 

//____________________________________________________________________
//
// $Log: BrSiRdoModule.cxx,v $
// Revision 1.18  2002/05/08 16:30:59  cholm
// Added 3 histograms, one of the sum of the multiplicity in each eta bin,
// one with the number of fills, and a third, the ratio of these two.  Unless
// something tricky is going on, this should be our dN/deta distribution for
// the TMA and SMA.  Also fixed a few warning (probably GCC3 errors) in the
// Si and Tile modules.
//
// Revision 1.17  2002/03/05 20:34:49  sanders
// fixed problem with low hit events not being correctly counted for
// use in dNdEta calculations
//
// Revision 1.16  2002/01/27 16:13:03  cholm
// Use pass-by-reference ('&') rather than pointers ('*') in the method
// BrMultRdoModule::CalibrateAdc, since that's the proper C++ way to go
// about these things.
//
// Revision 1.15  2002/01/26 16:17:33  sanders
// Modified point where the energy threshold is applied.  Delaying the
// threshold cut until after the energy calibration is necessary for
// checking the energy calibration.
// Also corrected an indexing error that was cutting off the first adc
// channel in the histograms.
//
// Revision 1.14  2002/01/04 21:30:11  sanders
// Added "Setters" for range of raw adc values.
//
// Revision 1.13  2002/01/03 19:44:05  cholm
// Added method to set wether one should do path lengt correction or not.
// Defualt is to do it.  Also prepared the class to use the class BrTableNames
// (or some other class, like BrDetectorList or something).
//
// Revision 1.12  2001/12/07 18:13:20  cholm
// Set better ranges for the ADC, Energy and Multiplicity histograms.
//
// Revision 1.11  2001/11/19 04:07:49  sanders
// Revised rdo modules for 2001 si and tile calibrations.
//
// Revision 1.10  2001/11/13 15:51:32  cholm
// REmoved initialisation of calibrations.
//
// Revision 1.9  2001/11/12 14:55:46  sanders
// Added modifications for 200 GeV multiplicity/centrality calibrations.
// Added cfs method to BrZdcRdoModule since this is needed to obtain
// reliable position for low amplitude signals (avoids strong slewing
// correction)
//
// Revision 1.8  2001/11/02 15:15:36  cholm
// Histogram range fixes.
//
// Revision 1.7  2001/10/29 21:00:35  cholm
// Corrected a very bad mistake in the previous commit:  A manager was
// initialised in the module - BAD.  Managers may not be initialised in
// modules, only thier services may be used.
//
// Revision 1.6  2001/10/27 22:52:43  sanders
// Files modified for use with Yr 2 calibrations.  The run number
// is now found using BrRunInfoManager.
//
// Revision 1.5  2001/10/08 11:29:14  cholm
// Changed to use new DB access classes
//
// Revision 1.4  2001/09/20 13:44:18  cholm
// Removed the use of temp ASCII files, since not needed anymore
//
// Revision 1.3  2001/08/30 12:34:45  cholm
// Added more documentation to the pulser correction function.
//
// Revision 1.2  2001/06/22 17:41:52  cholm
// Change names so that every data class has the same format, so that
// we will not have to worry about that later on. The affected classes
// are:
//
//         BrDigBB             ->        BrBbDig
//         BrRdoBB             ->        BrBbRdo
//         BrDigZDC            ->        BrZdcDig
//         BrRdoZDC            ->        BrZdcRdo
//         BrDigRHIC           ->        BrRichDig
//         BrDigDC             ->        BrDcDig
//         BrDigC1             ->        BrDcC1
// 	BrDigHit            ->	      BrHitDig
// 	BrDigTof	    ->	      BrTofDig
// 	BrTPCSequence	    ->	      BrTpcSequence
// 	BrTPCCluster	    ->	      BrTpcCluster
// 	BrTPCClusterTable   ->	      BrTpcClusterTable
//
// These changes has ofcourse been propegated to the modules as well,
// giving the changes
//
//         BrRdoModuleBB	    ->	      BrBbRdoModule
// 	BrRdoModuleZDC	    ->	      BrZdcRdoModule
// 	BrTPCClusterFinder  ->	      BrTpcClusterFinder
// 	BrTPCSequenceAdder  ->	      BrTpcSequenceAdder
//
// Revision 1.1.1.1  2001/06/21 14:55:09  hagel
// Initial revision of brat2
//
// Revision 1.16  2001/06/01 15:49:28  cholm
// Fix of some default values from -1 to zero (gave bad results)
// BrSiCalibration had a bug in returning the correction function.
// Tile|Rdo modules had some minor bugs, and I did some improvments
// Mult Rdo module had some serious bugs, but should be ok now.
// BrMultRdo is fixed a lot too.
//
// Revision 1.15  2001/05/31 01:46:42  cholm
// Second rewamp of this directory.  All RDO modules use the common
// BrMultRdoModule, and they both write BrMultRdo Objects.  Also introduced
// ABC for Br[Tile|Si][Parameters|Calibration] since they have a lot in common,
// and the code can be made more efficient this way.
//
// A possible further thing to do, is to make an ABC for the CentModules, and
// the corresponding calibration modules, since they are very VERY similar.
// However, the current module BrMultCentModule is in the way.  Need to talk
// to Steve about that.
//
// Revision 1.14  2001/05/23 12:28:20  cholm
// Uses BrMultModule to obtain vertex
//
// Revision 1.13  2001/05/02 22:29:20  sanders
// Fix error that forced fOutlierMethod = kHitCorrection
//
// Revision 1.12  2001/05/01 13:00:39  cholm
// Fix "division by zero" problem.
//
// Revision 1.11  2001/04/19 15:14:20  cholm
// Added outlier correction method kHitCorrectopn
//
// Revision 1.10  2001/04/19 00:30:16  sanders
// Removed hard coded BB vertex offset.
//
// Revision 1.9  2001/04/16 02:35:12  sanders
// Changes to have BrSiRdoModule and BrTileRdoModule report the same
// multiplicities as BrRdoModuleMult
//
// Revision 1.8  2001/04/13 02:59:50  sanders
// Further work on reconciling "old" and "new" code.  Added additional checks
// for using TPM1 vertex.
//
// Revision 1.7  2001/04/11 14:04:18  cholm
// Fixed a few bug
//
// Revision 1.6  2001/04/06 20:04:50  cholm
// Corrected log
//
//

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