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

PlexPlaneId.cxx

Go to the documentation of this file.
00001 
00002 // $Id: PlexPlaneId.cxx,v 1.42 2007/04/27 14:28:16 rhatcher Exp $
00003 //
00004 // PlexPlaneId
00005 //
00006 // PlexPlaneId encapsulates strip end encoding
00007 //
00008 // Author:  R. Hatcher 2000.11.28
00009 //
00011 
00012 #include "Plex/PlexPlaneId.h"
00013 
00014 #include "Plex/PlexScintMdlId.h"
00015 #include "Plex/PlexVetoShieldHack.h"
00016 
00017 #include <iostream>
00018 #include <iomanip>
00019 #include <string>
00020 
00021 #include <cassert>
00022 
00023 #include "MessageService/MsgService.h"
00024 CVSID("$Id: PlexPlaneId.cxx,v 1.42 2007/04/27 14:28:16 rhatcher Exp $");
00025 
00026 ClassImp(PlexPlaneId)
00027 
00028 //_____________________________________________________________________________
00029 
00030 // define standard geometry values (declared static in header)
00031 //Bool_t PlexPlaneId::fgFarIsUV = false;
00032 //UInt_t PlexPlaneId::fgNumPlnsInFarSM[3] = { 249, 237, 0 };
00033 Bool_t PlexPlaneId::fgCalDetCosmicsAView = false;  // in real life: kB   
00034 
00035 //_____________________________________________________________________________
00036 ostream& operator<<(ostream& os, const PlexPlaneId& p)
00037 {
00038    os << p.AsString();
00039 
00040   return os;
00041 }
00042 
00043 //_____________________________________________________________________________
00044 PlexPlaneId::PlexPlaneId(Detector::Detector_t detector,
00045                          UInt_t plane, Bool_t isSteel,
00046                          PlaneView::PlaneView_t view,
00047                          PlaneCoverage::PlaneCoverage_t coverage)
00048 
00049    : fEncoded(defaultPlexPlaneId)
00050 {
00051    // Normal ctor
00052 
00053    SetDetector(detector);
00054    SetIsSteel(isSteel);
00055    SetPlane(plane,view,coverage);
00056 }
00057 
00058 //_____________________________________________________________________________
00059 const char * PlexPlaneId::AsString(Option_t *option) const
00060 {
00061    // Return unpacked StripEndId as a string
00062    // User should copy result because it points to a 
00063    // statically allocated string.
00064    // Internally uses a circular list of buffers to avoid problems
00065    // using AsString multiple times in a cout-like situation.
00066 
00067    const int nbuffers = 8;   // use a circular list of strings
00068    static char newstring[nbuffers][27]; // = "|123456789|1234 VX|123|SE|";
00069       //                                      12345678901234567890123456
00070    static int  ibuffer = nbuffers;
00071    ibuffer = (ibuffer+1)%nbuffers;  // each time move to next buffer
00072 
00073    Detector::Detector_t det = GetDetector();
00074    char detc                = Detector::AsString(det)[0];
00075    int  ipln                = GetPlane();
00076    char type                = (IsSteel() ? 'P' : 'A'); 
00077    char viewc               = PlaneView::AsString(GetPlaneView())[0];
00078    const char* cover        = PlaneCoverage::AsString(GetPlaneCoverage());
00079 
00080    switch (option[0]) {
00081    case 'b':
00082       // override P/A type with B 
00083       // b is for "box" containing steel+scint (or steel alone if no active)
00084       type = 'B';
00085    default:
00086       // compact rendering identifying only the plane info
00087       if ( Detector::kFar == det && IsVetoShield() ) {
00088         sprintf(newstring[ibuffer],"%c%3.3d%c%c%2.2s",
00089                 detc, ipln, type, viewc, cover);
00090       }
00091       else {
00092         sprintf(newstring[ibuffer],"%c%3.3d%c%c%c",
00093                 detc, ipln, type, viewc, cover[0]);
00094       }
00095       break;
00096    }
00097    
00098    return newstring[ibuffer];
00099 }
00100 
00101 //_____________________________________________________________________________
00102 Bool_t PlexPlaneId::IsValid() const
00103 { 
00104   // test if plane # = all bits on as signal of invalid value
00105   // also fail if IsSteel=false but PlaneCoverage=NoActive
00106   if ( IsNull() ) return false;
00107   if ( ! IsSteel() && 
00108        GetPlaneCoverage() == PlaneCoverage::kNoActive ) return false;
00109   return true;
00110        
00111 }
00112 
00113 //_____________________________________________________________________________
00114 UShort_t PlexPlaneId::NumberOfStrips() const
00115 {
00116   // Expected number of strips for this plane 
00117   // Hard coded values depending on PlaneCoverage and Detector
00118 
00119   if ( IsSteel() ) return 0;  // steel planes have no strips
00120 
00121   switch (GetPlaneCoverage()) {
00122   case (PlaneCoverage::kNoActive):    return   0; // strip on pln w/ no active?
00123   case (PlaneCoverage::kNearPartial): return  68; // 28 + 20 + 20
00124   case (PlaneCoverage::kNearFull):    return  96; // 28 + 20 + 16 + 16 + 16
00125   case (PlaneCoverage::kTotal): {
00126     switch (GetDetector()) {
00127     case (Detector::kFar):        return 192; // 28+28+20+20+20+20+28+28
00128     case (Detector::kCalDet):     return  24;
00129     default:
00130       MSG("Plex",Msg::kWarning) 
00131         << "NumberOfStrips for PlaneCoverage::kTotal "
00132         << "on Detector::k" << Detector::AsString(GetDetector())
00133         << " is not defined" << endl;
00134       return 0;
00135     }
00136     break;
00137   }
00138   case (PlaneCoverage::kVScN):
00139   case (PlaneCoverage::kVSCN):
00140   case (PlaneCoverage::kVSeS):
00141   case (PlaneCoverage::kVSES):
00142   case (PlaneCoverage::kVScS):
00143   case (PlaneCoverage::kVSCS):
00144   case (PlaneCoverage::kVSeN):
00145   case (PlaneCoverage::kVSEN):
00146     return 20;  // all veto shield modules have 20 strips
00147   default:
00148       MSG("Plex",Msg::kWarning) 
00149         << "NumberOfStrips for PlaneCoverage::k" 
00150         << PlaneCoverage::AsString(GetPlaneCoverage())
00151         << " is not defined." << endl;
00152       return 0;
00153   }
00154 }
00155 
00156 //_____________________________________________________________________________
00157 PlexPlaneId PlexPlaneId::GetNext(PlexPlaneId::EPlaneType ptype,
00158                                  PlaneView::PlaneView_t view,
00159                                  PlaneCoverage::PlaneCoverage_t cover) const
00160 {
00161    // Find the next plane id (of type scint, steel or either).
00162    // If beyond end return an invalid id
00163    // Skip planes that don't exist (ie. scint on bookend plane, or
00164    // those in the near spectrometer.
00165    // If view or cover is other than kUnknown then look for that 
00166    // particular type.
00167 
00168    PlexPlaneId next(*this);
00169    while (true) {
00170    moveit:
00171       if (next.IsSteel()) {
00172          // steel means next should be scint of *NEXT* plane
00173          next.SetPlane(next.GetPlane()+1);
00174          next.SetIsSteel(false);
00175          // move along if there is no actual scintillator
00176          if (next.GetPlaneCoverage() == PlaneCoverage::kNoActive) goto moveit;
00177       }
00178       else {
00179          // scint means next should be steel of same plane
00180          next.SetIsSteel(true);
00181       }
00182       bool okview  = ( PlaneView::kUnknown == view ) || 
00183                      ( next.GetPlaneView() == view );
00184       bool okcover = ( PlaneCoverage::kUnknown == cover ) || 
00185                      ( next.GetPlaneCoverage() == cover );
00186       if ( okview && okcover ) {
00187         switch (ptype) {
00188         case PlexPlaneId::kScintOrSteel: 
00189           return next;
00190           break;
00191         case PlexPlaneId::kScint:        
00192           if (!next.IsSteel()) return next; 
00193           break;
00194         case PlexPlaneId::kSteel:
00195           if ( next.IsSteel()) return next;
00196           break;
00197         }
00198       }
00199       if (!next.IsValid()) return next; // beyond the end
00200    }
00201 }
00202 //_____________________________________________________________________________
00203 PlexPlaneId PlexPlaneId::GetPrevious(PlexPlaneId::EPlaneType ptype,
00204                                      PlaneView::PlaneView_t view,
00205                                      PlaneCoverage::PlaneCoverage_t cover) const
00206 {
00207    // Find the previous plane id (of type scint, steel or either).
00208    // If beyond end return an invalid id
00209    // Skip planes that don't exist (ie. scint on bookend plane, or
00210    // those in the near spectrometer.
00211    // If view or cover is other than kUnknown then look for that 
00212    // particular type.
00213 
00214    PlexPlaneId next(*this);
00215    while (true) {
00216    moveit:
00217       if (next.IsSteel()) {
00218          // steel means previous should be scint of same plane
00219          next.SetIsSteel(false);
00220          // move along if there is no actual scintillator
00221          if (next.GetPlaneCoverage() == PlaneCoverage::kNoActive) goto moveit;
00222       }
00223       else {
00224          // scint means next should be steel of *PREVIOUS* plane
00225          next.SetPlane(next.GetPlane()-1);
00226          next.SetIsSteel(true);
00227       }
00228       bool okview  = ( PlaneView::kUnknown == view ) || 
00229                      ( next.GetPlaneView() == view );
00230       bool okcover = ( PlaneCoverage::kUnknown == cover ) || 
00231                      ( next.GetPlaneCoverage() == cover );
00232       if ( okview && okcover ) {
00233         switch (ptype) {
00234         case PlexPlaneId::kScintOrSteel: 
00235           return next;
00236           break;
00237         case PlexPlaneId::kScint:
00238           if (!next.IsSteel()) return next;
00239           break;
00240         case PlexPlaneId::kSteel:
00241           if ( next.IsSteel()) return next;
00242           break;
00243         }
00244       }
00245       if (!next.IsValid()) return next; // beyond the end
00246    }
00247 }
00248 
00249 //_____________________________________________________________________________
00250 UShort_t PlexPlaneId::GetNumStrips() const
00251 {
00252   if (IsSteel() || GetPlaneCoverage()==PlaneCoverage::kNoActive) return 0;
00253   return PlexScintMdlId::GetNumStripsInPln(*this);
00254 }
00255 
00256 UShort_t PlexPlaneId::GetNumScintMdls() const
00257 {
00258   if (IsSteel() || GetPlaneCoverage()==PlaneCoverage::kNoActive) return 0;
00259   return PlexScintMdlId::GetNumScintMdlsInPln(*this);
00260 }
00261 //_____________________________________________________________________________
00262 void PlexPlaneId::Print(Option_t *option) const
00263 {
00264    // Print the (decoded) value
00265 
00266    printf("%s\n",AsString(option));
00267 }
00268 
00269 //_____________________________________________________________________________
00270 
00271 void PlexPlaneId::SetPlane(UInt_t plane,
00272                            PlaneView::PlaneView_t view,
00273                            PlaneCoverage::PlaneCoverage_t coverage)
00274 {
00275    // Set the Plane # (and view, coverage)
00276    // if the view or coverage are unknown (default) then
00277    // use Default values based on detector+plane#
00278    // This is to protect the casual user who diddles with just
00279    // the plane#
00280 
00281    // set everything to invalid if one goes beyond the ends
00282    Detector::Detector_t detector = GetDetector();
00283    Bool_t out_of_range = false;
00284    Bool_t accept_out_of_range = false;
00285    switch (detector) {
00286    case Detector::kNear: 
00287       out_of_range = ( plane > LastPlaneNearSpect() );
00288       break;
00289    case Detector::kFar: {
00290 
00291       // for now simple allow "anything goes" for veto shield stuff
00292       // allow special 511 for UgliDbi*Struct hack
00293       if (plane>=511) { out_of_range = false; break; }
00294 
00295       out_of_range = ( plane > LastPlaneFarSM1() ); 
00296       // some sites might have older DB's that attempt to build
00297       // these non-existent planes ... leading to numerous
00298       // error messages from UgliGeometry.  For now accept them
00299       // but this will change eventually.
00300       // accept_out_of_range = ( plane >= 486 && plane <= 497 );
00301 
00302       break;
00303    }
00304    case Detector::kCalDet: 
00305       out_of_range = (plane > 5*12+4);
00306       break;
00307    default:
00308       out_of_range = false;
00309       break;
00310    }
00311    if (out_of_range) { 
00312      MAXMSG("Plex",Msg::kDebug,20)
00313        << "SetPlane() " << Detector::AsString(detector)
00314        << " plane " << plane << " is out-of-range."
00315        << endl;
00316      if ( ! accept_out_of_range ) {
00317        fEncoded = defaultPlexPlaneId;
00318        return; 
00319      }
00320    }
00321 
00322    // push the plane # into the field
00323    fEncoded = ( fEncoded & ~maskPlexIdPlane ) | 
00324      ( ( plane << shftPlexIdPlane ) & maskPlexIdPlane );   
00325 
00326    // set the view and coverage if they weren't supplied
00327 
00328    if (view == PlaneView::kUnknown) 
00329       view = DefaultPlaneView(detector,plane);
00330    SetPlaneView(view);
00331 
00332    if (coverage == PlaneCoverage::kUnknown) 
00333       coverage = DefaultPlaneCoverage(detector,plane);
00334    SetPlaneCoverage(coverage);
00335 
00336 }
00337 
00338 //_____________________________________________________________________________
00339 PlaneView::PlaneView_t PlexPlaneId::DefaultPlaneView(
00340    Detector::Detector_t detector, UInt_t plane)
00341 {
00342    // Determine plane view given just (detector,plane#)
00343 
00344    static Int_t warn_mask = 0;
00345 
00346    switch (detector) {
00347    case Detector::kNear:
00348       // 0=blank, 1=u, 2=v, 3=u, 4=v ...
00349       // planes 1,6,11... are full coverage
00350       // otherwise if plane<121 partial
00351       // otherwise uninstrumented
00352       if ( plane<1 ||  plane>LastPlaneNearSpect() ||
00353           ( plane>LastPlaneNearCalor() && (plane%5 !=1)) ) {
00354          return PlaneView::kUnknown;
00355       } 
00356       else if (plane%2 == 1) {
00357          return PlaneView::kU;
00358       } 
00359       else {
00360          return PlaneView::kV;
00361       }
00362       break;
00363    case Detector::kFar:
00364    {
00365       // veto shield stuff first
00366       if ( PlexVetoShieldHack::IsMuxPlnVetoShield(plane) ) {
00367         // ambiguous .. "mux" planes cover various views
00368         return PlaneView::kVSUnknown;
00369       }
00370       if ( PlexVetoShieldHack::IsMdlPlnVetoShield(plane) ) {
00371         // little to go on... use semi-bogus context
00372         const VldContext& vldc = PlexVetoShieldHack::GetDefaultContext();
00373         return PlexVetoShieldHack::GetMdlPlaneView(vldc,plane);
00374       }
00375 
00376       // first plane of each of the two SM is blank
00377       UInt_t far_blank[3];
00378       far_blank[0] = 0;
00379       far_blank[1] = LastPlaneFarSM0() + 1;
00380       far_blank[2] = LastPlaneFarSM1() + 1;  // beyond the end
00381 
00382       if ( plane <= far_blank[0] ) return PlaneView::kUnknown;
00383       if ( plane == far_blank[1] ) return PlaneView::kUnknown;
00384       if ( plane >= far_blank[2] ) return PlaneView::kUnknown;
00385 
00386       UInt_t insuper = plane;
00387       if ( plane < far_blank[1] ) {
00388          // nada
00389       }
00390       else {
00391          insuper = plane - far_blank[1];
00392       }
00393 
00394       if (insuper%2 == 1) return PlaneView::kV;
00395       else                return PlaneView::kU;
00396 
00397       break;
00398    }
00399    case Detector::kCalDet:
00400       // 5 supermodules of 12 planes + 4 on floor
00401       // plane 0 is legal, (plane 60 for was for older REROOT)
00402       if ( plane > 5*12+4 || plane == 60 ) {
00403          return PlaneView::kUnknown;
00404       } 
00405       else if ( plane > 5*12 ) {
00406          // floor or "cosmic" planes are 61,62,63,64
00407          return ((fgCalDetCosmicsAView) ? PlaneView::kA : PlaneView::kB ) ;
00408       }
00409       // plane 0 has strips running horizontal (kV)
00410       else if ( plane%2 == 0 ) {
00411          return PlaneView::kV;
00412       } 
00413       else {
00414          return PlaneView::kU;
00415       }
00416       break;
00417    default:
00418       if (! (warn_mask&detector) ) {
00419          MSG("Plex",Msg::kWarning) 
00420          << "PlexPlaneId::DefaultPlaneView "
00421          << "not unique for detector type "
00422          << Detector::AsString(detector) << endl
00423          << "    ... first and only warning " << endl;
00424          warn_mask |= detector;
00425       }
00426 //      assert(0);
00427       break;
00428    }
00429 
00430    return PlaneView::kUnknown;
00431 
00432 }
00433 
00434 //_____________________________________________________________________________
00435 PlaneCoverage::PlaneCoverage_t PlexPlaneId::DefaultPlaneCoverage(
00436    Detector::Detector_t detector, UInt_t plane)
00437 {
00438    // Determine plane coverage given just (detector,plane#)
00439 
00440    static Int_t warn_mask = 0;
00441 
00442    switch (detector) {
00443    case Detector::kNear:
00444       // planes 1,6,11... are full coverage
00445       // otherwise if plane<121 partial
00446       // otherwise uninstrumented
00447 
00448       if ( plane<1 || plane>LastPlaneNearSpect() ) {
00449          return PlaneCoverage::kUninstrumented;
00450       }
00451       else if (plane%5 == 1) {
00452          return PlaneCoverage::kNearFull;
00453       }
00454       else if ( plane<=LastPlaneNearCalor() ) {
00455          return PlaneCoverage::kNearPartial;
00456       }
00457       else {
00458          return PlaneCoverage::kUninstrumented;
00459       }
00460       break;
00461    case Detector::kFar:
00462    {
00463       // veto shield stuff first
00464       if ( PlexVetoShieldHack::IsMuxPlnVetoShield(plane) ) {
00465         // ambiguous .. "mux" planes cover various views
00466         return PlaneCoverage::kUnknown;
00467       }
00468       if ( PlexVetoShieldHack::IsMdlPlnVetoShield(plane) ) {
00469         // little to go on... use semi-bogus context
00470         const VldContext& vldc = PlexVetoShieldHack::GetDefaultContext();
00471         return PlexVetoShieldHack::GetMdlPlaneCoverage(vldc,plane);
00472       }
00473 
00474       // first plane of each SM is blank
00475       UInt_t far_blank[3];
00476       far_blank[0] = 0;
00477       far_blank[1] = LastPlaneFarSM0() + 1;
00478       far_blank[2] = LastPlaneFarSM1() + 1; // beyond the end
00479 
00480       if ( plane <= far_blank[0] ) return PlaneCoverage::kUninstrumented;
00481       if ( plane == far_blank[1] ) return PlaneCoverage::kUninstrumented;
00482       if ( plane >= far_blank[2] ) return PlaneCoverage::kUninstrumented;
00483       return PlaneCoverage::kTotal;
00484 
00485       break;
00486    }
00487    case Detector::kCalDet:
00488       if ( plane > 5*12+4 ) return PlaneCoverage::kUninstrumented;
00489       if ( plane == 60    ) return PlaneCoverage::kUninstrumented;
00490       return PlaneCoverage::kTotal;
00491       break;
00492    default:
00493       if (! (warn_mask&detector) ) {
00494       MSG("Plex",Msg::kWarning) 
00495          << "PlexPlaneId::DefaultPlaneCoverage "
00496          << " not unique for detector type "
00497          << Detector::AsString(detector) << endl
00498          << "    ... first and only warning " << endl;
00499          
00500       warn_mask |= detector;
00501       }
00502 //      assert(0);
00503       break;
00504    }
00505 
00506    return PlaneCoverage::kUnknown;
00507 
00508 }
00509 
00510 //_____________________________________________________________________________
00511 

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