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 <tracking/trackFindingCDC/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 for (
int iCh = 0; iCh < fadcTdcChannels; ++iCh) {
272 const int offset = fadcTdcChannels;
273 unsigned short fadcSum = 0;
274 unsigned short tdc1 = 0x7fff;
275 unsigned short tdc2 = 0x7fff;
277 for (
int iSample = 0; iSample < nSamples; ++iSample) {
280 unsigned short fadc =
m_buffer.at(iCh + 2 * fadcTdcChannels * iSample);
287 unsigned short tdc =
m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x7fff;
288 unsigned short tdcIsValid = (
m_buffer.at(iCh + 2 * fadcTdcChannels * iSample + offset) & 0x8000) >> 15;
289 if (tdcIsValid == 1) {
298 fadcs.push_back(fadc);
302 const unsigned short status = 0;
303 m_CDCRawHitWaveForms.appendNew(status, trgNumber, iNode, iFiness, board, iCh, iSample, trgTime, fadc, tdc);
308 if (tdc1 != 0x7fff) {
312 if (trgTime < tdc1) {
313 tdc1 = (trgTime | 0x8000) - tdc1;
315 tdc1 = trgTime - tdc1;
325 for (
int iSample = 0; iSample < nSamples; ++iSample) {
332 B2WARNING(
"Skip invalid wire board, channel: " << board <<
", " << iCh);
344 printf(
"FADC ch %2d : ", iCh);
345 for (
int iSample = 0; iSample < nSamples; ++iSample) {
346 printf(
"%4x ", fadcs.at(iSample));
350 printf(
"TDC ch %2d : ", iCh);
351 for (
int iSample = 0; iSample < nSamples; ++iSample) {
352 printf(
"%4x ", tdcs.at(iSample));
359 }
else if (dataType == 2) {
361 B2INFO(
"CDCUnpacker : Suppressed mode.");
366 for (
int it = 0; it < dataLength; ++it) {
367 int index = it + c_headearWords;
368 m_buffer.push_back(
static_cast<unsigned short>((ibuf[index] & 0xffff0000) >> 16));
369 m_buffer.push_back(
static_cast<unsigned short>(ibuf[index] & 0xffff));
372 const size_t bufSize =
m_buffer.size();
373 for (
size_t it = 0; it < bufSize;) {
374 unsigned short header =
m_buffer.at(it);
375 unsigned short ch = (header & 0xff00) >> 8;
376 unsigned short length = (header & 0xff) / 2;
378 if (header == 0xff02) {
383 if (!((length == 4) || (length == 5))) {
385 B2ERROR(
"CDCUnpacker : data length should be 4 or 5 words."
386 <<
LogVar(
"data length", length)
387 <<
LogVar(
"board id", board)
388 <<
LogVar(
"channel", ch));
391 B2WARNING(
"CDCUnpacker : data length should be 4 or 5 words."
392 <<
LogVar(
"data length", length)
393 <<
LogVar(
"board id", board)
394 <<
LogVar(
"channel", ch));
399 unsigned short tot =
m_buffer.at(it + 1);
400 unsigned short fadcSum =
m_buffer.at(it + 2);
403 int diff = fadcSum - (*m_adcPedestalFromDB)->getPedestal(board, ch);
407 fadcSum =
static_cast<unsigned short>(diff);
410 unsigned short tdc1 = 0;
411 unsigned short tdc2 = 0;
412 unsigned short tdcFlag = 0;
416 }
else if (length == 5) {
418 tdc2 =
m_buffer.at(it + 4) & 0x7fff;
419 tdcFlag = (
m_buffer.at(it + 4) & 0x8000) >> 15;
421 B2ERROR(
"CDCUnpacker : Undefined data length (should be 4 or 5 short words) ");
425 B2WARNING(
"Invalid channel "
429 <<
LogVar(
"length", length)
439 printf(
"%4x %4x %4x %4x %4x %4x %4x \n", ch, length, tot, fadcSum, tdc1, tdc2, tdcFlag);
441 if (length == 4 || length == 5) {
444 const unsigned short status = trigType;
470 trgTime, fadcSum, tdc1, tdc2, tot);
476 m_CDCRawHits.appendNew(status, trgNumber, iNode, iFiness, board, ch,
477 trgTime, fadcSum, tdc1, tdc2, tot);
481 B2WARNING(
"Skip invalid wire board, channel: " << board <<
", " << ch);
484 B2WARNING(
"Undefined board id is fired: " <<
LogVar(
"board id", board) <<
" " <<
LogVar(
"channel", ch));
491 B2WARNING(
"CDCUnpacker : Undefined CDC Data Block : Block # " <<
LogVar(
"block id", i));
502 int tdc = hit.getTDCCount();
503 if (hit.is2ndHit()) {
512 hit.setTDCCount(
static_cast<unsigned short>(tdc));
520 B2INFO(
"CDCUnpacker : End run.");
527 B2INFO(
"CDCUnpacker : Terminated.");
537 return m_map[iBoard][iCh];
547 std::cout << fileName << std::endl;
548 if (fileName ==
"") {
549 B2ERROR(
"CDC unpacker can't find a filename: " <<
LogVar(
"file name", fileName));
555 ifs.open(fileName.c_str());
563 ifs >> isl >> icl >> iw >> iBoard >> iCh;
564 const WireID wireId(isl, icl, iw);
565 m_map[iBoard][iCh] = wireId;
569 const int isl = cm.getISuperLayer();
570 const int il = cm.getILayer();
571 const int iw = cm.getIWire();
572 const int iBoard = cm.getBoardID();
573 const int iCh = cm.getBoardChannel();
574 const WireID wireId(isl, il, iw);
575 m_map[iBoard][iCh] = wireId;
584 if (!(*m_adcPedestalFromDB).isValid()) {
594 for (
int j = 0; j < nwords; ++j) {
595 printf(
" %.8x", buf[j]);
596 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 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 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 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.