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

GeoStripNode.cxx

Go to the documentation of this file.
00001 
00002 // $Id: GeoStripNode.cxx,v 1.17 2007/11/11 07:28:43 rhatcher Exp $
00003 //
00004 // GeoStripNode
00005 //
00006 // GeoStripNode is a strip node
00007 //
00008 // Author:  S. Kasahara 06/04
00010 
00011 #include <TGeoVolume.h>
00012 #include <TGeoMatrix.h>
00013 #include <TGeoBBox.h>
00014 #include <TMath.h>
00015 
00016 #include "MessageService/MsgService.h"
00017 #include "GeoGeometry/GeoGeometry.h"
00018 #include "GeoGeometry/GeoStripNode.h"
00019 #include "GeoGeometry/GeoScintPlnNode.h"
00020 #include "GeoGeometry/GeoScintMdlNode.h"
00021 
00022 ClassImp(GeoStripNode)
00023 CVSID("$Id: GeoStripNode.cxx,v 1.17 2007/11/11 07:28:43 rhatcher Exp $");
00024 
00025 //_____________________________________________________________________________
00026 GeoStripNode::GeoStripNode(GeoGeometry* geom, TGeoVolume* stpvol, 
00027                            TGeoMatrix* stpmatrix, GeoScintMdlNode* mdlNode, 
00028                            std::string nodename,const PlexStripEndId& stripid)
00029   : GeoNode(geom,stpvol,stpmatrix,
00030             mdlNode->GetScintMdlVolume()->GetAirNode()->GetVolume(),
00031             mdlNode->GetGlobalPath()+"/" + 
00032             mdlNode->GetScintMdlVolume()->GetAirNode()->GetName() + "/" +
00033             nodename,nodename),fStripEndId(stripid),fScintMdlNode(mdlNode) {
00034   // Normal constructor
00035   // Node is constructed and added to volume parentvol with position specified
00036   // by stpmatrix.
00037   // Protected
00038 
00039   UpdateGlobalManager();
00040 
00041 }
00042 
00043 //_____________________________________________________________________________
00044 GeoStripNode::~GeoStripNode() {
00045   // Destructor should delete any owned objects
00046 
00047   UpdateGlobalManager();
00048 
00049   if ( CountRef() ) {
00050     MSG("Geo",Msg::kWarning)
00051       << "GeoStripNode destructor " << GetSEId()
00052       << " still had " << CountRef()
00053       << " outstanding references " << endl;
00054   }
00055 }
00056 
00057 //_____________________________________________________________________________
00058 Float_t GeoStripNode::GetHalfLength() const {
00059   // Return the strip's half length (along local x)
00060 
00061   UpdateGlobalManager();
00062   Float_t halflength = GetStripVolume() -> GetHalfLength();
00063   
00064   MSG("Geo",Msg::kDebug) << "GetHalfLength " << fStripEndId.AsString() 
00065                          << " halflength " << halflength << endl;
00066   
00067   return halflength;
00068 
00069 }
00070 
00071 //_____________________________________________________________________________
00072 Float_t GeoStripNode::GetHalfThickness() const {
00073   // Return the strip's half thickness (along local z)
00074 
00075   UpdateGlobalManager();
00076 
00077   Float_t halfthickness = GetStripVolume() -> GetHalfThickness();
00078   MSG("Geo",Msg::kDebug) << "GetHalfThickness " << fStripEndId.AsString() 
00079                          << " halfthickness " << halfthickness << endl;
00080   
00081   return halfthickness;
00082   
00083 }
00084 
00085 //_____________________________________________________________________________
00086 Float_t GeoStripNode::GetHalfWidth() const {
00087   // Return the strip's half width (along local y)
00088 
00089   UpdateGlobalManager();
00090 
00091   Float_t halfwidth = GetStripVolume() -> GetHalfWidth();
00092   MSG("Geo",Msg::kDebug) << "GetHalfWidth " << fStripEndId.AsString() 
00093                          << " halfwidth " << halfwidth << endl;
00094   
00095   return halfwidth;
00096 
00097 }
00098 
00099 //_____________________________________________________________________________
00100 Float_t GeoStripNode::PartialLength(StripEnd::StripEnd_t stripend) const{
00101   // Return the strip's partial length at the specified end
00102   // If the strip end is not specified, return the total length
00103 
00104   UpdateGlobalManager();
00105 
00106   Float_t lenpart = GetStripVolume() -> GetLenPart(stripend);
00107   MSG("Geo",Msg::kDebug) << "PartialLength " << fStripEndId.AsString() 
00108                          << " end " << StripEnd::AsString(stripend) 
00109                          << " lenpart " << lenpart << endl;
00110   
00111   return lenpart;
00112   
00113 }
00114 
00115 //_____________________________________________________________________________
00116 Float_t GeoStripNode::WlsBypass() const {
00117   // Return the length of the wls fiber along coil hole bypass
00118 
00119   UpdateGlobalManager();
00120 
00121   Float_t wlsbypass = GetStripVolume() -> GetWlsLenBypass();
00122 
00123   MSG("Geo",Msg::kDebug) << "WlsBypass " << fStripEndId.AsString() 
00124                          << " wlsbypass " << wlsbypass << endl;
00125 
00126   return wlsbypass;
00127   
00128 }
00129 
00130 //_____________________________________________________________________________
00131 Float_t GeoStripNode::WlsPigtail(StripEnd::StripEnd_t stripend) const {
00132   // Return the length of the wls fiber "pigtail" (the portion extending
00133   // beyond the strip end), if either StripEnd::kEast or StripEnd::kWest
00134   // is specified.  Otherwise, return 0 with error message. pigtail length
00135   // includes the extra pigtail length associated with the scint module.
00136 
00137   UpdateGlobalManager();
00138 
00139   Float_t wlspigtail = 0;
00140   
00141   switch (stripend) {
00142 
00143   case StripEnd::kEast:
00144   case StripEnd::kWest: 
00145     {
00146       GeoScintMdlNode* mdlNode = GetScintMdlNode();
00147       wlspigtail = GetStripVolume()->GetWlsLen(stripend) 
00148         + mdlNode->GetExtraWlsFiber(stripend);
00149     }
00150     break;
00151   
00152   default:
00153     MSG("Geo",Msg::kWarning) << "WlsPigtail called with stripend "
00154                              << StripEnd::AsString(stripend) 
00155                              << ". Must specify kEast or kWest." << endl;
00156   } // end of switch
00157 
00158   MSG("Geo",Msg::kDebug) << "WlsPigtail " << fStripEndId.AsString() << " end " 
00159                          << StripEnd::AsString(stripend) 
00160                          << " wlspigtail " << wlspigtail << endl;
00161 
00162   return wlspigtail;
00163   
00164 }
00165 
00166 //_____________________________________________________________________________
00167 Bool_t GeoStripNode::IsMirrored(StripEnd::StripEnd_t stripend) const {
00168   // Return true if specified stripend is mirrored, else false. 
00169 
00170   UpdateGlobalManager();
00171 
00172   Bool_t isMirrored = GetStripVolume() -> IsMirrored(stripend);
00173 
00174   MSG("Geo",Msg::kDebug) << "IsMirrored " << fStripEndId.AsString() << " end " 
00175                          << StripEnd::AsString(stripend) << " isMirrored "
00176                          << isMirrored << endl;
00177 
00178   return isMirrored;
00179   
00180 }
00181 
00182 //_____________________________________________________________________________
00183 Float_t GeoStripNode::GetLPosRelMdl() const {
00184   // Return the lpos relative to module (x-pos from translation matrix)
00185 
00186 
00187   UpdateGlobalManager();
00188 
00189   const Double_t* trans = GetMatrix() -> GetTranslation();
00190   
00191   MSG("Geo",Msg::kDebug) << "GetLPosRelMdl " << fStripEndId.AsString() 
00192                          << " lposrelmdl " << trans[0] << endl;
00193 
00194   return trans[0]; 
00195   
00196 }
00197 
00198 //_____________________________________________________________________________
00199 GeoScintPlnNode* GeoStripNode::GetScintPlnNode(void) const{
00200   // Return scint plane node from which this strip descends
00201 
00202   UpdateGlobalManager();
00203 
00204   MSG("Geo",Msg::kDebug) << "GetScintPlnNode " << fStripEndId.AsString() 
00205                          << endl;
00206 
00207   return (GetScintMdlNode()->GetScintPlnNode());
00208   
00209 }
00210 
00211 //_____________________________________________________________________________
00212 Float_t GeoStripNode::GetTPosRelMdl() const {
00213   // Return the tpos relative to module (y-pos from translation matrix)
00214 
00215   MSG("Geo",Msg::kDebug) << fStripEndId.AsString() << endl;
00216 
00217   UpdateGlobalManager();
00218 
00219   const Double_t* trans = GetMatrix() -> GetTranslation();
00220 
00221   return trans[1];
00222   
00223 }
00224 
00225 
00226 //_____________________________________________________________________________
00227 Float_t GeoStripNode::GetZRotRelMdlRad() const {
00228   // Return the zrot relative to module in radians
00229 
00230   MSG("Geo",Msg::kDebug) << fStripEndId.AsString() << endl;
00231 
00232   UpdateGlobalManager();
00233 
00234   const Double_t* rotmatrix = GetMatrix() -> GetRotationMatrix();
00235   Float_t zrotrelmdlrad = TMath::ATan2(rotmatrix[3],rotmatrix[0]);
00236 
00237   return zrotrelmdlrad;
00238    
00239 }
00240 
00241 //_____________________________________________________________________________
00242 Float_t GeoStripNode::GetTPos(Float_t orthCoord) const {
00243   // Get the strip's tpos offset from scint plane origin
00244   // orthCoord is the t-pos in the orthogonal view in ideal scint plane
00245   // coordinates. For example, if this strip is a U-view strip, the orthcoord
00246   // is the tpos in the "ideal" V-view plane coordinates.
00247   // This allows one to include rotation corrections.
00248   // if orthCoord > 100000 (cm) (default), use the center of the strip.
00249 
00250   MSG("Geo",Msg::kDebug) << fStripEndId.AsString() << " orthCoord "
00251                          << orthCoord << endl;
00252 
00253   UpdateGlobalManager();
00254 
00255   // First convert strip center to scint plane coordinates
00256   Double_t striplxyz[3] = {0}; // center of strip
00257   // Convert strip center in strip coordinates to module coordinates
00258   Double_t modulelxyz[3] = {0};
00259   GetMatrix() -> LocalToMaster(striplxyz,modulelxyz);
00260   // Convert strip center in module coordinates to scint plane coordinates
00261   Double_t scplanelxyz[3] = {0};      
00262   GeoScintMdlNode* mdlNode = GetScintMdlNode();
00263   mdlNode -> GetMatrix() -> LocalToMaster(modulelxyz,scplanelxyz);
00264 
00265   // tpos of center of strip
00266   Float_t tpos = scplanelxyz[1];
00267   if ( orthCoord > 100000. ) return tpos;
00268   
00269   // Adjust tpos at orthCoord position for rotation of strip about z-axis
00270   Float_t zrotrelmdlrad = GetZRotRelMdlRad();
00271   Float_t zrotrelplnrad = mdlNode->GetZRotRelPlnRad();
00272   GeoScintPlnNode* scplnNode = GetScintPlnNode();
00273   Float_t zrotrelsteelrad = scplnNode->GetZRotRelSteelRad();
00274 
00275   // Pick the ideal steel plane rotation and subtract it off
00276   Float_t zrotrelsteelideal = 0;
00277   Float_t lpos = orthCoord;
00278   if ( fStripEndId.GetDetector() == Detector::kFar ||
00279        fStripEndId.GetDetector() == Detector::kNear  ) {
00280     if ( fStripEndId.GetPlaneView() == PlaneView::kU ) {
00281       zrotrelsteelideal = -0.785398163; // -45 degrees
00282       lpos = -orthCoord; // lpos is in opposite direction of V-view tpos
00283     }
00284     else if ( fStripEndId.GetPlaneView() == PlaneView::kV ) {
00285       zrotrelsteelideal = +0.785398163; // +45 degrees
00286     }
00287   }
00288   else if ( fStripEndId.GetDetector() == Detector::kCalDet ) {
00289     if ( fStripEndId.GetPlaneView() == PlaneView::kU ) {
00290       zrotrelsteelideal = -1.570796327;
00291       lpos = -orthCoord; // lpos is in opposite direction of V-view tpos
00292     }
00293     else if ( fStripEndId.GetPlaneView() == PlaneView::kV ) {
00294       zrotrelsteelideal = 0;
00295     }
00296   }
00297   
00298   Float_t zrottot = (zrotrelsteelrad - zrotrelsteelideal) + zrotrelplnrad
00299                   +  zrotrelmdlrad;
00300   
00301   Float_t deltatpos = lpos * TMath::Tan(zrottot);
00302   tpos += deltatpos;
00303   
00304   return tpos;
00305   
00306 }
00307 
00308 
00309 
00310 //_____________________________________________________________________________
00311 Float_t GeoStripNode::ClearFiber(StripEnd::StripEnd_t end) const {
00312   // Return clear fiber length of scint module to which this strip belongs
00313 
00314   UpdateGlobalManager();
00315 
00316   Float_t clearfiber = GetScintMdlNode() -> GetClearFiber(end);
00317   
00318   MSG("Geo",Msg::kDebug) << "ClearFiber " << fStripEndId.AsString() << " end "
00319                          << StripEnd::AsString(end) 
00320                          << " clearfiber " << clearfiber << endl;
00321 
00322   return clearfiber;
00323   
00324 }
00325 
00326 //_____________________________________________________________________________
00327 Float_t GeoStripNode::TotalAttenuation(StripEnd::StripEnd_t /* end */,
00328                                        const Float_t /* alongLength */) const {
00329   // Dummy, but also dummy in UgliStripNode.
00330 
00331   UpdateGlobalManager();
00332 
00333   MSG("Geo",Msg::kWarning) 
00334     << "GeoStripNode::TotalAttenuation not implemented yet." << endl;
00335   return 0;
00336   
00337 }
00338 
00339 //_____________________________________________________________________________
00340 Float_t GeoStripNode::DistanceAlong(const PlexStripEndId& orthogonalStrip) 
00341  const{
00342   // Get the distance along a strip represented by the specified orthogonal 
00343   // strip. Note this is relative to the strip's local coordinate system 
00344   // origin.
00345   //
00346   // This strip node is expressed as a line in parametric form:
00347   //     xyz(i) = base(i) + s*dir(i) for i= 0,1,2 (x,y,z)
00348   // where base is LocalToGlobal(TVector3(0,0,0)) 
00349   // and dir is (LocalToGlobal(TVector3(1,0,0)-base)), i.e. the 
00350   // unit vector along the strip length.
00351   // The returned value is "s", the distance along the strip length 
00352   // (measured from the strip local origin) defining the point on 
00353   // this strip with the smallest distance to any point on the orthogonal 
00354   // strip.
00355   //
00356   // The algorithm used here to determine the intersection or closest approach
00357   // of two skew lines is the same as that in R. Hatcher's UgliStripNode, 
00358   // which was adapted from:
00359   //   Graphic Gems, ed. Andrew S. Glassner, pg 304
00360   //   ISBN 0-12-286165-5   T385.G697 (1990)
00361   //
00362   
00363   UpdateGlobalManager();
00364 
00365   const Double_t farAway = 1.0e25;
00366   
00367   GeoStripNode* otherNode = GetGeoGeometry()->GetStripNode(orthogonalStrip);
00368   
00369   if ( !otherNode ) {
00370     MSG("Geo",Msg::kError)
00371       << "GeoStripNode::DistanceAlong(), other strip "
00372       << orthogonalStrip << " does not exist." << endl;
00373     return farAway;
00374   }
00375   
00376   // Define base & dir for this strip
00377   TVector3 baseThis = this -> GlobalPos(0.,false);
00378   TVector3 dirThis = this -> GlobalPos(1.,false) - baseThis; 
00379   
00380   // Define base & dir for the other strip
00381   TVector3 baseOther = otherNode -> GlobalPos(0.,false);
00382   TVector3 dirOther = otherNode -> GlobalPos(1.,false) - baseOther;
00383   
00384   TVector3 dirCross = dirThis.Cross(dirOther);
00385   Double_t dirCrossMag2 = dirCross.Mag2();
00386   if ( dirCrossMag2 == 0.0 ) {
00387     // exactly parallel
00388     return farAway;
00389   }
00390 
00391   TVector3 dp = baseOther - baseThis;
00392   TVector3 dpxv = dp.Cross(dirOther);
00393   Double_t s = dpxv.Dot(dirCross)/dirCrossMag2;
00394   
00395   return s;
00396   
00397 }
00398 
00399 //_____________________________________________________________________________
00400 TVector3 GeoStripNode::Intersection(const PlexStripEndId& orthogonalStrip) 
00401 const {
00402   // Return the 3-d "intersection" of two strips in global coordinates.  
00403   // The intersection is determined as the mid-point of the vector joining 
00404   // the strips at the distance of closest approach.  
00405   //
00406   // The strip nodes are expressed as a line in parametric form:
00407   //     xyz(i) = base(i) + s*dir(i) for i= 0,1,2 (x,y,z) // for this strip
00408   //     xyz(i) = base(i) + t*dir(i) for i= 0,1,2 (x,y,z) // for ortho strip
00409   // where base is LocalToGlobal(TVector3(0,0,0)) 
00410   // and dir is (LocalToGlobal(TVector3(1,0,0)-base)), i.e. the 
00411   // unit vector along the strip length.
00412   // The position along both strips at the distance of closest approach
00413   // is solved for to determine:
00414   //     xyz_s0(i) = base(i) + s0*dir(i) for i= 0,1,2 (x,y,z) //for this strip
00415   //     xyz_t0(i) = base(i) + t0*dir(i) for i= 0,1,2 (x,y,z) //for ortho strip
00416   // The returned mid-point is then:
00417   //     xyz_mid = 0.5*(xyz_s0+xyz_t0)
00418   //
00419   // The algorithm used here to determine the intersection or closest approach
00420   // of two skew lines is the same as that in R. Hatcher's UgliStripNode, 
00421   // which was adapted from:
00422   //   Graphic Gems, ed. Andrew S. Glassner, pg 304
00423   //   ISBN 0-12-286165-5   T385.G697 (1990)
00424   //
00425 
00426   UpdateGlobalManager();
00427 
00428   const Double_t farAway = 1.0e25;
00429   const TVector3 farAway3(farAway,farAway,farAway);
00430 
00431   GeoStripNode* otherNode = GetGeoGeometry()->GetStripNode(orthogonalStrip);
00432   
00433   if ( !otherNode ) {
00434     MSG("Geo",Msg::kError)
00435       << "GeoStripNode::DistanceAlong() other strip "
00436       << orthogonalStrip << " does not exist." << endl;
00437     return farAway3;
00438   }
00439 
00440   // Define base & dir for this strip
00441   TVector3 baseThis = this -> GlobalPos(0.,false);
00442   TVector3 dirThis = this -> GlobalPos(1.,false) - baseThis; 
00443   
00444   // Define base & dir for the other strip
00445   TVector3 baseOther = otherNode -> GlobalPos(0.,false);
00446   TVector3 dirOther = otherNode -> GlobalPos(1.,false) - baseOther;
00447   
00448   TVector3 dirCross = dirThis.Cross(dirOther);
00449   Double_t dirCrossMag2 = dirCross.Mag2();
00450   if ( dirCrossMag2 == 0.0 ) {
00451     // exactly parallel
00452     return 0.5*(baseThis+baseOther) + farAway*dirThis;
00453   }
00454 
00455   TVector3 dp = baseOther - baseThis;
00456   TVector3 dpxvThis = dp.Cross(dirOther);
00457   Double_t s0 = dpxvThis.Dot(dirCross)/dirCrossMag2;
00458 
00459   TVector3 xyz_s0 = baseThis + s0*dirThis;
00460   
00461   dirCross *= -1;
00462   dp       *= -1;
00463   TVector3 dpxvOther = dp.Cross(dirThis);
00464   Double_t t0 = dpxvOther.Dot(dirCross)/dirCrossMag2;
00465   
00466   TVector3 xyz_t0 = baseOther + t0*dirOther;
00467   
00468   return 0.5*(xyz_s0 + xyz_t0);
00469 
00470 }
00471 
00472 //_____________________________________________________________________________
00473 TVector3 GeoStripNode::GlobalPos(const Float_t alongLength,
00474                                  const Bool_t onWLS) const {
00475   // Return position based on distance along centerline *or* WLS fiber
00476   // Position on WLS fiber is not implemented yet, as is also true for
00477   // UgliStripNode.
00478 
00479   MSG("Geo",Msg::kDebug) << fStripEndId.AsString() 
00480                          << " alongLength " << alongLength << endl;
00481 
00482   UpdateGlobalManager();
00483 
00484   if ( onWLS ) {
00485     MSG("Geo",Msg::kWarning) 
00486       << "GeoStripNode::GlobalPos not implemented yet with onWLS = kTRUE."
00487       << " Ignored." << endl;
00488   }
00489   
00490   return LocalToGlobal(TVector3(alongLength,0.,0.));
00491   
00492 }
00493 
00494 //_____________________________________________________________________________
00495 void GeoStripNode::SetZRotRelMdlRad(Float_t /*radians*/) {
00496   // Dummy Set method
00497 
00498   UpdateGlobalManager();
00499 
00500   MSG("Geo",Msg::kWarning) 
00501     << "GeoStripNode::SetZRotRelMdlRad not implemented yet." << endl;
00502   return;
00503   
00504 }
00505 
00506 //_____________________________________________________________________________
00507 void GeoStripNode::SetLTPosRelMdl(Float_t /*lpos*/, Float_t /*tpos*/) {
00508   // Dummy Set method
00509 
00510   UpdateGlobalManager();
00511 
00512   MSG("Geo",Msg::kWarning) 
00513     << "GeoStripNode::SetLTPosRelMdl not implemented yet." << endl;
00514   return;
00515   
00516 }
00517 
00518 
00519 
00520 
00521 
00522 
00523 

Generated on Mon Feb 15 11:06:45 2010 for loon by  doxygen 1.3.9.1