Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • le.koch/cbmroot
  • patrick.pfistner_AT_kit.edu/cbmroot
  • lena.rossel_AT_stud.uni-frankfurt.de/cbmroot
  • i.deppner/cbmroot
  • fweig/cbmroot
  • karpushkin_AT_inr.ru/cbmroot
  • v.akishina/cbmroot
  • rishat.sultanov_AT_cern.ch/cbmroot
  • l_fabe01_AT_uni-muenster.de/cbmroot
  • pwg-c2f/cbmroot
  • j.decuveland/cbmroot
  • a.toia/cbmroot
  • i.vassiliev/cbmroot
  • n.herrmann/cbmroot
  • o.lubynets/cbmroot
  • se.gorbunov/cbmroot
  • cornelius.riesen_AT_physik.uni-giessen.de/cbmroot
  • zhangqn17_AT_mails.tsinghua.edu.cn/cbmroot
  • bartosz.sobol/cbmroot
  • ajit.kumar/cbmroot
  • computing/cbmroot
  • a.agarwal_AT_vecc.gov.in/cbmroot
  • osingh/cbmroot
  • wielanek_AT_if.pw.edu.pl/cbmroot
  • malgorzata.karabowicz.stud_AT_pw.edu.pl/cbmroot
  • m.shiroya/cbmroot
  • s.roy/cbmroot
  • p.-a.loizeau/cbmroot
  • a.weber/cbmroot
  • ma.beyer/cbmroot
  • d.klein/cbmroot
  • d.smith/cbmroot
  • mvdsoft/cbmroot
  • d.spicker/cbmroot
  • y.h.leung/cbmroot
  • aksharma/cbmroot
  • m.deveaux/cbmroot
  • mkunold/cbmroot
  • h.darwish/cbmroot
  • pk.sharma_AT_vecc.gov.in/cbmroot
  • f_fido01_AT_uni-muenster.de/cbmroot
  • g.kozlov/cbmroot
  • d.emschermann/cbmroot
  • evgeny.lavrik/cbmroot
  • v.friese/cbmroot
  • f.uhlig/cbmroot
  • ebechtel_AT_ikf.uni-frankfurt.de/cbmroot
  • a.senger/cbmroot
  • praisig/cbmroot
  • s.lebedev/cbmroot
  • redelbach_AT_compeng.uni-frankfurt.de/cbmroot
  • p.subramani/cbmroot
  • a_meye37_AT_uni-muenster.de/cbmroot
  • om/cbmroot
  • o.golosov/cbmroot
  • l.chlad/cbmroot
  • a.bercuci/cbmroot
  • d.ramirez/cbmroot
  • v.singhal/cbmroot
  • h.schiller/cbmroot
  • apuntke/cbmroot
  • f.zorn/cbmroot
  • rubio_AT_physi.uni-heidelberg.de/cbmroot
  • p.chudoba/cbmroot
  • apuntke/mcbmroot
  • r.karabowicz/cbmroot
66 results
Show changes
Commits on Source (11)
Showing
with 451 additions and 294 deletions
......@@ -334,23 +334,10 @@ Bool_t CbmDeviceUnpack::InitContainers()
crob_map[i] = crob_map21[i];
}
else if (fuRunId >= 2335) {
const size_t nfasp0 = 72;
const size_t nfasps = 36;
uint8_t map22[] = {
84, 85, 86, 87, 88, 89, // FEB14/0xffc1
90, 91, 92, 93, 94, 95, // FEB17/0xffc1
96, 97, 98, 99, 100, 101, // FEB18/0xffc1
102, 103, 104, 105, 106, 107, // FEB16/0xffc1
72, 73, 74, 75, 76, 77, // FEB9/0xffc1
78, 79, 80, 81, 82, 83 // FEB8/0xffc1
};
for (uint32_t i(0); i < nfasps; i++)
map[i + nfasp0] = map22[i];
uint16_t crob_map22[] = {0xffc2, 0xffc5, 0xffc1, 0, 0};
for (uint32_t i(0); i < NCROBMOD; i++)
crob_map[i] = crob_map22[i];
}
trdfasp2dconfig->SetFaspMapping(5, map);
trdfasp2dconfig->SetCrobMapping(5, crob_map);
std::string parfilesbasepathTrdfasp2d = Form("%s/parameters/trd", srcDir.Data());
trdfasp2dconfig->SetParFilesBasePath(parfilesbasepathTrdfasp2d);
......
......@@ -39,11 +39,11 @@ CbmTrdCluster::CbmTrdCluster(const std::vector<int32_t>& indices, int32_t addres
}
//____________________________________________________________________
CbmTrdCluster::CbmTrdCluster(int32_t address, int32_t idx, int32_t ch, int32_t row, int32_t time)
CbmTrdCluster::CbmTrdCluster(int32_t address, int32_t idx, uint16_t chT, uint16_t chR, int32_t row, int32_t time)
: CbmCluster()
{
ReInit(address, row, time);
AddDigi(idx, ch);
AddDigi(idx, chT, chR);
}
//____________________________________________________________________
......@@ -62,42 +62,67 @@ CbmTrdCluster& CbmTrdCluster::operator=(const CbmTrdCluster& ref)
}
//____________________________________________________________________
bool CbmTrdCluster::AddDigi(int32_t idx, int32_t channel, int32_t terminator, int32_t dt)
bool CbmTrdCluster::AddChannel(bool r)
{
/** Extend basic functionality of CbmCluster::AddDigi().
* If channel>=0 add this info to channel map.
if (!r) {
if (!fStartCh) return false;
fStartCh--;
}
fNCols++;
return true;
}
//____________________________________________________________________
bool CbmTrdCluster::AddDigi(int32_t idx, uint16_t chT, uint16_t chR, int32_t dt)
{
/** Extend basic functionality of CbmCluster::AddDigi() for the case of 2D.
* If chT < 0 use the basic functionality [default].
*
* For the 2D the parameters are intergpreted as follows
* chT : tilted paired channel [default 0x0fffffff]
* chR : rectangular paired channel
* dt : offset in clks of the prompt signal
*
* if chT and chR positive the (chT, chR) are interpreted as the 2 channels
* of the digi specific to the 2D version. The following specific cases
* can be distinguished :
* - ch == 0 : no data, cluster signal sequence terminator
* - ch == -ch : no data, channel masked in HW
*/
if (channel < 0) { // basic functionality for rectangular pads
if (chT == 0xffff) { // basic functionality for rectangular pads
CbmCluster::AddDigi(idx);
return true;
}
if (channel >= 0xffff) LOG(warn) << GetName() << "::AddDigi: pad-channel truncated to 2bytes.";
uint16_t chMin = (chT != 0 ? chT : chR), chMax = (chR != 0 ? chR : chT);
// assume triangular pads only
if (!fNCols) { // first digi
fStartCh = channel;
fStartCh = chMin;
CbmCluster::AddDigi(idx);
if (terminator < 0) SetProfileStart();
else if (terminator > 0)
SetProfileStop();
}
else if (channel > GetEndCh()) { // digi @ end
if (HasOpenStop()) return false;
else if (chMin > GetEndCh()) { // digi @ end
//if (HasStop()) return false;
CbmCluster::AddDigi(idx);
if (terminator > 0) SetProfileStop();
}
else if (channel < fStartCh) { // digi @ beginning
if (HasOpenStart()) return false;
fStartCh = channel;
else if (chMax < fStartCh) { // digi @ beginning
//if (HasStart()) return false;
fStartCh = chMin;
vector<int32_t> vec = GetDigis();
ClearDigis();
CbmCluster::AddDigi(idx);
AddDigis(vec);
if (terminator < 0) SetProfileStart();
}
fNCols++;
int nch(0);
if (chT == 0) SetStart();
else
nch++;
if (chR == 0) SetStop();
else
nch++;
fNCols += nch;
if (dt > 0) fStartTime -= dt;
return true;
......@@ -122,45 +147,27 @@ void CbmTrdCluster::ReInit(int32_t address, int32_t row, int32_t time)
// check truncation
if (row >= 0x1f) LOG(warn) << GetName() << "::ReInit: pad-row truncated to 5bits.";
SetNRows(row);
SetProfileStart(0);
SetProfileStop(0);
SetStart(false);
SetStop(false);
if (std::abs(time) >= 0x7fffffff) LOG(warn) << GetName() << "::ReInit: buffer time truncated to 4bytes.";
fStartTime = time;
}
//____________________________________________________________________
int32_t CbmTrdCluster::IsChannelInRange(int32_t ch) const
int32_t CbmTrdCluster::IsChannelInRange(uint16_t chT, uint16_t chR) const
{
if (!fNCols) return -2;
// if(IsTerminatedLeft() && fAddressCh[0]>ch) return -1;
// if(IsTerminatedRight() && fAddressCh[clSize-1]<ch) return 1;
if (fStartCh > ch + 1) return -1;
if (fStartCh + fNCols < ch) return 1;
uint16_t chMin = (chT != 0 ? chT : chR), chMax = (chR != 0 ? chR : chT);
if (fStartCh > chMax + 1) return -1;
if (fStartCh + fNCols < chMin) return 1;
return 0;
}
//____________________________________________________________________
uint16_t CbmTrdCluster::GetSize() const
{
uint16_t size(0);
if (HasFaspDigis()) {
size = GetNCols() << 1;
if (HasOpenStart()) size--;
if (HasOpenStop()) size--;
if (size <= 0) {
LOG(warn) << GetName() << "::GetSize: Fasp cluster meta-info corrupt.";
std::cout << ToString();
return 0;
}
}
else
size = GetNCols();
return size;
}
//____________________________________________________________________
bool CbmTrdCluster::Merge(CbmTrdCluster* second, bool typ)
bool CbmTrdCluster::Merge(CbmTrdCluster* second)
{
if (GetRow() != second->GetRow()) return false;
// time difference condition
......@@ -170,8 +177,8 @@ bool CbmTrdCluster::Merge(CbmTrdCluster* second, bool typ)
else if (abs(int32_t(second->fStartTime - fStartTime)) > 20)
return false;
// look before current
if (second->fStartCh + second->fNCols == fStartCh && !second->HasOpenStop() && !HasOpenStart()) {
// cout<<"Merge before with "<<second->ToString();
if (second->fStartCh + second->fNCols == fStartCh) {
// std::cout<<"Merge before with "<<second->ToString();
fStartCh = second->fStartCh;
fNCols += second->fNCols;
fStartTime = std::min(fStartTime, second->fStartTime);
......@@ -180,47 +187,19 @@ bool CbmTrdCluster::Merge(CbmTrdCluster* second, bool typ)
ClearDigis();
AddDigis(second->GetDigis());
AddDigis(vec);
if (second->HasOpenStart()) SetProfileStart();
if (second->HasStart()) SetStart();
return true;
}
// special care for clusters which can be merged also on pairing neighboring on 2D read-out
if (typ) {
if ((second->fStartCh + second->fNCols - 1 == fStartCh) && second->HasOpenStop()
&& HasOpenStart()) { // need to merge digi
fStartCh = second->fStartCh;
fNCols += second->fNCols - 1;
fStartTime = std::min(fStartTime, second->fStartTime);
vector<int32_t> vec = GetDigis();
ClearDigis();
AddDigis(second->GetDigis());
AddDigis(vec);
SetProfileStart(false);
return true;
}
}
// look after current
if (fStartCh + fNCols == second->fStartCh && !HasOpenStop() && !second->HasOpenStart()) {
// cout<<"Merge after with "<<second->ToString();
if (fStartCh + fNCols == second->fStartCh) {
// std::cout<<"Merge after with "<<second->ToString();
fNCols += second->fNCols;
fStartTime = std::min(fStartTime, second->fStartTime);
AddDigis(second->GetDigis());
if (second->HasOpenStop()) SetProfileStop();
if (second->HasStop()) SetStop();
return true;
}
// special care for clusters which can be merged also on pairing neighboring on 2D read-out
if (typ) {
if ((fStartCh + fNCols - 1 == second->fStartCh) && HasOpenStop() && second->HasOpenStart()) { // need to merge digi
fNCols += second->fNCols - 1;
fStartTime = std::min(fStartTime, second->fStartTime);
AddDigis(second->GetDigis());
SetProfileStop(false);
return true;
}
}
return false;
}
......@@ -231,10 +210,10 @@ string CbmTrdCluster::ToString() const
ss << CbmCluster::ToString();
ss << "CbmTrdCluster: mod=" << GetAddress() << " row=" << (int32_t) GetRow() << " "
<< (HasFaspDigis() ? "Fasp_" : "Spadic_") << "Chs=";
ss << (HasOpenStart() ? "/" : "|");
ss << (HasStart() ? "|" : "/");
for (int32_t i(0); i < fNCols; i++)
ss << fStartCh + i << " ";
ss << (HasOpenStop() ? "\\" : "|");
ss << (HasStop() ? "|" : "/");
ss << endl;
return ss.str();
}
......
......@@ -30,9 +30,9 @@ public:
{
kFasp = 5 ///< set type of FEE digis contained
,
kProfileStart ///< only for triangular if no T in first col
kStart ///< only for triangular if no T in first col
,
kProfileStop ///< only for triangular if no R in last col
kStop ///< only for triangular if no R in last col
};
/**
* \brief Default constructor.
......@@ -41,14 +41,15 @@ public:
CbmTrdCluster(const CbmTrdCluster& ref);
CbmTrdCluster(const std::vector<int32_t>& indices, int32_t address);
/**
* \brief Constructor starting from first digit.
* \brief Constructor starting from first digit (FASP specific).
* \param[in] address global module address
* \param[in] idx global digi index in the TClonesArray
* \param[in] ch RO channel address within the module
* \param[in] chT RO channel address within the module for tilt pairing
* \param[in] chR RO channel address within the module for rect pairing
* \param[in] r module row for the RO channel
* \param[in] time relative buffer DAQ time
*/
CbmTrdCluster(int32_t address, int32_t idx, int32_t ch, int32_t r, int32_t time);
CbmTrdCluster(int32_t address, int32_t idx, uint16_t chT, uint16_t chR, int32_t r, int32_t time);
/**
* \brief Destructor.
*/
......@@ -56,14 +57,19 @@ public:
CbmTrdCluster& operator=(const CbmTrdCluster& ref);
/** \brief Append a channel to cluster edge. The usage is to account for the masked channels.
* The mask status is assumed to be performed in the calling function.
* \param[in] r by default apply to the right edge. If false apply to left
*/
bool AddChannel(bool r = true);
/** \brief Append digi to cluster
* \param[in] idx index of digi in TClonesArray
* \param[in] channel RO channel for digi
* \param[in] terminator state of digi for triangular pads: 0 if complete, -/+ if T/R misses
* \param[in] chT RO channel for digi (tilt pairing for FASP) default 0xffff (SPADIC)
* \param[in] chR RO channel for rect pairing (only for FASP)
* \param[in] dt update start time of cluster if current digi is prompt
* \return true if successful
*/
bool AddDigi(int32_t idx, int32_t channel = -1, int32_t terminator = 0, int32_t dt = 0);
bool AddDigi(int32_t idx, uint16_t chT = 0xffff, uint16_t chR = 0, int32_t dt = 0);
/** \brief reset cluster data*/
void Clear(Option_t*);
/** Accessors **/
......@@ -71,24 +77,25 @@ public:
uint16_t GetNRows() const { return fNRows & 0x1f; }
uint16_t GetEndCh() const { return fStartCh + fNCols - 1; }
uint16_t GetRow() const { return GetNRows(); }
uint16_t GetSize() const;
uint16_t GetSize() const { return GetNCols(); }
uint16_t GetStartCh() const { return fStartCh; }
uint32_t GetStartTime() const { return fStartTime; }
bool HasFaspDigis() const { return TESTBIT(fNRows, kFasp); }
bool HasOpenStart() const { return TESTBIT(fNRows, kProfileStart); }
bool HasOpenStop() const { return TESTBIT(fNRows, kProfileStop); }
bool HasStart() const { return TESTBIT(fNRows, kStart); }
bool HasStop() const { return TESTBIT(fNRows, kStop); }
/** \brief Query on RO channel list
* \param[in] channel RO channel for digi
/** \brief Query on RO channels list
* \param[in] chT tilted RO channel for digi
* \param[in] chR rectangular RO channel for digi
* \return -1 before range; 0 in range; 1 after range; -2 cluster empty of digits
*/
int32_t IsChannelInRange(int32_t ch) const;
int32_t IsChannelInRange(uint16_t chT, uint16_t chR) const;
/** \brief Merge current cluster with info from second
* \param[in] second cluster to be added
* \param[in] typ the type of pad-plane of the source chamber; true if Trd2d
* \return success or fail
*/
bool Merge(CbmTrdCluster* second, bool typ = true);
bool Merge(CbmTrdCluster* second);
/** \brief Initialize basic parameters of the cluster
* \param[in] address global module address
* \param[in] row cluster row in the module
......@@ -103,8 +110,8 @@ public:
fNRows |= (nrows & 0x1f);
}
void SetFaspDigis(bool set = true) { set ? SETBIT(fNRows, kFasp) : CLRBIT(fNRows, kFasp); }
void SetProfileStart(bool set = true) { set ? SETBIT(fNRows, kProfileStart) : CLRBIT(fNRows, kProfileStart); }
void SetProfileStop(bool set = true) { set ? SETBIT(fNRows, kProfileStop) : CLRBIT(fNRows, kProfileStop); }
void SetStart(bool set = true) { set ? SETBIT(fNRows, kStart) : CLRBIT(fNRows, kStart); }
void SetStop(bool set = true) { set ? SETBIT(fNRows, kStop) : CLRBIT(fNRows, kStop); }
/** \brief Extended functionality*/
virtual std::string ToString() const;
......
......@@ -4,6 +4,10 @@
#include "CbmTrdModuleAbstract.h"
#include "CbmTrdParAsic.h"
#include <Logger.h>
//_______________________________________________________________________________
CbmTrdModuleAbstract::CbmTrdModuleAbstract()
: TNamed()
......@@ -40,6 +44,15 @@ CbmTrdModuleAbstract::~CbmTrdModuleAbstract()
if (fAsicPar) delete fAsicPar;
}
//_______________________________________________________________________________
bool CbmTrdModuleAbstract::IsChannelMasked(int ch) const
{
if (!fAsicPar) return false;
const CbmTrdParAsic* p = fAsicPar->GetAsicPar(ch);
if (!p) return false;
return p->IsChannelMasked(ch);
}
//_______________________________________________________________________________
void CbmTrdModuleAbstract::LocalToMaster(Double_t in[3], Double_t out[3])
{
......
......@@ -73,6 +73,11 @@ public:
*/
bool Has2dPadPlane() const { return TESTBIT(fModConfig, eCbmTrdModuleDef::kTrd2d); }
/** \brief Inquire the ASIC par set
* \return true for actively masked channel
*/
bool IsChannelMasked(int ch) const;
virtual void LocalToMaster(Double_t in[3], Double_t out[3]);
virtual void SetAsicPar(CbmTrdParSetAsic* p = nullptr) { fAsicPar = p; }
......
......@@ -45,6 +45,7 @@ public:
virtual Int_t GetNchannels() const = 0;
virtual Int_t GetFebGrouping() const { return fFebGrouping; }
virtual std::vector<Int_t> GetChannelAddresses() const { return fChannelAddresses; }
virtual bool IsChannelMasked(int) const { return false; }
virtual void LoadParams(FairParamList*) { ; }
virtual void Print(Option_t* opt = "") const;
/** \brief Query ASIC for specific pad address
......
......@@ -38,15 +38,22 @@ const CbmTrdParFaspChannel* CbmTrdParFasp::GetChannel(Int_t ch_address) const
return &fCalib[ch_address];
}
//___________________________________________________________________
bool CbmTrdParFasp::IsChannelMasked(int chId) const
{
if (chId < 0 || chId >= NFASPCH) return false;
return fCalib[chId].IsMasked();
}
//___________________________________________________________________
void CbmTrdParFasp::LoadParams(FairParamList* l)
{
printf("CbmTrdParFasp::LoadParams(FairParamList*)\n");
// printf("CbmTrdParFasp::LoadParams(FairParamList*)\n");
TArrayI value(NFASPCH);
if (l->fill(Form("%dCHS", fAddress), &value)) {
for (Int_t ich(0); ich < NFASPCH; ich++) {
Int_t pair = ich % 2;
printf(" ch[%2d] pair[%d] value[%d] ChAddress=%d\n", ich, pair, value[ich], 2 * value[ich] + pair);
// printf(" ch[%2d] pair[%d] value[%d] ChAddress=%d\n", ich, pair, value[ich], 2 * value[ich] + pair);
SetChannelAddress(2 * value[ich] + pair);
fCalib[ich].SetPairing(pair);
}
......@@ -62,16 +69,16 @@ void CbmTrdParFasp::LoadParams(FairParamList* l)
fCalib[ich].fMinDelaySignal = value[ich];
}
void CbmTrdParFasp::LoadParams(TArrayI& valArray, Int_t iAsic)
//___________________________________________________________________
void CbmTrdParFasp::LoadParams(int* valArray)
{
// Where does the asic info start in large array
Int_t offset = iAsic * (1 + NFASPCH * 4);
// Int_t asicAddress = valArray[ offset++ ];
offset++;
// printf("CbmTrdParFasp::LoadParams(%d)\n", fAddress);
int offset(0);
SetChannelMask(valArray[offset++]);
for (Int_t ich(0); ich < NFASPCH; ich++) {
Int_t pair = ich % 2; // TODO pairing should be set from the external parameters
SetChannelAddress(valArray[offset++]);
fCalib[ich].SetPairing(pair);
int chAddress = valArray[offset++];
SetChannelAddress(abs(chAddress));
fCalib[ich].SetPairing(bool(chAddress > 0));
}
for (Int_t ich(0); ich < NFASPCH; ich++) {
fCalib[ich].fPileUpTime = valArray[offset++];
......@@ -107,6 +114,26 @@ Bool_t CbmTrdParFasp::SetCalibParameters(Int_t ch, Double_t const* par)
return kTRUE;
}
//___________________________________________________________________
void CbmTrdParFasp::SetChannelMask(uint32_t mask)
{
for (Int_t ich(0); ich < NFASPCH; ich++) {
bool on = !bool((mask >> ich) & 0x1);
fCalib[ich].SetMask(on);
}
}
//___________________________________________________________________
uint32_t CbmTrdParFasp::GetChannelMask() const
{
uint32_t mask(0);
for (Int_t ich(0); ich < NFASPCH; ich++) {
if (!fCalib[ich].IsMasked()) mask |= 0x1;
mask <<= 1;
}
return mask;
}
//___________________________________________________________________
void CbmTrdParFasp::Print(Option_t* opt) const
{
......@@ -133,8 +160,8 @@ CbmTrdParFaspChannel::CbmTrdParFaspChannel(Int_t pup, Int_t ft, Int_t thr, Int_t
//___________________________________________________________________
void CbmTrdParFaspChannel::Print(Option_t* /*opt*/) const
{
printf("[%c]; CALIB { PUT[ns]=%3d FT[clk]=%2d THR[ADC]=%4d MDS[ADC]=%4d }\n", (HasPairingR() ? 'R' : 'T'),
fPileUpTime, fFlatTop, fThreshold, fMinDelaySignal);
printf("[%c]; MASK{%c}; CALIB{ PUT[ns]=%3d FT[clk]=%2d THR[ADC]=%4d MDS[ADC]=%4d }\n", (HasPairingR() ? 'R' : 'T'),
(IsMasked() ? 'X' : ' '), fPileUpTime, fFlatTop, fThreshold, fMinDelaySignal);
}
ClassImp(CbmTrdParFasp);
......
......@@ -9,6 +9,9 @@
#define NCROBMOD 5
#define NFASPCROB NFASPMOD / NCROBMOD
#define NFASPCH 16
// The size of the parameter translation is calculated as follows:
// size = detId + chMask + NFASPCH*(chAddress + pileUp + threshold + delay)
#define NFASPPARS 2 + 4 * NFASPCH
#define FASP_EPOCH_LENGTH 128
......@@ -33,6 +36,8 @@ public:
enum CbmTrdParFaspChannelDef
{
kPair = 0 //< pad pairing type definition see SetPairing()
,
kMask = 1 //< pad masking. See SetMask()
};
/** \brief Parametrization of a FASP channel based on CADENCE simulations from 12.01.2018 and
* parabolic parametrization of dt(signal).
......@@ -48,12 +53,15 @@ public:
/** \brief Query pad pairing type.*/
Bool_t HasPairingR() const { return TESTBIT(fConfig, kPair); }
Bool_t HasPairingT() const { return !TESTBIT(fConfig, kPair); }
bool IsMasked() const { return TESTBIT(fConfig, kMask); }
void Print(Option_t* opt = "") const;
/** \brief Specify pad pairing type.
*\param[in] rect if rect=kTRUE rectangular pairing; tilt otherwise
*/
void SetPairing(Bool_t rect) { rect ? SETBIT(fConfig, kPair) : CLRBIT(fConfig, kPair); }
/** \brief Mask channel for processing.*/
void SetMask(Bool_t set) { set ? SETBIT(fConfig, kMask) : CLRBIT(fConfig, kMask); }
protected:
UShort_t fPileUpTime; ///< Signal formation time in ns
......@@ -76,25 +84,39 @@ class CbmTrdParFasp : public CbmTrdParAsic {
public:
CbmTrdParFasp(Int_t address = 0, Int_t FebGrouping = -1, Double_t x = 0, Double_t y = 0, Double_t z = 0);
virtual ~CbmTrdParFasp() { ; }
/** \brief Query the calibration for one FASP RO channel
* \param pad_address the index of the pad on the module [row*ncol+col]
* \param pair 0 for tilt and 1 for rect
*/
const CbmTrdParFaspChannel* GetChannel(Int_t pad_address, UChar_t pair) const;
const CbmTrdParFaspChannel* GetChannel(Int_t ch_address) const;
/** \brief Query the calibration for one FASP RO channel
* \param chId the index of the channel in the current FASP [0 - 15]
*/
const CbmTrdParFaspChannel* GetChannel(Int_t chId) const;
virtual Int_t GetNchannels() const { return NFASPCH; };
virtual Int_t GetChannelAddress(Int_t ich) const
/** \brief Return the global RO channel for curent FASP and channel index
* \param chId the index of the channel in the current FASP [0 - 15]
*/
virtual Int_t GetChannelAddress(Int_t chId) const
{
return ((ich < 0 || ich >= GetNchannels()) ? 0 : fChannelAddresses[ich]);
return ((chId < 0 || chId >= GetNchannels()) ? 0 : fChannelAddresses[chId]);
}
Int_t GetPadAddress(Int_t ich) const { return 0.5 * GetChannelAddress(ich); }
virtual uint32_t GetChannelMask() const;
virtual bool IsChannelMasked(int ch) const;
int GetPadAddress(Int_t ich) const { return int(0.5 * GetChannelAddress(ich)); }
Double_t GetSizeX() const { return fgSizeX; }
Double_t GetSizeY() const { return fgSizeY; }
Double_t GetSizeZ() const { return fgSizeZ; }
virtual void LoadParams(FairParamList* l);
void LoadParams(TArrayI&, Int_t);
/** \brief Load ASIC parameters from param file. Called from e.g. CbmTrdParSetAsic*/
void LoadParams(int* vals);
virtual void Print(Option_t* opt = "") const;
/** \brief Load FASP calibration parameters for a specific channel
*\param ch Address of the channel inside FASP
*\param par pointer to the list of parameters
*/
virtual Bool_t SetCalibParameters(Int_t ch, Double_t const* par);
virtual void SetChannelMask(uint32_t mask);
private:
static Double_t fgSizeX; ///< FASP half size in x [cm]
......
......@@ -4,6 +4,7 @@
#include "CbmTrdParSetAsic.h"
#include "CbmTrdDigi.h" // for eCbmTrdAsicType
#include "CbmTrdParAsic.h" // for CbmTrdParAsic
#include "CbmTrdParFasp.h" // for CbmTrdParFasp, NFASPCH, CbmTrdParFasp...
#include "CbmTrdParMod.h" // for CbmTrdParMod
......@@ -14,7 +15,10 @@
#include <TArrayI.h> // for TArrayI
#include <TGenericClassInfo.h> // for TGenericClassInfo
#include <TObjArray.h>
#include <TObjString.h>
#include <TString.h> // for Form
#include <TSystem.h>
#include <utility> // for pair
......@@ -79,19 +83,18 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
new CbmTrdParSetAsic(GetName(), Form("%s for Module %d", GetTitle(), moduleId[i]) /*, GetContext()*/);
// only for FASP
if (9 == typeAsic[i]) {
Int_t sizePerFasp = 1 + NFASPCH * 4;
Int_t maxValues = maxNrAsics * (sizePerFasp);
Int_t maxValues = maxNrAsics * (NFASPPARS);
TArrayI values(maxValues);
if (!l->fill(Form("FaspInfo - Module %d", moduleId[i]), &values)) continue;
for (Int_t iasic = 0; iasic < nAsic[i]; iasic++) {
Int_t offset = iasic * (sizePerFasp);
address = values[offset + 0];
Int_t offset = iasic * (NFASPPARS);
address = values[offset++];
if (address == moduleId[i] * 1000 + 999) continue;
asic = new CbmTrdParFasp(address);
static_cast<CbmTrdParFasp*>(asic)->LoadParams(values, iasic);
static_cast<CbmTrdParFasp*>(asic)->LoadParams(&(values.GetArray()[offset]));
fModPar[moduleId[i]]->SetAsicPar(address, asic);
}
fModPar[moduleId[i]]->SetAsicType(1);
fModPar[moduleId[i]]->SetAsicType((int) CbmTrdDigi::eCbmTrdAsicType::kFASP);
}
else {
Int_t maxValues = maxNrAsics * (5 + NSPADICCH);
......@@ -111,7 +114,7 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
asic->SetChannelAddresses(addresses);
fModPar[moduleId[i]]->SetAsicPar(address, asic);
}
fModPar[moduleId[i]]->SetAsicType(0);
fModPar[moduleId[i]]->SetAsicType((int) CbmTrdDigi::eCbmTrdAsicType::kSPADIC);
}
}
return kTRUE;
......@@ -177,29 +180,28 @@ void CbmTrdParSetAsic::putParams(FairParamList* l)
l->add(Form("SpadicInfo - Module %d", moduleId[i]), asicInfo);
}
if (mod->fModuleMap.begin()->second->IsA() == CbmTrdParFasp::Class()) {
Int_t sizePerFasp = 1 + NFASPCH * 4;
Int_t fullSize = nAsic[i] * sizePerFasp;
Int_t fullSize = nAsic[i] * NFASPPARS;
TArrayI asicInfo(fullSize);
iAsicNr = 0;
for (auto iModuleIt : mod->fModuleMap) {
int offset = iAsicNr * sizePerFasp;
asicInfo[offset] = iModuleIt.first;
int offset = iAsicNr * NFASPPARS;
asicInfo[offset++] = iModuleIt.first;
CbmTrdParFasp* fasp = (CbmTrdParFasp*) iModuleIt.second;
asicInfo[offset++] = fasp->GetChannelMask();
Int_t ich(0);
for (auto chAddress : fasp->GetChannelAddresses()) {
asicInfo[offset + 1 + ich] = chAddress;
asicInfo[offset + ich] = chAddress;
const CbmTrdParFaspChannel* ch = fasp->GetChannel(ich);
if (!ch) {
LOG(info) << "Missing calib for Fasp[" << offset << "] pad " << chAddress;
ich++;
continue;
}
asicInfo[offset + 1 + (1 * NFASPCH) + ich] = ch->GetPileUpTime();
asicInfo[offset + 1 + (2 * NFASPCH) + ich] = ch->GetThreshold();
asicInfo[offset + 1 + (3 * NFASPCH) + ich] = ch->GetMinDelaySignal();
asicInfo[offset + (1 * NFASPCH) + ich] = ch->GetPileUpTime();
asicInfo[offset + (2 * NFASPCH) + ich] = ch->GetThreshold();
asicInfo[offset + (3 * NFASPCH) + ich] = ch->GetMinDelaySignal();
ich++;
}
iAsicNr++;
......
......@@ -18,6 +18,12 @@ class FairParamList;
/**
* \brief Describe TRD module ASIC settings (electronic gain, delays, etc)
*
* The following concepts are used :
* - DAQ id : unique id of an ASIC composed of the format modId*1000+asicId.
* - modId : is calculated according to the CbmTrdAddress::GetModuleId().
* - asicId : uniquely identify the ASICs in one module.
* - chAddress : identify the read-out pad(s) connected to the ASIC. In the case of FASP it distinguish between R and T pairing
**/
class CbmTrdParSetAsic : public CbmTrdParSet {
public:
......@@ -30,22 +36,70 @@ public:
/** \brief Reset all parameters **/
virtual void clear() { ; }
/** \brief Add ASIC par to the current module
* It applies to the list of ASICs.
* \param mod ASIC par (FASP or SPADIC)
*/
virtual void addParam(CbmTrdParMod* mod);
/** \brief Add Module list of ASIC par to the setup list
* It applies to the list of lists.
* \param module list
*/
void AddParameters(CbmTrdParSetAsic*); // (VF) renamed to avoid shadowing of virtual method
/** \brief Build the ASICs par for the current module from the info stored in the param file
* It applies to the list of ASICs.
* \param module ASICs par (FASP or SPADIC)
*/
Bool_t getParams(FairParamList*);
/** \brief Store the ASICs par info for the current module into the param file
* It applies to the list of ASICs.
* \param module ASICs par (FASP or SPADIC)
*/
void putParams(FairParamList*);
/** \brief Query the ASICs in the module for their DAQ address.
* It applies to the list of ASICs.
* Returns the list of id of the ASICs within the module.
*/
virtual void GetAsicAddresses(std::vector<Int_t>* a) const;
/** \brief Look for the ASIC which operates on a specific channel
*\param chAddress Address of the channel
* It applies to the list of ASICs.
*\param chAddress Pad address of the channel
*\return id of the ASIC operating on the channel. -1 in case of failure
*/
virtual Int_t GetAsicAddress(Int_t chAddress) const;
/** \brief Look for the ASIC parameters of a given DAQ id
* It applies to the list of ASICs.
* \param address ASIC address from DAQ
* \return A read-only pointer to the parameters
*/
virtual const CbmTrdParAsic* GetAsicPar(Int_t address) const { return (CbmTrdParAsic*) GetModulePar(address); }
/** \brief Look for the ASIC parameters of a given DAQ id
* It applies to the list of ASICs.
* \param address ASIC address from DAQ
* \return A read-write pointer to the parameters
*/
virtual CbmTrdParAsic* GetAsicPar(Int_t address) { return (CbmTrdParAsic*) GetModulePar(address); }
/** \brief Query the type of ASICs in the list
* It applies to the list of ASICs.
*/
virtual Int_t GetAsicType() const { return fType; }
/** \brief Returns the set of ASIC pars corresponding to a whole module
* It applies to the list of lists.
* \param detId module Identifier in the CBM geometry
*/
virtual const CbmTrdParSet* GetModuleSet(Int_t detId) const;
/** \brief Returns the number of ASICs for the current module
* It applies to the list of ASICs.
*/
virtual Int_t GetNofAsics() const { return GetNrOfModules(); }
virtual void Print(Option_t* opt = "") const;
/** \brief Initialize the ASIC parameters for DAQ id
* It applies to the list of ASICs.
* \param address DAQ id of the ASIC in the current module
*/
virtual void SetAsicPar(Int_t address, CbmTrdParAsic* p);
virtual void SetAsicType(Int_t t) { fType = t; }
......
......@@ -331,23 +331,10 @@ void run_unpack_tsa(std::vector<std::string> infile = {"test.tsa"}, UInt_t runid
crob_map[i] = crob_map21[i];
}
else if (runid >= 2335) {
const size_t nfasp0 = 72;
const size_t nfasps = 36;
uint8_t map22[] = {
84, 85, 86, 87, 88, 89, // FEB14/0xffc1
90, 91, 92, 93, 94, 95, // FEB17/0xffc1
96, 97, 98, 99, 100, 101, // FEB18/0xffc1
102, 103, 104, 105, 106, 107, // FEB16/0xffc1
72, 73, 74, 75, 76, 77, // FEB9/0xffc1
78, 79, 80, 81, 82, 83 // FEB8/0xffc1
};
for (uint32_t i(0); i < nfasps; i++)
map[i + nfasp0] = map22[i];
uint16_t crob_map22[] = {0xffc2, 0xffc5, 0xffc1, 0, 0};
for (uint32_t i(0); i < NCROBMOD; i++)
crob_map[i] = crob_map22[i];
}
trdfasp2dconfig->SetFaspMapping(5, map);
trdfasp2dconfig->SetCrobMapping(5, crob_map);
std::string parfilesbasepathTrdfasp2d = Form("%s/parameters/trd", srcDir.Data());
trdfasp2dconfig->SetParFilesBasePath(parfilesbasepathTrdfasp2d);
......
......@@ -79,12 +79,24 @@ Bool_t CbmTrdClusterFinder::AddCluster(CbmTrdCluster* c)
// ---- addDigisToModules ----
UInt_t CbmTrdClusterFinder::addDigisToModules()
{
const int NDIGICHUNK = 100; // force flush of cluster buffer once every NDIGICHUNK digi to avoid memory exhaustion
UInt_t ndigis = static_cast<UInt_t>(std::abs(CbmDigiManager::Instance()->GetNofDigis(ECbmModuleId::kTrd)));
if (ndigis == 0) return 0;
for (size_t idigi = 0; idigi < ndigis; idigi++) {
int jdigi(0);
for (size_t idigi(0); idigi < ndigis; idigi++) {
addDigiToModule(idigi);
// once in a while dump finished clusters
// TODO ad hoc condition. Maybe a find a better one
if (jdigi >= NDIGICHUNK) {
processDigisInModules(jdigi, nullptr, false);
jdigi = 0;
}
else
jdigi++;
}
return ndigis;
return jdigi;
}
// ---- addDigisToModules ----
......@@ -118,14 +130,16 @@ void CbmTrdClusterFinder::addDigiToModule(UInt_t digiIdx)
}
// ---- processDigisInModules ----
void CbmTrdClusterFinder::processDigisInModules(UInt_t ndigis, CbmEvent* event)
void CbmTrdClusterFinder::processDigisInModules(UInt_t ndigis, CbmEvent* event, bool clr)
{
// printf("AB :: processDigisInModules(%d, %p) clr[%c]\n", ndigis, (void*) event, (clr?'Y':'N'));
CbmTrdModuleRec* mod(NULL);
Int_t digiCounter(0), clsCounter(0);
for (std::map<Int_t, CbmTrdModuleRec*>::iterator imod = fModules.begin(); imod != fModules.end(); imod++) {
mod = imod->second;
digiCounter += mod->GetOverThreshold();
clsCounter += mod->FindClusters();
clsCounter += mod->FindClusters(event || clr);
AddClusters(mod->GetClusters(), event, kTRUE);
}
......
......@@ -187,10 +187,11 @@ private:
/**
* @brief Call the clusterizer function of each module
*
* @param ndigis
* @param event
* @param ndigis total number of digis processed
* @param event link to digi event in case event-by-event reco is activated
* @param clr force clear clusters buffers
*/
void processDigisInModules(UInt_t ndigis, CbmEvent* event = nullptr);
void processDigisInModules(UInt_t ndigis, CbmEvent* event = nullptr, bool clr = true);
/**
* @brief Adds the module corresponding to the address of the passed digi to the ModuleMap (fModules)
......
......@@ -45,7 +45,7 @@ public:
/**
* \brief Steering routine for finding digits clusters
**/
virtual Int_t FindClusters() = 0;
virtual Int_t FindClusters(bool clr = true) = 0;
virtual Int_t GetOverThreshold() const { return 0; }
virtual TClonesArray* GetClusters() { return fClusters; }
virtual const TClonesArray* GetClusters() const { return fClusters; }
......
......@@ -37,7 +37,7 @@ CbmTrdModuleRec2D::CbmTrdModuleRec2D() : CbmTrdModuleRec() {}
CbmTrdModuleRec2D::CbmTrdModuleRec2D(Int_t mod, Int_t ly, Int_t rot) : CbmTrdModuleRec(mod, ly, rot)
{
SetNameTitle(Form("Trd2dReco%d", mod), "Reconstructor for triangular pads.");
// printf("%s (%s)\n", GetName(), GetTitle()); Config(1,0);
// printf("%s (%s)\n", GetName(), GetTitle()); Config(0, 1, 0);
}
//_______________________________________________________________________________
......@@ -51,17 +51,32 @@ Bool_t CbmTrdModuleRec2D::AddDigi(const CbmTrdDigi* d, Int_t id)
* chunk is to have abs(dt)<5 wrt cluster t0
*/
if (CWRITE()) cout << "\nadd @" << id << " " << d->ToString();
int pad = d->GetAddressChannel(), col, row = GetPadRowCol(pad, col), dtime;
uint16_t chT = pad << 1, chR = chT + 1;
int faspAddress = fAsicPar->GetAsicAddress(chT);
const CbmTrdParFasp* p = static_cast<const CbmTrdParFasp*>(fAsicPar->GetAsicPar(faspAddress));
if (!p) {
LOG(error) << GetName() << "::AddDigi : Could not find FASP params for address=" << faspAddress << " @ pad=" << pad;
return false;
}
const CbmTrdParFaspChannel* daqFaspChT = p->GetChannel(pad, 0);
const CbmTrdParFaspChannel* daqFaspChR = p->GetChannel(pad, 1);
if (CWRITE(0)) {
cout << "\nadd @" << id << " " << d->ToString();
daqFaspChT->Print();
daqFaspChR->Print();
}
Int_t ch = d->GetAddressChannel(), col, row = GetPadRowCol(ch, col), dtime;
Double_t t, r = d->GetCharge(t, dtime);
Int_t tm = d->GetTimeDAQ() - fT0, terminator(0);
Int_t tm = d->GetTimeDAQ() - fT0;
if (dtime < 0) tm += dtime; // correct for the difference between tilt and rect
if (r < 1) terminator = 1;
else if (t < 1)
terminator = -1;
if (r < 1 && !daqFaspChR->IsMasked()) chR = 0;
if (t < 1 && !daqFaspChT->IsMasked()) chT = 0;
if (CWRITE()) printf("row[%2d] col[%2d] tm[%2d] terminator[%d]\n", row, col, tm, terminator);
if (CWRITE(0))
printf("row[%2d] col[%2d] tm[%2d] chT[%4d] chR[%4d]\n", row, col, tm, chT * (daqFaspChT->IsMasked() ? -1 : 1),
chR * (daqFaspChR->IsMasked() ? -1 : 1));
CbmTrdCluster* cl(nullptr);
// get the link to saved clusters
......@@ -71,23 +86,23 @@ Bool_t CbmTrdModuleRec2D::AddDigi(const CbmTrdDigi* d, Int_t id)
Bool_t kINSERT(kFALSE);
std::list<CbmTrdCluster*>::iterator itc = fBuffer[row].begin();
for (; itc != fBuffer[row].end(); itc++) {
//if (CWRITE()) cout << (*itc)->ToString();
//if (CWRITE(0)) cout << (*itc)->ToString();
UShort_t tc = (*itc)->GetStartTime();
Int_t dt = tc - tm;
if (dt < -5) continue;
else if (dt < 5) {
if (CWRITE()) printf("match time dt=%d\n", dt);
if ((*itc)->IsChannelInRange(ch) == 0) {
if (!(*itc)->AddDigi(id, ch, terminator, dt)) break;
if (CWRITE(0)) printf("match time dt=%d\n", dt);
if ((*itc)->IsChannelInRange(chT, chR) == 0) {
if (!(*itc)->AddDigi(id, chT, chR, dt)) break;
kINSERT = kTRUE;
if (CWRITE()) cout << " => Cl (Ad) " << (*itc)->ToString();
if (CWRITE(0)) cout << " => Cl (Ad) " << (*itc)->ToString();
break;
}
}
else {
if (CWRITE()) printf("break for time dt=%d\n", dt);
if (CWRITE(0)) printf("break for time dt=%d\n", dt);
break;
}
}
......@@ -95,28 +110,23 @@ Bool_t CbmTrdModuleRec2D::AddDigi(const CbmTrdDigi* d, Int_t id)
if (!kINSERT) {
if (itc != fBuffer[row].end() && itc != fBuffer[row].begin()) {
itc--;
fBuffer[row].insert(itc, cl = new CbmTrdCluster(fModAddress, id, ch, row, tm));
if (CWRITE()) cout << " => Cl (I) ";
fBuffer[row].insert(itc, cl = new CbmTrdCluster(fModAddress, id, chT, chR, row, tm));
if (CWRITE(0)) cout << " => Cl (I) ";
}
else {
fBuffer[row].push_back(cl = new CbmTrdCluster(fModAddress, id, ch, row, tm));
if (CWRITE()) cout << " => Cl (Pb) ";
fBuffer[row].push_back(cl = new CbmTrdCluster(fModAddress, id, chT, chR, row, tm));
if (CWRITE(0)) cout << " => Cl (Pb) ";
}
cl->SetFaspDigis((d->GetType() == CbmTrdDigi::eCbmTrdAsicType::kFASP));
if (terminator < 0) cl->SetProfileStart();
else if (terminator > 0)
cl->SetProfileStop();
if (CWRITE()) cout << cl->ToString();
if (CWRITE(0)) cout << cl->ToString();
}
}
else {
fBuffer[row].push_back(cl = new CbmTrdCluster(fModAddress, id, ch, row, tm));
fBuffer[row].push_back(cl = new CbmTrdCluster(fModAddress, id, chT, chR, row, tm));
cl->SetFaspDigis((d->GetType() == CbmTrdDigi::eCbmTrdAsicType::kFASP));
if (terminator < 0) cl->SetProfileStart();
else if (terminator > 0)
cl->SetProfileStop();
if (CWRITE()) cout << " => Cl (Nw) " << cl->ToString();
if (CWRITE(0)) cout << " => Cl (Nw) " << cl->ToString();
}
fTimeLast = tm;
return kTRUE;
}
......@@ -133,46 +143,98 @@ Int_t CbmTrdModuleRec2D::GetOverThreshold() const
}
//_______________________________________________________________________________
Int_t CbmTrdModuleRec2D::FindClusters()
const CbmTrdParFaspChannel* CbmTrdModuleRec2D::GetFaspChCalibrator(uint16_t ch) const
{
CbmTrdCluster* cl(nullptr);
int faspAddress = fAsicPar->GetAsicAddress(ch);
const CbmTrdParFasp* p = static_cast<const CbmTrdParFasp*>(fAsicPar->GetAsicPar(faspAddress));
if (!p) {
LOG(error) << GetName() << "::GetFaspChCalibrator : Could not find FASP params for address=" << faspAddress
<< " @ ch=" << ch;
return nullptr;
}
return p->GetChannel(ch / 2, ch % 2);
}
// get the link to saved clusters
Int_t ncl(0);
std::list<CbmTrdCluster*>::iterator itc0, itc1;
for (std::map<Int_t, std::list<CbmTrdCluster*>>::iterator ir = fBuffer.begin(); ir != fBuffer.end(); ir++) {
itc0 = (*ir).second.begin();
while ((*ir).second.size() > 1 && itc0 != (*ir).second.end()) { // try merge clusters
itc1 = itc0;
itc1++;
Bool_t kMERGE = kFALSE;
while (itc1 != (*ir).second.end()) {
if (CWRITE()) cout << " base cl[0] : " << (*itc0)->ToString() << " + cl[1] : " << (*itc1)->ToString();
if ((*itc0)->Merge((*itc1))) {
if (CWRITE()) cout << " SUM : " << (*itc0)->ToString();
kMERGE = kTRUE;
delete (*itc1);
itc1 = (*ir).second.erase(itc1);
if (itc1 == (*ir).second.end()) break;
//_______________________________________________________________________________
int CbmTrdModuleRec2D::AddClusterEdges(CbmTrdCluster* cl)
{
bool left = false, right = !left;
int nchRow = 2 * GetNcols(), nchAdd(0);
// check cluster is not at chmb left edge.
if (cl->GetStartCh() > 0 && (cl->GetStartCh() % nchRow != 0)) {
const CbmTrdParFaspChannel* daqCh = GetFaspChCalibrator(cl->GetStartCh() - 1);
if (daqCh && daqCh->IsMasked()) {
cl->AddChannel(left);
nchAdd++;
}
}
// check cluster is not at chmb right edge.
if (cl->GetEndCh() < NFASPMOD * NFASPCH && (cl->GetEndCh() % nchRow != nchRow - 1)) {
const CbmTrdParFaspChannel* daqCh = GetFaspChCalibrator(cl->GetEndCh() + 1);
if (daqCh && daqCh->IsMasked()) {
cl->AddChannel(right);
nchAdd++;
}
}
return nchAdd;
}
//_______________________________________________________________________________
Int_t CbmTrdModuleRec2D::FindClusters(bool clr)
{
int ncl0(0), ncl(0), mcl(0);
std::list<CbmTrdCluster*>::iterator itc0, itc1, itc;
for (auto& clRow : fBuffer) {
if (CWRITE(0)) cout << "\nrow=" << clRow.first << " ncl=" << clRow.second.size() << endl;
// Phase 0 : try merge clusters if more than one on a row
if (clRow.second.size() > 1) {
itc0 = clRow.second.begin();
// TODO look left and right for masked channels. If they exists add them to cluster.
// if (AddClusterEdges(*itc0) && CWRITE(0)) cout << " edge cl[0] : " << (*itc0)->ToString();
itc = std::prev(clRow.second.end());
while (itc0 != itc) { // try merge clusters
if (CWRITE(0)) cout << "->BASE cl[0] : " << (*itc0)->ToString();
bool kMERGE(false);
itc1 = std::next(itc0);
while (itc1 != clRow.second.end()) {
if (CWRITE(0)) cout << " + cl[1] : " << (*itc1)->ToString();
if ((*itc0)->Merge((*itc1))) {
if (CWRITE(0)) cout << " SUM : " << (*itc0)->ToString();
kMERGE = true;
delete (*itc1);
itc1 = clRow.second.erase(itc1);
itc = std::prev(clRow.second.end());
}
else
itc1++;
}
else
itc1++;
if (!kMERGE) itc0++;
}
if (!kMERGE) itc0++;
}
for (itc0 = (*ir).second.begin(); itc0 != (*ir).second.end(); itc0++) {
cl = (*itc0);
cl = new ((*fClusters)[ncl++]) CbmTrdCluster(*cl);
cl->SetFaspDigis((*itc0)->HasFaspDigis());
delete (*itc0);
mcl += clRow.second.size();
// Phase 1 : copy older clusters from the buffer to the module wise storage
CbmTrdCluster* clDet(nullptr);
for (itc = clRow.second.begin(); itc != clRow.second.end();) {
if (!clr && fTimeLast - (*itc)->GetStartTime() < fTimeWinKeep) {
itc++;
continue;
}
clDet = new ((*fClusters)[ncl++]) CbmTrdCluster(*(*itc));
clDet->SetFaspDigis((*itc)->HasFaspDigis());
delete (*itc);
itc = clRow.second.erase(itc);
}
}
fBuffer.clear();
if (clr) fBuffer.clear();
for (auto clRow : fBuffer)
ncl0 += clRow.second.size();
if (CWRITE(0)) printf("AB :: FindClusters() cls_found = %d cls_write = %d cls_keep = %d\n", mcl, ncl, ncl0);
// printf("fClusters[%p] nCl[%d]\n", (void*)fClusters, fClusters->GetEntriesFast());
// LOG(info) << GetName() << "::FindClusters : " << ncl;
return ncl;
}
......@@ -187,7 +249,7 @@ Bool_t CbmTrdModuleRec2D::PreProcessHits()
*/
Int_t nhits = fHits->GetEntriesFast();
if (CWRITE()) LOG(info) << GetName() << "::PreProcessHits(" << nhits << ")";
if (CWRITE(1)) LOG(info) << GetName() << "::PreProcessHits(" << nhits << ")";
CbmTrdHit* hit(nullptr);
for (Int_t ih(0); ih < nhits; ih++) {
......@@ -196,7 +258,7 @@ Bool_t CbmTrdModuleRec2D::PreProcessHits()
nhits += Deconvolute(hit);
}
nhits = fHits->GetEntriesFast();
if (CWRITE()) LOG(info) << GetName() << "::Deconvolute(" << nhits << ")";
if (CWRITE(1)) LOG(info) << GetName() << "::Deconvolute(" << nhits << ")";
return kTRUE;
}
......@@ -212,7 +274,7 @@ Bool_t CbmTrdModuleRec2D::PostProcessHits()
/** Steering routine for classifying hits and apply further analysis
* -> hit merging for row-cross (see RowCross)
*/
return true;
CbmTrdHit *h0(nullptr), *h1(nullptr);
Int_t a0, nhits = fHits->GetEntriesFast();
......@@ -241,7 +303,7 @@ Bool_t CbmTrdModuleRec2D::PostProcessHits()
// call the working algorithm
if (MergeHits(h0, a0)) h0->SetRowCross(h1);
if (CWRITE()) {
if (CWRITE(1)) {
cout << ih << " : " << h0->ToString();
cout << jh << " : " << h1->ToString();
cout << "\n" << endl;
......@@ -265,7 +327,7 @@ Bool_t CbmTrdModuleRec2D::PostProcessHits()
}
fDigis.clear();
if (CWRITE()) LOG(info) << GetName() << "::MergeHits(" << nhits << ")";
if (CWRITE(1)) LOG(info) << GetName() << "::MergeHits(" << nhits << ")";
return kTRUE;
}
......@@ -526,7 +588,7 @@ Bool_t CbmTrdModuleRec2D::MergeHits(CbmTrdHit* h, Int_t a0)
h->SetMaxType(IsMaxTilt());
h->SetOverFlow(HasOvf());
if (CWRITE()) {
if (CWRITE(1)) {
printf("-> loc[%6.2f %6.2f %6.2f] err[%6.2f %6.2f %6.2f]\n", local_pad[0], local_pad[1], local_pad[2],
local_pad_err[0], local_pad_err[1], local_pad_err[2]);
printf("REC col[%2d] row[%2d] dx[%7.3f(pw) %7.3f(cm)] x[%7.2f] y[%7.2f] dy[%5.2f] t0[%llu]\n", vcM, vrM,
......@@ -688,7 +750,7 @@ Bool_t CbmTrdModuleRec2D::BuildHit(CbmTrdHit* h)
fgEdep->SetPoint(ip, xc, 0);
fgEdep->SetPointError(ip, 0., 300);
}
//if(CWRITE()) fgEdep->Print();
//if(CWRITE(1)) fgEdep->Print();
}
Double_t e(0.), xlo(*vx.begin()), xhi(*vx.rbegin());
......@@ -738,7 +800,7 @@ Bool_t CbmTrdModuleRec2D::BuildHit(CbmTrdHit* h)
h->SetMaxType(IsMaxTilt());
h->SetOverFlow(HasOvf());
if (CWRITE()) {
if (CWRITE(1)) {
printf("-> loc[%6.2f %6.2f %6.2f] err[%6.2f %6.2f %6.2f]\n", local_pad[0], local_pad[1], local_pad[2],
local_pad_err[0], local_pad_err[1], local_pad_err[2]);
printf("REC col[%2d] row[%2d] x[%7.2f] dx[%5.2f] y[%7.2f] dy[%5.2f] t0[%llu]\n", vcM, vrM, global[0], dx, global[1],
......@@ -790,7 +852,7 @@ CbmTrdHit* CbmTrdModuleRec2D::MakeHit(Int_t ic, const CbmTrdCluster* cl, std::ve
hf->Draw("p");
}
if (CWRITE()) cout << cl->ToString();
if (CWRITE(1)) cout << cl->ToString();
if (!LoadDigis(digis, ic)) return nullptr;
if (!ProjectDigis(ic)) return nullptr;
Int_t nofHits = fHits->GetEntriesFast();
......@@ -799,7 +861,7 @@ CbmTrdHit* CbmTrdModuleRec2D::MakeHit(Int_t ic, const CbmTrdCluster* cl, std::ve
hit->SetRefId(ic);
//hit->SetMatch();
BuildHit(hit);
if (CWRITE()) cout << hit->ToString();
if (CWRITE(1)) cout << hit->ToString();
if (CDRAW()) DrawHit(hit);
return hit;
}
......@@ -851,7 +913,7 @@ Double_t CbmTrdModuleRec2D::GetXoffset(Int_t n0) const
dx += vs[ir] * vx[ir];
}
if (TMath::Abs(R) > 0) return dx / R;
LOG(warn) << GetName() << "::GetXoffset : Unexpected null sum.";
LOG(warn) << GetName() << "::GetXoffset : Null total charge for hit size " << n;
return 0.;
}
......@@ -867,7 +929,8 @@ Double_t CbmTrdModuleRec2D::GetYoffset(Int_t n0) const
}
}
if (TMath::Abs(T) > 0) return dy / T;
LOG(warn) << GetName() << "::GetYoffset : Unexpected null sum.";
LOG(warn) << GetName() << "::GetYoffset : Null total charge for hit size " << n;
//if (CWRITE(1))
return 0.;
}
......@@ -1089,7 +1152,7 @@ Int_t CbmTrdModuleRec2D::ProjectDigis(Int_t cid, Int_t cjd)
dg = (*i);
dg0 = nullptr;
dg1 = nullptr;
if (CWRITE()) cout << "dg0 :" << dg->ToString();
if (CWRITE(1)) cout << "dg0 :" << dg->ToString();
// initialize
if (col < 0) {
......@@ -1138,7 +1201,7 @@ Int_t CbmTrdModuleRec2D::ProjectDigis(Int_t cid, Int_t cjd)
}
if (dg0) i1++;
}
if (CWRITE()) {
if (CWRITE(1)) {
if (dg0) cout << "dgR :" << dg0->ToString();
if (dg1) cout << "dgT :" << dg1->ToString();
cout << "-------------------------------------" << endl;
......@@ -1280,7 +1343,7 @@ Int_t CbmTrdModuleRec2D::ProjectDigis(Int_t cid, Int_t cjd)
else
SetBiasY(0);
if (CWRITE()) {
if (CWRITE(1)) {
printf("t0[clk]=%llu col[%2d] row[%2d] sz[%d] OVF[%c] %c", vt0, vcM, vrM, Int_t(vs.size() - 2),
(ovf < 0 ? 'y' : 'n'), IsOpenLeft() ? '(' : '[');
if (IsSymmHit()) {
......@@ -1339,7 +1402,7 @@ Int_t CbmTrdModuleRec2D::LoadDigis(vector<const CbmTrdDigi*>* digis, vector<CbmT
dg = (*idgM);
idgM++;
}
if (CWRITE()) cout << dg->ToString();
if (CWRITE(1)) cout << dg->ToString();
r = dg->GetCharge(t, dt);
if (t0 == 0) t0 = dg->GetTimeDAQ(); // set arbitrary t0 to avoid double digis loop
if (col0 < 0) GetPadRowCol(dg->GetAddressChannel(), col0); // initialilze
......@@ -1497,7 +1560,7 @@ Int_t CbmTrdModuleRec2D::LoadDigisRC(vector<const CbmTrdDigi*>* digis, const Int
col = col0;
step = 1;
}
if (CWRITE()) printf("col0[%d] col1[%d] step[%2d]\n", col0, col1, step);
if (CWRITE(1)) printf("col0[%d] col1[%d] step[%2d]\n", col0, col1, step);
const CbmTrdDigi *dg0(nullptr), *dg1(nullptr), *dg10(nullptr);
// always loop on the largest cluster
......@@ -1505,7 +1568,7 @@ Int_t CbmTrdModuleRec2D::LoadDigisRC(vector<const CbmTrdDigi*>* digis, const Int
dg0 = (*i0);
dg1 = nullptr;
dg10 = nullptr;
if (CWRITE()) cout << "dg0 :" << dg0->ToString();
if (CWRITE(1)) cout << "dg0 :" << dg0->ToString();
r = dg0->GetCharge(t, dt);
if (t > 0) t -= CbmTrdFASP::GetBaselineCorr();
......@@ -1554,7 +1617,7 @@ Int_t CbmTrdModuleRec2D::LoadDigisRC(vector<const CbmTrdDigi*>* digis, const Int
}
if (dg1) i1++;
if (CWRITE()) {
if (CWRITE(1)) {
if (dg1) cout << "dgR :" << dg1->ToString();
if (dg10) cout << "dgT :" << dg10->ToString();
cout << "-------------------------------------" << endl;
......@@ -1669,7 +1732,7 @@ Bool_t CbmTrdModuleRec2D::MergeDigis(vector<const CbmTrdDigi*>* digis, vector<Cb
dgM->SetCharge(t, r, dt);
Int_t rtrg(dgR->GetTriggerType() & 2), ttrg(dgT->GetTriggerType() & 1);
dgM->SetTriggerType(rtrg | ttrg); //merge the triggers
if (CWRITE()) {
if (CWRITE(1)) {
cout << "MERGE" << endl;
cout << dgT->ToString();
cout << dgR->ToString();
......
......@@ -19,6 +19,7 @@ using std::map;
using std::vector;
class TGraphErrors;
class CbmTrdDigiRec;
class CbmTrdParFaspChannel;
class TF1;
/** @class CbmTrdModuleRec2D
** @brief Cluster finding and hit reconstruction algorithms for the TRD(2D) module.
......@@ -37,9 +38,10 @@ class CbmTrdModuleRec2D : public CbmTrdModuleRec {
public:
enum ECbmTrdModuleRec2D
{
kVerbose = 0, ///< steer verbosity on/off
kDraw = 1, ///< steer graphic representation on/off
kHelpers = 2 ///< use helper graph for time and energy estimation
kVerbCluster = 0, ///< steer clusterizer verbosity on/off
kVerbReco = 1, ///< steer reconstructor verbosity on/off
kDraw = 2, ///< steer graphic representation on/off
kHelpers = 3 ///< use helper graph for time and energy estimation
};
/** \brief Default constructor.*/
......@@ -51,11 +53,6 @@ public:
/** \brief Add digi to local module **/
virtual Bool_t AddDigi(const CbmTrdDigi* d, Int_t id);
/** \brief Config task with the following settings
* \param[in] v verbosity toggle
* \param[in] d drawing toggle
*/
virtual inline void Config(Bool_t vb, Bool_t dw);
virtual void DrawHit(CbmTrdHit*) const { ; }
/** \brief Count RO channels (R or T) with data**/
virtual Int_t GetOverThreshold() const;
......@@ -64,7 +61,7 @@ public:
/** \brief Finalize hits (merge RC hits, etc)**/
virtual Bool_t PostProcessHits();
/** \brief Finalize clusters **/
virtual Int_t FindClusters();
virtual Int_t FindClusters(bool clr);
/** \brief Steering routine for building hits **/
virtual Bool_t MakeHits();
/** \brief Steering routine for converting cluster to hit **/
......@@ -135,10 +132,25 @@ private:
CbmTrdModuleRec2D(const CbmTrdModuleRec2D& ref);
const CbmTrdModuleRec2D& operator=(const CbmTrdModuleRec2D& ref);
/** \brief Config task with the following settings
* \param[in] vcl toggle verbosity clusterizer
* \param[in] vrc toggle verbosity reconsructor
* \param[in] dw drawing toggle
*/
virtual inline void Config(Bool_t vcl, Bool_t vrc, Bool_t dw);
Bool_t CDRAW() const { return TESTBIT(fConfigMap, ECbmTrdModuleRec2D::kDraw); }
Bool_t CWRITE() const { return TESTBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbose); }
Bool_t CWRITE(int level) const
{
if (level) return TESTBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbReco);
else
return TESTBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbCluster);
}
Bool_t CHELPERS() const { return TESTBIT(fConfigMap, ECbmTrdModuleRec2D::kHelpers); }
/** \brief Add left and right edge channels to the cluster in case this are masked channels
* \return no of edges added to cluster
*/
int AddClusterEdges(CbmTrdCluster* cl);
/** \brief Implement cuts for hit convolution definition
* \param[in] h hit to be analysed.
* \return TRUE if double cluster
......@@ -151,6 +163,10 @@ private:
Bool_t Deconvolute(CbmTrdHit* h);
Double_t GetXoffset(Int_t n0 = 0) const;
Double_t GetYoffset(Int_t n0 = 0) const;
/** \brief Retrive FASP ch calibrator by RO ch number in the module
* \param[in] ch channel id in the current module.
*/
const CbmTrdParFaspChannel* GetFaspChCalibrator(uint16_t ch) const;
/** \brief Load digis info into local data structures
* \param[in] digis initial digis list shrinked for incomplete digis.
* \param[in] vdgM list of merged digis
......@@ -201,6 +217,8 @@ private:
UChar_t fConfigMap = 0; //! task configuration settings
ULong64_t fT0 = 0; //! start time of event/time slice [clk]
uint fTimeLast = 0; //! time of last digi processed in module [clk]
uint fTimeWinKeep = 11; //! time interval to still keep clusters in buffer [clk]
std::map<Int_t, std::list<CbmTrdCluster*>> fBuffer; //row-wise organized clusters
std::map<Int_t, vector<CbmTrdDigiRec*>> fDigis; //!cluster-wise organized calibrated digi
// working representation of a hit on which the reconstruction is performed
......@@ -230,12 +248,16 @@ private:
2) // Triangular pad module; Cluster finding and hit reconstruction algorithms
};
void CbmTrdModuleRec2D::Config(Bool_t vb, Bool_t dw)
void CbmTrdModuleRec2D::Config(Bool_t vcl, Bool_t vrc, Bool_t dw)
{
if (vb) SETBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbose);
if (vcl) SETBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbCluster);
else
CLRBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbCluster);
printf("CbmTrdModuleRec2D::kVerbCluster[%c]\n", CWRITE(0) ? 'y' : 'n');
if (vrc) SETBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbReco);
else
CLRBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbose);
printf("CbmTrdModuleRec2D::Verbose[%c]\n", CWRITE() ? 'y' : 'n');
CLRBIT(fConfigMap, ECbmTrdModuleRec2D::kVerbReco);
printf("CbmTrdModuleRec2D::kVerbReco[%c]\n", CWRITE(1) ? 'y' : 'n');
if (dw) SETBIT(fConfigMap, ECbmTrdModuleRec2D::kDraw);
else
CLRBIT(fConfigMap, ECbmTrdModuleRec2D::kDraw);
......
......@@ -68,7 +68,7 @@ void CbmTrdModuleRecR::Clear(Option_t* opt)
}
//_______________________________________________________________________________
Int_t CbmTrdModuleRecR::FindClusters()
Int_t CbmTrdModuleRecR::FindClusters(bool)
{
std::deque<std::tuple<Int_t, Bool_t, const CbmTrdDigi*>>::iterator mainit;
......
......@@ -37,7 +37,7 @@ public:
/**
* \brief Steering routine for finding digits clusters
**/
virtual Int_t FindClusters();
virtual Int_t FindClusters(bool clr = true);
Int_t GetOverThreshold() const { return fDigiCounter; }
Double_t GetSpaceResolution(Double_t val = 3.0);
......
......@@ -75,13 +75,13 @@ double CbmTrdHitMC::GetSignal(uint idx) const
//_____________________________________________________________________
CbmTrdHitMC::eCbmTrdHitMCshape CbmTrdHitMC::GetClShape() const
{
if (fCluster.HasOpenStart()) {
if (fCluster.HasOpenStop()) return eCbmTrdHitMCshape::kRT;
if (fCluster.HasStart()) {
if (fCluster.HasStop()) return eCbmTrdHitMCshape::kRT;
else
return eCbmTrdHitMCshape::kRR;
}
else {
if (fCluster.HasOpenStop()) return eCbmTrdHitMCshape::kTT;
if (fCluster.HasStop()) return eCbmTrdHitMCshape::kTT;
else
return eCbmTrdHitMCshape::kTR;
}
......
......@@ -127,16 +127,6 @@ CbmTrdUnpackFaspAlgo::GetParContainerRequest(std::string geoTag, std::uint32_t r
return &fParContVec;
}
//_________________________________________________________________________________
void CbmTrdUnpackFaspAlgo::SetAsicMapping(const std::map<uint32_t, uint8_t[NFASPMOD]>& asicMap)
{
if (!fFaspMap) fFaspMap = new std::map<uint32_t, uint8_t[NFASPMOD]>(asicMap);
else {
delete fFaspMap;
fFaspMap = new std::map<uint32_t, uint8_t[NFASPMOD]>(asicMap);
}
}
//_________________________________________________________________________________
void CbmTrdUnpackFaspAlgo::SetCrobMapping(const std::map<uint32_t, uint16_t[NCROBMOD]>& map)
{
......@@ -152,25 +142,6 @@ void CbmTrdUnpackFaspAlgo::SetCrobMapping(const std::map<uint32_t, uint16_t[NCRO
}
}
//_________________________________________________________________________________
void CbmTrdUnpackFaspAlgo::PrintAsicMapping()
{
if (!fFaspMap) {
LOG(info) << GetName() << "No asic mapping loaded.";
return;
}
LOG(info) << GetName() << "Fasp Asic mapping on modules:";
for (auto imod : (*fFaspMap)) {
printf("Mod [%6d] :", imod.first);
for (int ifasp(0); ifasp < NFASPMOD; ifasp++) {
if (ifasp % 9 == 0) printf("\n");
int jfasp = imod.second[ifasp];
printf("%3d ", (jfasp == 0xff ? -1 : jfasp));
}
printf("\n");
}
}
//_________________________________________________________________________________
CbmTrdUnpackFaspAlgo::CbmTrdFaspMessageType CbmTrdUnpackFaspAlgo::mess_type(uint32_t wd)
{
......@@ -251,6 +222,10 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas
for (auto imess : messes) {
const Int_t pad = faspPar->GetPadAddress(imess.ch);
const CbmTrdParFaspChannel* chCalib = faspPar->GetChannel(imess.ch);
if (chCalib->IsMasked()) {
LOG(warn) << GetName() << "::pushDigis - FASP par " << mod_id * 1000 + lFasp << " ch " << int(imess.ch)
<< " masked but have data. Masks need attention.";
}
const ULong64_t lTime = fTime + tdaqOffset + imess.tlab;
const UShort_t lchR = chCalib->HasPairingR() ? imess.data : 0;
const UShort_t lchT = chCalib->HasPairingR() ? 0 : imess.data;
......@@ -449,8 +424,6 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
continue;
}
if (fFaspMap) fasp_id = ((*fFaspMap)[mod_id])[fasp_id];
if (lFaspOld != fasp_id) {
// push
if (vMess.size()) { pushDigis(vMess, mod_id); }
......