| Report problems to ATLAS LXR Team (with time and IP address indicated) |
|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
||||
|
||||||
| Links to LXR source navigation pages for stable releases | [ 12.*.* ] [ 13.*.* ] [ 14.*.* ] [ 15.*.* ] | |||||
001 #include "GaudiKernel/MsgStream.h" 002 #include "AthenaKernel/getMessageSvc.h" 003 // 004 #include "MuonGeoModel/MuonChamber.h" 005 #include "MuonGeoModel/Position.h" 006 #include "MuonReadoutGeometry/MuonStation.h" 007 #include "MuonGeoModel/FPVMAP.h" 008 #include "MuonReadoutGeometry/MuonDetectorManager.h" 009 #include "MuonGeoModel/Station.h" 010 #include "MuonGeoModel/Csc.h" 011 #include "MuonGeoModel/Mdt.h" 012 #include "MuonGeoModel/Tgc.h" 013 #include "MuonGeoModel/Rpc.h" 014 #include "MuonGeoModel/Ded.h" 015 #include "MuonGeoModel/Sup.h" 016 #include "MuonGeoModel/Spacer.h" 017 #include "MuonGeoModel/SpacerBeam.h" 018 #include "MuonGeoModel/Cutout.h" 019 #include "MuonReadoutGeometry/GlobalUtilities.h" 020 // 021 #include "MuonGeoModel/StandardComponent.h" 022 #include "MuonGeoModel/LbiComponent.h" 023 #include "MuonGeoModel/CbmComponent.h" 024 #include "MuonGeoModel/MdtComponent.h" 025 #include "MuonGeoModel/RpcComponent.h" 026 #include "MuonGeoModel/SupComponent.h" 027 #include "MuonGeoModel/TgcComponent.h" 028 #include "MuonGeoModel/CscComponent.h" 029 #include "MuonReadoutGeometry/MdtReadoutElement.h" 030 #include "MuonReadoutGeometry/RpcReadoutElement.h" 031 #include "MuonReadoutGeometry/TgcReadoutElement.h" 032 #include "MuonReadoutGeometry/CscReadoutElement.h" 033 // just to check subtype, cutout: 034 #include "MuonGeoModel/MYSQL.h" 035 #include "MuonGeoModel/CSC_Technology.h" 036 #include "MuonGeoModel/MDT_Technology.h" 037 #include "MuonGeoModel/RPC_Technology.h" 038 #include "MuonGeoModel/TGC_Technology.h" 039 #include "MuonGeoModel/LBI_Technology.h" 040 // 041 #include "MuonIdHelpers/MdtIdHelper.h" 042 #include "MuonIdHelpers/RpcIdHelper.h" 043 #include "MuonIdHelpers/TgcIdHelper.h" 044 #include "MuonIdHelpers/CscIdHelper.h" 045 // 046 #include "GeoModelKernel/GeoBox.h" 047 #include "GeoModelKernel/GeoTube.h" 048 #include "GeoModelKernel/GeoTrd.h" 049 #include "GeoModelKernel/GeoPhysVol.h" 050 #include "GeoModelKernel/GeoFullPhysVol.h" 051 #include "GeoModelKernel/GeoLogVol.h" 052 #include "GeoModelKernel/GeoMaterial.h" 053 #include "GeoModelKernel/GeoNameTag.h" 054 #include "GeoModelKernel/GeoSerialDenominator.h" 055 #include "GeoModelKernel/GeoTransform.h" 056 #include "GeoModelKernel/GeoShapeShift.h" 057 #include "GeoModelKernel/GeoShapeSubtraction.h" 058 #include "GeoModelKernel/GeoShapeUnion.h" 059 #include "GeoModelKernel/GeoShapeIntersection.h" 060 #include "GeoModelKernel/GeoIdentifierTag.h" 061 #include "CLHEP/Geometry/Transform3D.h" 062 #include <vector> 063 #include <fstream> 064 #include <iomanip> 065 066 #define RPCON true 067 #define useAssemblies false 068 069 namespace MuonGM { 070 071 072 MuonChamber::MuonChamber(Station *s): DetectorElement(s->GetName()) 073 { 074 075 width = s->GetWidth1(); 076 longWidth = s->GetWidth2(); 077 thickness = s->GetThickness(); 078 length=s->GetLength(); 079 station = s; 080 // CSL envelope is too small for its components - enlarge it slightly 081 std::string stname(station->GetName(), 0, 3); 082 if (stname == "CSL") longWidth *= 1.015; 083 084 m_msgSvc = Athena::getMessageSvc(); 085 m_enableFineClashFixing = 0; 086 } 087 088 089 GeoVPhysVol* 090 MuonChamber::build(MuonDetectorManager* m_manager, int zi, 091 int fi, bool is_mirrored, bool& isAssembly) 092 { 093 MsgStream log(m_msgSvc, "MuGM:MuonChamber"); 094 bool m_debug = log.level() <= MSG::DEBUG; 095 bool m_verbose = log.level() <= MSG::VERBOSE; 096 if (m_verbose) std::cout << " Building a MuonChamber for station " 097 << station->GetName() << " at zi, fi " 098 << zi << " " << fi+1 << " is_mirrored " << is_mirrored 099 << " is assembly = " << isAssembly << std::endl; 100 std::string stname(station->GetName(), 0, 3); 101 MYSQL* mysql=MYSQL::GetPointer(); 102 MDT* m = (MDT*)mysql->GetATechnology("MDT0"); 103 double halfpitch = (m->pitch)/2.; 104 105 std::string stName = station->GetName(); 106 const MdtIdHelper* mdt_id = m_manager->mdtIdHelper(); 107 int stationType = mdt_id->stationNameIndex(stName.substr(0,3)); 108 bool is_barrel = (stName.substr(0,1)=="B"); 109 110 std::string geometry_version=m_manager->geometryVersion(); 111 112 double extratop = station->GetExtraTopThickness(); 113 double extrabottom = station->GetExtraBottomThickness(); 114 double totthick = thickness + extratop + extrabottom; 115 116 GeoTrd* maintrd; 117 maintrd = new GeoTrd(totthick/2, totthick/2, width/2, 118 longWidth/2, length/2); 119 if (length <= 0) std::cerr << " Invalid length " << length << " for station " 120 << station->GetName() << " fi/zi " << fi+1 121 << "/" << zi << std::endl; 122 if (m_verbose) log << MSG::VERBOSE << " MuonChamber size thick,w,lw,l " 123 << totthick << ", " << width << ", " << longWidth 124 << ", " << length << std::endl; 125 126 const GeoShape* strd = 0; 127 double dx = 0.; 128 if ( (extratop + extrabottom) != 0.) { 129 // sup on top & bottom 130 dx = extratop/2. - extrabottom/2.; 131 if (m_verbose) log<<MSG::VERBOSE<<" station name "<<station->GetName()<<" extra top, bottom, dx = " 132 <<extratop<<" "<<extrabottom<<endreq; 133 strd = & ( (*maintrd) << HepTranslate3D(dx, 0., 0.) ); 134 } else { 135 strd = maintrd; 136 } 137 138 double amdbOrigine_along_length = station->getAmdbOrigine_along_length(); 139 double amdbOrigine_along_thickness = station->getAmdbOrigine_along_thickness(); 140 141 // Fix clash of EIS1 and CSS1. Cut out upper corner of CSS1 envelope (along long width) 142 if (stname == "CSS") { 143 StandardComponent* comp = 0; 144 double clen = 0; 145 double cthick = 0; 146 double cypos = 0; 147 double cxpos = 0; 148 for (int i = 0; i < station->GetNrOfComponents(); i++) { 149 comp = (StandardComponent*)station->GetComponent(i); 150 if ((comp->name).substr(0,3) == "CSC") { 151 clen = comp->dy; 152 cthick = comp->GetThickness(); 153 cypos = clen - comp->posy + 1.0 - length/2.; 154 cxpos = -totthick/2. + comp->posz + cthick/2. + 0.1; 155 break; 156 } 157 } 158 GeoShape* box = new GeoBox(cthick/2., longWidth/2., (length-clen)/2.); 159 box->ref(); 160 strd = &(strd->subtract( (*box) << HepTranslate3D(cxpos, 0., cypos) ) ); 161 box->unref(); 162 } 163 164 if (m_enableFineClashFixing > 0) { 165 // Mother volume modifications for specific chambers 166 167 // Fix clashes of non-cutout BMS with BTWingRib 168 if ((stname == "BMS" && std::abs(zi) == 5) || 169 (stname == "BMS" && std::abs(zi) == 1 && fi != 3)) { 170 StandardComponent* comp = 0; 171 double cutlen = 0.; 172 double cutthick = 0.; 173 double top_edge = 0.; 174 for (int i = station->GetNrOfComponents() - 2; i > -1; i--) { 175 comp = (StandardComponent*)station->GetComponent(i); 176 top_edge = comp->posy + comp->dy; 177 cutlen = length - top_edge; 178 if ((comp->posy != 0 && cutlen > 0.1) || comp->dy > 0.75*length) { 179 cutthick = comp->GetThickness() + 1.; 180 break; 181 } 182 } 183 GeoShape* box1 = new GeoBox(cutthick/2., (longWidth+2.)/2., cutlen); 184 box1->ref(); 185 strd = &(strd->subtract( (*box1) << HepTranslate3D( (totthick-cutthick)/2., 0., length/2.) ) ); 186 box1->unref(); 187 } 188 } 189 190 // Skip mother volume modifications for assembly volumes since they cannot cause clash 191 if (!isAssembly) { 192 193 bool testEIL = (stname == "EIL" && std::abs(zi) != 1 194 && (std::abs(zi) != 4 || fi == 0 || fi == 4)); 195 196 if ((m_enableFineClashFixing && 197 (stname == "BML" || stname == "BIL" || stname == "BOL" || 198 stname == "BMS" || stname == "BIS" || stname == "BOS")) || 199 testEIL) { 200 double root3 = 1.7320508; 201 StandardComponent* comp = 0; 202 double mdt_half_thick = -1.; 203 double mdt_pos = 0.; 204 double xtube1 = 0; 205 double xtube2 = 0; 206 207 int index = 0; 208 int mdt_index[4] = {0, 0, 0, 0}; 209 for (int i = 0; i < station->GetNrOfComponents(); i++) { 210 comp = (StandardComponent*)station->GetComponent(i); 211 std::string compName = (comp->name).substr(0,3); 212 if (compName == "MDT") { 213 mdt_index[index] = i; 214 index += 1; 215 } 216 } 217 218 // Prepare boxes and cylinders for chamber volume mods 219 GeoShape* box = new GeoBox((totthick+2.)/2., (longWidth+2.)/2., halfpitch); 220 box->ref(); 221 const GeoShape* frontcyl = new GeoTube(0.0, halfpitch+0.001, longWidth/2.); 222 frontcyl = &( (*frontcyl) << HepRotateX3D(90.*deg) ); 223 frontcyl->ref(); 224 const GeoShape* backcyl = new GeoTube(0.0, halfpitch-0.001, (longWidth+2.)/2.); 225 backcyl = &( (*backcyl) << HepRotateX3D(90.*deg) ); 226 backcyl->ref(); 227 228 if (index > 0) { 229 // If chamber has MDTs, shorten length by halfpitch (remove what was added in DBReader.h) 230 strd = &(strd->subtract( (*box) << HepTranslate3D(0., 0., length/2.) ) ); 231 double sign = 1.; 232 for (int i = 0; i < index; i++) { 233 comp = (StandardComponent*)station->GetComponent(mdt_index[i]); 234 mdt_half_thick = comp->GetThickness()/2.; 235 mdt_pos = -totthick/2. + comp->posz + mdt_half_thick; 236 if (geometry_version.substr(0,1) != "P") mdt_pos += amdbOrigine_along_thickness; 237 xtube1 = sign*(mdt_half_thick - (root3 + 1.)*halfpitch); 238 xtube2 = sign*(mdt_half_thick - (3*root3 + 1.)*halfpitch); 239 strd = &(strd->add( (*frontcyl) << HepTranslate3D(mdt_pos+xtube1, 0., length/2.-halfpitch) ) ); 240 strd = &(strd->subtract( (*backcyl) << HepTranslate3D(mdt_pos+xtube1, 0., -length/2.) ) ); 241 242 if (stname == "BIL" || (stname == "BIS" && std::abs(zi) != 8) || testEIL) { 243 strd = &(strd->add( (*frontcyl) << HepTranslate3D(mdt_pos+xtube2, 0., length/2.-halfpitch) ) ); 244 strd = &(strd->subtract( (*backcyl) << HepTranslate3D(mdt_pos+xtube2, 0., -length/2.) ) ); 245 } 246 247 sign *= -1.; 248 } 249 } 250 if (stname != "EIL") { 251 if (zi < 0 && !is_mirrored) strd = &( (*strd) << HepRotateX3D(180.*deg) ); 252 } 253 254 box->unref(); 255 frontcyl->unref(); 256 backcyl->unref(); 257 } // fine clash fixing 258 } // !isAssembly 259 260 261 // This will allow the MDT tube structure to be mirrored w.r.t. the chamber at z>0 262 // and to correctly place any other component in the station 263 if (zi<0 && !is_mirrored && stName[0]=='B' && (geometry_version != "CTB2004") ) { 264 if (station->hasMdts()) { 265 amdbOrigine_along_length += halfpitch; 266 } 267 } 268 269 if (m_verbose) log << MSG::VERBOSE <<"amdb origine: in the length direction = " 270 << amdbOrigine_along_length<<" in the thickness direction = " 271 << amdbOrigine_along_thickness << endreq; 272 273 if (isAssembly) if (m_debug) log<<MSG::DEBUG<<"Station "<<stName<<" at zi, fi " 274 <<zi<<" "<<fi+1<<" will be described as Assembly"<<endreq; 275 276 // for BOG in layout Q we will have to shorten CHV, CMI as these 277 // are not shortened in AMDB 278 double lengthShiftCP = 0.; 279 280 // if this is a BOG, we want to make cutouts in the MOTHER VOLUME 281 if (stName.substr(0,3) == "BOG" && 282 (m_manager->IncludeCutoutsBogFlag() || m_manager->IncludeCutoutsFlag())) 283 { 284 if (m_verbose) log << MSG::VERBOSE << "amdb org: length= " 285 << amdbOrigine_along_length << " thickness= " 286 << amdbOrigine_along_thickness << endreq; 287 // std::cout<<"This is "<<stName<<" at zi/fi "<<zi<<"/"<<fi<<std::endl; 288 std::string statType=stName.substr(0,3); 289 if (station->GetNrOfCutouts() >0 ) { 290 if (m_debug) log << MSG::DEBUG << "Station "<<stName<<" at zi, fi "<<zi 291 <<" "<<fi+1<<" has components with cutouts " << endreq; 292 isAssembly = true; 293 // std::cout << "From the MuonChamber " << stName << " at zi, fi " << zi 294 // << " " << fi+1 << " this will be an assembly " << std::endl; 295 296 // look for FIRST component with cutouts and loop over all of the cutouts: 297 bool foundCutouts = false; 298 for (int j = 0; j < station->GetNrOfComponents(); j++) { 299 StandardComponent* c = (StandardComponent*)station->GetComponent(j); 300 // std::cout << "Loop over components " << j << " name " << c->name 301 // << " Job = " << c->index << " foundCutouts = " << foundCutouts 302 // << std::endl; 303 if (!foundCutouts) { 304 for (int ii=0; ii<station->GetNrOfCutouts();ii++) { 305 Cutout* cut = station->GetCutout(ii); 306 // if this is a BOG in layout Q, set the CP param: 307 // (both cuts have same length so ok to reset it) 308 // std::cout<<"Loop over station cutouts "<<ii<<std::endl; 309 if (geometry_version.substr(0,1) != "P") { 310 lengthShiftCP = cut->lengthY; 311 // also do here some tweaking to prevent undershoot 312 // of the cutouts wrt mother volume: 313 if ( fabs(cut->dx-600.7)<0.1 ) 314 { 315 cut->dx = cut->dx + 10.*mm; 316 cut->widthXs = cut->widthXs + 20.*mm; 317 cut->widthXl = cut->widthXl + 20.*mm; 318 //std::cout<<" redefining par.s for BOG1 cutouts " 319 //<<std::endl; 320 } 321 if ( fabs(cut->dx+600.7)<0.1 ) 322 { 323 cut->dx = cut->dx - 10.*mm; 324 cut->widthXs = cut->widthXs + 20.*mm; 325 cut->widthXl = cut->widthXl + 20.*mm; 326 } 327 if (fabs(cut->lengthY-180.2)<0.001) 328 { 329 cut->lengthY = cut->lengthY+(0.010)*mm; 330 //imt std::cout<<"Redefining "<<stName<<" cut lengthY to " 331 //imt <<cut->lengthY 332 //imt <<std::endl; 333 } 334 if (fabs(cut->dy-1019.8)<0.001) 335 { 336 cut->dy = 1216.4185-cut->lengthY; 337 } 338 } 339 // create the cutout with the full thickness of the STATION 340 cut->setThickness(totthick*1.01);// extra to be sure 341 // std::cout << "cutout subtype/icut/ijob = " << cut->subtype << "/" << cut->icut 342 // << "/" << cut->ijob << std::endl; 343 if ((cut->subtype == 344 mysql->allocPosFindSubtype(statType, fi, zi))&& 345 (cut->icut == mysql->allocPosFindCutout(statType, fi, zi))&& 346 (cut->ijob == c->index)) 347 { 348 foundCutouts = true; 349 } 350 } // Loop over cutouts 351 } // If no cutouts 352 } // Loop over components 353 } 354 }// end of special loop just for cutouts 355 356 // remove overlaps between end-cap and forward region of TGC stations, 357 // T[1-3]E1_station and T[1-3]F1_station 358 if (stName.substr(0,1) == "T" && stName.substr(2,1) == "E" && stName.substr(1,1) != "4") { 359 GeoTrd* strdoverlap = new GeoTrd(totthick/4, totthick/4, width/2, 360 longWidth/2, 400./2); 361 strd = &(strd->subtract((*strdoverlap) << HepTranslate3D(-totthick/4., 0., -length/2+400./2.) )); 362 } 363 364 const GeoMaterial* mtrd = 0; 365 if (useAssemblies || isAssembly) { 366 mtrd = matManager->getMaterial("special::Ether"); 367 } else { 368 mtrd = matManager->getMaterial("std::Air"); 369 } 370 GeoLogVol* ltrd = new GeoLogVol(stName+"_Station", strd, mtrd); 371 GeoPhysVol* ptrd = new GeoPhysVol(ltrd); 372 373 double ypos; 374 double zpos; 375 double xpos; //imt new 376 static double irad = 0; 377 int ndbz[2] = {0,0}; 378 379 // Compute how many RPC modules there are in the station 380 int nDoubletR = 0; 381 int nRpc = 0; 382 int nTgc = 0; 383 int nCsc = 0; 384 int nMdt = 0; 385 double previous_depth = 0.; 386 if (m_verbose) log << MSG::VERBOSE << " Station Name = " << stName 387 << " fi/zi " << fi << "/" << zi 388 <<" defining the n. of DoubletR to "; 389 390 for (int j = 0; j < station->GetNrOfComponents(); j++) { 391 StandardComponent* d = (StandardComponent*)station->GetComponent(j); 392 std::string cn = (d->name).substr(0,3); 393 if (cn == "RPC") { 394 nRpc++; 395 if ( nRpc == 1 ) nDoubletR++; 396 double depth = -thickness/2.+d->posz+d->GetThickness()/2.; 397 // std::cerr << " nRpc, nDoubletR, depth " << nRpc << " " << nDoubletR 398 // << " " << depth; 399 if ( nDoubletR == 1 && nRpc>1 && depth*previous_depth < 0) nDoubletR++; 400 // std::cerr<<" updated to "<<nDoubletR<<std::endl; 401 previous_depth = depth; 402 } 403 if (cn == "CSC") {nCsc++;} 404 if (cn == "TGC") {nTgc++;} 405 if (cn == "MDT") {nMdt++;} 406 } 407 if (m_debug){ 408 log<<MSG::DEBUG<<" "<<nDoubletR; 409 log<<MSG::DEBUG<<" nMdt/Rpc/Tgc/Csc "<<nMdt<<"/"<<nRpc<<"/"<<nTgc<<"/"<<nCsc<<endreq; 410 } 411 //std::cerr<<" nRpc, nDoubletR "<<nRpc<<" "<<nDoubletR<<" in "<<stName<<std::endl; 412 413 // Get location and dimensions of long beams and pass them to cross beams 414 // in order to make holes 415 int numLB = -1; 416 double LBheight = 0; 417 double LBwidth = 0; 418 double LBpos[2] = {-1, -1}; 419 for (int i = 0; i < station->GetNrOfComponents(); i++) { 420 StandardComponent* c = (StandardComponent*)station->GetComponent(i); 421 std::string cname = (c->name).substr(0,2); 422 if (cname == "LB") { 423 LBI* lb = (LBI*) mysql->GetTechnology(c->name); 424 numLB++; 425 LBpos[numLB] = c->posy + c->dy/2.; 426 LBheight = lb->height; 427 LBwidth = c->dy; 428 } 429 if (numLB > 0) break; // only 2 LBs per chamber 430 } 431 432 for (int i = 0; i < station->GetNrOfComponents(); i++) { 433 StandardComponent* c = (StandardComponent*)station->GetComponent(i); 434 std::string cname = (c->name).substr(0,3); 435 if (cname == "CRO" || cname == "CMI" || cname == "CHV") { 436 CbmComponent* ccbm = (CbmComponent*)c; 437 ccbm->lb_height = LBheight; 438 ccbm->lb_width = LBwidth; 439 ccbm->hole_pos1 = LBpos[0]; 440 ccbm->hole_pos2 = LBpos[1]; 441 } 442 } 443 444 // Look for the subtype of the CMI in the chamber to let LB know ... 445 std::string CMIcomponentNumber = ""; 446 for (int j = 0; j < station->GetNrOfComponents(); j++) { 447 StandardComponent* d = (StandardComponent*)station->GetComponent(j); 448 std::string cn = (d->name).substr(0,3); 449 if (cn == "CMI") { 450 CMIcomponentNumber = (d->name).substr(3,2); 451 break; 452 } 453 } 454 for (int j = 0; j < station->GetNrOfComponents(); j++) { 455 StandardComponent* d = (StandardComponent*)station->GetComponent(j); 456 std::string cn = (d->name).substr(0,2); 457 if (cn == "LB") { 458 LbiComponent* lbic = (LbiComponent*)d; 459 if (lbic) { 460 // std::cerr << "associating to LB comp " << lbic->name << " CMIsubtype = " 461 // << CMIcomponentNumber << std::endl; 462 lbic->associated_CMIsubtype = CMIcomponentNumber; 463 } 464 else log << MSG::ERROR 465 << "MuonChamber :: cannot associate a CMI subtype to the LB component " 466 << endreq; 467 } 468 } 469 470 // Build the MuonStation(readout-geometry) corresponding to this MuonChamber(raw-geometry) 471 MuonStation* mstat; 472 if (stName.substr(0,1) == "B") 473 mstat = new MuonStation(stName.substr(0,3), width, totthick, length, 474 longWidth, totthick, length, zi, fi+1, 475 (zi<0 && !is_mirrored)); //!< fi here goes from 0 to 7; in amdb from 1 to 8; 476 else 477 mstat = new MuonStation(stName.substr(0,3), width, length, totthick, 478 longWidth, length, totthick, zi, fi+1, 479 (zi<0 && !is_mirrored));//!< fi here goes from 0 to 7; in amdb from 1 to 8; 480 m_manager->addMuonStation(mstat); 481 if (m_debug) log << MSG::DEBUG << " Building a MuonStation for this MuonChamber " 482 << station->GetName() << " at zi, fi " 483 << zi << " " << fi+1 << " is_mirrored " << is_mirrored << endreq; 484 485 486 // here the big loop over the components !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 487 488 for (int i = 0; i < station->GetNrOfComponents(); i++) { 489 StandardComponent* c = (StandardComponent*)station->GetComponent(i); 490 if (m_verbose) log << MSG::VERBOSE 491 << " Component loop for " << stName << " " << stationType 492 << " at zi, fi " << zi << " " << fi+1 << " " << c->name 493 << " thickness " << c->GetThickness() << " length " << c->dy 494 << " w, lw " << c->dx1 << " " << c->dx2 << std::endl; 495 496 ypos = -thickness/2. + c->posz + c->GetThickness()/2.; 497 zpos = 0.; 498 xpos = 0.; 499 500 if (geometry_version.substr(0,1) != "P") { 501 ypos = -thickness/2. + (c->posz+amdbOrigine_along_thickness)+c->GetThickness()/2.; 502 zpos = -length/2. + amdbOrigine_along_length + c->posy + c->dy/2.; 503 xpos = c->posx; 504 } 505 506 std::string techname = c->name; 507 std::string type = techname.substr(0,3); 508 509 GeoVPhysVol* lv = NULL; 510 GeoVPhysVol* lvd = NULL; 511 GeoVPhysVol* lvs = NULL; 512 GeoVPhysVol* lvo = NULL; 513 GeoFullPhysVol* lvm = NULL; 514 GeoFullPhysVol* lvr = NULL; 515 GeoFullPhysVol* lvt = NULL; 516 GeoFullPhysVol* lvc = NULL; 517 518 double BeamHeight; 519 520 // Are there cutouts? 521 std::string statType = stName.substr(0,3); 522 double cthickness = c->GetThickness(); 523 int ncutouts = 0; 524 std::vector<Cutout*> vcutdef; 525 std::vector<Cutout*> vcutdef_todel; 526 for (int ii = 0; ii < station->GetNrOfCutouts(); ii++) { 527 Cutout* cut = station->GetCutout(ii); 528 cut->setThickness(cthickness*1.01); // extra thickness to be sure 529 if ((cut->subtype == 530 mysql->allocPosFindSubtype(statType, fi, zi))&& 531 (cut->icut == mysql->allocPosFindCutout(statType, fi, zi))&& 532 (cut->ijob == c->index)) 533 { 534 double tempdx = cut->dx; 535 double tempdy = cut->dy; 536 double templengthY = cut->lengthY; 537 cut->dx = 0.; 538 cut->dy = 0.; 539 if (geometry_version.substr(0,1) != "P" && stName.substr(0,3)=="BOG") 540 { // make the cutouts a bit longer 541 cut->lengthY=templengthY+31.; 542 } 543 cut->dx = tempdx; 544 cut->dy = tempdy; 545 cut->lengthY = templengthY; 546 // in thickness, cutout will coincide with component 547 // not needed (DHW) double xposcut = 0.; // rel. to component thickness 548 // double yposcut = -xpos+cut->dx; // rel. to component width 549 // double zposcut = -zpos+cut->dy; // rel. to component length 550 // if (geometry_version.substr(0,1) != "P" && stName.substr(0,3)=="BOG") 551 // { 552 // move the extended cut region out a little 553 // if (cut->dy < 10.) zposcut = -zpos+cut->dy - 15.5; 554 // } 555 ncutouts++; 556 557 // Corrected cutout values for BMS7, BMS14 558 if (stName.substr(0,3) == "BMS") { 559 if (fi == 3) { 560 if (std::abs(zi) == 1) { 561 double margin = 1.0; // make cutout a little bigger to avoid coincident boundaries 562 if (type == "RPC" || type == "DED") { 563 cut->widthXl += 2*margin; 564 cut->widthXs += 2*margin; 565 cut->dx += margin; 566 cut->lengthY += 2*margin; 567 cut->dy = -margin; 568 } 569 } 570 if (zi == -1) { 571 if (type == "MDT") cut->dy = 0.; 572 } 573 } 574 } 575 576 if (stName.substr(0,3) == "BOS" && zi == -6 && type == "MDT") { 577 cut->dy = c->dy - cut->dy - cut->lengthY - halfpitch; 578 } 579 580 if (is_mirrored || (zi < 0 && type == "MDT") ) { 581 // MDT in chambers explicitly described at z<0 have to be 582 // rotated by 180deg to adj. tube staggering 583 // reverse the position (x amdb) of the cutout if the station is mirrored 584 Cutout* cutmirr = new Cutout(*cut); 585 cutmirr->dx = - cutmirr->dx; 586 // this way, after the rotation by 180 deg, the cut will be at the same global phi 587 // it has for the station at z>0 588 vcutdef.push_back(cutmirr); 589 vcutdef_todel.push_back(cutmirr); 590 591 } else if (stName.substr(0,3) == "BMS" && std::abs(zi) == 6) { 592 // BMS2, BMS13 593 Cutout* bms2cutfix = new Cutout(*cut); 594 bms2cutfix->dy = cut->dy - c->posy; 595 vcutdef.push_back(bms2cutfix); 596 vcutdef_todel.push_back(bms2cutfix); 597 } else if (stName.substr(0,3) == "BMS" && std::abs(zi) == 4) { 598 // BMS6, BMS11 599 Cutout* bms6cutfix = new Cutout(*cut); 600 bms6cutfix->dx = 0.; 601 bms6cutfix->dy = 0.; 602 if (cut->ijob < 28) { 603 bms6cutfix->dy = 15.; 604 } else if (cut->ijob == 33) { 605 bms6cutfix->dy = 10.; 606 } 607 if (zi == 4 && (cut->ijob == 21 || cut->ijob == 25) ) bms6cutfix->dy = c->dy - cut->lengthY; 608 if (zi == -4 && (cut->ijob == 29 || cut->ijob == 33) ) bms6cutfix->dy = c->dy - cut->lengthY; 609 vcutdef.push_back(bms6cutfix); 610 vcutdef_todel.push_back(bms6cutfix); 611 } else if (stName.substr(0,3) == "BMS" && std::abs(zi) == 2) { 612 // BMS5, BMS9 613 Cutout* bms5cutfix = new Cutout(*cut); 614 bms5cutfix->dx = 0.; 615 bms5cutfix->dy = 0.; 616 if (zi == 2 && (cut->ijob == 32 || cut->ijob == 36) ) bms5cutfix->dy = c->dy - cut->lengthY; 617 if (zi == -2 && (cut->ijob == 24 || cut->ijob == 28) ) bms5cutfix->dy = c->dy - cut->lengthY; 618 vcutdef.push_back(bms5cutfix); 619 vcutdef_todel.push_back(bms5cutfix); 620 621 } else if (stName == "BOS5") { 622 // Looks like a problem in the database for BOS5. 623 // Hard-code the values until there is a fix. DHW 624 Cutout* bos5cutfix = new Cutout(*cut); 625 if (type == "RPC") bos5cutfix->dy = 0.0; 626 if (type == "DED") bos5cutfix->dy = c->dy - cut->lengthY; 627 vcutdef.push_back(bos5cutfix); 628 vcutdef_todel.push_back(bos5cutfix); 629 630 // } else if (stName.substr(0,3) == "BMS" && zi == 3) { 631 // Looks like a problem in the database for BMS4 (cut->dy = -110.83) 632 // Hard-code the values until there is a fix. DHW 633 // if (type == "MDT") { 634 // Cutout* bms4cutfix = new Cutout(*cut); 635 // bms4cutfix->dy = 110.83; 636 // vcutdef.push_back(bms4cutfix); 637 // vcutdef_todel.push_back(bms4cutfix); 638 // std::cout << " BMS4 cut fixed for component " << c->name << std::endl; 639 // } 640 641 } else if (type == "TGC") { 642 // In AMDB, y coordinates of cutout and component are given by 643 // radius from detector z-axis. To get standard y value of cutout, 644 // subtract radius of component from radius of cutout 645 Cutout* tgccut = new Cutout(*cut); 646 tgccut->dy -= c->posy; // 647 vcutdef.push_back(tgccut); 648 vcutdef_todel.push_back(tgccut); 649 650 } else { 651 vcutdef.push_back(cut); 652 } 653 } 654 } // Loop over cutouts in station 655 656 if (ncutouts > 0) if (m_debug) log << MSG::DEBUG 657 << c->name << " of station " 658 << stName << " at fi/zi " << fi+1 << "/" 659 << zi << " has " << ncutouts << " cutouts " 660 << endreq; 661 662 // define here the total transform that will be applied to component: 663 HepTransform3D htcomponent; 664 GeoTransform* xfcomponent = NULL; 665 GeoAlignableTransform * xfaligncomponent = NULL; 666 // // for RPCs we need a vector of transforms for M28 geometry... 667 // std::vector<GeoTransform*> xfrpccomponent; 668 669 if (type == "CRO") { 670 if (stName.substr(0,1) != "B" && is_mirrored) mstat->setxAmdbCRO(-xpos); 671 else mstat->setxAmdbCRO(xpos); 672 } 673 674 if (type == "MDT") { 675 htcomponent = HepTranslateX3D(ypos)*HepTranslateZ3D(zpos)*HepTranslateY3D(xpos); 676 if (zi < 0 && !is_mirrored && stName[0] == 'B' 677 && (geometry_version != "CTB2004") ) { 678 // this (rotation + shift of halfpitch) will mirror the tube structure w.r.t. the chamber at z>0 679 htcomponent = htcomponent*HepRotateX3D(180.*deg); 680 if (geometry_version.substr(0,3) != "P03" ) 681 htcomponent = htcomponent*HepTranslateZ3D(halfpitch); 682 } 683 684 // ss - 24-05-2006 I don't really understand if this is needed at all 685 // it was introduced by Isabel T. 686 if (zi < 0 && stName.substr(0,3) == "BOG" && is_mirrored) { 687 // htcomponent = htcomponent*HepRotateX3D(180.*deg); 688 // tubes OK but chambers wrong 689 // htcomponent = HepRotateX3D(180.*deg)*htcomponent; 690 // chambers OK but tubes wrong 691 htcomponent = HepRotateX3D(180.*deg)*htcomponent* 692 HepRotateX3D(180.*deg); // turn chambers but go back for tubes 693 } // ss - 24-05-2006 I don't really understand if this is needed at all 694 695 xfaligncomponent = new GeoAlignableTransform(htcomponent); 696 std::string key=stName+techname; 697 698 // for cutouts: 699 // MDT cutouts for BOS1,5, BMS7,14, (problem with BMS4,10), EMS 700 bool mdtCutoutFlag = ((stname == "BOS" && std::abs(zi) == 6) || 701 (stname == "BMS" && (std::abs(zi) == 1 && fi == 3)) || 702 (stname == "EMS" && (std::abs(zi) == 1 || std::abs(zi) == 3))); 703 if (((m_manager->IncludeCutoutsFlag() && mdtCutoutFlag) || 704 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG") ) 705 && zi >= 0) 706 key += "p"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) 707 +"_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 708 else if (((m_manager->IncludeCutoutsFlag() && mdtCutoutFlag) || 709 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG") ) 710 && zi < 0) 711 key += "m"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) 712 +"_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 713 714 FPVMAP* savemem = FPVMAP::GetPointer(); 715 GeoVPhysVol* fpv = savemem->GetDetector(key); 716 if (fpv == 0) { 717 Mdt* r = new Mdt(c, stName+techname); 718 if (m_debug) log << MSG::DEBUG << " Building an MDT for station " 719 << key << " component name is " << c->name 720 << " m_manager->IncludeCutoutsFlag() " 721 << m_manager->IncludeCutoutsFlag() 722 << " m_manager->IncludeCutoutsBogFlag() " 723 << m_manager->IncludeCutoutsBogFlag() << endreq; 724 if ((m_manager->IncludeCutoutsFlag() && mdtCutoutFlag) || 725 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 726 { 727 // std::cout << "Building the Mdt " << techname << " in station " 728 // << stName << " at fi/zi " << fi << "/" << zi << std::endl; 729 lvm = r->build(vcutdef); 730 } else { 731 lvm = r->build(); 732 } 733 //log<<MSG::DEBUG<<" Storing in FPVMAP with key "<<key<<endreq; 734 savemem->StoreDetector(lvm, key); 735 delete r; 736 r = 0; 737 738 } else { 739 GeoFullPhysVol* rfpv = (GeoFullPhysVol*)fpv; 740 if (m_verbose) log << MSG::VERBOSE << " This MDT for station " 741 << key << " component name is " 742 << c->name << " already exists; clone it " << endreq; 743 lvm = rfpv->clone(); 744 } 745 746 } else if (type=="SPA" && m_manager->MinimalGeoFlag() == 0) { 747 if (techname == "SPA01" && stName.substr(0,1) == "C") { 748 if (m_debug) log << MSG::DEBUG 749 << "Ficticious spacer SPA01 in CSC chamber - skip it " 750 << endreq; 751 // ignore SPA 1 component of CSS/CSL chambers in R02.03 (it is there only for AMDB convenience, 752 // leaving the CSC envelop => global position of the station unchanged) 753 continue; 754 } 755 756 htcomponent = HepTranslateX3D(ypos)*HepTranslateZ3D(zpos); 757 xfcomponent = new GeoTransform(htcomponent); 758 std::string key = stName+techname; 759 if ((m_manager->IncludeCutoutsFlag()|| 760 (m_manager->IncludeCutoutsBogFlag()&&stName.substr(0,3) == "BOG")) && zi >= 0) 761 key += "p"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 762 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 763 else if ((m_manager->IncludeCutoutsFlag() || 764 (m_manager->IncludeCutoutsBogFlag()&&stName.substr(0,3)=="BOG")) && zi < 0) 765 key += "m"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 766 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 767 FPVMAP* savemem = FPVMAP::GetPointer(); 768 GeoVPhysVol *fpv = savemem->GetDetector(key); 769 if (fpv == 0) { 770 Spacer* r = new Spacer(c); 771 // log << MSG::DEBUG << " Building a SPA for station " 772 // << key << " component name is " << c->name << endreq; 773 if (m_manager->IncludeCutoutsFlag()|| 774 (m_manager->IncludeCutoutsBogFlag()&&stName.substr(0,3)=="BOG")) 775 { 776 lv = r->build(1); 777 } else { 778 lv = r->build(); 779 } 780 // log << MSG::DEBUG << " Storing in FPVMAP with key " << key << endreq; 781 savemem->StoreDetector(lv, key); 782 delete r; 783 r = 0; 784 } 785 else lv = fpv; 786 787 } else if ((type=="CHV" || type=="CRO" || type=="CMI" || 788 type=="LB0" || type == "LBI") && m_manager->MinimalGeoFlag() == 0) { 789 SpacerBeam* r = new SpacerBeam(c); 790 BeamHeight = r->height; 791 ypos = c->posx; 792 double zpos1 = c->posy - length/2. + c->dy/2.; 793 if (geometry_version.substr(0,1) == "P") zpos = zpos1; 794 double xpos = (c->posz+amdbOrigine_along_thickness) - thickness/2. + BeamHeight/2.; 795 double angle = 0.; 796 if (fabs(c->excent) > 0.001) { 797 angle = atan((longWidth-width)/length/2.); 798 if (c->excent <0.) angle = -angle; 799 } 800 801 // This is an attempt to provide some info to LB construction in order 802 // to avoid the clash of LB with CXx in the endcaps ... 803 if (type == "LB0") { 804 if (stName == "EML1" || stName == "EML6") { 805 if ((c->dx1 > width) && zpos < 0.) { 806 r->width = 0.98*width; 807 } 808 if ((c->dx1/longWidth) > 0.98 && zpos > 0.) { 809 double mywidth = 0.93*longWidth; 810 r->width = mywidth; 811 } 812 } 813 } 814 // 815 if (type == "CMI" || type == "CHV" || type == "CRO") { 816 // Shorten CHV, CMI lengths to fit in BOL4 envelope 817 if (stname == "BOL" && zi == 1 && (fi+1) == 3) { 818 r->length = length - halfpitch; 819 zpos = -halfpitch/2.; 820 } 821 } 822 // 823 if (!is_mirrored) { 824 htcomponent = HepTranslate3D(xpos,ypos,zpos)*HepRotateX3D(angle); 825 } else { 826 htcomponent = HepTranslate3D(xpos,-ypos,zpos)*HepRotateX3D(-angle); 827 } 828 xfcomponent = new GeoTransform(htcomponent); 829 std::string key = stName+techname; 830 if ((m_manager->IncludeCutoutsFlag() || 831 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 832 && zi >= 0) 833 key += "p" + buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 834 "_" + buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 835 else if ((m_manager->IncludeCutoutsFlag() || 836 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 837 && zi < 0) 838 key += "m" + buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 839 "_" + buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 840 841 // can have LB of different length in same station: 842 if (type.substr(0,2) == "LB") key += buildString(int(c->dx1),0); 843 844 // log << MSG::DEBUG << " Building a SpacerBeam for station " 845 // << key << " component name is " 846 // << c->name << endreq; 847 FPVMAP* savemem = FPVMAP::GetPointer(); 848 GeoVPhysVol* fpv = savemem->GetDetector(key); 849 if (fpv == 0 || (stName.substr(0,3) == "BOG" && type == "CMI")) { 850 if (stName.substr(0,3)=="BOG") 851 if (m_verbose) log << MSG::VERBOSE << " Building a SpacerBeam for station " 852 << key << " component name is " << c->name << endreq; 853 if (m_manager->IncludeCutoutsFlag() || 854 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 855 { 856 lvo = r->build(1, is_barrel); 857 } else { 858 lvo = r->build(is_barrel); 859 } 860 // log << MSG::DEBUG << "LB: " << r->name << " height is " << 861 // r->height << " length is " << r->length << " width is " 862 // << r->width << endreq; 863 // log << MSG::DEBUG << " Storing in FPVMAP with key " << key << endreq; 864 savemem->StoreDetector(lvo, key); 865 // AMDB origin is in bottom centre of bottom cross-piece at 866 // end of bar. 867 // From centre, it is -height/2 in x, 0 in y, -length/2 in z 868 869 } else { 870 if (stName.substr(0,3)=="BOG") 871 if (m_verbose) log << MSG::VERBOSE << " This spacerbeam for station " 872 << key << " component name is " 873 << c->name << " already exists; re-use it " << endreq; 874 lvo = fpv; 875 } 876 delete r; 877 r = 0; 878 879 } else if (type == "RPC") { 880 // position stuff needed for cutout, used to be below: 881 RpcComponent* rp = (RpcComponent*)c; 882 int ndivy = rp->ndivy; 883 int ndivz = rp->ndivz; 884 // double rwidth = width/ndivy; 885 // double rlength = length/ndivz; 886 // if (geometry_version == "M28") { 887 // double zposi = -(ndivz-1)*rlength/2.; 888 // for (int j = 0; j < ndivz; j++) { 889 // double yposi = (ndivy-1)*rwidth/2.; 890 // for (int i = 0; i < ndivy; i++) { 891 // htcomponent = HepTranslateX3D(ypos )*HepTranslateY3D(yposi)* 892 // HepTranslateZ3D(zposi); 893 // xfcomponent = new GeoTransform(htcomponent); 894 // //xfrpccomponent.push_back(xfcomponent); 895 // yposi -= rwidth; 896 // } 897 // zposi += rlength; 898 // } 899 // } else 900 // { 901 if (ndivz != 1 || ndivy != 1) log << MSG::ERROR << " RPC segmentation z,y " 902 << ndivz << " " << ndivy << std::endl; 903 double xpos = c->posx; 904 double zpos1 = -length/2. + c->posy+c->dy/2.; 905 if (geometry_version.substr(0,1) == "P") zpos = zpos1; // Preserve layout P03 906 // implement really the mirror symmetry 907 if (is_mirrored) xpos = -xpos; 908 909 if (m_verbose) log << MSG::VERBOSE << " In station " << stName 910 << " with " << nDoubletR << " doubletR," 911 << " RPC " << (c->name).substr(3,2) 912 << " has swap flag = " << rp->iswap 913 << " ypos, zpos " 914 << ypos << " " << zpos << " " << endreq; 915 916 htcomponent = HepTranslateX3D(ypos)* 917 HepTranslateY3D(xpos)*HepTranslateZ3D(zpos); 918 if (rp->iswap == -1) // this is like amdb iswap 919 { 920 htcomponent = htcomponent*HepRotateY3D(180*deg); 921 } 922 xfaligncomponent = new GeoAlignableTransform(htcomponent); 923 //xfrpccomponent.push_back(xfcomponent); 924 // } 925 926 // end of position stuff 927 928 bool rpcCutoutFlag = (stname == "BOS" && std::abs(zi) == 6) || 929 (stname == "BMS" && (std::abs(zi) == 2 || std::abs(zi) == 4 || std::abs(zi) == 6) ) || 930 (stname == "BMS" && std::abs(zi) == 1 && fi == 3); 931 std::string key=stName+techname; 932 if (((m_manager->IncludeCutoutsFlag() && rpcCutoutFlag) || 933 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 934 && zi >= 0) { 935 key += "p"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 936 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0) + 937 "_"+buildString(vcutdef.size(),0) + 938 "_"+buildString(rp->iswap,0); 939 } else if (((m_manager->IncludeCutoutsFlag() && rpcCutoutFlag) || 940 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 941 && zi < 0) { 942 key += "m"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 943 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0) + 944 "_"+buildString(vcutdef.size(),0) + 945 "_"+buildString(rp->iswap,0); 946 } 947 FPVMAP* savemem = FPVMAP::GetPointer(); 948 GeoVPhysVol* fpv = savemem->GetDetector(key); 949 if (fpv == 0) { 950 Rpc* r = new Rpc(c); 951 r->setLogVolName(stName+techname); 952 // log << MSG::DEBUG << " Building a RPC for station " 953 // << key << " component name is " 954 // << c->name << endreq; 955 if ((m_manager->IncludeCutoutsFlag() && rpcCutoutFlag) || 956 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 957 { 958 lvr = r->build(m_manager->MinimalGeoFlag(), 1, vcutdef); 959 } else { 960 lvr = r->build(m_manager->MinimalGeoFlag()); 961 } 962 // log<<MSG::DEBUG<<" Storing in FPVMAP with key "<<key<<endreq; 963 savemem->StoreDetector(lvr, key); 964 delete r; 965 r = 0; 966 967 } else { 968 GeoFullPhysVol* rfpv = (GeoFullPhysVol*)fpv; 969 //log<<MSG::DEBUG<<" This RPC for station "<<key 970 // <<" component name is " 971 // <<c->name<<" already exists; clone it "<<endreq; 972 lvr = rfpv->clone(); 973 } 974 975 } else if (type=="DED" && m_manager->MinimalGeoFlag() == 0) { 976 double xpos = c->posx; 977 if (is_mirrored) xpos = -xpos; 978 double zpos1 = -length/2.+c->posy+c->dy/2.; 979 if (geometry_version.substr(0,1) == "P") zpos = zpos1; // Preserve layout P03 980 htcomponent = HepTranslateX3D(ypos)*HepTranslateY3D(xpos)*HepTranslateZ3D(zpos); 981 if (stname == "BMS" && (zi == -2 || zi == -4) && c->name == "DED03") 982 htcomponent = htcomponent*HepRotateY3D(180*deg); 983 xfcomponent = new GeoTransform(htcomponent); 984 985 bool dedCutoutFlag = (stname == "BOS" && std::abs(zi) == 6) || 986 (stname == "BMS" && (std::abs(zi) == 2 || std::abs(zi) == 4 || std::abs(zi) == 6) ) || 987 (stname == "BMS" && std::abs(zi) == 1 && fi == 3); 988 std::string key=stName+techname; 989 if (((m_manager->IncludeCutoutsFlag() && dedCutoutFlag) || 990 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) && zi>=0) { 991 key += "p"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 992 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0) + 993 "_"+buildString(vcutdef.size(),0); 994 } 995 else if (((m_manager->IncludeCutoutsFlag() && dedCutoutFlag) || 996 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) && zi<0) { 997 key += "m"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0)+ 998 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0)+ 999 "_"+buildString(vcutdef.size(),0); 1000 } 1001 key += buildString(int(c->dy),0) + "_" + buildString(int(c->dx1),0); 1002 FPVMAP* savemem = FPVMAP::GetPointer(); 1003 GeoVPhysVol* fpv = savemem->GetDetector(key); 1004 1005 if (fpv == 0) { 1006 Ded* r = new Ded(c); 1007 // log<<MSG::DEBUG<<" Building a DED for station "<<key 1008 // <<" component name is " <<c->name<<endreq; 1009 if ((m_manager->IncludeCutoutsFlag() && dedCutoutFlag) || 1010 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3) == "BOG")) 1011 { 1012 lvd = r->build(1, vcutdef); 1013 } else { 1014 lvd = r->build(); 1015 } 1016 // log<<MSG::DEBUG<<" Storing in FPVMAP with key " 1017 // <<key<<endreq; 1018 savemem->StoreDetector(lvd, key); 1019 delete r; 1020 r = 0; 1021 1022 } else { 1023 lvd = fpv; 1024 } 1025 1026 } else if (type=="SUP" && m_manager->MinimalGeoFlag() == 0) { 1027 ypos = -thickness/2. + c->posz; 1028 SupComponent* csup = (SupComponent*)c; 1029 double zpos = -length/2. + c->posy+c->dy/2. - csup->zAMDB0(); 1030 ypos = ypos - csup->xAMDB0(); 1031 double xpos = c->posx - csup->yAMDB0(); 1032 // log<<MSG::DEBUG 1033 // <<" show AMDB origin with respect to phys vol centre: " 1034 // <<csup->xAMDB0()<<" " 1035 // <<csup->yAMDB0()<<" " 1036 // <<csup->zAMDB0()<<endreq; 1037 // log<<MSG::DEBUG<<" z transform done"<<endreq; 1038 // log<<MSG::DEBUG<<" ypos = "<<ypos<<endreq; 1039 // log<<MSG::DEBUG<<" y transform done"<<endreq; 1040 // log<<MSG::DEBUG<<" x transform done"<<endreq; 1041 // log<<MSG::DEBUG<<" its centre x-translated by "<<ypos; 1042 // log<<" y-translated by "<<xpos; 1043 // log<<" z-translated by "<<zpos<<endreq; 1044 htcomponent = HepTranslateX3D(ypos)*HepTranslateY3D(xpos)* 1045 HepTranslateZ3D(zpos); 1046 std::string key = stName+techname; 1047 if ((m_manager->IncludeCutoutsFlag() || 1048 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3)=="BOG")) 1049 && zi >= 0) 1050 key += "p"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 1051 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 1052 else if ((m_manager->IncludeCutoutsFlag()|| 1053 (m_manager->IncludeCutoutsBogFlag() && stName.substr(0,3)=="BOG")) 1054 && zi < 0) 1055 key += "m"+buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 1056 "_"+buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 1057 FPVMAP* savemem = FPVMAP::GetPointer(); 1058 GeoVPhysVol* fpv = savemem->GetDetector(key); 1059 if (fpv == 0) { 1060 // log<<MSG::DEBUG<<" definig ypos, from thickness & c->posz = " 1061 // <<-thickness/2.<<" "<<c->posz<<endreq; 1062 // Sup *r=new Sup(c); 1063 // lvs=r->build(); 1064 // log<<MSG::DEBUG<<" a pointer to a sup " <<lvs 1065 // <<" is now available in the station "<<endreq; 1066 // log<<MSG::DEBUG<<" Storing in FPVMAP with key "<<key<<endreq; 1067 savemem->StoreDetector(lvs, key); 1068 } else { 1069 lvs = fpv; 1070 } 1071 1072 } else if (type == "TGC") { 1073 TgcComponent* tg = (TgcComponent*)station->GetComponent(i); 1074 TgcComponent* tgInner = (TgcComponent*)station->GetComponent(0); 1075 irad = tgInner->posy; 1076 TgcComponent* tgOuter = 1077 (TgcComponent*)station->GetComponent(station->GetNrOfComponents()-1); 1078 double orad = tgOuter->posy + tgOuter->dy; 1079 double start = -(orad-irad)/2. + (tg->posy-irad) + tg->dy/2; 1080 double xstart = -thickness/2. + tg->GetThickness()/2.; 1081 htcomponent = HepTranslateX3D(xstart + tg->posz)*HepTranslateZ3D(start); 1082 xfaligncomponent = new GeoAlignableTransform(htcomponent); 1083 1084 // Define key for this TGC component 1085 std::string key = stName + techname; 1086 if (m_manager->IncludeCutoutsFlag()) { 1087 if (mysql->allocPosFindCutout(statType, fi, zi) > 0) { 1088 // If there is a cutout for this chamber, give it a special key 1089 if (zi >= 0) 1090 key += "p" + buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 1091 "_" + buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 1092 else if (zi < 0) 1093 key += "m" + buildString(mysql->allocPosFindSubtype(statType, fi, zi),0) + 1094 "_" + buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 1095 } 1096 } 1097 char chswidth[32]; 1098 sprintf(chswidth,"%i",int(10*c->dx1)); 1099 key += chswidth; 1100 1101 FPVMAP* savemem = FPVMAP::GetPointer(); 1102 GeoVPhysVol* fpv = savemem->GetDetector(key); 1103 if (fpv == 0) { 1104 Tgc* t = new Tgc(c); 1105 t->setLogVolName(stName+techname); 1106 if (m_manager->IncludeCutoutsFlag()) { 1107 lvt = t->build(m_manager->MinimalGeoFlag(), 1, vcutdef); 1108 } else { 1109 lvt = t->build(m_manager->MinimalGeoFlag()); 1110 } 1111 savemem->StoreDetector(lvt, key); 1112 delete t; 1113 t = 0; 1114 } else { 1115 GeoFullPhysVol* rfpv = (GeoFullPhysVol*)fpv; 1116 lvt = rfpv->clone(); 1117 } 1118 1119 } else if (type=="CSC") { 1120 htcomponent = HepTranslateX3D(ypos)*HepTranslateZ3D(zpos); 1121 xfaligncomponent = new GeoAlignableTransform(htcomponent); 1122 // Here define the key for this CSC component 1123 std::string key = stName+techname; 1124 if (m_manager->IncludeCutoutsFlag() 1125 && zi >= 0) 1126 key += "p" + buildString(mysql->allocPosFindSubtype(statType, fi, zi),0)+ 1127 "_" + buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 1128 else if (m_manager->IncludeCutoutsFlag() 1129 && zi < 0) 1130 key += "m" + buildString(mysql->allocPosFindSubtype(statType, fi, zi),0)+ 1131 "_" + buildString(mysql->allocPosFindCutout(statType, fi, zi),0); 1132 FPVMAP* savemem = FPVMAP::GetPointer(); 1133 1134 GeoVPhysVol* fpv = savemem->GetDetector(key); 1135 if (fpv == 0) { 1136 Csc* t = new Csc(c); 1137 t->setLogVolName(stName+techname); 1138 // log<<MSG::DEBUG<<" Building a CSC for station " 1139 // <<key<<" component name is "<<c->name<<endreq; 1140 if (m_manager->IncludeCutoutsFlag() ) { 1141 lvc = t->build(m_manager->MinimalGeoFlag(), 1, vcutdef); 1142 } else { 1143 lvc = t->build(m_manager->MinimalGeoFlag()); 1144 } 1145 // log<<MSG::DEBUG<<" Storing in FPVMAP with key "<<key<<endreq; 1146 savemem->StoreDetector(lvc, key); 1147 delete t; 1148 t = 0; 1149 } else { 1150 GeoFullPhysVol* rfpv = (GeoFullPhysVol*)fpv; 1151 // log<<MSG::DEBUG<<" This CSC for station "<<key 1152 // <<" component name is " 1153 // <<c->name<<" already exists; clone it "<<endreq; 1154 lvc = rfpv->clone(); 1155 } 1156 1157 } else { 1158 if (type != "MDT" && type != "RPC" && type != "TGC" && type != "SUP" 1159 && type != "DED" && type != "SPA" && type != "CHV" 1160 && type != "CRO" && type != "CMI" && type != "LB0" 1161 && type != "LBI") log << MSG::INFO << "Unknown component " 1162 << type << endreq; 1163 } 1164 1165 // Place components in chamber envelope 1166 if (lvm) { 1167 int stationEta = zi; 1168 int stationPhi = fi+1; 1169 int ml = 1; 1170 int tubel = 1; 1171 int tube = 1; 1172 if (ypos > 0.) ml = 2; 1173 std::string stag = "ml["+MuonGM::buildString(ml,0)+"]"+techname+"component"; 1174 GeoNameTag* nm = new GeoNameTag(stag); 1175 ptrd->add(new GeoIdentifierTag(c->index)); 1176 ptrd->add(nm); 1177 /* 1178 std::cout << " MDT position " << 1179 (xfcomponent->getTransform())[0][0] << " " << 1180 (xfcomponent->getTransform())[0][1] << " " << 1181 (xfcomponent->getTransform())[0][2] << " " << 1182 (xfcomponent->getTransform())[0][3] << " " << std::endl << 1183 (xfcomponent->getTransform())[1][0] << " " << 1184 (xfcomponent->getTransform())[1][1] << " " << 1185 (xfcomponent->getTransform())[1][2] << " " << 1186 (xfcomponent->getTransform())[1][3] << " " << std::endl << 1187 (xfcomponent->getTransform())[2][0] << " " << 1188 (xfcomponent->getTransform())[2][1] << " " << 1189 (xfcomponent->getTransform())[2][2] << " " << 1190 (xfcomponent->getTransform())[2][3] << " " << std::endl; 1191 */ 1192 xfaligncomponent->setDelta(HepTransform3D::Identity); 1193 //delete xfcomponent; 1194 ptrd->add(xfaligncomponent); 1195 ptrd->add(lvm); 1196 const MdtIdHelper* mdt_id = m_manager->mdtIdHelper(); 1197 MdtReadoutElement* det = new MdtReadoutElement(lvm, stName, zi, fi+1, 1198 is_mirrored, m_manager); 1199 Position ip = mysql->GetStationPosition(stName.substr(0,3),fi,zi); 1200 setMdtReadoutGeom(det, (MdtComponent*)c, ip); 1201 det->setHasCutouts(ncutouts > 0); 1202 det->setNofREinStation(nMdt, nRpc, nTgc, nCsc); 1203 det->setStationEta(stationEta); 1204 det->setStationPhi(stationPhi); 1205 det->setMultilayer(ml); 1206 det->setParentStationPV(PVConstLink(ptrd)); 1207 det->setParentMuonStation(mstat); 1208 int jobIndex = c->index; 1209 mstat->addMuonReadoutElement(det,jobIndex); 1210 if (m_debug) log << MSG::DEBUG << std::string(stName+techname) 1211 << " trying to build a MDT Id from stType/eta/phi/ml/tl/t " 1212 << stationType << "/" << stationEta << "/" 1213 << stationPhi << "/" << ml << "/" << tubel << "/" 1214 << tube << "\n Copy number is " << c->index 1215 << " tagName " << stag << endreq; 1216 Identifier id = mdt_id->channelID(stationType, stationEta, 1217 stationPhi, ml, tubel, tube); 1218 det->setIdentifier(id); 1219 det->setLastInitField(5); 1220 //========================= 1221 // A little debug section 1222 1223 // std::cout << "ID = " << mdt_id->show_to_string(id) << std::endl; 1224 // std::cout << " Mdtreadoutelement normal = " << std::endl; 1225 // HepVector3D dumv=det->normal(); 1226 // std::cout << "(" << dumv.x() << ", " << dumv.y() << ", " << dumv.z() 1227 // << ")" << std::endl; 1228 // std::cout << " Mdtreadoutelement transform = " << std::endl; 1229 // HepTransform3D dummy=det->transform(id); 1230 // std::cout << dummy[0][0] << " " << dummy[0][1] << " " 1231 // << dummy[0][2] << " " << dummy[0][3] << std::endl 1232 // << dummy[1][0] << " " << dummy[1][1] << " " 1233 // << dummy[1][2] << " " << dummy[1][3] << std::endl 1234 // << dummy[2][0] << " " << dummy[2][1] << " " 1235 // << dummy[2][2] << " " << dummy[2][3] << std::endl; 1236 //========================= 1237 m_manager->addMdtReadoutElement(det, id); 1238 } 1239 1240 if (lvc) { 1241 CscComponent* cs = (CscComponent*)station->GetComponent(i); 1242 int stationEta = zi; 1243 int stationPhi = fi+1; 1244 int chamberLayer = 1; 1245 if (ypos > 0.) chamberLayer = 2; 1246 std::string stag = "cl["+MuonGM::buildString(chamberLayer,0)+"]"+techname+"component"; 1247 GeoNameTag *nm = new GeoNameTag(stag); 1248 ptrd->add(new GeoIdentifierTag(c->index)); 1249 ptrd->add(nm); 1250 /* 1251 std::cout << " CSC position " << 1252 (xfcomponent->getTransform())[0][0] << " " << 1253 (xfcomponent->getTransform())[0][1] << " " << 1254 (xfcomponent->getTransform())[0][2] << " " << 1255 (xfcomponent->getTransform())[0][3] << " " << std::endl << 1256 (xfcomponent->getTransform())[1][0] << " " << 1257 (xfcomponent->getTransform())[1][1] << " " << 1258 (xfcomponent->getTransform())[1][2] << " " << 1259 (xfcomponent->getTransform())[1][3] << " " << std::endl << 1260 (xfcomponent->getTransform())[2][0] << " " << 1261 (xfcomponent->getTransform())[2][1] << " " << 1262 (xfcomponent->getTransform())[2][2] << " " << 1263 (xfcomponent->getTransform())[2][3] << " " << std::endl; 1264 */ 1265 xfaligncomponent->setDelta(HepTransform3D::Identity); 1266 //delete xfcomponent; 1267 ptrd->add(xfaligncomponent); 1268 ptrd->add(lvc); 1269 1270 CscReadoutElement* det = 1271 new CscReadoutElement(lvc, stName, zi, fi+1, is_mirrored, m_manager); 1272 Position ip = mysql->GetStationPosition(stName.substr(0,3),fi,zi); 1273 setCscReadoutGeom(det, cs, ip, geometry_version, stName); 1274 1275 const CscIdHelper* csc_id = m_manager->cscIdHelper(); 1276 det->setHasCutouts(ncutouts > 0); 1277 det->setNofREinStation(nMdt, nRpc, nTgc, nCsc); 1278 det->setStationEta(stationEta); 1279 det->setStationPhi(stationPhi); 1280 det->setChamberLayer(chamberLayer); 1281 det->setParentStationPV(PVConstLink(ptrd)); 1282 det->setParentMuonStation(mstat); 1283 int jobIndex = c->index; 1284 mstat->addMuonReadoutElement(det,jobIndex); 1285 if (m_debug) log<<MSG::DEBUG<<std::string(stName+techname) 1286 <<" trying to build a CSC Id from stType/eta/phi/ml " 1287 <<stationType<<"/" 1288 <<stationEta<<"/" 1289 <<stationPhi<<"/" 1290 <<chamberLayer<<"/ and /1/0/1 \n Copy number is "<<c->index<<" tagName " 1291 <<stag<<endreq; 1292 Identifier id = csc_id->channelID(stationType, 1293 stationEta, 1294 stationPhi, 1295 chamberLayer, 1296 1, 0, 1); 1297 det->setIdentifier(id); 1298 det->setLastInitField(5); 1299 m_manager->addCscReadoutElement(det, id); 1300 } 1301 1302 if (lvt) { 1303 if (m_debug) log << MSG::DEBUG 1304 << " Adding a TGC chamber to the tree zi,fi, is_mirrored " 1305 << zi << " " << fi+1 << " " << is_mirrored << endreq; 1306 1307 TgcComponent* tg = (TgcComponent*)station->GetComponent(i); 1308 if (m_verbose) log << MSG::VERBOSE << "There's a TGC named " << techname 1309 << " of thickness " << tg->GetThickness() << endreq; 1310 1311 const TgcIdHelper* tgc_id = m_manager->tgcIdHelper(); 1312 int stationEta = 0; 1313 stationEta = tg->index; 1314 if (zi<0) stationEta = -stationEta; 1315 int nch = 0; 1316 int fioff = 0; 1317 int stationPhi = 0; 1318 if (geometry_version.substr(0,1) == "P" || geometry_version.substr(0,3) == "CTB") 1319 { 1320 nch = 3; 1321 if ( (stName).substr(2,1) == "E" && 1322 (stName).substr(1,1) != "4" ) nch = 6; 1323 fioff = abs(zi); 1324 if (fioff>3 && (stName).substr(2,1) == "F") fioff = fioff-3; 1325 stationPhi = fi*nch + fioff; 1326 } else 1327 { 1328 stationPhi = MuonGM::stationPhiTGC(stName,fi+1,zi, geometry_version); 1329 } 1330 int ttag = 1000*stationPhi+tg->index; 1331 std::string stag = "stPhiJob["+MuonGM::buildString(ttag,0) 1332 +"]"+techname+"tgccomponent"; 1333 GeoNameTag* nm = new GeoNameTag(stag); 1334 int geoid = 0; 1335 if (useAssemblies || isAssembly) { 1336 geoid = c->index; 1337 } else { 1338 if (zi < 0) ttag = -ttag; 1339 geoid = ttag; 1340 } 1341 ptrd->add(new GeoIdentifierTag(geoid)); 1342 ptrd->add(nm); 1343 xfaligncomponent->setDelta(HepTransform3D::Identity); 1344 //delete xfcomponent; 1345 ptrd->add(xfaligncomponent); 1346 ptrd->add(lvt); 1347 1348 TgcReadoutElement* det = new TgcReadoutElement(lvt, stName, zi, fi+1, 1349 is_mirrored, m_manager); 1350 Position ip = mysql->GetStationPosition(stName.substr(0,3),fi,zi); 1351 setTgcReadoutGeom(det, tg, ip, geometry_version, stName); 1352 det->setHasCutouts(ncutouts>0); 1353 det->setNofREinStation(nMdt, nRpc, nTgc, nCsc); 1354 det->setStationEta(stationEta); 1355 det->setStationPhi(stationPhi); 1356 det->setParentStationPV(PVConstLink(ptrd)); 1357 det->setParentMuonStation(mstat); 1358 int jobIndex = c->index; 1359 mstat->addMuonReadoutElement(det,jobIndex); 1360 if (m_debug) log<<MSG::DEBUG<<std::string(stName+techname) 1361 <<" trying to build a TGC Id from stType/eta/phi " 1362 <<stationType<<"/" 1363 <<stationEta<<"/" 1364 <<stationPhi<<"/ and /1/0/1 \n Copy number is "<<geoid<<" tagName = "<<stag<<endreq; 1365 int gg = 1; 1366 int isStrip = 0; 1367 int ch = 1; 1368 Identifier id = tgc_id->channelID(stationType, stationEta, 1369 stationPhi, gg, isStrip, ch); 1370 det->setIdentifier(id); 1371 det->setLastInitField(4); 1372 m_manager->addTgcReadoutElement(det, id); 1373 } 1374 1375 if (lvr && RPCON){ 1376 RpcComponent* rp = (RpcComponent*)c; 1377 int ndivy = rp->ndivy; 1378 int ndivz = rp->ndivz; 1379 // if (geometry_version == "M28") 1380 // { 1381 // GeoSerialDenominator* nm = 1382 // new GeoSerialDenominator(stName + "_stName "+techname+" rpccomponent "); 1383 // for (int j = 0; j < ndivz; j++) { 1384 // for (int i = 0; i < ndivy; i++) { 1385 // xfcomponent = xfrpccomponent[i+j*ndivy]; 1386 // ptrd->add(nm); 1387 // ptrd->add(xfcomponent); 1388 // ptrd->add(lvr); 1389 // } 1390 // } 1391 1392 // } 1393 // else 1394 // { 1395 if (ndivz!=1 || ndivy!=1 ) log << MSG::ERROR << " RPC segmentation z,y " 1396 << ndivz << " " << ndivy <<std::endl; 1397 double zpos = -length/2. + c->posy+c->dy/2.; 1398 double xpos = c->posx; 1399 // implement really the mirror symmetry 1400 if (is_mirrored) xpos = -xpos; 1401 1402 // ... putting back to here! 1403 // log<<MSG::DEBUG<<" In station "<<stName<<" with " 1404 // <<nDoubletR<<" doubletR," 1405 // <<" RPC "<<(c->name).substr(3,2) 1406 // <<" has swap flag = "<<rp->iswap 1407 // <<" ypos, yd, zpos, zd " 1408 // <<ypos<<" "<<yd<<" "<<zpos<<" "<<zd<<endreq; 1409 // htcomponent = HepTranslateX3D(ypos)*HepTranslateY3D(xpos) 1410 // *HepTranslateZ3D(zpos); 1411 // xfcomponent = new GeoTransform(htcomponent); 1412 1413 const RpcIdHelper* rpc_id = m_manager->rpcIdHelper(); 1414 int stationEta = zi; 1415 int stationPhi = fi+1; 1416 int doubletR = 1; 1417 int nfields = 6; 1418 int doubletZ = 0; 1419 1420 if (nRpc > 1 && nDoubletR == 2 && ypos>0.) doubletR=2; 1421 ndbz[doubletR-1]++; 1422 1423 if (zi <= 0 && !is_mirrored) { 1424 // the special cases 1425 doubletZ = 1; 1426 if (zpos<-100.*mm) doubletZ=2; 1427 if (fabs(xpos) > 100.*mm && ndbz[doubletR-1] > 2) { 1428 doubletZ = 3; 1429 nfields++; 1430 } 1431 if (fabs(xpos) > 100.*mm ) ndbz[doubletR-1]--; 1432 1433 } else { 1434 doubletZ = 1; 1435 if (zpos > 100.*mm) doubletZ=2; 1436 if (fabs(xpos) > 100.*mm && ndbz[doubletR-1] > 2) { 1437 doubletZ = 3; 1438 nfields++; 1439 } 1440 if (fabs(xpos) > 100.*mm ) ndbz[doubletR-1]--; 1441 } 1442 1443 int dbphi = 1; 1444 if (xpos > 100.*mm) dbphi = 2; 1445 // doublet phi not aware of pos. in space !!! 1446 1447 int doubletPhi = dbphi; 1448 // doublet phi aware of pos. in space !!! 1449 if (zi < 0 && is_mirrored && doubletZ == 3) { 1450 doubletPhi++; 1451 if (doubletPhi > 2) doubletPhi = 1; 1452 } else if (zi < 0 && is_mirrored && doubletZ == 2 && 1453 doubletR == 1 && stName == "BMS6") { 1454 doubletPhi++; 1455 if (doubletPhi>2) doubletPhi=1; 1456 } 1457 1458 // never defined fields: set to the lower limit 1459 int gasGap = 1; 1460 int measuresPhi = 0; 1461 int strip = 1; 1462 1463 //int tag = rp->index + doubletR*100 + dbphi*1000; 1464 int geoid = 0; 1465 std::string stag; 1466 int tag = doubletZ + doubletR*100 + dbphi*1000; 1467 if (rp->iswap == -1) tag = -1*tag; 1468 stag = "SwapdbPdbRdbZ["+MuonGM::buildString(tag,0) 1469 +"]"+techname+"rpccomponent"; 1470 if (useAssemblies || isAssembly) { 1471 geoid = c->index; 1472 } 1473 else 1474 { 1475 int tag = rp->index + doubletR*100 + dbphi*1000; 1476 if (rp->iswap == -1) tag=-1*tag; 1477 geoid = tag; 1478 } 1479 1480 GeoNameTag* nm = new GeoNameTag(stag); 1481 ptrd->add(new GeoIdentifierTag( geoid )); 1482 ptrd->add(nm); 1483 /* 1484 std::cout << " RPC position " << std::endl << 1485 (xfcomponent->getTransform())[0][0] << " " << 1486 (xfcomponent->getTransform())[0][1] << " " << 1487 (xfcomponent->getTransform())[0][2] << " " << 1488 (xfcomponent->getTransform())[0][3] << " " << std::endl << 1489 (xfcomponent->getTransform())[1][0] << " " << 1490 (xfcomponent->getTransform())[1][1] << " " << 1491 (xfcomponent->getTransform())[1][2] << " " << 1492 (xfcomponent->getTransform())[1][3] << " " << std::endl << 1493 (xfcomponent->getTransform())[2][0] << " " << 1494 (xfcomponent->getTransform())[2][1] << " " << 1495 (xfcomponent->getTransform())[2][2] << " " << 1496 (xfcomponent->getTransform())[2][3] << " " << std::endl; 1497 */ 1498 xfaligncomponent->setDelta(HepTransform3D::Identity); 1499 //delete xfcomponent; 1500 ptrd->add(xfaligncomponent); 1501 ptrd->add(lvr); 1502 1503 RpcReadoutElement* det = new RpcReadoutElement(lvr, stName, zi, fi+1, 1504 is_mirrored, m_manager); 1505 Position ip = mysql->GetStationPosition(stName.substr(0,3),fi,zi); 1506 setRpcReadoutGeom(det, rp, ip, geometry_version, m_manager); 1507 det->setHasCutouts(ncutouts > 0); 1508 det->setNofREinStation(nMdt, nRpc, nTgc, nCsc); 1509 det->setStationEta(stationEta); 1510 det->setStationPhi(stationPhi); 1511 det->setDoubletR(doubletR); 1512 det->setDoubletZ(doubletZ); 1513 det->setDoubletPhi(doubletPhi); 1514 if (m_debug) log << MSG::DEBUG << std::string(stName+techname) 1515 << " trying to build a RPC Id from stType/eta/phi/dbR/dbZ/dbP " 1516 << stationType << "/" 1517 << stationEta << "/" << stationPhi << "/" << doubletR << "/" 1518 << doubletZ << "/" << doubletPhi 1519 << "///" << gasGap << "/" << measuresPhi << "/" << strip << "\n Copy number " 1520 << geoid << " tagName= " << stag << endreq; 1521 1522 det->setParentStationPV(PVConstLink(ptrd)); 1523 det->setParentMuonStation(mstat); 1524 int jobIndex = c->index; 1525 mstat->addMuonReadoutElement(det,jobIndex); 1526 Identifier id = rpc_id->channelID(stationType, stationEta, 1527 stationPhi, doubletR, doubletZ, 1528 doubletPhi, gasGap, measuresPhi, 1529 strip); 1530 det->setIdentifier(id); 1531 det->setLastInitField(nfields); 1532 //========================= 1533 // A little debug section 1534 1535 // std::cout << "ID = " << rpc_id->show_to_string(id) << std::endl; 1536 // HepPoint3D dummy=det->gasGapPos(id); 1537 // std::cout << " Rpcreadoutelement gas gap pos = " 1538 // << dummy.x() << " " << dummy.y() << " " 1539 // << dummy.z() << std::endl; 1540 // dummy=det->stripPos(id); 1541 // std::cout << " Rpcreadoutelement strip pos = " 1542 // << dummy.x() << " " << dummy.y() << " " 1543 // << dummy.z() << std::endl; 1544 //========================= 1545 m_manager->addRpcReadoutElement(det, id); 1546 // } 1547 } 1548 1549 if (lvs && RPCON) { 1550 SupComponent* csup = (SupComponent*)c; 1551 std::string cname = csup->name; 1552 if (m_verbose) log << MSG::VERBOSE 1553 << " yes, the component is a SupComponent named " 1554 << cname << endreq; 1555 GeoNameTag* nm = new GeoNameTag(stName + "_stName "+techname+" supcomponent"); 1556 ptrd->add(new GeoIdentifierTag(c->index)); 1557 ptrd->add(nm); 1558 ptrd->add(xfcomponent); 1559 if (m_verbose) { 1560 log << MSG::VERBOSE << " register x" << endreq; 1561 log << MSG::VERBOSE << " register y" << endreq; 1562 log << MSG::VERBOSE << " register z" << endreq; 1563 } 1564 ptrd->add(lvs); 1565 if (m_verbose) log << MSG::VERBOSE << " register lvs" << endreq; 1566 } 1567 1568 if (lvd && RPCON) { 1569 GeoNameTag* nm = new GeoNameTag(stName + "_stName "+techname+" dedcomponent"); 1570 ptrd->add(new GeoIdentifierTag(c->index)); 1571 ptrd->add(nm); 1572 /* 1573 std::cout << " DED position " << 1574 (xfcomponent->getTransform())[0][0] << " " << 1575 (xfcomponent->getTransform())[0][1] << " " << 1576 (xfcomponent->getTransform())[0][2] << " " << 1577 (xfcomponent->getTransform())[0][3] << " " << std::endl << 1578 (xfcomponent->getTransform())[1][0] << " " << 1579 (xfcomponent->getTransform())[1][1] << " " << 1580 (xfcomponent->getTransform())[1][2] << " " << 1581 (xfcomponent->getTransform())[1][3] << " " << std::endl << 1582 (xfcomponent->getTransform())[2][0] << " " << 1583 (xfcomponent->getTransform())[2][1] << " " << 1584 (xfcomponent->getTransform())[2][2] << " " << 1585 (xfcomponent->getTransform())[2][3] << " " << std::endl; 1586 */ 1587 ptrd->add(xfcomponent); 1588 ptrd->add(lvd); 1589 } 1590 1591 if (lvo) { 1592 // translate from AMDB chamber coordinates: 1593 // (move chamber origin and swap axes around) 1594 // D-line gives AMDB coords of AMDB component origin 1595 // we need MuonGM coords of MuonGM component origin... 1596 // take off length/2, thickness/2 to get to AMDB chamber org 1597 // then put back GetLength()/2, GetThickness()/2 to get to 1598 // component org. 1599 GeoNameTag* nm = new GeoNameTag(stName + "_stName "+techname+" component"); 1600 ptrd->add(new GeoIdentifierTag(c->index)); 1601 ptrd->add(nm); 1602 /* 1603 std::cout << techname << " position in " << stName << std::endl << 1604 (xfcomponent->getTransform())[0][0] << " " << 1605 (xfcomponent->getTransform())[0][1] << " " << 1606 (xfcomponent->getTransform())[0][2] << " " << 1607 (xfcomponent->getTransform())[0][3] << " " << std::endl << 1608 (xfcomponent->getTransform())[1][0] << " " << 1609 (xfcomponent->getTransform())[1][1] << " " << 1610 (xfcomponent->getTransform())[1][2] << " " << 1611 (xfcomponent->getTransform())[1][3] << " " << std::endl << 1612 (xfcomponent->getTransform())[2][0] << " " << 1613 (xfcomponent->getTransform())[2][1] << " " << 1614 (xfcomponent->getTransform())[2][2] << " " << 1615 (xfcomponent->getTransform())[2][3] << " " << std::endl; 1616 */ 1617 ptrd->add(xfcomponent); 1618 ptrd->add(lvo); 1619 } 1620 1621 if (lv) { 1622 GeoNameTag *nm = new GeoNameTag(stName + "_stName "+techname+" component"); 1623 ptrd->add(new GeoIdentifierTag(c->index)); 1624 ptrd->add(nm); 1625 ptrd->add(xfcomponent); 1626 ptrd->add(lv); 1627 } 1628 1629 for (size_t i = 0 ; i < vcutdef_todel.size(); i++) delete vcutdef_todel[i]; 1630 1631 } // End big loop over components 1632 return ptrd; 1633 } 1634 1635 1636 void MuonChamber::setCscReadoutGeom(CscReadoutElement* re, const CscComponent* cc, 1637 const Position& ip, std::string gVersion, 1638 std::string stName) 1639 { 1640 re->m_Ssize = cc->dx1; 1641 re->m_LongSsize = cc->dx2; 1642 re->m_Rsize = cc->dy; 1643 re->m_LongRsize = cc->dy; 1644 re->m_Zsize = cc->GetThickness(); 1645 re->m_LongZsize = cc->GetThickness(); 1646 re->m_RlengthUpToMaxWidth = cc->maxwdy; 1647 re->m_excent = cc->excent; 1648 1649 // Csc features specific to this readout element 1650 std::string tname = cc->name; 1651 re->setTechnologyName(tname); 1652 1653 if (ip.isAssigned) { 1654 re->setStationS(ip.shift); 1655 } else { 1656 std::cerr << " MuonChamber::setCscReadoutGeom: position not found " << std::endl; 1657 assert(0); 1658 } 1659 1660 MYSQL* mysql = MYSQL::GetPointer(); 1661 CSC* thisc = (CSC*)mysql->GetTechnology(tname); 1662 re->m_anodecathode_distance = thisc->anocathodist; 1663 re->m_ngasgaps = thisc->numOfLayers; 1664 re->m_nstriplayers = thisc->numOfLayers; 1665 re->m_nwirelayers = thisc->numOfLayers; 1666 re->m_roxacellwidth = thisc->roxacellwith; 1667 re->m_nEtastripsperlayer = thisc->nEtastrips; 1668 re->m_nPhistripsperlayer = thisc->nPhistrips; 1669 re->m_Etastrippitch = thisc->cathreadoutpitch; 1670 re->m_Phistrippitch = thisc->phireadoutpitch; 1671 re->m_Etastripwidth = re->m_Etastrippitch ; 1672 re->m_Phistripwidth = re->m_Phistrippitch ; 1673 1674 if (gVersion.substr(0,3) == "P03") { 1675 if (stName.substr(0,3) == "CSS") re->m_nPhistripsperlayer = 28; 1676 else re->m_nPhistripsperlayer = 44; 1677 } 1678 1679 } 1680 1681 1682 void MuonChamber::setMdtReadoutGeom(MdtReadoutElement* re, const MdtComponent* cc, 1683 const Position& ip) 1684 { 1685 re->m_Ssize = cc->dx1; 1686 re->m_LongSsize = cc->dx2; 1687 1688 if (re->m_inBarrel) { 1689 re->m_Rsize = cc->GetThickness(); 1690 re->m_LongRsize = cc->GetThickness(); 1691 re->m_Zsize = cc->dy; 1692 re->m_LongZsize = cc->dy; 1693 } else { 1694 re->m_Rsize = cc->dy; 1695 re->m_LongRsize = cc->dy; 1696 re->m_Zsize = cc->GetThickness(); 1697 re->m_LongZsize = cc->GetThickness(); 1698 } 1699 1700 re->m_cutoutShift = cc->cutoutTubeXShift; 1701 re->m_tubelenStepSize = cc->tubelenStepSize; 1702 1703 if (ip.isAssigned) { 1704 re->setStationS(ip.shift); 1705 } else { 1706 std::cerr << " MuonChamber::setMdtReadoutGeom: position not found " << std::endl; 1707 assert(0); 1708 } 1709 1710 std::string tname = cc->name; 1711 re->setTechnologyName(tname); 1712 MYSQL* mysql = MYSQL::GetPointer(); 1713 MDT* thism = (MDT*)mysql->GetTechnology(tname); 1714 re->m_nlayers = thism->numOfLayers; 1715 re->m_tubepitch = thism->pitch; 1716 re->m_tubelayerpitch = thism->y[1]-thism->y[0]; 1717 re->m_endpluglength = thism->tubeEndPlugLength; 1718 re->m_deadlength = cc->deadx; //thism->tubeDeadLength; 1719 1720 if (re->m_inBarrel) { 1721 re->m_ntubesperlayer = int(re->m_Zsize/re->m_tubepitch); 1722 re->m_nsteps = 1; // all tubes have the same length 1723 re->m_ntubesinastep = re->m_ntubesperlayer; 1724 re->m_tubelength[0] = re->m_Ssize; 1725 } else { 1726 re->m_ntubesperlayer = int(re->m_Rsize/re->m_tubepitch); 1727 re->m_nsteps = int(re->m_Rsize/re->m_tubelenStepSize); 1728 re->m_ntubesinastep = int(re->m_tubelenStepSize/re->m_tubepitch); 1729 re->m_tubelength[0] = re->m_Ssize; 1730 double diff = (re->m_LongSsize - re->m_Ssize) * 1731 (re->m_LongRsize - re->m_tubepitch/2.)/re->m_LongRsize; 1732 for (int is = 0; is < re->m_nsteps; ++is) { 1733 double len = re->m_Ssize + is*diff/re->m_nsteps; 1734 re->m_tubelength[is] = len; 1735 } 1736 } 1737 1738 for (int tl = 0; tl < re->m_nlayers; ++tl) { 1739 re->m_firstwire_x[tl] = thism->x[tl]; 1740 re->m_firstwire_y[tl] = thism->y[tl]; 1741 } 1742 1743 } 1744 1745 1746 void MuonChamber::setRpcReadoutGeom(RpcReadoutElement* re, const RpcComponent* cc, 1747 const Position& ip, std::string gVersion, 1748 MuonDetectorManager* m_manager) 1749 { 1750 re->m_Ssize = cc->dx1; 1751 re->m_LongSsize = cc->dx2; 1752 re->m_Rsize = cc->GetThickness(); 1753 re->m_LongRsize = cc->GetThickness(); 1754 re->m_Zsize = cc->dy; 1755 re->m_LongZsize = cc->dy; 1756 1757 re->m_hasDEDontop = true; 1758 if (cc->iswap == -1) re->m_hasDEDontop = false; 1759 1760 if (ip.isAssigned) { 1761 re->setStationS(ip.shift); 1762 } else { 1763 std::cerr << " MuonChamber::setRpcReadoutGeom: position not found " << std::endl; 1764 assert(0); 1765 } 1766 1767 std::string tname = cc->name; 1768 re->setTechnologyName(tname); 1769 MYSQL* mysql = MYSQL::GetPointer(); 1770 RPC* thisr = (RPC*)mysql->GetTechnology(tname); 1771 re->m_nphigasgaps = thisr->NGasGaps_in_s; 1772 re->m_netagasgaps = thisr->NGasGaps_in_z; 1773 re->m_gasgapssize = re->m_Ssize/re->m_nphigasgaps - 2.*thisr->bakeliteframesize; 1774 re->m_gasgapzsize = re->m_Zsize/re->m_netagasgaps - 2.*thisr->bakeliteframesize; 1775 re->m_nphistrippanels = thisr->NstripPanels_in_s; 1776 re->m_netastrippanels = thisr->NstripPanels_in_z; 1777 re->m_phistrippitch = thisr->stripPitchS; 1778 re->m_etastrippitch = thisr->stripPitchZ; 1779 re->m_exthonthick = thisr->externalSupPanelThickness; 1780 1781 const GenericRPCCache* rc = m_manager->getGenericRpcDescriptor(); 1782 re->m_phistripwidth = re->m_phistrippitch - rc->stripSeparation; 1783 re->m_etastripwidth = re->m_etastrippitch - rc->stripSeparation; 1784 re->m_nphistripsperpanel = int((re->m_Ssize/re->m_nphistrippanels)/re->m_phistrippitch); 1785 1786 while ((re->m_nphistripsperpanel%8) != 0) {re->m_nphistripsperpanel--;} 1787 re->m_netastripsperpanel = int((re->m_Zsize/re->m_netastrippanels)/re->m_etastrippitch); 1788 while ((re->m_netastripsperpanel%8) != 0) {re->m_netastripsperpanel--;} 1789 1790 re->m_phipaneldead = re->m_Ssize/re->m_nphistrippanels 1791 - re->m_nphistripsperpanel*re->m_phistrippitch 1792 + rc->stripSeparation; 1793 re->m_phipaneldead = re->m_phipaneldead/2.; 1794 re->m_etapaneldead = re->m_Zsize/re->m_netastrippanels 1795 - re->m_netastripsperpanel*re->m_etastrippitch 1796 + rc->stripSeparation; 1797 re->m_etapaneldead = re->m_etapaneldead/2.; 1798 re->m_phistriplength = re->m_LongZsize/re->m_netastrippanels; 1799 re->m_etastriplength = re->m_LongSsize/re->m_nphistrippanels; 1800 1801 // first strip position on each phi panel 1802 for (int is = 0; is < re->m_nphistrippanels; ++is) re->first_phistrip_s[is] = -999999.; 1803 re->first_phistrip_s[0] = -re->m_Ssize/2. + re->m_phipaneldead + re->m_phistripwidth/2.; 1804 if (re->m_nphistrippanels == 2) 1805 re->first_phistrip_s[1] = re->m_phipaneldead + re->m_phistripwidth/2.; 1806 1807 double offset = 0.; 1808 if (gVersion.substr(0,3) == "P03") offset = rc->frontendBoardWidth; 1809 1810 for (int is = 0; is < re->m_netastrippanels; ++is) re->phistrip_z[is] = -999999.; 1811 re->phistrip_z[0] = -re->m_Zsize/2. + offset + re->m_phistriplength/2.; 1812 if (re->m_netastrippanels == 2) re->phistrip_z[1] = re->m_Zsize/2. - offset - re->m_phistriplength/2.; 1813 1814 // first strip position on each eta panel 1815 for (int is = 0; is < re->m_netastrippanels; ++is) re->first_etastrip_z[is] = -999999.; 1816 re->first_etastrip_z[0] = -re->m_Zsize/2. + re->m_etapaneldead + re->m_etastripwidth/2.; 1817 if (re->m_netastrippanels == 2) 1818 re->first_etastrip_z[1] = re->m_etapaneldead + re->m_etastripwidth/2.; 1819 1820 for (int is = 0; is < re->m_nphistrippanels; ++is) re->etastrip_s[is] = -999999.; 1821 re->etastrip_s[0] = -re->m_Ssize/2. + offset + re->m_etastriplength/2.; 1822 if (re->m_nphistrippanels == 2) re->etastrip_s[1] = re->m_Ssize/2. - offset - re->m_etastriplength/2.; 1823 1824 } 1825 1826 1827 void 1828 MuonChamber::setTgcReadoutGeom(TgcReadoutElement* re, const TgcComponent* cc, 1829 const Position& ip, std::string gVersion, 1830 std::string stName) 1831 { 1832 re->m_Ssize = cc->dx1; 1833 re->m_LongSsize = cc->dx2; 1834 re->m_Rsize = cc->dy; 1835 re->m_LongRsize = cc->dy; 1836 re->m_Zsize = cc->GetThickness(); 1837 re->m_LongZsize = cc->GetThickness(); 1838 1839 std::string tname = cc->name; 1840 int tname_index = MuonGM::strtoint(tname,3,2); 1841 re->setTechnologyName(tname); 1842 1843 if (ip.isAssigned) { 1844 re->setStationS(ip.shift); 1845 } else { 1846 std::cerr <<" MuonChamber::setTgcReadoutGeom position not found " << std::endl; 1847 assert(0); 1848 } 1849 1850 MYSQL* mysql = MYSQL::GetPointer(); 1851 if (gVersion.substr(0,1) == "P" || gVersion.substr(0,3) == "CTB") 1852 { 1853 char index[2]; 1854 sprintf(index,"%i", cc->index); 1855 re->m_readout_name = stName.substr(0,3) + index; 1856 re->m_readoutParams = mysql->GetTgcRPars(re->m_readout_name); 1857 } else { 1858 char index[2]; 1859 sprintf(index,"%i", cc->index); 1860 //std::cout<<" cc->index = <"<<cc->index<<">"<<std::endl; 1861 re->m_readout_name = stName.substr(0,4) + "_" + index; 1862 re->m_readoutParams = mysql->GetTgcRPars(tname_index); 1863 } 1864 1865 if (re->m_readoutParams == 0) 1866 std::cout << " MuonChamber::setTgcReadoutGeometry: no readoutParams found for key <" 1867 << re->m_readout_name << ">" << std::endl; 1868 else { 1869 re->m_readout_type = re->m_readoutParams->chamberType(); 1870 } 1871 1872 TGC* thist = (TGC*)(mysql->GetTechnology(tname)); 1873 const std::size_t ncomp = (thist->materials).size(); 1874 std::string::size_type npos; 1875 for (std::size_t i = 0; i < ncomp; ++i) { 1876 double newpos = -re->m_Zsize/2. + thist->positions[i] + thist->tck[i]/2.; 1877 const std::string& matname = thist->materials[i]; 1878 if ((npos = matname.find("TGCGas")) != std::string::npos ) 1879 {//here is a gasgap 1880 int Nstripplanes = 0; 1881 int Nwireplanes = 0; 1882 re->m_ngasgaps++; 1883 re->m_nwireplanes++; 1884 Nwireplanes = re->m_nwireplanes; 1885 re->m_nstripplanes++; 1886 Nstripplanes = re->m_nstripplanes; 1887 re->m_nstrips_per_plane[Nstripplanes-1] = 0; 1888 re->m_nwires_per_plane[Nwireplanes-1] = 0; 1889 re->m_nwiregangs_per_plane[Nwireplanes-1] = 0; 1890 re->m_strippitch[Nstripplanes-1] = 0.; 1891 re->m_stripwidth[Nstripplanes-1] = 0.; 1892 re->m_wirepitch[Nwireplanes-1] = re->m_readoutParams->wirePitch();