9#include <cdc/modules/cdcUnpacker/CDCUnpackerModule.h>
11#include <cdc/dbobjects/CDCChannelMap.h>
13#include <framework/datastore/DataStore.h>
14#include <framework/datastore/RelationArray.h>
15#include <framework/logging/Logger.h>
16#include <framework/utilities/FileSystem.h>
18#include <framework/database/DBArray.h>
19#include <cdc/topology/CDCWireTopology.h>
72 if ((*m_channelMapFromDB).isValid()) {
75 B2FATAL(
"Channel map is not valid");
79 B2INFO(
"CDCUnpacker: initialize() Called.");
111 B2INFO(
"CDCUnpacker: beginRun() called.");
122 B2INFO(
"CDCUnpacker: event() started.");
147 const int nEntries =
m_rawCDCs.getEntries();
149 B2DEBUG(99,
"nEntries of RawCDCs : " << nEntries);
151 for (
int i = 0; i < nEntries; ++i) {
152 const int subDetectorId =
m_rawCDCs[i]->GetNodeID(0);
153 const int iNode = (subDetectorId & 0xFFFFFF);
154 const int nEntriesRawCDC =
m_rawCDCs[i]->GetNumEntries();
156 B2DEBUG(99,
LogVar(
"nEntries of rawCDC[i]", nEntriesRawCDC));
158 for (
int j = 0; j < nEntriesRawCDC; ++j) {
159 int trigType =
m_rawCDCs[i]->GetTRGType(j);
162 int MaxNumOfCh =
m_rawCDCs[i]->GetMaxNumOfCh(j);
164 if (MaxNumOfCh == 4) readoutName =
"COPPER";
165 else if (MaxNumOfCh == 48) readoutName =
"PCIe40";
167 B2FATAL(
"CDC UnpackerModule: Invalid value of GetMaxNumOfCh from raw data: " <<
LogVar(
"Number of ch: ",
170 for (
int k = 0; k < MaxNumOfCh; ++k) {
171 nWords[k] =
m_rawCDCs[i]->GetDetectorNwords(j, k);
172 if (MaxNumOfCh == 48 &&
m_rawCDCs[i]->CheckOnlineRemovedDataBit(j, k) ==
true) {
174 B2FATAL(
"The data is not removed for the bad channel (" << j <<
"," << k <<
") with error flag in ff55 trailer! ");
176 data32tab[k] = (
int*)
m_rawCDCs[i]->GetDetectorBuffer(j, k);
183 for (
int iFiness = 0; iFiness < MaxNumOfCh; ++iFiness) {
184 int* ibuf = data32tab[iFiness];
185 const int nWord = nWords[iFiness];
186 B2DEBUG(99,
LogVar(
"nWords (from " + readoutName +
" header)", nWord));
189 B2INFO(
"CDCUnpacker : Print out CDC data block.");
193 const int c_headearWords = 3;
194 if (nWord < c_headearWords) {
196 B2WARNING(
"CDCUnpacker : No CDC block header.");
202 B2INFO(
"CDCUnpacker : RawDataBlock(CDC) : Block # "
205 <<
LogVar(
"Finness", iFiness));
212 B2WARNING(
"Unrecoverable board " << std::hex <<
m_boardId);
218 const int swDataLength = dataLength * 2;
221 if (dataLength != (nWord - c_headearWords)) {
223 B2ERROR(
"Inconsistent data size between " + readoutName +
" and CDC FEE."
224 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
225 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
228 B2WARNING(
"Inconsistent data size between " + readoutName +
" and CDC FEE."
229 <<
LogVar(
"data length", dataLength) <<
LogVar(
"nWord", nWord)
230 <<
LogVar(
"Node ID", iNode) <<
LogVar(
"Finness ID", iFiness));
235 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Data size", dataLength));
243 B2INFO(
"CDCUnpacker : " <<
LogVar(
"Board", board) <<
LogVar(
"Trigger number", trgNumber)
244 <<
LogVar(
"Trigger time ", trgTime));
253 B2INFO(
"CDCUnpacker : Raw data mode.");
258 for (
int it = 0; it < dataLength; ++it) {
259 int index = it + c_headearWords;
261 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
262 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
265 const int fadcTdcChannels = 48;
266 const int nSamples = swDataLength / (2 * fadcTdcChannels);
268 std::vector<unsigned short> fadcs;
269 std::vector<unsigned short> tdcs;
271 if (
m_buffer.size() < fadcTdcChannels + 2 * fadcTdcChannels * nSamples)
continue;
273 for (
int iCh = 0; iCh < fadcTdcChannels; ++iCh) {
274 const int offset = fadcTdcChannels;
275 unsigned short fadcSum = 0;
276 unsigned short tdc1 = 0x7fff;
277 unsigned short tdc2 = 0x7fff;
279 for (
int iSample = 0; iSample < nSamples; ++iSample) {
282 unsigned short fadc =
m_buffer.at(iCh + 2 * fadcTdcChannels * iSample);
289 unsigned short tdc =
m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x7fff;
290 unsigned short tdcIsValid = (
m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x8000) >> 15;
291 if (tdcIsValid == 1) {
300 fadcs.push_back(fadc);
304 const unsigned short status = 0;
305 m_CDCRawHitWaveForms.appendNew(status, trgNumber, iNode, iFiness, board, iCh, iSample, trgTime, fadc, tdc);
310 if (tdc1 != 0x7fff) {
314 if (trgTime < tdc1) {
315 tdc1 = (trgTime | 0x8000) - tdc1;
317 tdc1 = trgTime - tdc1;
327 for (
int iSample = 0; iSample < nSamples; ++iSample) {
334 B2WARNING(
"Skip invalid wire board, channel: " << board <<
", " << iCh);
346 printf(
"FADC ch %2d : ", iCh);
347 for (
int iSample = 0; iSample < nSamples; ++iSample) {
348 printf(
"%4x ", fadcs.at(iSample));
352 printf(
"TDC ch %2d : ", iCh);
353 for (
int iSample = 0; iSample < nSamples; ++iSample) {
354 printf(
"%4x ", tdcs.at(iSample));
361 }
else if (dataType == 2) {
363 B2INFO(
"CDCUnpacker : Suppressed mode.");
368 for (
int it = 0; it < dataLength; ++it) {
369 int index = it + c_headearWords;
370 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
371 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
374 const size_t bufSize =
m_buffer.size();
375 for (
size_t it = 0; it < bufSize;) {
376 unsigned short header =
m_buffer.at(it);
377 unsigned short ch = (header & 0xff00) >> 8;
378 unsigned short length = (header & 0xff) / 2;
380 if (header == 0xff02) {
385 if (!((length == 4) || (length == 5))) {
387 B2ERROR(
"CDCUnpacker : data length should be 4 or 5 words."
388 <<
LogVar(
"data length", length)
389 <<
LogVar(
"board id", board)
390 <<
LogVar(
"channel", ch));
393 B2WARNING(
"CDCUnpacker : data length should be 4 or 5 words."
394 <<
LogVar(
"data length", length)
395 <<
LogVar(
"board id", board)
396 <<
LogVar(
"channel", ch));
401 if (it + 2 >= bufSize) {
402 B2ERROR(
"CDCUnpacker : buffer overrun it + 2"
403 <<
LogVar(
"data length from header", length)
404 <<
LogVar(
"actual data length", bufSize)
405 <<
LogVar(
"board id", board)
406 <<
LogVar(
"channel", ch));
409 unsigned short tot =
m_buffer.at(it + 1);
410 unsigned short fadcSum =
m_buffer.at(it + 2);
413 int diff = fadcSum - (*m_adcPedestalFromDB)->getPedestal(board, ch);
417 fadcSum =
static_cast<unsigned short>(diff);
420 unsigned short tdc1 = 0;
421 unsigned short tdc2 = 0;
422 unsigned short tdcFlag = 0;
425 if (it + 3 >= bufSize) {
426 B2ERROR(
"CDCUnpacker : buffer overrun it + 3"
427 <<
LogVar(
"data length from header", length)
428 <<
LogVar(
"actual data length", bufSize)
429 <<
LogVar(
"board id", board)
430 <<
LogVar(
"channel", ch));
434 }
else if (length == 5) {
435 if (it + 4 >= bufSize) {
436 B2ERROR(
"CDCUnpacker : buffer overrun it + 4"
437 <<
LogVar(
"data length from header", length)
438 <<
LogVar(
"actual data length", bufSize)
439 <<
LogVar(
"board id", board)
440 <<
LogVar(
"channel", ch));
444 tdc2 =
m_buffer.at(it + 4) & 0x7fff;
445 tdcFlag = (
m_buffer.at(it + 4) & 0x8000) >> 15;
447 B2ERROR(
"CDCUnpacker : Undefined data length (should be 4 or 5 short words) ");
451 B2WARNING(
"Invalid channel "
455 <<
LogVar(
"length", length)
465 printf(
"%4x %4x %4x %4x %4x %4x %4x \n", ch, length, tot, fadcSum, tdc1, tdc2, tdcFlag);
467 if (length == 4 || length == 5) {
470 const unsigned short status = trigType;
496 trgTime, fadcSum, tdc1, tdc2, tot);
502 m_CDCRawHits.appendNew(status, trgNumber, iNode, iFiness, board, ch,
503 trgTime, fadcSum, tdc1, tdc2, tot);
507 B2WARNING(
"Skip invalid wire board, channel: " << board <<
", " << ch);
510 B2WARNING(
"Undefined board id is fired: " <<
LogVar(
"board id", board) <<
" " <<
LogVar(
"channel", ch));
517 B2WARNING(
"CDCUnpacker : Undefined CDC Data Block : Block # " <<
LogVar(
"block id", i));
528 int tdc = hit.getTDCCount();
529 if (hit.is2ndHit()) {
538 hit.setTDCCount(
static_cast<unsigned short>(tdc));
546 B2INFO(
"CDCUnpacker : End run.");
553 B2INFO(
"CDCUnpacker : Terminated.");
563 return m_map[iBoard][iCh];
573 std::cout << fileName << std::endl;
574 if (fileName ==
"") {
575 B2ERROR(
"CDC unpacker can't find a filename: " <<
LogVar(
"file name", fileName));
581 ifs.open(fileName.c_str());
589 ifs >> isl >> icl >> iw >> iBoard >> iCh;
590 const WireID wireId(isl, icl, iw);
591 m_map[iBoard][iCh] = wireId;
595 const int isl = cm.getISuperLayer();
596 const int il = cm.getILayer();
597 const int iw = cm.getIWire();
598 const int iBoard = cm.getBoardID();
599 const int iCh = cm.getBoardChannel();
600 const WireID wireId(isl, il, iw);
601 m_map[iBoard][iCh] = wireId;
610 if (!(*m_adcPedestalFromDB).isValid()) {
620 for (
int j = 0; j < nwords; ++j) {
621 printf(
" %.8x", buf[j]);
622 if ((j + 1) % 10 == 0) {
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
void set2ndHitFlag()
Setter for 2nd hit flag.
void setOtherHitIndices(CDCHit *otherHit)
Setter for the other hit indices.
The CDCRawHit (suppressed mode) class.
StoreArray< RawCDC > m_rawCDCs
Input array for CDC Raw.
bool m_enableDatabase
Enable/Disable to read the channel map from the database.
int m_boardId
Front end board ID.
std::vector< unsigned short > m_buffer
Short ward buffer of CDC event block.
int m_channelTrig
Channel for the trigger.
bool m_dataSizeError
True if data size error between CDCFE and COPPER has been already reported.
std::string m_relCDCRawHitWFToCDCHitName
Relation name between CDCRawHitWaveForm and CDCHit.
std::string m_rawCDCName
Name of the RawCDC dataobject (suppressed mode).
void initialize() override
Initializes the Module.
DBArray< CDCChannelMap > * m_channelMapFromDB
Channel map retrieved from DB.
StoreArray< CDCRawHitWaveForm > m_CDCRawHitWaveForms
Raw hit waveforms.
std::string m_relCDCRawHitToCDCHitName
Relation name between CDCRawHit and CDCHit.
void printBuffer(int *buf, int nwords)
Print out the CDC data block in hex.
int getTriggerNumber()
Getter for trigger number.
void event() override
Event action (main routine).
StoreArray< CDCRawHit > m_CDCRawHits
Raw hits.
bool m_subtractTrigTiming
Enable/Disable to subtract the trigger timing from TDCs.
bool m_dataLengthError
True if data length error has been already reported.
void endRun() override
End run action.
void terminate() override
Termination action.
int m_fadcThreshold
FADC threshold.
int getTriggerTime()
Getter for trigger time in nsec.
int m_tdcOffset
TDC offset (nsec).
std::string m_xmlMapFileName
Name of the assignment map of FE board channel to the cell.
WireID m_map[300][48]
Assignment map of FE board channel to the cell.
int getDataType()
Getter for CDC data mode.
std::string m_cdcRawHitName
Name of the CDCRawHit dataobject (suppressed mode).
bool m_pedestalSubtraction
Whether pedestal is subtracted (true) or not (false).
void beginRun() override
Begin run action.
bool m_relationRawHits
True if add relation of CDCHits, CDCRawHits, and CDCRawHitWaveForms.
bool m_recoverBoardIdError
Recover boardID error if true, skip information otherwise.
DBObjPtr< CDCADCDeltaPedestals > * m_adcPedestalFromDB
ADC delta pedestal.
int m_boardIDTrig
Board ID for the trigger.
bool m_enableStoreCDCRawHit
Enable/Disable to store CDCRawHit.
int m_tdcAuxOffset
TDC auxiliary offset (nsec).
int getDataLength()
Getter for data length in byte.
void loadMap()
Load FE channel to cell ID map.
WireID getWireID(int iBoard, int iCh) const
Getter of Wire ID.
CDCUnpackerModule()
Constructor of the module.
bool m_enablePrintOut
Enable/Disable to print out the data to the terminal.
bool isValidBoardChannel(WireID wireId)
Check if the hit wire is valid or not.
std::string m_cdcRawHitWaveFormName
Name of the CDCRawHit dataobject (raw data mode).
void setCDCPacketHeader(const int *buf)
Set CDC Packet header.
virtual ~CDCUnpackerModule()
Destructor of the module.
bool m_enable2ndHit
Enable/Disable to 2nd hit output.
int getBoardId()
Getter for FE board ID.
std::string m_cdcHitName
Tree name of the CDCHit object.
void setADCPedestal()
Set DBobject of ADC delta pedestal.
StoreArray< CDCHit > m_CDCHits
CDC hits.
Class representing the sense wire arrangement in the whole of the central drift chamber.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
bool isValidWireID(const WireID &wireID) const
Checks the validity of a wireID convenience object.
Class for accessing arrays of objects in the database.
Class for accessing objects in the database.
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
static std::string arrayName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Low-level class to create/modify relations between StoreArrays.
Class to identify a wire inside the CDC.
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.