CbmDeviceHitBuilderTof.cxx 186.29 KiB
/* Copyright (C) 2018-2021 PI-UHd, GSI
SPDX-License-Identifier: GPL-3.0-only
Authors: Norbert Herrmann [committer] */
/**
* CbmDeviceHitBuilderTof.cxx
*
* @since 2018-05-31
* @author N. Herrmann
*/
#include "CbmDeviceHitBuilderTof.h"
// CBM Classes and includes
#include "CbmDigiManager.h"
// TOF Classes and includes
#include "CbmMatch.h"
#include "CbmTofAddress.h" // in cbmdata/tof
#include "CbmTofCell.h" // in tof/TofData
#include "CbmTofClusterizersDef.h"
#include "CbmTofCreateDigiPar.h" // in tof/TofTools
#include "CbmTofDetectorId_v12b.h" // in cbmdata/tof
#include "CbmTofDetectorId_v14a.h" // in cbmdata/tof
#include "CbmTofDetectorId_v21a.h" // in cbmdata/tof
#include "CbmTofDigi.h" // in cbmdata/tof
#include "CbmTofDigiBdfPar.h" // in tof/TofParam
#include "CbmTofDigiPar.h" // in tof/TofParam
#include "CbmTofGeoHandler.h" // in tof/TofTools
#include "CbmTofHit.h" // in cbmdata/tof
#include "CbmTofPoint.h" // in cbmdata/tof
#include "FairEventHeader.h"
#include "FairFileHeader.h"
#include "FairGeoParSet.h"
#include "FairMQLogger.h"
#include "FairMQProgOptions.h" // device->fConfig
#include "FairRootFileSink.h"
#include "FairRootManager.h"
#include "FairRunOnline.h"
#include "FairRuntimeDb.h"
#include "FairSource.h"
// ROOT Classes and includes
#include "TClonesArray.h"
#include "TDirectory.h"
#include "TF1.h"
#include "TF2.h"
#include "TGeoManager.h"
#include "TH1.h"
#include "TH2.h"
#include "TLine.h"
#include "TMath.h"
#include "TMinuit.h"
#include "TProfile.h"
#include "TROOT.h"
#include "TRandom3.h"
#include "TVector3.h"
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <chrono>
#include <iomanip>
#include <stdexcept>
#include <string>
#include <thread> // this_thread::sleep_for
struct InitTaskError : std::runtime_error {
using std::runtime_error::runtime_error;
};
using namespace std;
// Constants definitions
static Int_t iMess = 0;
static Int_t iIndexDut = 0;
static Double_t StartAnalysisTime = 0.;
//const Double_t cLight = 29.9792; // in cm/ns
static FairRootManager* rootMgr = NULL;
static Int_t iRunId = 1;
static Int_t SelMask = DetMask;
static Double_t dTstart = 0.;
static Double_t dTmax = 0.;
CbmTofDigi* pRef;
CbmTofDigi* pRefCal;
CbmDigiManager* fDigiMan;
CbmDeviceHitBuilderTof::CbmDeviceHitBuilderTof()
: fNumMessages(0)
, fGeoMan(NULL)
, fGeoHandler(new CbmTofGeoHandler())
, fTofId(NULL)
, fDigiPar(NULL)
, fChannelInfo(NULL)
, fDigiBdfPar(NULL)
, fiNDigiIn(0)
, fvDigiIn()
, fEventHeader()
, fEvtHeader(NULL)
, fTofHitsColl(NULL)
, fTofDigiMatchColl(NULL)
, fTofHitsCollOut(NULL)
, fTofDigiMatchCollOut(NULL)
, fiNbHits(0)
, fiNevtBuild(0)
, fiMsgCnt(100)
, fdTOTMax(50.)
, fdTOTMin(0.)
, fdTTotMean(2.)
, fdMaxTimeDist(0.)
, fdMaxSpaceDist(0.)
, fdEvent(0)
, fiMaxEvent(-1)
, fiRunId(111)
, fiOutputTreeEntry(0)
, fiFileIndex(0)
, fStorDigi()
, fStorDigiInd()
, vDigiIndRef()
, fviClusterMul()
, fviClusterSize()
, fviTrkMul()
, fvdX()
, fvdY()
, fvdDifX()
, fvdDifY()
, fvdDifCh()
, fvCPDelTof()
, fvCPTOff()
, fvCPTotGain()
, fvCPTotOff()
, fvCPWalk()
, fvLastHits()
, fvDeadStrips()
, fvPulserOffset()
, fvPulserTimes()
, fhEvDetMul(NULL)
, fhEvDigiMul(NULL)
, fhEvRateIn(NULL)
, fhEvRateOut(NULL)
, fhPulMul(NULL)
, fhDigiTdif(NULL)
, fhPulserTimesRaw()
, fhPulserTimeRawEvo()
, fhPulserTimesCor()
, fhDigiTimesRaw()
, fhDigiTimesCor()
, fhRpcDigiTot()
, fhRpcDigiCor()
, fhRpcCluMul()
, fhRpcCluRate()
, fhRpcCluPosition()
, fhRpcCluDelPos()
, fhRpcCluDelMatPos()
, fhRpcCluTOff()
, fhRpcCluDelTOff()
, fhRpcCluDelMatTOff()
, fhRpcCluTrms()
, fhRpcCluTot()
, fhRpcCluSize()
, fhRpcCluAvWalk()
, fhRpcCluAvLnWalk()
, fhRpcCluWalk()
, fhSmCluPosition()
, fhSmCluTOff()
, fhSmCluSvel()
, fhSmCluFpar()
, fhRpcDTLastHits()
, fhRpcDTLastHits_Tot()
, fhRpcDTLastHits_CluSize()
, fhTRpcCluMul()
, fhTRpcCluPosition()
, fhTRpcCluTOff()
, fhTRpcCluTot()
, fhTRpcCluSize()
, fhTRpcCluAvWalk()
, fhTRpcCluDelTof()
, fhTRpcCludXdY()
, fhTRpcCluWalk()
, fhTSmCluPosition()
, fhTSmCluTOff()
, fhTSmCluTRun()
, fhTRpcCluTOffDTLastHits()
, fhTRpcCluTotDTLastHits()
, fhTRpcCluSizeDTLastHits()
, fhTRpcCluMemMulDTLastHits()
, fhSeldT()
, dTRef(0.)
, fCalMode(0)
, fdCaldXdYMax(0.)
, fiCluMulMax(0)
, fTRefMode(0)
, fTRefHits(0)
, fDutId(0)
, fDutSm(0)
, fDutRpc(0)
, fDutAddr(0)
, fSelId(0)
, fSelSm(0)
, fSelRpc(0)
, fSelAddr(0)
, fSel2Id(0)
, fSel2Sm(0)
, fSel2Rpc(0)
, fSel2Addr(0)
, fiMode(0)
, fiPulserMode(0)
, fiPulMulMin(0)
, fiPulDetRef(0)
, fiPulTotMin(0)
, fiPulTotMax(1000)
, fDetIdIndexMap()
, fviDetId()
, fPosYMaxScal(0.)
, fTRefDifMax(0.)
, fTotMax(0.)
, fTotMin(0.)
, fTotMean(0.)
, fdDelTofMax(60.)
, fMaxTimeDist(0.)
, fdChannelDeadtime(0.)
, fdMemoryTime(0.)
, fEnableMatchPosScaling(kTRUE)
, fbPs2Ns(kFALSE)
, fCalParFileName("")
, fOutHstFileName("")
, fOutRootFileName("")
, fCalParFile(NULL)
, fOutRootFile(NULL)
{
}
CbmDeviceHitBuilderTof::~CbmDeviceHitBuilderTof()
{
if (NULL != fOutRootFile) {
LOG(info) << "Finally close root file " << fOutRootFile->GetName();
fOutRootFile->cd();
rootMgr->LastFill();
rootMgr->Write();
WriteHistograms();
fOutRootFile->Write();
fOutRootFile->Close();
}
}
void CbmDeviceHitBuilderTof::InitTask()
try {
// Get the information about created channels from the device
// Check if the defined channels from the topology (by name)
// are in the list of channels which are possible/allowed
// for the device
// The idea is to check at initilization if the devices are
// properly connected. For the time beeing this is done with a
// nameing convention. It is not avoided that someone sends other
// data on this channel.
int noChannel = fChannels.size();
LOG(info) << "Number of defined input channels: " << noChannel;
for (auto const& entry : fChannels) {
LOG(info) << "Channel name: " << entry.first;
if (!IsChannelNameAllowed(entry.first)) throw InitTaskError("Channel name does not match.");
if (entry.first != "syscmd") OnData(entry.first, &CbmDeviceHitBuilderTof::HandleData);
else
OnData(entry.first, &CbmDeviceHitBuilderTof::HandleMessage);
}
InitWorkspace();
InitContainers();
LoadGeometry();
InitRootOutput();
}
catch (InitTaskError& e) {
LOG(error) << e.what();
ChangeState(fair::mq::Transition::ErrorFound);
}
bool CbmDeviceHitBuilderTof::IsChannelNameAllowed(std::string channelName)
{
for (auto const& entry : fAllowedChannels) {
std::size_t pos1 = channelName.find(entry);
if (pos1 != std::string::npos) {
const vector<std::string>::const_iterator pos =
std::find(fAllowedChannels.begin(), fAllowedChannels.end(), entry);
const vector<std::string>::size_type idx = pos - fAllowedChannels.begin();
LOG(info) << "Found " << entry << " in " << channelName;
LOG(info) << "Channel name " << channelName << " found in list of allowed channel names at position " << idx;
return true;
}
}
LOG(info) << "Channel name " << channelName << " not found in list of allowed channel names.";
LOG(error) << "Stop device.";
return false;
}
Bool_t CbmDeviceHitBuilderTof::InitWorkspace()
{
LOG(info) << "Init work space for CbmDeviceHitBuilderTof.";
fOutRootFileName = fConfig->GetValue<string>("OutRootFile");
fiMaxEvent = fConfig->GetValue<int64_t>("MaxEvent");
LOG(info) << "Max number of events to be processed: " << fiMaxEvent;
fiRunId = fConfig->GetValue<int64_t>("RunId");
fiMode = fConfig->GetValue<int64_t>("Mode");
fiPulserMode = fConfig->GetValue<int64_t>("PulserMode");
fiPulMulMin = fConfig->GetValue<uint64_t>("PulMulMin");
fiPulDetRef = fConfig->GetValue<uint64_t>("PulDetRef");
fiPulTotMin = fConfig->GetValue<uint64_t>("PulTotMin");
fiPulTotMax = fConfig->GetValue<uint64_t>("PulTotMax");
dTmax = (Double_t) fConfig->GetValue<uint64_t>("ReqTint");
//fTofCalDigisColl = new TClonesArray("CbmTofDigi", 100);
//fTofCalDigisCollOut = new TClonesArray("CbmTofDigi", 100);
fTofCalDigiVec = new std::vector<CbmTofDigi>();
fTofHitsColl = new TClonesArray("CbmTofHit", 100);
fTofHitsCollOut = new TClonesArray("CbmTofHit", 100);
fTofDigiMatchColl = new TClonesArray("CbmMatch", 100);
fTofDigiMatchCollOut = new TClonesArray("CbmMatch", 100);
/*
fDigiMan = CbmDigiManager::Instance();
fDigiMan->Init();
if (!fDigiMan->IsPresent(ECbmModuleId::kTof)) {
LOG(error) << "HitBuilder: No digi input!";
//return kFALSE;
}
*/
if (fOutRootFileName != "") { // prepare root output
FairRunOnline* fRun = new FairRunOnline(0);
rootMgr = FairRootManager::Instance();
//fOutRootFile = rootMgr->OpenOutFile(fOutRootFileName);
if (rootMgr->InitSink()) {
fRun->SetSink(new FairRootFileSink(fOutRootFileName));
fOutRootFile = rootMgr->GetOutFile();
if (NULL == fOutRootFile) LOG(fatal) << "could not open root file";
}
else
LOG(fatal) << "could not init Sink";
}
// steering variables
fDutId = fConfig->GetValue<uint64_t>("DutType");
fDutSm = fConfig->GetValue<uint64_t>("DutSm");
fDutRpc = fConfig->GetValue<uint64_t>("DutRpc");
fSelId = fConfig->GetValue<uint64_t>("SelType");
fSelSm = fConfig->GetValue<uint64_t>("SelSm");
fSelRpc = fConfig->GetValue<uint64_t>("SelRpc");
fSel2Id = fConfig->GetValue<uint64_t>("Sel2Type");
fSel2Sm = fConfig->GetValue<uint64_t>("Sel2Sm");
fSel2Rpc = fConfig->GetValue<uint64_t>("Sel2Rpc");
fiBeamRefType = fConfig->GetValue<uint64_t>("BRefType");
fiBeamRefSm = fConfig->GetValue<uint64_t>("BRefSm");
fiBeamRefDet = fConfig->GetValue<uint64_t>("BRefDet");
return kTRUE;
}
Bool_t CbmDeviceHitBuilderTof::InitRootOutput()
{
if (NULL != fOutRootFile) {
LOG(info) << "Init Root Output to " << fOutRootFile->GetName();
/*
fFileHeader->SetRunId(iRunId);
rootMgr->WriteFileHeader(fFileHeader);
*/
rootMgr->InitSink();
fEvtHeader = new FairEventHeader();
fEvtHeader->SetRunId(iRunId);
rootMgr->Register("EventHeader.", "Event", fEvtHeader, kTRUE);
auto source = rootMgr->GetSource();
if (source) { source->FillEventHeader(fEvtHeader); }
// rootMgr->Register("CbmTofDigi", "Tof raw Digi", fTofCalDigisColl, kTRUE);
// fOutRootFile->cd();
// rootMgr->RegisterAny("TofCalDigi", fTofCalDigiVec, kTRUE);
rootMgr->RegisterAny("TofDigi", fTofCalDigiVec, kTRUE);
TTree* outTree = new TTree(FairRootManager::GetTreeName(), "/cbmout", 99);
LOG(info) << "define Tree " << outTree->GetName();
//rootMgr->TruncateBranchNames(outTree, "cbmout");
//rootMgr->SetOutTree(outTree);
rootMgr->GetSink()->SetOutTree(outTree);
rootMgr->WriteFolder();
LOG(info) << "Initialized outTree with rootMgr at " << rootMgr;
/*
/// Save old global file and folder pointer to avoid messing with FairRoot
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
fOutRootFile = new TFile(fOutRootFileName,"recreate");
fRootEvent = new TTree("CbmEvent","Cbm Event");
fRootEvent->Branch("CbmDigi",fTofCalDigisColl);
LOG(info)<<"Open Root Output file " << fOutRootFileName;
fRootEvent->Write();
/// Restore old global file and folder pointer to avoid messing with FairRoot
gFile = oldFile;
gDirectory = oldDir;
*/
}
return kTRUE;
}
Bool_t CbmDeviceHitBuilderTof::InitContainers()
{
LOG(info) << "Init parameter containers for CbmDeviceHitBuilderTof.";
FairRuntimeDb* fRtdb = FairRuntimeDb::instance();
if (NULL == fRtdb) LOG(error) << "No FairRuntimeDb found";
// NewSimpleMessage creates a copy of the data and takes care of its destruction (after the transfer takes place).
// Should only be used for small data because of the cost of an additional copy
// Int_t fiRunId=1535700811; // from *geo*.par.root file
Int_t NSet = 3;
std::string parSet[NSet];
parSet[0] = "CbmTofDigiPar";
parSet[1] = "CbmTofDigiBdfPar";
parSet[2] = "FairGeoParSet";
std::string Channel = "parameters";
Bool_t isSimulation = kFALSE;
Int_t iGeoVersion;
FairParSet* cont;
for (Int_t iSet = 1; iSet < NSet; iSet++) {
std::string message = parSet[iSet] + "," + to_string(fiRunId);
LOG(info) << "Requesting parameter container, sending message: " << message;
FairMQMessagePtr req(NewSimpleMessage(message));
//FairMQMessagePtr req(NewSimpleMessage( "CbmTofDigiBdfPar,111" )); //original format
FairMQMessagePtr rep(NewMessage());
CbmTofCreateDigiPar* tofDigiPar = NULL;
if (Send(req, Channel) > 0) {
if (Receive(rep, Channel) >= 0) {
if (rep->GetSize() != 0) {
CbmMqTMessage tmsg(rep->GetData(), rep->GetSize());
switch (iSet) {
case 0:
fDigiPar = static_cast<CbmTofDigiPar*>(tmsg.ReadObject(tmsg.GetClass()));
//fDigiPar->print();
break;
case 1:
fDigiBdfPar = static_cast<CbmTofDigiBdfPar*>(tmsg.ReadObject(tmsg.GetClass()));
//fDigiBdfPar->print();
LOG(info) << "Calib data file: " << fDigiBdfPar->GetCalibFileName();
fdMaxTimeDist = fDigiBdfPar->GetMaxTimeDist(); // in ns
fdMaxSpaceDist = fDigiBdfPar->GetMaxDistAlongCh(); // in cm
if (fMaxTimeDist != fdMaxTimeDist) {
fdMaxTimeDist = fMaxTimeDist; // modify default
fdMaxSpaceDist = fdMaxTimeDist * fDigiBdfPar->GetSignalSpeed()
* 0.5; // cut consistently on positions (with default signal velocity)
}
break;
case 2: // Geometry container
cont = static_cast<FairParSet*>(tmsg.ReadObject(tmsg.GetClass()));
cont->init();
cont->Print();
//fRtdb->InitContainer(parSet[iSet]);
if (NULL == fGeoMan) fGeoMan = (TGeoManager*) ((FairGeoParSet*) cont)->GetGeometry(); //crashes
LOG(info) << "GeoMan: " << fGeoMan << " " << gGeoManager;
iGeoVersion = fGeoHandler->Init(isSimulation);
if (k21a > iGeoVersion) {
LOG(error) << "Incompatible geometry !!!";
ChangeState(fair::mq::Transition::Stop);
}
switch (iGeoVersion) {
case k14a: fTofId = new CbmTofDetectorId_v14a(); break;
case k21a: fTofId = new CbmTofDetectorId_v21a(); break;
}
if (NULL == fDigiPar) {
if (NULL == fRtdb) {
LOG(info) << "Instantiate FairRunDb";
fRtdb = FairRuntimeDb::instance();
assert(fRtdb);
}
// create digitization parameters from geometry file
tofDigiPar = new CbmTofCreateDigiPar("TOF Digi Producer", "TOF task");
LOG(info) << "Create DigiPar ";
tofDigiPar->Init();
fDigiPar = (CbmTofDigiPar*) (fRtdb->getContainer("CbmTofDigiPar"));
if (NULL == fDigiPar) {
LOG(error) << "CbmTofEventClusterizer::InitParameters => Could not obtain CbmTofDigiPar";
return kFALSE;
}
}
gGeoManager->Export("HitBuilder.geo.root");
break;
case 3: // Calib
break;
default: LOG(warn) << "Parameter Set " << iSet << " not implemented ";
}
LOG(info) << "Received parameter from server:";
}
else {
LOG(warn) << "Received empty reply. Parameter not available";
}
}
}
}
Bool_t initOK = ReInitContainers();
CreateHistograms();
if (!InitCalibParameter()) return kFALSE; // ChangeState(PAUSE); // for debugging
fDutAddr = CbmTofAddress::GetUniqueAddress(fDutSm, fDutRpc, 0, 0, fDutId);
fSelAddr = CbmTofAddress::GetUniqueAddress(fSelSm, fSelRpc, 0, 0, fSelId);
fSel2Addr = CbmTofAddress::GetUniqueAddress(fSel2Sm, fSel2Rpc, 0, 0, fSel2Id);
if (fiBeamRefType > -1) {
if (fiBeamRefDet > -1) {
fiBeamRefAddr = CbmTofAddress::GetUniqueAddress(fiBeamRefSm, fiBeamRefDet, 0, 0, fiBeamRefType);
}
else {
SelMask = ModMask;
fiBeamRefAddr = CbmTofAddress::GetUniqueAddress(fiBeamRefSm, 0, 0, 0, fiBeamRefType);
}
}
else
fiBeamRefAddr = -1;
iIndexDut = fDigiBdfPar->GetDetInd(fDutAddr);
LOG(info) << Form("Use Dut 0x%08x, Sel 0x%08x, Sel2 0x%08x, BRef 0x%08x", fDutAddr, fSelAddr, fSel2Addr,
fiBeamRefAddr);
return initOK;
}
Bool_t CbmDeviceHitBuilderTof::ReInitContainers()
{
LOG(info) << "ReInit parameter containers for CbmDeviceHitBuilderTof.";
return kTRUE;
}
// handler is called whenever a message arrives on "data", with a reference to the message and a sub-channel index (here 0)
//bool CbmDeviceHitBuilderTof::HandleData(FairMQMessagePtr& msg, int /*index*/)
bool CbmDeviceHitBuilderTof::HandleData(FairMQParts& parts, int /*index*/)
{
// Don't do anything with the data
// Maybe add an message counter which counts the incomming messages and add
// an output
fNumMessages++;
LOG(debug) << "Received message " << fNumMessages << " with " << parts.Size() << " parts"
<< ", size0: " << parts.At(0)->GetSize();
std::string msgStrE(static_cast<char*>(parts.At(0)->GetData()), (parts.At(0))->GetSize());
std::istringstream issE(msgStrE);
boost::archive::binary_iarchive inputArchiveE(issE);
inputArchiveE >> fEventHeader;
LOG(debug) << "EventHeader: " << fEventHeader[0] << " " << fEventHeader[1] << " " << fEventHeader[2] << " "
<< fEventHeader[3] << " " << fEventHeader[4];
fiNDigiIn = 0;
// LOG(debug) << "Received message # "<< fNumMessages
// << " with size " << msg->GetSize()<<" at "<< msg->GetData();
//std::string msgStr(static_cast<char*>(msg->GetData()), msg->GetSize());
std::string msgStr(static_cast<char*>(parts.At(1)->GetData()), (parts.At(1))->GetSize());
std::istringstream iss(msgStr);
boost::archive::binary_iarchive inputArchive(iss);
std::vector<CbmTofDigi*> vdigi;
inputArchive >> vdigi;
/* ---- for debugging ----------------
int *pData = static_cast <int *>(msg->GetData());
for (int iData=0; iData<msg->GetSize()/NBytes; iData++) {
LOG(info) << Form(" ind %d, poi %p, data: 0x%08x",iData,pData,*pData++);
}
*/
//vector descriptor and data separated -> transfer of vectors does not work reliably
//std::vector<CbmTofDigi>* vdigi = static_cast<std::vector<CbmTofDigi>*>(msg->GetData());
// (*vdigi).resize(fiNDigiIn);
LOG(debug) << "vdigi vector at " << vdigi.data() << " with size " << vdigi.size();
for (UInt_t iDigi = 0; iDigi < vdigi.size(); iDigi++) {
LOG(debug) << "#" << iDigi << " " << vdigi[iDigi]->ToString();
}
/*
const Int_t iNDigiIn=100;
std::array<CbmTofDigi,iNDigiIn> *aTofDigi = static_cast<std::array<CbmTofDigi,iNDigiIn>*>(msg->GetData());
for (int iDigi=0; iDigi<fiNDigiIn; iDigi++) {
LOG(info) << "#" << iDigi << " " <<(*aTofDigi)[iDigi].ToString();
}
pDigiIn=static_cast<CbmTofDigi*> (msg->GetData());
CbmTofDigi* pDigi=pDigiIn;
CbmTofDigi aTofDigi[fiNDigiIn];
for (int iDigi=0; iDigi<fiNDigiIn; iDigi++) {
//aTofDigi[iDigi] = *pDigi++;
aTofDigi[iDigi] = *pDigi;
fvDigiIn[iDigi] = *pDigi;
LOG(info) << "#" << iDigi << " at "<<pDigi<< " " <<aTofDigi[iDigi].ToString();
// LOG(info) << "#" << iDigi << " at "<<pDigi<< " " <<pDigi->ToString(); // does not work ???
pDigi++;
}
*/
fiNDigiIn = vdigi.size();
fvDigiIn.resize(fiNDigiIn);
for (int iDigi = 0; iDigi < fiNDigiIn; iDigi++) {
fvDigiIn[iDigi] = *vdigi[iDigi];
// Remap Digis for v21a_cosmicHD
if (1) {
int iSmType = 8;
int iSm = -1;
int iRpc = 0;
int iDetId = 0;
CbmTofDigi* pDigi = &fvDigiIn[iDigi];
if (pDigi->GetType() == 6 && pDigi->GetRpc() == 1) {
switch ((int) (pDigi->GetChannel() * 2 + pDigi->GetSide())) {
case 62: //800
iSm = 0;
break;
case 46: //810
iSm = 1;
break;
case 22: //820
iSm = 2;
break;
case 2: //830
iSm = 3;
break;
default:;
}
if (iSm > -1) {
iDetId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, 0, 0, iSmType);
pDigi->SetAddress(iDetId);
}
}
} //remapping end
delete vdigi[iDigi];
}
vdigi.clear();
// for( Int_t i = 0; i < fTofCalDigisColl->GetEntriesFast(); i++ ) ((CbmTofDigi*) fTofCalDigisColl->At(i))->Delete();
// fTofCalDigisColl->Clear("C");
// for( Int_t i = 0; i < fTofHitsColl->GetEntriesFast(); i++ ) ((CbmTofHit*) fTofHitsColl->At(i))->Delete();
fTofHitsColl->Clear("C");
//fTofHitsColl->Delete(); // Are the elements deleted?
//fTofHitsColl = new TClonesArray("CbmTofHit",100);
//for( Int_t i = 0; i < fTofDigiMatchColl->GetEntriesFast(); i++ ) ((CbmMatch*) fTofDigiMatchColl->At(i))->Delete();
fTofDigiMatchColl->Clear("C");
fiNbHits = 0;
if (fNumMessages % 10000 == 0) LOG(info) << "Processed " << fNumMessages << " messages";
if (fEventHeader.size() > 3) {
fhPulMul->Fill((Double_t) fEventHeader[3]);
if (fEventHeader[3] > 0) {
//LOG(debug) << "Pulser event found, Mul "<< fEventHeader[3];
if (!MonitorPulser()) return kFALSE;
return kTRUE; // separate events from pulser
}
}
LOG(debug) << " Process msg " << fNumMessages << " at evt " << fdEvent << ", PulMode " << fiPulserMode;
if (fiPulserMode > 0) { // don't process events without valid pulser correction
if (fvPulserTimes[fiPulDetRef][0].size() == 0) return kTRUE;
}
fdEvent++;
fhEvDetMul->Fill((Double_t) fEventHeader[1]);
fhEvDigiMul->Fill(fiNDigiIn);
if (fiNDigiIn > 0) {
if (dTstart == 0) {
dTstart = fvDigiIn[0].GetTime() + fEventHeader[4];
LOG(info) << "Start time set to " << dTstart / 1.E9 << " sec ";
}
fhEvRateIn->Fill((fvDigiIn[0].GetTime() + fEventHeader[4] - dTstart) / 1.E9);
}
if (!InspectRawDigis()) return kFALSE;
if (fiPulserMode > 0)
if (!ApplyPulserCorrection()) return kFALSE;
if (!BuildClusters()) return kFALSE;
//if(!MergeClusters()) return kFALSE;
if (NULL != fOutRootFile) { // CbmEvent output to root file
fEvtHeader->SetEventTime((double) fEventHeader[4]);
auto source = rootMgr->GetSource();
if (source) { source->FillEventHeader(fEvtHeader); }
//LOG(info) << "Fill WriteOutBuffer with rootMgr at " << rootMgr;
fOutRootFile->cd();
rootMgr->Fill();
rootMgr->StoreWriteoutBufferData(rootMgr->GetEventTime());
fhEvRateOut->Fill((fvDigiIn[0].GetTime() + fEventHeader[4] - dTstart) / 1.E9);
//rootMgr->StoreAllWriteoutBufferData();
rootMgr->DeleteOldWriteoutBufferData();
if ((Int_t) fdEvent == fiMaxEvent) {
rootMgr->Write();
WriteHistograms();
fOutRootFile->Close();
LOG(info) << "File closed after " << fdEvent << " events. ";
ChangeState(fair::mq::Transition::Stop);
}
}
if (!FillHistos()) return kTRUE; // event not selected for histogramming, skip sending it
//if(!SendHits()) return kFALSE;
if (!SendAll()) return kFALSE;
return kTRUE;
}
/************************************************************************************/
bool CbmDeviceHitBuilderTof::HandleMessage(FairMQMessagePtr& msg, int /*index*/)
{
const char* cmd = (char*) (msg->GetData());
const char cmda[4] = {*cmd};
LOG(info) << "Handle message " << cmd << ", " << cmd[0];
//LOG(info) << "Current State: " << fair::mq::StateMachine::GetCurrentStateName();
// only one implemented so far "Stop"
if (NULL != fOutRootFile) {
LOG(info) << "Close root file " << fOutRootFile->GetName();
fOutRootFile->cd();
rootMgr->LastFill();
rootMgr->Write();
WriteHistograms();
fOutRootFile->Write();
fOutRootFile->Close();
}
if (strcmp(cmda, "STOP")) {
LOG(info) << "STOP";
/* Invalid syntax
ChangeState(internal_READY);
LOG(info) << "Current State: " << FairMQStateMachine::GetCurrentStateName();
ChangeState(internal_DEVICE_READY);
LOG(info) << "Current State: " << FairMQStateMachine::GetCurrentStateName();
ChangeState(internal_IDLE);
LOG(info) << "Current State: " << FairMQStateMachine::GetCurrentStateName();
ChangeState(END);
LOG(info) << "Current State: " << FairMQStateMachine::GetCurrentStateName();
*/
ChangeState(fair::mq::Transition::Stop);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
ChangeState(fair::mq::Transition::End);
}
return true;
}
/************************************************************************************/
Bool_t CbmDeviceHitBuilderTof::InitCalibParameter()
{
// dimension and initialize calib parameter
// Int_t iNbDet = fDigiBdfPar->GetNbDet();
Int_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes();
fTotMean = 1.;
fCalMode = -1;
if (fTotMean != 0.) fdTTotMean = fTotMean; // adjust target mean for TTT
fvCPTOff.resize(iNbSmTypes);
fvCPTotGain.resize(iNbSmTypes);
fvCPTotOff.resize(iNbSmTypes);
fvCPWalk.resize(iNbSmTypes);
fvCPDelTof.resize(iNbSmTypes);
for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
fvCPTOff[iSmType].resize(iNbSm * iNbRpc);
fvCPTotGain[iSmType].resize(iNbSm * iNbRpc);
fvCPTotOff[iSmType].resize(iNbSm * iNbRpc);
fvCPWalk[iSmType].resize(iNbSm * iNbRpc);
fvCPDelTof[iSmType].resize(iNbSm * iNbRpc);
for (Int_t iSm = 0; iSm < iNbSm; iSm++) {
for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
//LOG(info)<<Form(" fvCPDelTof resize for SmT %d, R %d, B %d ",iSmType,iNbSm*iNbRpc,nbClDelTofBinX);
fvCPDelTof[iSmType][iSm * iNbRpc + iRpc].resize(nbClDelTofBinX);
for (Int_t iBx = 0; iBx < nbClDelTofBinX; iBx++) {
// LOG(info)<<Form(" fvCPDelTof for SmT %d, R %d, B %d",iSmType,iSm*iNbRpc+iRpc,iBx);
fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx].resize(iNSel);
for (Int_t iSel = 0; iSel < iNSel; iSel++)
fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx][iSel] = 0.; // initialize
}
Int_t iNbChan = fDigiBdfPar->GetNbChan(iSmType, iRpc);
fvCPTOff[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
fvCPTotGain[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
fvCPTotOff[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
fvCPWalk[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
Int_t nbSide = 2 - fDigiBdfPar->GetChanType(iSmType, iRpc);
for (Int_t iCh = 0; iCh < iNbChan; iCh++) {
fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
fvCPTotOff[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh].resize(nbSide);
for (Int_t iSide = 0; iSide < nbSide; iSide++) {
fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] = 0.; //initialize
fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] = 1.; //initialize
fvCPTotOff[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] = 0.; //initialize
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][iSide].resize(nbClWalkBinX);
for (Int_t iWx = 0; iWx < nbClWalkBinX; iWx++) {
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][iSide][iWx] = 0.;
}
}
}
}
}
}
LOG(info) << "defaults set";
/// Save old global file and folder pointer to avoid messing with FairRoot
// <= To prevent histos from being sucked in by the param file of the TRootManager!
TFile* oldFile = gFile;
TDirectory* oldDir = gDirectory;
if (0 < fCalMode) {
fCalParFileName = fDigiBdfPar->GetCalibFileName();
LOG(info) << "InitCalibParameter: read histos from "
<< "file " << fCalParFileName;
// read parameter from histos
if (fCalParFileName.IsNull()) return kTRUE;
fCalParFile = new TFile(fCalParFileName, "");
if (NULL == fCalParFile) {
LOG(error) << "InitCalibParameter: "
<< "file " << fCalParFileName << " does not exist!";
ChangeState(fair::mq::Transition::Stop);
}
/*
gDirectory->Print();
fCalParFile->cd();
fCalParFile->ls();
*/
for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
TProfile* hSvel = (TProfile*) gDirectory->FindObjectAny(Form("cl_SmT%01d_Svel", iSmType));
// copy Histo to memory
TDirectory* curdir = gDirectory;
if (NULL != hSvel) {
gDirectory->cd(oldDir->GetPath());
//TProfile *hSvelmem =
//(TProfile*) hSvel->Clone();
gDirectory->cd(curdir->GetPath());
}
else {
LOG(info) << "Svel histogram not found for module type " << iSmType;
}
for (Int_t iPar = 0; iPar < 4; iPar++) {
TProfile* hFparcur = (TProfile*) gDirectory->FindObjectAny(Form("cl_SmT%01d_Fpar%1d", iSmType, iPar));
if (NULL != hFparcur) {
gDirectory->cd(oldDir->GetPath());
//TProfile *hFparmem =
//(TProfile*) hFparcur->Clone();
gDirectory->cd(curdir->GetPath());
}
}
for (Int_t iSm = 0; iSm < iNbSm; iSm++)
for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
// update default parameter
if (NULL != hSvel) {
Double_t Vscal = 1.; //hSvel->GetBinContent(iSm*iNbRpc+iRpc+1);
if (Vscal == 0.) Vscal = 1.;
fDigiBdfPar->SetSigVel(iSmType, iSm, iRpc, fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * Vscal);
LOG(info) << "Modify " << iSmType << iSm << iRpc << " Svel by " << Vscal << " to "
<< fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc);
}
TH2F* htempPos_pfx =
(TH2F*) gDirectory->FindObjectAny(Form("cl_CorSmT%01d_sm%03d_rpc%03d_Pos_pfx", iSmType, iSm, iRpc));
TH2F* htempTOff_pfx =
(TH2F*) gDirectory->FindObjectAny(Form("cl_CorSmT%01d_sm%03d_rpc%03d_TOff_pfx", iSmType, iSm, iRpc));
TH1D* htempTot_Mean =
(TH1D*) gDirectory->FindObjectAny(Form("cl_CorSmT%01d_sm%03d_rpc%03d_Tot_Mean", iSmType, iSm, iRpc));
TH1D* htempTot_Off =
(TH1D*) gDirectory->FindObjectAny(Form("cl_CorSmT%01d_sm%03d_rpc%03d_Tot_Off", iSmType, iSm, iRpc));
if (NULL != htempPos_pfx && NULL != htempTOff_pfx && NULL != htempTot_Mean && NULL != htempTot_Off) {
Int_t iNbCh = fDigiBdfPar->GetNbChan(iSmType, iRpc);
Int_t iNbinTot = htempTot_Mean->GetNbinsX();
for (Int_t iCh = 0; iCh < iNbCh; iCh++) {
Double_t YMean = ((TProfile*) htempPos_pfx)->GetBinContent(iCh + 1); //nh +1 empirical(?)
Double_t TMean = ((TProfile*) htempTOff_pfx)->GetBinContent(iCh + 1);
//Double_t dTYOff=YMean/fDigiBdfPar->GetSignalSpeed() ;
Double_t dTYOff = YMean / fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc);
fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][0] += -dTYOff + TMean;
fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][1] += +dTYOff + TMean;
for (Int_t iSide = 0; iSide < 2; iSide++) {
Double_t TotMean = htempTot_Mean->GetBinContent(iCh * 2 + 1 + iSide); //nh +1 empirical(?)
if (0.001 < TotMean) { fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] *= fdTTotMean / TotMean; }
fvCPTotOff[iSmType][iSm * iNbRpc + iRpc][iCh][iSide] = htempTot_Off->GetBinContent(iCh * 2 + 1 + iSide);
}
if (5 == iSmType || 8 == iSmType) {
fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][1] = fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][0];
fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][1] = fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][0];
fvCPTotOff[iSmType][iSm * iNbRpc + iRpc][iCh][1] = fvCPTotOff[iSmType][iSm * iNbRpc + iRpc][iCh][0];
}
LOG(debug) << "InitCalibParameter:"
<< " SmT " << iSmType << " Sm " << iSm << " Rpc " << iRpc << " Ch " << iCh
<< Form(": YMean %f, TMean %f", YMean, TMean) << " -> "
<< Form(" %f, %f, %f, %f ", fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][0],
fvCPTOff[iSmType][iSm * iNbRpc + iRpc][iCh][1],
fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][0],
fvCPTotGain[iSmType][iSm * iNbRpc + iRpc][iCh][1])
<< ", NbinTot " << iNbinTot;
TH1D* htempWalk0 = (TH1D*) gDirectory->FindObjectAny(
Form("Cor_SmT%01d_sm%03d_rpc%03d_Ch%03d_S0_Walk_px", iSmType, iSm, iRpc, iCh));
TH1D* htempWalk1 = (TH1D*) gDirectory->FindObjectAny(
Form("Cor_SmT%01d_sm%03d_rpc%03d_Ch%03d_S1_Walk_px", iSmType, iSm, iRpc, iCh));
if (NULL != htempWalk0 && NULL != htempWalk1) { // reinitialize Walk array
LOG(debug) << "Initialize Walk correction for "
<< Form(" SmT%01d_sm%03d_rpc%03d_Ch%03d", iSmType, iSm, iRpc, iCh);
if (htempWalk0->GetNbinsX() != nbClWalkBinX)
LOG(error) << "InitCalibParameter: Inconsistent Walk histograms";
for (Int_t iBin = 0; iBin < nbClWalkBinX; iBin++) {
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][0][iBin] = htempWalk0->GetBinContent(iBin + 1);
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][1][iBin] = htempWalk1->GetBinContent(iBin + 1);
//LOG(debug)<<Form(" SmT%01d_sm%03d_rpc%03d_Ch%03d bin %d walk %f ",iSmType, iSm, iRpc, iCh, iBin,
// fvCPWalk[iSmType][iSm*iNbRpc+iRpc][iCh][0][iBin]);
if (5 == iSmType || 8 == iSmType) { // Pad structure
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][1][iBin] =
fvCPWalk[iSmType][iSm * iNbRpc + iRpc][iCh][0][iBin];
}
}
}
}
}
else {
LOG(warn) << " Calibration histos " << Form("cl_SmT%01d_sm%03d_rpc%03d_XXX", iSmType, iSm, iRpc)
<< " not found. ";
}
for (Int_t iSel = 0; iSel < iNSel; iSel++) {
TH1D* htmpDelTof = (TH1D*) gDirectory->FindObjectAny(
Form("cl_CorSmT%01d_sm%03d_rpc%03d_Sel%02d_DelTof", iSmType, iSm, iRpc, iSel));
if (NULL == htmpDelTof) {
LOG(debug) << " Histos " << Form("cl_CorSmT%01d_sm%03d_rpc%03d_Sel%02d_DelTof", iSmType, iSm, iRpc, iSel)
<< " not found. ";
continue;
}
LOG(debug) << " Load DelTof from histos "
<< Form("cl_CorSmT%01d_sm%03d_rpc%03d_Sel%02d_DelTof", iSmType, iSm, iRpc, iSel) << ".";
for (Int_t iBx = 0; iBx < nbClDelTofBinX; iBx++) {
fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx][iSel] += htmpDelTof->GetBinContent(iBx + 1);
}
// copy Histo to memory
// TDirectory * curdir = gDirectory;
gDirectory->cd(oldDir->GetPath());
TH1D* h1DelTof =
(TH1D*) htmpDelTof->Clone(Form("cl_CorSmT%01d_sm%03d_rpc%03d_Sel%02d_DelTof", iSmType, iSm, iRpc, iSel));
LOG(debug) << " copy histo " << h1DelTof->GetName() << " to directory " << oldDir->GetName();
gDirectory->cd(curdir->GetPath());
}
}
}
}
// fCalParFile->Delete();
/// Restore old global file and folder pointer to avoid messing with FairRoot
// <= To prevent histos from being sucked in by the param file of the TRootManager!
gFile = oldFile;
gDirectory = oldDir;
LOG(info) << "InitCalibParameter: initialization done";
return kTRUE;
}
static TH2F* fhBucDigiCor = NULL;
/************************************************************************************/
// Histogram definitions
void CbmDeviceHitBuilderTof::CreateHistograms()
{
TDirectory* oldir = gDirectory; // <= To prevent histos from being sucked in by the param file of the TRootManager!
gROOT->cd(); // <= To prevent histos from being sucked in by the param file of the TRootManager !
// process event header info
fhEvDetMul = new TH1F("hEvDetMul", "Detector multiplicity of Selector; Mul", 50, 0, 50);
fhEvDigiMul = new TH1F("hEvDigiMul", "Digi multiplicity of Selector; Mul", 1000, 0, 10000);
fhEvRateIn = new TH1F("hEvRateIn", "Incoming Event rate; time (s); rate (Hz)", 10000, 0, 10000);
fhEvRateOut = new TH1F("hEvRateOut", "Outgoing Event rate; time (s); rate (Hz)", 10000, 0, 10000);
fhPulMul = new TH1F("hPulMul", "Pulser multiplicity; Mul", 110, 0, 110);
fhDigiTdif = new TH1F("hDigiTdif", "Digi time difference; #Deltat ns)", 8000, -20, 20);
Int_t iNDet = 0;
dTmax *= 2; // cover full range of selector
for (Int_t iModTyp = 0; iModTyp < 10; iModTyp++)
iNDet += fDigiBdfPar->GetNbSm(iModTyp) * fDigiBdfPar->GetNbRpc(iModTyp);
fhPulserTimesRaw = new TH2F(Form("hPulserTimesRaw"), Form("Pulser Times uncorrected; Det# []; t - t0 [ns]"),
iNDet * 2, 0, iNDet * 2, 999, -dTmax, dTmax);
fhPulserTimeRawEvo.resize(iNDet * 2);
for (Int_t iDetSide = 0; iDetSide < iNDet * 2; iDetSide++) {
fhPulserTimeRawEvo[iDetSide] = new TProfile(
Form("hPulserTimeRawEvo_%d", iDetSide),
Form("Raw Pulser TimeEvolution %d; PulserEvent# ; DeltaT [ns] ", iDetSide), 1000, 0., 1.E5, -dTmax, dTmax);
}
fhPulserTimesCor = new TH2F(Form("hPulserTimesCor"), Form("Pulser Times corrected; Det# []; t - t0 [ns]"), iNDet * 2,
0, iNDet * 2, 999, -10., 10.);
fhDigiTimesRaw = new TH2F(Form("hDigiTimesRaw"), Form("Digi Times uncorrected; Det# []; t - t0 [ns]"), iNDet * 2, 0,
iNDet * 2, 999, -dTmax, dTmax);
fhDigiTimesCor = new TH2F(Form("hDigiTimesCor"), Form("Digi Times corrected; Det# []; t - t0 [ns]"), iNDet * 2, 0,
iNDet * 2, 999, -dTmax, dTmax);
fhBucDigiCor = new TH2F(Form("hBucDigiCor"), Form("Buc Digi Correlation; ch1 []; ch2 []"), 128, 0, 128, 128, 0, 128);
Int_t iNbDet = fDigiBdfPar->GetNbDet();
fDetIdIndexMap.clear();
fhRpcDigiTot.resize(iNbDet);
fhRpcDigiCor.resize(iNbDet);
fviDetId.resize(iNbDet);
for (Int_t iDetIndx = 0; iDetIndx < iNbDet; iDetIndx++) {
Int_t iUniqueId = fDigiBdfPar->GetDetUId(iDetIndx);
fDetIdIndexMap[iUniqueId] = iDetIndx;
fviDetId[iDetIndx] = iUniqueId;
Int_t iSmType = CbmTofAddress::GetSmType(iUniqueId);
Int_t iSmId = CbmTofAddress::GetSmId(iUniqueId);
Int_t iRpcId = CbmTofAddress::GetRpcId(iUniqueId);
LOG(info) << "Index map entry " << iDetIndx << ": TSR " << iSmType << iSmId << iRpcId
<< Form(", addr 0x%08x", iUniqueId);
fhRpcDigiTot[iDetIndx] = new TH2F(
Form("hDigiTot_SmT%01d_sm%03d_rpc%03d", iSmType, iSmId, iRpcId),
Form("Digi Tot of Rpc #%03d in Sm %03d of type %d; digi 0; digi 1", iRpcId, iSmId, iSmType),
2 * fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, 2 * fDigiBdfPar->GetNbChan(iSmType, iRpcId), 256, 0, 256);
fhRpcDigiCor[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_DigiCor", iSmType, iSmId, iRpcId),
Form("Digi Correlation of Rpc #%03d in Sm %03d of type %d; digi 0; digi 1", iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId));
}
if (0 == fiMode) return; // no cluster histograms needed
// Sm related distributions
fhSmCluPosition.resize(fDigiBdfPar->GetNbSmTypes());
fhSmCluTOff.resize(fDigiBdfPar->GetNbSmTypes());
fhSmCluSvel.resize(fDigiBdfPar->GetNbSmTypes());
fhSmCluFpar.resize(fDigiBdfPar->GetNbSmTypes());
fhTSmCluPosition.resize(fDigiBdfPar->GetNbSmTypes());
fhTSmCluTOff.resize(fDigiBdfPar->GetNbSmTypes());
fhTSmCluTRun.resize(fDigiBdfPar->GetNbSmTypes());
for (Int_t iS = 0; iS < fDigiBdfPar->GetNbSmTypes(); iS++) {
Double_t YSCAL = 50.;
if (fPosYMaxScal != 0.) YSCAL = fPosYMaxScal;
Int_t iUCellId(0);
fChannelInfo = NULL;
// Cover the case that the geometry file does not contain the module
// indexed with 0 of a certain module type BUT modules with higher indices.
for (Int_t iSM = 0; iSM < fDigiBdfPar->GetNbSm(iS); iSM++) {
iUCellId = CbmTofAddress::GetUniqueAddress(iSM, 0, 0, 0, iS);
fChannelInfo = fDigiPar->GetCell(iUCellId);
// Retrieve geometry information from the first module of a certain
// module type that is found in the geometry file.
if (NULL != fChannelInfo) { break; }
}
if (NULL == fChannelInfo) {
LOG(warn) << "No DigiPar for SmType " << Form("%d, 0x%08x", iS, iUCellId);
continue;
}
Double_t YDMAX = TMath::Max(2., fChannelInfo->GetSizey()) * YSCAL;
fhSmCluPosition[iS] =
new TH2F(Form("cl_SmT%01d_Pos", iS), Form("Clu position of SmType %d; Sm+Rpc# []; ypos [cm]", iS),
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0,
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 99, -YDMAX, YDMAX);
Double_t TSumMax = 1.E3;
if (fTRefDifMax != 0.) TSumMax = fTRefDifMax;
fhSmCluTOff[iS] =
new TH2F(Form("cl_SmT%01d_TOff", iS), Form("Clu TimeZero in SmType %d; Sm+Rpc# []; TOff [ns]", iS),
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0,
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 99, -TSumMax, TSumMax);
TProfile* hSvelcur = (TProfile*) gDirectory->FindObjectAny(Form("cl_SmT%01d_Svel", iS));
if (NULL == hSvelcur) {
fhSmCluSvel[iS] =
new TProfile(Form("cl_SmT%01d_Svel", iS), Form("Clu Svel in SmType %d; Sm+Rpc# []; v/v_{nominal} ", iS),
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0,
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0.8, 1.2);
fhSmCluSvel[iS]->Sumw2();
}
else
fhSmCluSvel[iS] = (TProfile*) hSvelcur->Clone();
fhSmCluFpar[iS].resize(4);
for (Int_t iPar = 0; iPar < 4; iPar++) {
TProfile* hFparcur = (TProfile*) gDirectory->FindObjectAny(Form("cl_SmT%01d_Fpar%1d", iS, iPar));
if (NULL == hFparcur) {
LOG(info) << "Histo " << Form("cl_SmT%01d_Fpar%1d", iS, iPar) << " not found, recreate ...";
fhSmCluFpar[iS][iPar] = new TProfile(Form("cl_SmT%01d_Fpar%1d", iS, iPar),
Form("Clu Fpar %d in SmType %d; Sm+Rpc# []; value ", iPar, iS),
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0,
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), -dTmax, dTmax);
}
else
fhSmCluFpar[iS][iPar] = (TProfile*) hFparcur->Clone();
}
fhTSmCluPosition[iS].resize(iNSel);
fhTSmCluTOff[iS].resize(iNSel);
fhTSmCluTRun[iS].resize(iNSel);
for (Int_t iSel = 0; iSel < iNSel; iSel++) { // Loop over selectors
fhTSmCluPosition[iS][iSel] = new TH2F(Form("cl_TSmT%01d_Sel%02d_Pos", iS, iSel),
Form("Clu position of SmType %d under Selector %02d; Sm+Rpc# "
"[]; ypos [cm]",
iS, iSel),
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0,
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 99, -YDMAX, YDMAX);
fhTSmCluTOff[iS][iSel] = new TH2F(Form("cl_TSmT%01d_Sel%02d_TOff", iS, iSel),
Form("Clu TimeZero in SmType %d under Selector %02d; Sm+Rpc# "
"[]; TOff [ns]",
iS, iSel),
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 0,
fDigiBdfPar->GetNbSm(iS) * fDigiBdfPar->GetNbRpc(iS), 99, -TSumMax, TSumMax);
fhTSmCluTRun[iS][iSel] = new TH2F(Form("cl_TSmT%01d_Sel%02d_TRun", iS, iSel),
Form("Clu TimeZero in SmType %d under Selector %02d; Event# "
"[]; TMean [ns]",
iS, iSel),
100, 0, MaxNbEvent, 99, -TSumMax, TSumMax);
}
}
// RPC related distributions
LOG(info) << " Define Clusterizer histos for " << iNbDet << " detectors ";
fhRpcCluMul.resize(iNbDet);
fhRpcCluRate.resize(iNbDet);
fhRpcCluPosition.resize(iNbDet);
fhRpcCluDelPos.resize(iNbDet);
fhRpcCluDelMatPos.resize(iNbDet);
fhRpcCluTOff.resize(iNbDet);
fhRpcCluDelTOff.resize(iNbDet);
fhRpcCluDelMatTOff.resize(iNbDet);
fhRpcCluTrms.resize(iNbDet);
fhRpcCluTot.resize(iNbDet);
fhRpcCluSize.resize(iNbDet);
fhRpcCluAvWalk.resize(iNbDet);
fhRpcCluAvLnWalk.resize(iNbDet);
fhRpcCluWalk.resize(iNbDet);
fhRpcDTLastHits.resize(iNbDet);
fhRpcDTLastHits_Tot.resize(iNbDet);
fhRpcDTLastHits_CluSize.resize(iNbDet);
if (fTotMax != 0.) fdTOTMax = fTotMax;
if (fTotMin != 0.) fdTOTMin = fTotMin;
for (Int_t iDetIndx = 0; iDetIndx < iNbDet; iDetIndx++) {
Int_t iUniqueId = fDigiBdfPar->GetDetUId(iDetIndx);
Int_t iSmType = CbmTofAddress::GetSmType(iUniqueId);
Int_t iSmId = CbmTofAddress::GetSmId(iUniqueId);
Int_t iRpcId = CbmTofAddress::GetRpcId(iUniqueId);
Int_t iUCellId = CbmTofAddress::GetUniqueAddress(iSmId, iRpcId, 0, 0, iSmType);
fChannelInfo = fDigiPar->GetCell(iUCellId);
if (NULL == fChannelInfo) {
LOG(warn) << "No DigiPar for Det " << Form("0x%08x", iUCellId);
continue;
}
LOG(info) << "DetIndx " << iDetIndx << ", SmType " << iSmType << ", SmId " << iSmId << ", RpcId " << iRpcId
<< " => UniqueId " << Form("(0x%08x, 0x%08x)", iUniqueId, iUCellId) << ", dx " << fChannelInfo->GetSizex()
<< ", dy " << fChannelInfo->GetSizey() << Form(" ChPoi: %p ", fChannelInfo) << ", nbCh "
<< fDigiBdfPar->GetNbChan(iSmType, 0);
// check access to all channel infos
for (Int_t iCh = 0; iCh < fDigiBdfPar->GetNbChan(iSmType, iRpcId); iCh++) {
Int_t iCCellId = CbmTofAddress::GetUniqueAddress(iSmId, iRpcId, iCh, 0, iSmType);
fChannelInfo = fDigiPar->GetCell(iCCellId);
if (NULL == fChannelInfo) LOG(warn) << Form("missing ChannelInfo for ch %d addr 0x%08x", iCh, iCCellId);
}
fChannelInfo = fDigiPar->GetCell(iUCellId);
fhRpcCluMul[iDetIndx] =
new TH1F(Form("cl_SmT%01d_sm%03d_rpc%03d_Mul", iSmType, iSmId, iRpcId),
Form("Clu multiplicity of Rpc #%03d in Sm %03d of type %d; M []; Cnts", iRpcId, iSmId, iSmType),
2. + 2. * fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, 2. + 2. * fDigiBdfPar->GetNbChan(iSmType, iRpcId));
fhRpcCluRate[iDetIndx] =
new TH1F(Form("cl_SmT%01d_sm%03d_rpc%03d_rate", iSmType, iSmId, iRpcId),
Form("Clu rate of Rpc #%03d in Sm %03d of type %d; Time (s); Rate (Hz)", iRpcId, iSmId, iSmType), 3600.,
0., 3600.);
fhRpcDTLastHits[iDetIndx] = new TH1F(Form("cl_SmT%01d_sm%03d_rpc%03d_DTLastHits", iSmType, iSmId, iRpcId),
Form("Clu #DeltaT to last hits of Rpc #%03d in Sm %03d of type %d; log( "
"#DeltaT (ns)); counts",
iRpcId, iSmId, iSmType),
100., 0., 10.);
fhRpcDTLastHits_Tot[iDetIndx] = new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Tot_DTLH", iSmType, iSmId, iRpcId),
Form("Clu Tot of Rpc #%03d in Sm %03d of type %d; log(#DeltaT (ns)); TOT "
"[ns]",
iRpcId, iSmId, iSmType),
100, 0., 10., 100, fdTOTMin, 4. * fdTOTMax);
fhRpcDTLastHits_CluSize[iDetIndx] = new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_CluSize_DTLH", iSmType, iSmId, iRpcId),
Form("Clu Size of Rpc #%03d in Sm %03d of type %d; log(#DeltaT (ns)); "
"CluSize []",
iRpcId, iSmId, iSmType),
100, 0., 10., 16, 0.5, 16.5);
Double_t YSCAL = 50.;
if (fPosYMaxScal != 0.) YSCAL = fPosYMaxScal;
Double_t YDMAX = TMath::Max(2., fChannelInfo->GetSizey()) * YSCAL;
fhRpcCluPosition[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Pos", iSmType, iSmId, iRpcId),
Form("Clu position of Rpc #%03d in Sm %03d of type %d; Strip []; ypos [cm]", iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -YDMAX, YDMAX);
fhRpcCluDelPos[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_DelPos", iSmType, iSmId, iRpcId),
Form("Clu position difference of Rpc #%03d in Sm %03d of type "
"%d; Strip []; #Deltaypos(clu) [cm]",
iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -10., 10.);
fhRpcCluDelMatPos[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_DelMatPos", iSmType, iSmId, iRpcId),
Form("Matched Clu position difference of Rpc #%03d in Sm %03d of type "
"%d; Strip []; #Deltaypos(mat) [cm]",
iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -5., 5.);
Double_t TSumMax = 1.E3;
if (fTRefDifMax != 0.) TSumMax = fTRefDifMax;
fhRpcCluTOff[iDetIndx] = new TH2F(
Form("cl_SmT%01d_sm%03d_rpc%03d_TOff", iSmType, iSmId, iRpcId),
Form("Clu TimeZero of Rpc #%03d in Sm %03d of type %d; Strip []; TOff [ns]", iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -TSumMax, TSumMax);
fhRpcCluDelTOff[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_DelTOff", iSmType, iSmId, iRpcId),
Form("Clu TimeZero Difference of Rpc #%03d in Sm %03d of type %d; Strip "
"[]; #DeltaTOff(clu) [ns]",
iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -0.6, 0.6);
fhRpcCluDelMatTOff[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_DelMatTOff", iSmType, iSmId, iRpcId),
Form("Clu TimeZero Difference of Rpc #%03d in Sm %03d of type %d; Strip "
"[]; #DeltaTOff(mat) [ns]",
iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -0.6, 0.6);
fhRpcCluTrms[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Trms", iSmType, iSmId, iRpcId),
Form("Clu Time RMS of Rpc #%03d in Sm %03d of type %d; Strip []; Trms [ns]", iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, 0., 0.5);
fhRpcCluTot[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Tot", iSmType, iSmId, iRpcId),
Form("Clu Tot of Rpc #%03d in Sm %03d of type %d; StripSide []; TOT [ns]", iRpcId, iSmId, iSmType),
2 * fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, 2 * fDigiBdfPar->GetNbChan(iSmType, iRpcId), 100,
fdTOTMin, fdTOTMax);
fhRpcCluSize[iDetIndx] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Size", iSmType, iSmId, iRpcId),
Form("Clu size of Rpc #%03d in Sm %03d of type %d; Strip []; size [strips]", iRpcId, iSmId, iSmType),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 16, 0.5, 16.5);
// Walk histos
fhRpcCluAvWalk[iDetIndx] = new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_AvWalk", iSmType, iSmId, iRpcId),
Form("Walk in SmT%01d_sm%03d_rpc%03d_AvWalk", iSmType, iSmId, iRpcId),
nbClWalkBinX, fdTOTMin, fdTOTMax, nbClWalkBinY, -TSumMax, TSumMax);
fhRpcCluAvLnWalk[iDetIndx] =
new TH2D(Form("cl_SmT%01d_sm%03d_rpc%03d_AvLnWalk", iSmType, iSmId, iRpcId),
Form("Walk in SmT%01d_sm%03d_rpc%03d_AvLnWalk", iSmType, iSmId, iRpcId), nbClWalkBinX,
TMath::Log10(fdTOTMax / 50.), TMath::Log10(fdTOTMax), nbClWalkBinY, -TSumMax, TSumMax);
fhRpcCluWalk[iDetIndx].resize(fDigiBdfPar->GetNbChan(iSmType, iRpcId));
for (Int_t iCh = 0; iCh < fDigiBdfPar->GetNbChan(iSmType, iRpcId); iCh++) {
fhRpcCluWalk[iDetIndx][iCh].resize(2);
for (Int_t iSide = 0; iSide < 2; iSide++) {
fhRpcCluWalk[iDetIndx][iCh][iSide] =
new TH2D(Form("cl_SmT%01d_sm%03d_rpc%03d_Ch%03d_S%01d_Walk", iSmType, iSmId, iRpcId, iCh, iSide),
Form("Walk in SmT%01d_sm%03d_rpc%03d_Ch%03d_S%01d_Walk", iSmType, iSmId, iRpcId, iCh, iSide),
nbClWalkBinX, fdTOTMin, fdTOTMax, nbClWalkBinY, -TSumMax, TSumMax);
}
/*
(fhRpcCluWalk[iDetIndx]).push_back( hTemp );
*/
}
}
// Trigger selected histograms
if (0 < iNSel) {
fhSeldT.resize(iNSel);
for (Int_t iSel = 0; iSel < iNSel; iSel++) {
fhSeldT[iSel] = new TH2F(Form("cl_dt_Sel%02d", iSel), Form("Selector time %02d; dT [ns]", iSel), 99,
-fdDelTofMax * 10., fdDelTofMax * 10., 16, -0.5, 15.5);
}
fhTRpcCluMul.resize(iNbDet);
fhTRpcCluPosition.resize(iNbDet);
fhTRpcCluTOff.resize(iNbDet);
fhTRpcCluTot.resize(iNbDet);
fhTRpcCluSize.resize(iNbDet);
fhTRpcCluAvWalk.resize(iNbDet);
fhTRpcCluDelTof.resize(iNbDet);
fhTRpcCludXdY.resize(iNbDet);
fhTRpcCluWalk.resize(iNbDet);
fhTRpcCluTOffDTLastHits.resize(iNbDet);
fhTRpcCluTotDTLastHits.resize(iNbDet);
fhTRpcCluSizeDTLastHits.resize(iNbDet);
fhTRpcCluMemMulDTLastHits.resize(iNbDet);
for (Int_t iDetIndx = 0; iDetIndx < iNbDet; iDetIndx++) {
Int_t iUniqueId = fDigiBdfPar->GetDetUId(iDetIndx);
Int_t iSmType = CbmTofAddress::GetSmType(iUniqueId);
Int_t iSmId = CbmTofAddress::GetSmId(iUniqueId);
Int_t iRpcId = CbmTofAddress::GetRpcId(iUniqueId);
Int_t iUCellId = CbmTofAddress::GetUniqueAddress(iSmId, iRpcId, 0, 0, iSmType);
fChannelInfo = fDigiPar->GetCell(iUCellId);
if (NULL == fChannelInfo) {
LOG(warn) << "No DigiPar for Det " << Form("0x%08x", iUCellId);
continue;
}
LOG(debug) << "DetIndx " << iDetIndx << ", SmType " << iSmType << ", SmId " << iSmId << ", RpcId " << iRpcId
<< " => UniqueId " << Form("(0x%08x, 0x%08x)", iUniqueId, iUCellId) << ", dx "
<< fChannelInfo->GetSizex() << ", dy " << fChannelInfo->GetSizey() << Form(" poi: 0x%p ", fChannelInfo)
<< ", nbCh " << fDigiBdfPar->GetNbChan(iSmType, iRpcId);
fhTRpcCluMul[iDetIndx].resize(iNSel);
fhTRpcCluPosition[iDetIndx].resize(iNSel);
fhTRpcCluTOff[iDetIndx].resize(iNSel);
fhTRpcCluTot[iDetIndx].resize(iNSel);
fhTRpcCluSize[iDetIndx].resize(iNSel);
fhTRpcCluAvWalk[iDetIndx].resize(iNSel);
fhTRpcCluDelTof[iDetIndx].resize(iNSel);
fhTRpcCludXdY[iDetIndx].resize(iNSel);
fhTRpcCluWalk[iDetIndx].resize(iNSel);
fhTRpcCluTOffDTLastHits[iDetIndx].resize(iNSel);
fhTRpcCluTotDTLastHits[iDetIndx].resize(iNSel);
fhTRpcCluSizeDTLastHits[iDetIndx].resize(iNSel);
fhTRpcCluMemMulDTLastHits[iDetIndx].resize(iNSel);
for (Int_t iSel = 0; iSel < iNSel; iSel++) {
fhTRpcCluMul[iDetIndx][iSel] =
new TH1F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_Mul", iSmType, iSmId, iRpcId, iSel),
Form("Clu multiplicity of Rpc #%03d in Sm %03d of type %d "
"under Selector %02d; M []; cnts",
iRpcId, iSmId, iSmType, iSel),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0., fDigiBdfPar->GetNbChan(iSmType, iRpcId));
if (NULL == fhTRpcCluMul[iDetIndx][iSel]) LOG(error) << " Histo not generated !";
Double_t YSCAL = 50.;
if (fPosYMaxScal != 0.) YSCAL = fPosYMaxScal;
Double_t YDMAX = TMath::Max(2., fChannelInfo->GetSizey()) * YSCAL;
fhTRpcCluPosition[iDetIndx][iSel] = new TH2F(
Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_Pos", iSmType, iSmId, iRpcId, iSel),
Form("Clu position of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; Strip []; ypos [cm]",
iRpcId, iSmId, iSmType, iSel),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 100, -YDMAX, YDMAX);
Double_t TSumMax = 1.E4;
if (fTRefDifMax != 0.) TSumMax = fTRefDifMax;
fhTRpcCluTOff[iDetIndx][iSel] = new TH2F(
Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_TOff", iSmType, iSmId, iRpcId, iSel),
Form("Clu TimeZero of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; Strip []; TOff [ns]",
iRpcId, iSmId, iSmType, iSel),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 99, -TSumMax, TSumMax);
if (fTotMax != 0.) fdTOTMax = fTotMax;
fhTRpcCluTot[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_Tot", iSmType, iSmId, iRpcId, iSel),
Form("Clu Tot of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; StripSide []; TOT [ns]",
iRpcId, iSmId, iSmType, iSel),
fDigiBdfPar->GetNbChan(iSmType, iRpcId) * 2, 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId) * 2, 100,
fdTOTMin, fdTOTMax);
fhTRpcCluSize[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_Size", iSmType, iSmId, iRpcId, iSel),
Form("Clu size of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; Strip []; size [strips]",
iRpcId, iSmId, iSmType, iSel),
fDigiBdfPar->GetNbChan(iSmType, iRpcId), 0, fDigiBdfPar->GetNbChan(iSmType, iRpcId), 16, 0.5, 16.5);
// Walk histos
fhTRpcCluAvWalk[iDetIndx][iSel] =
new TH2D(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_AvWalk", iSmType, iSmId, iRpcId, iSel),
Form("Walk in SmT%01d_sm%03d_rpc%03d_Sel%02d_AvWalk; TOT; T-TSel", iSmType, iSmId, iRpcId, iSel),
nbClWalkBinX, fdTOTMin, fdTOTMax, nbClWalkBinY, -TSumMax, TSumMax);
// Tof Histos
fhTRpcCluDelTof[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_DelTof", iSmType, iSmId, iRpcId, iSel),
Form("SmT%01d_sm%03d_rpc%03d_Sel%02d_DelTof; TRef-TSel; T-TSel", iSmType, iSmId, iRpcId, iSel),
nbClDelTofBinX, -fdDelTofMax, fdDelTofMax, nbClDelTofBinY, -TSumMax, TSumMax);
// Position deviation histos
fhTRpcCludXdY[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_dXdY", iSmType, iSmId, iRpcId, iSel),
Form("SmT%01d_sm%03d_rpc%03d_Sel%02d_dXdY; #Delta x [cm]; "
"#Delta y [cm];",
iSmType, iSmId, iRpcId, iSel),
nbCldXdYBinX, -dXdYMax, dXdYMax, nbCldXdYBinY, -dXdYMax, dXdYMax);
fhTRpcCluWalk[iDetIndx][iSel].resize(fDigiBdfPar->GetNbChan(iSmType, iRpcId));
for (Int_t iCh = 0; iCh < fDigiBdfPar->GetNbChan(iSmType, iRpcId); iCh++) {
fhTRpcCluWalk[iDetIndx][iSel][iCh].resize(2);
for (Int_t iSide = 0; iSide < 2; iSide++) {
fhTRpcCluWalk[iDetIndx][iSel][iCh][iSide] = new TH2D(
Form("cl_SmT%01d_sm%03d_rpc%03d_Ch%03d_S%01d_Sel%02d_Walk", iSmType, iSmId, iRpcId, iCh, iSide, iSel),
Form("Walk in SmT%01d_sm%03d_rpc%03d_Ch%03d_S%01d_Sel%02d_Walk", iSmType, iSmId, iRpcId, iCh, iSide,
iSel),
nbClWalkBinX, fdTOTMin, fdTOTMax, nbClWalkBinY, -TSumMax, TSumMax);
}
}
fhTRpcCluTOffDTLastHits[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_TOff_DTLH", iSmType, iSmId, iRpcId, iSel),
Form("Clu TimeZero of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; log(#DeltaT (ns)); TOff [ns]",
iRpcId, iSmId, iSmType, iSel),
100, 0., 10., 99, -TSumMax, TSumMax);
fhTRpcCluTotDTLastHits[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_Tot_DTLH", iSmType, iSmId, iRpcId, iSel),
Form("Clu Tot of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; log(#DeltaT (ns)); TOT [ns]",
iRpcId, iSmId, iSmType, iSel),
100, 0., 10., 100, fdTOTMin, fdTOTMax);
fhTRpcCluSizeDTLastHits[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_Size_DTLH", iSmType, iSmId, iRpcId, iSel),
Form("Clu size of Rpc #%03d in Sm %03d of type %d under "
"Selector %02d; log(#DeltaT (ns)); size [strips]",
iRpcId, iSmId, iSmType, iSel),
100, 0., 10., 10, 0.5, 10.5);
fhTRpcCluMemMulDTLastHits[iDetIndx][iSel] =
new TH2F(Form("cl_SmT%01d_sm%03d_rpc%03d_Sel%02d_MemMul_DTLH", iSmType, iSmId, iRpcId, iSel),
Form("Clu Memorized Multiplicity of Rpc #%03d in Sm %03d of type %d "
"under Selector %02d; log(#DeltaT (ns)); TOff [ns]",
iRpcId, iSmId, iSmType, iSel),
100, 0., 10., 10, 0, 10);
}
}
}
gDirectory->cd(oldir->GetPath()); // <= To prevent histos from being sucked in by the param file of the TRootManager!
return;
}
/************************************************************************************/
void CbmDeviceHitBuilderTof::WriteHistograms()
{
TList* tHistoList(NULL);
tHistoList = gROOT->GetList();
TIter next(tHistoList);
// Write histogramms to the file
fOutRootFile->cd();
{
TH1* h;
TObject* obj;
while ((obj = (TObject*) next())) {
if (obj->InheritsFrom(TH1::Class())) {
h = (TH1*) obj;
// cout << "Write histo " << h->GetTitle() << endl;
h->Write();
}
}
}
}
/************************************************************************************/
Bool_t CbmDeviceHitBuilderTof::BuildClusters()
{
fiNevtBuild++;
if (!CalibRawDigis()) return kFALSE;
if (0 == fiMode) return kTRUE; // no customer yet
if (!FillDigiStor()) return kFALSE;
if (!BuildHits()) return kFALSE;
return kTRUE;
}
/************************************************************************************/
Bool_t CbmDeviceHitBuilderTof::InspectRawDigis()
{
Int_t iNbTofDigi = fiNDigiIn;
pRef = NULL;
for (Int_t iDigInd = 0; iDigInd < fiNDigiIn; iDigInd++) {
CbmTofDigi* pDigi = &fvDigiIn[iDigInd];
//LOG(debug)<<iDigInd<<" "<<pDigi;
Int_t iAddr = pDigi->GetAddress() & DetMask;
Int_t iDetIndx = fDigiBdfPar->GetDetInd(iAddr);
/*
LOG(info)<<iDigInd
//<<Form(" Address : 0x%08x ",pDigi->GetAddress())
<<Form(" TSRCS %d%d%d%02d%d ", (int)pDigi->GetType(),
(int)pDigi->GetSm(),(int)pDigi->GetRpc(),(int)pDigi->GetChannel(),(int)pDigi->GetSide())
<<" : " << Form("Ind %2d, T %15.3f, Tot %5.1f",iDetIndx,pDigi->GetTime(),pDigi->GetTot());
*/
if (fiBeamRefAddr < 0 || iAddr == fiBeamRefAddr) {
//LOG(debug) << Form("Ref digi found for 0x%08x, Mask 0x%08x ", fiBeamRefAddr, DetMask);
if (NULL == pRef) pRef = pDigi;
else {
if (pDigi->GetTime() < pRef->GetTime()) pRef = pDigi;
}
}
if (fDigiBdfPar->GetNbDet() - 1 < iDetIndx || iDetIndx < 0) {
LOG(warn) << Form(" Wrong DetIndx %d >< %d,0 ", iDetIndx, fDigiBdfPar->GetNbDet());
break;
}
fhRpcDigiTot[iDetIndx]->Fill(2 * pDigi->GetChannel() + pDigi->GetSide(), pDigi->GetTot());
if (NULL == fhRpcDigiCor[iDetIndx]) {
if (100 < iMess++)
LOG(warn) << Form(" DigiCor Histo for DetIndx %d derived from 0x%08x not found", iDetIndx,
pDigi->GetAddress());
continue;
}
Double_t dTDifMin = dDoubleMax;
CbmTofDigi* pDigi2Min = NULL;
// for (Int_t iDigI2 =iDigInd+1; iDigI2<iNbTofDigi;iDigI2++){
for (Int_t iDigI2 = 0; iDigI2 < iNbTofDigi; iDigI2++) {
CbmTofDigi* pDigi2 = &fvDigiIn[iDigI2];
if (pDigi != pDigi2) { fhDigiTdif->Fill(pDigi->GetTime() - pDigi2->GetTime()); }
if (pDigi->GetAddress() != pDigi2->GetAddress())
if (pDigi->GetType() == 6 && pDigi2->GetType() == 6)
fhBucDigiCor->Fill(pDigi->GetRpc() * 64 + pDigi->GetChannel() * 2 + pDigi->GetSide(),
pDigi2->GetRpc() * 64 + pDigi2->GetChannel() * 2 + pDigi2->GetSide());
if (iDetIndx == fDigiBdfPar->GetDetInd(pDigi2->GetAddress())) {
/*
LOG(info) <<" Correlate DetIndx "<<iDetIndx
<<Form(", TSRCS %d%d%d%02d%d ", (int)pDigi->GetType(),
(int)pDigi->GetSm(),(int)pDigi->GetRpc(),(int)pDigi->GetChannel(),(int)pDigi->GetSide())
<<Form(" with %d%d%d%02d%d ", (int)pDigi2->GetType(),
(int)pDigi2->GetSm(),(int)pDigi2->GetRpc(),(int)pDigi2->GetChannel(),(int)pDigi2->GetSide());
*/
if (0. == pDigi->GetSide() && 1. == pDigi2->GetSide()) {
fhRpcDigiCor[iDetIndx]->Fill(pDigi->GetChannel(), pDigi2->GetChannel());
}
else {
if (1. == pDigi->GetSide() && 0. == pDigi2->GetSide()) {
fhRpcDigiCor[iDetIndx]->Fill(pDigi2->GetChannel(), pDigi->GetChannel());
}
}
if (pDigi->GetSide() != pDigi2->GetSide()) {
if (pDigi->GetChannel() == pDigi2->GetChannel()) {
Double_t dTDif = TMath::Abs(pDigi->GetTime() - pDigi2->GetTime());
if (dTDif < dTDifMin) {
dTDifMin = dTDif;
pDigi2Min = pDigi2;
//LOG(debug) << "Digi2 found at "<<iDigI2<<" with TDif = "<<dTDifMin<<" ns";
}
}
else if (TMath::Abs(pDigi->GetChannel() - pDigi2->GetChannel())
== 1) { // opposite side missing, neighbouring channel has hit on opposite side // FIXME
// check that same side digi of neighbouring channel is absent
Int_t iDigI3 = 0;
for (; iDigI3 < iNbTofDigi; iDigI3++) {
CbmTofDigi* pDigi3 = &fvDigiIn[iDigI3];
if (pDigi3->GetSide() == pDigi->GetSide() && pDigi2->GetChannel() == pDigi3->GetChannel()) break;
}
if (iDigI3 == iNbTofDigi) { // same side neighbour did not fire
Int_t iCorMode = 0; // Missing hit correction mode
switch (iCorMode) {
case 0: // no action
break;
case 1: // shift found hit
LOG(debug) << Form("shift channel %d%d%d%d%d and ", (Int_t) pDigi->GetType(), (Int_t) pDigi->GetSm(),
(Int_t) pDigi->GetRpc(), (Int_t) pDigi->GetChannel(), (Int_t) pDigi->GetSide())
<< Form(" %d%d%d%d%d ", (Int_t) pDigi2->GetType(), (Int_t) pDigi2->GetSm(),
(Int_t) pDigi2->GetRpc(), (Int_t) pDigi2->GetChannel(), (Int_t) pDigi2->GetSide());
//if(pDigi->GetTime() < pDigi2->GetTime())
if (pDigi->GetSide() == 0)
pDigi2->SetAddress(pDigi->GetSm(), pDigi->GetRpc(), pDigi->GetChannel(), 1 - pDigi->GetSide(),
pDigi->GetType());
else
pDigi->SetAddress(pDigi2->GetSm(), pDigi2->GetRpc(), pDigi2->GetChannel(), 1 - pDigi2->GetSide(),
pDigi2->GetType());
LOG(debug) << Form("resultchannel %d%d%d%d%d and ", (Int_t) pDigi->GetType(), (Int_t) pDigi->GetSm(),
(Int_t) pDigi->GetRpc(), (Int_t) pDigi->GetChannel(), (Int_t) pDigi->GetSide())
<< Form(" %d%d%d%d%d ", (Int_t) pDigi2->GetType(), (Int_t) pDigi2->GetSm(),
(Int_t) pDigi2->GetRpc(), (Int_t) pDigi2->GetChannel(), (Int_t) pDigi2->GetSide());
break;
case 2: // insert missing hits
CbmTofDigi* pDigiN = new CbmTofDigi(*pDigi);
pDigiN->SetAddress(pDigi->GetSm(), pDigi->GetRpc(), pDigi2->GetChannel(), pDigi->GetSide(),
pDigi->GetType());
pDigiN->SetTot(pDigi2->GetTot());
fvDigiIn.push_back(*pDigiN);
CbmTofDigi* pDigiN2 = new CbmTofDigi(*pDigi2);
pDigiN2->SetAddress(pDigi2->GetSm(), pDigi2->GetRpc(), pDigi->GetChannel(), pDigi2->GetSide(),
pDigi2->GetType());
pDigiN2->SetTot(pDigi->GetTot());
fvDigiIn.push_back(*pDigiN2);
break;
}
}
}
}
}
}
if (pDigi2Min != NULL) {
CbmTofDetectorInfo xDetInfo(ECbmModuleId::kTof, pDigi->GetType(), pDigi->GetSm(), pDigi->GetRpc(), 0,
pDigi->GetChannel());
Int_t iChId = fTofId->SetDetectorInfo(xDetInfo);
fChannelInfo = fDigiPar->GetCell(iChId);
if (NULL == fChannelInfo) {
LOG(warn) << Form("Invalid ChannelInfo for 0x%08x, 0x%08x", iChId, pDigi2Min->GetAddress()) << " TSRC "
<< pDigi->GetType() << pDigi->GetSm() << pDigi->GetRpc() << pDigi->GetChannel();
continue;
}
if (fDigiBdfPar->GetSigVel(pDigi->GetType(), pDigi->GetSm(), pDigi->GetRpc()) * dTDifMin * 0.5
< fPosYMaxScal * fChannelInfo->GetSizey()) {
//check consistency
if (8 == pDigi->GetType() || 5 == pDigi->GetType()) {
if (pDigi->GetTime() != pDigi2Min->GetTime()) {
if (fiMsgCnt-- > 0) {
LOG(warn) << "Inconsistent duplicated digis in event " << fiNevtBuild << ", Ind: " << iDigInd;
LOG(warn) << " " << pDigi->ToString();
LOG(warn) << " " << pDigi2Min->ToString();
}
pDigi2Min->SetTot(pDigi->GetTot());
pDigi2Min->SetTime(pDigi->GetTime());
}
}
}
}
}
if (NULL != pRef) {
// LOG(debug) << Form("pRef from 0x%08x ",pRef->GetAddress());
for (Int_t iDigInd = 0; iDigInd < fiNDigiIn; iDigInd++) {
CbmTofDigi* pDigi = &fvDigiIn[iDigInd];
Int_t iAddr = pDigi->GetAddress() & DetMask;
Int_t iDet = fDetIdIndexMap[iAddr]; // Detector Index
Int_t iSide = pDigi->GetSide();
fhDigiTimesRaw->Fill(iDet * 2 + iSide, pDigi->GetTime() - pRef->GetTime());
}
}
return kTRUE;
}
/************************************************************************************/
Bool_t CbmDeviceHitBuilderTof::CalibRawDigis()
{
CbmTofDigi* pDigi;
CbmTofDigi* pCalDigi = NULL;
Int_t iDigIndCal = -1;
// channel deadtime map
std::map<Int_t, Double_t> mChannelDeadTime;
fTofCalDigiVec->clear();
Int_t iNbTofDigi = fvDigiIn.size();
for (Int_t iDigInd = 0; iDigInd < iNbTofDigi; iDigInd++) {
pDigi = (CbmTofDigi*) &fvDigiIn[iDigInd];
Int_t iAddr = pDigi->GetAddress();
/*
LOG(debug)<<"BC " // Before Calibration
<<Form("0x%08x",pDigi->GetAddress())<<" TSRC "
<<pDigi->GetType()
<<pDigi->GetSm()
<<pDigi->GetRpc()
<<Form("%2d",(Int_t)pDigi->GetChannel())<<" "
<<pDigi->GetSide()<<" "
<<Form("%f",pDigi->GetTime())<<" "
<<pDigi->GetTot();
*/
if (pDigi->GetType() == 5 || pDigi->GetType() == 8) // for Pad counters generate fake digi to mockup a strip
if (pDigi->GetSide() == 1) continue; // skip one side to avoid double entries
Bool_t bValid = kTRUE;
std::map<Int_t, Double_t>::iterator it;
it = mChannelDeadTime.find(iAddr);
if (it != mChannelDeadTime.end()) {
/*
LOG(debug)<<"CCT found valid ChannelDeadtime entry "<<mChannelDeadTime[iAddr]
<<", DeltaT "<<pDigi->GetTime()-mChannelDeadTime[iAddr];
*/
if ((bValid = (pDigi->GetTime() > mChannelDeadTime[iAddr] + fdChannelDeadtime))) {
// pCalDigi =
// new ((*fTofCalDigisColl)[++iDigIndCal]) CbmTofDigi(*pDigi);
fTofCalDigiVec->push_back(CbmTofDigi(*pDigi));
pCalDigi = &(fTofCalDigiVec->back());
iDigIndCal++;
}
}
else {
// pCalDigi = new ((*fTofCalDigisColl)[++iDigIndCal]) CbmTofDigi(*pDigi);
fTofCalDigiVec->push_back(CbmTofDigi(*pDigi));
pCalDigi = &(fTofCalDigiVec->back());
iDigIndCal++;
}
mChannelDeadTime[iAddr] = pDigi->GetTime();
if (!bValid) continue;
if (pRef != NULL)
if (pDigi == pRef) pRefCal = pCalDigi;
/*
LOG(debug)<<"DC " // After deadtime check. before Calibration
<<Form("0x%08x",pDigi->GetAddress())<<" TSRC "
<<pDigi->GetType()
<<pDigi->GetSm()
<<pDigi->GetRpc()
<<Form("%2d",(Int_t)pDigi->GetChannel())<<" "
<<pDigi->GetSide()<<" "
<<Form("%f",pDigi->GetTime())<<" "
<<pDigi->GetTot();
*/
if (fbPs2Ns) {
pCalDigi->SetTime(pCalDigi->GetTime() / 1000.); // for backward compatibility
pCalDigi->SetTot(pCalDigi->GetTot() / 1000.); // for backward compatibility
}
if (fDigiBdfPar->GetNbSmTypes() > pDigi->GetType() // prevent crash due to misconfiguration
&& fDigiBdfPar->GetNbSm(pDigi->GetType()) > pDigi->GetSm()
&& fDigiBdfPar->GetNbRpc(pDigi->GetType()) > pDigi->GetRpc()
&& fDigiBdfPar->GetNbChan(pDigi->GetType(), pDigi->GetRpc()) > pDigi->GetChannel()) {
// apply calibration vectors
pCalDigi->SetTime(pCalDigi->GetTime() - // calibrate Digi Time
fvCPTOff[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType())
+ pDigi->GetRpc()][pDigi->GetChannel()][pDigi->GetSide()]);
// LOG(debug)<<" CluCal-TOff: "<<pCalDigi->ToString();
Double_t dTot = pCalDigi->GetTot() - // subtract Offset
fvCPTotOff[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType())
+ pDigi->GetRpc()][pDigi->GetChannel()][pDigi->GetSide()];
if (dTot < 0.001) dTot = 0.001;
pCalDigi->SetTot(dTot * // calibrate Digi ToT
fvCPTotGain[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType())
+ pDigi->GetRpc()][pDigi->GetChannel()][pDigi->GetSide()]);
// walk correction
Double_t dTotBinSize = (fdTOTMax - fdTOTMin) / nbClWalkBinX;
Int_t iWx = (Int_t)((pCalDigi->GetTot() - fdTOTMin) / dTotBinSize);
if (0 > iWx) iWx = 0;
if (iWx >= nbClWalkBinX) iWx = nbClWalkBinX - 1;
Double_t dDTot = (pCalDigi->GetTot() - fdTOTMin) / dTotBinSize - (Double_t) iWx - 0.5;
Double_t dWT =
fvCPWalk[pCalDigi->GetType()][pCalDigi->GetSm() * fDigiBdfPar->GetNbRpc(pCalDigi->GetType())
+ pCalDigi->GetRpc()][pCalDigi->GetChannel()][pCalDigi->GetSide()][iWx];
if (dDTot > 0) { // linear interpolation to next bin
if (iWx < nbClWalkBinX - 1) { // linear interpolation to next bin
dWT +=
dDTot
* (fvCPWalk[pCalDigi->GetType()][pCalDigi->GetSm() * fDigiBdfPar->GetNbRpc(pCalDigi->GetType())
+ pCalDigi->GetRpc()][pCalDigi->GetChannel()][pCalDigi->GetSide()][iWx + 1]
- fvCPWalk[pCalDigi->GetType()]
[pCalDigi->GetSm() * fDigiBdfPar->GetNbRpc(pCalDigi->GetType()) + pCalDigi->GetRpc()]
[pCalDigi->GetChannel()][pCalDigi->GetSide()][iWx]); //memory leak???
}
}
else // dDTot < 0, linear interpolation to next bin
{
if (0 < iWx) { // linear interpolation to next bin
dWT -=
dDTot
* (fvCPWalk[pCalDigi->GetType()][pCalDigi->GetSm() * fDigiBdfPar->GetNbRpc(pCalDigi->GetType())
+ pCalDigi->GetRpc()][pCalDigi->GetChannel()][pCalDigi->GetSide()][iWx - 1]
- fvCPWalk[pCalDigi->GetType()]
[pCalDigi->GetSm() * fDigiBdfPar->GetNbRpc(pCalDigi->GetType()) + pCalDigi->GetRpc()]
[pCalDigi->GetChannel()][pCalDigi->GetSide()][iWx]); //memory leak???
}
}
pCalDigi->SetTime(pCalDigi->GetTime() - dWT); // calibrate Digi Time
// LOG(debug)<<" CluCal-Walk: "<<pCalDigi->ToString();
}
else {
LOG(info) << "Skip1 Digi "
<< " Type " << pDigi->GetType() << " " << fDigiBdfPar->GetNbSmTypes() << " Sm " << pDigi->GetSm() << " "
<< fDigiBdfPar->GetNbSm(pDigi->GetType()) << " Rpc " << pDigi->GetRpc() << " "
<< fDigiBdfPar->GetNbRpc(pDigi->GetType()) << " Ch " << pDigi->GetChannel() << " "
<< fDigiBdfPar->GetNbChan(pDigi->GetType(), 0);
}
if (pCalDigi->GetType() == 5
|| pCalDigi->GetType() == 8) { // for Pad counters generate fake digi to mockup a strip
//CbmTofDigi* pCalDigi2 =
// new ((*fTofCalDigisColl)[++iDigIndCal]) CbmTofDigi(*pCalDigi);
fTofCalDigiVec->push_back(CbmTofDigi(*pCalDigi));
CbmTofDigi* pCalDigi2 = &(fTofCalDigiVec->back());
iDigIndCal++;
if (pCalDigi->GetSide() == 0)
pCalDigi2->SetAddress(pCalDigi->GetSm(), pCalDigi->GetRpc(), pCalDigi->GetChannel(), 1, pCalDigi->GetType());
else
pCalDigi2->SetAddress(pCalDigi->GetSm(), pCalDigi->GetRpc(), pCalDigi->GetChannel(), 0, pCalDigi->GetType());
}
} // for( Int_t iDigInd = 0; iDigInd < nTofDigi; iDigInd++ )
iNbTofDigi = fTofCalDigiVec->size();
// fTofCalDigisColl->GetEntriesFast(); // update because of added duplicted digis
LOG(debug) << "CbmTofHitBuilder: Sort " << fTofCalDigiVec->size() << " calibrated digis ";
if (iNbTofDigi > 1) {
// fTofCalDigisColl->Sort(iNbTofDigi); // Time order again, in case modified by the calibration
/// Sort the buffers of hits due to the time offsets applied
std::sort(fTofCalDigiVec->begin(), fTofCalDigiVec->end(),
[](const CbmTofDigi& a, const CbmTofDigi& b) -> bool { return a.GetTime() < b.GetTime(); });
// std::sort(fTofCalDigiVec->begin(), fTofCalDigiVec->end());
// if(!fTofCalDigisColl->IsSorted()){
// if ( ! std::is_sorted(fTofCalDigiVec->begin(), fTofCalDigiVec->end()))
if (!std::is_sorted(fTofCalDigiVec->begin(), fTofCalDigiVec->end(),
[](const CbmTofDigi& a, const CbmTofDigi& b) -> bool { return a.GetTime() < b.GetTime(); }))
LOG(warning) << "CbmTofHitBuilder: Digi sorting not successful ";
}
if (NULL != pRef) {
// LOG(debug) << Form("pRef from 0x%08x ",pRef->GetAddress());
for (Int_t iDigInd = 0; iDigInd < iNbTofDigi; iDigInd++) {
// pDigi = (CbmTofDigi*) fTofCalDigisColl->At(iDigInd);
pDigi = &(fTofCalDigiVec->at(iDigInd));
Int_t iAddr = pDigi->GetAddress() & DetMask;
Int_t iDet = fDetIdIndexMap[iAddr]; // Detector Index
Int_t iSide = pDigi->GetSide();
fhDigiTimesCor->Fill(iDet * 2 + iSide, pDigi->GetTime() - pRefCal->GetTime());
}
}
return kTRUE;
}
/************************************************************************************/
Bool_t CbmDeviceHitBuilderTof::BuildHits()
{
Int_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes();
// Hit variables
Double_t dWeightedTime = 0.0;
Double_t dWeightedPosX = 0.0;
Double_t dWeightedPosY = 0.0;
Double_t dWeightedPosZ = 0.0;
Double_t dWeightsSum = 0.0;
//vPtsRef.clear();
vDigiIndRef.clear();
//CbmTofCell *fTrafoCell=NULL;
//Int_t iTrafoCell=-1;
Int_t iNbChanInHit = 0;
// Last Channel Temp variables
Int_t iLastChan = -1;
Double_t dLastPosX = 0.0; // -> Comment to remove warning because set but never used
Double_t dLastPosY = 0.0;
Double_t dLastTime = 0.0;
// Channel Temp variables
Double_t dPosX = 0.0;
Double_t dPosY = 0.0;
Double_t dPosZ = 0.0;
Double_t dTime = 0.0;
Double_t dTimeDif = 0.0;
Double_t dTotS = 0.0;
Int_t fiNbSameSide = 0;
// gGeoManager->SetTopVolume( gGeoManager->FindVolumeFast("tof_v14a") );
gGeoManager->SetTopVolume(gGeoManager->FindVolumeFast("cave"));
gGeoManager->CdTop();
if (kTRUE == fDigiBdfPar->UseExpandedDigi()) {
for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
for (Int_t iSm = 0; iSm < iNbSm; iSm++)
for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
Int_t iNbCh = fDigiBdfPar->GetNbChan(iSmType, iRpc);
Int_t iChType = fDigiBdfPar->GetChanType(iSmType, iRpc);
/*
LOG(debug)<<"RPC - Loop "
<< Form(" %3d %3d %3d %3d ",iSmType,iSm,iRpc,iChType);
*/
fviClusterMul[iSmType][iSm][iRpc] = 0;
Int_t iChId = 0;
Int_t iDetId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, 0, 0, iSmType);
;
Int_t iDetIndx = fDetIdIndexMap[iDetId]; // Detector Index
if (0 == iChType) {
// Don't spread clusters over RPCs!!!
dWeightedTime = 0.0;
dWeightedPosX = 0.0;
dWeightedPosY = 0.0;
dWeightedPosZ = 0.0;
dWeightsSum = 0.0;
iNbChanInHit = 0;
//vPtsRef.clear();
// For safety reinitialize everything
iLastChan = -1;
// dLastPosX = 0.0; // -> Comment to remove warning because set but never used
dLastPosY = 0.0;
dLastTime = 0.0;
//LOG(debug2)<<"ChanOrient "
// << Form(" %3d %3d %3d %3d %3d ",iSmType,iSm,iRpc,fDigiBdfPar->GetChanOrient( iSmType, iRpc ),iNbCh);
if (1 == fDigiBdfPar->GetChanOrient(iSmType, iRpc)) {
// Horizontal strips => X comes from left right time difference
} // if( 1 == fDigiBdfPar->GetChanOrient( iSmType, iRpc ) )
else { // Vertical strips => Y comes from bottom top time difference
for (Int_t iCh = 0; iCh < iNbCh; iCh++) {
//LOG(debug3)<<"VDigisize "
// << Form(" T %3d Sm %3d R %3d Ch %3d Size %3lu ",
// iSmType,iSm,iRpc,iCh,fStorStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size());
if (0 == fStorDigi[iSmType][iSm * iNbRpc + iRpc].size()) continue;
if (fvDeadStrips[iDetIndx] & (1 << iCh)) continue; // skip over dead channels
//if( 0 < fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size() )
// fhNbDigiPerChan->Fill( fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size() );
while (1 < fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size()) {
while ((fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0])->GetSide()
== (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1])->GetSide()) {
// Not one Digi of each end!
fiNbSameSide++;
if (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size() > 2) {
LOG(debug) << "SameSide Digis! on TSRC " << iSmType << iSm << iRpc << iCh << ", Times: "
<< Form("%f", (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0])->GetTime()) << ", "
<< Form("%f", (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1])->GetTime())
<< ", DeltaT "
<< (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1])->GetTime()
- (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0])->GetTime()
<< ", array size: " << fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size();
if (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][2]->GetSide()
== fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0]->GetSide()) {
LOG(debug) << "3 consecutive SameSide Digis! on TSRC " << iSmType << iSm << iRpc << iCh
<< ", Times: " << (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0])->GetTime()
<< ", " << (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1])->GetTime()
<< ", DeltaT "
<< (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1])->GetTime()
- (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0])->GetTime()
<< ", array size: " << fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size();
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
}
else {
if (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][2]->GetTime()
- fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0]->GetTime()
> fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][2]->GetTime()
- fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1]->GetTime()) {
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
}
else {
LOG(debug) << Form("Ev %8.0f, digis not properly time ordered, TSRCS "
"%d%d%d%d%d ",
fdEvent, iSmType, iSm, iRpc, iCh,
(Int_t) fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0]->GetSide());
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin() + 1);
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin() + 1);
}
}
}
else {
LOG(debug) << "SameSide Erase fStor entries(d) " << iSmType << ", SR " << iSm * iNbRpc + iRpc
<< ", Ch" << iCh;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
}
if (2 > fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size()) break;
continue;
} // same condition side end
LOG(debug) << "digis processing for "
<< Form(" SmT %3d Sm %3d Rpc %3d Ch %3d # %3lu ", iSmType, iSm, iRpc, iCh,
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size());
if (2 > fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size()) {
LOG(debug) << Form("Leaving digi processing for TSRC %d%d%d%d, size %3lu", iSmType, iSm, iRpc, iCh,
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size());
break;
}
/* Int_t iLastChId = iChId; // Save Last hit channel*/
// 2 Digis = both sides present
CbmTofDetectorInfo xDetInfo(ECbmModuleId::kTof, iSmType, iSm, iRpc, 0, iCh);
iChId = fTofId->SetDetectorInfo(xDetInfo);
Int_t iUCellId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, iCh, 0, iSmType);
LOG(debug) << Form("TSRC %d%d%d%d size %3lu ", iSmType, iSm, iRpc, iCh,
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size())
<< Form(" ChId: 0x%08x 0x%08x ", iChId, iUCellId);
fChannelInfo = fDigiPar->GetCell(iChId);
if (NULL == fChannelInfo) {
LOG(error) << "BuildHits: no geometry info! "
<< Form(" %3d %3d %3d %3d 0x%08x 0x%08x ", iSmType, iSm, iRpc, iCh, iChId, iUCellId);
break;
}
TGeoNode* fNode = // prepare local->global trafo
gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
// fNode->Print();
if (NULL == fNode) { // Transformation matrix not available !!!??? - Check
LOG(error) << Form("Node at (%6.1f,%6.1f,%6.1f) : %p", fChannelInfo->GetX(), fChannelInfo->GetY(),
fChannelInfo->GetZ(), fNode);
ChangeState(fair::mq::Transition::Stop);
}
CbmTofDigi* xDigiA = fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][0];
CbmTofDigi* xDigiB = fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][1];
dTimeDif = (xDigiA->GetTime() - xDigiB->GetTime());
if (5 == iSmType && dTimeDif != 0.) {
// FIXME -> Overflow treatment in calib/tdc/TMbsCalibTdcTof.cxx
LOG(debug) << "BuildHits: Diamond hit in " << iSm << " with inconsistent digits "
<< xDigiA->GetTime() << ", " << xDigiB->GetTime() << " -> " << dTimeDif;
/*
LOG(debug) << " "<<xDigiA->ToString();
LOG(debug) << " "<<xDigiB->ToString();
*/
}
if (1 == xDigiA->GetSide())
// 0 is the top side, 1 is the bottom side
dPosY = fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * dTimeDif * 0.5;
else
// 0 is the bottom side, 1 is the top side
dPosY = -fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * dTimeDif * 0.5;
if (TMath::Abs(dPosY) > fChannelInfo->GetSizey()
&& fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size() > 2) {
LOG(debug) << "Hit candidate outside correlation window, check for "
"better possible digis, "
<< " mul " << fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size();
CbmTofDigi* xDigiC = fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][2];
Double_t dPosYN = 0.;
Double_t dTimeDifN = 0;
if (xDigiC->GetSide() == xDigiA->GetSide()) dTimeDifN = xDigiC->GetTime() - xDigiB->GetTime();
else
dTimeDifN = xDigiA->GetTime() - xDigiC->GetTime();
if (1 == xDigiA->GetSide()) dPosYN = fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * dTimeDifN * 0.5;
else
dPosYN = -fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * dTimeDifN * 0.5;
if (TMath::Abs(dPosYN) < TMath::Abs(dPosY)) {
LOG(debug) << "Replace digi on side " << xDigiC->GetSide() << ", yPosNext " << dPosYN
<< " old: " << dPosY;
dTimeDif = dTimeDifN;
dPosY = dPosYN;
if (xDigiC->GetSide() == xDigiA->GetSide()) {
xDigiA = xDigiC;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
}
else {
xDigiB = xDigiC;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
++(fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin() + 1));
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
++(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin() + 1));
}
}
}
if (xDigiA->GetSide() == xDigiB->GetSide()) {
LOG(error) << "Wrong combinations of digis " << fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][0]
<< "," << fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][1];
}
// The "Strip" time is the mean time between each end
dTime = 0.5 * (xDigiA->GetTime() + xDigiB->GetTime());
// Weight is the total charge => sum of both ends ToT
dTotS = xDigiA->GetTot() + xDigiB->GetTot();
// use local coordinates, (0,0,0) is in the center of counter ?
dPosX = ((Double_t)(-iNbCh / 2 + iCh) + 0.5) * fChannelInfo->GetSizex();
dPosZ = 0.;
/*
LOG(debug)
<<"NbChanInHit "
<< Form(" %3d %3d %3d %3d %3d 0x%p %1.0f Time %f PosX %f PosY %f Svel %f ",
iNbChanInHit,iSmType,iRpc,iCh,iLastChan,xDigiA,xDigiA->GetSide(),
dTime,dPosX,dPosY,fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))
// << Form( ", Offs %f, %f ",fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][0],
// fvCPTOff[iSmType][iSm*iNbRpc+iRpc][iCh][1])
;
*/
// Now check if a hit/cluster is already started
if (0 < iNbChanInHit) {
if (iLastChan == iCh - 1) {
/*
fhDigTimeDifClust->Fill( dTime - dLastTime );
fhDigSpacDifClust->Fill( dPosY - dLastPosY );
fhDigDistClust->Fill( dPosY - dLastPosY,
dTime - dLastTime );
*/
}
// if( iLastChan == iCh - 1 )
// a cluster is already started => check distance in space/time
// For simplicity, just check along strip direction for now
// and break cluster when a not fired strip is found
if (TMath::Abs(dTime - dLastTime) < fdMaxTimeDist && iLastChan == iCh - 1
&& TMath::Abs(dPosY - dLastPosY) < fdMaxSpaceDist) {
// Add to cluster/hit
dWeightedTime += dTime * dTotS;
dWeightedPosX += dPosX * dTotS;
dWeightedPosY += dPosY * dTotS;
dWeightedPosZ += dPosZ * dTotS;
dWeightsSum += dTotS;
iNbChanInHit += 1;
vDigiIndRef.push_back((Int_t)(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][0]));
vDigiIndRef.push_back((Int_t)(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][1]));
LOG(debug) << " Add Digi and erase fStor entries(a): NbChanInHit " << iNbChanInHit << ", "
<< iSmType << ", SR " << iSm * iNbRpc + iRpc << ", Ch" << iCh;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
} // if current Digis compatible with last fired chan
else {
// Save Hit
dWeightedTime /= dWeightsSum;
dWeightedPosX /= dWeightsSum;
dWeightedPosY /= dWeightsSum;
dWeightedPosZ /= dWeightsSum;
// TVector3 hitPosLocal(dWeightedPosX, dWeightedPosY, dWeightedPosZ);
//TVector3 hitPos;
Double_t hitpos_local[3];
hitpos_local[0] = dWeightedPosX;
hitpos_local[1] = dWeightedPosY;
hitpos_local[2] = dWeightedPosZ;
Double_t hitpos[3];
//TGeoNode* cNode =
gGeoManager->GetCurrentNode();
/*TGeoHMatrix* cMatrix =*/gGeoManager->GetCurrentMatrix();
//cNode->Print();
//cMatrix->Print();
gGeoManager->LocalToMaster(hitpos_local, hitpos);
/*
LOG(debug)<<
Form("LocalToMaster for node %p: (%6.1f,%6.1f,%6.1f) ->(%6.1f,%6.1f,%6.1f)",
cNode, hitpos_local[0], hitpos_local[1], hitpos_local[2],
hitpos[0], hitpos[1], hitpos[2]);
*/
TVector3 hitPos(hitpos[0], hitpos[1], hitpos[2]);
// Simple errors, not properly done at all for now
// Right way of doing it should take into account the weight distribution
// and real system time resolution
TVector3 hitPosErr(0.5, 0.5, 0.5); // including positioning uncertainty
/*
TVector3 hitPosErr( fChannelInfo->GetSizex()/TMath::Sqrt(12.0), // Single strips approximation
0.5, // Use generic value
1.);
*/
//fDigiBdfPar->GetFeeTimeRes() * fDigiBdfPar->GetSigVel(iSmType,iRpc), // Use the electronics resolution
//fDigiBdfPar->GetNbGaps( iSmType, iRpc)*
//fDigiBdfPar->GetGapSize( iSmType, iRpc)/ //10.0 / // Change gap size in cm
//TMath::Sqrt(12.0) ); // Use full RPC thickness as "Channel" Z size
// Int_t iDetId = vPtsRef[0]->GetDetectorID();// detID = pt->GetDetectorID() <= from TofPoint
// calc mean ch from dPosX=((Double_t)(-iNbCh/2 + iCh)+0.5)*fChannelInfo->GetSizex();
Int_t iChm = floor(dWeightedPosX / fChannelInfo->GetSizex()) + iNbCh / 2;
if (iChm < 0) iChm = 0;
if (iChm > iNbCh - 1) iChm = iNbCh - 1;
iDetId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, iChm, 0, iSmType);
//Int_t iRefId = 0; // Index of the correspondng TofPoint
// if(NULL != fTofPointsColl) {
//iRefId = fTofPointsColl->IndexOf( vPtsRef[0] );
//}
/*
LOG(debug)<<"Save Hit "
<< Form(" %3d %3d 0x%08x %3d %3d %3d %f %f",
fiNbHits,iNbChanInHit,iDetId,iChm,iLastChan,iRefId,
dWeightedTime,dWeightedPosY)
<<", DigiSize: "<<vDigiIndRef.size()
<<", DigiInds: ";
for (UInt_t i=0; i<vDigiIndRef.size();i++){
LOG(debug)<<" "<<vDigiIndRef.at(i)<<"(M"<<fviClusterMul[iSmType][iSm][iRpc]<<")";
}
*/
fviClusterMul[iSmType][iSm][iRpc]++;
if (vDigiIndRef.size() < 2) {
LOG(warn) << "Digi refs for Hit " << fiNbHits << ": " << vDigiIndRef.size();
}
if (fiNbHits > 0) {
CbmTofHit* pHitL = (CbmTofHit*) fTofHitsColl->At(fiNbHits - 1);
if (iDetId == pHitL->GetAddress() && dWeightedTime == pHitL->GetTime()) {
LOG(debug) << "Store Hit twice? "
<< " fiNbHits " << fiNbHits << ", " << Form("0x%08x", iDetId);
}
}
CbmTofHit* pHit =
new CbmTofHit(iDetId, hitPos,
hitPosErr, //local detector coordinates
fiNbHits, // this number is used as reference!!
dWeightedTime,
vDigiIndRef.size(), // number of linked digis = 2*CluSize
//vPtsRef.size(), // flag = number of TofPoints generating the cluster
Int_t(dWeightsSum * 10.)); //channel -> Tot
//0) ; //channel
// output hit
new ((*fTofHitsColl)[fiNbHits]) CbmTofHit(*pHit);
// memorize hit
if (fdMemoryTime > 0.) { LH_store(iSmType, iSm, iRpc, iChm, pHit); }
else {
pHit->Delete();
}
/*
new((*fTofDigiMatchColl)[fiNbHits]) CbmMatch();
CbmMatch* digiMatch = (CbmMatch *)fTofDigiMatchColl->At(fiNbHits);
*/
CbmMatch* digiMatch = new ((*fTofDigiMatchColl)[fiNbHits]) CbmMatch();
for (UInt_t i = 0; i < vDigiIndRef.size(); i++) {
Double_t dTot = ((CbmTofDigi*) (&(fTofCalDigiVec->at(vDigiIndRef.at(i)))))->GetTot();
digiMatch->AddLink(CbmLink(dTot, vDigiIndRef.at(i), fiOutputTreeEntry, fiFileIndex));
}
fiNbHits++;
// For Histogramming
fviClusterSize[iSmType][iRpc].push_back(iNbChanInHit);
//fviTrkMul[iSmType][iRpc].push_back( vPtsRef.size() );
fvdX[iSmType][iRpc].push_back(dWeightedPosX);
fvdY[iSmType][iRpc].push_back(dWeightedPosY);
/* no TofPoint available for data!
fvdDifX[iSmType][iRpc].push_back( vPtsRef[0]->GetX() - dWeightedPosX);
fvdDifY[iSmType][iRpc].push_back( vPtsRef[0]->GetY() - dWeightedPosY);
fvdDifCh[iSmType][iRpc].push_back( fGeoHandler->GetCell( vPtsRef[0]->GetDetectorID() ) -1 -iLastChan );
*/
//vPtsRef.clear();
vDigiIndRef.clear();
// Start a new hit
dWeightedTime = dTime * dTotS;
dWeightedPosX = dPosX * dTotS;
dWeightedPosY = dPosY * dTotS;
dWeightedPosZ = dPosZ * dTotS;
dWeightsSum = dTotS;
iNbChanInHit = 1;
// Save pointer on CbmTofPoint
// vPtsRef.push_back( (CbmTofPoint*)(xDigiA->GetLinks()) );
// Save next digi address
vDigiIndRef.push_back((Int_t)(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][0]));
vDigiIndRef.push_back((Int_t)(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][1]));
//LOG(debug2)<<"Erase fStor entries(b) "<<iSmType<<", SR "<<iSm*iNbRpc+iRpc<<", Ch"<<iCh;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
} // else of if current Digis compatible with last fired chan
} // if( 0 < iNbChanInHit)
else {
LOG(debug) << Form("1.Hit on channel %d, time: %f, PosY %f", iCh, dTime, dPosY);
// first fired strip in this RPC
dWeightedTime = dTime * dTotS;
dWeightedPosX = dPosX * dTotS;
dWeightedPosY = dPosY * dTotS;
dWeightedPosZ = dPosZ * dTotS;
dWeightsSum = dTotS;
iNbChanInHit = 1;
// Save pointer on CbmTofPoint
//if(NULL != fTofPointsColl)
// vPtsRef.push_back( (CbmTofPoint*)(xDigiA->GetLinks()) );
vDigiIndRef.push_back((Int_t)(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][0]));
vDigiIndRef.push_back((Int_t)(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][1]));
//LOG(debug)<<"Erase fStor entries(c) "<<iSmType<<", SR "<<iSm*iNbRpc+iRpc<<", Ch"<<iCh;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin());
} // else of if( 0 < iNbChanInHit)
iLastChan = iCh;
dLastPosX = dPosX;
dLastPosY = dPosY;
dLastTime = dTime;
if (AddNextChan(iSmType, iSm, iRpc, iLastChan, dLastPosX, dLastPosY, dLastTime, dWeightsSum)) {
iNbChanInHit = 0; // cluster already stored
}
} // while( 1 < fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size() )
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].clear();
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].clear();
} // for( Int_t iCh = 0; iCh < iNbCh; iCh++ )
//LOG(debug2)<<"finished V-RPC"
// << Form(" %3d %3d %3d %d %f %fx",iSmType,iSm,iRpc,fTofHitsColl->GetEntriesFast(),dLastPosX,dLastPosY);
} // else of if( 1 == fDigiBdfPar->GetChanOrient( iSmType, iRpc ) )
} // if( 0 == iChType)
else {
LOG(error) << "=> Cluster building "
<< "from digis to hits not implemented for pads, Sm type " << iSmType << " Rpc " << iRpc;
return kFALSE;
} // else of if( 0 == iChType)
// Now check if another hit/cluster is started
// and save it if it's the case
if (0 < iNbChanInHit) {
/*
LOG(debug)<<"Process cluster "
<<iNbChanInHit;
*/
// Check orientation to properly assign errors
if (1 == fDigiBdfPar->GetChanOrient(iSmType, iRpc)) {
// LOG(debug1)<<"H-Hit ";
} // if( 1 == fDigiBdfPar->GetChanOrient( iSmType, iRpc ) )
else {
//LOG(debug2)<<"V-Hit ";
// Save Hit
dWeightedTime /= dWeightsSum;
dWeightedPosX /= dWeightsSum;
dWeightedPosY /= dWeightsSum;
dWeightedPosZ /= dWeightsSum;
//TVector3 hitPos(dWeightedPosX, dWeightedPosY, dWeightedPosZ);
Double_t hitpos_local[3] = {3 * 0.};
hitpos_local[0] = dWeightedPosX;
hitpos_local[1] = dWeightedPosY;
hitpos_local[2] = dWeightedPosZ;
Double_t hitpos[3];
//TGeoNode* cNode=
gGeoManager->GetCurrentNode();
/*TGeoHMatrix* cMatrix =*/gGeoManager->GetCurrentMatrix();
//cNode->Print();
//cMatrix->Print();
gGeoManager->LocalToMaster(hitpos_local, hitpos);
/*
LOG(debug)<<
Form(" LocalToMaster for V-node %p: (%6.1f,%6.1f,%6.1f) ->(%6.1f,%6.1f,%6.1f)",
cNode, hitpos_local[0], hitpos_local[1], hitpos_local[2],
hitpos[0], hitpos[1], hitpos[2])
;
*/
TVector3 hitPos(hitpos[0], hitpos[1], hitpos[2]);
// Event errors, not properly done at all for now
// Right way of doing it should take into account the weight distribution
// and real system time resolution
TVector3 hitPosErr(0.5, 0.5, 0.5); // including positioning uncertainty
/*
TVector3 hitPosErr( fChannelInfo->GetSizex()/TMath::Sqrt(12.0), // Single strips approximation
0.5, // Use generic value
1.);
*/
Int_t iChm = floor(dWeightedPosX / fChannelInfo->GetSizex()) + iNbCh / 2;
if (iChm < 0) iChm = 0;
if (iChm > iNbCh - 1) iChm = iNbCh - 1;
iDetId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, iChm, 0, iSmType);
//Int_t iRefId = 0; // Index of the correspondng TofPoint
//if(NULL != fTofPointsColl) iRefId = fTofPointsColl->IndexOf( vPtsRef[0] );
/*
LOG(debug)<<"Save V-Hit "
<< Form(" %3d %3d 0x%08x %3d 0x%08x", // %3d %3d
fiNbHits,iNbChanInHit,iDetId,iLastChan,iRefId) //vPtsRef.size(),vPtsRef[0])
// dWeightedTime,dWeightedPosY)
<<", DigiSize: "<<vDigiIndRef.size();
for (UInt_t i=0; i<vDigiIndRef.size();i++){
LOG(debug)<<"DigiIndRef "<<i<<" "<<vDigiIndRef.at(i)<<"(M"<<fviClusterMul[iSmType][iSm][iRpc]<<")";
}
*/
fviClusterMul[iSmType][iSm][iRpc]++;
if (vDigiIndRef.size() < 2) {
LOG(warn) << "Digi refs for Hit " << fiNbHits << ": " << vDigiIndRef.size();
}
if (fiNbHits > 0) {
CbmTofHit* pHitL = (CbmTofHit*) fTofHitsColl->At(fiNbHits - 1);
if (iDetId == pHitL->GetAddress() && dWeightedTime == pHitL->GetTime())
LOG(debug) << "Store Hit twice? "
<< " fiNbHits " << fiNbHits << ", " << Form("0x%08x", iDetId);
}
CbmTofHit* pHit = new CbmTofHit(iDetId, hitPos,
hitPosErr, //local detector coordinates
fiNbHits, // this number is used as reference!!
dWeightedTime,
vDigiIndRef.size(), // number of linked digis = 2*CluSize
//vPtsRef.size(), // flag = number of TofPoints generating the cluster
Int_t(dWeightsSum * 10.)); //channel -> Tot
// 0) ; //channel
// vDigiIndRef);
// output hit
new ((*fTofHitsColl)[fiNbHits]) CbmTofHit(*pHit);
// memorize hit
if (fdMemoryTime > 0.) { LH_store(iSmType, iSm, iRpc, iChm, pHit); }
else {
pHit->Delete();
}
/*
new((*fTofDigiMatchColl)[fiNbHits]) CbmMatch();
CbmMatch* digiMatch = (CbmMatch *)fTofDigiMatchColl->At(fiNbHits);
*/
CbmMatch* digiMatch = new ((*fTofDigiMatchColl)[fiNbHits]) CbmMatch();
for (UInt_t i = 0; i < vDigiIndRef.size(); i++) {
Double_t dTot = ((CbmTofDigi*) (&(fTofCalDigiVec->at(vDigiIndRef.at(i)))))->GetTot();
digiMatch->AddLink(CbmLink(dTot, vDigiIndRef.at(i), fiOutputTreeEntry, fiFileIndex));
}
fiNbHits++;
// For Histogramming
fviClusterSize[iSmType][iRpc].push_back(iNbChanInHit);
//fviTrkMul[iSmType][iRpc].push_back( vPtsRef.size() );
fvdX[iSmType][iRpc].push_back(dWeightedPosX);
fvdY[iSmType][iRpc].push_back(dWeightedPosY);
/*
fvdDifX[iSmType][iRpc].push_back( vPtsRef[0]->GetX() - dWeightedPosX);
fvdDifY[iSmType][iRpc].push_back( vPtsRef[0]->GetY() - dWeightedPosY);
fvdDifCh[iSmType][iRpc].push_back( fGeoHandler->GetCell( vPtsRef[0]->GetDetectorID() ) -1 -iLastChan );
*/
//vPtsRef.clear();
vDigiIndRef.clear();
} // else of if( 1 == fDigiBdfPar->GetChanOrient( iSmType, iRpc ) )
} // if( 0 < iNbChanInHit)
} // for each sm/rpc pair
} // for( Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++ )
}
return kTRUE;
}
/************************************************************************************/
Bool_t CbmDeviceHitBuilderTof::MergeClusters() { return kTRUE; }
void CbmDeviceHitBuilderTof::LH_store(Int_t iSmType, Int_t iSm, Int_t iRpc, Int_t iChm, CbmTofHit* pHit)
{
if (fvLastHits[iSmType][iSm][iRpc][iChm].size() == 0) fvLastHits[iSmType][iSm][iRpc][iChm].push_back(pHit);
else {
Double_t dLastTime = pHit->GetTime();
if (dLastTime >= fvLastHits[iSmType][iSm][iRpc][iChm].back()->GetTime()) {
fvLastHits[iSmType][iSm][iRpc][iChm].push_back(pHit);
LOG(debug) << Form(" Store LH from Ev %8.0f for TSRC %d%d%d%d, size %lu, addr 0x%08x, "
"time %f, dt %f",
fdEvent, iSmType, iSm, iRpc, iChm, fvLastHits[iSmType][iSm][iRpc][iChm].size(),
pHit->GetAddress(), dLastTime,
dLastTime - fvLastHits[iSmType][iSm][iRpc][iChm].front()->GetTime());
}
else {
if (dLastTime
>= fvLastHits[iSmType][iSm][iRpc][iChm].front()->GetTime()) { // hit has to be inserted in the proper place
std::list<CbmTofHit*>::iterator it;
for (it = fvLastHits[iSmType][iSm][iRpc][iChm].begin(); it != fvLastHits[iSmType][iSm][iRpc][iChm].end(); ++it)
if ((*it)->GetTime() > dLastTime) break;
fvLastHits[iSmType][iSm][iRpc][iChm].insert(--it, pHit);
Double_t deltaTime = dLastTime - (*it)->GetTime();
LOG(debug) << Form("Hit inserted into LH from Ev %8.0f for TSRC "
"%d%d%d%d, size %lu, addr 0x%08x, delta time %f ",
fdEvent, iSmType, iSm, iRpc, iChm, fvLastHits[iSmType][iSm][iRpc][iChm].size(),
pHit->GetAddress(), deltaTime);
}
else { // this hit is first
Double_t deltaTime = dLastTime - fvLastHits[iSmType][iSm][iRpc][iChm].front()->GetTime();
LOG(debug) << Form("first LH from Ev %8.0f for TSRC %d%d%d%d, size "
"%lu, addr 0x%08x, delta time %f ",
fdEvent, iSmType, iSm, iRpc, iChm, fvLastHits[iSmType][iSm][iRpc][iChm].size(),
pHit->GetAddress(), deltaTime);
if (deltaTime == 0.) {
// remove hit, otherwise double entry?
pHit->Delete();
}
else {
fvLastHits[iSmType][iSm][iRpc][iChm].push_front(pHit);
}
}
}
}
}
void CbmDeviceHitBuilderTof::CheckLHMemory()
{
if ((Int_t) fvLastHits.size() != fDigiBdfPar->GetNbSmTypes())
LOG(error) << Form("Inconsistent LH Smtype size %lu, %d ", fvLastHits.size(), fDigiBdfPar->GetNbSmTypes());
for (Int_t iSmType = 0; iSmType < fDigiBdfPar->GetNbSmTypes(); iSmType++) {
if ((Int_t) fvLastHits[iSmType].size() != fDigiBdfPar->GetNbSm(iSmType))
LOG(error) << Form("Inconsistent LH Sm size %lu, %d T %d", fvLastHits[iSmType].size(),
fDigiBdfPar->GetNbSm(iSmType), iSmType);
for (Int_t iSm = 0; iSm < fDigiBdfPar->GetNbSm(iSmType); iSm++) {
if ((Int_t) fvLastHits[iSmType][iSm].size() != fDigiBdfPar->GetNbRpc(iSmType))
LOG(error) << Form("Inconsistent LH Rpc size %lu, %d TS %d%d ", fvLastHits[iSmType][iSm].size(),
fDigiBdfPar->GetNbRpc(iSmType), iSmType, iSm);
for (Int_t iRpc = 0; iRpc < fDigiBdfPar->GetNbRpc(iSmType); iRpc++) {
if ((Int_t) fvLastHits[iSmType][iSm][iRpc].size() != fDigiBdfPar->GetNbChan(iSmType, iRpc))
LOG(error) << Form("Inconsistent LH RpcChannel size %lu, %d TSR %d%d%d ",
fvLastHits[iSmType][iSm][iRpc].size(), fDigiBdfPar->GetNbChan(iSmType, iRpc), iSmType, iSm,
iRpc);
for (Int_t iCh = 0; iCh < fDigiBdfPar->GetNbChan(iSmType, iRpc); iCh++)
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 0) {
CbmTofDetectorInfo xDetInfo(ECbmModuleId::kTof, iSmType, iSm, iRpc, 0, iCh);
Int_t iAddr = fTofId->SetDetectorInfo(xDetInfo);
if (fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetAddress() != iAddr)
LOG(error) << Form("Inconsistent address for Ev %8.0f in list of size %lu for "
"TSRC %d%d%d%d: 0x%08x, time %f",
fdEvent, fvLastHits[iSmType][iSm][iRpc][iCh].size(), iSmType, iSm, iRpc, iCh,
fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetAddress(),
fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetTime());
}
}
}
}
LOG(debug) << Form("LH check passed for event %8.0f", fdEvent);
}
void CbmDeviceHitBuilderTof::CleanLHMemory()
{
if ((Int_t) fvLastHits.size() != fDigiBdfPar->GetNbSmTypes())
LOG(error) << Form("Inconsistent LH Smtype size %lu, %d ", fvLastHits.size(), fDigiBdfPar->GetNbSmTypes());
for (Int_t iSmType = 0; iSmType < fDigiBdfPar->GetNbSmTypes(); iSmType++) {
if ((Int_t) fvLastHits[iSmType].size() != fDigiBdfPar->GetNbSm(iSmType))
LOG(error) << Form("Inconsistent LH Sm size %lu, %d T %d", fvLastHits[iSmType].size(),
fDigiBdfPar->GetNbSm(iSmType), iSmType);
for (Int_t iSm = 0; iSm < fDigiBdfPar->GetNbSm(iSmType); iSm++) {
if ((Int_t) fvLastHits[iSmType][iSm].size() != fDigiBdfPar->GetNbRpc(iSmType))
LOG(error) << Form("Inconsistent LH Rpc size %lu, %d TS %d%d ", fvLastHits[iSmType][iSm].size(),
fDigiBdfPar->GetNbRpc(iSmType), iSmType, iSm);
for (Int_t iRpc = 0; iRpc < fDigiBdfPar->GetNbRpc(iSmType); iRpc++) {
if ((Int_t) fvLastHits[iSmType][iSm][iRpc].size() != fDigiBdfPar->GetNbChan(iSmType, iRpc))
LOG(error) << Form("Inconsistent LH RpcChannel size %lu, %d TSR %d%d%d ",
fvLastHits[iSmType][iSm][iRpc].size(), fDigiBdfPar->GetNbChan(iSmType, iRpc), iSmType, iSm,
iRpc);
for (Int_t iCh = 0; iCh < fDigiBdfPar->GetNbChan(iSmType, iRpc); iCh++)
while (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 0) {
CbmTofDetectorInfo xDetInfo(ECbmModuleId::kTof, iSmType, iSm, iRpc, 0, iCh);
Int_t iAddr = fTofId->SetDetectorInfo(xDetInfo);
if (fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetAddress() != iAddr)
LOG(error) << Form("Inconsistent address for Ev %8.0f in list of size %lu for "
"TSRC %d%d%d%d: 0x%08x, time %f",
fdEvent, fvLastHits[iSmType][iSm][iRpc][iCh].size(), iSmType, iSm, iRpc, iCh,
fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetAddress(),
fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetTime());
fvLastHits[iSmType][iSm][iRpc][iCh].front()->Delete();
fvLastHits[iSmType][iSm][iRpc][iCh].pop_front();
}
}
}
}
LOG(info) << Form("LH cleaning done after %8.0f events", fdEvent);
}
Bool_t CbmDeviceHitBuilderTof::AddNextChan(Int_t iSmType, Int_t iSm, Int_t iRpc, Int_t iLastChan, Double_t dLastPosX,
Double_t dLastPosY, Double_t dLastTime, Double_t dLastTotS)
{
//Int_t iNbSm = fDigiBdfPar->GetNbSm( iSmType);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
Int_t iNbCh = fDigiBdfPar->GetNbChan(iSmType, iRpc);
// Int_t iChType = fDigiBdfPar->GetChanType( iSmType, iRpc );
Int_t iCh = iLastChan + 1;
LOG(debug) << Form("Inspect channel TSRC %d%d%d%d at time %f, pos %f, size ", iSmType, iSm, iRpc, iCh, dLastTime,
dLastPosY)
<< fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size();
if (iCh == iNbCh) return kFALSE;
if (0 == fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size()) return kFALSE;
//if( 0 < fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size() )
// fhNbDigiPerChan->Fill( fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size() );
if (1 < fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size()) {
Bool_t AddedHit = kFALSE;
for (Int_t i1 = 0; i1 < (Int_t) fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size() - 1; i1++) {
if (AddedHit) break;
Int_t i2 = i1 + 1;
while (!AddedHit && i2 < (Int_t) fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].size()) {
// LOG(debug)<<"check digi pair "<<i1<<","<<i2<<" with size "<<fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size();
if ((fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][i1])->GetSide()
== (fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][i2])->GetSide()) {
i2++;
continue;
} // endif same side
// 2 Digis, both sides present
CbmTofDigi* xDigiA = fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][i1];
CbmTofDigi* xDigiB = fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh][i2];
Double_t dTime = 0.5 * (xDigiA->GetTime() + xDigiB->GetTime());
if (TMath::Abs(dTime - dLastTime) < fdMaxTimeDist) {
CbmTofDetectorInfo xDetInfo(ECbmModuleId::kTof, iSmType, iSm, iRpc, 0, iCh);
Int_t iChId = fTofId->SetDetectorInfo(xDetInfo);
fChannelInfo = fDigiPar->GetCell(iChId);
gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
Double_t dTimeDif = xDigiA->GetTime() - xDigiB->GetTime();
Double_t dPosY = 0.;
if (1 == xDigiA->GetSide()) dPosY = fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * dTimeDif * 0.5;
else
dPosY = -fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc) * dTimeDif * 0.5;
if (TMath::Abs(dPosY - dLastPosY) < fdMaxSpaceDist) { // append digi pair to current cluster
Double_t dNClHits = (Double_t)(vDigiIndRef.size() / 2);
Double_t dPosX = ((Double_t)(-iNbCh / 2 + iCh) + 0.5) * fChannelInfo->GetSizex();
Double_t dTotS = xDigiA->GetTot() + xDigiB->GetTot();
Double_t dNewTotS = (dLastTotS + dTotS);
dLastPosX = (dLastPosX * dLastTotS + dPosX * dTotS) / dNewTotS;
dLastPosY = (dLastPosY * dLastTotS + dPosY * dTotS) / dNewTotS;
dLastTime = (dLastTime * dLastTotS + dTime * dTotS) / dNewTotS;
dLastTotS = dNewTotS;
// attach selected digis from pool
Int_t Ind1 = fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][i1];
Int_t Ind2 = fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh][i2];
vDigiIndRef.push_back(Ind1);
vDigiIndRef.push_back(Ind2);
// remove selected digis from pool
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin()
+ i1);
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin() + i1);
std::vector<int>::iterator it;
it = find(fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin(),
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].end(), Ind2);
if (it != fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].end()) {
auto ipos = it - fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin();
LOG(debug) << "Found i2 " << i2 << " with Ind2 " << Ind2 << " at position " << ipos;
fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].erase(fStorDigi[iSmType][iSm * iNbRpc + iRpc][iCh].begin()
+ ipos);
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].erase(
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc][iCh].begin() + ipos);
}
else {
LOG(error) << " Did not find i2 " << i2 << " with Ind2 " << Ind2;
}
//if(iCh == iNbCh-1) break; //Last strip reached
if (iCh != (iNbCh - 1)
&& AddNextChan(iSmType, iSm, iRpc, iCh, dLastPosX, dLastPosY, dLastTime, dLastTotS)) {
LOG(debug) << "Added Strip " << iCh << " to cluster of size " << dNClHits;
return kTRUE; // signal hit was already added
}
AddedHit = kTRUE;
} //TMath::Abs(dPosY - dLastPosY) < fdMaxSpaceDist
} //TMath::Abs(dTime-dLastTime)<fdMaxTimeDist)
i2++;
} // while(i2 < fStorDigi[iSmType][iSm*iNbRpc+iRpc][iCh].size()-1 )
} // end for i1
} // end if size
Double_t hitpos_local[3] = {3 * 0.};
hitpos_local[0] = dLastPosX;
hitpos_local[1] = dLastPosY;
hitpos_local[2] = 0.;
Double_t hitpos[3];
TGeoNode* cNode = gGeoManager->GetCurrentNode();
if (NULL == cNode) { // Transformation matrix not available !!!??? - Check
LOG(error) << Form("Node at (%6.1f,%6.1f,%6.1f) : %p", fChannelInfo->GetX(), fChannelInfo->GetY(),
fChannelInfo->GetZ(), cNode);
ChangeState(fair::mq::Transition::Stop);
}
/*TGeoHMatrix* cMatrix = */ gGeoManager->GetCurrentMatrix();
gGeoManager->LocalToMaster(hitpos_local, hitpos);
TVector3 hitPos(hitpos[0], hitpos[1], hitpos[2]);
TVector3 hitPosErr(0.5, 0.5, 0.5); // FIXME including positioning uncertainty
Int_t iChm = floor(dLastPosX / fChannelInfo->GetSizex()) + iNbCh / 2;
if (iChm < 0) iChm = 0;
if (iChm > iNbCh - 1) iChm = iNbCh - 1;
Int_t iDetId = CbmTofAddress::GetUniqueAddress(iSm, iRpc, iChm, 0, iSmType);
// Int_t iNbChanInHit=vDigiIndRef.size()/2;
fviClusterMul[iSmType][iSm][iRpc]++;
/*
LOG(debug)<<"Save A-Hit "
<< Form("%2d %2d 0x%08x %3d t %f, y %f ",
fiNbHits,iNbChanInHit,iDetId,iLastChan,dLastTime,dLastPosY)
<<", DigiSize: "<<vDigiIndRef.size();
for (UInt_t i=0; i<vDigiIndRef.size();i++){
LOG(debug)<<"DigiIndRef "<<i<<" "<<vDigiIndRef.at(i)<<"(M"<<fviClusterMul[iSmType][iSm][iRpc]<<")";
}
*/
CbmTofHit* pHit = new CbmTofHit(iDetId, hitPos,
hitPosErr, //local detector coordinates
fiNbHits, // this number is used as reference!!
dLastTime,
vDigiIndRef.size(), // number of linked digis = 2*CluSize
//vPtsRef.size(), // flag = number of TofPoints generating the cluster
Int_t(dLastTotS * 10.)); //channel -> Tot
// output hit
new ((*fTofHitsColl)[fiNbHits]) CbmTofHit(*pHit);
if (fdMemoryTime > 0.) { // memorize hit
LH_store(iSmType, iSm, iRpc, iChm, pHit);
}
else {
pHit->Delete();
}
CbmMatch* digiMatch = new ((*fTofDigiMatchColl)[fiNbHits]) CbmMatch();
for (Int_t i = 0; i < (Int_t) vDigiIndRef.size(); i++) {
Double_t dTot = ((CbmTofDigi*) (&(fTofCalDigiVec->at(vDigiIndRef.at(i)))))->GetTot();
digiMatch->AddLink(CbmLink(dTot, vDigiIndRef.at(i), fiOutputTreeEntry, fiFileIndex));
}
fiNbHits++;
vDigiIndRef.clear();
return kTRUE;
}
static Double_t f1_xboxe(double* x, double* par)
{
double xx = x[0];
double wx = 1. - par[4] * TMath::Power(xx + par[5], 2);
double xboxe = par[0] * 0.25 * (1. + TMath::Erf((xx + par[1] - par[3]) / par[2]))
* (1. + TMath::Erf((-xx + par[1] + par[3]) / par[2]));
return xboxe * wx;
}
void CbmDeviceHitBuilderTof::fit_ybox(const char* hname)
{
TH1* h1;
h1 = (TH1*) gROOT->FindObjectAny(hname);
if (NULL != h1) { fit_ybox(h1, 0.); }
}
void CbmDeviceHitBuilderTof::fit_ybox(TH1* h1, Double_t ysize)
{
Double_t* fpar = NULL;
fit_ybox(h1, ysize, fpar);
}
void CbmDeviceHitBuilderTof::fit_ybox(TH1* h1, Double_t ysize, Double_t* fpar = NULL)
{
TAxis* xaxis = h1->GetXaxis();
Double_t Ymin = xaxis->GetXmin();
Double_t Ymax = xaxis->GetXmax();
TF1* f1 = new TF1("YBox", f1_xboxe, Ymin, Ymax, 6);
Double_t yini = (h1->GetMaximum() + h1->GetMinimum()) * 0.5;
if (ysize == 0.) ysize = Ymax * 0.8;
f1->SetParameters(yini, ysize * 0.5, 1., 0., 0., 0.);
// f1->SetParLimits(1,ysize*0.8,ysize*1.2);
f1->SetParLimits(2, 0.2, 3.);
f1->SetParLimits(3, -4., 4.);
if (fpar != NULL) {
Double_t fp[4];
for (Int_t i = 0; i < 4; i++)
fp[i] = *fpar++;
for (Int_t i = 0; i < 4; i++)
f1->SetParameter(2 + i, fp[i]);
LOG(debug) << "Ini Fpar for " << h1->GetName() << " with "
<< Form(" %6.3f %6.3f %6.3f %6.3f ", fp[0], fp[1], fp[2], fp[3]);
}
h1->Fit("YBox", "Q");
double res[10];
double err[10];
res[9] = f1->GetChisquare();
for (int i = 0; i < 6; i++) {
res[i] = f1->GetParameter(i);
err[i] = f1->GetParError(i);
//cout << " FPar "<< i << ": " << res[i] << ", " << err[i] << endl;
}
LOG(debug) << "YBox Fit of " << h1->GetName() << " ended with chi2 = " << res[9]
<< Form(", strip length %7.2f +/- %5.2f, position resolution "
"%7.2f +/- %5.2f at y_cen = %7.2f +/- %5.2f",
2. * res[1], 2. * err[1], res[2], err[2], res[3], err[3]);
}
Bool_t CbmDeviceHitBuilderTof::LoadGeometry()
{
LOG(info) << "LoadGeometry starting for " << fDigiBdfPar->GetNbDet() << " described detectors, "
<< fDigiPar->GetNrOfModules() << " geometrically known modules ";
//gGeoManager->Export("HitBuilder.loadgeo.root"); // write current status to file
Int_t iNrOfCells = fDigiPar->GetNrOfModules();
LOG(info) << "Digi Parameter container contains " << iNrOfCells << " cells.";
for (Int_t icell = 0; icell < iNrOfCells; ++icell) {
Int_t cellId = fDigiPar->GetCellId(icell); // cellId is assigned in CbmTofCreateDigiPar
fChannelInfo = fDigiPar->GetCell(cellId);
Int_t smtype = fGeoHandler->GetSMType(cellId);
Int_t smodule = fGeoHandler->GetSModule(cellId);
Int_t module = fGeoHandler->GetCounter(cellId);
Int_t cell = fGeoHandler->GetCell(cellId);
Double_t x = fChannelInfo->GetX();
Double_t y = fChannelInfo->GetY();
Double_t z = fChannelInfo->GetZ();
Double_t dx = fChannelInfo->GetSizex();
Double_t dy = fChannelInfo->GetSizey();
LOG(debug) << "-I- InitPar " << icell << " Id: " << Form("0x%08x", cellId) << " " << cell << " tmcs: " << smtype
<< " " << smodule << " " << module << " " << cell << " x=" << Form("%6.2f", x)
<< " y=" << Form("%6.2f", y) << " z=" << Form("%6.2f", z) << " dx=" << dx << " dy=" << dy;
TGeoNode* fNode = // prepare local->global trafo
gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
if (NULL == fNode) { // Transformation matrix not available !!!??? - Check
LOG(error) << Form("Node at (%6.1f,%6.1f,%6.1f) : %p", fChannelInfo->GetX(), fChannelInfo->GetY(),
fChannelInfo->GetZ(), fNode);
ChangeState(fair::mq::Transition::Stop);
}
if (icell == 0) {
TGeoHMatrix* cMatrix = gGeoManager->GetCurrentMatrix();
//cNode->Print();
cMatrix->Print();
}
}
Int_t iNbDet = fDigiBdfPar->GetNbDet();
fvDeadStrips.resize(iNbDet);
fvPulserOffset.resize(iNbDet);
fvPulserTimes.resize(iNbDet);
for (Int_t iDetIndx = 0; iDetIndx < iNbDet; iDetIndx++) {
Int_t iUniqueId = fDigiBdfPar->GetDetUId(iDetIndx);
Int_t iSmType = CbmTofAddress::GetSmType(iUniqueId);
Int_t iSmId = CbmTofAddress::GetSmId(iUniqueId);
Int_t iRpcId = CbmTofAddress::GetRpcId(iUniqueId);
LOG(info) << " DetIndx " << iDetIndx << "(" << iNbDet << "), SmType " << iSmType << ", SmId " << iSmId << ", RpcId "
<< iRpcId << " => UniqueId " << Form("0x%08x ", iUniqueId)
<< Form(" Svel %6.6f, DeadStrips 0x%08x ", fDigiBdfPar->GetSigVel(iSmType, iSmId, iRpcId),
fvDeadStrips[iDetIndx]);
Int_t iCell = -1;
while (kTRUE) {
Int_t iUCellId = CbmTofAddress::GetUniqueAddress(iSmId, iRpcId, ++iCell, 0, iSmType);
fChannelInfo = fDigiPar->GetCell(iUCellId);
if (NULL == fChannelInfo) break;
}
fvPulserOffset[iDetIndx].resize(2); // provide vector for both sides
for (Int_t i = 0; i < 2; i++)
fvPulserOffset[iDetIndx][i] = 0.; // initialize
fvPulserTimes[iDetIndx].resize(2); // provide vector for both sides
}
// return kTRUE;
Int_t iNbSmTypes = fDigiBdfPar->GetNbSmTypes();
if (kTRUE == fDigiBdfPar->UseExpandedDigi()) {
fStorDigi.resize(iNbSmTypes);
fStorDigiInd.resize(iNbSmTypes);
fviClusterSize.resize(iNbSmTypes);
fviTrkMul.resize(iNbSmTypes);
fvdX.resize(iNbSmTypes);
fvdY.resize(iNbSmTypes);
fvdDifX.resize(iNbSmTypes);
fvdDifY.resize(iNbSmTypes);
fvdDifCh.resize(iNbSmTypes);
fviClusterMul.resize(iNbSmTypes);
fvLastHits.resize(iNbSmTypes);
for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
fStorDigi[iSmType].resize(iNbSm * iNbRpc);
fStorDigiInd[iSmType].resize(iNbSm * iNbRpc);
fviClusterSize[iSmType].resize(iNbRpc);
fviTrkMul[iSmType].resize(iNbRpc);
fvdX[iSmType].resize(iNbRpc);
fvdY[iSmType].resize(iNbRpc);
fvdDifX[iSmType].resize(iNbRpc);
fvdDifY[iSmType].resize(iNbRpc);
fvdDifCh[iSmType].resize(iNbRpc);
for (Int_t iSm = 0; iSm < iNbSm; iSm++) {
fviClusterMul[iSmType].resize(iNbSm);
fvLastHits[iSmType].resize(iNbSm);
for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
fviClusterMul[iSmType][iSm].resize(iNbRpc);
fvLastHits[iSmType][iSm].resize(iNbRpc);
Int_t iNbChan = fDigiBdfPar->GetNbChan(iSmType, iRpc);
if (iNbChan == 0) {
LOG(warn) << "LoadGeometry: StoreDigi without channels "
<< Form("SmTy %3d, Sm %3d, NbRpc %3d, Rpc, %3d ", iSmType, iSm, iNbRpc, iRpc);
}
fStorDigi[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
fvLastHits[iSmType][iSm][iRpc].resize(iNbChan);
} // for( Int_t iRpc = 0; iRpc < iNbRpc; iRpc++ )
} // for( Int_t iSm = 0; iSm < iNbSm; iSm++ )
} // for( Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++ )
} // if( kTRUE == fDigiBdfPar->UseExpandedDigi() )
else {
fStorDigi.resize(iNbSmTypes);
fStorDigiInd.resize(iNbSmTypes);
fviClusterSize.resize(iNbSmTypes);
fviTrkMul.resize(iNbSmTypes);
fvdX.resize(iNbSmTypes);
fvdY.resize(iNbSmTypes);
fvdDifX.resize(iNbSmTypes);
fvdDifY.resize(iNbSmTypes);
fvdDifCh.resize(iNbSmTypes);
for (Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++) {
Int_t iNbSm = fDigiBdfPar->GetNbSm(iSmType);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
fStorDigi[iSmType].resize(iNbSm * iNbRpc);
fStorDigiInd[iSmType].resize(iNbSm * iNbRpc);
fviClusterSize[iSmType].resize(iNbRpc);
fviTrkMul[iSmType].resize(iNbRpc);
fvdX[iSmType].resize(iNbRpc);
fvdY[iSmType].resize(iNbRpc);
fvdDifX[iSmType].resize(iNbRpc);
fvdDifY[iSmType].resize(iNbRpc);
fvdDifCh[iSmType].resize(iNbRpc);
for (Int_t iSm = 0; iSm < iNbSm; iSm++) {
for (Int_t iRpc = 0; iRpc < iNbRpc; iRpc++) {
Int_t iNbChan = fDigiBdfPar->GetNbChan(iSmType, iRpc);
fStorDigi[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
fStorDigiInd[iSmType][iSm * iNbRpc + iRpc].resize(iNbChan);
} // for( Int_t iRpc = 0; iRpc < iNbRpc; iRpc++ )
} // for( Int_t iSm = 0; iSm < iNbSm; iSm++ )
} // for( Int_t iSmType = 0; iSmType < iNbSmTypes; iSmType++ )
} // else of if( kTRUE == fDigiBdfPar->UseExpandedDigi() )
return kTRUE;
}
Bool_t CbmDeviceHitBuilderTof::FillDigiStor()
{
// Loop over the digis array and store the Digis in separate vectors for
// each RPC modules
CbmTofDigi* pDigi;
Int_t iNbTofDigi = (Int_t) fTofCalDigiVec->size();
//fTofCalDigisColl->GetEntriesFast();
for (Int_t iDigInd = 0; iDigInd < iNbTofDigi; iDigInd++) {
//pDigi = (CbmTofDigi*) fTofCalDigisColl->At(iDigInd);
pDigi = &(fTofCalDigiVec->at(iDigInd));
/*
LOG(info)<<"AC " // After Calibration
<<Form("0x%08x",pDigi->GetAddress())<<" TSRC "
<<pDigi->GetType()
<<pDigi->GetSm()
<<pDigi->GetRpc()
<<Form("%2d",(Int_t)pDigi->GetChannel())<<" "
<<pDigi->GetSide()<<" "
<<Form("%f",pDigi->GetTime())<<" "
<<pDigi->GetTot();
*/
if (fDigiBdfPar->GetNbSmTypes() > pDigi->GetType() // prevent crash due to misconfiguration
&& fDigiBdfPar->GetNbSm(pDigi->GetType()) > pDigi->GetSm()
&& fDigiBdfPar->GetNbRpc(pDigi->GetType()) > pDigi->GetRpc()
&& fDigiBdfPar->GetNbChan(pDigi->GetType(), pDigi->GetRpc()) > pDigi->GetChannel()) {
fStorDigi[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
[pDigi->GetChannel()]
.push_back(pDigi);
fStorDigiInd[pDigi->GetType()][pDigi->GetSm() * fDigiBdfPar->GetNbRpc(pDigi->GetType()) + pDigi->GetRpc()]
[pDigi->GetChannel()]
.push_back(iDigInd);
}
else {
LOG(info) << "Skip2 Digi "
<< " Type " << pDigi->GetType() << " " << fDigiBdfPar->GetNbSmTypes() << " Sm " << pDigi->GetSm() << " "
<< fDigiBdfPar->GetNbSm(pDigi->GetType()) << " Rpc " << pDigi->GetRpc() << " "
<< fDigiBdfPar->GetNbRpc(pDigi->GetType()) << " Ch " << pDigi->GetChannel() << " "
<< fDigiBdfPar->GetNbChan(pDigi->GetType(), 0);
}
} // for( Int_t iDigInd = 0; iDigInd < nTofDigi; iDigInd++ )
return kTRUE;
}
Bool_t CbmDeviceHitBuilderTof::SendHits()
{
//Output Log
for (Int_t iHit = 0; iHit < fiNbHits; iHit++) {
CbmTofHit* pHit = (CbmTofHit*) fTofHitsColl->At(iHit);
LOG(debug) << Form("Found Hit %d, addr 0x%08x, X %6.2f, Y %6.2f Z %6.2f T %6.2f CLS %d", iHit, pHit->GetAddress(),
pHit->GetX(), pHit->GetY(), pHit->GetZ(), pHit->GetTime(), pHit->GetFlag());
}
// prepare output hit vector
std::vector<CbmTofHit*> vhit;
vhit.resize(fiNbHits);
for (Int_t iHit = 0; iHit < fiNbHits; iHit++) {
CbmTofHit* pHit = (CbmTofHit*) fTofHitsColl->At(iHit);
vhit[iHit] = pHit;
}
// prepare output string streams
std::stringstream ossE;
boost::archive::binary_oarchive oaE(ossE);
oaE << fEventHeader;
std::string* strMsgE = new std::string(ossE.str());
std::stringstream oss;
boost::archive::binary_oarchive oa(oss);
oa << vhit;
std::string* strMsg = new std::string(oss.str());
FairMQParts parts;
parts.AddPart(NewMessage(
const_cast<char*>(strMsgE->c_str()), // data
strMsgE->length(), // size
[](void*, void* object) { delete static_cast<std::string*>(object); },
strMsgE)); // object that manages the data
parts.AddPart(NewMessage(
const_cast<char*>(strMsg->c_str()), // data
strMsg->length(), // size
[](void*, void* object) { delete static_cast<std::string*>(object); },
strMsg)); // object that manages the data
if (Send(parts, "tofhits")) {
LOG(error) << "Problem sending data ";
return false;
}
return kTRUE;
}
Bool_t CbmDeviceHitBuilderTof::SendAll() { return kTRUE; }
Bool_t CbmDeviceHitBuilderTof::FillHistos()
{
Int_t iNbTofHits = fTofHitsColl->GetEntriesFast();
CbmTofHit* pHit;
//gGeoManager->SetTopVolume( gGeoManager->FindVolumeFast("tof_v14a") );
gGeoManager->CdTop();
if (0 < iNbTofHits) {
Bool_t BSel[iNSel];
Double_t dTTrig[iNSel];
CbmTofHit* pTrig[iNSel];
Double_t ddXdZ[iNSel];
Double_t ddYdZ[iNSel];
Double_t dSel2dXdYMin[iNSel];
Int_t iBeamRefMul = 0;
Int_t iBeamAddRefMul = 0;
if (0 < iNSel) { // check software triggers
LOG(debug) << "FillHistos() for " << iNSel << " triggers"
<< ", Dut " << fDutId << fDutSm << fDutRpc << Form(", 0x%08x", fDutAddr) << ", Sel " << fSelId
<< fSelSm << fSelRpc << Form(", 0x%08x", fSelAddr) << ", Sel2 " << fSel2Id << fSel2Sm << fSel2Rpc
<< Form(", 0x%08x", fSel2Addr);
/*
LOG(debug) <<"FillHistos: Muls: "
<<fviClusterMul[fDutId][fDutSm][fDutRpc]
<<", "<<fviClusterMul[fSelId][fSelSm][fSelRpc]
;
*/
// monitor multiplicities
Int_t iNbDet = fDigiBdfPar->GetNbDet();
for (Int_t iDetIndx = 0; iDetIndx < iNbDet; iDetIndx++) {
Int_t iDetId = fviDetId[iDetIndx];
Int_t iSmType = CbmTofAddress::GetSmType(iDetId);
Int_t iSm = CbmTofAddress::GetSmId(iDetId);
Int_t iRpc = CbmTofAddress::GetRpcId(iDetId);
//LOG(info) << Form(" indx %d, Id 0x%08x, TSR %d %d %d", iDetIndx, iDetId, iSmType, iSm, iRpc)
// ;
if (NULL != fhRpcCluMul[iDetIndx]) fhRpcCluMul[iDetIndx]->Fill(fviClusterMul[iSmType][iSm][iRpc]); //
}
// do input distributions first
for (Int_t iHitInd = 0; iHitInd < iNbTofHits; iHitInd++) {
pHit = (CbmTofHit*) fTofHitsColl->At(iHitInd);
if (NULL == pHit) continue;
if (StartAnalysisTime == 0.) {
StartAnalysisTime = pHit->GetTime();
LOG(info) << "StartAnalysisTime set to " << StartAnalysisTime << " ns. ";
}
Int_t iDetId = (pHit->GetAddress() & DetMask);
std::map<UInt_t, UInt_t>::iterator it = fDetIdIndexMap.find(iDetId);
if (it == fDetIdIndexMap.end()) continue; // continue for invalid detector index
Int_t iDetIndx = it->second; //fDetIdIndexMap[iDetId];
Int_t iSmType = CbmTofAddress::GetSmType(iDetId);
Int_t iSm = CbmTofAddress::GetSmId(iDetId);
Int_t iRpc = CbmTofAddress::GetRpcId(iDetId);
Int_t iCh = CbmTofAddress::GetChannelId(pHit->GetAddress());
Double_t dTimeAna = (pHit->GetTime() - StartAnalysisTime) / 1.E9;
//LOG(debug)<<"TimeAna "<<StartAnalysisTime<<", "<< pHit->GetTime()<<", "<<dTimeAna;
fhRpcCluRate[iDetIndx]->Fill(dTimeAna);
if (fdMemoryTime > 0. && fvLastHits[iSmType][iSm][iRpc][iCh].size() == 0)
LOG(error) << Form(" <E> hit not stored in memory for TSRC %d%d%d%d", iSmType, iSm, iRpc, iCh);
//CheckLHMemory();
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 1) { // check for outdated hits
//std::list<CbmTofHit *>::iterator it0=fvLastHits[iSmType][iSm][iRpc][iCh].begin();
//std::list<CbmTofHit *>::iterator itL=fvLastHits[iSmType][iSm][iRpc][iCh].end();
//CbmTofHit* pH0 = *it0;
//CbmTofHit* pHL = *(--itL);
CbmTofHit* pH0 = fvLastHits[iSmType][iSm][iRpc][iCh].front();
CbmTofHit* pHL = fvLastHits[iSmType][iSm][iRpc][iCh].back();
if (pH0->GetTime() > pHL->GetTime())
LOG(warn) << Form("Invalid time ordering in ev %8.0f in list of "
"size %lu for TSRC %d%d%d%d: Delta t %f ",
fdEvent, fvLastHits[iSmType][iSm][iRpc][iCh].size(), iSmType, iSm, iRpc, iCh,
pHL->GetTime() - pH0->GetTime());
//while( (*((std::list<CbmTofHit *>::iterator) fvLastHits[iSmType][iSm][iRpc][iCh].begin()))->GetTime()+fdMemoryTime < pHit->GetTime()
while (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 2.
|| fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetTime() + fdMemoryTime < pHit->GetTime()) {
LOG(debug) << " pop from list size " << fvLastHits[iSmType][iSm][iRpc][iCh].size()
<< Form(" outdated hits for ev %8.0f in TSRC %d%d%d%d", fdEvent, iSmType, iSm, iRpc, iCh)
<< Form(" with tHit - tLast %f ",
pHit->GetTime() - fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetTime())
//(*((std::list<CbmTofHit *>::iterator) fvLastHits[iSmType][iSm][iRpc][iCh].begin()))->GetTime())
;
if (fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetAddress() != pHit->GetAddress())
LOG(error) << Form("Inconsistent address in list of size %lu for TSRC %d%d%d%d: "
"0x%08x, time %f",
fvLastHits[iSmType][iSm][iRpc][iCh].size(), iSmType, iSm, iRpc, iCh,
fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetAddress(),
fvLastHits[iSmType][iSm][iRpc][iCh].front()->GetTime());
fvLastHits[iSmType][iSm][iRpc][iCh].front()->Delete();
fvLastHits[iSmType][iSm][iRpc][iCh].pop_front();
}
} //fvLastHits[iSmType][iSm][iRpc][iCh].size()>1)
// plot remaining time difference to previous hits
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 1) { // check for previous hits in memory time interval
CbmMatch* digiMatch = (CbmMatch*) fTofDigiMatchColl->At(iHitInd);
Double_t dTotSum = 0.;
for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink += 2) { // loop over digis
CbmLink L0 = digiMatch->GetLink(iLink);
Int_t iDigInd0 = L0.GetIndex();
Int_t iDigInd1 = (digiMatch->GetLink(iLink + 1)).GetIndex();
CbmTofDigi* pDig0 = (CbmTofDigi*) (&(fTofCalDigiVec->at(iDigInd0)));
CbmTofDigi* pDig1 = (CbmTofDigi*) (&(fTofCalDigiVec->at(iDigInd1)));
dTotSum += pDig0->GetTot() + pDig1->GetTot();
}
std::list<CbmTofHit*>::iterator itL = fvLastHits[iSmType][iSm][iRpc][iCh].end();
itL--;
for (UInt_t iH = 0; iH < fvLastHits[iSmType][iSm][iRpc][iCh].size() - 1; iH++) {
itL--;
fhRpcDTLastHits[iDetIndx]->Fill(TMath::Log10(pHit->GetTime() - (*itL)->GetTime()));
fhRpcDTLastHits_CluSize[iDetIndx]->Fill(TMath::Log10(pHit->GetTime() - (*itL)->GetTime()),
digiMatch->GetNofLinks() / 2.);
fhRpcDTLastHits_Tot[iDetIndx]->Fill(TMath::Log10(pHit->GetTime() - (*itL)->GetTime()), dTotSum);
}
}
} // iHitInd loop end
// do reference first
dTRef = dDoubleMax;
fTRefHits = 0;
for (Int_t iHitInd = 0; iHitInd < iNbTofHits; iHitInd++) {
pHit = (CbmTofHit*) fTofHitsColl->At(iHitInd);
if (NULL == pHit) continue;
Int_t iDetId = (pHit->GetAddress() & DetMask);
if (fiBeamRefAddr == iDetId) {
if (fviClusterMul[fiBeamRefType][fiBeamRefSm][fiBeamRefDet] > fiBeamRefMulMax) break;
// Check Tot
CbmMatch* digiMatch = (CbmMatch*) fTofDigiMatchColl->At(iHitInd);
Double_t TotSum = 0.;
for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink += 2) { // loop over digis
CbmLink L0 = digiMatch->GetLink(iLink); //vDigish.at(ivDigInd);
Int_t iDigInd0 = L0.GetIndex();
if (iDigInd0 < (Int_t) fTofCalDigiVec->size()) {
CbmTofDigi* pDig0 = &(fTofCalDigiVec->at(iDigInd0));
TotSum += pDig0->GetTot();
}
}
TotSum /= (0.5 * digiMatch->GetNofLinks());
if (TotSum > fhRpcCluTot[iIndexDut]->GetYaxis()->GetXmax()) continue; // ignore too large clusters
fTRefHits = 1;
if (pHit->GetTime() < dTRef) { dTRef = pHit->GetTime(); }
iBeamRefMul++;
}
else { //additional reference type multiplicity
if (fiBeamRefType == CbmTofAddress::GetSmType(iDetId)) iBeamAddRefMul++;
}
}
LOG(debug) << "FillHistos: BRefMul: " << iBeamRefMul << ", " << iBeamAddRefMul;
if (iBeamRefMul == 0) return kFALSE; // don't fill histos without reference time
if (iBeamAddRefMul < fiBeamAddRefMul) return kFALSE; // ask for confirmation by other beam counters
for (Int_t iSel = 0; iSel < iNSel; iSel++) {
BSel[iSel] = kFALSE;
pTrig[iSel] = NULL;
Int_t iDutMul = 0;
Int_t iRefMul = 0;
Int_t iR0 = 0;
Int_t iRl = 0;
ddXdZ[iSel] = 0.;
ddYdZ[iSel] = 0.;
dSel2dXdYMin[iSel] = 1.E300;
switch (iSel) {
case 0: // Detector under Test (Dut) && Diamonds,BeamRef
iRl = fviClusterMul[fDutId][fDutSm].size();
if (fDutRpc > -1) {
iR0 = fDutRpc;
iRl = fDutRpc + 1;
}
for (Int_t iRpc = iR0; iRpc < iRl; iRpc++)
iDutMul += fviClusterMul[fDutId][fDutSm][iRpc];
LOG(debug) << "Selector 0: DutMul " << fviClusterMul[fDutId][fDutSm][fDutRpc] << ", " << iDutMul
<< ", BRefMul " << iBeamRefMul << " TRef: " << dTRef << ", BeamAddRefMul " << iBeamAddRefMul
<< ", " << fiBeamAddRefMul;
if (iDutMul > 0 && iDutMul < fiCluMulMax) {
dTTrig[iSel] = dDoubleMax;
// LOG(debug1)<<"Found selector 0, NbHits "<<iNbTofHits;
for (Int_t iHitInd = 0; iHitInd < iNbTofHits; iHitInd++) {
pHit = (CbmTofHit*) fTofHitsColl->At(iHitInd);
if (NULL == pHit) continue;
Int_t iDetId = (pHit->GetAddress() & DetMask);
// LOG(debug1)<<Form(" Det 0x%08x, Dut 0x%08x, T %f, TTrig %f",
// iDetId, fDutAddr, pHit->GetTime(), dTTrig[iSel])
// ;
//if( fDutId == CbmTofAddress::GetSmType( iDetId ))
if (fDutAddr == iDetId) {
if (pHit->GetTime() < dTTrig[iSel]) {
dTTrig[iSel] = pHit->GetTime();
pTrig[iSel] = pHit;
BSel[iSel] = kTRUE;
}
}
}
LOG(debug) << Form("Found selector 0 with mul %d from 0x%08x at %f ", iDutMul, pTrig[iSel]->GetAddress(),
dTTrig[iSel]);
}
break;
case 1: // MRef & BRef
iRl = fviClusterMul[fSelId][fSelSm].size();
if (fSelRpc > -1) {
iR0 = fSelRpc;
iRl = fSelRpc + 1;
}
for (Int_t iRpc = iR0; iRpc < iRl; iRpc++)
iRefMul += fviClusterMul[fSelId][fSelSm][iRpc];
LOG(debug) << "FillHistos(): selector 1: RefMul " << fviClusterMul[fSelId][fSelSm][fSelRpc] << ", "
<< iRefMul << ", BRefMul " << iBeamRefMul;
if (iRefMul > 0 && iRefMul < fiCluMulMax) {
// LOG(debug1)<<"FillHistos(): Found selector 1";
dTTrig[iSel] = dDoubleMax;
for (Int_t iHitInd = 0; iHitInd < iNbTofHits; iHitInd++) {
pHit = (CbmTofHit*) fTofHitsColl->At(iHitInd);
if (NULL == pHit) continue;
Int_t iDetId = (pHit->GetAddress() & DetMask);
if (fSelAddr == iDetId) {
if (pHit->GetTime() < dTTrig[iSel]) {
dTTrig[iSel] = pHit->GetTime();
pTrig[iSel] = pHit;
BSel[iSel] = kTRUE;
}
}
}
LOG(debug) << Form("Found selector 1 with mul %d from 0x%08x at %f ", iRefMul, pTrig[iSel]->GetAddress(),
dTTrig[iSel]);
}
break;
default: LOG(info) << "FillHistos: selection not implemented " << iSel; ;
} // switch end
if (fTRefMode > 10) { dTTrig[iSel] = dTRef; }
} // iSel - loop end
if (fSel2Id > 0) { // confirm selector by independent match
for (Int_t iSel = 0; iSel < iNSel; iSel++) {
if (BSel[iSel]) {
BSel[iSel] = kFALSE;
if (fviClusterMul[fSel2Id][fSel2Sm][fSel2Rpc] > 0
&& fviClusterMul[fSel2Id][fSel2Sm][fSel2Rpc] < fiCluMulMax)
for (Int_t iHitInd = 0; iHitInd < iNbTofHits; iHitInd++) {
pHit = (CbmTofHit*) fTofHitsColl->At(iHitInd);
if (NULL == pHit) continue;
Int_t iDetId = (pHit->GetAddress() & DetMask);
if (fSel2Addr == iDetId) {
Double_t dzscal = 1.;
if (fEnableMatchPosScaling) dzscal = pHit->GetZ() / pTrig[iSel]->GetZ();
Double_t dSEl2dXdz = (pHit->GetX() - pTrig[iSel]->GetX()) / (pHit->GetZ() - pTrig[iSel]->GetZ());
Double_t dSEl2dYdz = (pHit->GetY() - pTrig[iSel]->GetY()) / (pHit->GetZ() - pTrig[iSel]->GetZ());
if (TMath::Sqrt(TMath::Power(pHit->GetX() - dzscal * pTrig[iSel]->GetX(), 2.)
+ TMath::Power(pHit->GetY() - dzscal * pTrig[iSel]->GetY(), 2.))
< fdCaldXdYMax) {
BSel[iSel] = kTRUE;
Double_t dX2Y2 = TMath::Sqrt(dSEl2dXdz * dSEl2dXdz + dSEl2dYdz * dSEl2dYdz);
if (dX2Y2 < dSel2dXdYMin[iSel]) {
ddXdZ[iSel] = dSEl2dXdz;
ddYdZ[iSel] = dSEl2dYdz;
dSel2dXdYMin[iSel] = dX2Y2;
}
break;
}
}
}
} // BSel condition end
} // iSel lopp end
} // Sel2Id condition end
UInt_t uTriggerPattern = 1;
for (Int_t iSel = 0; iSel < iNSel; iSel++)
if (BSel[iSel]) {
uTriggerPattern |= (0x1 << (iSel * 3 + CbmTofAddress::GetRpcId(pTrig[iSel]->GetAddress() & DetMask)));
}
for (Int_t iSel = 0; iSel < iNSel; iSel++) {
if (BSel[iSel]) {
if (dTRef != 0. && fTRefHits > 0) {
for (UInt_t uChannel = 0; uChannel < 16; uChannel++) {
if (uTriggerPattern & (0x1 << uChannel)) { fhSeldT[iSel]->Fill(dTTrig[iSel] - dTRef, uChannel); }
}
}
}
}
} // 0<iNSel software triffer check end
for (Int_t iHitInd = 0; iHitInd < iNbTofHits; iHitInd++) {
pHit = (CbmTofHit*) fTofHitsColl->At(iHitInd);
if (NULL == pHit) continue;
Int_t iDetId = (pHit->GetAddress() & DetMask);
std::map<UInt_t, UInt_t>::iterator it = fDetIdIndexMap.find(iDetId);
if (it == fDetIdIndexMap.end()) continue; // continue for invalid detector index
Int_t iDetIndx = it->second; //fDetIdIndexMap[iDetId];
Int_t iSmType = CbmTofAddress::GetSmType(iDetId);
Int_t iSm = CbmTofAddress::GetSmId(iDetId);
Int_t iRpc = CbmTofAddress::GetRpcId(iDetId);
Int_t iNbRpc = fDigiBdfPar->GetNbRpc(iSmType);
if (-1 < fviClusterMul[iSmType][iSm][iRpc]) {
for (Int_t iSel = 0; iSel < iNSel; iSel++)
if (BSel[iSel]) {
Double_t w = fviClusterMul[iSmType][iSm][iRpc];
if (w == 0.) w = 1.;
else
w = 1. / w;
fhTRpcCluMul[iDetIndx][iSel]->Fill(fviClusterMul[iSmType][iSm][iRpc], w);
}
}
if (fviClusterMul[iSmType][iSm][iRpc] > fiCluMulMax) continue; // skip this event
if (iBeamRefMul == 0) break;
Int_t iChId = pHit->GetAddress();
fChannelInfo = fDigiPar->GetCell(iChId);
Int_t iCh = CbmTofAddress::GetChannelId(iChId);
if (NULL == fChannelInfo) {
LOG(error) << "Invalid Channel Pointer for ChId " << Form(" 0x%08x ", iChId) << ", Ch " << iCh;
continue;
}
/*TGeoNode *fNode=*/ // prepare global->local trafo
gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
/*
LOG(debug1)<<"Hit info: "
<<Form(" 0x%08x %d %f %f %f %f %f %d",iChId,iCh,
pHit->GetX(),pHit->GetY(),pHit->GetTime(),fChannelInfo->GetX(),fChannelInfo->GetY(), iHitInd )
;
*/
Double_t hitpos[3];
hitpos[0] = pHit->GetX();
hitpos[1] = pHit->GetY();
hitpos[2] = pHit->GetZ();
Double_t hitpos_local[3];
//TGeoNode* cNode=
gGeoManager->GetCurrentNode();
gGeoManager->MasterToLocal(hitpos, hitpos_local);
/*
LOG(debug1)<< Form(" MasterToLocal for %d, %d%d%d, node %p: (%6.1f,%6.1f,%6.1f) ->(%6.1f,%6.1f,%6.1f)",
iDetIndx, iSmType, iSm, iRpc,
cNode, hitpos[0], hitpos[1], hitpos[2],
hitpos_local[0], hitpos_local[1], hitpos_local[2])
;
*/
fhRpcCluPosition[iDetIndx]->Fill((Double_t) iCh, hitpos_local[1]); //pHit->GetY()-fChannelInfo->GetY());
fhSmCluPosition[iSmType]->Fill((Double_t)(iSm * iNbRpc + iRpc), hitpos_local[1]);
for (Int_t iSel = 0; iSel < iNSel; iSel++)
if (BSel[iSel]) {
fhTRpcCluPosition[iDetIndx][iSel]->Fill((Double_t) iCh,
hitpos_local[1]); //pHit->GetY()-fChannelInfo->GetY());
fhTSmCluPosition[iSmType][iSel]->Fill((Double_t)(iSm * iNbRpc + iRpc), hitpos_local[1]);
}
if (TMath::Abs(hitpos_local[1]) > fChannelInfo->GetSizey() * fPosYMaxScal) continue;
/*
LOG(debug1)<<" TofDigiMatchColl entries:"
<<fTofDigiMatchColl->GetEntriesFast()
;
*/
if (iHitInd > fTofDigiMatchColl->GetEntriesFast()) {
LOG(error) << " Inconsistent DigiMatches for Hitind " << iHitInd
<< ", TClonesArraySize: " << fTofDigiMatchColl->GetEntriesFast();
}
CbmMatch* digiMatch = (CbmMatch*) fTofDigiMatchColl->At(iHitInd);
/*
LOG(debug1)<<" got "
<<digiMatch->GetNofLinks()<< " matches for iCh "<<iCh<<" at iHitInd "<<iHitInd
;
*/
fhRpcCluSize[iDetIndx]->Fill((Double_t) iCh, digiMatch->GetNofLinks() / 2.);
for (Int_t iSel = 0; iSel < iNSel; iSel++)
if (BSel[iSel]) {
fhTRpcCluSize[iDetIndx][iSel]->Fill((Double_t) iCh, digiMatch->GetNofLinks() / 2.);
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 1) { // check for previous hits in memory time interval
std::list<CbmTofHit*>::iterator itL = fvLastHits[iSmType][iSm][iRpc][iCh].end();
itL--;
for (UInt_t iH = 0; iH < fvLastHits[iSmType][iSm][iRpc][iCh].size() - 1; iH++) {
itL--;
fhTRpcCluSizeDTLastHits[iDetIndx][iSel]->Fill(TMath::Log10(pHit->GetTime() - (*itL)->GetTime()),
digiMatch->GetNofLinks() / 2.);
}
}
}
Double_t TotSum = 0.;
for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) { // loop over digis
CbmLink L0 = digiMatch->GetLink(iLink); //vDigish.at(ivDigInd);
Int_t iDigInd0 = L0.GetIndex();
if (iDigInd0 < (Int_t) fTofCalDigiVec->size()) {
CbmTofDigi* pDig0 = &(fTofCalDigiVec->at(iDigInd0));
TotSum += pDig0->GetTot();
}
}
Double_t dMeanTimeSquared = 0.;
Double_t dNstrips = 0.;
Double_t dDelTof = 0.;
Double_t dTcor[iNSel];
Double_t dTTcor[iNSel];
Double_t dZsign[iNSel];
Double_t dzscal = 1.;
//Double_t dDist=0.;
for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink += 2) { // loop over digis
CbmLink L0 = digiMatch->GetLink(iLink); //vDigish.at(ivDigInd);
Int_t iDigInd0 = L0.GetIndex();
Int_t iDigInd1 = (digiMatch->GetLink(iLink + 1)).GetIndex(); //vDigish.at(ivDigInd+1);
//LOG(debug1)<<" " << iDigInd0<<", "<<iDigInd1;
if (iDigInd0 < (Int_t) fTofCalDigiVec->size() && iDigInd1 < (Int_t) fTofCalDigiVec->size()) {
CbmTofDigi* pDig0 = &(fTofCalDigiVec->at(iDigInd0));
CbmTofDigi* pDig1 = &(fTofCalDigiVec->at(iDigInd1));
if ((Int_t) pDig0->GetType() != iSmType) {
LOG(error) << Form(" Wrong Digi SmType for Tofhit %d in iDetIndx "
"%d, Ch %d with %3.0f strips at Indx %d, %d",
iHitInd, iDetIndx, iCh, dNstrips, iDigInd0, iDigInd1);
}
/*
LOG(debug1)<<" fhRpcCluTot: Digi 0 "<<iDigInd0<<": Ch "<<pDig0->GetChannel()<<", Side "<<pDig0->GetSide()
<<", StripSide "<<(Double_t)iCh*2.+pDig0->GetSide()
<<" Digi 1 "<<iDigInd1<<": Ch "<<pDig1->GetChannel()<<", Side "<<pDig1->GetSide()
<<" , StripSide "<<(Double_t)iCh*2.+pDig1->GetSide()
<<", Tot0 " << pDig0->GetTot() <<", Tot1 "<<pDig1->GetTot();
*/
fhRpcCluTot[iDetIndx]->Fill(pDig0->GetChannel() * 2. + pDig0->GetSide(), pDig0->GetTot());
fhRpcCluTot[iDetIndx]->Fill(pDig1->GetChannel() * 2. + pDig1->GetSide(), pDig1->GetTot());
Int_t iCh0 = pDig0->GetChannel();
Int_t iCh1 = pDig1->GetChannel();
Int_t iS0 = pDig0->GetSide();
Int_t iS1 = pDig1->GetSide();
if (iCh0 != iCh1 || iS0 == iS1) {
LOG(error) << Form(" MT2 for Tofhit %d in iDetIndx %d, Ch %d from %3.0f strips: ", iHitInd, iDetIndx, iCh,
dNstrips)
<< Form(" Dig0: Ind %d, Ch %d, Side %d, T: %6.1f ", iDigInd0, iCh0, iS0, pDig0->GetTime())
<< Form(" Dig1: Ind %d, Ch %d, Side %d, T: %6.1f ", iDigInd1, iCh1, iS1, pDig1->GetTime());
continue;
}
if (0 > iCh0 || fDigiBdfPar->GetNbChan(iSmType, iRpc) <= iCh0) {
LOG(error) << Form(" Wrong Digi for Tofhit %d in iDetIndx %d, Ch %d at Indx %d, %d "
"from %3.0f strips: %d, %d, %d, %d",
iHitInd, iDetIndx, iCh, iDigInd0, iDigInd1, dNstrips, iCh0, iCh1, iS0, iS1);
continue;
}
if (digiMatch->GetNofLinks() > 2) //&& digiMatch->GetNofLinks()<8 ) // FIXME: hardcoded limits on CluSize
{
dNstrips += 1.;
dMeanTimeSquared += TMath::Power(0.5 * (pDig0->GetTime() + pDig1->GetTime()) - pHit->GetTime(), 2);
// fhRpcCluAvWalk[iDetIndx]->Fill(0.5*(pDig0->GetTot()+pDig1->GetTot()),
// 0.5*(pDig0->GetTime()+pDig1->GetTime())-pHit->GetTime());
fhRpcCluAvLnWalk[iDetIndx]->Fill(TMath::Log10(0.5 * (pDig0->GetTot() + pDig1->GetTot())),
0.5 * (pDig0->GetTime() + pDig1->GetTime()) - pHit->GetTime());
Double_t dTotWeigth = (pDig0->GetTot() + pDig1->GetTot()) / TotSum;
Double_t dCorWeigth = 1. - dTotWeigth;
fhRpcCluDelTOff[iDetIndx]->Fill(
pDig0->GetChannel(), dCorWeigth * (0.5 * (pDig0->GetTime() + pDig1->GetTime()) - pHit->GetTime()));
Double_t dDelPos = 0.5 * (pDig0->GetTime() - pDig1->GetTime()) * fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc);
if (0 == pDig0->GetSide()) dDelPos *= -1.;
fhRpcCluDelPos[iDetIndx]->Fill(pDig0->GetChannel(), dCorWeigth * (dDelPos - hitpos_local[1]));
fhRpcCluWalk[iDetIndx][iCh0][iS0]->Fill(
pDig0->GetTot(),
pDig0->GetTime()
- (pHit->GetTime()
- (1. - 2. * pDig0->GetSide()) * hitpos_local[1] / fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc)));
fhRpcCluWalk[iDetIndx][iCh1][iS1]->Fill(
pDig1->GetTot(),
pDig1->GetTime()
- (pHit->GetTime()
- (1. - 2. * pDig1->GetSide()) * hitpos_local[1] / fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc)));
fhRpcCluAvWalk[iDetIndx]->Fill(pDig0->GetTot(), pDig0->GetTime()
- (pHit->GetTime()
- (1. - 2. * pDig0->GetSide()) * hitpos_local[1]
/ fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc)));
fhRpcCluAvWalk[iDetIndx]->Fill(pDig1->GetTot(), pDig1->GetTime()
- (pHit->GetTime()
- (1. - 2. * pDig1->GetSide()) * hitpos_local[1]
/ fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc)));
} // end of Clustersize > 1 condition
/*
LOG(debug1)<<" fhTRpcCluTot: Digi 0 "<<iDigInd0<<": Ch "<<pDig0->GetChannel()<<", Side "<<pDig0->GetSide()
<<", StripSide "<<(Double_t)iCh*2.+pDig0->GetSide()
<<" Digi 1 "<<iDigInd1<<": Ch "<<pDig1->GetChannel()<<", Side "<<pDig1->GetSide()
<<", StripSide "<<(Double_t)iCh*2.+pDig1->GetSide()
;
*/
for (Int_t iSel = 0; iSel < iNSel; iSel++)
if (BSel[iSel]) {
if (NULL == pHit || NULL == pTrig[iSel]) {
LOG(info) << " invalid pHit, iSel " << iSel << ", iDetIndx " << iDetIndx;
break;
}
if (pHit->GetAddress() == pTrig[iSel]->GetAddress()) continue;
fhTRpcCluTot[iDetIndx][iSel]->Fill(pDig0->GetChannel() * 2. + pDig0->GetSide(), pDig0->GetTot());
fhTRpcCluTot[iDetIndx][iSel]->Fill(pDig1->GetChannel() * 2. + pDig1->GetSide(), pDig1->GetTot());
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 1) { // check for previous hits in memory time interval
std::list<CbmTofHit*>::iterator itL = fvLastHits[iSmType][iSm][iRpc][iCh].end();
itL--;
for (UInt_t iH = 0; iH < fvLastHits[iSmType][iSm][iRpc][iCh].size() - 1; iH++) {
itL--;
fhTRpcCluTotDTLastHits[iDetIndx][iSel]->Fill(TMath::Log10(pHit->GetTime() - (*itL)->GetTime()),
pDig0->GetTot());
fhTRpcCluTotDTLastHits[iDetIndx][iSel]->Fill(TMath::Log10(pHit->GetTime() - (*itL)->GetTime()),
pDig1->GetTot());
}
}
if (iLink == 0) { // Fill histo only once (for 1. digi entry)
if (fEnableMatchPosScaling) dzscal = pHit->GetZ() / pTrig[iSel]->GetZ();
fhTRpcCludXdY[iDetIndx][iSel]->Fill(pHit->GetX() - dzscal * pTrig[iSel]->GetX(),
pHit->GetY() - dzscal * pTrig[iSel]->GetY());
dZsign[iSel] = 1.;
if (pHit->GetZ() < pTrig[iSel]->GetZ()) dZsign[iSel] = -1.;
}
// look for geometrical match with selector hit
//if( iSmType==fiBeamRefType // to get entries in diamond/BeamRef histos
if (iSmType == 5 // FIXME, to get entries in diamond histos
|| TMath::Sqrt(TMath::Power(pHit->GetX() - dzscal * pTrig[iSel]->GetX(), 2.)
+ TMath::Power(pHit->GetY() - dzscal * pTrig[iSel]->GetY(), 2.))
< fdCaldXdYMax) {
if (!fEnableMatchPosScaling && dSel2dXdYMin[iSel] < 1.E300)
if (TMath::Sqrt(
TMath::Power(pHit->GetX()
- (pTrig[iSel]->GetX() + ddXdZ[iSel] * (pHit->GetZ() - (pTrig[iSel]->GetZ()))),
2.)
+ TMath::Power(pHit->GetY()
- (pTrig[iSel]->GetY() + ddYdZ[iSel] * (pHit->GetZ() - (pTrig[iSel]->GetZ()))),
2.))
> 0.5 * fdCaldXdYMax)
continue; // refine position selection cut in cosmic measurement
dTcor[iSel] = 0.; // precaution
if (dTRef != 0.
&& TMath::Abs(dTRef - dTTrig[iSel]) < fdDelTofMax) { // correct times for DelTof - velocity spread
if (iLink == 0) { // do calculations only once (at 1. digi entry) // interpolate!
// calculate spatial distance to trigger hit
/*
dDist=TMath::Sqrt(TMath::Power(pHit->GetX()-pTrig[iSel]->GetX(),2.)
+TMath::Power(pHit->GetY()-pTrig[iSel]->GetY(),2.)
+TMath::Power(pHit->GetZ()-pTrig[iSel]->GetZ(),2.));
*/
// determine correction value
//if(fiBeamRefAddr != iDetId) // do not do this for reference counter itself
if (fTRefMode < 11) // do not do this for trigger counter itself
{
Double_t dTentry = dTRef - dTTrig[iSel] + fdDelTofMax;
Int_t iBx = dTentry / 2. / fdDelTofMax * nbClDelTofBinX;
if (iBx < 0) iBx = 0;
if (iBx > nbClDelTofBinX - 1) iBx = nbClDelTofBinX - 1;
Double_t dBinWidth = 2. * fdDelTofMax / nbClDelTofBinX;
Double_t dDTentry = dTentry - ((Double_t) iBx) * dBinWidth;
Int_t iBx1 = 0;
dDTentry < 0 ? iBx1 = iBx - 1 : iBx1 = iBx + 1;
Double_t w0 = 1. - TMath::Abs(dDTentry) / dBinWidth;
Double_t w1 = 1. - w0;
if (iBx1 < 0) iBx1 = 0;
if (iBx1 > nbClDelTofBinX - 1) iBx1 = nbClDelTofBinX - 1;
dDelTof = fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx][iSel] * w0
+ fvCPDelTof[iSmType][iSm * iNbRpc + iRpc][iBx1][iSel] * w1;
//dDelTof *= dDist; // has to be consistent with fhTRpcCluDelTof filling
/*
LOG(debug1)<<Form(" DelTof for SmT %d, Sm %d, R %d, T %d, dTRef %6.1f, Bx %d, Bx1 %d, DTe %6.1f -> DelT %6.1f",
iSmType, iSm, iRpc, iSel, dTRef-dTTrig[iSel], iBx, iBx1, dDTentry, dDelTof)
;
*/
}
dTTcor[iSel] = dDelTof * dZsign[iSel];
dTcor[iSel] = pHit->GetTime() - dDelTof - dTTrig[iSel];
// Double_t dAvTot=0.5*(pDig0->GetTot()+pDig1->GetTot());
} // if(iLink==0)
LOG(debug) << Form(" TRpcCluWalk for Ev %d, Link %d(%d), Sel %d, TSR %d%d%d, "
"Ch %d,%d, S %d,%d T %f, DelTof %6.1f, W-ent: %6.0f,%6.0f",
fiNevtBuild, iLink, (Int_t) digiMatch->GetNofLinks(), iSel, iSmType, iSm, iRpc,
iCh0, iCh1, iS0, iS1, dTTrig[iSel], dDelTof,
fhTRpcCluWalk[iDetIndx][iSel][iCh0][iS0]->GetEntries(),
fhTRpcCluWalk[iDetIndx][iSel][iCh1][iS1]->GetEntries());
if (fhTRpcCluWalk[iDetIndx][iSel][iCh0][iS0]->GetEntries()
!= fhTRpcCluWalk[iDetIndx][iSel][iCh1][iS1]->GetEntries())
LOG(error) << Form(" Inconsistent walk histograms -> debugging "
"necessary ... for %d, %d, %d, %d, %d, %d, %d ",
fiNevtBuild, iDetIndx, iSel, iCh0, iCh1, iS0, iS1);
/*
LOG(debug1)<<Form(" TRpcCluWalk values side %d: %f, %f, side %d: %f, %f ",
iS0,pDig0->GetTot(),pDig0->GetTime()
+((1.-2.*pDig0->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))-dTTcor[iSel]-dTTrig[iSel],
iS1,pDig1->GetTot(),pDig1->GetTime()
+((1.-2.*pDig1->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))-dTTcor[iSel]-dTTrig[iSel])
;
*/
fhTRpcCluWalk[iDetIndx][iSel][iCh0][iS0]->Fill(
pDig0->GetTot(),
//(pDig0->GetTime()+((1.-2.*pDig0->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))-dTTrig[iSel])-dTTcor[iSel]);
//dTcor[iSel]+(1.-2.*pDig0->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc));
dTcor[iSel]);
fhTRpcCluWalk[iDetIndx][iSel][iCh1][iS1]->Fill(
pDig1->GetTot(),
//(pDig1->GetTime()+((1.-2.*pDig1->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))-dTTrig[iSel])-dTTcor[iSel]);
//dTcor[iSel]+(1.-2.*pDig1->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc));
dTcor[iSel]);
fhTRpcCluAvWalk[iDetIndx][iSel]->Fill(
pDig0->GetTot(),
//(pDig0->GetTime()+((1.-2.*pDig0->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))-dTTrig[iSel])-dTTcor[iSel]);
//dTcor[iSel]+(1.-2.*pDig0->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc));
dTcor[iSel]);
fhTRpcCluAvWalk[iDetIndx][iSel]->Fill(
pDig1->GetTot(),
//(pDig1->GetTime()+((1.-2.*pDig1->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc))-dTTrig[iSel])-dTTcor[iSel]);
//dTcor[iSel]+(1.-2.*pDig1->GetSide())*hitpos_local[1]/fDigiBdfPar->GetSigVel(iSmType,iSm,iRpc));
dTcor[iSel]);
if (iLink == 0) { // Fill histo only once (for 1. digi entry)
//fhTRpcCluDelTof[iDetIndx][iSel]->Fill(dTRef-dTTrig[iSel],dTcor[iSel]/dDist);
fhTRpcCluDelTof[iDetIndx][iSel]->Fill(dTRef - dTTrig[iSel], dTcor[iSel]);
fhTSmCluTOff[iSmType][iSel]->Fill((Double_t)(iSm * iNbRpc + iRpc), dTcor[iSel]);
fhTSmCluTRun[iSmType][iSel]->Fill(fdEvent, dTcor[iSel]);
if (iDetId
!= (pTrig[iSel]->GetAddress()
& DetMask)) { // transform matched hit-pair back into detector frame
hitpos[0] = pHit->GetX() - dzscal * pTrig[iSel]->GetX() + fChannelInfo->GetX();
hitpos[1] = pHit->GetY() - dzscal * pTrig[iSel]->GetY() + fChannelInfo->GetY();
hitpos[2] = pHit->GetZ();
gGeoManager->MasterToLocal(hitpos, hitpos_local); // transform into local frame
fhRpcCluDelMatPos[iDetIndx]->Fill((Double_t) iCh, hitpos_local[1]);
fhRpcCluDelMatTOff[iDetIndx]->Fill((Double_t) iCh,
(pHit->GetTime() - dTTrig[iSel]) - dTTcor[iSel]);
}
} // iLink==0 condition end
} // position condition end
} // Match condition end
} // closing of selector loop
}
else {
LOG(error) << "FillHistos: invalid digi index " << iDetIndx << " digi0,1" << iDigInd0 << ", " << iDigInd1
<< " - max:" << fTofCalDigiVec->size()
// << " in event " << XXX
;
}
} // iLink digi loop end;
if (1 < dNstrips) {
// Double_t dVar=dMeanTimeSquared/dNstrips - TMath::Power(pHit->GetTime(),2);
Double_t dVar = dMeanTimeSquared / (dNstrips - 1);
//if(dVar<0.) dVar=0.;
Double_t dTrms = TMath::Sqrt(dVar);
LOG(debug) << Form(" Trms for Tofhit %d in iDetIndx %d, Ch %d from "
"%3.0f strips: %6.3f ns",
iHitInd, iDetIndx, iCh, dNstrips, dTrms);
fhRpcCluTrms[iDetIndx]->Fill((Double_t) iCh, dTrms);
pHit->SetTimeError(dTrms);
}
/*
LOG(debug1)<<" Fill Time of iDetIndx "<<iDetIndx<<", hitAddr "
<<Form(" %08x, y = %5.2f",pHit->GetAddress(),hitpos_local[1])
<<" for |y| <"
<<fhRpcCluPosition[iDetIndx]->GetYaxis()->GetXmax()
;
*/
if (TMath::Abs(hitpos_local[1]) < (fhRpcCluPosition[iDetIndx]->GetYaxis()->GetXmax())) {
if (dTRef != 0. && fTRefHits == 1) {
fhRpcCluTOff[iDetIndx]->Fill((Double_t) iCh, pHit->GetTime() - dTRef);
fhSmCluTOff[iSmType]->Fill((Double_t)(iSm * iNbRpc + iRpc), pHit->GetTime() - dTRef);
for (Int_t iSel = 0; iSel < iNSel; iSel++)
if (BSel[iSel]) {
/*
LOG(debug1)<<" TRpcCluTOff "<< iDetIndx <<", Sel "<< iSel
<<Form(", Dt %7.3f, LHsize %lu ",
pHit->GetTime()-dTTrig[iSel],fvLastHits[iSmType][iSm][iRpc][iCh].size());
*/
if (pHit->GetAddress() == pTrig[iSel]->GetAddress()) continue;
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 1) { // check for previous hits in memory time interval
std::list<CbmTofHit*>::iterator itL = fvLastHits[iSmType][iSm][iRpc][iCh].end();
itL--;
for (UInt_t iH = 0; iH < fvLastHits[iSmType][iSm][iRpc][iCh].size() - 1; iH++) {
itL--;
//LOG(debug1)<<Form(" %f,",pHit->GetTime()-(*itL)->GetTime());
}
}
// fill Time Offset histograms without velocity spread (DelTof) correction
fhTRpcCluTOff[iDetIndx][iSel]->Fill((Double_t) iCh,
pHit->GetTime()
- dTTrig[iSel]); // -dTTcor[iSel] only valid for matches
if (fvLastHits[iSmType][iSm][iRpc][iCh].size() > 1) { // check for previous hits in memory time interval
std::list<CbmTofHit*>::iterator itL = fvLastHits[iSmType][iSm][iRpc][iCh].end();
itL--;
for (Int_t iH = 0; iH < 1; iH++) { // use only last hit
// for(Int_t iH=0; iH<fvLastHits[iSmType][iSm][iRpc][iCh].size()-1; iH++){//fill for all memorized hits
itL--;
Double_t dTsinceLast = pHit->GetTime() - (*itL)->GetTime();
if (dTsinceLast > fdMemoryTime)
LOG(error) << Form("Invalid Time since last hit on channel "
"TSRC %d%d%d%d: %f > %f",
iSmType, iSm, iRpc, iCh, dTsinceLast, fdMemoryTime);
fhTRpcCluTOffDTLastHits[iDetIndx][iSel]->Fill(TMath::Log10(dTsinceLast),
pHit->GetTime() - dTTrig[iSel]);
fhTRpcCluMemMulDTLastHits[iDetIndx][iSel]->Fill(TMath::Log10(dTsinceLast),
fvLastHits[iSmType][iSm][iRpc][iCh].size() - 1);
}
}
}
}
}
}
}
return kTRUE;
}
static Int_t iNPulserFound = 0;
Bool_t CbmDeviceHitBuilderTof::MonitorPulser()
{
iNPulserFound++;
const Int_t iDet0 = fiPulDetRef; // Define reference detector
const Double_t Tlim = 0.5;
Int_t iDigi0 = -1;
switch (fiPulserMode) {
case 1: // mcbm :
if ((UInt_t) fiNDigiIn != fiPulMulMin * 2 + 2) { // 2 * working RPCs + 1 Diamond
LOG(debug) << "Incomplete or distorted pulser event " << iNPulserFound << " with " << fiNDigiIn
<< " digis instead of " << fiPulMulMin * 2 + 2;
if ((UInt_t) fiNDigiIn < fiPulMulMin * 2) return kTRUE;
}
break;
case 2: // micro CBM cosmic
if ((UInt_t) fiNDigiIn < fiPulMulMin * 2) return kTRUE;
break;
;
default:;
}
for (Int_t iDigi = 0; iDigi < (Int_t) fiNDigiIn; iDigi++) {
Int_t iCh = fvDigiIn[iDigi].GetChannel();
if (iCh != 0 && iCh != 31) continue;
Int_t iAddr = fvDigiIn[iDigi].GetAddress() & DetMask;
Int_t iDet = fDetIdIndexMap[iAddr];
if (iDet == iDet0) {
Int_t iSide = fvDigiIn[iDigi].GetSide();
if (iSide == 1) { // for pulser mode 1
iDigi0 = iDigi;
break;
}
}
}
if (iDigi0 == -1) {
LOG(debug) << Form("Pulser reference %d not found in pulser event %d of mul %d, return", iDet0, iNPulserFound,
fiNDigiIn);
return kTRUE;
}
if (fvPulserTimes[iDet0][0].size() > 0)
LOG(debug) << fiNDigiIn << " pulser digis with ref in "
<< Form("0x%08x at %d with deltaT %12.3f", fvDigiIn[iDigi0].GetAddress(), iDigi0,
fvDigiIn[iDigi0].GetTime() - fvPulserTimes[iDet0][0].back());
for (Int_t iDigi = 0; iDigi < fiNDigiIn; iDigi++) {
Int_t iCh = fvDigiIn[iDigi].GetChannel();
Int_t iDetIndx = fDigiBdfPar->GetDetInd(fvDigiIn[iDigi].GetAddress() & DetMask);
fhRpcDigiTot[iDetIndx]->Fill(2 * iCh + fvDigiIn[iDigi].GetSide(), fvDigiIn[iDigi].GetTot());
Int_t iAddr = fvDigiIn[iDigi].GetAddress() & DetMask;
Int_t iDet = fDetIdIndexMap[iAddr];
Int_t iSide = fvDigiIn[iDigi].GetSide();
switch (fiPulserMode) {
case 0:
case 1: // mCBM
if (fvDigiIn[iDigi].GetType() != 5) {
if (iCh != 0 && iCh != 31) continue;
if (fvDigiIn[iDigi].GetTot() > fiPulTotMax || fvDigiIn[iDigi].GetTot() < fiPulTotMin) continue;
}
else {
LOG(debug) << "Found PulHit of Type 5 in Ch " << iCh;
// if (iCh == 5) iSide=1; // Special case for diamond, pulser for channels 5-8 in channel 5, stored as side 1
// if (iCh !=0 && iCh != 5) continue;
if (iCh > 39) iSide = 1; // Special case for diamond in Mar2019
if (iCh != 0 && iCh != 40) continue;
}
break;
case 2:
if (fvDigiIn[iDigi].GetType() == 8) // ceramic RPC
if (fvDigiIn[iDigi].GetRpc() != 7) continue;
if (iCh != 0 && iCh != 31) continue;
break;
}
if (fvPulserTimes[iDet][iSide].size() == (UInt_t) NPulserTimes) fvPulserTimes[iDet][iSide].pop_front();
if (iDet == iDet0 && 1 == iSide) {
// check consistency of latest hit
if (fvPulserTimes[iDet][iSide].size() > 1) {
Double_t TDif = (fvPulserTimes[iDet][iSide].back() - fvPulserTimes[iDet][iSide].front())
/ (fvPulserTimes[iDet][iSide].size() - 1);
if (TMath::Abs(fvDigiIn[iDigi].GetTime() - fvPulserTimes[iDet][iSide].back() - TDif)
> 1.E3) { // probably due to parallel processing
// action, reset
fvPulserTimes[iDet][iSide].clear();
}
else {
if (TMath::Abs(fvDigiIn[iDigi].GetTime() - fvPulserTimes[iDet][iSide].back() - TDif) > 10.) {
LOG(info) << Form("Unexpected Pulser Time for event %d, pulser %d: "
"%15.1f instead %15.1f, TDif: %10.1f != %10.1f",
(int) fdEvent, iNPulserFound, fvDigiIn[iDigi].GetTime(),
fvPulserTimes[iDet][iSide].back() + TDif,
fvDigiIn[iDigi].GetTime() - fvPulserTimes[iDet][iSide].back(), TDif);
// append dummy entry
fvPulserTimes[iDet][iSide].push_back((Double_t)(fvPulserTimes[iDet][iSide].back() + TDif));
continue;
}
}
}
// append new entry
fvPulserTimes[iDet][iSide].push_back((Double_t)(fvDigiIn[iDigi].GetTime()));
}
else {
Double_t dDeltaT0 = (Double_t)(fvDigiIn[iDigi].GetTime() - fvDigiIn[iDigi0].GetTime());
// check consistency of latest hit
if (fvPulserOffset[iDet][iSide] != 0.)
if (TMath::Abs(dDeltaT0 - fvPulserOffset[iDet][iSide]) > Tlim) {
LOG(info) << "Unexpected pulser offset at ev " << fdEvent << ", pulcnt " << iNPulserFound << " for Det "
<< iDet << Form(", addr 0x%08x", iAddr) << ", side " << iSide << ": "
<< dDeltaT0 - fvPulserOffset[iDet][iSide] << " ( " << fvPulserTimes[iDet][iSide].size() << " ) ";
fvPulserTimes[iDet][iSide].clear();
// skip this event
// continue;
}
// fill monitoring histo
if (fvPulserOffset[iDet][iSide] != 0.) {
fhPulserTimesRaw->Fill(iDet * 2 + iSide, dDeltaT0 - fvPulserOffset[iDet][iSide]);
fhPulserTimeRawEvo[iDet * 2 + iSide]->Fill(iNPulserFound, dDeltaT0 - fvPulserOffset[iDet][iSide]);
}
// append new entry
fvPulserTimes[iDet][iSide].push_back(dDeltaT0);
}
}
for (Int_t iDet = 0; iDet < (Int_t) fvPulserTimes.size(); iDet++) {
for (Int_t iSide = 0; iSide < 2; iSide++) {
if (iDet == iDet0 && iSide == 1) continue; // skip reference counter
if (fvPulserTimes[iDet][iSide].size() > 0) {
Double_t Tmean = 0.;
std::list<Double_t>::iterator it;
for (it = fvPulserTimes[iDet][iSide].begin(); it != fvPulserTimes[iDet][iSide].end(); ++it)
Tmean += *it;
Tmean /= fvPulserTimes[iDet][iSide].size();
if (TMath::Abs(Tmean - fvPulserOffset[iDet][iSide]) > Tlim)
LOG(debug) << "New pulser offset at ev " << fdEvent << ", pulcnt " << iNPulserFound << " for Det " << iDet
<< ", side " << iSide << ": " << Tmean << " ( " << fvPulserTimes[iDet][iSide].size() << " ) ";
fvPulserOffset[iDet][iSide] = Tmean;
}
}
}
for (Int_t iDigi = 0; iDigi < fiNDigiIn; iDigi++) {
Int_t iCh = fvDigiIn[iDigi].GetChannel();
Int_t iAddr = fvDigiIn[iDigi].GetAddress() & DetMask;
Int_t iDet = fDetIdIndexMap[iAddr];
Int_t iSide = fvDigiIn[iDigi].GetSide();
switch (fiPulserMode) {
case 1:
if (fvDigiIn[iDigi].GetType() != 5) {
if (iCh != 0 && iCh != 31) continue;
}
else {
//if (iCh == 5) iSide=1; // Special case for diamond, pulser for channels 5-8 in channel 5, stored as side 1
if (iCh > 39) iSide = 1; // Special case for diamond in Mar2019
// if(iCh !=0 && iCh != 5) continue;
if (iCh != 0 && iCh != 40) continue;
}
break;
case 2:
if (fvDigiIn[iDigi].GetType() == 8) // ceramic RPC
if (fvDigiIn[iDigi].GetRpc() != 7) continue;
if (iCh != 0 && iCh != 31) continue;
break;
}
Double_t dDeltaT0 =
(Double_t)(fvDigiIn[iDigi].GetTime() - fvDigiIn[iDigi0].GetTime()) - fvPulserOffset[iDet][iSide];
// fill monitoring histo
fhPulserTimesCor->Fill(iDet * 2 + iSide, dDeltaT0);
}
return kTRUE;
}
Bool_t CbmDeviceHitBuilderTof::ApplyPulserCorrection()
{
for (Int_t iDigi = 0; iDigi < fiNDigiIn; iDigi++) {
Int_t iAddr = fvDigiIn[iDigi].GetAddress() & DetMask;
Int_t iDet = fDetIdIndexMap[iAddr];
Int_t iSide = fvDigiIn[iDigi].GetSide();
switch (fiPulserMode) {
case 1: // diamond has pulser in ch 0 and 5
if (5 == fvDigiIn[iDigi].GetType()) {
continue; // no pulser correction for diamond, mapping to be resolved
Int_t iCh = fvDigiIn[iDigi].GetChannel();
if (iCh > 4) iSide = 1;
}
break;
case 2: // correct all cer pads by same rpc/side 0
if (8 == fvDigiIn[iDigi].GetType() || 5 == fvDigiIn[iDigi].GetType()) {
const Int_t iRefAddr = 0x00078006;
iDet = fDetIdIndexMap[iRefAddr];
}
break;
}
fvDigiIn[iDigi].SetTime(fvDigiIn[iDigi].GetTime() - fvPulserOffset[iDet][iSide]);
}
return kTRUE;
}