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
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ class SegmentationChip
// The "detector coordinate system" refers to the hit position in row,col inside the sensor
// This class provides the transformations from the local and detector coordinate systems
// The conversion between global and local coordinate systems is operated by the transformation matrices
// For the curved VD layers there exist three coordinate systems and one is transient.
// For the curved VD layers there exist four coordinate systems.
// 1. The global (curved) coordinate system. The chip's center of coordinate system is
// defined at the the mid-point of the detector.
// 2. The local (flat) coordinate system. This is the tube segment projected onto a flat
// surface. In the projection we implicitly assume that the inner and outer
// stretch does not depend on the radius.
// 3. The detector coordinate system. Defined by the row and column segmentation
// defined at the upper edge in the flat coord.
// 2. The local (curved) coordinate system, centered in 0,0,0.
// 3. The local (flat) coordinate system. This is the tube segment projected onto a flat
// surface, centered in the middle of the chip, with the y axis pointing towards the interaction point.
// In the projection we implicitly assume that the inner and outer stretch does not depend on the radius.
// 4. The detector coordinate system. Defined by the row and column segmentation.
// For the flat ML and OT layers, there exist two coordinate systems:
// 1. The global (flat) coordinate system. The chip's center of coordinate system is
// defined at the the mid-point of the detector.
// 2. The detector coordinate system. Defined by the row and column segmentation
// 2. The detector coordinate system. Defined by the row and column segmentation.
// TODO: add segmentation for VD disks

public:
Expand Down Expand Up @@ -121,15 +121,20 @@ class SegmentationChip
pitchCol = PitchColMLOT;
maxWidth = constants::ML::width;
maxLength = constants::ML::length;
} else if (subDetID == 1 && layer >= 4) { // OT
} else if (subDetID == 1 && layer == 4) { // ML/OT (mixed layer, length = ML but staggered as OT)
pitchRow = PitchRowMLOT;
pitchCol = PitchColMLOT;
maxWidth = constants::OT::width;
maxLength = constants::OT::length;
maxWidth = constants::OT::halfstave::width;
maxLength = constants::ML::length;
} else if (subDetID == 1 && layer > 4) { // OT
pitchRow = PitchRowMLOT;
pitchCol = PitchColMLOT;
maxWidth = constants::OT::halfstave::width;
maxLength = constants::OT::halfstave::length;
}
// convert to row/col
iRow = static_cast<int>(std::floor((maxWidth / 2 - xRow) / pitchRow));
iCol = static_cast<int>(std::floor((zCol + maxLength / 2) / pitchCol));
iRow = static_cast<int>(((maxWidth / 2 - xRow) / pitchRow));
iCol = static_cast<int>(((zCol + maxLength / 2) / pitchCol));
};

// Check local coordinates (cm) validity.
Expand All @@ -143,9 +148,12 @@ class SegmentationChip
} else if (subDetID == 1 && layer <= 3) { // ML
maxWidth = constants::ML::width;
maxLength = constants::ML::length;
} else if (subDetID == 1 && layer >= 4) { // OT
maxWidth = constants::OT::width;
maxLength = constants::OT::length;
} else if (subDetID == 1 && layer == 4) { // ML/OT (mixed layer, length = ML but staggered as OT)
maxWidth = constants::OT::halfstave::width;
maxLength = constants::ML::length;
} else if (subDetID == 1 && layer > 4) { // OT
maxWidth = constants::OT::halfstave::width;
maxLength = constants::OT::halfstave::length;
}
return (-maxWidth / 2 < x && x < maxWidth / 2 && -maxLength / 2 < z && z < maxLength / 2);
}
Expand All @@ -162,9 +170,12 @@ class SegmentationChip
} else if (subDetID == 1 && layer <= 3) { // ML
nRows = constants::ML::nRows;
nCols = constants::ML::nCols;
} else if (subDetID == 1 && layer >= 4) { // OT
nRows = constants::OT::nRows;
nCols = constants::OT::nCols;
} else if (subDetID == 1 && layer == 4) { // ML/OT (mixed layer, length = ML but staggered as OT)
nRows = constants::OT::halfstave::nRows;
nCols = constants::ML::nCols;
} else if (subDetID == 1 && layer > 4) { // OT
nRows = constants::OT::halfstave::nRows;
nCols = constants::OT::halfstave::nCols;
}
return (row >= 0 && row < static_cast<float>(nRows) && col >= 0 && col < static_cast<float>(nCols));
}
Expand Down Expand Up @@ -210,9 +221,12 @@ class SegmentationChip
} else if (subDetID == 1 && layer <= 3) { // ML
xRow = 0.5 * (constants::ML::width - PitchRowMLOT) - (row * PitchRowMLOT);
zCol = col * PitchRowMLOT + 0.5 * (PitchRowMLOT - constants::ML::length);
} else if (subDetID == 1 && layer >= 4) { // OT
xRow = 0.5 * (constants::OT::width - PitchRowMLOT) - (row * PitchRowMLOT);
zCol = col * PitchColMLOT + 0.5 * (PitchColMLOT - constants::OT::length);
} else if (subDetID == 1 && layer == 4) { // ML/OT (mixed layer, length = ML but staggered as OT)
xRow = 0.5 * (constants::OT::halfstave::width - PitchRowMLOT) - (row * PitchRowMLOT);
zCol = col * PitchRowMLOT + 0.5 * (PitchRowMLOT - constants::ML::length);
} else if (subDetID == 1 && layer > 4) { // OT
xRow = 0.5 * (constants::OT::halfstave::width - PitchRowMLOT) - (row * PitchRowMLOT);
zCol = col * PitchColMLOT + 0.5 * (PitchColMLOT - constants::OT::halfstave::length);
}
}

