9 #include "GaudiKernel/IToolSvc.h"
10 #include "GaudiKernel/MsgStream.h"
16 #include "GeoModelKernel/GeoVolumeCursor.h"
17 #include "GeoModelKernel/GeoVDetectorManager.h"
19 #include "GeoModelKernel/GeoTubs.h"
20 #include "GeoModelKernel/GeoTrd.h"
21 #include "GeoModelKernel/GeoShapeShift.h"
40 ATH_MSG_ERROR(
"Could not retrieve MuonGM::MuonDetectorManager" );
42 return StatusCode::FAILURE;
52 return StatusCode::SUCCESS;
57 out <<
"<?xml version=\"1.0\"?>" << std::endl
58 <<
"<!DOCTYPE AMuonGeometry [" << std::endl
59 <<
"<!ELEMENT AMuonGeometry (ABox | ATBx | ATrd)*>" << std::endl
60 <<
"<!ELEMENT ABox EMPTY >" << std::endl
61 <<
"<!ATTLIST ABox" << std::endl
62 <<
" n CDATA #REQUIRED" << std::endl
63 <<
" zi CDATA #REQUIRED" << std::endl
64 <<
" zo CDATA #REQUIRED" << std::endl
65 <<
" ri CDATA #REQUIRED" << std::endl
66 <<
" ro CDATA #REQUIRED" << std::endl
67 <<
" w CDATA #REQUIRED" << std::endl
68 <<
" eta CDATA #REQUIRED" << std::endl
69 <<
" phi CDATA #REQUIRED" << std::endl
70 <<
" dphi CDATA \"0\"" << std::endl
71 <<
" sh CDATA \"0\"" << std::endl
72 <<
" RPCi CDATA \"0\"" << std::endl
73 <<
" RPCo CDATA \"0\">" << std::endl
74 <<
"<!ELEMENT ATBx EMPTY >" << std::endl
75 <<
"<!ATTLIST ATBx" << std::endl
76 <<
" n CDATA #REQUIRED" << std::endl
77 <<
" zi CDATA #REQUIRED" << std::endl
78 <<
" zo CDATA #REQUIRED" << std::endl
79 <<
" ri CDATA #REQUIRED" << std::endl
80 <<
" ro CDATA #REQUIRED" << std::endl
81 <<
" w CDATA #REQUIRED" << std::endl
82 <<
" eta CDATA #REQUIRED" << std::endl
83 <<
" phi CDATA #REQUIRED" << std::endl
84 <<
" sh CDATA \"0\"" << std::endl
85 <<
" dphi CDATA \"0\"" << std::endl
86 <<
" RPCi CDATA \"0\"" << std::endl
87 <<
" RPCo CDATA \"0\"" << std::endl
88 <<
" zis CDATA #REQUIRED" << std::endl
89 <<
" zos CDATA #REQUIRED" << std::endl
90 <<
" ws CDATA #REQUIRED" << std::endl
91 <<
" or CDATA \"0\">" << std::endl
92 <<
"<!ELEMENT ATrd EMPTY >" << std::endl
93 <<
"<!ATTLIST ATrd" << std::endl
94 <<
" n CDATA #REQUIRED" << std::endl
95 <<
" zi CDATA #REQUIRED" << std::endl
96 <<
" zo CDATA #REQUIRED" << std::endl
97 <<
" ri CDATA #REQUIRED" << std::endl
98 <<
" ro CDATA #REQUIRED" << std::endl
99 <<
" wi CDATA #REQUIRED" << std::endl
100 <<
" wo CDATA #REQUIRED" << std::endl
101 <<
" eta CDATA #REQUIRED" << std::endl
102 <<
" phi CDATA #REQUIRED" << std::endl
103 <<
" dphi CDATA \"0\"" << std::endl
104 <<
" sh CDATA \"0\"" << std::endl
105 <<
" a CDATA \"0\">" << std::endl
107 <<
"<AMuonGeometry>" << std::endl;
120 for (
int sn=0; sn<=snMax; sn++) {
126 std::string stationTech;
148 if (stationTech ==
"TGC") {
159 for (
int eta=-16; eta<=16; eta++) {
160 std::vector<const MuonGM::MuonStation *> *stations =
new std::vector<const MuonGM::MuonStation *>;
163 for (
int phi=maxPhi; phi>0; phi--) {
170 if (station) stations->push_back(station);
174 while (stations->size() > 0) {
179 HepGeom::Point3D<double> pos1 =
getPosition(station1, maxPhi);
182 double shift1 =
getShift(pos1, dphi1);
186 double signed_dz = station1->
Zsize()/2.;
187 if (pos1.z()<0) signed_dz *= -1;
188 double zi1 = pos1.z() - signed_dz;
189 double zo1 = pos1.z() + signed_dz;
190 double ri1 = pos1.perp() - station1->
Rsize()/2.;
191 double ro1 = pos1.perp() + station1->
Rsize()/2.;
192 double wi1 = station1->
Ssize();
196 std::string phiString =
DataType(phi1).toString();
199 stations->erase(stations->end()-1, stations->end());
204 for (
it=stations->end()-1;
it>=stations->begin(); --
it) {
206 int phi2 = (*it)->getPhiIndex();
208 double shift2 =
getShift(pos2, dphi2);
211 double signed_dz2 = (*it)->Zsize()/2.;
212 if (pos2.z()<0) signed_dz2 *= -1;
213 double zi2 = pos2.z() - signed_dz2;
214 double zo2 = pos2.z() + signed_dz2;
215 double ri2 = pos2.perp() - (*it)->Rsize()/2.;
216 double ro2 = pos2.perp() + (*it)->Rsize()/2.;
217 double wi2 = (*it)->Ssize();
218 double wo2 = (*it)->LongSsize();
235 phiString +=
" " +
DataType(phi2).toString();
237 stations->erase(
it,
it+1);
262 }
else if (
stationName[1] ==
'I' && eta==7 && wi1>1800) {
269 <<
" zi=\"" << zi1/10. <<
"\"" <<
" zo=\"" << zo1/10. <<
"\""
270 <<
" ri=\"" << ri1/10. <<
"\"" <<
" ro=\"" << ro1/10. <<
"\""
271 <<
" w=\"" << wi1/10. <<
"\""
272 <<
" eta=\"" << eta <<
"\""
273 <<
" phi=\"" << phiString <<
"\"";
277 out <<
" dphi=\"" << 180/
M_PI * dphi1 <<
"\"";
281 out <<
" sh=\"" << shift1/10. <<
"\"";
285 out <<
" RPCi=\"" << rpci <<
"\"";
287 out <<
" RPCo=\"" << rpco <<
"\"";
288 out <<
" />" << std::endl;
293 writeATrd(
out, stationTech,
stationName, zi1, zo1, ri1, ro1, wi1, wo1, eta, phiString, dphi1, shift1, alpha1);
311 return HepGeom::RotateZ3D(-phi) *
pos;
319 }
else if (std::abs(
pos.phi() -
M_PI/8.) <
M_PI/16.) {
332 CLHEP::HepRotation rot = trans.getRotation();
335 return M_PI/2. - rot.getTheta();
340 HepGeom::Point3D<double> rotpos;
346 rotpos = HepGeom::RotateZ3D(-dphi) *
pos;
359 out <<
"</AMuonGeometry>" << std::endl;
364 const std::string& stationTech,
const std::string&
stationName,
365 double zi,
double zo,
double ri,
double ro,
double wi,
double wo,
366 int eta,
const std::string& phiString,
367 double dphi,
double shift,
double alpha)
const {
369 out <<
"<ATrd n=\"" << stationTech <<
"_" <<
stationName << std::abs(eta) <<
"\""
370 <<
" zi=\"" << zi/10. <<
"\"" <<
" zo=\"" << zo/10. <<
"\""
371 <<
" ri=\"" << ri/10. <<
"\"" <<
" ro=\"" << ro/10. <<
"\""
372 <<
" wi=\"" << wi/10. <<
"\"" <<
" wo=\"" << wo/10. <<
"\""
373 <<
" eta=\"" << eta <<
"\""
374 <<
" phi=\"" << phiString <<
"\"";
378 out <<
" dphi=\"" << 180/
M_PI * dphi <<
"\"";
382 out <<
" sh=\"" << shift/10. <<
"\"";
388 out <<
" />" << std::endl;
400 ATH_MSG_ERROR(
"Could not retrieve the ATLAS GeoModelExperiment from detector store" );
405 GeoVolumeCursor av(world);
406 while (!av.atEnd()) {
407 if ( av.getName()==
"Muon") {
408 GeoVolumeCursor
pv(av.getVolume());
409 while (!
pv.atEnd()) {
410 if (
pv.getVolume()->getLogVol()->getName()==
"NewSmallWheel") {
412 GeoVolumeCursor pvnsw(
pv.getVolume());
414 while (!pvnsw.atEnd()){
415 std::string
stationName = pvnsw.getVolume()->getLogVol()->getName();
421 GeoVolumeCursor pvnswsub(pvnsw.getVolume());
422 bool newChamber =
true;
423 std::string phiString =
"";
424 std::string phiString_mirrorEta =
"";
425 double dphi=0, shift=0, zi=0, zo=0, ri=0, ro=0, wi=0, wo=0;
426 std::string chamberName=
"";
427 HepGeom::Point3D<double> pos_rot;
429 while (!pvnswsub.atEnd()){
430 if (((pvnswsub.getVolume()->getLogVol())->getShape())->typeID() == GeoTrd::getClassTypeID() ) {
435 readNSWMMPars(&pvnswsub, maxPhi, chamberName, pos_rot, zi, zo, ri, ro, wi, wo, dphi, shift,
phiIndex);
443 std::string chamberName2;
444 HepGeom::Point3D<double> pos_rot2;
445 double zi2, zo2, ri2, ro2, wi2, wo2, dphi2, shift2;
447 readNSWMMPars(&pvnswsub, maxPhi, chamberName2, pos_rot2, zi2, zo2, ri2, ro2, wi2, wo2, dphi2, shift2, phiIndex2);
449 if (chamberName != chamberName2
465 std::string stationPhi =
DataType(phiIndex2).toString();
466 if (phiString.find(stationPhi) == std::string::npos) phiString +=
" " + stationPhi;
469 else if (pos_rot.distance(HepGeom::Point3D<double>(pos_rot2.x(), pos_rot2.y(), -pos_rot2.z())) <
m_smallDistance
474 std::string stationPhi =
DataType(phiIndex2).toString();
475 if (phiString_mirrorEta.find(stationPhi) == std::string::npos){
476 if (not phiString_mirrorEta.empty()) phiString_mirrorEta +=
" ";
477 phiString_mirrorEta += stationPhi;
490 if (phiString!=
"" && (newChamber || pvnswsub.atEnd())){
494 std::string stationTech =
"MM";
495 std::string
stationName =
"MM"+chamberName.substr(7,1);
496 int eta = std::stoi(chamberName.substr(8,1));
497 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
498 if (phiString_mirrorEta!=
"") {
499 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
503 phiString_mirrorEta =
"";
518 GeoVolumeCursor pvnswsub(pvnsw.getVolume());
519 bool newChamber =
true;
520 std::string phiString =
"";
521 std::string phiString_mirrorEta =
"";
523 double dz=0, dphi=0, shift=0;
524 std::string chamberName=
"";
525 HepGeom::Point3D<double> pos_rot;
526 const GeoSimplePolygonBrep* theBrep =
nullptr;
528 while (!pvnswsub.atEnd()){
529 if (((pvnswsub.getVolume()->getLogVol())->getShape())->typeID() == GeoShapeShift::getClassTypeID() ) {
544 std::string chamberName2;
545 HepGeom::Point3D<double> pos_rot2;
546 const GeoSimplePolygonBrep* theBrep2;
547 int nvtx2, phiIndex2;
548 double dz2, dphi2, shift2;
549 readNSWSTGCPars(&pvnswsub, maxPhi, chamberName2, pos_rot2, theBrep2, nvtx2, dz2, dphi2, shift2, phiIndex2);
552 bool isSameShape =
true;
554 for (
int i=0;
i<nvtx; ++
i){
555 if ( !
equalLength(theBrep->getXVertex(
i), theBrep2->getXVertex(
i))
556 || !
equalLength(theBrep->getYVertex(
i), theBrep2->getYVertex(
i)) )
567 if (chamberName != chamberName2
579 std::string stationPhi =
DataType(phiIndex2).toString();
580 if (phiString.find(stationPhi) == std::string::npos) phiString +=
" " + stationPhi;
583 else if (pos_rot.distance(HepGeom::Point3D<double>(pos_rot2.x(), pos_rot2.y(), -pos_rot2.z())) <
m_smallDistance) {
585 std::string stationPhi =
DataType(phiIndex2).toString();
586 if (phiString_mirrorEta.find(stationPhi) == std::string::npos) {
587 if (not phiString_mirrorEta.empty()) phiString_mirrorEta +=
" ";
588 phiString_mirrorEta += stationPhi;
600 if (phiString!=
"" && (newChamber || pvnswsub.atEnd())){
604 std::string stationTech =
"STGC";
605 std::string
stationName =
"ST"+chamberName.substr(8,1);
606 int eta = std::stoi(chamberName.substr(9,1));
607 double signed_dz = dz;
608 if (pos_rot.z()<0) dz *= -1;
609 double zi = pos_rot.z() - signed_dz;
610 double zo = pos_rot.z() + signed_dz;
611 double rho = pos_rot.perp();
612 double ri, ro, wi, wo;
618 const int vtxList[] = {0, 1, 2, 3};
620 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
621 if (phiString_mirrorEta!=
"") {
622 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
634 const int vtxList1[] = {5, 2, 3, 4};
636 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
637 if (phiString_mirrorEta!=
"") {
638 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
642 const int vtxList2[] = {0, 1, 2, 5};
644 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
645 if (phiString_mirrorEta!=
"") {
646 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
652 ATH_MSG_ERROR(
"Shape not supported by GeometryJiveXML: polygon shape with "<<nvtx <<
" verticies in NSW sTGC." );
655 phiString_mirrorEta =
"";
678 if (phi<0) phi += 2.*
M_PI;
689 HepGeom::Point3D<double> pos_rot = HepGeom::RotateZ3D(-sectorPhi) * HepGeom::Point3D<double>(
pos.x(),
pos.y(),
pos.z());
695 double& zi,
double& zo,
double& ri,
double& ro,
double& wi,
double& wo,
double& dphi,
double& shift,
int&
phiIndex)
const {
697 chamberName =
pv->getVolume()->getLogVol()->getName();
698 const GeoTrd* theTrd =
dynamic_cast<const GeoTrd*
> ((
pv->getVolume()->getLogVol())->getShape());
704 double signed_dz = theTrd->getXHalfLength1();
705 if (pos_rot.z()<0) signed_dz *= -1;
707 zi = pos_rot.z() - signed_dz;
708 zo = pos_rot.z() + signed_dz;
709 ri = pos_rot.perp() - theTrd->getZHalfLength();
710 ro = pos_rot.perp() + theTrd->getZHalfLength();
711 wi = 2.0 * theTrd->getYHalfLength1();
712 wo = 2.0 * theTrd->getYHalfLength2();
720 std::string& chamberName, HepGeom::Point3D<double>& pos_rot,
const GeoSimplePolygonBrep*& theBrep,
721 int& nvtx,
double& dz,
double& dphi,
double& shift,
int&
phiIndex)
const {
723 chamberName =
pv->getVolume()->getLogVol()->getName();
725 const GeoShapeShift* theShift =
dynamic_cast<const GeoShapeShift*
> ((
pv->getVolume()->getLogVol())->getShape());
726 theBrep =
dynamic_cast<const GeoSimplePolygonBrep*
> (theShift->getOp());
727 nvtx = theBrep->getNVertices();
728 dz = theBrep->getDZ();
741 double& ri,
double& ro,
double& wi,
double& wo)
const {
745 ri =
rho + theBrep->getYVertex(vtx[3]);
746 ro =
rho + theBrep->getYVertex(vtx[0]);
747 wi = theBrep->getXVertex(vtx[3]) - theBrep->getXVertex(vtx[2]);
748 wo = theBrep->getXVertex(vtx[0]) - theBrep->getXVertex(vtx[1]);