ROOT logo
/////////////////////////////////////////////////////////////
//
//  HTrb3TdcUnpacker
//
//  This is class to unpack and calibrate data of single FPGA TDC
//  It should be similar to functionality of hadaq::TdcProcessor from 'stream' framework
//
/////////////////////////////////////////////////////////////

#ifndef HTRB3TDCUNPACKER_H
#define HTRB3TDCUNPACKER_H

#include "htrb3unpacker.h"
#include "htrb3calpar.h"
#include "hades.h"
#include "hevent.h"
#include "heventheader.h"

#include "TObject.h"
#include <vector>
#include <map>

class HTrb3CalparTdc;

class HTrb3TdcUnpacker : public HTrb3Unpacker  {


#define  REFCHAN 0

    //#define USE_FILLED_TDC 1  // switch to use list of TDCs with data only (CAUTION: TDC with missing ref time will not emmit warnings if they don't transport data)

public:

   struct ChannelRec {
      Double_t rising_tm[10];
      Double_t falling_tm[10];
      UInt_t   rising_mult;
      UInt_t   falling_mult;
      Bool_t   hasData;

      ChannelRec() :
         rising_mult(0),
	  falling_mult(0),
          hasData(kFALSE) {}

      void clear()
      {
         rising_mult  = 0;
	 falling_mult = 0;
         hasData      = kFALSE;
      }

      void addHit(Bool_t rising, Double_t tm)
      {
         if (rising) {
            if (rising_mult < 10)
               rising_tm[rising_mult++] = tm;
	 } else {
            if (falling_mult < 10)
               falling_tm[falling_mult++] = tm;
	 }
         hasData = kTRUE;
      }

      Double_t getHit(Bool_t rising, UInt_t cnt)
      {
         return rising ?
            (cnt<rising_mult ? rising_tm[cnt] : 0.) :
            (cnt<falling_mult ? falling_tm[cnt] : 0.);
      }

      Double_t getLastHit(Bool_t rising)
      {
         return rising ?
            (rising_mult>0 ? rising_tm[rising_mult-1] : 0.) :
            (falling_mult>0 ? falling_tm[falling_mult-1] : 0.);
      }

      void substractRefTime(Double_t reftm)
      {
         for (UInt_t n=0;n<rising_mult;n++)
            rising_tm[n] -= reftm;

         for (UInt_t n=0;n<falling_mult;n++)
            falling_tm[n] -= reftm;
      }
   };

   static const size_t maxchan = 65;
   struct TDC {
      UInt_t pSubEvtId;
      UInt_t fTdcId;
      UInt_t nChan;
      UInt_t fCalibr[2]; //!< temporary fine time calibration info from data stream
      Int_t fNcalibr; // counter of available fine time calibration values
      Bool_t  fFoundInStream;  // TDC was found in the data stream
      ChannelRec fCh[maxchan];
      std::vector<Int_t>chanList; // list of channels containing data (if USE_FILLED_TDC is defined)
      Bool_t  fhasData ;  //!

      TDC(size_t numchannels=maxchan) :
         pSubEvtId(0),
         fTdcId(0),
	  nChan(numchannels), fNcalibr(0), fFoundInStream(kFALSE) {
	      chanList.reserve(maxchan);
	  }

      void clear()
      {
         for (UInt_t i = 0; i < nChan; ++i)
	     fCh[i].clear();
	 chanList.clear();
         fhasData = kFALSE;
      }
      Bool_t hasData(){
	  for (UInt_t ch=0;ch<numChannels();ch++) {
              if(ch==REFCHAN) continue;
	      if(fCh[ch].hasData) return kTRUE;
	  }
          return kFALSE;
      }
      UInt_t getTrbAddr() const { return fTdcId; }
      UInt_t numChannels() const { return nChan; }
      ChannelRec& getCh(UInt_t n) { return fCh[n]; }

