ATLAS Offline Software
Loading...
Searching...
No Matches
PixelDigitization Namespace Reference

Functions

std::string formBichselDataFileName (int particleType, unsigned int nCols)
BichselData getBichselDataFromFile (const std::string &fullFilename)
std::tuple< double, double, double > parseThreeDoubles (const std::string &line)
std::pair< int, int > fastSearch (const std::vector< double > &vec, double item)
double randomThreshold (const PixelChargeCalib::Thresholds &t, CLHEP::HepRandomEngine *pEngine)
void crossTalk (double crossTalk, SiChargedDiodeCollection &chargedDiodes)
void thermalNoise (double thermalNoise, SiChargedDiodeCollection &chargedDiodes, CLHEP::HepRandomEngine *rndmEngine)
void randomNoise (SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, int nBcid, const PixelChargeCalibCondData *chargeCalibData, CLHEP::HepRandomEngine *rndmEngine, InDetDD::IPixelReadoutManager *pixelReadout)
void randomNoise (SiChargedDiodeCollection &chargedDiodes, const ITkPixSimulationParameters &chipData, int nBcid, const PixelChargeCalibCondData *chargeCalibData, CLHEP::HepRandomEngine *rndmEngine, InDetDD::IPixelReadoutManager *pixelReadout)
void randomNoise (SiChargedDiodeCollection &chargedDiodes, const double totalNoiseOccupancy, const std::vector< float > &noiseShape, float overflowToT, const PixelChargeCalibCondData *chargeCalibData, CLHEP::HepRandomEngine *rndmEngine, InDetDD::IPixelReadoutManager *pixelReadout)
void randomDisable (SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, CLHEP::HepRandomEngine *rndmEngine)
void randomDisable (SiChargedDiodeCollection &chargedDiodes, const ITkPixSimulationParameters &chipData, CLHEP::HepRandomEngine *rndmEngine)
void randomDisable (SiChargedDiodeCollection &chargedDiodes, double disableProbability, CLHEP::HepRandomEngine *rndmEngine)
int generateToT (CLHEP::HepRandomEngine *rndmEngine, double mean, double sd, const std::pair< int, int > &range)
double getG4Time (const SiTotalCharge &totalCharge)

Function Documentation

◆ crossTalk()

void PixelDigitization::crossTalk ( double crossTalk,
SiChargedDiodeCollection & chargedDiodes )

Definition at line 28 of file PixelNoiseFunctions.cxx.

