00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include <iostream>
00012 using namespace std;
00013 #include <TGeoPgon.h>
00014 #include <TGeoManager.h>
00015 #include <TGeoMatrix.h>
00016 #include <TGeoShape.h>
00017
00018 #include "GeoGeometry/GeoScintPlnVolume.h"
00019 #include "GeoGeometry/GeoScintMdlNode.h"
00020 #include "GeoGeometry/GeoGeometry.h"
00021 #include "GeoGeometry/GeoMediumMap.h"
00022 #include "GeoGeometry/GeoMedium.h"
00023 #include "Plex/PlexPlaneId.h"
00024 #include "MessageService/MsgService.h"
00025
00026 ClassImp(GeoScintPlnVolume)
00027 CVSID("$Id: GeoScintPlnVolume.cxx,v 1.20 2008/01/09 06:38:11 schubert Exp $");
00028
00029
00030 GeoScintPlnVolume::GeoScintPlnVolume() : GeoVolume(),
00031 fDetector(Detector::kUnknown),
00032 fCoverage(PlaneCoverage::kUnknown),fView(PlaneView::kUnknown),
00033 fVetoShield(false), fThick(0) {
00034
00035
00036 }
00037
00038
00039 GeoScintPlnVolume::GeoScintPlnVolume(GeoGeometry* geo,
00040 const PlexPlaneId& plnid,
00041 Float_t plnthick) : GeoVolume(geo,
00042 (GeoGeometry::GetGeoCompatibleName(plnid.AsString())).c_str(),0),
00043 fDetector(plnid.GetDetector()),
00044 fCoverage(plnid.GetPlaneCoverage()),fView(plnid.GetPlaneView()),
00045 fVetoShield(plnid.IsVetoShield()),
00046 fThick(plnthick) {
00047
00048
00049
00050
00051 const GeoMediumMap& medMap = fGeoGeometry->GetMediumMap();
00052 if ( fVetoShield ) SetMedium(medMap.GetMedium(Geo::kVSPlnScint));
00053 else SetMedium(medMap.GetMedium(Geo::kPlnScint));
00054
00055 fShpName = string(GetName());
00056 if ( fVetoShield && fShpName.size() >= 4 ) {
00057 fShpName.erase(0,fShpName.size() - 4);
00058 }
00059 else if ( fShpName.size() >= 3 ) {
00060 fShpName.erase(0,fShpName.size() - 3);
00061 }
00062
00063 TGeoShape* shape = GetExistingShape();
00064 if (!shape) shape = BuildPlaneShape();
00065
00066 SetShape(shape);
00067
00068
00069
00070 gGeoManager -> GetListOfGVolumes() -> Remove(this);
00071 Int_t index = gGeoManager->GetListOfVolumes() -> GetEntriesFast();
00072 gGeoManager -> GetListOfVolumes()
00073 -> AddAtAndExpand(this,index);
00074
00075
00076 AddCoilNode();
00077
00078 }
00079
00080
00081 Int_t GeoScintPlnVolume::NumberOfStrips() const {
00082
00083
00084 UpdateGlobalManager();
00085
00086 Int_t nstrip = 0;
00087 Int_t nmodule = GetNdaughters();
00088 for ( int imdl = 0; imdl < nmodule; imdl++ ) {
00089 GeoScintMdlNode* mdlNode = dynamic_cast<GeoScintMdlNode*>(GetNode(imdl));
00090 if ( mdlNode ) nstrip += mdlNode -> NumberOfStrips();
00091 }
00092
00093 return nstrip;
00094
00095 }
00096
00097
00098 std::vector<GeoStripNode*> GeoScintPlnVolume::GetStripNodePtrVector() const {
00099
00100
00101 UpdateGlobalManager();
00102
00103 std::vector<GeoStripNode*> stpnodes;
00104 Int_t nmodule = GetNdaughters();
00105 for ( int imdl = 0; imdl < nmodule; imdl++ ) {
00106 GeoScintMdlNode* mdlNode = dynamic_cast<GeoScintMdlNode*>(GetNode(imdl));
00107 if ( mdlNode ) {
00108 std::vector<GeoStripNode*> mdlstpnodes=mdlNode->GetStripNodePtrVector();
00109 std::vector<GeoStripNode*>::const_iterator mdlstpitr=mdlstpnodes.begin();
00110 while (mdlstpitr != mdlstpnodes.end()) {
00111 stpnodes.push_back(*mdlstpitr);
00112 mdlstpitr++;
00113 }
00114 }
00115
00116 }
00117
00118 return stpnodes;
00119
00120 }
00121
00122
00123 std::vector<GeoScintMdlNode*> GeoScintPlnVolume::GetScintMdlNodePtrVector()
00124 const {
00125
00126
00127 UpdateGlobalManager();
00128
00129 std::vector<GeoScintMdlNode*> mdlnodes;
00130 Int_t nmodule = GetNdaughters();
00131 for ( int imdl = 0; imdl < nmodule; imdl++ ) {
00132 GeoScintMdlNode* mdlNode = dynamic_cast<GeoScintMdlNode*>(GetNode(imdl));
00133 if ( mdlNode ) mdlnodes.push_back(mdlNode);
00134 }
00135
00136 return mdlnodes;
00137
00138 }
00139
00140
00141 void GeoScintPlnVolume::Print(Option_t* ) const {
00142
00143
00144 UpdateGlobalManager();
00145
00146 cout << "GeoScintPlnVolume::Print\n"
00147 << GetName() << endl;
00148 cout << "Det " << Detector::AsString(fDetector) << " Cover "
00149 << PlaneCoverage::AsString(fCoverage) << " View "
00150 << PlaneView::AsString(fView) << endl;
00151 cout << " Thick " << fThick << endl;
00152
00153 }
00154
00155
00156 TGeoShape* GeoScintPlnVolume::BuildPlaneShape() const {
00157
00158
00159 UpdateGlobalManager();
00160
00161 TGeoShape* shape = 0;
00162
00163 switch ( fDetector ) {
00164
00165 case Detector::kFar:
00166
00167 shape = BuildFar();
00168 break;
00169
00170 case Detector::kNear:
00171
00172 shape = BuildNear();
00173 break;
00174
00175 case Detector::kCalDet:
00176
00177 shape = BuildCalDet();
00178 break;
00179
00180 default:
00181
00182 MSG("Geo",Msg::kError)<< "Scint Pln shape construction for detector type\n"
00183 << Detector::AsString(fDetector)
00184 << " not yet supported." << endl;
00185
00186 }
00187
00188 return shape;
00189
00190 }
00191
00192
00193 TGeoShape* GeoScintPlnVolume::BuildFar() const {
00194
00195
00196 UpdateGlobalManager();
00197
00198 if ( fVetoShield ) {
00199 return BuildFarVetoActive();
00200 }
00201
00202 return BuildFarActive();
00203
00204 }
00205
00206
00207 TGeoShape* GeoScintPlnVolume::BuildCalDet() const {
00208
00209
00210
00211 UpdateGlobalManager();
00212
00213 Double_t scale = GetScale();
00214
00215 Float_t halfx = scale*(0.5*Geo::kCalDetSteelWidth
00216 +Geo::kModuleSkinThick);
00217 Float_t halfy = halfx;
00218 Float_t halfz = 0.5*fThick;
00219
00220 MSG("Geo",Msg::kDebug)
00221 << "Build cal detector scint pln shape " << fShpName.c_str()
00222 << " w/halfthick " << halfz << " and halfwidth " << halfx
00223 << "." << endl;
00224
00225
00226 TGeoBBox* plnShape = new TGeoBBox(fShpName.c_str(),halfx,halfy,halfz);
00227
00228 return plnShape;
00229
00230
00231 }
00232
00233
00234 TGeoShape* GeoScintPlnVolume::BuildFarVetoActive() const {
00235
00236
00237
00238 UpdateGlobalManager();
00239
00240 MSG("Geo",Msg::kDebug)
00241 << "Build far detector veto active plane shape " << endl;
00242
00243 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00244
00245 Float_t halfx = scale*(0.5*Geo::kFarSteelWidth+Geo::kModuleSkinThick);
00246 Float_t halfy = scale*(0.5*20.*Geo::kStripWidth+Geo::kModuleSkinThick);
00247 Float_t halfz = 0.5*fThick;
00248
00249
00250 TGeoBBox* plnShape = new TGeoBBox(fShpName.c_str(),halfx,halfy,halfz);
00251
00252 return plnShape;
00253
00254
00255 }
00256
00257
00258 TGeoShape* GeoScintPlnVolume::BuildFarActive() const {
00259
00260
00261
00262
00263 UpdateGlobalManager();
00264
00265 MSG("Geo",Msg::kDebug)
00266 << "Build far detector active plane shape " << endl;
00267
00268 Double_t scale = GetScale();
00269
00270
00271
00272
00273 Double_t r_inscribed = scale*(0.5*Geo::kFarSteelWidth*1.02
00274 +Geo::kModuleSkinThick);
00275 Double_t r_coil = 0.;
00276
00277
00278 TGeoPgon* plnShape = new TGeoPgon(fShpName.c_str(),22.5,360.,8,2);
00279
00280 plnShape -> DefineSection(0,-0.5*fThick,r_coil,r_inscribed);
00281 plnShape -> DefineSection(1,+0.5*fThick,r_coil,r_inscribed);
00282
00283 return plnShape;
00284
00285 }
00286
00287
00288 TGeoShape* GeoScintPlnVolume::BuildNear() const {
00289
00290
00291 UpdateGlobalManager();
00292
00293 switch ( fCoverage ) {
00294 case ( PlaneCoverage::kNearFull ) :
00295 return BuildNearFullActive();
00296 case ( PlaneCoverage::kNearPartial ) :
00297 return BuildNearPartialActive();
00298 default:
00299 MSG("Geo",Msg::kWarning)
00300 << "Unable to construct near active plane w/ coverage "
00301 << PlaneCoverage::AsString(fCoverage) << endl;
00302 }
00303
00304 return 0;
00305
00306 }
00307
00308
00309 TGeoShape* GeoScintPlnVolume::BuildNearPartialActive() const {
00310
00311
00312
00313 UpdateGlobalManager();
00314
00315 MSG("Geo",Msg::kDebug) <<
00316 "Build near detector partial active plane shape " << endl;
00317
00318 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00319
00320
00321 Float_t halfz = 0.5*fThick;
00322 Double_t r_coil = 0.;
00323
00324
00325
00326 Double_t r_inscribed = 2.9*scale;
00327 TGeoPgon* plnShape = new TGeoPgon(fShpName.c_str(),22.5,360.,8,2);
00328 plnShape -> DefineSection(0,-halfz, r_coil, r_inscribed);
00329 plnShape -> DefineSection(1,+halfz, r_coil, r_inscribed);
00330
00331 return plnShape;
00332
00333 }
00334
00335
00336 TGeoShape* GeoScintPlnVolume::BuildNearFullActive() const {
00337
00338
00339
00340 UpdateGlobalManager();
00341
00342 MSG("Geo",Msg::kDebug) <<
00343 "Build near detector full active plane shape " << endl;
00344
00345 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00346
00347
00348 Float_t halfz = 0.5*fThick;
00349 Double_t r_coil = 0.;
00350
00351
00352
00353
00354
00355
00356 Double_t r_inscribed = 2.91*scale;
00357
00358 TGeoPgon* plnShape = new TGeoPgon(fShpName.c_str(),22.5,360.,8,2);
00359 plnShape -> DefineSection(0,-halfz, r_coil, r_inscribed);
00360 plnShape -> DefineSection(1,+halfz, r_coil, r_inscribed);
00361
00362 return plnShape;
00363
00364 }
00365
00366
00367 void GeoScintPlnVolume::AddCoilNode() {
00368
00369
00370 UpdateGlobalManager();
00371
00372 switch ( fDetector ) {
00373
00374 case Detector::kFar:
00375 {
00376 if ( !fVetoShield ) {
00377 TGeoVolume* volCoil = BuildFarCoilVolume();
00378 if ( fView == PlaneView::kU ) {
00379 TGeoRotation* rot45 = fGeoGeometry->GetRot45();
00380 this -> AddNode(volCoil,1,rot45);
00381 }
00382 else {
00383 TGeoRotation* rot315 = fGeoGeometry->GetRot315();
00384 this -> AddNode(volCoil,1,rot315);
00385 }
00386 }
00387 }
00388 break;
00389
00390 case Detector::kNear:
00391 {
00392 TGeoVolume* volCoil = BuildNearCoilVolume();
00393 this -> AddNode(volCoil,1,gGeoIdentity);
00394 }
00395 break;
00396
00397 default:
00398
00399 break;
00400
00401 }
00402
00403 return;
00404
00405 }
00406
00407
00408 TGeoVolume* GeoScintPlnVolume::BuildFarCoilVolume() const {
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 UpdateGlobalManager();
00431
00432 const GeoMediumMap& medMap = fGeoGeometry -> GetMediumMap();
00433
00434
00435
00436
00437
00438
00439 TGeoVolume* volBypass = gGeoManager->GetVolume("FABY");
00440 if ( volBypass ) return volBypass;
00441
00442 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00443
00444 Float_t halfz = 0.5*fThick;
00445
00446 TGeoVolume* volCoil
00447 = gGeoManager->MakeTube("FACO",medMap.GetMedium(Geo::kCRSctCoil),
00448 0,Geo::kCoilRad*scale,halfz);
00449 volCoil -> SetLineColor(42);
00450
00451 TGeoVolume* volThroat
00452 = gGeoManager->MakeTube("FATR",medMap.GetMedium(Geo::kCRSctThroat),
00453 0,Geo::kThroatRad*scale,halfz);
00454 volThroat -> SetLineColor(kBlue);
00455
00456 TGeoVolume* volFlange
00457 = gGeoManager->MakeTube("FAFL",medMap.GetMedium(Geo::kCRSctFlange),
00458 0,Geo::kFlangeRad*scale,halfz);
00459 volFlange -> SetLineColor(46);
00460
00461 volBypass
00462 = gGeoManager->MakeTube("FABY",medMap.GetMedium(Geo::kCRSctBypass),
00463 0,Geo::kFarBypassRad*scale,halfz);
00464 volBypass -> SetLineColor(kBlue);
00465 volBypass -> SetLineStyle(2);
00466 volBypass -> SetVisibility(kFALSE);
00467
00468 volBypass -> AddNode(volFlange,1,gGeoIdentity);
00469 volFlange -> AddNode(volThroat,1,gGeoIdentity);
00470 volThroat -> AddNode(volCoil,1,new TGeoTranslation(0,-0.01*scale,0));
00471
00472 return volBypass;
00473
00474 }
00475
00476
00477 TGeoVolume* GeoScintPlnVolume::BuildNearCoilVolume() const {
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 UpdateGlobalManager();
00506
00507 const GeoMediumMap& medMap = fGeoGeometry -> GetMediumMap();
00508
00509
00510
00511
00512 std::string preface = "NAV";
00513 if ( fView == PlaneView::kU ) preface = "NAU";
00514 if ( fCoverage == PlaneCoverage::kNearFull ) preface += "f";
00515 else preface += "p";
00516
00517
00518
00519
00520 TGeoVolume* volBypass
00521 = gGeoManager->GetVolume(std::string(preface+"BY").c_str());
00522 if ( volBypass ) return volBypass;
00523
00524 Double_t scale = Geo::GetScale(fGeoGeometry -> GetAppType());
00525
00526 Float_t halfz = 0.5*fThick;
00527
00528 TGeoVolume* volWater
00529 = gGeoManager->MakeTube(std::string(preface+"WA").c_str(),
00530 medMap.GetMedium(Geo::kCRSctWater),
00531 0,Geo::kNearCoolRad*scale,halfz);
00532 volWater -> SetLineColor(kGreen);
00533
00534 TGeoVolume* volCoil
00535 = gGeoManager->MakeBox(std::string(preface+"CO").c_str(),
00536 medMap.GetMedium(Geo::kCRSctCoil),
00537 Geo::kCoilRad*scale,Geo::kCoilRad*scale,halfz);
00538 volCoil -> SetLineColor(kBlack);
00539
00540 TGeoVolume* volThroat
00541 = gGeoManager->MakeBox(std::string(preface+"TR").c_str(),
00542 medMap.GetMedium(Geo::kCRSctThroat),
00543 Geo::kThroatRad*scale,Geo::kThroatRad*scale,halfz);
00544 volThroat -> SetLineColor(kBlue);
00545
00546 TGeoVolume* volFlange
00547 = gGeoManager->MakeBox(std::string(preface+"FL").c_str(),
00548 medMap.GetMedium(Geo::kCRSctFlange),
00549 Geo::kFlangeRad*scale,Geo::kFlangeRad*scale,halfz);
00550 volFlange -> SetLineColor(kBlack);
00551
00552
00553 if ( fCoverage == PlaneCoverage::kNearPartial ) {
00554 volBypass = gGeoManager->MakeBox(std::string(preface+"BY").c_str(),
00555 medMap.GetMedium(Geo::kCRSctBypass),
00556 Geo::kNearPartialBypassRad*scale,
00557 Geo::kNearPartialBypassRad*scale,halfz);
00558 }
00559 else {
00560
00561 volBypass
00562 = gGeoManager->MakeTube(std::string(preface+"BY").c_str(),
00563 medMap.GetMedium(Geo::kCRSctBypass),
00564 0,Geo::kNearFullBypassRad*scale,halfz);
00565 }
00566
00567 volBypass -> SetLineColor(kBlue);
00568 volBypass -> SetLineStyle(2);
00569
00570 volBypass -> AddNode(volFlange,1,gGeoIdentity);
00571 volFlange -> AddNode(volThroat,1,gGeoIdentity);
00572
00573
00574
00575 if ( fView == PlaneView::kU ) {
00576 volThroat -> AddNode(volCoil,1,
00577 new TGeoTranslation(+0.01*scale,-0.01*scale,0));
00578 }
00579 else {
00580
00581 volThroat -> AddNode(volCoil,1,
00582 new TGeoTranslation(-0.01*scale,-0.01*scale,0));
00583 }
00584
00585 Int_t nx = 6;
00586 Int_t ny = 8;
00587
00588 Float_t xedge = 0.02475*scale;
00589 Float_t x0 = -Geo::kCoilRad*scale + xedge;
00590
00591 Float_t xsep = 2.*(Geo::kCoilRad*scale - xedge)/(Float_t)(nx-1);
00592
00593 Float_t yedge = 0.02221*scale;
00594 Float_t y0 = -Geo::kCoilRad*scale + yedge;
00595
00596 Float_t ysep = 2.*(Geo::kCoilRad*scale - yedge)/(Float_t)(ny-1);
00597
00598 for ( int ix = 0; ix < nx; ix++ ) {
00599 Float_t xpos = x0 + (Float_t)ix*xsep;
00600 for ( int iy = 0; iy < ny; iy++ ) {
00601 Float_t ypos = y0 + (Float_t)iy*ysep;
00602 Int_t itube = ix*ny+iy+1;
00603 if ( fView == PlaneView::kU ) {
00604 volCoil -> AddNode(volWater,itube,new TGeoTranslation(ypos,xpos,0));
00605 }
00606 else {
00607
00608 volCoil -> AddNode(volWater,itube,new TGeoTranslation(xpos,ypos,0));
00609 }
00610 }
00611 }
00612
00613 return volBypass;
00614
00615 }
00616