      Int_t correctRefTimeCh(UInt_t refch = REFCHAN)
      {
         // calculates all times to first hit in channel 0

	 if (refch>=numChannels()) return kFALSE;
         if(!fhasData)             return kTRUE;
	 if(!fFoundInStream)       return kTRUE;   // skipp empty data
	 if (fCh[refch].rising_mult<=0)
	 {
	     Long_t seqnum = -1;
	     if (gHades != 0 && gHades->getCurrentEvent() != 0 &&
		 gHades->getCurrentEvent()->getHeader() != 0) {
		 seqnum = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
	     }
	     cerr << "   Warning<HTrb3TdcUnpacker::TDC::correctRefTimeCh()>: No reference time for trb=0x" << hex << getTrbAddr() <<" sub event 0x"<<pSubEvtId<< dec << " in evt seq=" << seqnum << endl;
	     return kFALSE;
	 }
         Double_t reftm = fCh[refch].rising_tm[0];
         for (UInt_t ch=0;ch<numChannels();ch++)
            fCh[ch].substractRefTime(reftm);
         return kTRUE;
      }
   };

protected:
   HTrb3Calpar* calpar;         //! TDC calibration parameters
   std::map<UInt_t, HTrb3CalparTdc*> fCalpars;
   std::vector<TDC> fTDCs;      //!
   std::vector<Int_t> factiveTDCs;      //! list of TDCs found in the data stream
   std::vector<Int_t> fFilledTDCs;      //! if USE_FILLED_TDC is defined this list contains TDC with data
   std::map<UInt_t, Int_t> fTDCsMap; //!
   Int_t nCalSrc;               //! 0 -auto, 1 - no calibration, 2 - calpar, 3 - DAQ

   UInt_t fMinAddress; //!< for check of address range when autoregistration of tdcs
   UInt_t fMaxAddress; //!< for check of address range when autoregistration of tdcs
   Bool_t fUseTDCFromLookup; //! kTRUE : list of TDC build from lookup table, kFALSE : autoregister mode

   Int_t getEventSeqNumber();

   void addCalpar(UInt_t id1, HTrb3CalparTdc*);

 public:
   HTrb3TdcUnpacker(vector<UInt_t>& ids);
   virtual ~HTrb3TdcUnpacker();

   virtual Bool_t reinit();

   UInt_t numTDC      () const   { return fTDCs.size(); }
   TDC *  getTDC      (UInt_t n) { return &(fTDCs[n]); }
   UInt_t numActiveTDC() const   { return factiveTDCs.size(); }
   TDC *  getActiveTDC(UInt_t n) { return &(fTDCs[factiveTDCs[n]]); }
   UInt_t numFilledTDC() const   { return fFilledTDCs.size(); }
   TDC *  getFilledTDC(UInt_t n) { return &(fTDCs[fFilledTDCs[n]]); }

   /** preassign tdc of expected trbnet address. returns index in map*/
   Int_t addTDC(UInt_t trbaddr, size_t numchannels=maxchan);

   void setCalibrationSource(UInt_t s) { nCalSrc = s; }

   Bool_t scanTdcData(UInt_t trbaddr, UInt_t* data, UInt_t datalen);
   Bool_t correctRefTimeCh(UInt_t ch = 0);

   void setMinAddress(UInt_t trbnetaddress) { fMinAddress=trbnetaddress; }
   void setMaxAddress(UInt_t trbnetaddress) { fMaxAddress=trbnetaddress; }

protected:
   void clearAll();
   virtual Bool_t decodeData(UInt_t trbaddr, UInt_t n, UInt_t * data);

   ClassDef(HTrb3TdcUnpacker,0); // Unpacker for TRB3 FPGA TDC
};

