ATLAS Offline Software
Loading...
Searching...
No Matches
InDetDD::ITk::StripGmxInterface Class Reference

#include <StripGmxInterface.h>

Inheritance diagram for InDetDD::ITk::StripGmxInterface:
Collaboration diagram for InDetDD::ITk::StripGmxInterface:

Public Member Functions

 StripGmxInterface (SCT_DetectorManager *detectorManager, SiCommonItems *commonItems, WaferTree *waferTree)
virtual int sensorId (std::map< std::string, int > &index) const override final
virtual int splitSensorId (std::map< std::string, int > &index, std::pair< std::string, int > &extraIndex, std::map< std::string, int > &updatedIndex) const override final
virtual void addSensorType (const std::string &clas, const std::string &typeName, const std::map< std::string, std::string > &parameters) override final
void addSensor (const std::string &typeName, std::map< std::string, int > &index, int sequentialId, GeoVFullPhysVol *fpv) override final
void addSplitSensor (const std::string &typeName, std::map< std::string, int > &index, std::pair< std::string, int > &extraIndex, int sequentialId, GeoVFullPhysVol *fpv, int splitLevel) override final
virtual void addAlignable (int level, std::map< std::string, int > &index, GeoVFullPhysVol *fpv, GeoAlignableTransform *transform) override final
virtual void addSplitAlignable (int level, std::map< std::string, int > &index, std::pair< std::string, int > &extraIndex, GeoVFullPhysVol *fpv, GeoAlignableTransform *transform) override final
void buildReadoutGeometryFromSqlite (IRDBAccessSvc *rdbAccessSvc, GeoModelIO::ReadGeoModel *sqlreader)
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Member Functions

void makeSiStripBox (const std::string &typeName, const std::map< std::string, std::string > &parameters)
void makeStereoAnnulus (const std::string &typeName, const std::map< std::string, std::string > &parameters)
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

std::map< std::string, const SiDetectorDesign * > m_geometryMap
std::map< std::string, const SCT_ModuleSideDesign * > m_motherMap
SCT_DetectorManagerm_detectorManager {}
SiCommonItemsm_commonItems {}
WaferTreem_waferTree {}
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels).
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging).

Detailed Description

Definition at line 29 of file StripGmxInterface.h.

Constructor & Destructor Documentation

◆ StripGmxInterface()

InDetDD::ITk::StripGmxInterface::StripGmxInterface ( SCT_DetectorManager * detectorManager,
SiCommonItems * commonItems,
WaferTree * waferTree )

Definition at line 57 of file StripGmxInterface.cxx.

60 : AthMessaging("StripGmxInterface"),
61 m_detectorManager(detectorManager),
62 m_commonItems(commonItems),
63 m_waferTree(waferTree)
64{}
AthMessaging()
Default constructor:
SCT_DetectorManager * m_detectorManager

Member Function Documentation

◆ addAlignable()

void InDetDD::ITk::StripGmxInterface::addAlignable ( int level,
std::map< std::string, int > & index,
GeoVFullPhysVol * fpv,
GeoAlignableTransform * transform )
finaloverridevirtual

Definition at line 618 of file StripGmxInterface.cxx.

622{
623 ATH_MSG_DEBUG("addAlignable called");
624 //
625 // Get the offline-id appropriate to the level (0 = wafer, 1 = module, 2 = wheel/cylinder, 3 = part, i.e barrel or an endcap)
626 //
627 const SCT_ID *sctIdHelper = dynamic_cast<const SCT_ID *> (m_commonItems->getIdHelper());
628 if (not sctIdHelper){
629 ATH_MSG_ERROR("Failed dynamic_cast to SCT_ID in StripGmxInterface::addAlignable");
630 return;
631 }
632 Identifier id;
633 switch (level) {
634 case 0:
635 id = sctIdHelper->wafer_id(index[becStr],
636 index[layerStr],
637 index[phiStr],
638 index[etaStr],
639 index[sideStr]);
640 break;
641 case 1:
642 id = sctIdHelper->wafer_id(index[becStr],
643 index[layerStr],
644 index[phiStr],
645 index[etaStr],
646 0);
647 break;
648 case 2:
649 id = sctIdHelper->wafer_id(index[becStr],
650 index[layerStr],
651 0,
652 0,
653 0);
654 break;
655 case 3:
656 id = sctIdHelper->wafer_id(index[becStr],
657 0,
658 0,
659 0,
660 0);
661 break;
662 default:
663 throw GaudiException("Unknown level " + std::to_string(level) + " for alignment in addAlignable",
664 "StripGmxInterface::addAlignable", StatusCode::FAILURE);
665 break;
666 }
667 m_detectorManager->addAlignableTransform(level, id, transform, fpv);
668}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)

◆ addSensor()

void InDetDD::ITk::StripGmxInterface::addSensor ( const std::string & typeName,
std::map< std::string, int > & index,
int sequentialId,
GeoVFullPhysVol * fpv )
finaloverride

