Newer
Older
Simon Zhamkochyan
committed
///////////////////////////////////////////////////////////////////////////////
// //
// THcShower //
// //
// Shower counter class, describing a generic segmented shower detector. //
// //
// //
// //
// //
///////////////////////////////////////////////////////////////////////////////
#include "THcShower.h"
#include "THcShowerCluster.h"
Simon Zhamkochyan
committed
#include "THaEvData.h"
#include "THaDetMap.h"
#include "THcDetectorMap.h"
#include "THcGlobals.h"
#include "THaCutList.h"
Simon Zhamkochyan
committed
#include "THcParmList.h"
#include "VarDef.h"
#include "VarType.h"
#include "THaTrack.h"
#include "TClonesArray.h"
#include "THaTrackProj.h"
Simon Zhamkochyan
committed
#include "TMath.h"
#include "THaTrackProj.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
//_____________________________________________________________________________
THcShower::THcShower( const char* name, const char* description,
THaApparatus* apparatus ) :
THaNonTrackingDetector(name,description,apparatus)
{
// Constructor
fNLayers = 0; // No layers until we make them
fClusterList = new THcShowerClusterList;
Simon Zhamkochyan
committed
}
//_____________________________________________________________________________
THcShower::THcShower( ) :
THaNonTrackingDetector()
{
// Constructor
}
//_____________________________________________________________________________
void THcShower::Setup(const char* name, const char* description)
{
cout << "THcShower::Setup called " << GetName() << endl;
char prefix[2];
prefix[0] = tolower(GetApparatus()->GetName()[0]);
prefix[1] = '\0';
string layernamelist;
DBRequest list[]={
{"cal_num_layers", &fNLayers, kInt},
{"cal_layer_names", &layernamelist, kString},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list,prefix);
cout << layernamelist << endl;
cout << "Shower Counter: " << fNLayers << " layers" << endl;
vector<string> layer_names = vsplit(layernamelist);
if(layer_names.size() != (UInt_t) fNLayers) {
cout << "ERROR: Number of layers " << fNLayers
<< " doesn't agree with number of layer names "
<< layer_names.size() << endl;
// Should quit. Is there an official way to quit?
}
for(Int_t i=0;i<fNLayers;i++) {
fLayerNames[i] = new char[layer_names[i].length()];
strcpy(fLayerNames[i], layer_names[i].c_str());
}
char *desc = new char[strlen(description)+100];
for(Int_t i=0;i < fNLayers;i++) {
strcpy(desc, description);
strcat(desc, " Plane ");
strcat(desc, fLayerNames[i]);
fPlanes[i] = new THcShowerPlane(fLayerNames[i], desc, i+1, this);
cout << "Created Shower Plane " << fLayerNames[i] << ", " << desc << endl;
}
cout << "THcShower::Setup Return " << GetName() << endl;
Simon Zhamkochyan
committed
//_____________________________________________________________________________
THaAnalysisObject::EStatus THcShower::Init( const TDatime& date )
{
cout << "THcShower::Init " << GetName() << endl;
Setup(GetName(), GetTitle());
Simon Zhamkochyan
committed
// Should probably put this in ReadDatabase as we will know the
// maximum number of hits after setting up the detector map
Stephen A. Wood
committed
InitHitList(fDetMap, "THcRawShowerHit", 100);
Simon Zhamkochyan
committed
EStatus status;
if( (status = THaNonTrackingDetector::Init( date )) )
return fStatus=status;
for(Int_t ip=0;ip<fNLayers;ip++) {
if((status = fPlanes[ip]->Init( date ))) {
return fStatus=status;
}
}
char EngineDID[] = " CAL";
EngineDID[0] = toupper(GetApparatus()->GetName()[0]);
if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) {
static const char* const here = "Init()";
Simon Zhamkochyan
committed
Error( Here(here), "Error filling detectormap for %s.",
Simon Zhamkochyan
committed
return kInitError;
}
return fStatus = kOK;
}
//_____________________________________________________________________________
Int_t THcShower::ReadDatabase( const TDatime& date )
{
// Read this detector's parameters from the database file 'fi'.
// This function is called by THaDetectorBase::Init() once at the
// beginning of the analysis.
// 'date' contains the date/time of the run being analyzed.
// static const char* const here = "ReadDatabase()";
char prefix[2];
Simon Zhamkochyan
committed
// Read data from database
// Pull values from the THcParmList instead of reading a database
// file like Hall A does.
// We will probably want to add some kind of method to gHcParms to allow
// bulk retrieval of parameters of interest.
// Will need to determine which spectrometer in order to construct
// the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr)
cout << "THcShower::ReadDatabase called " << GetName() << endl;
Simon Zhamkochyan
committed
prefix[0]=tolower(GetApparatus()->GetName()[0]);
prefix[1]='\0';
Simon Zhamkochyan
committed
{
DBRequest list[]={
{"cal_num_neg_columns", &fNegCols, kInt},
{"cal_slop", &fSlop, kDouble},
{"cal_fv_test", &fvTest, kInt,0,1},
{"cal_fv_delta", &fvDelta, kDouble},
{"dbg_decoded_cal", &fdbg_decoded_cal, kInt},
{"dbg_sparsified_cal", &fdbg_sparsified_cal, kInt},
{"dbg_clusters_cal", &fdbg_clusters_cal, kInt},
{"dbg_tracks_cal", &fdbg_tracks_cal, kInt},
fvTest = 0; // Default if not defined
gHcParms->LoadParmValues((DBRequest*)&list, prefix);
}
cout << "Number of neg. columns = " << fNegCols << endl;
cout << "Slop parameter = " << fSlop << endl;
cout << "Fiducial volume test flag = " << fvTest << endl;
cout << "Fiducial volume excl. width = " << fvDelta << endl;
cout << "Decode debug flag = " << fdbg_decoded_cal << endl;
cout << "Sparsify debug flag = " << fdbg_sparsified_cal << endl;
cout << "Cluster debug flag = " << fdbg_clusters_cal << endl;
cout << "Tracking debug flag = " << fdbg_tracks_cal << endl;
{
DBRequest list[]={
{"cal_a_cor", &fAcor, kDouble},
{"cal_b_cor", &fBcor, kDouble},
{"cal_c_cor", &fCcor, kDouble},
{"cal_d_cor", &fDcor, kDouble},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list, prefix);
}
cout << "HMS Calorimeter coordinate correction constants:" << endl;
cout << " fAcor = " << fAcor << endl;
cout << " fBcor = " << fBcor << endl;
cout << " fCcor = " << fCcor << endl;
cout << " fDcor = " << fDcor << endl;
fNBlocks = new Int_t [fNLayers];
Simon Zhamkochyan
committed
for(Int_t i=0;i<fNLayers;i++) {
DBRequest list[]={
{Form("cal_%s_thick",fLayerNames[i]), &BlockThick[i], kDouble},
{Form("cal_%s_nr",fLayerNames[i]), &fNBlocks[i], kInt},
{Form("cal_%s_zpos",fLayerNames[i]), &fNLayerZPos[i], kDouble},
{Form("cal_%s_right",fLayerNames[i]), &YPos[2*i], kDouble},
{Form("cal_%s_left",fLayerNames[i]), &YPos[2*i+1], kDouble},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list, prefix);
Simon Zhamkochyan
committed
}
//Caution! Z positions (fronts) are off in hcal.param! Correct later on.
for(Int_t i=0;i<fNLayers;i++) {
XPos[i] = new Double_t [fNBlocks[i]];
DBRequest list[]={
{Form("cal_%s_top",fLayerNames[i]),XPos[i], kDouble, fNBlocks[i]},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list, prefix);
Simon Zhamkochyan
committed
}
for(Int_t i=0;i<fNLayers;i++) {
cout << "Plane " << fLayerNames[i] << ":" << endl;
cout << " Block thickness: " << BlockThick[i] << endl;
cout << " NBlocks : " << fNBlocks[i] << endl;
cout << " Z Position : " << fNLayerZPos[i] << endl;
cout << " Y Positions : " << YPos[2*i] << ", " << YPos[2*i+1] <<endl;
cout << " X Positions :";
for(Int_t j=0; j<fNBlocks[i]; j++) {
}
cout << endl;
Simon Zhamkochyan
committed
}
// Fiducial volume limits, based on Plane 1 positions.
//
fvXmin = XPos[0][0] + fvDelta;
fvXmax = XPos[0][fNBlocks[0]-1] + BlockThick[0] - fvDelta;
fvYmin = YPos[0] + fvDelta;
fvYmax = YPos[1] - fvDelta;
cout << "Fiducial volume limits:" << endl;
cout << " Xmin = " << fvXmin << " Xmax = " << fvXmax << endl;
cout << " Ymin = " << fvYmin << " Ymax = " << fvYmax << endl;
//Calibration related parameters (from hcal.param).
fNtotBlocks=0; //total number of blocks
for (Int_t i=0; i<fNLayers; i++) fNtotBlocks += fNBlocks[i];
cout << "Total number of blocks in the calorimeter: " << fNtotBlocks << endl;
//Pedestal limits from hcal.param.
Vardan Tadevosyan
committed
fShPosPedLimit = new Int_t [fNtotBlocks];
fShNegPedLimit = new Int_t [fNtotBlocks];
//Calibration constants
fPosGain = new Double_t [fNtotBlocks];
fNegGain = new Double_t [fNtotBlocks];
//Read in parameters from hcal.param
Double_t hcal_pos_cal_const[fNtotBlocks];
// Double_t hcal_pos_gain_ini[fNtotBlocks]; not used
// Double_t hcal_pos_gain_cur[fNtotBlocks]; not used
// Int_t hcal_pos_ped_limit[fNtotBlocks]; not used
Double_t hcal_pos_gain_cor[fNtotBlocks];
Double_t hcal_neg_cal_const[fNtotBlocks];
// Double_t hcal_neg_gain_ini[fNtotBlocks]; not used
// Double_t hcal_neg_gain_cur[fNtotBlocks]; not used
// Int_t hcal_neg_ped_limit[fNtotBlocks]; not used
Double_t hcal_neg_gain_cor[fNtotBlocks];
DBRequest list[]={
{"cal_pos_cal_const", hcal_pos_cal_const, kDouble, fNtotBlocks},
// {"cal_pos_gain_ini", hcal_pos_gain_ini, kDouble, fNtotBlocks},
// {"cal_pos_gain_cur", hcal_pos_gain_cur, kDouble, fNtotBlocks},
Vardan Tadevosyan
committed
{"cal_pos_ped_limit", fShPosPedLimit, kInt, fNtotBlocks},
{"cal_pos_gain_cor", hcal_pos_gain_cor, kDouble, fNtotBlocks},
{"cal_neg_cal_const", hcal_neg_cal_const, kDouble, fNtotBlocks},
// {"cal_neg_gain_ini", hcal_neg_gain_ini, kDouble, fNtotBlocks},
// {"cal_neg_gain_cur", hcal_neg_gain_cur, kDouble, fNtotBlocks},
Vardan Tadevosyan
committed
{"cal_neg_ped_limit", fShNegPedLimit, kInt, fNtotBlocks},
{"cal_neg_gain_cor", hcal_neg_gain_cor, kDouble, fNtotBlocks},
{"cal_min_peds", &fShMinPeds, kInt},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list, prefix);
cout << "hcal_pos_cal_const:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
cout << hcal_pos_cal_const[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
Vardan Tadevosyan
committed
cout << "fShPosPedLimit:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
Vardan Tadevosyan
committed
cout << fShPosPedLimit[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
cout << "hcal_pos_gain_cor:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
cout << hcal_pos_gain_cor[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
cout << "hcal_neg_cal_const:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
cout << hcal_neg_cal_const[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
Vardan Tadevosyan
committed
cout << "fShNegPedLimit:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
Vardan Tadevosyan
committed
cout << fShNegPedLimit[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
cout << "hcal_neg_gain_cor:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
cout << hcal_neg_gain_cor[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
// Calibration constants (GeV / ADC channel).
for (Int_t i=0; i<fNtotBlocks; i++) {
fPosGain[i] = hcal_pos_cal_const[i] * hcal_pos_gain_cor[i];
fNegGain[i] = hcal_neg_cal_const[i] * hcal_neg_gain_cor[i];
cout << "fPosGain:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
cout << fPosGain[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
cout << "fNegGain:" << endl;
for (Int_t j=0; j<fNLayers; j++) {
for (Int_t i=0; i<fNBlocks[j]; i++) {
cout << fNegGain[j*fNBlocks[j]+i] << " ";
};
cout << endl;
};
// Corrdiante corrected track energies per plane
fTREpl_cor = new Double_t [fNLayers];
fTREpl_pos_cor = new Double_t [fNLayers];
fTREpl_neg_cor = new Double_t [fNLayers];
// Origin of the calorimeter, at the centre of the face of the detector,
// or at the centre of the front of the 1-st layer.
//
Double_t xOrig = (XPos[0][0] + XPos[0][fNBlocks[0]-1])/2 + BlockThick[0]/2;
Double_t yOrig = (YPos[0] + YPos[1])/2;
Double_t zOrig = fNLayerZPos[0];
fOrigin.SetXYZ(xOrig, yOrig, zOrig);
cout << "Origin of the Calorimeter:" << endl;
cout << " Xorig = " << GetOrigin().X() << endl;
cout << " Yorig = " << GetOrigin().Y() << endl;
cout << " Zorig = " << GetOrigin().Z() << endl;
cout << endl;
// Detector axes. Assume no rotation.
//
DefineAxes(0.);
Simon Zhamkochyan
committed
fIsInit = true;
return kOK;
}
//_____________________________________________________________________________
Int_t THcShower::DefineVariables( EMode mode )
{
// Initialize global variables and lookup table for decoder
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
cout << "THcShower::DefineVariables called " << GetName() << endl;
Simon Zhamkochyan
committed
// Register variables in global list
{ "nhits", "Number of hits", "fNhits" },
Simon Zhamkochyan
committed
// { "a", "Raw ADC amplitudes", "fA" },
// { "a_p", "Ped-subtracted ADC amplitudes", "fA_p" },
// { "a_c", "Calibrated ADC amplitudes", "fA_c" },
// { "asum_p", "Sum of ped-subtracted ADCs", "fAsum_p" },
// { "asum_c", "Sum of calibrated ADCs", "fAsum_c" },
{ "nclust", "Number of clusters", "fNclust" },
{ "ntracks", "Number of shower tracks", "fNtracks" },
{ "emax", "Energy of largest cluster", "fE" },
{ "eprmax", "Preshower Energy of largest cluster", "fEpr" },
{ "xmax", "x-position (cm) of largest cluster", "fX" },
// { "z", "z-position (cm) of largest cluster", "fZ" },
{ "mult", "Multiplicity of largest cluster", "fMult" },
Simon Zhamkochyan
committed
// { "nblk", "Numbers of blocks in main cluster", "fNblk" },
// { "eblk", "Energies of blocks in main cluster", "fEblk" },
{ "trx", "track x-position in det plane (1st track)", "fTRX" },
{ "try", "track y-position in det plane (1st track)", "fTRY" },
{ "tre", "track energy in the calorimeter (1st track)", "fTRE" },
{ "trepr", "track energy in the preshower (1st track)", "fTREpr" },
{ "trecor", "Y-corrected track Edep (1st track)", "fTRE_cor" },
{ "treprcor", "Y-corrected track Epr (1st track)", "fTREpr_cor" },
{ "treplcor", "Y-corrected track Edep for planes", "fTREpl_cor" },
DefineVarsFromList( vars, mode );
Simon Zhamkochyan
committed
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
}
//_____________________________________________________________________________
THcShower::~THcShower()
{
// Destructor. Remove variables from global list.
if( fIsSetup )
RemoveVariables();
if( fIsInit )
DeleteArrays();
if (fTrackProj) {
fTrackProj->Clear();
delete fTrackProj; fTrackProj = 0;
}
}
//_____________________________________________________________________________
void THcShower::DeleteArrays()
{
// Delete member arrays. Used by destructor.
delete [] BlockThick; BlockThick = NULL;
delete [] fNBlocks; fNBlocks = NULL;
delete [] fNLayerZPos; fNLayerZPos = NULL;
delete [] XPos; XPos = NULL;
Simon Zhamkochyan
committed
//delete [] fSpacing; fSpacing = NULL;
//delete [] fCenter; fCenter = NULL; // This 2D. What is correct way to delete?
}
//_____________________________________________________________________________
inline
void THcShower::Clear(Option_t* opt)
Simon Zhamkochyan
committed
{
// Reset per-event data.
for(Int_t ip=0;ip<fNLayers;ip++) {
fPlanes[ip]->Clear(opt);
}
// fTrackProj->Clear();
fNtracks = 0;
Vardan Tadevosyan
committed
fX = -75.; //out of acceptance
fTRX = -75.; //out of acceptance
fTRY = -40.; //out of acceptance
fTRE = -0.;
fTREpr = -0.;
fTRE_cor = -0.;
fTREpr_cor = -0.;
for(Int_t ip=0;ip<fNLayers;ip++) {
fTREpl_cor[ip] = -0.;
fTREpl_pos_cor[ip] = -0.;
fTREpl_neg_cor[ip] = -0.;
}
fClusterList->clear();
Simon Zhamkochyan
committed
}
//_____________________________________________________________________________
Int_t THcShower::Decode( const THaEvData& evdata )
{
Simon Zhamkochyan
committed
// Get the Hall C style hitlist (fRawHitList) for this event
Stephen A. Wood
committed
Int_t nhits = DecodeToHitList(evdata);
if(gHaCuts->Result("Pedestal_event")) {
Int_t nexthit = 0;
for(Int_t ip=0;ip<fNLayers;ip++) {
nexthit = fPlanes[ip]->AccumulatePedestals(fRawHitList, nexthit);
if (fdbg_decoded_cal) {
cout << "THcShower::Decode: nexthit = " << nexthit << endl;
}
}
fAnalyzePedestals = 1; // Analyze pedestals first normal events
return(0);
}
if(fAnalyzePedestals) {
for(Int_t ip=0;ip<fNLayers;ip++) {
fPlanes[ip]->CalculatePedestals();
}
fAnalyzePedestals = 0; // Don't analyze pedestals next event
}
Int_t nexthit = 0;
for(Int_t ip=0;ip<fNLayers;ip++) {
nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit);
}
// fRawHitList is TClones array of THcRawShowerHit objects
// This debug output does not work, needs to be corrected.
// if (fdbg_decoded_cal) {
// cout << "THcShower::Decode: Shower raw hit list:" << endl;
// for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) {
// THcRawShowerHit* hit = (THcRawShowerHit *) fRawHitList->At(ihit);
// cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
// << hit->fADC_pos << " " << hit->fADC_neg << " " << endl;
// }
// cout << endl;
Simon Zhamkochyan
committed
return nhits;
}
//_____________________________________________________________________________
Int_t THcShower::ApplyCorrections( void )
{
return(0);
}
//_____________________________________________________________________________
//Double_t THcShower::TimeWalkCorrection(const Int_t& paddle,
// const ESide side)
//{
// return(0.0);
//}
Simon Zhamkochyan
committed
//_____________________________________________________________________________
Int_t THcShower::CoarseProcess( TClonesArray& tracks)
Simon Zhamkochyan
committed
{
// Calculation of coordinates of particle track cross point with shower
// plane in the detector coordinate system. For this, parameters of track
// reconstructed in THaVDC::CoarseTrack() are used.
//
// Apply corrections and reconstruct the complete hits.
if (fdbg_clusters_cal)
cout << "THcShower::CoarseProcess called ---------------------------" <<endl;
// Fill list of unclustered hits.
if (fdbg_clusters_cal) cout << "Filling list of unclustered hits..." << endl;
for(Int_t j=0; j < fNLayers; j++) {
if (fdbg_clusters_cal)cout << " Plane " << j << " Eplane = "
<< fPlanes[j]->GetEplane() << endl;
Simon Zhamkochyan
committed
for (Int_t i=0; i<fNBlocks[j]; i++) {
//May be should be done this way.
//
// Double_t Edep = fPlanes[j]->GetEmean(i);
// if (Edep > 0.) { //hit
// Double_t x = YPos[j][i] + BlockThick[j]/2.; //top + thick/2
// Double_t z = fNLayerZPos[j] + BlockThick[j]/2.;//front + thick/2
// THcShowerHit* hit = new THcShowerHit(i,j,x,z,Edep);
//ENGINE way.
//
if (fPlanes[j]->GetApos(i) - fPlanes[j]->GetPosPed(i) >
fPlanes[j]->GetPosThr(i) - fPlanes[j]->GetPosPed(i) ||
fPlanes[j]->GetAneg(i) - fPlanes[j]->GetNegPed(i) >
fPlanes[j]->GetNegThr(i) - fPlanes[j]->GetNegPed(i)) { //hit
Double_t Edep = fPlanes[j]->GetEmean(i);
Double_t Epos = fPlanes[j]->GetEpos(i);
Double_t Eneg = fPlanes[j]->GetEneg(i);
Double_t x = XPos[j][i] + BlockThick[j]/2.; //top + thick/2
Double_t z = fNLayerZPos[j] + BlockThick[j]/2.; //front + thick/2
THcShowerHit* hit = new THcShowerHit(i,j,x,z,Edep,Epos,Eneg);
HitList.push_back(hit);
if (fdbg_clusters_cal)
cout << " Hit: Edep = " << Edep << " X = " << x << " Z = " << z
<< " Block " << i << " Layer " << j << endl;
};
}
}
//Print out hits before clustering.
if (fdbg_clusters_cal) {
cout << "Total hits: " << fNhits << endl;
for (Int_t i=0; i!=fNhits; i++) {
cout << "unclustered hit " << i << ": ";
(*(HitList.begin()+i))->show();
}
// Create list of clusters and fill it.
// fClusterList = new THcShowerClusterList; //shall be allocated before
fClusterList->ClusterHits(HitList);
fNclust = (*fClusterList).NbClusters(); //number of clusters
//Print out the cluster list.
if (fdbg_clusters_cal) {
cout << "Cluster_list size: " << fNclust << endl;
for (Int_t i=0; i!=fNclust; i++) {
THcShowerCluster* cluster = (*fClusterList).ListedCluster(i);
//cout << "Cluster #" << i
//<<": E=" << (*cluster).clE()
//<< " Epr=" << (*cluster).clEpr()
//<< " X=" << (*cluster).clX()
//<< " Z=" << (*cluster).clZ()
//<< " size=" << (*cluster).clSize()
//<< endl;
for (UInt_t j=0; j!=(*cluster).clSize(); j++) {
//THcShowerHit* hit = (*cluster).ClusteredHit(j);
//cout << " hit #" << j << ": "; (*hit).show();
// The following is for testing the code, by comparison with Engine.
// The largest cluster by deposited energy, its size and energy
// depositions.
THcShowerCluster* MaxCluster = (*fClusterList).ListedCluster(0);
fE = (*MaxCluster).clE();
for (Int_t i=1; i<fNclust; i++) {
THcShowerCluster* cluster = (*fClusterList).ListedCluster(i);
Double_t E = (*cluster).clE();
if (fE < E) {
fE = E;
fMult = (*MaxCluster).clSize(); // number of hit counters
fEpr = (*MaxCluster).clEpr(); // Preshower energy
fX = (*MaxCluster).clX(); // X coordinate (in vertical direction)
if (fdbg_clusters_cal)
cout << "Max.cluster: fEpr = " << fEpr << " fE = " << fE << " fX = " << fX
<< endl;
// Track-to-cluster matching.
//
Int_t Ntracks = tracks.GetLast()+1; // Number of reconstructed tracks
if (fdbg_tracks_cal) {
cout << endl;
cout << "Number of reconstructed tracks = " << Ntracks << endl;
}
for (Int_t itrk=0; itrk<Ntracks; itrk++) {
THaTrack* theTrack = static_cast<THaTrack*>( tracks[itrk] );
cout << " Track " << itrk << ": "
<< " X = " << theTrack->GetX()
<< " Y = " << theTrack->GetY()
<< " Theta = " << theTrack->GetTheta()
<< " Phi = " << theTrack->GetPhi()
<< endl;
}
// Track coordinates at front of the calorimeter, initialize out of
// acceptance.
Double_t Xtr = -75.;
Double_t Ytr = -40.;
Vardan Tadevosyan
committed
// Associate a cluster to the track.
Int_t mclust = MatchCluster(theTrack, Xtr, Ytr);
Vardan Tadevosyan
committed
// if (mclust >= 0) fNtracks++; // number of shower tracks (This is not consistent with engine!)
// Do this for the 1-st track only for now.
//
if (itrk==0) {
fTRX = Xtr; // track coordinates at the calorimeter
Vardan Tadevosyan
committed
fTRY = Ytr;
if (mclust >= 0) { // if there is a matched cluster
//Assign energies (not Y corrected) of the matched cluster to the track.
THcShowerCluster* cluster = (*fClusterList).ListedCluster(mclust);
Vardan Tadevosyan
committed
fTRE = (*cluster).clE();
fTREpr = (*cluster).clEpr();
// Correct track energy depositions for the impact coordinate.
fTRE_cor = 0.; // Coord. corrected total energy depostion
for (Int_t ip=0; ip<fNLayers; ip++) {
// Coordinate correction factors for positive and negative sides,
// different for single PMT counters in the 1-st two layes and for
// 2 PMT counters in the rear two layers.
Float_t corpos = 1.;
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
Float_t corneg = 1.;
if (ip < fNegCols) {
corpos = Ycor(Ytr,0);
corneg = Ycor(Ytr,1);
}
else {
corpos = Ycor(Ytr);
corneg = 0.;
}
if (fdbg_tracks_cal) {
cout << " Plane " << ip << " Ytr = " << Ytr
<< " corpos = " << corpos
<< " corneg = " << corneg << endl;
}
fTREpl_pos_cor[ip] = (*cluster).clEplane(ip,0) * corpos;
fTREpl_neg_cor[ip] = (*cluster).clEplane(ip,1) * corneg;;
fTREpl_cor[ip] = fTREpl_pos_cor[ip] + fTREpl_neg_cor[ip];
if (fdbg_tracks_cal) {
cout << " fTREpl_pos_cor = " << fTREpl_pos_cor[ip]
<< " fTREpl_neg_cor = " << fTREpl_neg_cor[ip] << endl;
}
fTRE_cor += fTREpl_cor[ip];
} //over planes
fTREpr_cor = fTREpl_cor[0]; // Coord. corrected Edep in Preshower
if (fdbg_tracks_cal)
cout << " fTREpr = " << fTREpr
<< " fTREpr_cor = " << fTREpr_cor << endl;
} //mclust>=0
} //itrk==0
} //over tracks
if (fdbg_tracks_cal)
cout << "1st track cluster: fTRX = " << fTRX << " fTRY = " << fTRY
<< endl;
Vardan Tadevosyan
committed
if (fdbg_clusters_cal)
cout << "THcShower::CoarseProcess return ---------------------------" <<endl;
Simon Zhamkochyan
committed
return 0;
}
//-----------------------------------------------------------------------------
Int_t THcShower::MatchCluster(THaTrack* Track,
Vardan Tadevosyan
committed
Double_t& XTrFront, Double_t& YTrFront)
// Match a cluster to a given track. Return the cluster number,
// and track coordinates at the front of calorimeter.
if (fdbg_tracks_cal) {
cout << "THcShower::MatchCluster: Track at DC:"
<< " X = " << Track->GetX()
<< " Y = " << Track->GetY()
<< " Theta = " << Track->GetTheta()
<< " Phi = " << Track->GetPhi()
<< endl;
}
Vardan Tadevosyan
committed
XTrFront = kBig;
YTrFront = kBig;
Double_t pathl = kBig;
// Track interception with face of the calorimeter. The coordinates are
// in the calorimeter's local system.
fOrigin = fPlanes[0]->GetOrigin();
CalcTrackIntercept(Track, pathl, XTrFront, YTrFront);
// Transform coordiantes to the spectrometer's coordinate system.
XTrFront += GetOrigin().X();
YTrFront += GetOrigin().Y();
if (fdbg_tracks_cal)
cout << " Track at the front of Calorimeter:"
<< " X = " << XTrFront
<< " Y = " << YTrFront
<< " Pathl = " << pathl
<< endl;
Bool_t inFidVol = true; // In Fiducial Volume flag
// Re-evaluate Fid. Volume Flag if fid. volume test is requested
if (fvTest) {
// Track coordinates at the back of the detector.
// Origin at the front of the last layer.
fOrigin = fPlanes[fNLayers-1]->GetOrigin();
Double_t XTrBack = kBig;
Double_t YTrBack = kBig;
CalcTrackIntercept(Track, pathl, XTrBack, YTrBack);
XTrBack += GetOrigin().X(); // from local coord. system
YTrBack += GetOrigin().Y(); // to the spectrometer system
if (fdbg_tracks_cal)
cout << " Track at the back of Calorimeter:"
<< " X = " << XTrBack
<< " Y = " << YTrBack
<< " Pathl = " << pathl
<< endl;
inFidVol = (XTrFront < fvXmax) && (XTrFront > fvXmin) &&
(YTrFront < fvYmax) && (YTrFront > fvYmin) &&
(XTrBack < fvXmax) && (XTrBack > fvXmin) &&
(YTrBack < fvYmax) && (YTrBack > fvYmin);
if (fdbg_tracks_cal)
cout << " Fiducial volume test: inFidVol = " << inFidVol << endl;
}
// Match a cluster to the track.
Int_t mclust = -1; // The match cluster #, initialize with a bogus value.
Double_t deltaX = kBig; // Track to cluster distance
if (inFidVol) {
for (Int_t i=0; i<fNclust; i++) {
THcShowerCluster* cluster = (*fClusterList).ListedCluster(i);
Double_t dx = TMath::Abs( (*cluster).clX() - XTrFront );
if (dx <= (0.5*BlockThick[0] + fSlop)) {
fNtracks++; // number of shower tracks (Consistent with engine)
if (dx <= deltaX) {
mclust = i;
deltaX = dx;
}
if (fdbg_tracks_cal)
cout << "MatchCluster: mclust= " << mclust << " delatX= " << deltaX
<< endl;
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
//_____________________________________________________________________________
Float_t THcShower::GetShEnergy(THaTrack* Track) {
// Get total energy deposited in the cluster matched to the given
// spectrometer Track.
// Track coordinates at front of the calorimeter, initialize out of
// acceptance.
Double_t Xtr = -75.;
Double_t Ytr = -40.;
// Associate a cluster to the track.
Int_t mclust = MatchCluster(Track, Xtr, Ytr);
if (fdbg_tracks_cal) {
cout << "GetShEnergy: Track X = " << Xtr << " Y = " << Ytr;
if (mclust >= 0)
cout << " matched cluster # " << mclust << endl;
else
cout << " no matched cluster found" << endl;
}
// Coordinate corrected total energy deposition in the cluster.
Float_t Etrk = 0.;
if (mclust >= 0) { // if there is a matched cluster
// Get matched cluster.
THcShowerCluster* cluster = (*fClusterList).ListedCluster(mclust);
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
// Correct track energy depositions for the impact coordinate.
for (Int_t ip=0; ip<fNLayers; ip++) {
// Coordinate correction factors for positive and negative sides,
// different for single PMT counters in the 1-st two layes and for
// 2 PMT counters in the rear two layers.
Float_t corpos = 1.;
Float_t corneg = 1.;
if (ip < fNegCols) {
corpos = Ycor(Ytr,0);
corneg = Ycor(Ytr,1);
}
else {
corpos = Ycor(Ytr);
corneg = 0.;
}
if (fdbg_tracks_cal) {
cout << " Plane " << ip << " Ytr = " << Ytr
<< " corpos = " << corpos
<< " corneg = " << corneg << endl;
}
Etrk += (*cluster).clEplane(ip,0) * corpos;
Etrk += (*cluster).clEplane(ip,1) * corneg;;
} //over planes
} //mclust>=0
if (fdbg_tracks_cal) cout << " Etrk = " << Etrk << endl;
return Etrk;
}
Simon Zhamkochyan
committed
//_____________________________________________________________________________
Int_t THcShower::FineProcess( TClonesArray& tracks )
{
// Reconstruct coordinates of particle track cross point with shower
// plane, and copy the data into the following local data structure: