Skip to content

Commit 2c92f9e

Browse files
peressounkosawenzel
authored andcommitted
Add calibration and mis-alignment (#2294)
* Add PHOS to list of digitizers * Add misaligned volumes * First implementation of PHOS calibration DB
1 parent 652b3f0 commit 2c92f9e

16 files changed

Lines changed: 956 additions & 27 deletions

File tree

Detectors/PHOS/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# submit itself to any jurisdiction.
1010

1111
add_subdirectory(base)
12+
add_subdirectory(calib)
1213
add_subdirectory(simulation)
1314
add_subdirectory(reconstruction)
1415
if(BUILD_TESTING)

Detectors/PHOS/base/include/PHOSBase/Geometry.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class Geometry
7777
return sGeom;
7878
}
7979

80-
int AreNeighbours(Int_t absId1, Int_t absId2) const;
80+
int AreNeighbours(int absId1, int absId2) const;
8181

8282
///
8383
/// \return AbsId index of the PHOS cell
@@ -86,19 +86,19 @@ class Geometry
8686
/// \param strip: strip number
8787
// \param cell: cell in strip number
8888
///
89-
Int_t RelToAbsId(Int_t moduleNumber, Int_t strip, Int_t cell) const;
89+
int RelToAbsId(int moduleNumber, int strip, int cell) const;
9090
// Converts the absolute numbering into the following array
9191
// relid[0] = PHOS Module number 1:module
9292
// relid[1] = Row number inside a PHOS module (Phi coordinate)
9393
// relid[2] = Column number inside a PHOS module (Z coordinate)
94-
Bool_t AbsToRelNumbering(Int_t absId, Int_t* relid) const;
95-
Int_t AbsIdToModule(Int_t absId);
94+
bool AbsToRelNumbering(int absId, int* relid) const;
95+
int AbsIdToModule(int absId);
9696
void AbsIdToRelPosInModule(int absId, double& x, double& z) const;
97-
Bool_t RelToAbsNumbering(const Int_t* RelId, Int_t& AbsId) const;
97+
bool RelToAbsNumbering(const int* RelId, int& AbsId) const;
9898
// converts the absolute PHOS numbering to a relative
9999

100-
Int_t GetTotalNCells() const { return 56 * 64 * 4; } // TODO: evaluate from real geometry
101-
Int_t IsCellExists(Int_t absId) const
100+
int GetTotalNCells() const { return 56 * 64 * 4; } // TODO: evaluate from real geometry
101+
int IsCellExists(int absId) const
102102
{
103103
return absId > 0 && absId <= GetTotalNCells();
104104
} // TODO: evaluate from real geometry

Detectors/PHOS/base/src/Digit.cxx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// In applying this license CERN does not waive the privileges and immunities
88
// granted to it by virtue of its status as an Intergovernmental Organization
99
// or submit itself to any jurisdiction.
10+
#include "FairLogger.h"
1011

1112
#include "PHOSBase/Digit.h"
1213
#include <iostream>
@@ -61,6 +62,15 @@ Digit& Digit::operator+=(const Digit& other)
6162
mTime = other.mTime;
6263
}
6364

65+
if (mLabel == -1) {
66+
mLabel = other.mLabel;
67+
} else {
68+
if (mLabel != other.mLabel && other.mLabel != -1) {
69+
//if Label indexes are different, something wrong
70+
LOG(ERROR) << "Adding digits with different references to Labels:" << mLabel << " and " << other.mLabel;
71+
}
72+
}
73+
6474
mAmplitude += other.mAmplitude;
6575

6676
return *this;

Detectors/PHOS/base/src/Geometry.cxx

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,32 @@ Geometry::Geometry(const std::string_view name) : mGeoName(name) {}
3333
// return sGeom;
3434
// }
3535

36-
Int_t Geometry::RelToAbsId(Int_t moduleNumber, Int_t strip, Int_t cell) const
36+
int Geometry::RelToAbsId(int moduleNumber, int strip, int cell) const
3737
{
3838
// calculates absolute cell Id from moduleNumber, strip (number) and cell (number)
3939
// PHOS layout parameters:
40-
const Int_t nStrpZ = 28; // Number of strips along z-axis
41-
const Int_t nCrystalsInModule = 56 * 64; // Total number of crystals in module
42-
const Int_t nCellsXInStrip = 8; // Number of crystals in strip unit along x-axis
43-
const Int_t nZ = 56; // nStripZ * nCellsZInStrip
40+
const int nStrpZ = 28; // Number of strips along z-axis
41+
const int nCrystalsInModule = 56 * 64; // Total number of crystals in module
42+
const int nCellsXInStrip = 8; // Number of crystals in strip unit along x-axis
43+
const int nZ = 56; // nStripZ * nCellsZInStrip
4444

45-
Int_t row = nStrpZ - (strip - 1) % nStrpZ;
46-
Int_t col = (Int_t)std::ceil((Double_t)strip / (nStrpZ)) - 1;
45+
int row = nStrpZ - (strip - 1) % nStrpZ;
46+
int col = (int)std::ceil((Double_t)strip / (nStrpZ)) - 1;
4747

4848
return (moduleNumber - 1) * nCrystalsInModule + row * 2 + (col * nCellsXInStrip + (cell - 1) / 2) * nZ -
4949
(cell & 1 ? 1 : 0);
5050
}
5151

52-
Bool_t Geometry::AbsToRelNumbering(Int_t absId, Int_t* relid) const
52+
Bool_t Geometry::AbsToRelNumbering(int absId, int* relid) const
5353
{
5454
// Converts the absolute numbering into the following array
5555
// relid[0] = PHOS Module number 1:fNModules
5656
// relid[1] = Row number inside a PHOS module (Z coordinate)
5757
// relid[2] = Column number inside a PHOS module (Phi coordinate)
58-
const Int_t nZ = 56; // nStripZ * nCellsZInStrip
59-
const Int_t nPhi = 64; // nStripZ * nCellsZInStrip
58+
const int nZ = 56; // nStripZ * nCellsZInStrip
59+
const int nPhi = 64; // nStripZ * nCellsZInStrip
6060

61-
Int_t phosmodulenumber = (absId - 1) / (nZ * nPhi);
61+
int phosmodulenumber = (absId - 1) / (nZ * nPhi);
6262

6363
relid[0] = phosmodulenumber + 1;
6464
absId -= phosmodulenumber * nPhi * nZ;
@@ -67,15 +67,15 @@ Bool_t Geometry::AbsToRelNumbering(Int_t absId, Int_t* relid) const
6767

6868
return true;
6969
}
70-
Int_t Geometry::AbsIdToModule(Int_t absId)
70+
int Geometry::AbsIdToModule(int absId)
7171
{
72-
const Int_t nZ = 56;
73-
const Int_t nPhi = 64;
72+
const int nZ = 56;
73+
const int nPhi = 64;
7474

7575
return 1 + (absId - 1) / (nZ * nPhi);
7676
}
7777