Definition at line 552 of file StripGmxInterface.cxx.

556{
557 //
558 // Get the ATLAS "Offline" wafer identifier
559 //
560 const SCT_ID *sctIdHelper = dynamic_cast<const SCT_ID *> (m_commonItems->getIdHelper());
561 if (not sctIdHelper){
562 ATH_MSG_ERROR("StripGmxInterface::addSensor: ID helper pointer could not be cast to SCT_ID *");
563 return;
564 }
565 Identifier id = sctIdHelper->wafer_id(index[becStr],
566 index[layerStr],
567 index[phiStr],
568 index[etaStr],
569 index[sideStr]);
570 IdentifierHash hashId = sctIdHelper->wafer_hash(id);
571 //
572 // Now do our best to check if this is a valid id. If either the gmx file is wrong, or the xml file
573 // defining the allowed id's is wrong, you can get disallowed id's. These cause a crash later
574 // if allowed through. To do the check, we ask for the hash-id of this id. Invalid ids give a
575 // special invalid hash-id (0xFFFFFFFF). But we don't exit the run, to help debug things quicker.
576 //
577 if (!hashId.is_valid()) {
578 ATH_MSG_ERROR("Invalid id for sensitive module " << typeName << " volume with indices");
579 for (const auto& [key, value] : index) {
580 msg() << MSG::ERROR << key << " = " << value << "; ";
581 }
582 msg() << MSG::ERROR << endmsg;
583 ATH_MSG_ERROR("Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
584 return;
585 }
586
587 //
588 // Create the detector element and add to the DetectorManager
589 //
590 auto it = m_geometryMap.find(typeName);
591 if(it == m_geometryMap.end() || it->second == nullptr) {
592 ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
593 throw std::runtime_error("readout sensor type " + typeName + " not found.");
594 }
595 const SiDetectorDesign *design = it->second;
596
597 m_detectorManager->addDetectorElement(new SiDetectorElement(id, design, fpv, m_commonItems));
598
599 //
600 // Build up a map-structure for numerology
601 //
602 Wafer wafer((unsigned int) hashId);
603 std::string errorMessage("");
604 if (!m_waferTree->add(index[becStr],
605 index[layerStr],
606 index[etaStr],
607 index[phiStr],
608 index[sideStr],
609 wafer,
610 errorMessage)) {
611 ATH_MSG_ERROR(errorMessage);
612 }
613
614 return;
615}
#define endmsg
MsgStream & msg() const
The standard message stream.
constexpr bool is_valid() const
std::map< std::string, const SiDetectorDesign * > m_geometryMap

◆ addSensorType()

void InDetDD::ITk::StripGmxInterface::addSensorType ( const std::string & clas,
const std::string & typeName,
const std::map< std::string, std::string > & parameters )
finaloverridevirtual

Definition at line 128 of file StripGmxInterface.cxx.

131{
132 ATH_MSG_DEBUG("addSensorType called for class " << clas << ", typeName " << typeName);
133
134 if (clas == "SiStripBox") {
135 makeSiStripBox(typeName, parameters);
136 } else if (clas == "StereoAnnulus") {
137 makeStereoAnnulus(typeName, parameters);
138 } else { // To-do: add "Annulus"
139 ATH_MSG_ERROR("addSensorType: unrecognised sensor class: " << clas);
140 ATH_MSG_ERROR("No sensor design created");
141 }
142}
void makeStereoAnnulus(const std::string &typeName, const std::map< std::string, std::string > &parameters)
void makeSiStripBox(const std::string &typeName, const std::map< std::string, std::string > &parameters)

◆ addSplitAlignable()

void InDetDD::ITk::StripGmxInterface::addSplitAlignable ( int level,
std::map< std::string, int > & index,
std::pair< std::string, int > & extraIndex,
GeoVFullPhysVol * fpv,
GeoAlignableTransform * transform )
finaloverridevirtual

Definition at line 670 of file StripGmxInterface.cxx.

675{
676 ATH_MSG_DEBUG("addSplitAlignable called");
677 //
678 // Get the offline-id appropriate to the level (0 = wafer, 1 = module, 2 = wheel/cylinder, 3 = part, i.e barrel or an endcap)
679 //
680 std::map<std::string, int> updatedIndex;
681 splitSensorId(index,extraIndex,updatedIndex);
682
683 const SCT_ID *sctIdHelper = dynamic_cast<const SCT_ID *> (m_commonItems->getIdHelper());
684 if (not sctIdHelper){
685 ATH_MSG_ERROR("Failed dynamic_cast to SCT_ID in StripGmxInterface::addSplitAlignable");
686 return;
687 }
688 Identifier id;
689 switch (level) {
690 case 0:
691 id = sctIdHelper->wafer_id(updatedIndex[becStr],
692 updatedIndex[layerStr],
693 updatedIndex[phiStr],
694 updatedIndex[etaStr],
695 updatedIndex[sideStr]);
696 break;
697 case 1:
698 id = sctIdHelper->wafer_id(updatedIndex[becStr],
699 updatedIndex[layerStr],
700 updatedIndex[phiStr],
701 updatedIndex[etaStr],
702 0);
703 break;
704 case 2:
705 id = sctIdHelper->wafer_id(updatedIndex[becStr],
706 updatedIndex[layerStr],
707 0,
708 0,
709 0);
710 break;
711 case 3:
712 id = sctIdHelper->wafer_id(updatedIndex[becStr],
713 0,
714 0,
715 0,
716 0);
717 break;
718 default:
719 throw GaudiException("Unknown level " + std::to_string(level) + " for alignment in addSplitAlignable",
720 "StripGmxInterface::addSplitAlignable", StatusCode::FAILURE);
721 break;
722 }
723 m_detectorManager->addAlignableTransform(level, id, transform, fpv);
724}
virtual int splitSensorId(std::map< std::string, int > &index, std::pair< std::string, int > &extraIndex, std::map< std::string, int > &updatedIndex) const override final

◆ addSplitSensor()

void InDetDD::ITk::StripGmxInterface::addSplitSensor ( const std::string & typeName,
std::map< std::string, int > & index,
std::pair< std::string, int > & extraIndex,
int sequentialId,
GeoVFullPhysVol * fpv,
int splitLevel )
finaloverride

Definition at line 476 of file StripGmxInterface.cxx.

482{
483 std::map<std::string, int> updatedIndex;
484 splitSensorId(index,extraIndex,updatedIndex);
485 int splitIndex = extraIndex.second;
486 //
487 // Get the ATLAS "Offline" wafer identifier
488 //
489 const SCT_ID *sctIdHelper = dynamic_cast<const SCT_ID *> (m_commonItems->getIdHelper());
490 if (not sctIdHelper){
491 ATH_MSG_ERROR("Failed dynamic cast to SCT_ID in StripGmxInterface::addSplitSensor");
492 return;
493 }
494 Identifier id = sctIdHelper->wafer_id(updatedIndex[becStr],
495 updatedIndex[layerStr],
496 updatedIndex[phiStr],
497 updatedIndex[etaStr],
498 updatedIndex[sideStr]);
499 IdentifierHash hashId = sctIdHelper->wafer_hash(id);
500 //
501 // Now do our best to check if this is a valid id. If either the gmx file is wrong, or the xml file
502 // defining the allowed id's is wrong, you can get disallowed id's. These cause a crash later
503 // if allowed through. To do the check, we ask for the hash-id of this id. Invalid ids give a
504 // special invalid hash-id (0xFFFFFFFF). But we don't exit the run, to help debug things quicker.
505 //
506 if (!hashId.is_valid()) {
507 ATH_MSG_ERROR("Invalid id for sensitive wafer " << typeName << " volume with indices");
508 for (const auto& [key, value] : index) {
509 msg() << MSG::ERROR << key << " = " << value << "; ";
510 }
511 msg() << MSG::ERROR << endmsg;
512 ATH_MSG_ERROR("Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
513 return;
514 }
515
516 //
517 // Create the detector element and add to the DetectorManager
518 //
519 std::string splitTypeName = typeName + "_" + std::to_string(splitIndex);
520 if (updatedIndex[becStr] == 0) { // only barrel-type have side dependence
521 splitTypeName += "_" + std::to_string(updatedIndex[sideStr]);
522 }
523
524 auto it = m_geometryMap.find(splitTypeName);
525 if(it == m_geometryMap.end() || it->second == nullptr) {
526 ATH_MSG_ERROR("addSplitSensor: Error: Readout sensor type " << typeName << " not found.");
527 throw std::runtime_error("readout sensor type " + typeName + " not found.");
528 }
529 const SiDetectorDesign *design = it->second;
530
531 m_detectorManager->addDetectorElement(new SiDetectorElement(id, design, fpv, m_commonItems));
532
533 //
534 // Build up a map-structure for numerology
535 //
536 Wafer wafer((unsigned int) hashId);
537 std::string errorMessage("");
538 if (!m_waferTree->add(updatedIndex[becStr],
539 updatedIndex[layerStr],
540 updatedIndex[etaStr],
541 updatedIndex[phiStr],
542 updatedIndex[sideStr],
543 wafer,
544 errorMessage)) {
545 ATH_MSG_ERROR(errorMessage);
546 }
547
548 return;
549}

◆ buildReadoutGeometryFromSqlite()

void InDetDD::ITk::StripGmxInterface::buildReadoutGeometryFromSqlite ( IRDBAccessSvc * rdbAccessSvc,
GeoModelIO::ReadGeoModel * sqlreader )

Definition at line 726 of file StripGmxInterface.cxx.

726 {
727
728 IRDBRecordset_ptr stereoAnnulus = rdbAccessSvc->getRecordsetPtr("StereoAnnulus","");
729 const std::array<std::string,13> stereoAnnulusParamNames{"thickness","carrierType","readoutSide","fieldDirection","stripDirection","stereoAngle","centreR","nRows","splitLevel","nStrips","phiPitch","startR","endR"};
730
731 if(stereoAnnulus->size() !=0){
732 for (unsigned int iR =0;iR<stereoAnnulus->size();iR++){
733 std::map<std::string,std::string> stereoAnnulusMap;
734 for(const std::string& paramName:stereoAnnulusParamNames){
735 stereoAnnulusMap[paramName] = (*stereoAnnulus)[iR]->getString(paramName);
736 }
737 std::string stereoAnnulusName = (*stereoAnnulus)[iR]->getString("SensorType");
738 makeStereoAnnulus(stereoAnnulusName,stereoAnnulusMap);
739 }
740 }
741 else ATH_MSG_WARNING("Could not retrieve StereoAnnulus table");
742
743 IRDBRecordset_ptr stripBox = rdbAccessSvc->getRecordsetPtr("SiStripBox","");
744 const std::array<std::string,10> stripBoxParamNames{"thickness","carrierType","readoutSide","fieldDirection","stripDirection","nRows","stripLength","splitLevel","nStrips","pitch"};
745
746 if(stripBox->size() !=0){
747 for (unsigned int iR =0;iR<stripBox->size();iR++){
748 std::map<std::string,std::string> stripBoxMap;
749 for(const std::string& paramName:stripBoxParamNames){
750 std::string paramValue = (*stripBox)[iR]->getString(paramName);
751 stripBoxMap[paramName] = std::move(paramValue);
752 }
753 std::string stripBoxName = (*stripBox)[iR]->getString("SensorType");
754 makeSiStripBox(stripBoxName,stripBoxMap);
755 }
756 }
757 else ATH_MSG_WARNING("Could not retrieve SiStripBox table");
758
759 //Now, loop over the FullPhysVols and create the SiDetectorElements (including splitting where needed)
760 //lots of string parsing...
761 const std::array<std::string,5> fields{becStr,layerStr,phiStr,etaStr,sideStr};
762 //First, find which name the tables are in the file under (depends upon the plugin used to create the input file)
763 //sort these in order of precedence - ITkPlugin, then ITkStripPlugin, then GeoModelXMLPlugin
764 const std::array<std::string,3> publishers{"ITk","ITkStrip","GeoModelXML"};
765 //The below is a map of string keys which will contain all the Identifier/DetElement relevant info, and the associated FullPhysVol
766 // (once filled from the published table in the SQLite)
767 std::map<std::string, GeoFullPhysVol*> mapFPV;
768 for (auto & iPub : publishers){
769 //setting the "checkTable" option to true, so that an empty map will be returned if not found and we can try then next one
770 mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,true);
771 if (!mapFPV.empty()) {
772 ATH_MSG_DEBUG("Using FPV tables from publisher "<<iPub);
773 break;
774 }
775 }
776 if (mapFPV.empty()) ATH_MSG_ERROR("Could not find any FPV tables under the expected names: "<<publishers);
777 std::pair<std::string, int> extraIndex{etaStr, 0}; // eventually specify in XML the field to split in?
778 for (const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
779 //find the name of the corresponding detector design type
780 size_t startRG = fullPhysVolInfoString.find("RG_");
781 if(startRG==std::string::npos){
782 ATH_MSG_DEBUG("GeoFullPhysVol "<<fullPhysVolInfoString<<" does not have the expected format. Skipping");
783 continue;
784 }
785 std::string typeName = fullPhysVolInfoString.substr(startRG);
786 std::map<std::string, int> index;
787 for (const std::string & field:fields){
788 size_t first = fullPhysVolInfoString.find(field+"_");
789 size_t last = fullPhysVolInfoString.find('_',first+field.size()+1);//start looking only after end of first delimiter (plus 1 for the "_" appended) ends
790 if(first==std::string::npos || last==std::string::npos){
791 ATH_MSG_DEBUG("Could not extract "<<field<<" from "<<fullPhysVolInfoString<<". Skipping");
792 continue;
793 }
794 std::string strNew = fullPhysVolInfoString.substr(first+field.size()+1,last-(first+field.size()+1));
795 index[field] = std::stoi(strNew);
796 }
797 //now check if we need to split
798 size_t splitPos = fullPhysVolInfoString.find("split_");
799
800 if(splitPos!=std::string::npos){
801 size_t last = fullPhysVolInfoString.find('_',splitPos+6);//"split_" is 6 characters
802 std::string strNew = fullPhysVolInfoString.substr(splitPos+6,last-(splitPos+6));
803 int splitLevel = std::stoi(strNew);
804 for(int i=0;i<splitLevel;i++){
805 extraIndex.second = i;
806 addSplitSensor(typeName,index,extraIndex,0,fullPhysVolPointer,splitLevel);
807 }
808 }
809 else addSensor(typeName,index,0,fullPhysVolPointer);
810 }
811}
#define ATH_MSG_WARNING(x)
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
virtual IRDBRecordset_ptr getRecordsetPtr(std::string_view node, std::string_view tag, std::string_view tag2node="", std::string_view connName="ATLASDD")=0
Provides access to the Recordset object containing HVS-tagged data.
virtual unsigned int size() const =0
void addSplitSensor(const std::string &typeName, std::map< std::string, int > &index, std::pair< std::string, int > &extraIndex, int sequentialId, GeoVFullPhysVol *fpv, int splitLevel) override final
void addSensor(const std::string &typeName, std::map< std::string, int > &index, int sequentialId, GeoVFullPhysVol *fpv) override final
bool first
Definition DeMoScan.py:534
str index
Definition DeMoScan.py:362

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ makeSiStripBox()

void InDetDD::ITk::StripGmxInterface::makeSiStripBox ( const std::string & typeName,
const std::map< std::string, std::string > & parameters )
private

Definition at line 145 of file StripGmxInterface.cxx.

147{
148 //
149 // Get all parameters.
150 //
151
152 double thickness{0.320};
153 int readoutSide{1};
155 int nRows{1};
156 double pitch{0.080};
157 int nStrips{1280}; // Per row
158 double length{25.0};
159
160 std::string carrierString;
161 getParameter(typeName, parameters, "carrierType", carrierString);
162 if (carrierString == "electrons") {
163 carrier = InDetDD::electrons;
164 } else if (carrierString == "holes") {
165 carrier = InDetDD::holes;
166 } else {
167 throw GaudiException("Parameter carrierType should be electrons or holes for " + typeName,
168 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
169 }
170
171 std::string readoutSideString;
172 getParameter(typeName, parameters, "readoutSide", readoutSideString);
173 if (readoutSideString == "+") {
174 readoutSide = 1;
175 } else if (readoutSideString == "-") {
176 readoutSide = -1;
177 } else {
178 throw GaudiException("Parameter readoutSide should be + or - for " + typeName,
179 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
180 }
181
182 std::string fieldDirectionString;
183 getParameter(typeName, parameters, "fieldDirection", fieldDirectionString);
184 auto fieldDirectionOptional = direction(fieldDirectionString);
185 if (!fieldDirectionOptional){
186 throw GaudiException("Parameter fieldDirection should be x, y, or z for " + typeName,
187 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
188 }
189
190 std::string stripDirectionString;
191 getParameter(typeName, parameters, "stripDirection", stripDirectionString);
192 auto stripDirectionOptional = direction(stripDirectionString);
193 if (!stripDirectionOptional){
194 throw GaudiException("Parameter stripDirection should be x, y, or z for " + typeName,
195 "StripGmxInterface::makeSiStripBox", StatusCode::FAILURE);
196 }
197 const auto stripDirection = *stripDirectionOptional;
198 const auto fieldDirection = *fieldDirectionOptional;
199 getParameter(typeName, parameters, "thickness", thickness);
200 getParameter(typeName, parameters, "nRows", nRows);
201 getParameter(typeName, parameters, "nStrips", nStrips);
202 getParameter(typeName, parameters, "pitch", pitch);
203 getParameter(typeName, parameters, "stripLength", length);
204
205 //At the moment, we'd only ever want StripBarrel for this detector type, so throw a WARNING if it differs
206 //However, in future this may be different, so implementing the functionality to set this anyway
208 int detectorTypeEnum = 0;
209 if (checkParameter(typeName, parameters, "detectorType", detectorTypeEnum)) {
210 if (detectorTypeEnum == 4) detectorType = InDetDD::StripBarrel;
211 else ATH_MSG_WARNING("Non-strip barrel type set for strip box DetectorElement - is this intended?");
212 }
213
214
215 //
216 // Make Sensor Design and add to DetectorManager
217 //
218
219 int splitLevel{};
220 if (checkParameter(typeName, parameters, "splitLevel", splitLevel)) {
221 // start from middle of first strip row
222 double initZShift = length * (-static_cast<double>(splitLevel) * 0.5 + 0.5);
223
224 // now, the "Mother"...
225 // This is a container for all the other designs, to allow navigation
226 // between the different rows on a simulated sensor in the HITS
227 auto motherDesign = std::make_unique<StripBoxDesign>(stripDirection,
228 fieldDirection,
229 thickness,
230 readoutSide,
231 carrier,
232 nRows,
233 nStrips,
234 pitch,
235 length,
236 detectorType);
237
238 for (int i = 0; i< splitLevel; i++) {
239 for (int side : {0,1}) { //need different additional shift transform per side...
240 int sign = (side == 0) ? 1 : -1; //...because shift in different direction per side
241 double zShift = sign * (initZShift + (i * length));
242
243 auto design = std::make_unique<StripBoxDesign>(stripDirection,
244 fieldDirection,
245 thickness,
246 readoutSide,
247 carrier,
248 1, //single row
249 nStrips,
250 pitch,
251 length,
252 detectorType,
253 zShift);
254
255 design->setMother(motherDesign.get());
256 motherDesign->addChildDesign(i,design.get());
257
258 std::string splitName = typeName + "_" + std::to_string(i) + "_" + std::to_string(side);
259 m_geometryMap[splitName] = m_detectorManager->addDesign(std::move(design));
260 }
261 }
262
263 // Add to map for addSensor routine
264 m_motherMap[typeName] = motherDesign.get();
265 m_detectorManager->addMotherDesign(std::move(motherDesign));
266 } else { // no split level
267 auto design = std::make_unique<StripBoxDesign>(stripDirection,
268 fieldDirection,
269 thickness,
270 readoutSide,
271 carrier,
272 nRows,
273 nStrips,
274 pitch,
275 length,
276 detectorType);
277
278 // Add to map for addSensor routine
279 m_geometryMap[typeName] = design.get();
280 m_detectorManager->addDesign(std::move(design));
281 }
282}
double length(const pvec &v)
int sign(int a)
std::map< std::string, const SCT_ModuleSideDesign * > m_motherMap
int nStrips(const MuonGM::TgcReadoutElement &readoutEle, int layer)
std::vector< T > getParameter(const std::string &varName, const std::vector< std::string > &buffer)
unsigned int constexpr nRows
Definition RPDUtils.h:24
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.

◆ makeStereoAnnulus()

void InDetDD::ITk::StripGmxInterface::makeStereoAnnulus ( const std::string & typeName,
const std::map< std::string, std::string > & parameters )
private

Definition at line 285 of file StripGmxInterface.cxx.

287{
288 //
289 // Get all parameters.
290 //
291 int readoutSide{1};
292
294 double thickness{0.320};
295 double stereoAngle{0.020};
296 double centreR{500.};
297 int nRows{1};
298 std::vector <int> nStrips;
299 std::vector<double> phiPitch;
300 std::vector<double> startR;
301 std::vector<double> endR;
302 bool usePC{false}; // initialise to false
303
304 std::string carrierString;
305 getParameter(typeName, parameters, "carrierType", carrierString);
306 if (carrierString == "electrons") {
307 carrier = InDetDD::electrons;
308 } else if (carrierString == "holes") {
309 carrier = InDetDD::holes;
310 } else {
311 throw GaudiException("Parameter carrierType should be electrons or holes for " + typeName,
312 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
313 }
314
315 std::string readoutSideString;
316 getParameter(typeName, parameters, "readoutSide", readoutSideString);
317 if (readoutSideString == "+") {
318 readoutSide = 1;
319 } else if (readoutSideString == "-") {
320 readoutSide = -1;
321 } else {
322 throw GaudiException("Parameter readoutSide should be + or - for " + typeName,
323 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
324 }
325
326 std::string fieldDirectionString;
327 getParameter(typeName, parameters, "fieldDirection", fieldDirectionString);
328 auto fieldDirectionOptional = direction(fieldDirectionString);
329 if (!fieldDirectionOptional){
330 throw GaudiException("Parameter fieldDirection should be x, y, or z for " + typeName,
331 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
332 }
333 const auto fieldDirection = *fieldDirectionOptional;
334 //
335 std::string stripDirectionString;
336 getParameter(typeName, parameters, "stripDirection", stripDirectionString);
337 auto stripDirectionOptional = direction(stripDirectionString);
338 if (!stripDirectionOptional){
339 throw GaudiException("Parameter stripDirection should be x, y, or z for " + typeName,
340 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
341 }
342 const auto stripDirection = *stripDirectionOptional;
343 getParameter(typeName, parameters, "thickness", thickness);
344 getParameter(typeName, parameters, "stereoAngle", stereoAngle);
345 getParameter(typeName, parameters, "centreR", centreR);
346 getParameter(typeName, parameters, "nRows", nRows);
347
348 getParameters(typeName, parameters, "nStrips", nStrips);
349 if (nStrips.size() != static_cast<size_t>(nRows)) {
350 throw GaudiException("Wrong number of nStrips " + std::to_string(nStrips.size()) + " " + typeName,
351 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
352 }
353
354 getParameters(typeName, parameters, "phiPitch", phiPitch);
355 if (phiPitch.size() != static_cast<size_t>(nRows)) {
356 throw GaudiException("Wrong number of pitches " + std::to_string(phiPitch.size()) + " " + typeName,
357 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
358 }
359
360 getParameters(typeName, parameters, "startR", startR);
361 if (startR.size() != static_cast<size_t>(nRows)) {
362 throw GaudiException("Wrong number of startRs " + std::to_string(startR.size()) + " " + typeName,
363 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
364 }
365
366 getParameters(typeName, parameters, "endR", endR);
367 if (endR.size() != static_cast<size_t>(nRows)) {
368 throw GaudiException("Wrong number of endRs " + std::to_string(endR.size()) + " " + typeName,
369 "StripGmxInterface::makeStereoAnnulus", StatusCode::FAILURE);
370 }
371
372 if (checkParameter(typeName, parameters, "usePC", usePC)) ATH_MSG_INFO("Using polar co-ordinates for strip stereo annulus modules");
373
374
375 //At the moment, we'd only ever want StripEndcap for this detector type, so throw a WARNING if it differs
376 //However, in future this may be different, so implementing the functionality to set this anyway
378 int detectorTypeEnum = 0;
379 if (checkParameter(typeName, parameters, "detectorType", detectorTypeEnum)) {
380 if (detectorTypeEnum == 5) detectorType = InDetDD::StripEndcap;
381 else ATH_MSG_WARNING("Non-strip endcap type set for strip annulus DetectorElement - is this intended?");
382 }
383
384 //
385 // Make Sensor Design and add it to the DetectorManager
386 //
387 std::vector<int> singleRowStrips;
388 std::vector<double> singleRowPitch;
389 std::vector<double> singleRowMinR;
390 std::vector<double> singleRowMaxR;
391
392 int splitLevel{};
393 if (checkParameter(typeName, parameters, "splitLevel", splitLevel)) {
394 // now the mother...
395 auto motherDesign = std::make_unique<StripStereoAnnulusDesign>(stripDirection,
396 fieldDirection,
397 thickness,
398 readoutSide,
399 carrier,
400 nRows,
401 nStrips,
402 phiPitch,
403 startR,
404 endR,
405 stereoAngle,
406 centreR,
407 usePC,
408 detectorType);
409
410 for (int i = 0; i < splitLevel; i++) {
411 singleRowStrips.clear();
412 singleRowPitch.clear();
413 singleRowMinR.clear();
414 singleRowMaxR.clear();
415
416 singleRowStrips.push_back(nStrips[i]);
417 singleRowPitch.push_back(phiPitch[i]);
418 singleRowMinR.push_back(startR[i]);
419 singleRowMaxR.push_back(endR[i]);
420 //"shift" radius for correcting local<->global transforms
421 //centreR remains the relevant radius for bounds/stereo calculations
422 //since the strip frame is defined per wafer not per row
423 double thisCentreR = (singleRowMinR[0] + singleRowMaxR[0] ) *0.5;
424
425 auto design = std::make_unique<StripStereoAnnulusDesign>(stripDirection,
426 fieldDirection,
427 thickness,
428 readoutSide,
429 carrier,
430 1,//this design represents a single row by definition
431 singleRowStrips,
432 singleRowPitch,
433 singleRowMinR,
434 singleRowMaxR,
435 stereoAngle,
436 thisCentreR,
437 centreR,
438 usePC,
439 detectorType);
440
441 // Add to map for addSensor routine
442 std::string splitName = typeName + "_" + std::to_string(i);
443 design->setMother(motherDesign.get());
444 motherDesign->addChildDesign(i,design.get());
445
446 m_geometryMap[splitName] = design.get();
447 m_detectorManager->addDesign(std::move(design));
448
449 }
450
451 // finally, declare to the manager (now becomes const)
452 m_motherMap[typeName] = motherDesign.get();
453 m_detectorManager->addMotherDesign(std::move(motherDesign));
454
455 } else {
456 auto design = std::make_unique<StripStereoAnnulusDesign>(stripDirection,
457 fieldDirection,
458 thickness,
459 readoutSide,
460 carrier,
461 nRows,
462 nStrips,
463 phiPitch,
464 startR,
465 endR,
466 stereoAngle,
467 centreR,
468 usePC,
469 detectorType);
470
471 m_geometryMap[typeName] = design.get();
472 m_detectorManager->addDesign(std::move(design));
473 }
474}
#define ATH_MSG_INFO(x)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 167 of file AthMessaging.h.

168{
169 MsgStream* ms = m_msg_tls.get();
170 if (!ms) {
171 if (!m_initialized.test_and_set()) initMessaging();
172 ms = new MsgStream(m_imsg,m_nm);
173 m_msg_tls.reset( ms );
174 }
175
176 ms->setLevel (m_lvl);
177 return *ms;
178}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels).
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 182 of file AthMessaging.h.

183{ return msg() << lvl; }

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 // If user did not set explicit message level we have to initialize
154 // the messaging and retrieve the default via the MessageSvc.
155 if (m_lvl==MSG::NIL && !m_initialized.test_and_set()) initMessaging();
156
157 if (m_lvl <= lvl) {
158 msg() << lvl;
159 return true;
160 } else {
161 return false;
162 }
163}

◆ sensorId()

int InDetDD::ITk::StripGmxInterface::sensorId ( std::map< std::string, int > & index) const
finaloverridevirtual

Definition at line 67 of file StripGmxInterface.cxx.

68{
69 //
70 // Return the Simulation HitID (nothing to do with "ATLAS Identifiers" aka "Offline Identifiers"
71
72 int hitIdOfWafer = SiHitIdHelper::GetHelper()->buildHitId(SCT_HitIndex,
73 index[becStr],
74 index[layerStr],
75 index[etaStr],
76 index[phiStr],
77 index[sideStr]);
78
79 ATH_MSG_DEBUG("Index list: " << index[becStr] << " " << index[layerStr] << " "
80 << index[etaStr] << " " << index[phiStr] << " " << index[sideStr]);
81 ATH_MSG_DEBUG("hitIdOfWafer = " << std::hex << hitIdOfWafer << std::dec);
82 ATH_MSG_DEBUG(" bec = " << SiHitIdHelper::GetHelper()->getBarrelEndcap(hitIdOfWafer)
83 << " lay = " << SiHitIdHelper::GetHelper()->getLayerDisk(hitIdOfWafer)
84 << " eta = " << SiHitIdHelper::GetHelper()->getEtaModule(hitIdOfWafer)
85 << " phi = " << SiHitIdHelper::GetHelper()->getPhiModule(hitIdOfWafer)
86 << " side = " << SiHitIdHelper::GetHelper()->getSide(hitIdOfWafer));
87 return hitIdOfWafer;
88}
int buildHitId(const int, const int, const int, const int, const int, const int) const
static const SiHitIdHelper * GetHelper()

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

◆ splitSensorId()

int InDetDD::ITk::StripGmxInterface::splitSensorId ( std::map< std::string, int > & index,
std::pair< std::string, int > & extraIndex,
std::map< std::string, int > & updatedIndex ) const
finaloverridevirtual

Definition at line 90 of file StripGmxInterface.cxx.

93{
94 //
95 // Return the Simulation HitID (nothing to do with "ATLAS Identifiers" aka "Offline Identifiers"
96
97 if (extraIndex.first != etaStr) {
98 ATH_MSG_FATAL("Base Identifier: " << index[becStr] << " " << index[layerStr] << " "
99 << index[etaStr] << " " << index[phiStr] << " " << index[sideStr]);
100 ATH_MSG_FATAL("Attempting to split "<< extraIndex.second);
101 ATH_MSG_FATAL("Only splitting of eta_module supported for ITk strips!!!");
102 return -1;
103 }
104
105 //add the required amount to the requested field
106 updatedIndex = index;
107 updatedIndex[extraIndex.first] += extraIndex.second;
108
109 int hitIdOfWafer = SiHitIdHelper::GetHelper()->buildHitId(SCT_HitIndex,
110 index[becStr],
111 index[layerStr],
112 index[etaStr] + extraIndex.second,
113 index[phiStr],
114 index[sideStr]);
115
116 ATH_MSG_DEBUG("Index list: " << index[becStr] << " " << index[layerStr] << " "
117 << index[etaStr] + extraIndex.second << " " << index[phiStr] << " " << index[sideStr]);
118 ATH_MSG_DEBUG("hitIdOfWafer = " << std::hex << hitIdOfWafer << std::dec);
119 ATH_MSG_DEBUG(" bec = " << SiHitIdHelper::GetHelper()->getBarrelEndcap(hitIdOfWafer)
120 << " lay = " << SiHitIdHelper::GetHelper()->getLayerDisk(hitIdOfWafer)
121 << " eta = " << SiHitIdHelper::GetHelper()->getEtaModule(hitIdOfWafer)
122 << " phi = " << SiHitIdHelper::GetHelper()->getPhiModule(hitIdOfWafer)
123 << " side = " << SiHitIdHelper::GetHelper()->getSide(hitIdOfWafer));
124 return hitIdOfWafer;
125}
#define ATH_MSG_FATAL(x)

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging).

Definition at line 141 of file AthMessaging.h.

◆ m_commonItems

SiCommonItems* InDetDD::ITk::StripGmxInterface::m_commonItems {}
private

Definition at line 73 of file StripGmxInterface.h.

73{};

◆ m_detectorManager

SCT_DetectorManager* InDetDD::ITk::StripGmxInterface::m_detectorManager {}
private

Definition at line 72 of file StripGmxInterface.h.

72{};

◆ m_geometryMap

std::map<std::string, const SiDetectorDesign *> InDetDD::ITk::StripGmxInterface::m_geometryMap
private

Definition at line 70 of file StripGmxInterface.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_motherMap

std::map<std::string, const SCT_ModuleSideDesign *> InDetDD::ITk::StripGmxInterface::m_motherMap
private

Definition at line 71 of file StripGmxInterface.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels).

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_waferTree

WaferTree* InDetDD::ITk::StripGmxInterface::m_waferTree {}
private

Definition at line 74 of file StripGmxInterface.h.

74{};

The documentation for this class was generated from the following files: