#include "TRandom.h"
#include "hades.h"
#include "hcategory.h"
#include "hdatasource.h"
#include "hdetector.h"
#include "hevent.h"
#include "heventheader.h"
#include "hldsource.h"
#include "hldsubevt.h"
#include "hlocation.h"
#include "hrichcal.h"
#include "hrichcalsim.h"
#include "hrichdetector.h"
#include "hrichmappingpar.h"
#include "hrichunpacker.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "richdef.h"
#include <iostream>
ClassImp(HRichUnpacker)
const UInt_t HRichUnpacker::kHubDebugId = 0x5555;
const UInt_t HRichUnpacker::kADCZero = 0x2000;
HRichUnpacker::HRichUnpacker(Int_t richId,
Int_t strtEvt)
: HldUnpack()
{
fRichId = richId;
fStartEvt = strtEvt;
fSecMisMatchCntr = 0;
fEventNr = -1;
fpCalCat = NULL;
fpMapPar = NULL;
}
Bool_t HRichUnpacker::init(void)
{
HRichDetector* pRichDet = static_cast<HRichDetector*>(gHades->getSetup()->getDetector("Rich"));
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 ");
}
}
fpCalCat = gHades->getCurrentEvent()->getCategory(catRichCal);
if (NULL == fpCalCat) {
if (0 == gHades->getEmbeddingMode()) {
fpCalCat = pRichDet->buildCategory(catRichCal);
} else {
fpCalCat = pRichDet->buildMatrixCat("HRichCalSim", 1);
}
if (NULL == fpCalCat) {
Error("init", "Can not build HRichCal category.");
return kFALSE;
} else {
gHades->getCurrentEvent()->addCategory(catRichCal, fpCalCat, "Rich");
}
}
HRuntimeDb* rtdb = gHades->getRuntimeDb();
fpMapPar = static_cast<HRichMappingPar*>(rtdb->getContainer("RichMappingParameters"));
return kTRUE;
}
Int_t HRichUnpacker::execute()
{
UInt_t sourceSector = 10;
Int_t col = 0;
Int_t row = 0;
DHeader dHeader;
HLocation loc;
loc.set(3, 0, 0, 0);
fEventNr = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
if (NULL == pSubEvt) {
if (0 != gHades->getCurrentEvent()->getHeader()->getEventSeqNumber()) {
#if DEBUG_LEVEL > 0
Warning("execute", "EvtId: 0x%x, Unpacker 0x%x ==> no data", gHades->getCurrentEvent()->getHeader()->getId(), fRichId);
#endif
}
return 1;
}
if (fEventNr >= fStartEvt) {
for (UInt_t i = 0; i < pSubEvt->getDataLen(); i++) {
if (0xaaaaaaaa == pSubEvt->getData()[i]) {
continue;
}
dHeader.getEvent(pSubEvt->getData()[i]);
if (0 == dHeader.getSize()) {
continue;
}
if (kHubDebugId == dHeader.getSource()) {
#if DEBUG_LEVEL > 2
Info("execute", "Only debug info will follow, skiping.");
#endif
decodeTrbNet((pSubEvt->getData() + i), fRichId);
i += (dHeader.getSize());
continue;
}
i++;
if ((dHeader.getSource() & 0xf) > 4 ||
(dHeader.getSource() & 0xff00) != 0x3000) {
Error("execute", "Wrong ADSM number: 0x%x", dHeader.getSource());
}
sourceSector = (dHeader.getSource() >> 4) & 0xf;
for (UInt_t j = 0; j < dHeader.getSize(); j++, i++) {
if (0 != ((pSubEvt->getData()[i] >> 31) & 0x01)) {
#if DEBUG_LEVEL > 2
Info("execute", "debug info %x", pSubEvt->getData()[i]);
#endif
continue;
}
fDataWord.charge = (pSubEvt->getData()[i] >> RICH_CHARGE_OFFSET) & RICH_CHARGE_MASK;
fDataWord.channel = (pSubEvt->getData()[i] >> RICH_CHANNEL_OFFSET) & RICH_CHANNEL_MASK;
fDataWord.apv = (pSubEvt->getData()[i] >> RICH_APV_OFFSET) & RICH_APV_MASK;
fDataWord.adc = (pSubEvt->getData()[i] >> RICH_ADC_OFFSET) & RICH_ADC_MASK ;
fDataWord.sector = (pSubEvt->getData()[i] >> RICH_SECTOR_OFFSET) & RICH_SECTOR_MASK;
if (1 == fDataWord.channel % 2) {
continue;
}
if ((fDataWord.channel >= RICH_MAX_CHANNELS) ||
(fDataWord.adc >= RICH_MAX_ADCS) ||
(fDataWord.apv >= RICH_MAX_APVS) ||
(fDataWord.sector >= RICH_MAX_SECTORS)) {
Error("execute", "Evt %i SubEvtId %x Source %x: Wrong address (sec,adc,apv,ch) = (%i,%i,%i,%i)",
fEventNr, fRichId, dHeader.getSource(), fDataWord.sector, fDataWord.adc, fDataWord.apv, fDataWord.channel);
continue;
}
if (fDataWord.sector != sourceSector) {
fSecMisMatchCntr++;
Error("execute", "Evt %i SubEvtId %x Source %x: Unpacked sector %i differs from assigned sector %i (0x%x)",
fEventNr, fRichId, dHeader.getSource(), fDataWord.sector, sourceSector, pSubEvt->getData()[i]);
continue;
}
if (kFALSE == fpMapPar->getSWAddress(getAddress(fDataWord), row, col)) {
#if DEBUG_LEVEL > 4
Error("execute", "Evt %i SubEvtId %x Source %x: addr: %x: APV channel (sec,adc,apv,ch) = (%i,%i,%i,%i) is unconnected.",
fEventNr, fRichId, dHeader.getSource(), getAddress(fDataWord), fDataWord.sector, fDataWord.adc, fDataWord.apv, fDataWord.channel);
cerr << "printDataWord says:" << endl;
printDataWord(fDataWord);
cerr << "printMapping says:" << endl;
printMapping(fDataWord);
#endif
continue;
}
loc.setOffset(col);
loc.setIndex(1, row);
loc.setIndex(0, fDataWord.sector);
Float_t charge = static_cast<Float_t>(fDataWord.charge - kADCZero) + gRandom->Rndm();
HRichCal* pCell = NULL;
if (charge > 0.0) {
pCell = static_cast<HRichCal*>(fpCalCat->getSlot(loc));
if (NULL != pCell) {
if (0 == gHades->getEmbeddingMode()) {
pCell = new(pCell) HRichCal(loc[0], loc[1], loc[2]);
} else {
pCell = new(pCell) HRichCalSim(loc[0], loc[1], loc[2]);
}
pCell->setCharge(charge);
pCell->setEventNr(fEventNr);
} else {
Error("Execute", "getSlot(loc) returned NULL! (sec,row,col) = (%i,%i,%i), addr: 0x%x (%i,%i)", loc[0], loc[1], loc[2], getAddress(fDataWord), row, col);
}
}
}
i--;
}
}
return 1;
}
Bool_t HRichUnpacker::finalize(void)
{
#if DEBUG_LEVEL > 1
cerr << "SubEvtId:" << fRichId << " RICH: Number of evts processed: " << fEventNr << endl;
cerr << "SubEvtId:" << fRichId << " RICH: Sector mismatch errors: " << fSecMisMatchCntr << endl;
#endif
return kTRUE;
}
void HRichUnpacker::printDataWord(const DataWord & addr)
{
cout << "*****************************************************************************" << endl;
cout << "Event Nr: " << fEventNr << endl;
cout << " SEC: " << addr.sector
<< " ADC: " << addr.adc
<< " APV: " << addr.apv
<< " CH: " << addr.channel
<< " CHRG: " << addr.charge << endl;
}
void HRichUnpacker::printMapping(const DataWord & addr)
{
Int_t row = -1;
Int_t col = -1;
cout << "Event Nr: " << fEventNr << endl;
cout << "isValidAddress: " << fpMapPar->getSWAddress(getAddress(addr), row, col) << endl;
cout << "Col: " << col << endl;
cout << "Row: " << row << endl;
cout << "*****************************************************************************" << endl;
}
DHeader::DHeader()
{
reset();
}
void DHeader::reset()
{
fSize = 0;
fSource = 0;
}
void DHeader::getEvent(UInt_t word)
{
fSize = (word >> 16) & 0xffff;
fSource = word & 0xffff;
}
void DHeader::dump()
{
Info("dump", "%c size: 0x%04x source: 0x%04x\n", '%', fSize, fSource);
}