#endif /* !HTRB3TDCUNPACKER_H */


 htrb3tdcunpacker.h:1
 htrb3tdcunpacker.h:2
 htrb3tdcunpacker.h:3
 htrb3tdcunpacker.h:4
 htrb3tdcunpacker.h:5
 htrb3tdcunpacker.h:6
 htrb3tdcunpacker.h:7
 htrb3tdcunpacker.h:8
 htrb3tdcunpacker.h:9
 htrb3tdcunpacker.h:10
 htrb3tdcunpacker.h:11
 htrb3tdcunpacker.h:12
 htrb3tdcunpacker.h:13
 htrb3tdcunpacker.h:14
 htrb3tdcunpacker.h:15
 htrb3tdcunpacker.h:16
 htrb3tdcunpacker.h:17
 htrb3tdcunpacker.h:18
 htrb3tdcunpacker.h:19
 htrb3tdcunpacker.h:20
 htrb3tdcunpacker.h:21
 htrb3tdcunpacker.h:22
 htrb3tdcunpacker.h:23
 htrb3tdcunpacker.h:24
 htrb3tdcunpacker.h:25
 htrb3tdcunpacker.h:26
 htrb3tdcunpacker.h:27
 htrb3tdcunpacker.h:28
 htrb3tdcunpacker.h:29
 htrb3tdcunpacker.h:30
 htrb3tdcunpacker.h:31
 htrb3tdcunpacker.h:32
 htrb3tdcunpacker.h:33
 htrb3tdcunpacker.h:34
 htrb3tdcunpacker.h:35
 htrb3tdcunpacker.h:36
 htrb3tdcunpacker.h:37
 htrb3tdcunpacker.h:38
 htrb3tdcunpacker.h:39
 htrb3tdcunpacker.h:40
 htrb3tdcunpacker.h:41
 htrb3tdcunpacker.h:42
 htrb3tdcunpacker.h:43
 htrb3tdcunpacker.h:44
 htrb3tdcunpacker.h:45
 htrb3tdcunpacker.h:46
 htrb3tdcunpacker.h:47
 htrb3tdcunpacker.h:48
 htrb3tdcunpacker.h:49
 htrb3tdcunpacker.h:50
 htrb3tdcunpacker.h:51
 htrb3tdcunpacker.h:52
 htrb3tdcunpacker.h:53
 htrb3tdcunpacker.h:54
 htrb3tdcunpacker.h:55
 htrb3tdcunpacker.h:56
 htrb3tdcunpacker.h:57
 htrb3tdcunpacker.h:58
 htrb3tdcunpacker.h:59
 htrb3tdcunpacker.h:60
 htrb3tdcunpacker.h:61
 htrb3tdcunpacker.h:62
 htrb3tdcunpacker.h:63
 htrb3tdcunpacker.h:64
 htrb3tdcunpacker.h:65
 htrb3tdcunpacker.h:66
 htrb3tdcunpacker.h:67
 htrb3tdcunpacker.h:68
 htrb3tdcunpacker.h:69
 htrb3tdcunpacker.h:70
 htrb3tdcunpacker.h:71
 htrb3tdcunpacker.h:72
 htrb3tdcunpacker.h:73
 htrb3tdcunpacker.h:74
 htrb3tdcunpacker.h:75
 htrb3tdcunpacker.h:76
 htrb3tdcunpacker.h:77
 htrb3tdcunpacker.h:78
 htrb3tdcunpacker.h:79
 htrb3tdcunpacker.h:80
 htrb3tdcunpacker.h:81
 htrb3tdcunpacker.h:82
 htrb3tdcunpacker.h:83
 htrb3tdcunpacker.h:84
 htrb3tdcunpacker.h:85
 htrb3tdcunpacker.h:86
 htrb3tdcunpacker.h:87
 htrb3tdcunpacker.h:88
 htrb3tdcunpacker.h:89
 htrb3tdcunpacker.h:90
 htrb3tdcunpacker.h:91
 htrb3tdcunpacker.h:92
 htrb3tdcunpacker.h:93
 htrb3tdcunpacker.h:94
 htrb3tdcunpacker.h:95
 htrb3tdcunpacker.h:96
 htrb3tdcunpacker.h:97
 htrb3tdcunpacker.h:98
 htrb3tdcunpacker.h:99
 htrb3tdcunpacker.h:100
 htrb3tdcunpacker.h:101
 htrb3tdcunpacker.h:102
 htrb3tdcunpacker.h:103
 htrb3tdcunpacker.h:104
 htrb3tdcunpacker.h:105
 htrb3tdcunpacker.h:106
 htrb3tdcunpacker.h:107
 htrb3tdcunpacker.h:108
 htrb3tdcunpacker.h:109
 htrb3tdcunpacker.h:110
 htrb3tdcunpacker.h:111
 htrb3tdcunpacker.h:112
 htrb3tdcunpacker.h:113
 htrb3tdcunpacker.h:114
 htrb3tdcunpacker.h:115
 htrb3tdcunpacker.h:116
 htrb3tdcunpacker.h:117
 htrb3tdcunpacker.h:118
 htrb3tdcunpacker.h:119
 htrb3tdcunpacker.h:120
 htrb3tdcunpacker.h:121
 htrb3tdcunpacker.h:122
 htrb3tdcunpacker.h:123
 htrb3tdcunpacker.h:124
 htrb3tdcunpacker.h:125
 htrb3tdcunpacker.h:126
 htrb3tdcunpacker.h:127
 htrb3tdcunpacker.h:128
 htrb3tdcunpacker.h:129
 htrb3tdcunpacker.h:130
 htrb3tdcunpacker.h:131
 htrb3tdcunpacker.h:132
 htrb3tdcunpacker.h:133
 htrb3tdcunpacker.h:134
 htrb3tdcunpacker.h:135
 htrb3tdcunpacker.h:136
 htrb3tdcunpacker.h:137
 htrb3tdcunpacker.h:138
 htrb3tdcunpacker.h:139
 htrb3tdcunpacker.h:140
 htrb3tdcunpacker.h:141
 htrb3tdcunpacker.h:142
 htrb3tdcunpacker.h:143
 htrb3tdcunpacker.h:144
 htrb3tdcunpacker.h:145
 htrb3tdcunpacker.h:146
 htrb3tdcunpacker.h:147
 htrb3tdcunpacker.h:148
 htrb3tdcunpacker.h:149
 htrb3tdcunpacker.h:150
 htrb3tdcunpacker.h:151
 htrb3tdcunpacker.h:152
 htrb3tdcunpacker.h:153
 htrb3tdcunpacker.h:154
 htrb3tdcunpacker.h:155
 htrb3tdcunpacker.h:156
 htrb3tdcunpacker.h:157
 htrb3tdcunpacker.h:158
 htrb3tdcunpacker.h:159
 htrb3tdcunpacker.h:160
 htrb3tdcunpacker.h:161
 htrb3tdcunpacker.h:162
 htrb3tdcunpacker.h:163
 htrb3tdcunpacker.h:164
 htrb3tdcunpacker.h:165
 htrb3tdcunpacker.h:166
 htrb3tdcunpacker.h:167
 htrb3tdcunpacker.h:168
 htrb3tdcunpacker.h:169
 htrb3tdcunpacker.h:170
 htrb3tdcunpacker.h:171
 htrb3tdcunpacker.h:172
 htrb3tdcunpacker.h:173
 htrb3tdcunpacker.h:174
 htrb3tdcunpacker.h:175
 htrb3tdcunpacker.h:176
 htrb3tdcunpacker.h:177
 htrb3tdcunpacker.h:178
 htrb3tdcunpacker.h:179
 htrb3tdcunpacker.h:180
 htrb3tdcunpacker.h:181
 htrb3tdcunpacker.h:182
 htrb3tdcunpacker.h:183
 htrb3tdcunpacker.h:184
 htrb3tdcunpacker.h:185
 htrb3tdcunpacker.h:186
 htrb3tdcunpacker.h:187
 htrb3tdcunpacker.h:188
 htrb3tdcunpacker.h:189
 htrb3tdcunpacker.h:190
 htrb3tdcunpacker.h:191
 htrb3tdcunpacker.h:192
 htrb3tdcunpacker.h:193
 htrb3tdcunpacker.h:194
 htrb3tdcunpacker.h:195
 htrb3tdcunpacker.h:196
 htrb3tdcunpacker.h:197
 htrb3tdcunpacker.h:198
 htrb3tdcunpacker.h:199
 htrb3tdcunpacker.h:200