28 {
29 const InDetDD::PixelModuleDesign* p_design =
30 static_cast<const InDetDD::PixelModuleDesign*>(&(chargedDiodes.element())->design());
31 SiChargedDiodeMap oldChargedDiodes = chargedDiodes.chargedDiodes();
32
33 for (SiChargedDiodeIterator i_chargedDiode = oldChargedDiodes.begin(); i_chargedDiode != oldChargedDiodes.end();
34 ++i_chargedDiode) {
35 InDetDD::SiCellId diode = (*i_chargedDiode).second.diode();
36 std::vector<InDetDD::SiCellId> neighbours;
37 p_design->neighboursOfCell(diode, neighbours);
38 for (std::vector<InDetDD::SiCellId>::const_iterator p_neighbour = neighbours.begin();
39 p_neighbour != neighbours.end(); ++p_neighbour) {
40 const double intersection = p_design->intersectionLength(diode, *p_neighbour);
41 // add cross talk only if the intersection is non-zero
42 // if the original pixel is at (col,row) then the intersection length is
43 // (col+-1, row+-1) : 0 -> diagonal
44 // (col , row+-1) : 0.4 mm (or 0.6 if long pixel) pixel width = 400um or 600um
45 // (col+-1, row ) : 0.05 mm , pixel height = 50um
46 // intersection length is just the length of the contact surface between the two pixels
47 if (intersection > 0) {
48 // create a new charge:
49 // Q(new) = Q*L*X
50 // Q = charge of source pixel
51 // L = intersection length [mm]
52 // X = crosstalk factor [mm-1]
53 const SiChargedDiode& siCharge = (*i_chargedDiode).second;
56 chargedDiodes.add(*p_neighbour, charge);
57 }
58 }
59 }
60 return;
61 }
double charge(const T &p)
Definition AtlasPID.h:997
SiChargedDiodeMap::iterator SiChargedDiodeIterator
std::unordered_map< InDetDD::SiCellId, SiChargedDiode, SiChargedDiodeHash, std::equal_to< InDetDD::SiCellId >, SG::ArenaPoolSTLAllocator< std::pair< const InDetDD::SiCellId, SiChargedDiode > > > SiChargedDiodeMap
Class used to describe the design of a module (diode segmentation and readout scheme)
double intersectionLength(const SiCellId &diode1, const SiCellId &diode2) const
Compute the intersection length of two diodes: return: the intersection length when the two diodes ar...
virtual void neighboursOfCell(const SiCellId &cellId, std::vector< SiCellId > &neighbours) const
Get the neighbouring diodes of a given diode: Cell for which the neighbours must be found List of cel...
Identifier for the strip or pixel cell.
Definition SiCellId.h:29
@ diodeX_Talk
Definition SiCharge.h:28
SiChargedDiodeMap & chargedDiodes()
const InDetDD::SolidStateDetectorElementBase * element() const
void add(const InDetDD::SiCellId &diode, const T &charge)
double charge() const
const SiTotalCharge & totalCharge() const
const HepMcParticleLink & particleLink() const
double time() const
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
void crossTalk(double crossTalk, SiChargedDiodeCollection &chargedDiodes)

◆ fastSearch()

std::pair< int, int > PixelDigitization::fastSearch ( const std::vector< double > & vec,
double item )

Definition at line 73 of file PixelDigitizationUtilities.cxx.

73 {
74 std::pair<int, int> output{-1, -1};
75 if (vec.empty()) return output;
76 int index_low = 0;
77 int index_up = vec.size() - 1;
78 if ((item < vec[index_low]) || (item > vec[index_up])) {
79 return output;
80 } else if (item == vec[index_low]) {
81 output.first = index_low;
82 output.second = index_low;
83 return output;
84 } else if (item == vec[index_up]) {
85 output.first = index_up;
86 output.second = index_up;
87 return output;
88 }
89 while ((index_up - index_low) != 1) {
90 int index_middle = int(1.0 * (index_up + index_low) / 2.);
91 if (item < vec[index_middle]) index_up = index_middle;
92 else if (item > vec[index_middle]) index_low = index_middle;
93 else { // accurate hit. Though this is nearly impossible ...
94 output.first = index_middle;
95 output.second = index_middle;
96 return output;
97 }
98 }
99 output.first = index_low;
100 output.second = index_up;
101 return output;
102 }
std::vector< size_t > vec
output
Definition merge.py:16

◆ formBichselDataFileName()

std::string PixelDigitization::formBichselDataFileName ( int particleType,
unsigned int nCols )

Definition at line 18 of file PixelDigitizationUtilities.cxx.

18 {
19 const std::string prefix{"PixelDigitization/Bichsel_"};
20 const std::string suffix{".dat"};
21 const std::string particleTypeString = std::to_string(particleType);
22 const std::string nColString= (nCols == 1) ? "" : "_" + std::to_string(nCols) + "steps";
23 return prefix + particleTypeString + nColString + suffix;
24 }
static std::string to_string(const std::vector< T > &v)
unsigned int constexpr nCols
Definition RPDUtils.h:25

◆ generateToT()

int PixelDigitization::generateToT ( CLHEP::HepRandomEngine * rndmEngine,
double mean,
double sd,
const std::pair< int, int > & range )

Definition at line 192 of file PixelNoiseFunctions.cxx.

