00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #include <iostream>
00013 using namespace std;
00014 #include <TGeoManager.h>
00015 #include <TGeoMatrix.h>
00016 #include <TGeoBBox.h>
00017 #include <TGeoArb8.h>
00018 #include <TGeoXtru.h>
00019 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,6,0)
00020 #include <TGeoScaledShape.h>
00021 #endif
00022 #include <TROOT.h>
00023 #include <TMath.h>
00024
00025 #include "GeoGeometry/GeoScintMdlVolume.h"
00026 #include "GeoGeometry/GeoGeometry.h"
00027 #include "GeoGeometry/GeoMediumMap.h"
00028 #include "GeoGeometry/GeoStripVolume.h"
00029 #include "GeoGeometry/GeoStripNode.h"
00030 #include "GeoGeometry/GeoMedium.h"
00031 #include "MessageService/MsgService.h"
00032 #include "UgliGeometry/UgliDbiTables.h"
00033 #include "UgliGeometry/UgliDbiStructHash.h"
00034
00035 ClassImp(GeoScintMdlVolume)
00036 CVSID("$Id: GeoScintMdlVolume.cxx,v 1.18 2008/01/09 06:38:11 schubert Exp $");
00037
00038
00039 GeoScintMdlVolume::GeoScintMdlVolume() : GeoVolume(),fScintMdlId(),fThick(0),
00040 fSkinThick(0),
00041 fBaseShp(0),fBaseShpAir(0) {
00042
00043 if ( gROOT -> GetVersionInt() < 50600 ) {
00044 MSG("Geo",Msg::kFatal) << "GeoGeometry requires ROOT version >= 5.06/00."
00045 << "\n Please switch to a newer version of root."
00046 << endl;
00047 abort();
00048 }
00049
00050
00051 for ( int ip = 0; ip < 4; ip++ ) {
00052 for ( int ic = 0; ic < 2; ic++ ) fXY[ip][ic] = 0;
00053 }
00054
00055 }
00056
00057
00058 GeoScintMdlVolume::GeoScintMdlVolume(GeoGeometry* geo,
00059 const PlexScintMdlId& mdlId,
00060 const UgliDbiTables& ugliTables) :
00061 GeoVolume(geo,
00062 (GeoGeometry::GetGeoCompatibleName(mdlId.AsString())).c_str(),0),
00063 fScintMdlId(mdlId),fThick(0),fSkinThick(0),fBaseShp(0),fBaseShpAir(0) {
00064
00065
00066 if ( gROOT -> GetVersionInt() < 50600 ) {
00067 MSG("Geo",Msg::kFatal) << "GeoGeometry requires ROOT version >= 5.06/00."
00068 << "\n Please switch to a newer version of root."
00069 << endl;
00070 abort();
00071 }
00072
00073 UpdateGlobalManager();
00074
00075 const GeoMediumMap& medMap = fGeoGeometry -> GetMediumMap();
00076 if ( fScintMdlId.IsVetoShield() )
00077 SetMedium(medMap.GetMedium(Geo::kVSMdlAlSkin));
00078 else SetMedium(medMap.GetMedium(Geo::kMdlAlSkin));
00079
00080 MSG("Geo",Msg::kDebug) << "GeoScintMdlVolume ctor, mdl name "
00081 << GetName() << endl;
00082
00083 fShpName = GeoGeometry::GetGeoCompatibleName(mdlId.AsString());
00084
00085 Float_t scale = GetScale();
00086 fSkinThick = scale*Geo::kModuleSkinThick;
00087 fThick = scale*Geo::kStripThick + 2.*fSkinThick;
00088
00089
00090 std::string baseshpname
00091 = GeoGeometry::GetGeoCompatibleName(mdlId.AsString("s"));
00092 std::string baseshpairname = baseshpname + "_air";
00093 fBaseShp = dynamic_cast<TGeoShape*>(gGeoManager->GetListOfShapes()
00094 -> FindObject(baseshpname.c_str()));
00095 fBaseShpAir = dynamic_cast<TGeoShape*>(gGeoManager->GetListOfShapes()
00096 -> FindObject(baseshpairname.c_str()));
00097
00098 if ( !fBaseShp ) {
00099
00100 fBaseShp = BuildModuleShape(ugliTables,baseshpname);
00101 fBaseShpAir = BuildModuleShape(ugliTables,baseshpairname,true);
00102 }
00103
00104 TGeoShape* shape = BuildModuleShape(ugliTables,fShpName);
00105
00106 SetShape(shape);
00107
00108
00109
00110 gGeoManager -> GetListOfGVolumes() -> Remove(this);
00111 Int_t index = gGeoManager->GetListOfVolumes() -> GetEntriesFast();
00112 gGeoManager -> GetListOfVolumes() -> AddAtAndExpand(this,index);
00113
00114 this -> SetLineColor(17);
00115
00116 this -> SetVisibility(kTRUE);
00117
00118 this -> AddAirNode(ugliTables);
00119
00120 }
00121
00122
00123 void GeoScintMdlVolume::AddAirNode(const UgliDbiTables& ugliTables) {
00124
00125
00126
00127 UpdateGlobalManager();
00128
00129 Geo::EDetComponent detcomp = Geo::kMdlAir;
00130 if ( fScintMdlId.IsVetoShield() ) detcomp = Geo::kVSMdlAir;
00131
00132 std::string airShpName = fShpName+"_air";
00133 TGeoShape* airShape = BuildModuleShape(ugliTables,airShpName,true);
00134
00135 std::string airVolName = std::string(GetName()) + "_air";
00136 TGeoVolume* airVol = new TGeoVolume(airVolName.c_str(),airShape,
00137 fGeoGeometry->GetMediumMap().GetMedium(detcomp));
00138 airVol -> SetLineColor(17);
00139 airVol -> SetVisibility(kTRUE);
00140
00141 this -> AddNode(airVol,1,gGeoIdentity);
00142
00143 return;
00144
00145 }
00146
00147
00148 void GeoScintMdlVolume::Print(Option_t* ) const {
00149
00150
00151 UpdateGlobalManager();
00152
00153 cout << "GeoScintMdlVolume::Print\n"
00154 << GetName() << endl;
00155
00156 }
00157
00158
00159 GeoStripNode* GeoScintMdlVolume::GetStripNode(const PlexStripEndId& seid)
00160 const {
00161
00162
00163 UpdateGlobalManager();
00164
00165
00166 PlexStripEndId seid_clean(seid);
00167 seid_clean.SetEnd(StripEnd::kUnknown);
00168 seid_clean.SetSubPart(StripEnd::kWhole);
00169
00170 TGeoVolume* airVol = GetAirNode()->GetVolume();
00171 Int_t nstrip = airVol->GetNdaughters();
00172 for ( int istp = 0; istp < nstrip; istp++ ) {
00173 GeoStripNode* stpnode = dynamic_cast<GeoStripNode*>(airVol->GetNode(istp));
00174 if ( seid_clean == stpnode->GetSEId() ) {
00175 return stpnode;
00176 }
00177 }
00178
00179 return 0;
00180
00181 }
00182
00183
00184 std::vector<GeoStripNode*> GeoScintMdlVolume::GetStripNodePtrVector() const {
00185
00186
00187 UpdateGlobalManager();
00188
00189 std::vector<GeoStripNode*> stpnodes;
00190 TGeoVolume* airVol = GetAirNode()->GetVolume();
00191 Int_t nstrip = airVol->GetNdaughters();
00192 for ( int istp = 0; istp < nstrip; istp++ ) {
00193 GeoStripNode* stpnode = dynamic_cast<GeoStripNode*>(airVol->GetNode(istp));
00194 stpnodes.push_back(stpnode);
00195 }
00196
00197 return stpnodes;
00198
00199 }
00200
00201
00202
00203 TGeoShape* GeoScintMdlVolume::BuildModuleShape(const UgliDbiTables& ugliTables,
00204 std::string shpName,
00205 bool isInner) {
00206
00207
00208 UpdateGlobalManager();
00209
00210 MSG("Geo",Msg::kDebug) << "BuildModuleShape for shape " << shpName.c_str()
00211 << endl;
00212
00213
00214 TGeoShape* mdlBaseShp = fBaseShp;
00215 if ( isInner ) {
00216 mdlBaseShp = fBaseShpAir;
00217 }
00218
00219 if ( mdlBaseShp ) {
00220 BuildHalfY(ugliTables);
00221 Double_t halfybasic = dynamic_cast<TGeoBBox*>(mdlBaseShp) -> GetDY();
00222 Double_t halfy = 0.5*(fXY[1][1] - fXY[0][1]);
00223 if ( isInner ) halfy -= fSkinThick;
00224 Double_t scaley = halfy/halfybasic;
00225 if ( TMath::Abs(scaley - 1.) > 1.e-6 ) {
00226 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,6,0)
00227 return (new TGeoScaledShape(shpName.c_str(),mdlBaseShp,
00228 new TGeoScale(1.,scaley,1.)));
00229 #endif
00230 }
00231 else {
00232 return mdlBaseShp;
00233 }
00234 }
00235
00236 TGeoShape* shape = 0;
00237
00238 Detector::Detector_t dettype = fScintMdlId.GetDetector();
00239
00240 switch ( dettype ) {
00241
00242 case Detector::kFar:
00243
00244 shape = BuildFar(ugliTables,shpName,isInner);
00245 break;
00246
00247 case Detector::kNear:
00248
00249 shape = BuildNear(ugliTables,shpName,isInner);
00250 break;
00251
00252 case Detector::kCalDet:
00253
00254 shape = BuildCalDet(ugliTables,shpName,isInner);
00255 break;
00256
00257 default:
00258
00259 MSG("Geo",Msg::kError)<< "Scint mdl shape construction for detector type\n"
00260 << Detector::AsString(dettype)
00261 << " not yet supported." << endl;
00262
00263 }
00264
00265 return shape;
00266
00267 }
00268
00269
00270 TGeoShape* GeoScintMdlVolume::BuildCalDet(const UgliDbiTables& ugliTables,
00271 std::string shpName, bool isInner) {
00272
00273
00274 UpdateGlobalManager();
00275
00276 UChar_t mdlType = fScintMdlId.GetModuleType();
00277 std::string regionName = ( isInner ) ? "interior" : "shell";
00278
00279 MSG("Geo",Msg::kVerbose)
00280 << "Build cal detector module shape for module type "
00281 << mdlType << " " << regionName.c_str() << "." << endl;
00282
00283 TGeoShape* shape = 0;
00284
00285 switch ( mdlType ) {
00286 default:
00287
00288 shape = BuildBBox(ugliTables,shpName,isInner);
00289 break;
00290 }
00291
00292 return shape;
00293
00294 }
00295
00296
00297 TGeoShape* GeoScintMdlVolume::BuildFar(const UgliDbiTables& ugliTables,
00298 std::string shpName, bool isInner) {
00299
00300
00301 UpdateGlobalManager();
00302
00303 UChar_t mdlType = fScintMdlId.GetModuleType();
00304 std::string regionName = ( isInner ) ? "interior" : "shell";
00305
00306 MSG("Geo",Msg::kVerbose)
00307 << "Build far detector module shape for module type "
00308 << mdlType << " " << regionName.c_str() << "." << endl;
00309
00310 TGeoShape* shape = 0;
00311
00312 switch ( mdlType ) {
00313 case 'A':
00314 case 'a':
00315 case 'B':
00316 case 'b':
00317
00318 shape = BuildSimpleTrap(ugliTables,shpName,isInner);
00319 break;
00320 case 'C':
00321 case 'c':
00322 case 'E':
00323 case 'e':
00324
00325 shape = BuildBBox(ugliTables,shpName,isInner);
00326 break;
00327 case 'd':
00328 case 'f':
00329
00330 shape = BuildFardfXtru(ugliTables,shpName,isInner);
00331 break;
00332 case 'D':
00333 case 'F':
00334
00335 shape = BuildFarDFXtru(ugliTables,shpName,isInner);
00336 break;
00337 default:
00338 MSG("Geo",Msg::kError)
00339 << "Scint module shape construction for far detector module type\n"
00340 << mdlType << " not yet supported." << endl;
00341 }
00342
00343 return shape;
00344
00345 }
00346
00347
00348 TGeoShape* GeoScintMdlVolume::BuildNear(const UgliDbiTables& ugliTables,
00349 std::string shpName, bool isInner) {
00350
00351
00352 UpdateGlobalManager();
00353
00354 UChar_t mdlType = fScintMdlId.GetModuleType();
00355 std::string regionName = ( isInner ) ? "interior" : "shell";
00356
00357 MSG("Geo",Msg::kVerbose)
00358 << "Build near detector module shape for module type "
00359 << mdlType << " " << regionName.c_str() << "." << endl;
00360
00361 TGeoShape* shape = 0;
00362
00363 switch ( mdlType ) {
00364 case 'g':
00365 case 'G':
00366 case 'h':
00367 case 'H':
00368 case 'j':
00369 case 'J':
00370 case 'k':
00371 case 'K':
00372 case 'n':
00373 case 'N':
00374
00375 shape = BuildNearXtru(ugliTables,shpName,isInner);
00376 break;
00377 case 'i':
00378
00379 shape = BuildNeariXtru(ugliTables,shpName,isInner);
00380 break;
00381 case 'I':
00382
00383 shape = BuildNearIXtru(ugliTables,shpName,isInner);
00384 break;
00385 case 'l':
00386 case 'M':
00387
00388 shape = BuildNearlMXtru(ugliTables,shpName,isInner);
00389 break;
00390 case 'L':
00391 case 'm':
00392
00393 shape = BuildNearLmXtru(ugliTables,shpName,isInner);
00394 break;
00395 default:
00396 MSG("Geo",Msg::kError)
00397 << "Scint module shape construction for near detector module type\n"
00398 << mdlType << " not yet supported." << endl;
00399 }
00400
00401 return shape;
00402
00403 }
00404
00405
00406 TGeoShape* GeoScintMdlVolume::BuildSimpleTrap(const UgliDbiTables& ugliTables,
00407 std::string shpName,
00408 bool isInner) {
00409
00410
00411 UpdateGlobalManager();
00412
00413 Float_t m01 =0;
00414 Float_t m23 = 0;
00415 Build4Corners(ugliTables,m01,m23);
00416
00417 Double_t halfxloy = 0.5*(fXY[3][0] - fXY[0][0]);
00418 Double_t halfxhiy = 0.5*(fXY[2][0] - fXY[1][0]);
00419 Double_t halfy = 0.5*(fXY[1][1] - fXY[0][1]);
00420 Double_t halfz = 0.5*fThick;
00421
00422 if ( isInner ) {
00423
00424 Double_t b01 = fXY[1][1] - m01*fXY[1][0];
00425 Double_t arctanm = atan(TMath::Abs(m01));
00426 Double_t delta = fSkinThick/sin(arctanm);
00427 Double_t y0p = fXY[0][1] + fSkinThick;
00428 Double_t x0p = (y0p - b01)/m01 + delta;
00429 Double_t y1p = fXY[1][1] - fSkinThick;
00430 Double_t x1p = (y1p - b01)/m01 + delta;
00431
00432 halfxloy = -x0p;
00433 halfxhiy = -x1p;
00434 halfy -= fSkinThick;
00435 halfz -= fSkinThick;
00436 }
00437
00438 TGeoTrap* mdlShape = new TGeoTrap(shpName.c_str(), halfz, 0., 0.,
00439 halfy,halfxloy,halfxhiy,0.,halfy,
00440 halfxloy,halfxhiy,0.);
00441
00442 return mdlShape;
00443
00444 }
00445
00446
00447 TGeoShape* GeoScintMdlVolume::BuildBBox(const UgliDbiTables& ugliTables,
00448 std::string shpName, bool isInner) {
00449
00450
00451 UpdateGlobalManager();
00452
00453 Float_t m01 =0;
00454 Float_t m23 = 0;
00455 Build4Corners(ugliTables,m01,m23);
00456
00457 Double_t halfx = 0.5*(fXY[3][0] - fXY[0][0]);
00458 Double_t halfy = 0.5*(fXY[1][1] - fXY[0][1]);
00459 Double_t halfz = 0.5*fThick;
00460
00461 if ( isInner ) {
00462
00463 halfx -= fSkinThick;
00464 halfy -= fSkinThick;
00465 halfz -= fSkinThick;
00466 }
00467
00468 TGeoBBox* mdlShape = new TGeoBBox(shpName.c_str(), halfx, halfy, halfz);
00469
00470 return mdlShape;
00471
00472 }
00473
00474
00475 TGeoShape* GeoScintMdlVolume::BuildFardfXtru(const UgliDbiTables& ugliTables,
00476 std::string shpName,
00477 bool isInner) {
00478
00479
00480 UpdateGlobalManager();
00481
00482 Float_t m01 =0;
00483 Float_t m23 = 0;
00484 Build4Corners(ugliTables,m01,m23);
00485
00486 const int np = 15;
00487 Double_t xp[np] = {0}, yp[np] = {0};
00488
00489 Double_t halfthick = 0.5*fThick;
00490 Double_t skinthick = 0;
00491 Double_t radhole = Geo::kFarModuleHoleRad*GetScale();
00492 Double_t delta = 0;
00493 Double_t dang = TMath::Pi()/(np-5);
00494 radhole /= cos(0.5*dang);
00495
00496 if ( isInner ) {
00497 halfthick -= fSkinThick;
00498 skinthick = fSkinThick;
00499 radhole += fSkinThick;
00500 delta = TMath::ASin(skinthick/radhole);
00501 dang = (TMath::Pi()-2.*delta)/(np-5);
00502 }
00503
00504 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00505 xp[1] = fXY[1][0] + skinthick; yp[1] = fXY[1][1] - skinthick;
00506 xp[np-2] = fXY[2][0] - skinthick; yp[np-2] = fXY[2][1] - skinthick;
00507 xp[np-1] = fXY[3][0] - skinthick; yp[np-1] = fXY[3][1] + skinthick;
00508 Double_t holevtx = fXY[2][1];
00509 for ( int ip = 2; ip < np-2; ip++ ) {
00510 Double_t ang = dang*(ip-2)+delta;
00511 xp[ip] = -radhole*cos(ang); ;
00512 yp[ip] = holevtx - radhole*sin(ang);
00513 }
00514
00515 TGeoXtru* mdlShape = new TGeoXtru(2);
00516 mdlShape -> SetName(shpName.c_str());
00517
00518 mdlShape-> DefinePolygon(np,xp,yp);
00519
00520 mdlShape -> DefineSection(0,-halfthick);
00521 mdlShape -> DefineSection(1,+halfthick);
00522
00523 return mdlShape;
00524
00525 }
00526
00527
00528 TGeoShape* GeoScintMdlVolume::BuildNearLmXtru(const UgliDbiTables& ugliTables,
00529 std::string shpName,
00530 bool isInner) {
00531
00532
00533
00534 UpdateGlobalManager();
00535
00536 Float_t m01 =0;
00537 Float_t m23 = 0;
00538 Build4Corners(ugliTables,m01,m23);
00539
00540 const int np = 15;
00541 Double_t xp[np] = {0}, yp[np] = {0};
00542
00543 Double_t scale = Geo::GetScale(fGeoGeometry->GetAppType());
00544
00545 Double_t halfthick = 0.5*fThick;
00546 Double_t skinthick = 0;
00547 Double_t radhole = Geo::kNearModuleHoleRad*scale;
00548 Double_t delta = 0;
00549 Double_t dang = TMath::Pi()/(np-5);
00550 radhole /= cos(0.5*dang);
00551
00552 if ( isInner ) {
00553 halfthick -= fSkinThick;
00554 skinthick = fSkinThick;
00555 radhole += fSkinThick;
00556 delta = TMath::ASin(skinthick/radhole);
00557 dang = (TMath::Pi()-2.*delta)/(np-5);
00558 }
00559
00560 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00561 xp[1] = fXY[1][0] + skinthick; yp[1] = fXY[1][1] - skinthick;
00562 xp[np-2] = fXY[2][0] - skinthick; yp[np-2] = fXY[2][1] - skinthick;
00563 xp[np-1] = fXY[3][0] - skinthick; yp[np-1] = fXY[3][1] + skinthick;
00564 if ( isInner && TMath::Abs(fXY[2][0] - fXY[3][0]) > 0.0001*scale) {
00565 Double_t m23 = (fXY[2][1]-fXY[3][1])/(fXY[2][0]-fXY[3][0]);
00566 Double_t b23 = fXY[2][1] - m23*fXY[2][0];
00567 Double_t arctanm = atan(TMath::Abs(m23));
00568 Double_t delta = fSkinThick/sin(arctanm);
00569 xp[np-2] = (yp[np-2] - b23)/m23 - delta;
00570 xp[np-1] = (yp[np-1] - b23)/m23 - delta;
00571 }
00572
00573 Double_t holevtx = fXY[2][1];
00574 for ( int ip = 2; ip < np-2; ip++ ) {
00575 Double_t ang = dang*(ip-2)+delta;
00576 xp[ip] = -radhole*cos(ang); ;
00577 yp[ip] = holevtx - radhole*sin(ang);
00578 }
00579
00580 TGeoXtru* mdlShape = new TGeoXtru(2);
00581 mdlShape -> SetName(shpName.c_str());
00582
00583 mdlShape-> DefinePolygon(np,xp,yp);
00584
00585 mdlShape -> DefineSection(0,-halfthick);
00586 mdlShape -> DefineSection(1,+halfthick);
00587
00588 return mdlShape;
00589
00590 }
00591
00592
00593 TGeoShape* GeoScintMdlVolume::BuildNearlMXtru(const UgliDbiTables& ugliTables,
00594 std::string shpName,
00595 bool isInner) {
00596
00597
00598
00599 UpdateGlobalManager();
00600
00601 Float_t m01 =0;
00602 Float_t m23 = 0;
00603 Build4Corners(ugliTables,m01,m23);
00604
00605 const int np = 15;
00606 Double_t xp[np] = {0}, yp[np] = {0};
00607
00608 Double_t scale = Geo::GetScale(fGeoGeometry->GetAppType());
00609
00610 Double_t halfthick = 0.5*fThick;
00611 Double_t skinthick = 0;
00612 Double_t radhole = Geo::kNearModuleHoleRad*scale;
00613 Double_t delta = 0;
00614 Double_t dang = TMath::Pi()/(np-5);
00615 radhole /= cos(0.5*dang);
00616
00617 if ( isInner ) {
00618 halfthick -= fSkinThick;
00619 skinthick = fSkinThick;
00620 radhole += fSkinThick;
00621 delta = TMath::ASin(skinthick/radhole);
00622 dang = (TMath::Pi()-2.*delta)/(np-5);
00623 }
00624
00625 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00626 xp[1] = fXY[1][0] + skinthick; yp[1] = fXY[1][1] - skinthick;
00627 xp[2] = fXY[2][0] - skinthick; yp[2] = fXY[2][1] - skinthick;
00628 xp[3] = fXY[3][0] - skinthick; yp[3] = fXY[3][1] + skinthick;
00629 if ( isInner && TMath::Abs(fXY[2][0] - fXY[3][0]) > 0.0001*scale) {
00630 Double_t m23 = (fXY[2][1]-fXY[3][1])/(fXY[2][0]-fXY[3][0]);
00631 Double_t b23 = fXY[2][1] - m23*fXY[2][0];
00632 Double_t arctanm = atan(TMath::Abs(m23));
00633 Double_t delta = fSkinThick/sin(arctanm);
00634 xp[2] = (yp[2] - b23)/m23 - delta;
00635 xp[3] = (yp[3] - b23)/m23 - delta;
00636 }
00637
00638 Double_t holevtx = fXY[3][1];
00639 for ( int ip = 4; ip < np; ip++ ) {
00640 Double_t ang = dang*(ip-4)+delta;
00641 xp[ip] = radhole*cos(ang); ;
00642 yp[ip] = holevtx + radhole*sin(ang);
00643 }
00644
00645 TGeoXtru* mdlShape = new TGeoXtru(2);
00646 mdlShape -> SetName(shpName.c_str());
00647
00648 mdlShape-> DefinePolygon(np,xp,yp);
00649
00650 mdlShape -> DefineSection(0,-halfthick);
00651 mdlShape -> DefineSection(1,+halfthick);
00652
00653 return mdlShape;
00654
00655 }
00656
00657
00658 TGeoShape* GeoScintMdlVolume::BuildNearIXtru(const UgliDbiTables& ugliTables,
00659 std::string shpName,
00660 bool isInner) {
00661
00662
00663 UpdateGlobalManager();
00664
00665 Float_t m01 =0;
00666 Float_t m23 = 0;
00667 Build4Corners(ugliTables,m01,m23);
00668
00669
00670
00671 PlexStripEndId seid(fScintMdlId,56);
00672 const UgliDbiStrip* scStrip = ugliTables.GetDbiStripById(seid);
00673 std::string stpName = GeoGeometry::GetGeoCompatibleName(seid.AsString("s"));
00674 const GeoStripVolume* stpVol = dynamic_cast<const GeoStripVolume*>
00675 (gGeoManager->GetVolume(stpName.c_str()));
00676 if ( !stpVol ) {
00677 MSG("Geo",Msg::kFatal)
00678 << "Unable to find pre-built stripvol for volume "
00679 << stpName.c_str() << endl;
00680 abort();
00681 }
00682 Float_t ypositype = GetScale()*(scStrip->GetTPosRelMdl())
00683 + stpVol->GetHalfWidth() + fSkinThick;
00684
00685 const int np = 6;
00686 Double_t xp[np] = {0}, yp[np] = {0};
00687
00688 Double_t halfthick = 0.5*fThick;
00689 Double_t skinthick = 0;
00690
00691 if ( isInner ) {
00692 halfthick -= fSkinThick;
00693 skinthick = fSkinThick;
00694 }
00695
00696 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00697 xp[1] = fXY[0][0] + skinthick; yp[1] = ypositype - skinthick;
00698 xp[2] = fXY[1][0] + skinthick; yp[2] = ypositype - skinthick;
00699 xp[3] = fXY[1][0] + skinthick; yp[3] = fXY[1][1] - skinthick;
00700 xp[4] = fXY[2][0] - skinthick; yp[4] = fXY[2][1] - skinthick;
00701 xp[5] = fXY[3][0] - skinthick; yp[5] = fXY[3][1] + skinthick;
00702
00703 TGeoXtru* mdlShape = new TGeoXtru(2);
00704 mdlShape -> SetName(shpName.c_str());
00705
00706 mdlShape-> DefinePolygon(np,xp,yp);
00707
00708 mdlShape -> DefineSection(0,-halfthick);
00709 mdlShape -> DefineSection(1,+halfthick);
00710
00711 return mdlShape;
00712
00713 }
00714
00715
00716 TGeoShape* GeoScintMdlVolume::BuildNeariXtru(const UgliDbiTables& ugliTables,
00717 std::string shpName,
00718 bool isInner) {
00719
00720
00721 UpdateGlobalManager();
00722
00723 Float_t m01 =0;
00724 Float_t m23 = 0;
00725 Build4Corners(ugliTables,m01,m23);
00726
00727
00728
00729 PlexStripEndId seid(fScintMdlId,11);
00730 const UgliDbiStrip* scStrip = ugliTables.GetDbiStripById(seid);
00731 std::string stpName = GeoGeometry::GetGeoCompatibleName(seid.AsString("s"));
00732 const GeoStripVolume* stpVol = dynamic_cast<const GeoStripVolume*>
00733 (gGeoManager->GetVolume(stpName.c_str()));
00734
00735 if ( !stpVol ) {
00736 MSG("Geo",Msg::kFatal)
00737 << "Unable to find pre-built stripvol for volume "
00738 << stpName.c_str() << endl;
00739 abort();
00740 }
00741 Float_t ypositype = GetScale()*(scStrip->GetTPosRelMdl())
00742 - stpVol->GetHalfWidth() - fSkinThick;
00743
00744 const int np = 6;
00745 Double_t xp[np] = {0}, yp[np] = {0};
00746
00747 Double_t halfthick = 0.5*fThick;
00748 Double_t skinthick = 0;
00749
00750 if ( isInner ) {
00751 halfthick -= fSkinThick;
00752 skinthick = fSkinThick;
00753 }
00754
00755 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00756 xp[1] = fXY[0][0] + skinthick; yp[1] = ypositype + skinthick;
00757 xp[2] = fXY[1][0] + skinthick; yp[2] = ypositype + skinthick;
00758 xp[3] = fXY[1][0] + skinthick; yp[3] = fXY[1][1] - skinthick;
00759 xp[4] = fXY[2][0] - skinthick; yp[4] = fXY[2][1] - skinthick;
00760 xp[5] = fXY[3][0] - skinthick; yp[5] = fXY[3][1] + skinthick;
00761
00762 TGeoXtru* mdlShape = new TGeoXtru(2);
00763 mdlShape -> SetName(shpName.c_str());
00764
00765 mdlShape-> DefinePolygon(np,xp,yp);
00766
00767 mdlShape -> DefineSection(0,-halfthick);
00768 mdlShape -> DefineSection(1,+halfthick);
00769
00770 return mdlShape;
00771
00772 }
00773
00774
00775 TGeoShape* GeoScintMdlVolume::BuildNearXtru(const UgliDbiTables& ugliTables,
00776 std::string shpName, bool isInner){
00777
00778
00779
00780 UpdateGlobalManager();
00781
00782 Float_t m01 =0;
00783 Float_t m23 = 0;
00784 Build4Corners(ugliTables,m01,m23);
00785
00786 const int np = 4;
00787 Double_t xp[np] = {0}, yp[np] = {0};
00788
00789 Double_t halfthick = 0.5*fThick;
00790 Double_t skinthick = 0;
00791
00792 if ( isInner ) {
00793 halfthick -= fSkinThick;
00794 skinthick = fSkinThick;
00795 }
00796
00797 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00798 xp[1] = fXY[1][0] + skinthick; yp[1] = fXY[1][1] - skinthick;
00799 xp[2] = fXY[2][0] - skinthick; yp[2] = fXY[2][1] - skinthick;
00800 xp[3] = fXY[3][0] - skinthick; yp[3] = fXY[3][1] + skinthick;
00801
00802 if ( isInner && m23 > 0.0001) {
00803 Double_t b23 = fXY[2][1] - m23*fXY[2][0];
00804 Double_t arctanm = atan(TMath::Abs(m23));
00805 Double_t delta = fSkinThick/sin(arctanm);
00806 xp[2] = (yp[2] - b23)/m23 - delta;
00807 xp[3] = (yp[3] - b23)/m23 - delta;
00808 }
00809
00810 if ( isInner && m01 > 0.0001) {
00811 Double_t b01 = fXY[1][1] - m01*fXY[1][0];
00812 Double_t arctanm = atan(TMath::Abs(m01));
00813 Double_t delta = fSkinThick/sin(arctanm);
00814 xp[1] = (yp[1] - b01)/m01 + delta;
00815 xp[0] = (yp[0] - b01)/m01 + delta;
00816 }
00817
00818 TGeoXtru* mdlShape = new TGeoXtru(2);
00819 mdlShape -> SetName(shpName.c_str());
00820
00821 mdlShape-> DefinePolygon(np,xp,yp);
00822
00823 mdlShape -> DefineSection(0,-halfthick);
00824 mdlShape -> DefineSection(1,+halfthick);
00825
00826 return mdlShape;
00827
00828 }
00829
00830
00831 TGeoShape* GeoScintMdlVolume::BuildFarDFXtru(const UgliDbiTables& ugliTables,
00832 std::string shpName,
00833 bool isInner) {
00834
00835
00836 UpdateGlobalManager();
00837
00838 Float_t m01 =0;
00839 Float_t m23 = 0;
00840 Build4Corners(ugliTables,m01,m23);
00841
00842 const int np = 15;
00843 Double_t xp[np] = {0}, yp[np] = {0};
00844
00845 Double_t halfthick = 0.5*fThick;
00846 Double_t skinthick = 0;
00847 Double_t radhole = Geo::kFarModuleHoleRad*GetScale();
00848 Double_t delta = 0;
00849 Double_t dang = TMath::Pi()/(np-5);
00850 radhole /= cos(0.5*dang);
00851
00852 if ( isInner ) {
00853 halfthick -= fSkinThick;
00854 skinthick = fSkinThick;
00855 radhole += fSkinThick;
00856 delta = TMath::ASin(skinthick/radhole);
00857 dang = (TMath::Pi()-2.*delta)/(np-5);
00858 }
00859
00860 xp[0] = fXY[0][0] + skinthick; yp[0] = fXY[0][1] + skinthick;
00861 xp[1] = fXY[1][0] + skinthick; yp[1] = fXY[1][1] - skinthick;
00862 xp[2] = fXY[2][0] - skinthick; yp[2] = fXY[2][1] - skinthick;
00863 xp[3] = fXY[3][0] - skinthick; yp[3] = fXY[3][1] + skinthick;
00864 Double_t holevtx = fXY[3][1];
00865 for ( int ip = 4; ip < np; ip++ ) {
00866 Double_t ang = dang*(ip-4)+delta;
00867 xp[ip] = radhole*cos(ang); ;
00868 yp[ip] = holevtx + radhole*sin(ang);
00869 }
00870
00871 TGeoXtru* mdlShape = new TGeoXtru(2);
00872 mdlShape -> SetName(shpName.c_str());
00873
00874 mdlShape-> DefinePolygon(np,xp,yp);
00875
00876 mdlShape -> DefineSection(0,-halfthick);
00877 mdlShape -> DefineSection(1,+halfthick);
00878
00879 return mdlShape;
00880
00881 }
00882
00883
00884 void GeoScintMdlVolume::Build4Corners(const UgliDbiTables& ugliTables,
00885 Float_t& m01, Float_t& m23) {
00886
00887
00888
00889
00890
00891
00892
00893
00894 UpdateGlobalManager();
00895
00896 m01 = 0; m23 = 0;
00897 Float_t scale = GetScale();
00898
00899 UgliDbiStructHash modulestructhash(fScintMdlId);
00900 const UgliDbiScintMdlStruct* scModuleStruct
00901 = ugliTables.fScintMdlStructTbl
00902 .GetRowByIndex(modulestructhash.HashAsScintMdl());
00903
00904
00905 Int_t lostrip = scModuleStruct -> GetFirstStrip();
00906 Int_t histrip = scModuleStruct -> GetLastStrip();
00907
00908
00909
00910
00911
00912
00913
00914
00915 PlexStripEndId loseid(fScintMdlId,lostrip);
00916 const UgliDbiStrip* scStrip = ugliTables.GetDbiStripById(loseid);
00917 std::string stpName=GeoGeometry::GetGeoCompatibleName(loseid.AsString("s"));
00918 const GeoStripVolume* stpVol = dynamic_cast<const GeoStripVolume*>
00919 (gGeoManager -> GetVolume(stpName.c_str()));
00920 if ( !stpVol ) {
00921 MSG("Geo",Msg::kFatal)
00922 << "Unable to find pre-built stripvol for volume "
00923 << stpName.c_str() << endl;
00924 abort();
00925 }
00926
00927 Float_t lostriphalfwidth = stpVol->GetHalfWidth() + fSkinThick;
00928
00929
00930 fXY[0][0] = scale*(scStrip->GetLPosRelMdl())-stpVol->GetHalfLength()
00931 -fSkinThick;
00932 fXY[0][1] = scale*(scStrip->GetTPosRelMdl())+stpVol->GetHalfWidth()
00933 +fSkinThick;
00934
00935
00936 fXY[3][0] = scale*(scStrip->GetLPosRelMdl())+stpVol->GetHalfLength()
00937 +fSkinThick;
00938 fXY[3][1] = scale*(scStrip->GetTPosRelMdl())+stpVol->GetHalfWidth()
00939 +fSkinThick;
00940
00941
00942 PlexStripEndId hiseid(fScintMdlId,histrip);
00943 scStrip = ugliTables.GetDbiStripById(hiseid);
00944 stpName=GeoGeometry::GetGeoCompatibleName(hiseid.AsString("s"));
00945
00946 stpVol = dynamic_cast<GeoStripVolume*>
00947 (gGeoManager -> GetVolume(stpName.c_str()));
00948 if ( !stpVol ) {
00949 MSG("Geo",Msg::kFatal)
00950 << "Unable to find pre-built stripvol for volume "
00951 << stpName.c_str() << endl;
00952 abort();
00953 }
00954
00955 Double_t histriphalfwidth = stpVol->GetHalfWidth() + fSkinThick;
00956
00957
00958 fXY[1][0] = scale*(scStrip->GetLPosRelMdl())-stpVol->GetHalfLength()
00959 -fSkinThick;
00960 fXY[1][1] = scale*(scStrip->GetTPosRelMdl())+stpVol->GetHalfWidth()
00961 +fSkinThick;
00962
00963
00964 fXY[2][0] = scale*(scStrip->GetLPosRelMdl())+stpVol->GetHalfLength()
00965 +fSkinThick;
00966 fXY[2][1] = scale*(scStrip->GetTPosRelMdl())+stpVol->GetHalfWidth()
00967 +fSkinThick;
00968
00969
00970 UChar_t mdlType = fScintMdlId.GetModuleType();
00971 if ( mdlType != 'i' && mdlType != 'I' ) {
00972
00973 if ( TMath::Abs(fXY[1][0] - fXY[0][0]) >= 0.0001*scale ) {
00974 m01 = (fXY[1][1] - fXY[0][1])/
00975 (fXY[1][0] - fXY[0][0]);
00976 if ( m01 > 0 ) {
00977 fXY[0][0] -= 2.*lostriphalfwidth/m01;
00978 }
00979 else {
00980 fXY[1][0] += 2.*histriphalfwidth/m01;
00981 }
00982 }
00983 }
00984
00985
00986 if ( TMath::Abs(fXY[2][0] - fXY[3][0]) >= 0.0001*scale ) {
00987 m23 = (fXY[2][1] - fXY[3][1])/
00988 (fXY[2][0] - fXY[3][0]);
00989 if ( m23 < 0 ) {
00990 fXY[3][0] -= 2.*lostriphalfwidth/m23;
00991 }
00992 else {
00993 fXY[2][0] += 2.*histriphalfwidth/m23;
00994 }
00995 }
00996
00997 fXY[0][1] -= 2.*lostriphalfwidth;
00998 fXY[3][1] -= 2.*lostriphalfwidth;
00999
01000
01001
01002
01003
01004 }
01005
01006
01007 void GeoScintMdlVolume::BuildHalfY(const UgliDbiTables& ugliTables) {
01008
01009
01010
01011
01012 UpdateGlobalManager();
01013
01014 Float_t scale = GetScale();
01015
01016 UgliDbiStructHash modulestructhash(fScintMdlId);
01017 const UgliDbiScintMdlStruct* scModuleStruct
01018 = ugliTables.fScintMdlStructTbl
01019 .GetRowByIndex(modulestructhash.HashAsScintMdl());
01020
01021
01022 Int_t lostrip = scModuleStruct -> GetFirstStrip();
01023 Int_t histrip = scModuleStruct -> GetLastStrip();
01024
01025
01026 PlexStripEndId loseid(fScintMdlId,lostrip);
01027 const UgliDbiStrip* scStrip = ugliTables.GetDbiStripById(loseid);
01028
01029 Float_t striphalfwidth = 0.5*(Geo::kStripWidth)*scale + fSkinThick;
01030
01031 fXY[0][1] = scale*(scStrip->GetTPosRelMdl())-striphalfwidth;
01032
01033
01034 PlexStripEndId hiseid(fScintMdlId,histrip);
01035 scStrip = ugliTables.GetDbiStripById(hiseid);
01036
01037
01038 fXY[1][1] = scale*(scStrip->GetTPosRelMdl())+striphalfwidth;
01039
01040 }
01041
01042
01043 Int_t GeoScintMdlVolume::NumberOfStrips() const {
01044
01045
01046 UpdateGlobalManager();
01047
01048 return (this -> GetAirNode() -> GetVolume() -> GetNdaughters());
01049
01050 }
01051
01052