#include "hades.h"
#include "hcategory.h"
#include "hdebug.h"
#include "hevent.h"
#include "heventheader.h"
#include "hldsource.h"
#include "hldsubevt.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "htofdetector.h"
#include "htofraw.h"
#include "htofrawsim.h"
#include "htoftrb3lookup.h"
#include "htoftrb3unpacker.h"
#include "tofdef.h"
#include "htrbnetunpacker.h"
#include <iostream>
using namespace std;
ClassImp(HTofTrb3Unpacker)
#define TOF_TIME_MIN -300.0
#define TOF_TIME_MAX 1500.0
Bool_t HTofTrb3Unpacker::fHasPrintedTDC = kFALSE;
HTofTrb3Unpacker::HTofTrb3Unpacker(vector<UInt_t>& ids) : HTrb3TdcUnpacker(ids),
fLookup(0), fTimeRef(kTRUE), fTimeShift(0.) {
pRawCat = NULL;
}
Bool_t HTofTrb3Unpacker::init(void) {
HTofDetector* det = (HTofDetector*) gHades->getSetup()->getDetector("Tof");
if (!det) {
Error("init", "No TOF Detector found.");
return kFALSE;
}
if(gHades->getEmbeddingMode()==0) {
pRawCat=gHades->getSetup()->getDetector("Tof")->buildCategory(catTofRaw);
} else {
pRawCat=((HTofDetector*)(gHades->getSetup()->getDetector("Tof")))->buildMatrixCategory("HTofRawSim",0.5F);
}
if (!pRawCat) return kFALSE;
gHades->getCurrentEvent ()->addCategory (catTofRaw, pRawCat, "Tof");
fLoc.set(3, 0, 0, 0);
fLookup = (HTofTrb3Lookup*) (gHades->getRuntimeDb()->getContainer("TofTrb3Lookup"));
if (!fLookup) {
Error("init", "No Pointer to parameter container TofTrb3Lookup.");
return kFALSE;
}
if (NULL == trbNetUnpacker) {
if (gHades->getDataSource()) {
HDataSource* source = gHades->getDataSource();
if (source->InheritsFrom("HldSource")) {
trbNetUnpacker =
((HldSource *) gHades->getDataSource())->getTrbNetUnpacker();
} else {
Warning("init",
"DataSource not inherited from HldSource! trbNetUnpacker == 0 ");
}
} else {
Warning("init",
"Could not retrieve DataSource! trbNetUnpacker == 0 ");
}
}
if (!trbNetUnpacker->init()) {
Error("init()", "Failed to initialize HTrbNetUnpacker!");
return kFALSE;
}
return kTRUE;
}
Bool_t HTofTrb3Unpacker::reinit(void)
{
if (numTDC() == 0 )
{
if (fMinAddress == 0 && fMaxAddress == 0)
{
Int_t numTDC = fLookup->getSize();
Int_t offset = fLookup->getArrayOffset() ;
for (Int_t slot = 0; slot < numTDC; ++slot) {
Int_t trbnetaddress = offset+slot;
HTofTrb3LookupBoard* tdc = fLookup->getBoard(trbnetaddress);
if(tdc){
Int_t nChan = tdc->getSize();
if (trbnetaddress) {
Int_t tindex = addTDC(trbnetaddress,nChan);
Info("reinit", "Added TDC 0x%04x with %d channels from HTofTrb3Lookup to map index %d",
trbnetaddress, nChan,tindex);
}
}
}
setMinAddress(fLookup->getArrayOffset());
setMaxAddress(fLookup->getArrayOffset() + fLookup->getSize());
fUseTDCFromLookup = kTRUE;
fHasPrintedTDC = kTRUE;
} else {
Info("reinit", "TDCs will be added in auto register mode between min address 0x%04x and max address 0x%04x!",fMinAddress,fMaxAddress);
}
}
return kTRUE;
}
Int_t HTofTrb3Unpacker::execute(void) {
if (gHades->isCalibration()) {
return 1;
}
if (gHades->getCurrentEvent()->getHeader()->getId() == 0xe) {
return 1;
}
if (!pSubEvt)
return 1;
Int_t nEvt = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
if (!decode()) {
Error("decode",
"subsubevent decoding failed!!! Evt Nr : %i SubEvtId: %x", nEvt,
getSubEvtId());
return -1;
}
if (fTimeRef) {
correctRefTimeCh(REFCHAN);
}
const Double_t timeUnit=1e9;
for (UInt_t ntdc = 0; ntdc < numActiveTDC(); ntdc++) {
HTrb3TdcUnpacker::TDC* tdc = getActiveTDC(ntdc);
HTofTrb3LookupBoard *board = fLookup->getBoard(tdc->getTrbAddr());
if (!board) {
if (debugFlag > 0)
Warning("execute",
"Evt Nr : %i SubEvId: %x (%i) unpacked but TDC Board 0x%x not in lookup table",
nEvt, getSubEvtId(), getSubEvtId(), tdc->getTrbAddr());
continue;
}
for (UInt_t i = 0; i < tdc->numChannels(); i++) {
if(REFCHAN == i) continue;
HTrb3TdcUnpacker::ChannelRec& theRecord = tdc->getCh(i);
#ifndef TOF_USE_TRAILING_WITHOUT_LEADING_EDGES
if (theRecord.rising_mult < 1)
continue;
#endif
HTofTrb3LookupChan *chan = board->getChannel(i);
if (chan == 0) {
Warning("execute", "Missing channel %u in lookup table", i);
continue;
}
chan->getAddress(fLoc[0], fLoc[1], fLoc[2]);
if (fLoc[0] < 0) {
continue;
}
#ifdef TOF_USE_TIME_WINDOW
Double_t tmin = TOF_TIME_MIN;
Double_t tmax = TOF_TIME_MAX;
#endif
UInt_t lix = 0;
for (lix = 0; lix < theRecord.rising_mult; ++lix) {
Double_t tm0 = theRecord.rising_tm[lix] * timeUnit;
if (debugFlag > 0)
Warning("execute", "JJJJ current hit leading: tm0:%e, apply time shift:%e", tm0, fTimeShift);
tm0 +=fTimeShift;
#ifdef TOF_USE_TIME_WINDOW
if ((tm0 < tmin) || (tm0 > tmax)) {
if (debugFlag > 0)
Warning("execute",
"JJJJ Rejecting leading hit outside tmin:%e or tmax:%e",
tmin, tmax);
continue;
}
#endif
if (lix < theRecord.falling_mult) {
Double_t tm1 = theRecord.falling_tm[lix] * timeUnit;
if (debugFlag > 0)
Warning("execute", "JJJJ current hit falling: tm1:%e, apply time shift:%e",
tm1, fTimeShift);
tm1 +=fTimeShift;
#ifdef TOF_USE_TIME_WINDOW
if ((tm1 < tmin) || (tm1 > tmax)) {
if (debugFlag > 0)
Warning("execute",
"JJJJ Rejecting trailing hit outside tmin:%e or tmax:%e",
tmin, tmax);
#ifdef TOF_USE_LEADING_WITHOUT_TRAILING_EDGES
tm1=0.0;
#else
continue;
#endif
}
#endif
if (addRawHit(tm0, tm1, chan) != 0)
continue;
}
else {
#ifdef TOF_USE_LEADING_WITHOUT_TRAILING_EDGES
if(addRawHit(tm0, 0.0, chan)!=0)
continue;
#endif
}
}
#ifdef TOF_USE_TRAILING_WITHOUT_LEADING_EDGES
for (UInt_t tix=lix; tix< theRecord.falling_mult; ++tix)
{
Double_t tm1=theRecord.falling_tm[tix] * timeUnit;
#ifdef TOF_USE_TIME_WINDOW
if ((tm1 < tmin) || (tm1 > tmax)) {
if (debugFlag > 0)
Warning("execute",
"JJJJ Rejecting trailing hit outside tmin:%e or tmax:%e",
tmin, tmax);
continue;
#endif
if(addRawHit(0.0, tm1, chan)!=0)
continue;
}
#endif
}
}
return 1;
}
Int_t HTofTrb3Unpacker::addRawHit(Double_t t_leading, Double_t t_trailing,HTofTrb3LookupChan *chan)
{
HTofRaw* raw = (HTofRaw*) pRawCat->getObject(fLoc);
if (!raw) {
raw = (HTofRaw *) pRawCat->getSlot(fLoc);
if(gHades->getEmbeddingMode()==0) {
raw = new (raw) HTofRaw;
} else{
raw=new (raw) HTofRawSim;
}
if(raw){
raw->setSector((Char_t)fLoc[0]);
raw->setModule((Char_t)fLoc[1]);
raw->setCell((Char_t)fLoc[2]);
} else {
if (debugFlag > 0)
Warning("addRawHit()", "Can't get slot sec=%i, column=%i, cell=%i",
fLoc[0], fLoc[1],fLoc[2]);
return -1;
}
}
Char_t side = chan->getSide();
if(side=='r') {
raw->setRightTime(t_leading);
raw->setRightCharge(t_trailing - t_leading);
} else if (side=='l') {
raw->setLeftTime(t_leading);
raw->setLeftCharge(t_trailing - t_leading);
}
if (debugFlag > 1)
Warning("addRawHit",
"ADDING hit for sec:%d column:%d cell:%d tm0:%e tm1:%e",
fLoc[0], fLoc[1], fLoc[2], t_leading, t_trailing);
return 0;
}