Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 74 additions & 19 deletions DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/RecPoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,20 @@
#include "Rtypes.h"
#include <TObject.h>
#include <gsl/span>

#include <string>
#include <utility>
#include <map>
namespace o2
{
namespace ft0
{

struct ChannelDataFloat {

int ChId = -1; //channel Id
int ChainQTC = -1; //QTC chain
float CFDTime = -20000; //time in ps, 0 at the LHC clk center
float QTCAmpl = -20000; // Amplitude mV
int ChId = -1; // channel Id
int ChainQTC = -1; // QTC chain
float CFDTime = -20000; // time in ps, 0 at the LHC clk center
float QTCAmpl = -20000; // Amplitude mV

ChannelDataFloat() = default;
ChannelDataFloat(int iPmt, float time, float charge, int chainQTC)
Expand All @@ -56,10 +58,39 @@ class RecPoints
{

public:
enum : int { TimeMean,
TimeA,
TimeC,
Vertex };
enum ETimeType { kTimeMean,
kTimeA,
kTimeC,
kTimeVertex };

// Enum for trigger nits specified in rec-points and AOD data
enum ETriggerBits { kOrA = 0, // OrA time-trigger signal
kOrC = 1, // OrC time-trigger signal
kSemiCentral = 2, // Semi-central amplitude-trigger signal
kCentral = 3, // Central amplitude-trigger signal
kVertex = 4, // Vertex time-trigger signal
kIsActiveSideA = 5, // Side-A has at least one channel active
kIsActiveSideC = 6, // Side-C has at least one channel active
kIsFlangeEvent = 7 // Flange event at Side-C, at least one channel has time which corresponds to -82 cm area
};
static const inline std::map<unsigned int, std::string> sMapTriggerBits = {
{ETriggerBits::kOrA, "OrA"},
{ETriggerBits::kOrC, "OrC"},
{ETriggerBits::kSemiCentral, "Semicentral"},
{ETriggerBits::kCentral, "Central"},
{ETriggerBits::kVertex, "Vertex"},
{ETriggerBits::kIsActiveSideA, "IsActiveSideA"},
{ETriggerBits::kIsActiveSideC, "IsActiveSideC"},
{ETriggerBits::kIsFlangeEvent, "IsFlangeEvent"}};

enum ETechnicalBits { kLaser = 0, // indicates the laser was triggered in this BC
kOutputsAreBlocked = 1, // indicates that laser-induced pulses should arrive from detector to FEE in this BC (and trigger outputs are blocked)
kDataIsValid = 2, // data is valid for processing
};
static const inline std::map<unsigned int, std::string> sMapTechnicalBits = {
{ETechnicalBits::kLaser, "Laser"},
{ETechnicalBits::kOutputsAreBlocked, "OutputsAreBlocked"},
{ETechnicalBits::kDataIsValid, "DataIsValid"}};

o2::dataformats::RangeReference<int, int> ref;
o2::InteractionRecord mIntRecord; // Interaction record (orbit, bc)
Expand All @@ -73,39 +104,63 @@ class RecPoints
mIntRecord = iRec;
mTriggers = chTrig;
}
RecPoints(int chDataFirstEntryPos,
int chDataNEntries,
const o2::InteractionRecord& ir,
const std::array<short, 4>& arrTimes,
const o2::fit::Triggers& digitTriggers,
uint8_t extraTriggerWord) : mIntRecord(ir), mCollisionTime(arrTimes), mTriggers(digitTriggers)
{
ref.setFirstEntry(chDataFirstEntryPos);
ref.setEntries(chDataNEntries);
initRecPointTriggers(digitTriggers, extraTriggerWord);
}

~RecPoints() = default;

short getCollisionTime(int side) const { return mCollisionTime[side]; }
short getCollisionTimeMean() const { return getCollisionTime(TimeMean); }
short getCollisionTimeA() const { return getCollisionTime(TimeA); }
short getCollisionTimeC() const { return getCollisionTime(TimeC); }
short getCollisionTimeMean() const { return getCollisionTime(kTimeMean); }
short getCollisionTimeA() const { return getCollisionTime(kTimeA); }
short getCollisionTimeC() const { return getCollisionTime(kTimeC); }
bool isValidTime(int side) const { return getCollisionTime(side) < o2::InteractionRecord::DummyTime; }
void setCollisionTime(short time, int side) { mCollisionTime[side] = time; }

short getVertex() const { return getCollisionTime(Vertex); }
void setVertex(short vertex) { mCollisionTime[Vertex] = vertex; }
short getVertex() const { return getCollisionTime(kTimeVertex); }
void setVertex(short vertex) { mCollisionTime[kTimeVertex] = vertex; }

o2::fit::Triggers getTrigger() const { return mTriggers; }
void setTriggers(o2::fit::Triggers trig) { mTriggers = trig; }
uint8_t getTechnicalWord() const { return mTechnicalWord; }
static constexpr uint8_t makeExtraTrgWord(bool isActiveA = true, bool isActiveC = true, bool isFlangeEvent = true)
{
return (static_cast<uint8_t>(isActiveA) << kIsActiveSideA) |
(static_cast<uint8_t>(isActiveC) << kIsActiveSideC) |
(static_cast<uint8_t>(isFlangeEvent) << kIsFlangeEvent);
}

o2::InteractionRecord getInteractionRecord() const { return mIntRecord; };

// void SetMgrEventTime(Double_t time) { mTimeStamp = time; }

gsl::span<const ChannelDataFloat> getBunchChannelData(const gsl::span<const ChannelDataFloat> tfdata) const;
short static constexpr sDummyCollissionTime = 32767;

void print() const;
bool operator==(const RecPoints&) const = default;

private:
void initRecPointTriggers(const o2::fit::Triggers& digitTriggers, uint8_t extraTrgWord = 0)
{
const auto digitTriggerWord = digitTriggers.getTriggersignals();
const auto trgAndTechWordPair = o2::fit::Triggers::parseDigitTriggerWord(digitTriggerWord, true);
mTriggers.setTriggers(trgAndTechWordPair.first | extraTrgWord);
mTechnicalWord = trgAndTechWordPair.second;
}

std::array<short, 4> mCollisionTime = {sDummyCollissionTime,
sDummyCollissionTime,
sDummyCollissionTime,
sDummyCollissionTime};
o2::fit::Triggers mTriggers; // pattern of triggers in this BC

ClassDefNV(RecPoints, 3);
uint8_t mTechnicalWord{0}; // field for keeping ETechnicalBits
ClassDefNV(RecPoints, 4);
};
} // namespace ft0
} // namespace o2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ class Triggers
{
return trgWord | (static_cast<uint64_t>(checkMinBiasFT0(trgWord)) << bitMinBias);
}
static constexpr std::pair<uint8_t, uint8_t> parseDigitTriggerWord(uint8_t digitWord, bool shiftTechBitsToBegin = false)
{
const uint8_t techWordMask = word(bitLaser, bitOutputsAreBlocked, bitDataIsValid);
const uint8_t shiftTechWordPos = shiftTechBitsToBegin ? bitLaser : 0;
return {(digitWord & (~techWordMask)), (digitWord & techWordMask) >> shiftTechWordPos};
}

bool getOrA() const { return (triggersignals & (1 << bitA)) != 0; }
bool getOrC() const { return (triggersignals & (1 << bitC)) != 0; } // only used by FT0/FDD (same bit as OrAOut in FV0)
Expand Down Expand Up @@ -104,6 +110,10 @@ class Triggers
timeA = atimeA;
timeC = atimeC;
}
void setTriggers(uint8_t trgsig)
{
triggersignals = trgsig;
}

void setTriggers(Bool_t isA, Bool_t isC, Bool_t isVrtx, Bool_t isCnt, Bool_t isSCnt, uint8_t chanA, uint8_t chanC, int32_t aamplA,
int32_t aamplC, int16_t atimeA, int16_t atimeC, Bool_t isLaser, Bool_t isOutputsAreBlocked, Bool_t isDataValid)
Expand Down
21 changes: 17 additions & 4 deletions Detectors/FIT/FT0/reconstruction/src/CollisionTimeRecoTask.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ RP CollisionTimeRecoTask::processDigit(const o2::ft0::Digit& digit,
constexpr int nMCPsA = 4 * Geometry::NCellsA;

int nch{0};
bool isActiveA = false;
bool isActiveC = false;
bool isFlangeEvent = false;

for (const auto& channelData : inChData) {
if (channelData.ChId >= NCHANNELS) {
// Reference channels shouldn't participate in reco at all!
Expand All @@ -68,15 +72,23 @@ RP CollisionTimeRecoTask::processDigit(const o2::ft0::Digit& digit,
outChData.emplace_back(channelData.ChId, timeInPS, (float)channelData.QTCAmpl, channelData.ChainQTC);
nch++;
}
const bool isOkForTimeCalc = TimeFilterParam::Instance().checkAll(channelData);
// only signals which satisfy conditions may participate in time calculation
if (TimeFilterParam::Instance().checkAll(channelData)) {
if (channelData.ChId < nMCPsA) {
if (channelData.ChId < nMCPsA) {
// A-side
if (isOkForTimeCalc) {
sideAtime += timeInPS;
ndigitsA++;
} else {
}
isActiveA = true;
} else {
// C-side
if (isOkForTimeCalc) {
sideCtime += timeInPS;
ndigitsC++;
}
isActiveC = true;
isFlangeEvent |= channelData.CFDTime < -350 && channelData.CFDTime > -450;
}
}
std::array<short, 4> mCollisionTime = {RP::sDummyCollissionTime, RP::sDummyCollissionTime, RP::sDummyCollissionTime, RP::sDummyCollissionTime};
Expand All @@ -90,7 +102,8 @@ RP CollisionTimeRecoTask::processDigit(const o2::ft0::Digit& digit,
} else {
mCollisionTime[TimeMean] = std::min(mCollisionTime[TimeA], mCollisionTime[TimeC]);
}
return RecPoints{mCollisionTime, firstEntry, nch, digit.mIntRecord, digit.mTriggers};
const uint8_t extraTrgWord = RecPoints::makeExtraTrgWord(isActiveA, isActiveC, isFlangeEvent);
return RecPoints(firstEntry, nch, digit.mIntRecord, mCollisionTime, digit.mTriggers, extraTrgWord);
}
//______________________________________________________
void CollisionTimeRecoTask::FinishTask()
Expand Down