#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 "hemcdetector.h"
#include "hemcraw.h"
#include "hemctrb3lookup.h"
#include "hemctrb3unpacker.h"
#include "emcdef.h"
#include "htrbnetunpacker.h"
#include <iostream>
using namespace std;
ClassImp(HEmcTrb3Unpacker)
#define EMC_USE_TIME_WINDOW 1
#define EMC_TIME_MIN -300.0
#define EMC_TIME_MAX 1500.0
Bool_t HEmcTrb3Unpacker::fHasPrintedTDC = kFALSE;
HEmcTrb3Unpacker::HEmcTrb3Unpacker(vector<UInt_t>& ids) : HTrb3TdcUnpacker(ids),
fLookup(0), fTimeRef(kTRUE), fTimeShift(650.) {
pRawCat = NULL;
}
Bool_t HEmcTrb3Unpacker::init(void) {
HEmcDetector* det = (HEmcDetector*) gHades->getSetup()->getDetector("Emc");
if (!det) {
Error("init", "No EMC Detector found.");
return kFALSE;
}
pRawCat = det->buildCategory(catEmcRaw);
if (!pRawCat) return kFALSE;
else gHades->getCurrentEvent()->addCategory(catEmcRaw,pRawCat,"Emc");
fLoc.set(2, 0, 0);
fLookup = (HEmcTrb3Lookup*) (gHades->getRuntimeDb()->getContainer("EmcTrb3Lookup"));
if (!fLookup) {
Error("init", "No Pointer to parameter container EmcTrb3Lookup.");
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 HEmcTrb3Unpacker::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;
HEmcTrb3LookupBoard* 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 HEmcTrb3Lookup 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 HEmcTrb3Unpacker::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);
HEmcTrb3LookupBoard *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 EMC_USE_TRAILING_WITHOUT_LEADING_EDGES
if (theRecord.rising_mult < 1)
continue;
#endif
HEmcTrb3LookupChan *chan = board->getChannel(i);
if (chan == 0) {
Warning("execute", "Missing channel %u in lookup table", i);
continue;
}
chan->getAddress(fLoc[0], fLoc[1]);
if (fLoc[0] < 0) {
continue;
}
if (!chan->isDefinedChannel() || chan->isBrokenChannel())
continue;
Bool_t fastchannel = chan->isFastChannel();
if(fastchannel && chan->isSlowChannel())
{
Warning("execute", "NEVER COME HERE - channel %u has both fast and slow property! skip it..", i);
continue;
}
#ifdef EMC_USE_TIME_WINDOW
Double_t tmin = EMC_TIME_MIN;
Double_t tmax = EMC_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 EMC_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 EMC_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 EMC_USE_LEADING_WITHOUT_TRAILING_EDGES
tm1=0.0;
#else
continue;
#endif
}
#endif
if (addRawHit(tm0, tm1, fastchannel) != 0)
continue;
}
else {
#ifdef EMC_USE_LEADING_WITHOUT_TRAILING_EDGES
if(addRawHit(tm0, 0.0, fastchannel)!=0)
continue;
#endif
}
}
#ifdef EMC_USE_TRAILING_WITHOUT_LEADING_EDGES
for (UInt_t tix=lix; tix< theRecord.falling_mult; ++tix)
{
Double_t tm1=theRecord.falling_tm[tix] * timeUnit;
#ifdef EMC_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, fastchannel)!=0)
continue;
}
#endif
}
}
return 1;
}
Int_t HEmcTrb3Unpacker::addRawHit(Double_t t_leading, Double_t t_trailing,
Bool_t isfastchannel) {
HEmcRaw* raw = (HEmcRaw*) pRawCat->getObject(fLoc);
if (!raw) {
raw = (HEmcRaw *) pRawCat->getSlot(fLoc);
if (raw) {
raw = new (raw) HEmcRaw;
Char_t row,col;
HEmcDetector::getRowCol(fLoc[1],row,col);
raw->setAddress(fLoc[0], fLoc[1],row,col);
} else {
if (debugFlag > 0)
Warning("addRawHit()", "Can't get slot mod=%i, chan=%i",
fLoc[0], fLoc[1]);
return -1;
}
}
isfastchannel ?
raw->addFastHit(t_leading, t_trailing) :
raw->addSlowHit(t_leading, t_trailing);
if (debugFlag > 1)
Warning("addRawHit",
"JJJJ ADDING %s hit for mod:%d chan:%d tm0:%e tm1:%e",
(isfastchannel ? "fast" : "slow"), fLoc[0], fLoc[1], t_leading,
t_trailing);
return 0;
}