Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

UgliSteelPlnNode.cxx

Go to the documentation of this file.
00001 
00002 // $Id: UgliSteelPlnNode.cxx,v 1.26 2006/06/27 20:08:23 rhatcher Exp $
00003 //
00004 // UgliSteelPlnNode
00005 //
00006 // UgliSteelPlnNode is a single steel plane
00007 //
00008 // Author:  R. Hatcher 2000.11.15
00009 //
00011 
00012 #include "UgliGeometry/UgliSteelPlnNode.h"
00013 
00014 #include "UgliGeometry/UgliGeometry.h"
00015 #include "UgliGeometry/TGeometryX.h"
00016 
00017 #include "UgliGeometry/MinosOutline.h"
00018 #include "UgliGeometry/UgliDbiTables.h"
00019 #ifdef UGLI_USE_EXODUS
00020 #include "RerootExodus/RerootExodus.h"
00021 #endif
00022 
00023 #include "Conventions/Munits.h"
00024 
00025 #include "TBRIK.h"
00026 #include "TVector3.h"
00027 
00028 #include "MessageService/MsgService.h"
00029 CVSID("$Id: UgliSteelPlnNode.cxx,v 1.26 2006/06/27 20:08:23 rhatcher Exp $");
00030 
00031 #include <cassert>
00032 
00033 ClassImp(UgliSteelPlnNode)
00034 
00035 //_____________________________________________________________________________
00036 UgliSteelPlnNode::UgliSteelPlnNode()
00037   : UgliPlnNode()
00038 {
00039    // Default constructor (for i/o)
00040 }
00041 
00042 //______________________________________________________________________________
00043 UgliSteelPlnNode::~UgliSteelPlnNode()
00044 {
00045    // destructor should delete any owned objects
00046 #ifdef DUPLICATE_WARNING
00047    // this check is done in the base ~UgliPlnNode()
00048    if (CountRef()) {
00049       MSG("Ugli",Msg::kWarning)
00050         << "~UgliSteelPlnNode " << GetPlexPlaneId()
00051         << " still had " << CountRef()
00052         << " outstanding references " << endl;
00053    }
00054 #endif
00055 }
00056 
00057 //_____________________________________________________________________________
00058 UgliSteelPlnNode::UgliSteelPlnNode(UgliGeometry *ugliGeometry,
00059                                    const PlexPlaneId planeid)
00060    : UgliPlnNode(ugliGeometry,planeid)
00061 {
00062    // ctor that old REROOT-basaed UgliGeometry uses in constructing
00063 
00064    static Int_t nwarn = 2;
00065 
00066    if (nwarn > 0 ) {
00067       MSG("Ugli",Msg::kInfo) 
00068          << "UgliSteelPlnNode::ctor " 
00069          << "    " << planeid.AsString("p") 
00070          << "... needs DBI interface" << endl;
00071       nwarn--;
00072    }
00073 
00074    TGeometryX* fRootGeom = fUgliGeometry->GetTGeometryX();
00075 
00076    // assign the correct shape to this node
00077    // build an appropriate shape if necessary
00078    const char *shapename = "nshape";
00079    bool hasEars = true;
00080    if (!planeid.IsSteel()) {
00081       // this shouldn't be ...
00082       MSG("Ugli",Msg::kWarning) 
00083          << "UgliSteelPlnNode::ctor saw Scint PlaneId "
00084          << planeid.AsString() << endl;
00085    }
00086    switch (planeid.GetDetector()) {
00087    case Detector::kFar:
00088       shapename = "FarSteel";
00089       break;
00090    case Detector::kNear:
00091       shapename = "NearSteel";
00092       break;
00093    case Detector::kCalib:
00094       shapename = "CalDetSteel";
00095       break;
00096    default:
00097       shapename = "noshape";
00098       break;
00099    }
00100 
00101    MinosOutline* the_shape =
00102       dynamic_cast<MinosOutline*>(fRootGeom->GetShape(shapename));
00103    if ( ! the_shape ) {
00104       MSG("Ugli",Msg::kInfo)
00105          << "UgliSteelPlnNode ctor creating shape " << shapename << endl;
00106       Float_t halfthick  = 0.5 * 2.54 * Munits::cm;
00107 
00108       if (nwarn > 0 ) {
00109          MSG("Ugli",Msg::kDebug) 
00110             << "UgliSteelPlnNode::ctor kludge plane thickness" << endl;
00111          nwarn--;
00112       }
00113 
00114       the_shape = new MinosOutline(shapename,shapename,"void",
00115                                    planeid,hasEars,halfthick,1.);
00116    }
00117    fShape = the_shape;  // assign TNode member the correct shape
00118 
00119    // position and orient the shape correctly
00120    TNode* hallnode = fRootGeom->GetNode("hall");
00121    hallnode->cd();
00122    hallnode->UpdateMatrix();
00123 
00124    SetParent(hallnode);
00125 
00126    Float_t global[3], local[3];
00127    if (fUgliGeometry->GetVldRange().GetSimMask() & SimFlag::kReroot) {
00128 #ifdef UGLI_USE_EXODUS
00129       RerootExodus::RerootPlaneXYZ0(planeid,global);
00130       global[0] *= Munits::cm;
00131       global[1] *= Munits::cm;
00132       global[2] *= Munits::cm;
00133 #else
00134       static int nmsg = 5;
00135       if (nmsg-- > 0) 
00136          MSG("Ugli",Msg::kWarning) 
00137             << " steelpln positioning code must go here" << endl;
00138       assert(0);
00139 #endif
00140    }
00141 
00142    Float_t x0shift = the_shape->GetGlobalXOffset() * Munits::cm;
00143 
00144    hallnode->Master2Local(global,local);
00145    
00146    SetPosition(local[0]+x0shift,local[1],local[2]);
00147 
00148    SetVisibility(0);
00149 }
00150 
00151 //_____________________________________________________________________________
00152 UgliSteelPlnNode::UgliSteelPlnNode(const PlexPlaneId planeid,
00153                                    UgliGeometry *ugliGeometry,
00154                                    const UgliDbiTables& ugliTables)
00155    : UgliPlnNode(ugliGeometry,planeid)
00156 {
00157    // ctor for DBI driven UgliGeometry
00158 
00159    // expand the x-y size of the enclosing box 
00160    // just so we can see which is which
00161    // changing scale mucks up the global x shift
00162    Float_t xyscale_box = 1.0;
00163    Float_t xyscale_stl = 1.0;
00164    // set this ~100 to expand z coordinate
00165    Float_t bombz = 1.; // 100.;
00166    
00167    bool hasEars = true;
00168 
00169    //
00170    // build the enclosing box of steel (+ scint)
00171    //
00172    char boxname[16], stlname[16];
00173    sprintf(boxname,"%s",planeid.AsString("b"));  // dNNNBvc
00174    sprintf(stlname,"%s",planeid.AsString("p"));  // dNNNPvc
00175    if (planeid.IsVetoShield()) stlname[4] = 'P'; // force 'P'-ness
00176 
00177    UInt_t ipln = planeid.GetPlane();
00178    const UgliDbiSteelPln* steelRow = ugliTables.GetDbiSteelPlnByIndex(ipln);
00179    if (!steelRow) {
00180      MSG("Ugli",Msg::kError) 
00181        << " no UgliDbiSteelPln entry for " << planeid << endl;
00182      return;
00183    }
00184 
00185    Float_t dzbox = 0.5 * steelRow->GetTotalZ() *bombz; // box z half size
00186    MinosOutline *box_outline = 
00187       new MinosOutline(boxname,boxname,"void",planeid,hasEars,dzbox,xyscale_box);
00188 
00189    // additional shift due to near detector weirdness
00190 //no!   Float_t x0shift = xyscale_box * box_outline->GetGlobalXOffset();
00191 
00192    Float_t x0pln = steelRow->GetX0(); // no! +x0shift;
00193    Float_t y0pln = steelRow->GetY0();
00194    Float_t zback = steelRow->GetZBack();
00195    Float_t z0box = zback*bombz - dzbox;
00196          
00197    TRotMatrix *box_rotm =
00198       new TRotMatrix(boxname,boxname,
00199                   steelRow->GetThetaDeg(0),steelRow->GetPhiDeg(0),
00200                   steelRow->GetThetaDeg(1),steelRow->GetPhiDeg(1),
00201                   steelRow->GetThetaDeg(2),steelRow->GetPhiDeg(2));
00202 
00203    // the current working node should already be the hall
00204    TNode* hall_node = fUgliGeometry->GetTGeometryX()->GetCurrentNode();
00205    if ( !hall_node || strcmp("hall",hall_node->GetName()) ) {
00206       MSG("Ugli",Msg::kWarning) 
00207          << "UgliSteelPlnNode " << planeid
00208          << " ctor didn't start in the \"hall\" node: " 
00209          << hall_node->GetName()
00210          << endl;
00211       hall_node = fUgliGeometry->GetTNodeX("hall");
00212       if (!hall_node) {
00213          MSG("Ugli",Msg::kError) 
00214             << "UgliSteelPlnNode ctor found the \"hall\" node wasn't a TNodeX"
00215             << endl;
00216          return;
00217       }
00218       hall_node->cd();
00219    }
00220 
00221    // go inside the hall and place the containing box
00222    Float_t x0hall = hall_node->GetX();
00223    Float_t y0hall = hall_node->GetY();
00224    Float_t z0hall = hall_node->GetZ();
00225    TNodeX* box_node =
00226       new TNodeX(boxname,boxname,box_outline,
00227                  x0pln-x0hall,y0pln-y0hall,z0box-z0hall,box_rotm);
00228 
00229    box_node->SetLineColor(41); // a ghostly beige
00230 
00231    MSG("Ugli",Msg::kVerbose) << " create specific steel outline" << endl;
00232 
00233    // the actual steel plane gets put in the box
00234    // with no additional shifts or rotations
00235    // except that it gets shoved to the back (+z) of the box
00236    Float_t hthick = 0.5 * steelRow->GetThickness() *bombz;
00237    Float_t zshift_stl = dzbox - hthick;
00238    // build and attach the appropriate shape
00239    fShape = new MinosOutline(stlname,stlname,"steel",planeid,
00240                              hasEars,hthick,xyscale_stl);
00241 
00242    // parent was initialized by ctor ... we need to set it into the box
00243    SetParent(box_node);    // modified version in TNodeX needed
00244    SetPosition(0,0,zshift_stl);
00245    // by default,if no name supplied, it's built with the Identity matrix 
00246    // SetMatrix(fUgliGeometry->GetRotMatrix("Identity"))
00247    SetLineColor(50);   // kind of rusty color
00248 
00249    int box_vis = 1; // ?? 0 ??
00250    int stl_vis = 1; // ?? 0 ??
00251    box_node->SetVisibility(box_vis); 
00252    this->SetVisibility(stl_vis);
00253 
00254    // map "local" (steel) [0,0,zback] to global position
00255    TVector3 current = LocalToGlobal(TVector3(0,0,hthick)); 
00256    // adjust box position to make (x0,y0,zback) where it should be
00257    // this was easy when there were only U,V planes
00258    box_node->SetPosition(box_node->GetX()+x0pln-current.X(),
00259                          box_node->GetY()+y0pln-current.Y(),
00260                          box_node->GetZ()+zback-current.Z());
00261 
00262 }
00263 
00264 //_____________________________________________________________________________
00265 
00266 void UgliSteelPlnNode::IncrementRef()
00267 {
00268    fRef++; 
00269    fUgliGeometry->IncrementRef();
00270    SetVisibility(1);
00271 }
00272 
00273 void UgliSteelPlnNode::DecrementRef()
00274 { 
00275    fRef--; 
00276    fUgliGeometry->DecrementRef();
00277    if (!fRef) SetVisibility(0);
00278 }
00279 
00280 //_____________________________________________________________________________
00281 void UgliSteelPlnNode::TransformLocal2Global(Double_t *lxyz, Double_t *gxyz) const
00282 {
00283    // deal with fact that TNode::Master2Local isn't declared const
00284    UgliSteelPlnNode* self = const_cast<UgliSteelPlnNode*>(this);
00285    self->cd();
00286    self->UpdateMatrix();
00287    self->Local2Master(lxyz,gxyz);
00288 }
00289 
00290 //_____________________________________________________________________________
00291 Float_t UgliSteelPlnNode::GetHalfThickness() const
00292 {
00293 
00294    TBRIK *brik = dynamic_cast<TBRIK*>(fShape);
00295    if (brik) return brik->GetDz();
00296 
00297    TXTRU *xtru = dynamic_cast<TXTRU*>(fShape);
00298    if (xtru) {
00299       Int_t    nz = xtru->GetNz();
00300       Float_t* fz = xtru->GetZ();
00301       return 0.5*TMath::Abs(fz[0]-fz[nz-1]);
00302    }
00303 
00304    MSG("Ugli",Msg::kError) <<
00305       "UgliSteelPlnNode::GetHalfThickness: not a BRIK or TXTRU" << endl;
00306 
00307    return 0;
00308 }
00309 
00310 //_____________________________________________________________________________
00311 TVector3 UgliSteelPlnNode::GetCenter() const
00312 {
00313    Double_t lxyz[3] = {0., 0., 0.};
00314    Double_t gxyz[3];
00315 
00316    TransformLocal2Global(lxyz,gxyz);
00317    return TVector3(gxyz[0],gxyz[1],gxyz[2]);
00318 }
00319 
00320 //_____________________________________________________________________________
00321 Float_t UgliSteelPlnNode::GetX0() const
00322 {
00323    Double_t lxyz[3] = {0., 0., 0.};
00324    Double_t gxyz[3];
00325 
00326    TransformLocal2Global(lxyz,gxyz);
00327    return gxyz[0];
00328 }
00329 
00330 //_____________________________________________________________________________
00331 Float_t UgliSteelPlnNode::GetY0() const
00332 {
00333    Double_t lxyz[3] = {0., 0., 0.};
00334    Double_t gxyz[3];
00335 
00336    TransformLocal2Global(lxyz,gxyz);
00337    return gxyz[1];
00338 }
00339 
00340 //_____________________________________________________________________________
00341 Float_t UgliSteelPlnNode::GetZ0() const
00342 {
00343    Double_t lxyz[3] = {0., 0., 0.};
00344    Double_t gxyz[3];
00345 
00346    TransformLocal2Global(lxyz,gxyz);
00347    return gxyz[2];
00348 }
00349 
00350 //_____________________________________________________________________________
00351 TVector3 UgliSteelPlnNode::GlobalToLocal(const TVector3& global) const
00352 { 
00353    // get the local position based on global position
00354 
00355    Double_t gxyz[3], lxyz[3];
00356 
00357    gxyz[0] = global.X();
00358    gxyz[1] = global.Y();
00359    gxyz[2] = global.Z();
00360 
00361    // deal with fact that TNode::Master2Local isn't declared const
00362    UgliSteelPlnNode* self = const_cast<UgliSteelPlnNode*>(this);
00363    self->cd();
00364    self->UpdateMatrix();
00365    self->Master2Local(gxyz,lxyz);
00366 
00367    return TVector3(lxyz[0],lxyz[1],lxyz[2]);
00368 }
00369 
00370 //_____________________________________________________________________________
00371 TVector3 UgliSteelPlnNode::LocalToGlobal(const TVector3& local) const
00372 { 
00373    // get the global position based on local position
00374 
00375    Double_t gxyz[3], lxyz[3];
00376 
00377    lxyz[0] = local.X();
00378    lxyz[1] = local.Y();
00379    lxyz[2] = local.Z();
00380 
00381    // deal with fact that TNode::Local2Master isn't declared const
00382    UgliSteelPlnNode* self = const_cast<UgliSteelPlnNode*>(this);
00383    self->cd();
00384    self->UpdateMatrix();
00385    self->Local2Master(lxyz,gxyz);
00386 
00387    return TVector3(gxyz[0],gxyz[1],gxyz[2]);
00388 }
00389 
00390 //_____________________________________________________________________________
00391 TVector3 UgliSteelPlnNode::GlobalToLocalVect(const TVector3& global) const
00392 { 
00393    // get the local direction based on global direction
00394 
00395    Double_t gxyz[3], lxyz[3];
00396 
00397    gxyz[0] = global.X();
00398    gxyz[1] = global.Y();
00399    gxyz[2] = global.Z();
00400 
00401    // deal with fact that TNode::Master2Local isn't declared const
00402    UgliSteelPlnNode* self = const_cast<UgliSteelPlnNode*>(this);
00403    self->cd();
00404    self->UpdateMatrixVect();
00405    self->Master2LocalVect(gxyz,lxyz);
00406 
00407    return TVector3(lxyz[0],lxyz[1],lxyz[2]);
00408 }
00409 
00410 //_____________________________________________________________________________
00411 TVector3 UgliSteelPlnNode::LocalToGlobalVect(const TVector3& local) const
00412 { 
00413    // get the global direction based on local direction
00414 
00415    Double_t gxyz[3], lxyz[3];
00416 
00417    lxyz[0] = local.X();
00418    lxyz[1] = local.Y();
00419    lxyz[2] = local.Z();
00420 
00421    // deal with fact that TNode::Local2Master isn't declared const
00422    UgliSteelPlnNode* self = const_cast<UgliSteelPlnNode*>(this);
00423    self->cd();
00424    self->UpdateMatrixVect();
00425    self->Local2MasterVect(lxyz,gxyz);
00426 
00427    return TVector3(gxyz[0],gxyz[1],gxyz[2]);
00428 }
00429 
00430 //_____________________________________________________________________________

Generated on Mon Feb 15 11:07:49 2010 for loon by  doxygen 1.3.9.1