78-
int Geometry::AreNeighbours(Int_t absId1, Int_t absId2) const
78+
int Geometry::AreNeighbours(int absId1, int absId2) const
7979
{
8080

8181
// Gives the neighbourness of two digits = 0 are not neighbour but continue searching
@@ -87,15 +87,15 @@ int Geometry::AreNeighbours(Int_t absId1, Int_t absId2) const
8787
// The order of d1 and d2 is important: first (d1) should be a digit already in a cluster
8888
// which is compared to a digit (d2) not yet in a cluster
8989

90-
Int_t relid1[3];
90+
int relid1[3];
9191
AbsToRelNumbering(absId1, relid1);
9292

93-
Int_t relid2[3];
93+
int relid2[3];
9494
AbsToRelNumbering(absId2, relid2);
9595

9696
if (relid1[0] == relid2[0]) { // inside the same PHOS module
97-
Int_t rowdiff = TMath::Abs(relid1[1] - relid2[1]);
98-
Int_t coldiff = TMath::Abs(relid1[2] - relid2[2]);
97+
int rowdiff = TMath::Abs(relid1[1] - relid2[1]);
98+
int coldiff = TMath::Abs(relid1[2] - relid2[2]);
9999

100100
if ((coldiff <= 1) && (rowdiff <= 1)) { // At least common vertex
101101
return 1;
@@ -117,9 +117,21 @@ void Geometry::AbsIdToRelPosInModule(int absId, double& x, double& z) const
117117

118118
const double cellStep = 2.25;
119119

120-
Int_t relid[3];
120+
int relid[3];
121121
AbsToRelNumbering(absId, relid);
122122

123123
x = (relid[1] - 28 - 0.5) * cellStep;
124124
z = (relid[2] - 32 - 0.5) * cellStep;
125125
}
126+
bool Geometry::RelToAbsNumbering(const int* relId, int& absId) const
127+
{
128+
const int nZ = 56; // nStripZ * nCellsZInStrip
129+
const int nPhi = 64; // nStripZ * nCellsZInStrip
130+
131+
absId =
132+
(relId[0] - 1) * nPhi * nZ + // the offset of PHOS modules
133+
(relId[1] - 1) * nZ + // the offset along phi
134+
relId[2]; // the offset along z
135+
136+
return true;
137+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright CERN and copyright holders of ALICE O2. This software is distributed
2+
# under the terms of the GNU General Public License v3 (GPL Version 3), copied
3+
# verbatim in the file "COPYING".
4+
#
5+
# See http://alice-o2.web.cern.ch/license for full licensing information.
6+
#
7+
# In applying this license CERN does not waive the privileges and immunities
8+
# granted to it by virtue of its status as an Intergovernmental Organization or
9+
# submit itself to any jurisdiction.
10+
11+
o2_add_library(PHOSCalib
12+
SOURCES src/BadChannelMap.cxx
13+
src/CalibParams.cxx
14+
src/CalibDB.cxx
15+
PUBLIC_LINK_LIBRARIES O2::CCDB O2::PHOSBase)
16+
17+
o2_target_root_dictionary(PHOSCalib
18+
HEADERS include/PHOSCalib/BadChannelMap.h
19+
include/PHOSCalib/CalibParams.h
20+
include/PHOSCalib/CalibDB.h
21+
LINKDEF src/PHOSCalibLinkDef.h)
22+
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
#include <iosfwd>
11+
#include <bitset>
12+
#include <Rtypes.h>
13+
#include <CCDB/TObjectWrapper.h> // Needed to trigger dictionary build
14+
15+
class TH2;
16+
17+
namespace o2
18+
{
19+
20+
namespace phos
21+
{
22+
23+
/// \class BadChannelMap
24+
/// \brief CCDB container for bad (masked) channels in PHOS
25+
/// \author Dmitri Peresunko, adopted from EMCAL (Markus Fasel)
26+
/// \since Aug. 1, 2019
27+
///
28+
/// # The PHOS Bad Channel Map
29+
///
30+
/// The bad channel map contains channels which are marked to be
31+
/// bad and excluded from reonstruction: clusterization
32+
/// or other analysis processes.
33+
///
34+
/// Bad channels can be added via
35+
/// bcm.addBadChannel(1234);
36+
/// goodness of channel can be restored with
37+
/// bcm.setChannelGood(1234) ;
38+
///
39+
/// Reading the channel status is done via
40+
/// bool status = bcm.isChannelGood(1234);
41+
/// Calling isChannelGood for cells beyond PHOS
42+
/// will return the status bad.
43+
///
44+
/// For visualization a 2D histogram with the cell status as function of x(phi) vs z
45+
/// for each module can be created on the fly from the bad channel map. As the histogram is
46+
/// created dynamically from the absolute cell ID an instance of the PHOS Geometry
47+
/// is required - otherwise an empty histogram is created.
48+
///
49+
/// The bad channel map can be created from multiple bad channel
50+
/// maps using the operator +=. This allows for the combination
51+
/// of the bad channel map from multiple time slices.
52+
class BadChannelMap
53+
{
54+
public:
55+
/// \brief Constructor
56+
BadChannelMap() = default;
57+
58+
/// \brief Destructor
59+
~BadChannelMap() = default;
60+
61+
/// \brief Add bad channel map to this bad channel map
62+
/// \param rhs Bad channel map to be added to this bad channel map
63+
/// \return Reference to the combined bad channel map
64+
///
65+
/// Adding bad channels of another bad channel map to this
66+
/// bad channel map.
67+
BadChannelMap& operator+=(const BadChannelMap& rhs)
68+
{
69+
mBadCells |= rhs.mBadCells;
70+
return *this;
71+
}
72+
73+
/// \brief Comparison of two bad channel maps
74+
/// \return true if the bad channel maps are identical, false otherwise
75+
///
76+
/// Testing two bad channel maps for equalness.
77+
bool operator==(const BadChannelMap& other) const { return mBadCells == other.mBadCells; }
78+
79+
/// \brief Add bad cell to the container
80+
/// \param channelID Absolute ID of the bad channel
81+
/// \param mask type of the bad channel
82+
///
83+
/// Adding new bad channel to the container. In case a cell
84+
/// with the same ID is already present in the container,
85+
/// the mask status is updated. Otherwise it is added.
86+
///
87+
/// Only bad or warm cells are added to the container. In case
88+
/// the mask type is GOOD_CELL, the entry is removed from the
89+
/// container if present before, otherwise the cell is ignored.
90+
void addBadChannel(unsigned short channelID) { mBadCells.set(channelID); } //set bit to true
91+
92+
/// \brief Mark channel as good
93+
/// \param channelID Absolute ID of the channel
94+
///
95+
/// Setting channel as good.
96+
void setChannelGood(unsigned short channelID) { mBadCells.set(channelID, false); }
97+
98+
/// \brief Get the status of a certain cell
99+
/// \param channelID channel for which to obtain the channel status
100+
/// \return true if good channel
101+
///
102+
/// Provide the mask status of a cell.
103+
bool isChannelGood(unsigned short channelID) const { return !mBadCells.test(channelID); }
104+
105+
/// \brief Convert map into 2D histogram representation
106+
/// \param mod Module number
107+
/// \param h Histogram of size 64*56 to be filled with the bad channel map.
108+
///
109+
/// Convert bad channel map into a 2D map with phi(64) vs z(56) dimensions.
110+
/// Entries in the histogram are:
111+
/// - 0: GOOD_CELL
112+
/// - 1: BAD_CELL
113+
/// Attention: It is responsibility of user to create/delete histogram
114+
void getHistogramRepresentation(int mod, TH2* h) const;
115+
116+
/// \brief Print bad channels on a given stream
117+
/// \param stream Stream on which the bad channel map is printed on
118+
///
119+
/// Printing all bad channels store in the bad channel map
120+
/// on the stream.
121+
///
122+
/// The function is called in the operator<< providing direct access
123+
/// to protected members. Explicit calls by the users is normally not
124+
/// necessary.
125+
void PrintStream(std::ostream& stream) const;
126+
127+
private:
128+
static constexpr int NCHANNELS = 14337; ///< Number of channels starting from 1 (4*64*56+1
129+
std::bitset<NCHANNELS> mBadCells; ///< Container for bad cells, 1 means bad sell
130+
131+
ClassDefNV(BadChannelMap, 1);
132+
};
133+
134+
/// \brief Printing bad channel map on the stream
135+
/// \param in Stream where the bad channel map is printed on
136+
/// \param bcm Bad channel map to be printed
137+
/// \return Stream after printing the bad channel map
138+
///
139+
/// Printing cellID of all bad channels stored in the bad channel map
140+
/// on the stream.
141+
std::ostream& operator<<(std::ostream& in, const BadChannelMap& bcm);
142+
143+
} // namespace phos
144+
145+
} // namespace o2

0 commit comments

Comments
 (0)