Expand Down Expand Up @@ -263,17 +277,25 @@ class SegmentationChip
}

/// Print segmentation info
static const void Print() noexcept
static void Print() noexcept
{
LOG(info) << "Number of rows:\nVD L0: " << constants::VD::petal::layer::nRows[0]
<< "\nVD L1: " << constants::VD::petal::layer::nRows[1]
<< "\nVD L2: " << constants::VD::petal::layer::nRows[2]
<< "\nML stave: " << constants::ML::nRows
<< "\nOT stave: " << constants::OT::nRows;
<< "\nOT half stave: " << constants::OT::halfstave::nRows;

LOG(info) << "Number of cols:\nVD: " << constants::VD::petal::layer::nCols
<< "\nML stave: " << constants::ML::nCols
<< "\nOT stave: " << constants::OT::nCols;
<< "\nOT half stave: " << constants::OT::halfstave::nCols;

LOG(info) << "Pitch rows [cm]:\nVD: " << PitchRowVD
<< "\nML stave: " << PitchRowMLOT
<< "\nOT stave: " << PitchRowMLOT;

LOG(info) << "Pitch cols [cm]:\nVD: " << PitchColVD
<< "\nML stave: " << PitchColMLOT
<< "\nOT stave: " << PitchColMLOT;
}
};

Expand Down
19 changes: 14 additions & 5 deletions Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/Specs.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,25 @@ constexpr int nCols{static_cast<int>(length / chip::pitchZ)};

namespace ML
{
constexpr double width{constants::moduleMLOT::width * 1}; // width of the stave
constexpr double length{constants::moduleMLOT::length * 10}; // length of the stave
constexpr double width{constants::moduleMLOT::width * 1}; // width of the stave
// constexpr double length{constants::moduleMLOT::length * 10}; // length of the stave
constexpr double length{124 * cm}; // length of the stave, hardcoded to fit the implemented geometry
constexpr int nRows{static_cast<int>(width / constants::moduleMLOT::chip::pitchX)}; // number of rows in the stave
constexpr int nCols{static_cast<int>(length / constants::moduleMLOT::chip::pitchZ)}; // number of columns in the stave
} // namespace ML

namespace OT
{ //// TODO: add shorter lenght of the stave of L4
constexpr double width{moduleMLOT::width * 2}; // width of the stave
constexpr double length{moduleMLOT::length * 20}; // length of the stave
{
namespace halfstave
{
constexpr double width{moduleMLOT::width * 1}; // width of the half stave
// constexpr double length{moduleMLOT::length * 20}; // length of the halfstave
constexpr double length{258 * cm}; // length of the halfstave, hardcoded to fit the implemented geometry
constexpr int nRows{static_cast<int>(width / moduleMLOT::chip::pitchX)}; // number of rows in the halfstave
constexpr int nCols{static_cast<int>(length / moduleMLOT::chip::pitchZ)}; // number of columns in the halfstave
} // namespace halfstave
constexpr double width{halfstave::width * 2}; // width of the stave
constexpr double length{halfstave::length}; // length of the stave
constexpr int nRows{static_cast<int>(width / moduleMLOT::chip::pitchX)}; // number of rows in the stave
constexpr int nCols{static_cast<int>(length / moduleMLOT::chip::pitchZ)}; // number of columns in the stave
} // namespace OT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ struct DPLDigitizerParam : public o2::conf::ConfigurableParamHelper<DPLDigitizer
float strobeQRiseTime0 = 450.; ///< q @ which strobe rise time is 0

double timeOffset = 0.; ///< time offset (in seconds!) to calculate ROFrame from hit time
int chargeThreshold = 150; ///< charge threshold in Nelectrons
int minChargeToAccount = 15; ///< minimum charge contribution to account
int nSimSteps = 18; ///< number of steps in response simulation
int chargeThreshold = 1; ///< charge threshold in Nelectrons
int minChargeToAccount = 1; ///< minimum charge contribution to account
int nSimSteps = 25; ///< number of steps in response simulation
float energyToNElectrons = 1. / 3.6e-9; // conversion of eloss to Nelectrons

float Vbb = 0.0; ///< back bias absolute value for MFT (in Volt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ class DigiParams
float mStrobeLength = 0; ///< length of the strobe in ns (sig. over threshold checked in this window only)
double mTimeOffset = -2 * infTime; ///< time offset (in seconds!) to calculate ROFrame from hit time
int mROFrameBiasInBC = 0; ///< misalignment of the ROF start in BC
int mChargeThreshold = 150; ///< charge threshold in Nelectrons
int mMinChargeToAccount = 15; ///< minimum charge contribution to account
int mNSimSteps = 18; ///< number of steps in response simulation
int mChargeThreshold = 1; ///< charge threshold in Nelectrons
int mMinChargeToAccount = 1; ///< minimum charge contribution to account
int mNSimSteps = 25; ///< number of steps in response simulation
float mNSimStepsInv = 0; ///< its inverse

float mEnergyToNElectrons = 1. / 3.6e-9; // conversion of eloss to Nelectrons
Expand Down
43 changes: 14 additions & 29 deletions Detectors/Upgrades/ALICE3/TRK/simulation/src/Digitizer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,29 @@ void Digitizer::init()

/// setting scale factors to adapt to the APTS response function (adjusting pitch and Y shift)
// TODO: adjust Y shift when the geometry is improved
LOG(debug) << " Depth max: " << mChipSimRespVD->getDepthMax();
LOG(debug) << " Depth min: " << mChipSimRespVD->getDepthMin();
LOG(info) << " Depth max VD: " << mChipSimRespVD->getDepthMax();
LOG(info) << " Depth min VD: " << mChipSimRespVD->getDepthMin();

LOG(info) << " Depth max MLOT: " << mChipSimRespMLOT->getDepthMax();
LOG(info) << " Depth min MLOT: " << mChipSimRespMLOT->getDepthMin();

float thicknessVD = 0.0095; // cm --- hardcoded based on geometry currently present
float thicknessMLOT = 0.1; // cm --- hardcoded based on geometry currently present

mSimRespVDScaleX = o2::trk::constants::apts::pitchX / o2::trk::SegmentationChip::PitchRowVD;
mSimRespVDScaleZ = o2::trk::constants::apts::pitchZ / o2::trk::SegmentationChip::PitchColVD;
mSimRespVDScaleDepth = o2::trk::constants::apts::thickness / (thicknessVD); /// introducing this scaling factor because the silicon thickness for the moment is 1 mm -> rescale to 45 um which is the depth of the APTS response
// mSimRespVDShift = mChipSimRespVD->getDepthMax() - thicknessVD * mSimRespVDScaleDepth / 2.f; // the shift should be done considering the rescaling done to adapt to the wrong silicon thickness. TODO: remove the scaling factor for the depth when the silicon thickness match the simulated response
mSimRespVDShift = mChipSimRespVD->getDepthMax(); // the curved, rescaled, sensors have a width from 0 to -45. Must add 10 um (= max depth) to match the APTS response.
mSimRespVDShift = -mChipSimRespVD->getDepthMax(); // the curved, rescaled, sensors have a width from 0 to -45. Must add 10 um (= max depth) to match the APTS response.
mSimRespMLOTScaleX = o2::trk::constants::apts::pitchX / o2::trk::SegmentationChip::PitchRowMLOT;
mSimRespMLOTScaleZ = o2::trk::constants::apts::pitchZ / o2::trk::SegmentationChip::PitchColMLOT;
mSimRespMLOTScaleDepth = o2::trk::constants::apts::thickness / (thicknessMLOT); /// introducing this scaling factor because the silicon thickness for the moment is 1 mm -> rescale to 45 um which is the depth of the APTS response
mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT * mSimRespMLOTScaleDepth / 2.f; // the shift should be done considering the rescaling done to adapt to the wrong silicon thickness. TODO: remove the scaling factor for the depth when the silicon thickness match the simulated response
mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT / 2.f; // the shift should be done considering the rescaling done to adapt to the wrong silicon thickness. TODO: remove the scaling factor for the depth when the silicon thickness match the simulated response
mSimRespOrientation = false;

// importing the parameters from DPLDigitizerParam.h
auto& dOptTRK = DPLDigitizerParam<o2::detectors::DetID::TRK>::Instance();

LOGP(info, "TRK Digitizer is initialised.");
mParams.print();
LOGP(info, "VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT * mSimRespMLOTScaleDepth / 2.f);
LOGP(info, "VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT / 2.f);
LOGP(info, "VD pixel scale on x = {} ; z = {}", mSimRespVDScaleX, mSimRespVDScaleZ);
LOGP(info, "ML/OT pixel scale on x = {} ; z = {}", mSimRespMLOTScaleX, mSimRespMLOTScaleZ);
LOGP(info, "Response orientation: {}", mSimRespOrientation ? "flipped" : "normal");
Expand Down Expand Up @@ -115,8 +115,8 @@ void Digitizer::process(const std::vector<Hit>* hits, int evID, int srcID)
<< " cont.mode: " << isContinuous()
<< " Min/Max ROFrames " << mROFrameMin << "/" << mROFrameMax;

std::cout << "Printing segmentation info: " << std::endl;
SegmentationChip::Print();
// std::cout << "Printing segmentation info: " << std::endl;
// SegmentationChip::Print();

// // is there something to flush ?
if (mNewROFrame > mROFrameMin) {
Expand Down Expand Up @@ -335,13 +335,9 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID

//// adapting the depth (Y) of the chip to the APTS response maximum depth
LOG(debug) << "local original: startPos = " << xyzLocS << ", endPos = " << xyzLocE << std::endl;
if (subDetID == 0) {
xyzLocS.SetY(xyzLocS.Y() * mSimRespVDScaleDepth);
xyzLocE.SetY(xyzLocE.Y() * mSimRespVDScaleDepth);
} else {
xyzLocS.SetY(xyzLocS.Y() * mSimRespMLOTScaleDepth);
xyzLocE.SetY(xyzLocE.Y() * mSimRespMLOTScaleDepth);
}
xyzLocS.SetY(xyzLocS.Y());
xyzLocE.SetY(xyzLocE.Y());

LOG(debug) << "rescaled Y: startPos = " << xyzLocS << ", endPos = " << xyzLocE << std::endl;

math_utils::Vector3D<float> step(xyzLocE);
Expand Down Expand Up @@ -449,17 +445,6 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID
rspmat = resp->getResponse(mSimRespMLOTScaleX * (xyzLocS.X() - cRowPix), mSimRespMLOTScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
}

float tempPitchX = 0, tempPitchZ = 0;
if (subDetID == 0) {
tempPitchX = Segmentation::PitchRowVD;
tempPitchZ = Segmentation::PitchColVD;
} else {
tempPitchX = Segmentation::PitchRowMLOT;
tempPitchZ = Segmentation::PitchColMLOT;
}
LOG(debug) << "X and Z inside pixel at start = " << (xyzLocS.X() - cRowPix) << " , " << (xyzLocS.Z() - cColPix) << ", rescaled: " << mSimRespMLOTScaleX * (xyzLocS.X() - cRowPix) << " , " << mSimRespMLOTScaleZ * (xyzLocS.Z() - cColPix);
LOG(debug) << "Hit inside pitch? X: " << ((xyzLocS.X() - cRowPix) < tempPitchX) << " Z: " << ((xyzLocS.Z() - cColPix) < tempPitchZ);

xyzLocS += step;

if (rspmat == nullptr) {
Expand All @@ -479,7 +464,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID
if (colDest < 0 || colDest >= colSpan) {
continue;
}
respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, mSimRespOrientation ? !flipRow : flipRow, flipCol);
respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, mSimRespOrientation ? !flipRow : flipRow, !flipCol);
}
}
}
Expand Down