192 {
193 int nToT = static_cast<int>(CLHEP::RandGaussZiggurat::shoot(rndmEngine, mean, sd));
194 const auto &[lo,hi] = range;
195 //
196 if (nToT < lo) {
197 nToT = lo;
198 }
199 if (nToT >= hi) {
200 nToT = hi;
201 }
202 return nToT;
203 }
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")

◆ getBichselDataFromFile()

BichselData PixelDigitization::getBichselDataFromFile ( const std::string & fullFilename)

Definition at line 28 of file PixelDigitizationUtilities.cxx.

28 {
29 std::ifstream inputFile(fullFilename);
30 if (not inputFile){
31 std::string errmsg = "getBichselDataFromFile: File " + fullFilename +" could not be opened.";
32 throw std::runtime_error(errmsg);
33 }
34 BichselData iData;
35 std::string thisLine;
36 thisLine.reserve(60); //expecting maximum line length to be 53, allow some margin
37 while (getline(inputFile, thisLine)) {
38 const auto & [logBetaGamma, logCollisionEnergy, logCrossSection] = parseThreeDoubles(thisLine);
39 iData.addEntry(logBetaGamma, logCollisionEnergy, logCrossSection);
40 }
42 return iData;
43 }
static thread_local std::ostringstream errmsg
Definition WaferTree.h:25
std::tuple< double, double, double > parseThreeDoubles(const std::string &line)
std::vector< std::vector< double > > logIntegratedCrossSectionsVectorOfVector
Definition BichselData.h:18
void addEntry(double logBetaGamma, double logCollisionEnergy, double logIntegratedCrossSection)
std::vector< double > logHighestCrossSectionsVector
Definition BichselData.h:19

◆ getG4Time()

double PixelDigitization::getG4Time ( const SiTotalCharge & totalCharge)

Definition at line 206 of file PixelNoiseFunctions.cxx.

206 {
207 // If there is one single charge, return its time:
208 if (totalCharge.chargeComposition().empty()) {
209 return totalCharge.time();
210 }
211 auto p_charge = totalCharge.chargeComposition().begin();
212 int findfirst = 0;
213 SiCharge first = *p_charge;
214 // Look for first charge which is not noise
215 for (; p_charge != totalCharge.chargeComposition().end(); p_charge++) {
216 if (p_charge->processType() != SiCharge::noise) {
217 findfirst = 1;
218 break;
219 }
220 }
221 // if all charges were noise, return the time of the highest charge
222 if (findfirst == 0) {
223 return totalCharge.time();
224 }
225 // look for the earliest charge among the remaining non-noise charges:
226 first = *p_charge;
227 p_charge++;
228 for (; p_charge != totalCharge.chargeComposition().end(); p_charge++) {
229 if (p_charge->time() < first.time() && p_charge->processType() != SiCharge::noise) {
230 first = *p_charge;
231 }
232 }
233 return first.time();
234 }
const list_t & chargeComposition() const
bool first
Definition DeMoScan.py:534

◆ parseThreeDoubles()

std::tuple< double, double, double > PixelDigitization::parseThreeDoubles ( const std::string & line)

Definition at line 47 of file PixelDigitizationUtilities.cxx.

47 {
48 std::tuple<double, double, double> result{0., 0.,0.};
49 //in local testing, making the following 'static const' reduced the test time (one parse)
50 //from 1 637us to 455us. A total file parse test (209 lines of data) was reduced from
51 //54 156us to 3 657us
52 static const std::regex threeDoublesRx("^([-+.0-9eE]+)\\s+([-+.0-9eE]+)\\s+([-+.0-9eE]+)$");
53 std::smatch x3;
54 bool foundDoubles=std::regex_match(line, x3, threeDoublesRx);
55 if (foundDoubles){
56 try{
57 //std::stod might throw a out_of_range or an invalid_argument error
58 //both of which are subclasses of logic_error
59 result = {std::stod(x3[1]), std::stod(x3[2]), std::stod(x3[3])};
60 } catch (std::logic_error & e){
61 const std::string msg("parseThreeDoubles: error in parsing a number in "+ line);
62 throw(std::runtime_error(msg));
63 }
64 } else {
65 const std::string msg("parseThreeDoubles: error in parsing the line " + line);
66 throw(std::runtime_error(msg));
67 }
68 return result;
69 }
MsgStream & msg
Definition testRead.cxx:32

