ROOT logo
//////////////////////////////////////////////////////////////////////////////
//
// $Id: $
//
//*-- Author  : Martin Jurkovic <martin.jurkovic@ph.tum.de>
//*-- Revised : Martin Jurkovic <martin.jurkovic@ph.tum.de> 2010
//
//_HADES_CLASS_DESCRIPTION
//////////////////////////////////////////////////////////////////////////////
//
//  HRichUnpacker
//
//
//////////////////////////////////////////////////////////////////////////////


#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)
{
// Initialize input parameter containers and build output categories

   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 ");
      }
   }


// Output categories
   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");
      }
   }

// Input parameter containers
   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) {

      // decode the header first
      for (UInt_t i = 0; i < pSubEvt->getDataLen(); i++) {
         // Check for pedding word first (skip)
         if (0xaaaaaaaa == pSubEvt->getData()[i]) {
            continue;
         }

         // decode subsub_event and its header
         dHeader.getEvent(pSubEvt->getData()[i]);
         if (0 == dHeader.getSize()) {
            // no data im subsubevent
            continue;
         }

         // check for debug info data type
         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;
         }

         // After decoding and checking the header jump to the next data word
         i++;

         // Each data source (in this case ADC module) is uniquely assigned to a specific sector
         if ((dHeader.getSource() & 0xf) > 4 ||
             (dHeader.getSource() & 0xff00) != 0x3000) {
            Error("execute", "Wrong ADSM number: 0x%x", dHeader.getSource());
         }
         sourceSector = (dHeader.getSource() >> 4) & 0xf;

         // Read the sub-sub event
         for (UInt_t j = 0; j < dHeader.getSize(); j++, i++) {
            // Check for debug word (skip)
            if (0 != ((pSubEvt->getData()[i] >> 31) & 0x01)) {
#if DEBUG_LEVEL > 2
               Info("execute", "debug info %x", pSubEvt->getData()[i]);
#endif
               continue;
            }

            // Fill the data structure
            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;
            }

            // Check if the HW address is in reasonable range
            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;
            }

            // Check sector consistency
            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;
            }

            // Check if the apv channel is connected to a pad and get SW coordinates (row,col).
            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);

            // APV data are already calibrated. To the ADC value a random nb
            // [0;1] is added to account for the cut-off in the ADC
            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);
               }
            }
         } // end of unpacking subsub event

         // rewind by one data word
         i--;

      } // end of unpacking sub event
   } // end of start event condition
   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);
}
 hrichunpacker.cc:1
 hrichunpacker.cc:2
 hrichunpacker.cc:3
 hrichunpacker.cc:4
 hrichunpacker.cc:5
 hrichunpacker.cc:6
 hrichunpacker.cc:7
 hrichunpacker.cc:8
 hrichunpacker.cc:9
 hrichunpacker.cc:10
 hrichunpacker.cc:11
 hrichunpacker.cc:12
 hrichunpacker.cc:13
 hrichunpacker.cc:14
 hrichunpacker.cc:15
 hrichunpacker.cc:16
 hrichunpacker.cc:17
 hrichunpacker.cc:18
 hrichunpacker.cc:19
 hrichunpacker.cc:20
 hrichunpacker.cc:21
 hrichunpacker.cc:22
 hrichunpacker.cc:23
 hrichunpacker.cc:24
 hrichunpacker.cc:25
 hrichunpacker.cc:26
 hrichunpacker.cc:27
 hrichunpacker.cc:28
 hrichunpacker.cc:29
 hrichunpacker.cc:30
 hrichunpacker.cc:31
 hrichunpacker.cc:32
 hrichunpacker.cc:33
 hrichunpacker.cc:34
 hrichunpacker.cc:35
 hrichunpacker.cc:36
 hrichunpacker.cc:37
 hrichunpacker.cc:38
 hrichunpacker.cc:39
 hrichunpacker.cc:40
 hrichunpacker.cc:41
 hrichunpacker.cc:42
 hrichunpacker.cc:43
 hrichunpacker.cc:44
 hrichunpacker.cc:45
 hrichunpacker.cc:46
 hrichunpacker.cc:47
 hrichunpacker.cc:48
 hrichunpacker.cc:49
 hrichunpacker.cc:50
 hrichunpacker.cc:51
 hrichunpacker.cc:52
 hrichunpacker.cc:53
 hrichunpacker.cc:54
 hrichunpacker.cc:55
 hrichunpacker.cc:56
 hrichunpacker.cc:57
 hrichunpacker.cc:58
 hrichunpacker.cc:59
 hrichunpacker.cc:60
 hrichunpacker.cc:61
 hrichunpacker.cc:62
 hrichunpacker.cc:63
 hrichunpacker.cc:64
 hrichunpacker.cc:65
 hrichunpacker.cc:66
 hrichunpacker.cc:67
 hrichunpacker.cc:68
 hrichunpacker.cc:69
 hrichunpacker.cc:70
 hrichunpacker.cc:71
 hrichunpacker.cc:72
 hrichunpacker.cc:73
 hrichunpacker.cc:74
 hrichunpacker.cc:75
 hrichunpacker.cc:76
 hrichunpacker.cc:77
 hrichunpacker.cc:78
 hrichunpacker.cc:79
 hrichunpacker.cc:80
 hrichunpacker.cc:81
 hrichunpacker.cc:82
 hrichunpacker.cc:83
 hrichunpacker.cc:84
 hrichunpacker.cc:85
 hrichunpacker.cc:86
 hrichunpacker.cc:87
 hrichunpacker.cc:88
 hrichunpacker.cc:89
 hrichunpacker.cc:90
 hrichunpacker.cc:91
 hrichunpacker.cc:92
 hrichunpacker.cc:93
 hrichunpacker.cc:94
 hrichunpacker.cc:95
 hrichunpacker.cc:96
 hrichunpacker.cc:97
 hrichunpacker.cc:98
 hrichunpacker.cc:99
 hrichunpacker.cc:100
 hrichunpacker.cc:101
 hrichunpacker.cc:102
 hrichunpacker.cc:103
 hrichunpacker.cc:104
 hrichunpacker.cc:105
 hrichunpacker.cc:106
 hrichunpacker.cc:107
 hrichunpacker.cc:108
 hrichunpacker.cc:109
 hrichunpacker.cc:110
 hrichunpacker.cc:111
 hrichunpacker.cc:112
 hrichunpacker.cc:113
 hrichunpacker.cc:114
 hrichunpacker.cc:115
 hrichunpacker.cc:116
 hrichunpacker.cc:117
 hrichunpacker.cc:118
 hrichunpacker.cc:119
 hrichunpacker.cc:120
 hrichunpacker.cc:121
 hrichunpacker.cc:122
 hrichunpacker.cc:123
 hrichunpacker.cc:124
 hrichunpacker.cc:125
 hrichunpacker.cc:126
 hrichunpacker.cc:127
 hrichunpacker.cc:128
 hrichunpacker.cc:129
 hrichunpacker.cc:130
 hrichunpacker.cc:131
 hrichunpacker.cc:132
 hrichunpacker.cc:133
 hrichunpacker.cc:134
 hrichunpacker.cc:135
 hrichunpacker.cc:136
 hrichunpacker.cc:137
 hrichunpacker.cc:138
 hrichunpacker.cc:139
 hrichunpacker.cc:140
 hrichunpacker.cc:141
 hrichunpacker.cc:142
 hrichunpacker.cc:143
 hrichunpacker.cc:144
 hrichunpacker.cc:145
 hrichunpacker.cc:146
 hrichunpacker.cc:147
 hrichunpacker.cc:148
 hrichunpacker.cc:149
 hrichunpacker.cc:150
 hrichunpacker.cc:151
 hrichunpacker.cc:152
 hrichunpacker.cc:153
 hrichunpacker.cc:154
 hrichunpacker.cc:155
 hrichunpacker.cc:156
 hrichunpacker.cc:157
 hrichunpacker.cc:158
 hrichunpacker.cc:159
 hrichunpacker.cc:160
 hrichunpacker.cc:161
 hrichunpacker.cc:162
 hrichunpacker.cc:163
 hrichunpacker.cc:164
 hrichunpacker.cc:165
 hrichunpacker.cc:166
 hrichunpacker.cc:167
 hrichunpacker.cc:168
 hrichunpacker.cc:169
 hrichunpacker.cc:170
 hrichunpacker.cc:171
 hrichunpacker.cc:172
 hrichunpacker.cc:173
 hrichunpacker.cc:174
 hrichunpacker.cc:175
 hrichunpacker.cc:176
 hrichunpacker.cc:177
 hrichunpacker.cc:178
 hrichunpacker.cc:179
 hrichunpacker.cc:180
 hrichunpacker.cc:181
 hrichunpacker.cc:182
 hrichunpacker.cc:183
 hrichunpacker.cc:184
 hrichunpacker.cc:185
 hrichunpacker.cc:186
 hrichunpacker.cc:187
 hrichunpacker.cc:188
 hrichunpacker.cc:189
 hrichunpacker.cc:190
 hrichunpacker.cc:191
 hrichunpacker.cc:192
 hrichunpacker.cc:193
 hrichunpacker.cc:194
 hrichunpacker.cc:195
 hrichunpacker.cc:196
 hrichunpacker.cc:197
 hrichunpacker.cc:198
 hrichunpacker.cc:199
 hrichunpacker.cc:200
 hrichunpacker.cc:201
 hrichunpacker.cc:202
 hrichunpacker.cc:203
 hrichunpacker.cc:204
 hrichunpacker.cc:205
 hrichunpacker.cc:206
 hrichunpacker.cc:207
 hrichunpacker.cc:208
 hrichunpacker.cc:209
 hrichunpacker.cc:210
 hrichunpacker.cc:211
 hrichunpacker.cc:212
 hrichunpacker.cc:213
 hrichunpacker.cc:214
 hrichunpacker.cc:215
 hrichunpacker.cc:216
 hrichunpacker.cc:217
 hrichunpacker.cc:218
 hrichunpacker.cc:219
 hrichunpacker.cc:220
 hrichunpacker.cc:221
 hrichunpacker.cc:222
 hrichunpacker.cc:223
 hrichunpacker.cc:224
 hrichunpacker.cc:225
 hrichunpacker.cc:226
 hrichunpacker.cc:227
 hrichunpacker.cc:228
 hrichunpacker.cc:229
 hrichunpacker.cc:230
 hrichunpacker.cc:231
 hrichunpacker.cc:232
 hrichunpacker.cc:233
 hrichunpacker.cc:234
 hrichunpacker.cc:235
 hrichunpacker.cc:236
 hrichunpacker.cc:237
 hrichunpacker.cc:238
 hrichunpacker.cc:239
 hrichunpacker.cc:240
 hrichunpacker.cc:241
 hrichunpacker.cc:242
 hrichunpacker.cc:243
 hrichunpacker.cc:244
 hrichunpacker.cc:245
 hrichunpacker.cc:246
 hrichunpacker.cc:247
 hrichunpacker.cc:248
 hrichunpacker.cc:249
 hrichunpacker.cc:250
 hrichunpacker.cc:251
 hrichunpacker.cc:252
 hrichunpacker.cc:253
 hrichunpacker.cc:254
 hrichunpacker.cc:255
 hrichunpacker.cc:256
 hrichunpacker.cc:257
 hrichunpacker.cc:258
 hrichunpacker.cc:259
 hrichunpacker.cc:260
 hrichunpacker.cc:261
 hrichunpacker.cc:262
 hrichunpacker.cc:263
 hrichunpacker.cc:264
 hrichunpacker.cc:265
 hrichunpacker.cc:266
 hrichunpacker.cc:267
 hrichunpacker.cc:268
 hrichunpacker.cc:269
 hrichunpacker.cc:270
 hrichunpacker.cc:271
 hrichunpacker.cc:272
 hrichunpacker.cc:273
 hrichunpacker.cc:274
 hrichunpacker.cc:275
 hrichunpacker.cc:276
 hrichunpacker.cc:277
 hrichunpacker.cc:278
 hrichunpacker.cc:279
 hrichunpacker.cc:280
 hrichunpacker.cc:281
 hrichunpacker.cc:282
 hrichunpacker.cc:283
 hrichunpacker.cc:284
 hrichunpacker.cc:285
 hrichunpacker.cc:286
 hrichunpacker.cc:287
 hrichunpacker.cc:288
 hrichunpacker.cc:289
 hrichunpacker.cc:290
 hrichunpacker.cc:291
 hrichunpacker.cc:292
 hrichunpacker.cc:293
 hrichunpacker.cc:294
 hrichunpacker.cc:295