133 const std::map<std::string, std::string> ¶meters)
135 int circuitsPerEta{2};
136 int circuitsPerPhi{2};
137 double thickness{0.150};
140 double pitchEtaLong{};
141 double pitchPhiLong{};
142 double pitchEtaEnd{};
143 double pitchPhiEnd{};
144 int nEtaLongPerSide{};
145 int nPhiLongPerSide{};
146 int nEtaEndPerSide{};
147 int nPhiEndPerSide{};
148 int rowsPerCircuit{};
149 int columnsPerCircuit{};
156 bool phiSymmetric{
true};
157 bool etaSymmetric{
true};
158 bool depthSymmetric{
true};
161 getParameter(typeName, parameters,
"circuitsPerEta", circuitsPerEta);
162 getParameter(typeName, parameters,
"circuitsPerPhi", circuitsPerPhi);
163 getParameter(typeName, parameters,
"thickness", thickness);
164 getParameter(typeName, parameters,
"is3D", is3D);
165 getParameter(typeName, parameters,
"rows", rowsPerCircuit);
166 getParameter(typeName, parameters,
"columns", columnsPerCircuit);
167 getParameter(typeName, parameters,
"pitchEta", pitchEta);
168 getParameter(typeName, parameters,
"pitchPhi", pitchPhi);
169 getParameter(typeName, parameters,
"pitchEtaLong", pitchEtaLong);
170 getParameter(typeName, parameters,
"pitchPhiLong", pitchPhiLong);
171 getParameter(typeName, parameters,
"pitchEtaEnd", pitchEtaEnd);
172 getParameter(typeName, parameters,
"pitchPhiEnd", pitchPhiEnd);
173 getParameter(typeName, parameters,
"nPhiLongPerSide", nPhiLongPerSide);
174 getParameter(typeName, parameters,
"nEtaLongPerSide", nEtaLongPerSide);
175 getParameter(typeName, parameters,
"nPhiEndPerSide", nPhiEndPerSide);
176 getParameter(typeName, parameters,
"nEtaEndPerSide", nEtaEndPerSide);
178 checkParameter(typeName, parameters,
"phiSymmetric", phiSymmetric);
179 checkParameter(typeName, parameters,
"etaSymmetric", etaSymmetric);
180 checkParameter(typeName, parameters,
"depthSymmetric", depthSymmetric);
185 ATH_MSG_DEBUG(
"readout geo - design thickness " << thickness <<
" "
186 <<
" circuits " << circuitsPerPhi <<
" " << circuitsPerEta <<
" "
187 <<
" rows/columns " << rowsPerCircuit <<
" " << columnsPerCircuit <<
" "
188 <<
" pitch regular/long/end " << pitchPhi <<
" " << pitchEta
189 <<
" " << pitchPhiLong <<
" " << pitchEtaLong
190 <<
" " << pitchPhiEnd <<
" " << pitchEtaEnd
191 <<
" n-long " << nPhiLongPerSide <<
" " << nEtaLongPerSide
192 <<
" n-end " << nPhiEndPerSide <<
" " << nEtaEndPerSide
193 << carrier <<
" " << readoutSide);
198 int detectorTypeEnum = 0;
199 if (checkParameter(typeName, parameters,
"detectorType", detectorTypeEnum)) {
207 if ( circuitsPerPhi*rowsPerCircuit<0 || circuitsPerPhi*rowsPerCircuit >= std::numeric_limits<PixelDiodeTree::CellIndexType>::max()
208 || circuitsPerEta*columnsPerCircuit<0 || circuitsPerEta*columnsPerCircuit >= std::numeric_limits<PixelDiodeTree::CellIndexType>::max()) {
209 std::stringstream amsg;
210 amsg <<
"Index overflows index type of PixelDiodeTree. Parameters "
211 <<
"( " << circuitsPerPhi <<
" * " << rowsPerCircuit <<
" ), ( "
212 <<
"( " << circuitsPerEta <<
" * " << columnsPerCircuit <<
" ) !<"
213 << std::numeric_limits<PixelDiodeTree::CellIndexType>::max() <<
" each.";
214 throw std::runtime_error(amsg.str());
219 bool flipFE=(typeName.find(
"_even") !=std::string::npos);
223 auto computeAttribute = [readoutTechnology,
231 ](
const std::array<PixelDiodeTree::IndexType,2> &split_idx,
233 [[maybe_unused]]
const std::array<bool,4> &ganged,
234 [[maybe_unused]]
unsigned int split_i,
237 -> std::tuple<PixelDiodeTree::AttributeType,PixelDiodeTree::AttributeType>
257 assert(split_idx[0]>=0 && split_idx[1]>=0);
258 std::array<int,2> chip_idx{split_idx[0]/rowsPerCircuit, split_idx[1]/columnsPerCircuit};
260 unsigned int n_large_dimensions = ( (std::abs(diode_width[0]-pitchPhi)>pitchPhi*.25)
261 +(std::abs(diode_width[1]-pitchEta)>pitchEta*.25));
262 switch (n_large_dimensions) {
306 ? circuitsPerEta - chip_idx[1] - 1
307 : (circuitsPerPhi-1) * circuitsPerEta + chip_idx[1]);
309 return std::make_tuple(current_matrix_attribute, current_diode_attribute);
313 =
createPixelDiodeTree(std::array<unsigned int,2>{
static_cast<unsigned int>(circuitsPerPhi),
static_cast<unsigned int>(circuitsPerEta)},
314 std::array<unsigned int,2>{
static_cast<unsigned int>(rowsPerCircuit),
static_cast<unsigned int>(columnsPerCircuit)},
316 std::array<std::array<unsigned int,2>, 2>{ std::array<unsigned int,2>{
static_cast<unsigned int>(nPhiEndPerSide),
317 static_cast<unsigned int>(nEtaEndPerSide)},
318 std::array<unsigned int,2>{
static_cast<unsigned int>(nPhiLongPerSide),
319 static_cast<unsigned int>(nEtaLongPerSide)}},
323 std::array<std::array<unsigned int,2>, 2>{ std::array<unsigned int,2>{0u,0u},
324 std::array<unsigned int,2>{0u,0u}
329 auto design = std::make_unique<PixelModuleDesign>(thickness,
330 phiSymmetric, etaSymmetric, depthSymmetric,
331 circuitsPerPhi, circuitsPerEta,
332 columnsPerCircuit, rowsPerCircuit,
333 columnsPerCircuit, rowsPerCircuit,
334 std::move(diode_tree), carrier,
335 readoutSide, is3D, detectorType, readoutTechnology);
338 <<
" " << design->width() <<
"x" << design->length() <<
"x" << design->thickness()
339 <<
" " << design->rows() <<
"x" << design->columns()
340 <<
", " << circuitsPerPhi <<
"x" << circuitsPerEta <<
" "
341 << rowsPerCircuit <<
" " << columnsPerCircuit <<
":\n"
344 [[maybe_unused]]
auto observePtr =
m_detectorManager->addDesign(std::move(design));
431 const std::array<std::string,2> sensorTypes{
"QuadChip_RD53",
"SingleChip_RD53"};
432 const std::array<std::string,17> rd53_ParamNames{
"circuitsPerEta",
"circuitsPerPhi",
"columns",
"detectorType",
"is3D",
"nEtaEndPerSide",
"nEtaLongPerSide",
"nPhiEndPerSide",
"nPhiLongPerSide",
"pitchEta",
"pitchEtaEnd",
"pitchEtaLong",
"pitchPhi",
"pitchPhiEnd",
"pitchPhiLong",
"rows",
"thickness"};
434 for(
const std::string & sType:sensorTypes){
436 if(rd53->
size() !=0){
437 for (
unsigned int iR =0;iR<rd53->
size();iR++){
438 std::map<std::string,std::string> rd53_Map;
439 for(
const std::string & paramName:rd53_ParamNames){
440 std::string paramValue = (*rd53)[iR]->getString(paramName);
441 rd53_Map[paramName] = std::move(paramValue);
443 std::string rd35_Name = (*rd53)[iR]->getString(
"SensorType");
447 if ( rd35_Name.find(
"Quad")!= std::string::npos
448 && ( rd35_Name.find(
"endcap")!= std::string::npos
449 || rd35_Name.find(
"inclined")!= std::string::npos)) {
459 const std::array<std::string,5> fields{
"barrel_endcap",
"layer_wheel",
"phi_module",
"eta_module",
"side"};
462 const std::array<std::string,3> publishers({
"ITk",
"ITkPixel",
"GeoModelXML"});
465 std::map<std::string, GeoFullPhysVol*> mapFPV;
466 for (
auto & iPub : publishers){
468 mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,
true);
469 if (!mapFPV.empty()) {
474 if (mapFPV.empty())
ATH_MSG_ERROR(
"Could not find any FPV tables under the expected names: "<<publishers);
476 for (
const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
478 size_t startRG = fullPhysVolInfoString.find(
"RD53_");
479 if(startRG==std::string::npos){
480 ATH_MSG_DEBUG(
"GeoFullPhysVol "<<fullPhysVolInfoString<<
" does not have the expected format. Skipping");
483 std::string typeName = fullPhysVolInfoString.substr(startRG);
484 std::map<std::string, int>
index;
485 for (
const std::string & field:fields){
486 size_t first = fullPhysVolInfoString.find(field+
"_");
487 size_t last = fullPhysVolInfoString.find(
'_',first+field.size()+1);
488 if(first==std::string::npos || last==std::string::npos){
489 ATH_MSG_DEBUG(
"Could not extract "<<field<<
" from "<<fullPhysVolInfoString<<
". Skipping");
492 std::string strNew = fullPhysVolInfoString.substr(first+field.size()+1,last-(first+field.size()+1));
493 index[field] = std::stoi(strNew);
PixelDiodeTree createPixelDiodeTree(const std::array< unsigned int, 2 > &chip_dim, const std::array< unsigned int, 2 > &chip_matrix_dim, const PixelDiodeTree::Vector2D &pitch, const std::array< std::array< unsigned int, 2 >, 2 > &edge_dim, const std::array< PixelDiodeTree::Vector2D, 2 > &edge_pitch, const std::array< std::array< unsigned int, 2 >, 2 > &dead_zone, const AttributeRefiner &func_compute_attribute, std::ostream *debug_out=nullptr)
Create a pixel diode tree.