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"
38 ATH_MSG_ERROR(
"Could not retrieve MuonGM::MuonDetectorManager" );
40 return StatusCode::FAILURE;
50 return StatusCode::SUCCESS;
55 out <<
"<?xml version=\"1.0\"?>" << std::endl
56 <<
"<!DOCTYPE AMuonGeometry [" << std::endl
57 <<
"<!ELEMENT AMuonGeometry (ABox | ATBx | ATrd)*>" << std::endl
58 <<
"<!ELEMENT ABox EMPTY >" << std::endl
59 <<
"<!ATTLIST ABox" << std::endl
60 <<
" n CDATA #REQUIRED" << std::endl
61 <<
" zi CDATA #REQUIRED" << std::endl
62 <<
" zo CDATA #REQUIRED" << std::endl
63 <<
" ri CDATA #REQUIRED" << std::endl
64 <<
" ro CDATA #REQUIRED" << std::endl
65 <<
" w CDATA #REQUIRED" << std::endl
66 <<
" eta CDATA #REQUIRED" << std::endl
67 <<
" phi CDATA #REQUIRED" << std::endl
68 <<
" dphi CDATA \"0\"" << std::endl
69 <<
" sh CDATA \"0\"" << std::endl
70 <<
" RPCi CDATA \"0\"" << std::endl
71 <<
" RPCo CDATA \"0\">" << std::endl
72 <<
"<!ELEMENT ATBx EMPTY >" << std::endl
73 <<
"<!ATTLIST ATBx" << std::endl
74 <<
" n CDATA #REQUIRED" << std::endl
75 <<
" zi CDATA #REQUIRED" << std::endl
76 <<
" zo CDATA #REQUIRED" << std::endl
77 <<
" ri CDATA #REQUIRED" << std::endl
78 <<
" ro CDATA #REQUIRED" << std::endl
79 <<
" w CDATA #REQUIRED" << std::endl
80 <<
" eta CDATA #REQUIRED" << std::endl
81 <<
" phi CDATA #REQUIRED" << std::endl
82 <<
" sh CDATA \"0\"" << std::endl
83 <<
" dphi CDATA \"0\"" << std::endl
84 <<
" RPCi CDATA \"0\"" << std::endl
85 <<
" RPCo CDATA \"0\"" << std::endl
86 <<
" zis CDATA #REQUIRED" << std::endl
87 <<
" zos CDATA #REQUIRED" << std::endl
88 <<
" ws CDATA #REQUIRED" << std::endl
89 <<
" or CDATA \"0\">" << std::endl
90 <<
"<!ELEMENT ATrd EMPTY >" << std::endl
91 <<
"<!ATTLIST ATrd" << std::endl
92 <<
" n CDATA #REQUIRED" << std::endl
93 <<
" zi CDATA #REQUIRED" << std::endl
94 <<
" zo CDATA #REQUIRED" << std::endl
95 <<
" ri CDATA #REQUIRED" << std::endl
96 <<
" ro CDATA #REQUIRED" << std::endl
97 <<
" wi CDATA #REQUIRED" << std::endl
98 <<
" wo CDATA #REQUIRED" << std::endl
99 <<
" eta CDATA #REQUIRED" << std::endl
100 <<
" phi CDATA #REQUIRED" << std::endl
101 <<
" dphi CDATA \"0\"" << std::endl
102 <<
" sh CDATA \"0\"" << std::endl
103 <<
" a CDATA \"0\">" << std::endl
105 <<
"<AMuonGeometry>" << std::endl;
118 for (
int sn=0; sn<=snMax; sn++) {
124 std::string stationTech;
146 if (stationTech ==
"TGC") {
157 for (
int eta=-16; eta<=16; eta++) {
158 std::vector<const MuonGM::MuonStation *> *stations =
new std::vector<const MuonGM::MuonStation *>;
161 for (
int phi=maxPhi; phi>0; phi--) {
168 if (station) stations->push_back(station);
172 while (stations->size() > 0) {
177 HepGeom::Point3D<double> pos1 =
getPosition(station1, maxPhi);
180 double shift1 =
getShift(pos1, dphi1);
184 double signed_dz = station1->
Zsize()/2.;
185 if (pos1.z()<0) signed_dz *= -1;
186 double zi1 = pos1.z() - signed_dz;
187 double zo1 = pos1.z() + signed_dz;
188 double ri1 = pos1.perp() - station1->
Rsize()/2.;
189 double ro1 = pos1.perp() + station1->
Rsize()/2.;
190 double wi1 = station1->
Ssize();
194 std::string phiString =
DataType(phi1).toString();
197 stations->erase(stations->end()-1, stations->end());
202 for (
it=stations->end()-1;
it>=stations->begin(); --
it) {
204 int phi2 = (*it)->getPhiIndex();
206 double shift2 =
getShift(pos2, dphi2);
209 double signed_dz2 = (*it)->Zsize()/2.;
210 if (pos2.z()<0) signed_dz2 *= -1;
211 double zi2 = pos2.z() - signed_dz2;
212 double zo2 = pos2.z() + signed_dz2;
213 double ri2 = pos2.perp() - (*it)->Rsize()/2.;
214 double ro2 = pos2.perp() + (*it)->Rsize()/2.;
215 double wi2 = (*it)->Ssize();
216 double wo2 = (*it)->LongSsize();
233 phiString +=
" " +
DataType(phi2).toString();
235 stations->erase(
it,
it+1);
260 }
else if (
stationName[1] ==
'I' && eta==7 && wi1>1800) {
267 <<
" zi=\"" << zi1/10. <<
"\"" <<
" zo=\"" << zo1/10. <<
"\""
268 <<
" ri=\"" << ri1/10. <<
"\"" <<
" ro=\"" << ro1/10. <<
"\""
269 <<
" w=\"" << wi1/10. <<
"\""
270 <<
" eta=\"" << eta <<
"\""
271 <<
" phi=\"" << phiString <<
"\"";
275 out <<
" dphi=\"" << 180/
M_PI * dphi1 <<
"\"";
279 out <<
" sh=\"" << shift1/10. <<
"\"";
283 out <<
" RPCi=\"" << rpci <<
"\"";
285 out <<
" RPCo=\"" << rpco <<
"\"";
286 out <<
" />" << std::endl;
291 writeATrd(
out, stationTech,
stationName, zi1, zo1, ri1, ro1, wi1, wo1, eta, phiString, dphi1, shift1, alpha1);
309 return HepGeom::RotateZ3D(-phi) *
pos;
317 }
else if (std::abs(
pos.phi() -
M_PI/8.) <
M_PI/16.) {
330 CLHEP::HepRotation rot = trans.getRotation();
333 return M_PI/2. - rot.getTheta();
338 HepGeom::Point3D<double> rotpos;
344 rotpos = HepGeom::RotateZ3D(-dphi) *
pos;
357 out <<
"</AMuonGeometry>" << std::endl;
362 const std::string& stationTech,
const std::string&
stationName,
363 double zi,
double zo,
double ri,
double ro,
double wi,
double wo,
364 int eta,
const std::string& phiString,
365 double dphi,
double shift,
double alpha)
const {
367 out <<
"<ATrd n=\"" << stationTech <<
"_" <<
stationName << std::abs(eta) <<
"\""
368 <<
" zi=\"" << zi/10. <<
"\"" <<
" zo=\"" << zo/10. <<
"\""
369 <<
" ri=\"" << ri/10. <<
"\"" <<
" ro=\"" << ro/10. <<
"\""
370 <<
" wi=\"" << wi/10. <<
"\"" <<
" wo=\"" << wo/10. <<
"\""
371 <<
" eta=\"" << eta <<
"\""
372 <<
" phi=\"" << phiString <<
"\"";
376 out <<
" dphi=\"" << 180/
M_PI * dphi <<
"\"";
380 out <<
" sh=\"" << shift/10. <<
"\"";
384 out <<
" a=\"" << 180/
M_PI * alpha <<
"\"";
386 out <<
" />" << std::endl;
398 ATH_MSG_ERROR(
"Could not retrieve the ATLAS GeoModelExperiment from detector store" );
403 GeoVolumeCursor av(world);
404 while (!av.atEnd()) {
405 if ( av.getName()==
"Muon") {
406 GeoVolumeCursor
pv(av.getVolume());
407 while (!
pv.atEnd()) {
408 if (
pv.getVolume()->getLogVol()->getName()==
"NewSmallWheel") {
410 GeoVolumeCursor pvnsw(
pv.getVolume());
412 while (!pvnsw.atEnd()){
413 std::string
stationName = pvnsw.getVolume()->getLogVol()->getName();
419 GeoVolumeCursor pvnswsub(pvnsw.getVolume());
420 bool newChamber =
true;
421 std::string phiString =
"";
422 std::string phiString_mirrorEta =
"";
423 double dphi=0, shift=0, zi=0, zo=0, ri=0, ro=0, wi=0, wo=0;
424 std::string chamberName=
"";
425 HepGeom::Point3D<double> pos_rot;
427 while (!pvnswsub.atEnd()){
428 if (((pvnswsub.getVolume()->getLogVol())->getShape())->typeID() == GeoTrd::getClassTypeID() ) {
433 readNSWMMPars(&pvnswsub, maxPhi, chamberName, pos_rot, zi, zo, ri, ro, wi, wo, dphi, shift,
phiIndex);
441 std::string chamberName2;
442 HepGeom::Point3D<double> pos_rot2;
443 double zi2, zo2, ri2, ro2, wi2, wo2, dphi2, shift2;
445 readNSWMMPars(&pvnswsub, maxPhi, chamberName2, pos_rot2, zi2, zo2, ri2, ro2, wi2, wo2, dphi2, shift2, phiIndex2);
447 if (chamberName != chamberName2
463 std::string stationPhi =
DataType(phiIndex2).toString();
464 if (phiString.find(stationPhi) == std::string::npos) phiString +=
" " + stationPhi;
467 else if (pos_rot.distance(HepGeom::Point3D<double>(pos_rot2.x(), pos_rot2.y(), -pos_rot2.z())) <
m_smallDistance
472 std::string stationPhi =
DataType(phiIndex2).toString();
473 if (phiString_mirrorEta.find(stationPhi) == std::string::npos){
474 if (not phiString_mirrorEta.empty()) phiString_mirrorEta +=
" ";
475 phiString_mirrorEta += stationPhi;
488 if (phiString!=
"" && (newChamber || pvnswsub.atEnd())){
492 std::string stationTech =
"MM";
493 std::string
stationName =
"MM"+chamberName.substr(7,1);
494 int eta = std::stoi(chamberName.substr(8,1));
495 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
496 if (phiString_mirrorEta!=
"") {
497 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
501 phiString_mirrorEta =
"";
516 GeoVolumeCursor pvnswsub(pvnsw.getVolume());
517 bool newChamber =
true;
518 std::string phiString =
"";
519 std::string phiString_mirrorEta =
"";
521 double dz=0, dphi=0, shift=0;
522 std::string chamberName=
"";
523 HepGeom::Point3D<double> pos_rot;
524 const GeoSimplePolygonBrep* theBrep =
nullptr;
526 while (!pvnswsub.atEnd()){
527 if (((pvnswsub.getVolume()->getLogVol())->getShape())->typeID() == GeoShapeShift::getClassTypeID() ) {
542 std::string chamberName2;
543 HepGeom::Point3D<double> pos_rot2;
544 const GeoSimplePolygonBrep* theBrep2;
545 int nvtx2, phiIndex2;
546 double dz2, dphi2, shift2;
547 readNSWSTGCPars(&pvnswsub, maxPhi, chamberName2, pos_rot2, theBrep2, nvtx2, dz2, dphi2, shift2, phiIndex2);
550 bool isSameShape =
true;
552 for (
int i=0;
i<nvtx; ++
i){
553 if ( !
equalLength(theBrep->getXVertex(
i), theBrep2->getXVertex(
i))
554 || !
equalLength(theBrep->getYVertex(
i), theBrep2->getYVertex(
i)) )
565 if (chamberName != chamberName2
577 std::string stationPhi =
DataType(phiIndex2).toString();
578 if (phiString.find(stationPhi) == std::string::npos) phiString +=
" " + stationPhi;
581 else if (pos_rot.distance(HepGeom::Point3D<double>(pos_rot2.x(), pos_rot2.y(), -pos_rot2.z())) <
m_smallDistance) {
583 std::string stationPhi =
DataType(phiIndex2).toString();
584 if (phiString_mirrorEta.find(stationPhi) == std::string::npos) {
585 if (not phiString_mirrorEta.empty()) phiString_mirrorEta +=
" ";
586 phiString_mirrorEta += stationPhi;
598 if (phiString!=
"" && (newChamber || pvnswsub.atEnd())){
602 std::string stationTech =
"STGC";
603 std::string
stationName =
"ST"+chamberName.substr(8,1);
604 int eta = std::stoi(chamberName.substr(9,1));
605 double signed_dz = dz;
606 if (pos_rot.z()<0) dz *= -1;
607 double zi = pos_rot.z() - signed_dz;
608 double zo = pos_rot.z() + signed_dz;
609 double rho = pos_rot.perp();
610 double ri, ro, wi, wo;
616 const int vtxList[] = {0, 1, 2, 3};
618 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
619 if (phiString_mirrorEta!=
"") {
620 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
632 const int vtxList1[] = {5, 2, 3, 4};
634 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
635 if (phiString_mirrorEta!=
"") {
636 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
640 const int vtxList2[] = {0, 1, 2, 5};
642 writeATrd(
out, stationTech,
stationName, zi, zo, ri, ro, wi, wo, eta, phiString, dphi, shift, 0);
643 if (phiString_mirrorEta!=
"") {
644 writeATrd(
out, stationTech,
stationName, -zi, -zo, ri, ro, wi, wo, -eta, phiString_mirrorEta, dphi, shift, 0);
650 ATH_MSG_ERROR(
"Shape not supported by GeometryJiveXML: polygon shape with "<<nvtx <<
" verticies in NSW sTGC." );
653 phiString_mirrorEta =
"";
676 if (phi<0) phi += 2.*
M_PI;
687 HepGeom::Point3D<double> pos_rot = HepGeom::RotateZ3D(-sectorPhi) * HepGeom::Point3D<double>(
pos.x(),
pos.y(),
pos.z());
693 double& zi,
double& zo,
double& ri,
double& ro,
double& wi,
double& wo,
double& dphi,
double& shift,
int&
phiIndex)
const {
695 chamberName =
pv->getVolume()->getLogVol()->getName();
696 const GeoTrd* theTrd =
dynamic_cast<const GeoTrd*
> ((
pv->getVolume()->getLogVol())->getShape());
702 double signed_dz = theTrd->getXHalfLength1();
703 if (pos_rot.z()<0) signed_dz *= -1;
705 zi = pos_rot.z() - signed_dz;
706 zo = pos_rot.z() + signed_dz;
707 ri = pos_rot.perp() - theTrd->getZHalfLength();
708 ro = pos_rot.perp() + theTrd->getZHalfLength();
709 wi = 2.0 * theTrd->getYHalfLength1();
710 wo = 2.0 * theTrd->getYHalfLength2();
718 std::string& chamberName, HepGeom::Point3D<double>& pos_rot,
const GeoSimplePolygonBrep*& theBrep,
719 int& nvtx,
double& dz,
double& dphi,
double& shift,
int&
phiIndex)
const {
721 chamberName =
pv->getVolume()->getLogVol()->getName();
723 const GeoShapeShift* theShift =
dynamic_cast<const GeoShapeShift*
> ((
pv->getVolume()->getLogVol())->getShape());
724 theBrep =
dynamic_cast<const GeoSimplePolygonBrep*
> (theShift->getOp());
725 nvtx = theBrep->getNVertices();
726 dz = theBrep->getDZ();
739 double& ri,
double& ro,
double& wi,
double& wo)
const {
743 ri =
rho + theBrep->getYVertex(vtx[3]);
744 ro =
rho + theBrep->getYVertex(vtx[0]);
745 wi = theBrep->getXVertex(vtx[3]) - theBrep->getXVertex(vtx[2]);
746 wo = theBrep->getXVertex(vtx[0]) - theBrep->getXVertex(vtx[1]);