◆ randomDisable() [1/3]

void PixelDigitization::randomDisable ( SiChargedDiodeCollection & chargedDiodes,
const ITkPixSimulationParameters & chipData,
CLHEP::HepRandomEngine * rndmEngine )

Definition at line 173 of file PixelNoiseFunctions.cxx.

174 {
175 const double disableProbability = chipData.disableProbability();
176 return randomDisable(chargedDiodes, disableProbability, rndmEngine);
177 }
void randomDisable(SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, CLHEP::HepRandomEngine *rndmEngine)

◆ randomDisable() [2/3]

void PixelDigitization::randomDisable ( SiChargedDiodeCollection & chargedDiodes,
const PixelModuleData * moduleData,
CLHEP::HepRandomEngine * rndmEngine )

Definition at line 164 of file PixelNoiseFunctions.cxx.

165 {
166 const PixelID* pixelId = static_cast<const PixelID*>(chargedDiodes.element()->getIdHelper());
167 const int barrel_ec = pixelId->barrel_ec(chargedDiodes.element()->identify());
168 const int layerIndex = pixelId->layer_disk(chargedDiodes.element()->identify());
169 const double disableProbability = moduleData->getDisableProbability(barrel_ec, layerIndex);
170 return randomDisable(chargedDiodes, disableProbability, rndmEngine);
171 }
virtual Identifier identify() const override final
identifier of this detector element (inline)
This is an Identifier helper class for the Pixel subdetector.
Definition PixelID.h:67
int layer_disk(const Identifier &id) const
Definition PixelID.h:607
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition PixelID.h:600
double getDisableProbability(int barrel_ec, int layer) const

◆ randomDisable() [3/3]

void PixelDigitization::randomDisable ( SiChargedDiodeCollection & chargedDiodes,
double disableProbability,
CLHEP::HepRandomEngine * rndmEngine )

Definition at line 180 of file PixelNoiseFunctions.cxx.

