00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include <iostream>
00012 using namespace std;
00013 #include <TGeoPgon.h>
00014 #include <TGeoTube.h>
00015 #include <TGeoArb8.h>
00016 #include <TGeoXtru.h>
00017 #include <TGeoManager.h>
00018 #include <TGeoMatrix.h>
00019 #include <TGeoShape.h>
00020
00021 #include "GeoGeometry/GeoSteelPlnVolume.h"
00022 #include "GeoGeometry/GeoGeometry.h"
00023 #include "GeoGeometry/GeoMediumMap.h"
00024 #include "GeoGeometry/GeoMedium.h"
00025 #include "Plex/PlexPlaneId.h"
00026 #include "MessageService/MsgService.h"
00027
00028 ClassImp(GeoSteelPlnVolume)
00029 CVSID("$Id: GeoSteelPlnVolume.cxx,v 1.20 2008/01/09 06:38:11 schubert Exp $");
00030
00031
00032 GeoSteelPlnVolume::GeoSteelPlnVolume() : GeoVolume(),
00033 fDetector(Detector::kUnknown), fThick(0) {
00034
00035
00036 }
00037
00038
00039 GeoSteelPlnVolume::GeoSteelPlnVolume(GeoGeometry* geo,const PlexPlaneId& plnid,
00040 Float_t plnthick) :
00041 GeoVolume(geo,
00042 (GeoGeometry::GetGeoCompatibleName(plnid.AsString())).c_str(),
00043 geo->GetMediumMap().GetMedium(Geo::kPlnSteel)),
00044 fDetector(plnid.GetDetector()),fThick(plnthick) {
00045
00046
00047
00048 UpdateGlobalManager();
00049
00050 fShpName = string(GetName());
00051
00052
00053
00054
00055
00056
00057
00058 TGeoShape* shape = GetExistingShape();
00059 if (!shape) shape = BuildPlaneShape();
00060
00061 SetShape(shape);
00062
00063
00064
00065 gGeoManager -> GetListOfGVolumes() -> Remove(this);
00066 Int_t index = gGeoManager->GetListOfVolumes() -> GetEntriesFast();
00067 gGeoManager -> GetListOfVolumes()
00068 -> AddAtAndExpand(this,index);
00069
00070
00071 AddCoilNode();
00072
00073 }
00074
00075
00076 void GeoSteelPlnVolume::Print(Option_t* ) const {
00077
00078
00079 UpdateGlobalManager();
00080
00081 cout << "GeoSteelPlnVolume::Print\n"
00082 << GetName() << endl;
00083 cout << "Det " << Detector::AsString(fDetector) << endl;
00084 cout << " Thick " << fThick << endl;
00085
00086 }
00087
00088
00089 TGeoShape* GeoSteelPlnVolume::BuildPlaneShape() const {
00090
00091
00092 UpdateGlobalManager();
00093
00094 TGeoShape* shape = 0;
00095
00096 switch ( fDetector ) {
00097
00098 case Detector::kFar:
00099
00100 shape = BuildFar();
00101 break;
00102
00103 case Detector::kNear:
00104
00105 shape = BuildNear();
00106 break;
00107
00108 case Detector::kCalDet:
00109
00110 shape = BuildCalDet();
00111 break;
00112
00113 default:
00114
00115 MSG("Geo",Msg::kError)<< "Steel Pln shape construction for detector type\n"
00116 << Detector::AsString(fDetector)
00117 << " not yet supported." << endl;
00118
00119 }
00120
00121 return shape;
00122
00123 }
00124
00125
00126 TGeoShape* GeoSteelPlnVolume::BuildFar() const {
00127
00128
00129 UpdateGlobalManager();
00130
00131 return BuildFarSteelXtru();
00132
00133 }
00134
00135
00136 TGeoShape* GeoSteelPlnVolume::BuildNear() const {
00137
00138
00139 UpdateGlobalManager();
00140
00141 return BuildNearSteelXtru();
00142
00143 }
00144
00145
00146 TGeoShape* GeoSteelPlnVolume::BuildCalDet() const {
00147
00148
00149 UpdateGlobalManager();
00150
00151 return BuildCalDetSteelBasic();
00152
00153 }
00154
00155
00156 TGeoShape* GeoSteelPlnVolume::BuildFarSteelPgon() const {
00157
00158
00159 UpdateGlobalManager();
00160
00161 Double_t scale = GetScale();
00162
00163
00164 TGeoPgon* shape = new TGeoPgon(fShpName.c_str(),22.5,360.,8,2);
00165
00166 Double_t halfz = 0.5*fThick;
00167 Double_t r_inscribed = scale*(0.5*Geo::kFarSteelWidth);
00168
00169 shape -> DefineSection(0,-halfz,0.,r_inscribed);
00170 shape -> DefineSection(1,+halfz,0.,r_inscribed);
00171
00172 MSG("Geo",Msg::kDebug)
00173 << "Build far detector steel plane shape as simple octagon w/halfthick "
00174 << halfz << "." << endl;
00175
00176 return shape;
00177
00178 }
00179
00180
00181
00182 TGeoShape* GeoSteelPlnVolume::BuildFarSteelXtru() const {
00183
00184
00185
00186
00187 UpdateGlobalManager();
00188
00189 Double_t scale = GetScale();
00190
00191
00192 std::string xtruname = fShpName;
00193 TGeoXtru* shape = new TGeoXtru(2);
00194 shape -> SetName(xtruname.c_str());
00195
00196 const int nv = 32;
00197 Double_t x[nv] = {0};
00198 Double_t y[nv] = {0};
00199
00200 x[31] = 421.8893*Munits::cm; y[31] = -142.8876*Munits::cm;
00201 x[30] = 421.8893*Munits::cm; y[30] = -138.3342*Munits::cm;
00202 x[29] = 400.1614*Munits::cm; y[29] = -115.9855*Munits::cm;
00203 x[28] = 400.7823*Munits::cm; y[28] = 87.6358*Munits::cm;
00204 x[27] = 406.9902*Munits::cm; y[27] = 94.0507*Munits::cm;
00205 x[26] = 429.1319*Munits::cm; y[26] = 101.5003*Munits::cm;
00206 x[25] = 447.1350*Munits::cm; y[25] = 101.5003*Munits::cm;
00207 x[24] = 454.7915*Munits::cm; y[24] = 94.2577*Munits::cm;
00208 x[23] = 457.6886*Munits::cm; y[23] = 94.2577*Munits::cm;
00209 x[22] = 457.6886*Munits::cm; y[22] = 109.3637*Munits::cm;
00210 x[21] = 143.7724*Munits::cm; y[21] = 423.2799*Munits::cm;
00211 x[20] = 139.4268*Munits::cm; y[20] = 423.2799*Munits::cm;
00212 x[19] = 117.2850*Munits::cm; y[19] = 401.1382*Munits::cm;
00213 x[18] =-116.9622*Munits::cm; y[18] = 401.1382*Munits::cm;
00214 x[17] =-139.1040*Munits::cm; y[17] = 423.2799*Munits::cm;
00215 x[16] =-143.4496*Munits::cm; y[16] = 423.2799*Munits::cm;
00216 x[15] =-457.3658*Munits::cm; y[15] = 109.3637*Munits::cm;
00217 x[14] =-457.3658*Munits::cm; y[14] = 94.2577*Munits::cm;
00218 x[13] =-454.4687*Munits::cm; y[13] = 94.2577*Munits::cm;
00219 x[12] =-439.9834*Munits::cm; y[12] = 101.9141*Munits::cm;
00220 x[11] =-429.8438*Munits::cm; y[11] = 101.9141*Munits::cm;
00221 x[10] =-406.6674*Munits::cm; y[10] = 94.2577*Munits::cm;
00222 x[9] =-399.8386*Munits::cm; y[9] = 84.7388*Munits::cm;
00223 x[8] =-399.8386*Munits::cm; y[8] =-115.9855*Munits::cm;
00224 x[7] =-421.5665*Munits::cm; y[7] =-137.7134*Munits::cm;
00225 x[6] =-421.5665*Munits::cm; y[6] =-142.8867*Munits::cm;
00226 x[5] =-143.4496*Munits::cm; y[5] =-421.0036*Munits::cm;
00227 x[4] =-139.1040*Munits::cm; y[4] =-421.0036*Munits::cm;
00228 x[3] =-116.9622*Munits::cm; y[3] =-398.8619*Munits::cm;
00229 x[2] = 116.8712*Munits::cm; y[2] =-398.8619*Munits::cm;
00230 x[1] = 139.4268*Munits::cm; y[1] =-421.0036*Munits::cm;
00231 x[0] = 143.7724*Munits::cm; y[0] =-421.0036*Munits::cm;
00232
00233 for ( int iv = 0; iv < nv; iv++ ) {
00234 x[iv] *= scale;
00235 y[iv] *= scale;
00236 }
00237
00238 shape -> DefinePolygon(32,x,y);
00239
00240
00241 Double_t halfz = fThick/2.;
00242 shape -> DefineSection(0,-halfz);
00243 shape -> DefineSection(1,+halfz);
00244
00245 MSG("Geo",Msg::kDebug)
00246 << "Build far detector steel plane shape w/ears using TGeoXtru w/halfthick "
00247 << halfz << "." << endl;
00248
00249 return shape;
00250
00251 }
00252
00253
00254 TGeoShape* GeoSteelPlnVolume::BuildNearSteelXtru() const {
00255
00256
00257
00258
00259 UpdateGlobalManager();
00260
00261 MSG("Geo",Msg::kDebug)
00262 << "Build near detector steel plane shape using TGeoXtru"
00263 << endl;
00264
00265 Double_t scale = GetScale();
00266
00267
00268 std::string xtruname = fShpName;
00269 TGeoXtru* shape = new TGeoXtru(2);
00270 shape -> SetName(xtruname.c_str());
00271
00272 const int nv = 22;
00273 Double_t x[nv] = {0};
00274 Double_t y[nv] = {0};
00275
00276
00277 x[21] = -121.43*Munits::inch; y[21] = 0.47*Munits::inch;
00278 x[20] = -120.25*Munits::inch; y[20] = 0.47*Munits::inch;
00279 x[19] = -115.14*Munits::inch; y[19] = 3.42*Munits::inch;
00280 x[18] = -110.24*Munits::inch; y[18] = 3.42*Munits::inch;
00281 x[17] = -95.24*Munits::inch; y[17] = -1.48*Munits::inch;
00282 x[16] = -95.24*Munits::inch; y[16] =-35.47*Munits::inch;
00283 x[15] = -69.80*Munits::inch; y[15] =-60.91*Munits::inch;
00284 x[14] = -69.80*Munits::inch; y[14] =-75.04*Munits::inch;
00285 x[13] = 69.80*Munits::inch; y[13] =-75.04*Munits::inch;
00286 x[12] = 69.80*Munits::inch; y[12] =-60.91*Munits::inch;
00287 x[11] = 95.24*Munits::inch; y[11] = -35.47*Munits::inch;
00288 x[10] = 95.24*Munits::inch; y[10] = -1.48*Munits::inch;
00289 x[9] = 110.16*Munits::inch; y[9] = 3.42*Munits::inch;
00290 x[8] = 117.30*Munits::inch; y[8] = 3.42*Munits::inch;
00291 x[7] = 120.25*Munits::inch; y[7] = 0.47*Munits::inch;
00292 x[6] = 121.43*Munits::inch; y[6] = 0.47*Munits::inch;
00293 x[5] = 121.43*Munits::inch; y[5] = 9.28*Munits::inch;
00294 x[4] = 69.80*Munits::inch; y[4] = 60.91*Munits::inch;
00295 x[3] = 69.80*Munits::inch; y[3] = 75.04*Munits::inch;
00296 x[2] = -69.80*Munits::inch; y[2] = 75.04*Munits::inch;
00297 x[1] = -69.80*Munits::inch; y[1] = 60.91*Munits::inch;
00298 x[0] =-121.43*Munits::inch; y[0] = 9.28*Munits::inch;
00299
00300 Float_t xnearoffset = scale*Geo::kNearXOffset;
00301 for ( int iv = 0; iv < nv; iv++ ) {
00302 x[iv] = x[iv]*scale - xnearoffset;
00303 y[iv] = y[iv]*scale;
00304 }
00305
00306 shape -> DefinePolygon(22,x,y);
00307
00308
00309 Double_t halfz = fThick/2.;
00310 shape -> DefineSection(0,-halfz);
00311 shape -> DefineSection(1,+halfz);
00312
00313 MSG("Geo",Msg::kDebug)
00314 << "Build near detector steel plane shape using TGeoXtru w/halfthick "
00315 << halfz << endl;
00316
00317 return shape;
00318
00319 }
00320
00321
00322 TGeoShape* GeoSteelPlnVolume::BuildCalDetSteelBasic() const {
00323
00324
00325
00326
00327 UpdateGlobalManager();
00328
00329 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00330
00331
00332 Double_t halfwidth = scale*0.5*Geo::kCalDetSteelWidth;
00333 Double_t halfz = fThick/2.;
00334 MSG("Geo",Msg::kDebug)
00335 << "Build cal detector steel plane shape using TGeoBBox w/halfthick "
00336 << halfz << " and halfwidth " << halfwidth << endl;
00337
00338 TGeoBBox* shape = new TGeoBBox(fShpName.c_str(),halfwidth,halfwidth,
00339 halfz);
00340
00341 return shape;
00342
00343 }
00344
00345 void GeoSteelPlnVolume::AddCoilNode() {
00346
00347
00348 UpdateGlobalManager();
00349
00350 switch ( fDetector ) {
00351
00352 case Detector::kFar:
00353 {
00354 TGeoVolume* volCoil = BuildFarCoilVolume();
00355 this -> AddNode(volCoil,1,gGeoIdentity);
00356 }
00357 break;
00358
00359 case Detector::kNear:
00360 {
00361 TGeoVolume* volCoil = BuildNearCoilVolume();
00362 TGeoRotation* rot45 = fGeoGeometry->GetRot45();
00363 this -> AddNode(volCoil,1,rot45);
00364 }
00365 break;
00366
00367 default:
00368
00369 break;
00370
00371 }
00372
00373 return;
00374
00375 }
00376
00377
00378 TGeoVolume* GeoSteelPlnVolume::BuildFarCoilVolume() const {
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 UpdateGlobalManager();
00402
00403 const GeoMediumMap& medMap = fGeoGeometry -> GetMediumMap();
00404
00405
00406 TGeoVolume* volDetail = gGeoManager->GetVolume("FPDE");
00407 if ( volDetail ) return volDetail;
00408
00409 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00410
00411
00412
00413 TGeoVolume* volCoil
00414 = gGeoManager->MakeTube("FPCO",medMap.GetMedium(Geo::kCRStlCoil),
00415 0,Geo::kCoilRad*scale,-1.);
00416 volCoil -> SetLineColor(42);
00417
00418 TGeoVolume* volThroat = gGeoManager->MakeTube("FPTR",
00419 medMap.GetMedium(Geo::kCRStlThroat),
00420 0,Geo::kThroatRad*scale,-1.);
00421 volThroat -> SetLineColor(kBlue);
00422
00423 TGeoVolume* volNeck = gGeoManager->MakeTube("FPNK",
00424 medMap.GetMedium(Geo::kCRStlNeck),
00425 0,Geo::kNeckRad*scale,-1.);
00426 volNeck -> SetLineColor(46);
00427
00428 TGeoVolume* volHole
00429 = gGeoManager->MakeTube("FPHO",medMap.GetMedium(Geo::kCRStlHole),
00430 0,Geo::kFeHoleRad*scale,-1.);
00431 volHole -> SetLineColor(kBlue);
00432
00433 volDetail
00434 = gGeoManager->MakeTube("FPDE",medMap.GetMedium(Geo::kCRStlDetail),
00435 0,Geo::kDetailRad*scale,-1.);
00436 volDetail -> SetLineColor(kRed);
00437 volDetail -> SetLineStyle(2);
00438 volDetail -> SetVisibility(kFALSE);
00439
00440 volDetail -> AddNode(volHole ,1,gGeoIdentity);
00441 volHole -> AddNode(volNeck ,1,gGeoIdentity);
00442 volNeck -> AddNode(volThroat,1,gGeoIdentity);
00443 volThroat -> AddNode(volCoil ,1,new TGeoTranslation(0,-0.01*scale,0));
00444
00445 return volDetail;
00446
00447 }
00448
00449
00450 TGeoVolume* GeoSteelPlnVolume::BuildNearCoilVolume() const {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 UpdateGlobalManager();
00477
00478 const GeoMediumMap& medMap = fGeoGeometry -> GetMediumMap();
00479
00480
00481 TGeoVolume* volDetail = gGeoManager->GetVolume("NPDE");
00482 if ( volDetail ) return volDetail;
00483
00484 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00485
00486
00487
00488 TGeoVolume* volWater
00489 = gGeoManager->MakeTube("NPWA",medMap.GetMedium(Geo::kCRStlWater),
00490 0,Geo::kNearCoolRad*scale,-1.);
00491 volWater -> SetLineColor(kGreen);
00492
00493 TGeoVolume* volCoil
00494 = gGeoManager->MakeBox("NPCO",medMap.GetMedium(Geo::kCRStlCoil),
00495 Geo::kCoilRad*scale,Geo::kCoilRad*scale,-1.);
00496 volCoil -> SetLineColor(kBlack);
00497
00498 TGeoVolume* volThroat
00499 = gGeoManager->MakeBox("NPTR",medMap.GetMedium(Geo::kCRStlThroat),
00500 Geo::kThroatRad*scale,Geo::kThroatRad*scale,-1.);
00501 volThroat -> SetLineColor(kBlue);
00502
00503 TGeoVolume* volNeck
00504 = gGeoManager->MakeBox("NPNK",medMap.GetMedium(Geo::kCRStlNeck),
00505 Geo::kNeckRad*scale,Geo::kNeckRad*scale,-1.);
00506 volNeck -> SetLineColor(kBlack);
00507
00508 TGeoVolume* volHole
00509 = gGeoManager->MakeBox("NPHO",medMap.GetMedium(Geo::kCRStlHole),
00510 Geo::kFeHoleRad*scale,Geo::kFeHoleRad*scale,-1.);
00511 volHole -> SetLineColor(kBlue);
00512
00513 volDetail
00514 = gGeoManager->MakeTube("NPDE",medMap.GetMedium(Geo::kCRStlDetail),
00515 0,Geo::kDetailRad*scale,-1.);
00516 volDetail -> SetLineColor(kRed);
00517 volDetail -> SetLineStyle(2);
00518
00519
00520
00521
00522
00523 volDetail -> AddNode(volHole, 1,gGeoIdentity);
00524 volHole -> AddNode(volNeck ,1,gGeoIdentity);
00525 volNeck -> AddNode(volThroat,1,gGeoIdentity);
00526 volThroat -> AddNode(volCoil ,1,
00527 new TGeoTranslation(-0.01*scale,-0.01*scale,0));
00528
00529 Int_t nx = 6;
00530 Int_t ny = 8;
00531
00532 Float_t xedge = 0.02475*scale;
00533 Float_t x0 = -Geo::kCoilRad*scale + xedge;
00534
00535 Float_t xsep = 2.*(Geo::kCoilRad*scale - xedge)/(Float_t)(nx-1);
00536
00537 Float_t yedge = 0.02221*scale;
00538 Float_t y0 = -Geo::kCoilRad*scale + yedge;
00539
00540 Float_t ysep = 2.*(Geo::kCoilRad*scale - yedge)/(Float_t)(ny-1);
00541
00542 for ( int ix = 0; ix < nx; ix++ ) {
00543 Float_t xpos = x0 + (Float_t)ix*xsep;
00544 for ( int iy = 0; iy < ny; iy++ ) {
00545 Float_t ypos = y0 + (Float_t)iy*ysep;
00546 Int_t itube = ix*ny+iy+1;
00547 volCoil -> AddNode(volWater,itube,new TGeoTranslation(xpos,ypos,0));
00548 }
00549 }
00550
00551 return volDetail;
00552
00553 }
00554
00555