181 {
182 for (SiChargedDiodeOrderedIterator i_chargedDiode = chargedDiodes.orderedBegin();
183 i_chargedDiode != chargedDiodes.orderedEnd(); ++i_chargedDiode) {
184 if (CLHEP::RandFlat::shoot(rndmEngine) < disableProbability) {
185 SiHelper::disabled(**i_chargedDiode, true, false);
186 }
187 }
188 return;
189 }
SiChargedDiodeOrderedSet::iterator SiChargedDiodeOrderedIterator
SiChargedDiodeOrderedIterator orderedEnd()
SiChargedDiodeOrderedIterator orderedBegin()
static void disabled(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition SiHelper.h:93

◆ randomNoise() [1/3]

void PixelDigitization::randomNoise ( SiChargedDiodeCollection & chargedDiodes,
const double totalNoiseOccupancy,
const std::vector< float > & noiseShape,
float overflowToT,
const PixelChargeCalibCondData * chargeCalibData,
CLHEP::HepRandomEngine * rndmEngine,
InDetDD::IPixelReadoutManager * pixelReadout )

Definition at line 115 of file PixelNoiseFunctions.cxx.

116 {
117 const InDetDD::PixelModuleDesign* p_design =
118 static_cast<const InDetDD::PixelModuleDesign*>(&(chargedDiodes.element())->design());
119
120 const PixelID* pixelId = static_cast<const PixelID*>(chargedDiodes.element()->getIdHelper());
121 const IdentifierHash moduleHash = pixelId->wafer_hash(chargedDiodes.identify()); // wafer hash
122 const auto nCircuits = p_design->numberOfCircuits();
123 const auto nColumns = p_design->columnsPerCircuit();
124 const auto nRows = p_design->rowsPerCircuit();
125 const auto totalCells = nCircuits * nColumns * nRows;
126 int nNoise = CLHEP::RandPoisson::shoot(rndmEngine, totalCells * totalNoiseOccupancy);
127 //prepare to enter loop
128 const auto technology = p_design->getReadoutTechnology();
129 for (int i = 0; i < nNoise; i++) {
130 int circuit = CLHEP::RandFlat::shootInt(rndmEngine, nCircuits);
131 int column = CLHEP::RandFlat::shootInt(rndmEngine, nColumns);
132 int row = CLHEP::RandFlat::shootInt(rndmEngine, nRows);
133 if (row > 159 && technology == InDetDD::PixelReadoutTechnology::FEI3) {
134 row += 8;
135 } // jump over ganged pixels - rowsPerCircuit == 320 above
136
137 InDetDD::SiReadoutCellId roCell(row, nColumns * circuit + column);
138 Identifier noisyID = chargedDiodes.element()->identifierFromCellId(roCell);
139
140 if (roCell.isValid()) {
141 InDetDD::SiCellId diodeNoise = roCell;
142 float x = static_cast<float>(CLHEP::RandFlat::shoot(rndmEngine, 0., 1.)); // returns double
143 size_t bin{};
144 for (size_t j = 1; j < noiseShape.size(); j++) {
145 if (x > noiseShape[j - 1] && x <= noiseShape[j]) {
146 bin = j - 1;
147 break;
148 }
149 }
150 float noiseToTm = bin + 1.5f;
151 float noiseToT = CLHEP::RandGaussZiggurat::shoot(rndmEngine, noiseToTm, 1.f);
152 if (noiseToT < 1.f) { continue; } // throw away unphysical noise
153 noiseToT = std::min(noiseToT, overflowToT);
154 InDetDD::PixelDiodeType type = pixelReadout->getDiodeType(noisyID);
155 if (type == InDetDD::PixelDiodeType::NONE) continue;
156 float chargeShape = chargeCalibData->getCharge(type, moduleHash, circuit, noiseToT);
157 chargedDiodes.add(diodeNoise, SiCharge(chargeShape, 0, SiCharge::noise));
158 }
159 }
160 return;
161 }
#define x
This is a "hash" representation of an Identifier.
virtual PixelDiodeType getDiodeType(Identifier id) const =0
PixelReadoutTechnology getReadoutTechnology() const
int rowsPerCircuit() const
Number of cell rows per circuit:
int numberOfCircuits() const
Total number of circuits:
int columnsPerCircuit() const
Number of cell columns per circuit:
Identifier for the strip or pixel readout cell.
virtual Identifier identifierFromCellId(const SiCellId &cellId) const =0
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
float getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition PixelID.h:383
virtual Identifier identify() const override final

◆ randomNoise() [2/3]

void PixelDigitization::randomNoise ( SiChargedDiodeCollection & chargedDiodes,
const ITkPixSimulationParameters & chipData,
int nBcid,
const PixelChargeCalibCondData * chargeCalibData,
CLHEP::HepRandomEngine * rndmEngine,
InDetDD::IPixelReadoutManager * pixelReadout )

Definition at line 101 of file PixelNoiseFunctions.cxx.

104 {
105 const double totalNoiseOccupancy = chipData.noiseOccupancy() * nBcid;
106 //prepare to enter loop
107 const std::vector<float> &noiseShape = chipData.noiseShape();
108 // protection to the overflow ToT, that depends on the sensor technology
109 float overflowToT = std::numeric_limits<float>::max();
110 return randomNoise(chargedDiodes, totalNoiseOccupancy, noiseShape, overflowToT, chargeCalibData, rndmEngine, pixelReadout);
111 }
const std::vector< float > & noiseShape() const
void randomNoise(SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, int nBcid, const PixelChargeCalibCondData *chargeCalibData, CLHEP::HepRandomEngine *rndmEngine, InDetDD::IPixelReadoutManager *pixelReadout)

◆ randomNoise() [3/3]

void PixelDigitization::randomNoise ( SiChargedDiodeCollection & chargedDiodes,
const PixelModuleData * moduleData,
int nBcid,
const PixelChargeCalibCondData * chargeCalibData,
CLHEP::HepRandomEngine * rndmEngine,
InDetDD::IPixelReadoutManager * pixelReadout )

Definition at line 76 of file PixelNoiseFunctions.cxx.

79 {
80 const InDetDD::PixelModuleDesign* p_design =
81 static_cast<const InDetDD::PixelModuleDesign*>(&(chargedDiodes.element())->design());
82
83 const PixelID* pixelId = static_cast<const PixelID*>(chargedDiodes.element()->getIdHelper());
84 int barrel_ec = pixelId->barrel_ec(chargedDiodes.element()->identify());
85 int layerIndex = pixelId->layer_disk(chargedDiodes.element()->identify());
86 const double totalNoiseOccupancy = moduleData->getNoiseOccupancy(barrel_ec,layerIndex) * nBcid;
87 //prepare to enter loop
88 const std::vector<float> &noiseShape = moduleData->getNoiseShape(barrel_ec, layerIndex);
89 const auto technology = p_design->getReadoutTechnology();
90 // protection to the overflow ToT, that depends on the sensor technology
91 float overflowToT = std::numeric_limits<float>::max();
92 if (technology == InDetDD::PixelReadoutTechnology::FEI4) {
93 overflowToT = chargeCalibData->getFEI4OverflowToT();
94 } else if (technology == InDetDD::PixelReadoutTechnology::FEI3) {
95 overflowToT = moduleData->getFEI3Latency(barrel_ec, layerIndex);
96 }
97 return randomNoise(chargedDiodes, totalNoiseOccupancy, noiseShape, overflowToT, chargeCalibData, rndmEngine, pixelReadout);
98 }
constexpr int getFEI4OverflowToT() const
int getFEI3Latency(int barrel_ec, int layer) const
const std::vector< float > & getNoiseShape(int barrel_ec, int layer) const
double getNoiseOccupancy(int barrel_ec, int layer) const

◆ randomThreshold()

double PixelDigitization::randomThreshold ( const PixelChargeCalib::Thresholds & t,
CLHEP::HepRandomEngine * pEngine )

Definition at line 105 of file PixelDigitizationUtilities.cxx.

105 {
106 const double & thrand1 = CLHEP::RandGaussZiggurat::shoot(pEngine);
107 const double & thrand2 = CLHEP::RandGaussZiggurat::shoot(pEngine);
108 return t.value + t.sigma * thrand1 + t.noise * thrand2;
109 }

◆ thermalNoise()

void PixelDigitization::thermalNoise ( double thermalNoise,
SiChargedDiodeCollection & chargedDiodes,
CLHEP::HepRandomEngine * rndmEngine )

Definition at line 64 of file PixelNoiseFunctions.cxx.

65 {
66 for (SiChargedDiodeOrderedIterator i_chargedDiode = chargedDiodes.orderedBegin();
67 i_chargedDiode != chargedDiodes.orderedEnd(); ++i_chargedDiode) {
68 SiCharge charge(thermalNoise * CLHEP::RandGaussZiggurat::shoot(rndmEngine), 0, SiCharge::noise);
69 (*i_chargedDiode)->add(charge);
70 }
71 return;
72 }
void thermalNoise(double thermalNoise, SiChargedDiodeCollection &chargedDiodes, CLHEP::HepRandomEngine *rndmEngine)