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

Plexus.cxx

Go to the documentation of this file.
00001 
00002 // $Id: Plexus.cxx,v 1.48 2005/07/01 20:10:21 rhatcher Exp $
00003 //
00004 // Plexus
00005 //
00006 // Plexus is an actual connection map
00007 //
00008 // Author:  R. Hatcher 2000.05.03
00009 //
00011 
00012 #include "Plex/Plexus.h"
00013 #include "Plex/PlexLoanPool.h"
00014 
00015 #include "DatabaseInterface/DbiResultPtr.h"
00016 #include "DatabaseInterface/DbiTableProxy.h"
00017 #include "DatabaseInterface/DbiCache.h"
00018 
00019 #include "Plex/PlexPixelSpotToStripEnd.h"
00020 #include "Plex/PlexPixelToRawChannel.h"
00021 #include "Plex/PlexRawChannelReadoutType.h"
00022 #include "Plex/PlexRawChannelToPinDiode.h"
00023 #include "Plex/PlexPinDiodeToLed.h"
00024 #include "Plex/PlexStripEndToLed.h"
00025 
00026 #include "Plex/PlexVetoShieldHack.h"
00027 
00028 #include "MessageService/MsgService.h"
00029 CVSID("$Id: Plexus.cxx,v 1.48 2005/07/01 20:10:21 rhatcher Exp $");
00030 
00031 #include "TSystem.h"
00032 #include "TString.h"
00033 
00034 #include <set>
00035 #include <cassert>
00036 
00037 ClassImp(Plexus)
00038 
00039 Bool_t Plexus::fgAltLHasBrokenFibers = false;
00040 
00041 RawChannelId rcidNull;
00042 
00043 int paranoia = 0;
00044 
00045 //_____________________________________________________________________________
00046 Plexus::Plexus()
00047    : fRef(0), fVldRange(), fBuiltMaps(0)
00048 {
00049    // Default constructor
00050    MSG("Plex",Msg::kVerbose) << "default ctor " << endl;
00051 }
00052 
00053 //_____________________________________________________________________________
00054 Plexus::Plexus(const VldContext& vldc)
00055    : fRef(0), fBuiltMaps(0)
00056 {
00057    // normal constructor
00058    MSG("Plex",Msg::kVerbose) << "Plexus(vldc) ctor " << endl;
00059 
00060    const Int_t mostbits = 0x7fffffff;
00061    const VldTimeStamp longago     = VldTimeStamp((time_t)0,0);
00062    const VldTimeStamp forevermore = VldTimeStamp((time_t)mostbits,999999999);
00063    
00064    fVldRange = VldRange(mostbits,mostbits,longago,forevermore,"");
00065 
00066    const Registry& config = PlexLoanPool::Instance()->GetConfig();
00067    config.Get("Paranoia",paranoia);
00068    if (paranoia) {
00069      MSG("Plex",Msg::kInfo)
00070        << "Plexus(vldc) paranoia level " << paranoia << endl;
00071    }
00072 
00073    // prime veto shield converter table so that
00074    // DBI accounting for PlexPixelSpotToStripEnd is correctly attributed.
00075    if (vldc.GetDetector() == DetectorType::kFar) {
00076      MSG("Plex",Msg::kDebug) 
00077        << "Plexus(vldc) ctor - mux2mdl " << vldc << endl;
00078      DbiResultPtr<PlexVetoShieldMuxToMdl> mux2mdl(vldc);
00079    }
00080 
00081    BuildPixelMaps(vldc);
00082    BuildPinDiodeMap(vldc);
00083    // do Readout Map *after* we know ScintStrips and PinDiodes
00084    BuildReadoutMap(vldc);
00085    BuildLedMaps(vldc);
00086 }
00087 
00088 //_____________________________________________________________________________
00089 Plexus::~Plexus()
00090 {
00091    // delete all the owned sub-objects
00092 
00093 }
00094 
00095 //_____________________________________________________________________________
00096 Bool_t Plexus::IsCompatible(const VldContext &vldc)
00097 {
00098    // check compatibility of this plex with a context
00099 
00100    return fVldRange.IsCompatible(vldc);
00101 
00102 }
00103 
00104 //_____________________________________________________________________________
00105 Bool_t Plexus::IsCompatible(const VldContext *vldc)
00106 {
00107    // check compatibility of this plex with a context
00108 
00109    return fVldRange.IsCompatible(vldc);
00110 
00111 }
00112 
00113 //_____________________________________________________________________________
00114 void Plexus::Print(Option_t *option) const
00115 {
00116    // Print info about this object
00117    cout << " " << TObject::GetName()
00118         << " has " << CountRef() << " references " << endl
00119         << "    " << fVldRange.AsString("a") << endl;
00120 
00121    TString opt(option);
00122    if (opt.Contains("s")) {
00123 
00124      printf("   ChannelToPixel:    %6d   PixelToChannel:     %6d\n",
00125             fChannelToPixel.size(),fPixelToChannel.size());
00126      printf("   PixelToStripEnd:   %6d   StripEndToSpot:     %6d\n",
00127             fPixelToStripEnd.size(),fStripEndToSpot.size());
00128      printf("   ChannelToReadout:  %6d\n",fChannelToReadout.size());
00129      printf("   ChannelToPinDiode: %6d\n",fChannelToPinDiode.size());
00130      printf("   StripEndToLed:     %6d   PinDiodeToLed:      %6d\n",
00131             fStripEndToLed.size(),fPinDiodeToLed.size());
00132 
00133      // classify readout types
00134      if (opt.Contains("r")) {
00135        const vector<RawChannelId>& all_rcid = GetAllRawChannelIds();
00136        printf("   There are %d unique RawChannelIds\n",all_rcid.size());
00137 
00138        std::map<ReadoutType::Readout_t,UInt_t> readoutTypeCount;
00139        for (size_t i=0; i<all_rcid.size(); ++i) {
00140          RawChannelId rcid = all_rcid[i];
00141          ReadoutType::Readout_t rtype = GetReadoutType(rcid);
00142          readoutTypeCount[rtype]++;
00143        }
00144        
00145        std::map<ReadoutType::Readout_t,UInt_t>::const_iterator rtcItr = 
00146          readoutTypeCount.begin();
00147        while ( rtcItr != readoutTypeCount.end() ) {
00148          printf("     %-15s had %5d channels\n",
00149                 ReadoutType::AsString(rtcItr->first),
00150                 rtcItr->second);
00151          rtcItr++;
00152        }
00153      }
00154    }
00155 }
00156 
00157 //_____________________________________________________________________________
00158 RawChannelId Plexus::GetRawChannelId(const PlexStripEndId& seid) const
00159 {
00160    // Convert PlexStripEndId into RawChannelId (m:1 mapping)
00161    
00162   StripEnd::StripEnd_t end = seid.GetEnd();;
00163   if ( StripEnd::kWhole == end || StripEnd::kUnknown == end ) {
00164     MAXMSG("Plex",Msg::kInfo,10)
00165       << "GetRawChannelId called for SEId=" 
00166       << seid << " which has StripEnd either 'Unknown' or 'Whole';"
00167       << " this is unlikely to succeed."
00168       << endl;
00169   }
00170   else {
00171     Detector::Detector_t det = seid.GetDetector();
00172     if ( Detector::kNear == det && StripEnd::kEast == end ) {
00173       MAXMSG("Plex",Msg::kInfo,10)
00174         << "GetRawChannelId called for SEId=" 
00175         << seid << " which has StripEnd of 'East';"
00176         << " this is unlikely to succeed."
00177       << endl;
00178     }    
00179   }
00180 
00181    PlexPixelSpotId psid = fStripEndToSpot[seid];
00182 
00183    // clear the spot value as that isn't used in pixel->channel
00184    psid.SetSpot(0);
00185    return fPixelToChannel[psid];
00186 }
00187 
00188 //_____________________________________________________________________________
00189 RawChannelId Plexus::GetRawChannelId(const PlexPixelSpotId& psid) const
00190 {
00191    // Convert PlexPixelSpotId into RawChannelId (m:1 mapping)
00192    
00193    // clear the spot value as that isn't used in pixel->channel
00194    PlexPixelSpotId psid_nospot = psid;
00195    psid_nospot.SetSpot(0);
00196    return fPixelToChannel[psid_nospot];
00197 }
00198 
00199 //_____________________________________________________________________________
00200 RawChannelId Plexus::GetRawChannelId(const PlexPinDiodeId& diodeid) const
00201 {
00202    // Convert PinDiodeId into a RawChannelId
00203 
00204    // walk through the map looking for a match
00205    // this is slower than the reverse operation but
00206    // means that we don't need a second copy of the information
00207 
00208    typedef map<RawChannelId,PlexPinDiodeId>::const_iterator rc2pd_itr;
00209 
00210    for (rc2pd_itr irc2pd  = fChannelToPinDiode.begin();
00211                   irc2pd != fChannelToPinDiode.end(); ++irc2pd) {
00212       if (irc2pd->second == diodeid) return irc2pd->first;
00213    }
00214 
00215    // nothing appropriate found
00216    return RawChannelId();
00217 }
00218 
00219 //_____________________________________________________________________________
00220 PlexSEIdAltL Plexus::GetSEIdAltL(const RawChannelId& rcid,
00221                                  const PlexCalib* calib,
00222                                  Int_t adc, Double_t time) const
00223 { 
00224    // Convert RawChannelId into PlexStripEndId Alternative List (1:m mapping)
00225 
00226    //MSG("Plex",Msg::kVerbose)
00227    //   << " GetSEIdAltL RCID=" << rcid << ":" << endl;
00228 
00229    PlexSEIdAltL altlist;  // start with empty altlist
00230 
00231    // the map has the {pedestal,spars,common} mode bits off
00232    RawChannelId rcid0 = rcid;
00233    rcid0.ClearModeBits();
00234 
00235    // the near detector spectrometer can map RawChannel to >1 Pixel
00236    // far detector maps each Pixel to more than one StripEnd
00237    // do this as a nested loop over two multimaps
00238 
00239    typedef multimap<RawChannelId,PlexPixelSpotId>::const_iterator   rc2p_itr;
00240    typedef multimap<PlexPixelSpotId,PlexStripEndId>::const_iterator p2se_itr;
00241 
00242    pair<rc2p_itr,rc2p_itr> rc2p_limits = fChannelToPixel.equal_range(rcid0);
00243    for (rc2p_itr irc2p  = rc2p_limits.first; 
00244                  irc2p != rc2p_limits.second; ++irc2p) {
00245       pair<p2se_itr,p2se_itr> p2se_limits = 
00246          fPixelToStripEnd.equal_range(irc2p->second);
00247       for (p2se_itr ip2se  = p2se_limits.first;
00248                     ip2se != p2se_limits.second; ++ip2se) {
00249          PlexStripEndId seid = ip2se->second;
00250          if (seid.IsValid()) {
00251             // look to see if the spot is 0 signalling broken fiber
00252             PlexPixelSpotId spotid = fStripEndToSpot[seid];
00253             if (fgAltLHasBrokenFibers || spotid.GetSpot() != 0) {
00254                altlist.AddStripEndId(seid,spotid,0,calib,adc,time);
00255                //MSG("Plex",Msg::kVerbose)
00256                //    << "    add SEID=" << seid 
00257                //    << " " << seid.GetEncoded()
00258                //    << endl;
00259             }
00260             else {
00261                MSG("Plex",Msg::kVerbose)
00262                    << "    suppress broken fiber SEID=" << seid 
00263                    << " " << seid.GetEncoded()
00264                    << endl;
00265             }
00266          } // seid.IsValid()
00267       } // loop over Pixel->StripEnd
00268    } // loop over RawChannel->Pixel
00269 
00270    return altlist;
00271 }
00272 
00273 //_____________________________________________________________________________
00274 PlexStripEndId Plexus::GetStripEndId(const PlexPixelSpotId& psid) const
00275 { 
00276    // Convert PlexPixelSpotId into a PlexStripEndId (1:1)
00277 
00278    // this is a bit tricky because we've tossed the spot info
00279    // from the multimap fPixelToStripEnd for ease of building
00280    // AltL's, so we need to loop and test the round trip
00281 
00282    typedef multimap<PlexPixelSpotId,PlexStripEndId>::const_iterator p2se_itr;
00283 
00284    PlexPixelSpotId pixelid = psid;
00285    pixelid.SetSpot(0);  // zero out spot info for multimap pixel->seid(s)
00286 
00287    pair<p2se_itr,p2se_itr> p2se_limits = 
00288       fPixelToStripEnd.equal_range(pixelid);
00289    for (p2se_itr ip2se  = p2se_limits.first;
00290                  ip2se != p2se_limits.second; ++ip2se) {
00291       PlexStripEndId seid = ip2se->second;
00292       // check that this leads back to the *spot* we were given
00293       PlexPixelSpotId testspot = fStripEndToSpot[seid];
00294       if (testspot == psid) return seid;
00295    }
00296 
00297    return PlexStripEndId();  // no match
00298 
00299 }
00300 
00301 //_____________________________________________________________________________
00302 vector<PlexPixelSpotId> Plexus::GetPixelSpotIdVector(const RawChannelId& rcid, 
00303                                                      bool uniquePixels) const
00304 { 
00305    // Convert RawChannelId into a vector of PlexPixelSpotId's 
00306    // if uniquePixels=true then set spot=0 (1:m) and return
00307    // a list of *pixels* not pixel-spots.
00308    //
00309    // RawChannelId may not map to single Pixel in the case of
00310    // near detector.  
00311 
00312    vector<PlexPixelSpotId> pixelspots;
00313  
00314   if (uniquePixels) {
00315 
00316      // the map has the {pedestal,spars,common} mode bits off
00317      RawChannelId rcid0 = rcid;
00318      rcid0.ClearModeBits();
00319      
00320      typedef multimap<RawChannelId,PlexPixelSpotId>::const_iterator   rc2p_itr;
00321      
00322      pair<rc2p_itr,rc2p_itr> rc2p_limits = fChannelToPixel.equal_range(rcid0);
00323      for (rc2p_itr irc2p  = rc2p_limits.first; 
00324           irc2p != rc2p_limits.second; ++irc2p) {
00325        PlexPixelSpotId aspot = irc2p->second;
00326        pixelspots.push_back(aspot);
00327      }
00328 
00329    }
00330    else {
00331      // return all spots, even if the pixel part isn't unique
00332      // take the easy road out and use existing mechanism
00333      PlexSEIdAltL altl = this->GetSEIdAltL(rcid);
00334      for (size_t i=0; i < altl.size(); ++i) 
00335        pixelspots.push_back(altl[i].GetPixelSpotId());
00336    }
00337 
00338   return pixelspots;
00339 }
00340 
00341 //_____________________________________________________________________________
00342 PlexPixelSpotId Plexus::GetPixelSpotId(const PlexStripEndId& seid) const
00343 { 
00344    // Convert PlexStripEndId into a PlexPixelSpotId (1:1)
00345 
00346    return fStripEndToSpot[seid];
00347 }
00348 
00349 //_____________________________________________________________________________
00350 PlexPinDiodeId Plexus::GetPinDiodeId(const RawChannelId& rcid) const
00351 {
00352    // Convert RawChannelId into PlexPinDiodeId (if possible)
00353 
00354    // the map has the {pedestal,spars,common} mode bits off
00355    RawChannelId rcid0 = rcid;
00356    rcid0.ClearModeBits();
00357 
00358    return fChannelToPinDiode[rcid0];
00359 }
00360 
00361 //_____________________________________________________________________________
00362 ReadoutType::Readout_t Plexus::GetReadoutType(const RawChannelId& rcid) const
00363 { 
00364    // Determine what (eg. scint strip, pin diode, cerenkov, tof) 
00365    // is attached to raw channel
00366 
00367    if ( rcid == rcidNull ) return ReadoutType::kUnknown;
00368 
00369    // deal with special case of VA common mode rejection channels
00370    // no need to explicitly test for electronics type as unpacker does
00371    // (returns -1 if not a VA channel)
00372    switch (rcid.GetVaChannel()) {
00373    case  0:
00374    case  1:
00375    case 19:
00376    case 20:
00377    case 21:
00378       return ReadoutType::kVACommonMode;
00379       break;
00380    }
00381 
00382    // the map has the {pedestal,spars,common} mode bits off
00383    RawChannelId rcid0 = rcid;
00384    rcid0.ClearModeBits();
00385 
00386    // ideally this mapping would be to ReadoutType::Readout_t
00387    // but cint can't correctly handle enum as as second type of map
00388    // so use UShort_t (must be > 8 bits to correctly hold all Readout_t values)
00389 
00390    return (ReadoutType::Readout_t)fChannelToReadout[rcid0];
00391 
00392 }
00393 
00394 //_____________________________________________________________________________
00395 std::string Plexus::GetSpecialDescript(const RawChannelId& rcid) const
00396 {
00397    // if a special channel (Cerenkov, TOF, etc) from the 
00398    // PLEXRAWCHANNELREADOUTTYPE table return the associated string
00399    RawChannelId rcid0 = rcid;
00400    rcid0.ClearModeBits();
00401 
00402    return fSpecialDescript[rcid0];
00403 }
00404 //_____________________________________________________________________________
00405 RawChannelId Plexus::GetSpecialChannelContains(const std::string& key)const
00406 {
00407    // look for a special channel description string that contains
00408    // the passed key.  Allowing one to distinguish between different
00409    // special channels of the same readout type by extending what
00410    // is put in the PLEXRAWCHANNELREADOUTTYPE table
00411 
00412   typedef map<RawChannelId,std::string>::const_iterator rc2string_itr;
00413   for (rc2string_itr irc2s  = fSpecialDescript.begin();
00414                      irc2s != fSpecialDescript.end(); ++ irc2s) {
00415     // lazy approach ... use TString's Contains() to do work
00416     TString description(irc2s->second.c_str());
00417     if (description.Contains(key.c_str())) return irc2s->first;
00418   }
00419   return RawChannelId();
00420 
00421 }
00422 //_____________________________________________________________________________
00423 std::vector<PlexStripEndId> 
00424 Plexus::GetStripEndIdVector(const PlexLedId& ledid) const
00425 {
00426    // Convert PlexLedId into a vector of PlexStripEndId's (1:m)
00427 
00428    vector<PlexStripEndId> stripends;
00429 
00430    typedef map<PlexStripEndId,PlexLedId>::const_iterator se2led_itr;
00431 
00432    for (se2led_itr ise2led  = fStripEndToLed.begin();
00433                    ise2led != fStripEndToLed.end(); ++ise2led) {
00434       if (ise2led->second == ledid) stripends.push_back(ise2led->first);
00435    }
00436 
00437    return stripends;
00438 }
00439 
00440 //_____________________________________________________________________________
00441 std::pair<PlexPinDiodeId,PlexPinDiodeId> 
00442 Plexus::GetPinDiodeIds(const PlexLedId& ledid) const
00443 {
00444    // Convert PlexLedId into a pair of PlexPinDiodeId's (1:[1,2])
00445 
00446    pair<PlexPinDiodeId,PlexPinDiodeId> diodepair;
00447    PlexPinDiodeId high_gain;
00448    PlexPinDiodeId low_gain;
00449 
00450    typedef map<PlexPinDiodeId,PlexLedId>::const_iterator pd2led_itr;
00451 
00452    for (pd2led_itr ipd2led  = fPinDiodeToLed.begin();
00453                    ipd2led != fPinDiodeToLed.end(); ++ipd2led) {
00454       if (ipd2led->second == ledid) {
00455          PlexPinDiodeId pinid = ipd2led->first;
00456          if (pinid.GetGain()) {
00457             // high gain pin diode
00458             if (!high_gain.IsValid()) high_gain = pinid;
00459             else {
00460                // this shouldn't happen
00461                MSG("Plex",Msg::kError) 
00462                   << "GetPinDiodeIds already found high gain "
00463                   << high_gain.AsString()
00464                   << " before " << pinid.AsString() 
00465                   << ", ignore new " << endl;
00466             }
00467          }
00468          else {
00469             // low gain pin diode
00470             if (!low_gain.IsValid()) low_gain = pinid;
00471             else {
00472                // this shouldn't happen
00473                MSG("Plex",Msg::kError) 
00474                   << "GetPinDiodeIds already found low gain "
00475                   << low_gain.AsString()
00476                   << " before " << pinid.AsString() 
00477                   << ", ignore new " << endl;
00478             }
00479          }
00480       }
00481    }
00482 
00483 
00484    diodepair.first = high_gain;
00485    diodepair.second = low_gain;
00486    return diodepair;
00487 }
00488 
00489 //_____________________________________________________________________________
00490 PlexLedId Plexus::GetLedId(const PlexStripEndId& seid) const
00491 {
00492    // Convert PlexStripEndId into a PlexLedId (N:1)
00493 
00494    return fStripEndToLed[seid];
00495 }
00496 
00497 //_____________________________________________________________________________
00498 PlexLedId Plexus::GetLedId(const PlexPinDiodeId& diodeid) const
00499 {
00500    // Convert PlexPinDiodeId into a PlexLedId (N:1)
00501 
00502    return fPinDiodeToLed[diodeid];
00503 }
00504 
00505 //_____________________________________________________________________________
00506 const std::vector<PlexStripEndId>&
00507 Plexus::GetAllStripEnds(StripEnd::StripEnd_t restrictEnd) const
00508 { 
00509   // Return (build if necessary) a list of legal PlexStripEndIds
00510   // If restrictEnd is kEast or kWest limit list to that end
00511   // If restrictEnd is kWhole force ids to be only for whole strip
00512   //     (and eliminate duplicates)
00513 
00514   std::vector<PlexStripEndId>* thevector = 0;
00515   switch (restrictEnd) {
00516   case StripEnd::kEast:  thevector = &fAllEastEnds;  break;
00517   case StripEnd::kWest:  thevector = &fAllWestEnds;  break;
00518   case StripEnd::kWhole: thevector = &fAllStrips;    break;
00519   default:               thevector = &fAllStripEnds; break;
00520   }
00521 
00522   if ( thevector->empty() ) {
00523 
00524     // we need to fill the vector
00525 
00526     typedef map<PlexStripEndId,PlexPixelSpotId>::const_iterator se2spot_itr;
00527     se2spot_itr seItr    = fStripEndToSpot.begin();
00528     se2spot_itr seItrEnd = fStripEndToSpot.end();
00529     
00530     PlexStripEndId seidLast;
00531     
00532     for ( ; seItr != seItrEnd; ++seItr) {
00533       PlexStripEndId seid = seItr->first;
00534       switch (restrictEnd) {
00535         // if a particular side is chosen only add those
00536       case StripEnd::kEast:
00537       case StripEnd::kWest:
00538         if ( seid.GetEnd() != restrictEnd ) continue;
00539         break;
00540       case StripEnd::kWhole:
00541         seid.SetEnd(StripEnd::kWhole);  // for whole-ness
00542         // this next test is under the assumption that the PlexStripEndId
00543         // sorts ends of the same strips to consecutive places in the map
00544         // otherwise we'd have to be constructing a std::set to guarentee
00545         // uniqueness of the strips (or do ever lengthening searches)
00546         if ( seid == seidLast ) continue;
00547         seidLast = seid;
00548         break;
00549       default:
00550         // just add it with no restrictions
00551         break;
00552       }
00553       // add to the list
00554       thevector->push_back(seid);
00555     }
00556     
00557   }
00558 
00559   return *thevector;
00560 }
00561 
00562 //_____________________________________________________________________________
00563 const std::vector<PlexPixelSpotId>& 
00564 Plexus::GetAllPixelSpotIds(Plexus::ETrimSpots trim) const
00565 {
00566   // Return (build if necessary) a list of legal spots, pixels, tubes
00567   // If restrictEnd is kEast or kWest limit list to that end
00568   // If restrictEnd is kWhole force ids to be only for whole strip
00569   //     (and eliminate duplicates)
00570 
00571   std::vector<PlexPixelSpotId>* thevector = 0;
00572   switch (trim) {
00573   case kIncludeTube:  thevector = &fAllTubes;   break;
00574   case kIncludePixel: thevector = &fAllPixels;  break;
00575   default:            thevector = &fAllSpots;   break;
00576   }
00577 
00578   if ( thevector->empty() ) {
00579 
00580     // we need to fill the vector
00581     // but use an intermediate set to force uniqueness and ordering
00582     // based on normal PlexPixelSpotId order
00583    
00584     typedef std::map<PlexStripEndId,PlexPixelSpotId>::const_iterator se2spot_itr;
00585     se2spot_itr seItr    = fStripEndToSpot.begin();
00586     se2spot_itr seItrEnd = fStripEndToSpot.end();
00587     
00588     std::set<PlexPixelSpotId> spotSet;
00589     
00590     for ( ; seItr != seItrEnd; ++seItr) {
00591       PlexPixelSpotId spot = seItr->second;
00592       switch (trim) {
00593         // rely on fall through
00594       case kIncludeTube:  spot.SetPixel(0);
00595       case kIncludePixel: spot.SetSpot(0);
00596       default:            break;
00597       }
00598       // add to the set, let it take care of uniqueness
00599       spotSet.insert(spot);
00600     }
00601 
00602     // copy set values into vector
00603     typedef std::set<PlexPixelSpotId>::iterator spotset_itr;
00604     spotset_itr spotItr    = spotSet.begin();
00605     spotset_itr spotItrEnd = spotSet.end();
00606     for ( ; spotItr != spotItrEnd; ++spotItr)
00607       thevector->push_back(*spotItr);
00608   }
00609 
00610   return *thevector;
00611 }
00612 
00613 
00614 //_____________________________________________________________________________
00615 const std::vector<RawChannelId>& 
00616 Plexus::GetAllRawChannelIds() const
00617 {
00618   // Return (build if necessary) a list of legal RawChannelIds
00619 
00620   if ( fAllChannels.empty() ) {
00621 
00622     // we need to fill the vector
00623     // but use an intermediate set to force uniqueness and ordering
00624     // base on normal RawChannelId order
00625 
00626     std::set<RawChannelId> rcidSet;
00627     
00628     // fill from mapping of channels to pixels
00629     typedef std::map<RawChannelId,PlexPixelSpotId>::const_iterator rc2pixel_itr;
00630     rc2pixel_itr rcpxItr    = fChannelToPixel.begin();
00631     rc2pixel_itr rcpxItrEnd = fChannelToPixel.end();
00632     for ( ; rcpxItr != rcpxItrEnd; ++rcpxItr) rcidSet.insert(rcpxItr->first);
00633 
00634     //
00635     typedef std::map<RawChannelId,PlexPinDiodeId>::const_iterator rc2pin_itr;
00636     rc2pin_itr rcpinItr    = fChannelToPinDiode.begin();
00637     rc2pin_itr rcpinItrEnd = fChannelToPinDiode.end();
00638     for ( ; rcpinItr != rcpinItrEnd; ++rcpinItr) rcidSet.insert(rcpinItr->first);
00639     // 
00640     typedef std::map<RawChannelId,UShort_t>::const_iterator rc2type_itr;
00641     rc2type_itr rctypeItr    = fChannelToReadout.begin();
00642     rc2type_itr rctypeItrEnd = fChannelToReadout.end();
00643     for ( ; rctypeItr != rctypeItrEnd; ++rctypeItr) rcidSet.insert(rctypeItr->first);
00644 
00645     //
00646     typedef std::map<RawChannelId,std::string>::const_iterator rc2desc_itr;
00647     rc2desc_itr rcdescItr    = fSpecialDescript.begin();
00648     rc2desc_itr rcdescItrEnd = fSpecialDescript.end();
00649     for ( ; rcdescItr != rcdescItrEnd; ++rcdescItr) rcidSet.insert(rcdescItr->first);
00650     
00651 
00652     // copy set values into vector
00653     typedef std::set<RawChannelId>::iterator rcidset_itr;
00654     rcidset_itr rcidItr    = rcidSet.begin();
00655     rcidset_itr rcidItrEnd = rcidSet.end();
00656     for ( ; rcidItr != rcidItrEnd; ++rcidItr)
00657       fAllChannels.push_back(*rcidItr);
00658 
00659   }
00660   return fAllChannels;
00661 }
00662 
00663 
00664 //_____________________________________________________________________________
00665 const std::vector<PlexPinDiodeId>& 
00666 Plexus::GetAllPinDiodes() const
00667 {
00668   // Return (build if necessary) a list of legal PlexPindDiodeIds
00669 
00670   if ( fAllPinDiodes.empty() ) {
00671 
00672     // we need to fill the vector
00673     // but use an intermediate set to force uniqueness and ordering
00674     // base on normal PlexPinDiodeId order
00675 
00676     std::set<PlexPinDiodeId> pindSet;
00677     
00678     // fill from list of raw channel list mapped to pin diodes
00679     typedef std::map<RawChannelId,PlexPinDiodeId>::const_iterator rc2pin_itr;
00680     rc2pin_itr rcpinItr    = fChannelToPinDiode.begin();
00681     rc2pin_itr rcpinItrEnd = fChannelToPinDiode.end();
00682     for ( ; rcpinItr != rcpinItrEnd; ++rcpinItr) pindSet.insert(rcpinItr->second);
00683 
00684     // fill fromlist of pin diodes mapped to leds
00685     typedef std::map<PlexPinDiodeId,PlexLedId>::const_iterator pin2led_itr;
00686     pin2led_itr pinledItr    = fPinDiodeToLed.begin();
00687     pin2led_itr pinledItrEnd = fPinDiodeToLed.end();
00688     for ( ; pinledItr != pinledItrEnd; ++pinledItr) pindSet.insert(pinledItr->first);
00689 
00690     // copy set values into vector
00691     typedef std::set<PlexPinDiodeId>::iterator pindset_itr;
00692     pindset_itr pindItr    = pindSet.begin();
00693     pindset_itr pindItrEnd = pindSet.end();
00694     for ( ; pindItr != pindItrEnd; ++pindItr)
00695       fAllPinDiodes.push_back(*pindItr);
00696 
00697   }
00698   return fAllPinDiodes;
00699 }
00700 
00701 
00702 //_____________________________________________________________________________
00703 const std::vector<PlexLedId>& 
00704 Plexus::GetAllLeds() const
00705 {
00706   // Return (build if necessary) a list of legal PlexLedIds
00707 
00708   if ( fAllLeds.empty() ) {
00709 
00710     // we need to fill the vector
00711     // but use an intermediate set to force uniqueness and ordering
00712     // base on normal PlexLedId order
00713 
00714     std::set<PlexLedId> ledSet;
00715     
00716     // fill from mapping of stripends to leds
00717     typedef std::map<PlexStripEndId,PlexLedId>::const_iterator seid2led_itr;
00718     seid2led_itr seledItr    = fStripEndToLed.begin();
00719     seid2led_itr seledItrEnd = fStripEndToLed.end();
00720     for ( ; seledItr != seledItrEnd; ++seledItr) ledSet.insert(seledItr->second);
00721 
00722     // fill from mapping of pindiodes to leds
00723     typedef std::map<PlexPinDiodeId,PlexLedId>::const_iterator pind2led_itr;
00724     pind2led_itr pinledItr    = fPinDiodeToLed.begin();
00725     pind2led_itr pinledItrEnd = fPinDiodeToLed.end();
00726     for ( ; pinledItr != pinledItrEnd; ++pinledItr) ledSet.insert(pinledItr->second);
00727 
00728     // copy set values into vector
00729     typedef std::set<PlexLedId>::iterator ledset_itr;
00730     ledset_itr ledItr    = ledSet.begin();
00731     ledset_itr ledItrEnd = ledSet.end();
00732     for ( ; ledItr != ledItrEnd; ++ledItr)
00733       fAllLeds.push_back(*ledItr);
00734 
00735   }
00736   return fAllLeds;
00737 }
00738 
00739 
00740 //_____________________________________________________________________________
00741 void Plexus::LoadRDBCHack() const
00742 {
00743    static Bool_t first = true;
00744    if (!first) return;
00745    first = false;
00746 
00747 #ifdef MINOS_PROFILE
00748    MSG("Plex",Msg::kWarning)
00749       << " skip dynamic loading of libRDBC.so" << endl;
00750 #else
00751 #ifdef KEEP_SILLY_HACK
00752    MSG("Plex",Msg::kWarning)
00753       << " silly hack for libRDBC.so, expect this message once"
00754       << endl;
00755    gSystem->Load("libRDBC.so");
00756 #endif
00757 #endif
00758 }
00759 
00760 //_____________________________________________________________________________
00761 void Plexus::BuildPixelMaps(const VldContext& vldc) const
00762 { 
00763    // build the basic maps   RawChannel <--> PixelSpot <--> StripEnd
00764 
00765    if (kPixelMaps & fBuiltMaps) return;
00766    fBuiltMaps |= kPixelMaps;
00767    LoadRDBCHack();
00768 
00769    DbiCache* pstoseTblCache = 0;
00770    DbiCache* ptorcTblCache = 0;
00771 
00772    {
00773       // start of inner scope to that DbiResultPtr's will die, die, die
00774       // and thus Purge will see no remaining clients
00775       
00776       DbiResultPtr<PlexPixelSpotToStripEnd> pstoseResPtr(vldc);
00777       DbiResultPtr<PlexPixelToRawChannel>   ptorcResPtr(vldc);
00778 
00779       // update the fVldRange
00780       TrimVldRange("PlexPixelSpotToStripEnd",pstoseResPtr.GetValidityRec());
00781       TrimVldRange("PlexPixelToRawChannel",ptorcResPtr.GetValidityRec());
00782 
00783       // get a handle for the caches
00784       pstoseTblCache = pstoseResPtr.TableProxy().GetCache();
00785       ptorcTblCache = ptorcResPtr.TableProxy().GetCache();
00786 
00787       // how many rows did we get?
00788       UInt_t npstose = pstoseResPtr.GetNumRows();
00789       UInt_t nptorc  = ptorcResPtr.GetNumRows();
00790 
00791       // complain bitterly if either is zero
00792       // this is indicative of a serious database problem
00793       if (npstose == 0)
00794         MSG("Plex",Msg::kFatal)
00795           << "No entries retrieved from PlexPixelSpotToStripEnd table." 
00796           << endl;
00797       if (nptorc == 0)
00798         MSG("Plex",Msg::kFatal)
00799           << "No entries retrieved from PlexPixelToRawChannel table." 
00800           << endl;
00801 
00802       // build the maps:  PixelSpot <--> StripEnd 
00803       for (UInt_t irow = 0; irow < npstose; ++irow) {
00804          const PlexPixelSpotToStripEnd* pstose = pstoseResPtr.GetRow(irow);
00805          PlexPixelSpotId spotid = pstose->GetPlexPixelSpotId();
00806          PlexStripEndId    seid = pstose->GetPlexStripEndId();
00807 
00808          bool isokay_pstose = true;
00809          if ( paranoia ) { 
00810            if ( fStripEndToSpot.find(seid) != fStripEndToSpot.end() ) {
00811              isokay_pstose = false;
00812              if ( paranoia > 1 || seid.GetPlane() != 1023 ) 
00813                MSG("Plex",Msg::kInfo) 
00814                  << "BuildPixelMaps StripEnd "
00815                  << seid.AsString("c") 
00816                  << endl
00817                  << "   attached to PixelSpot "
00818                  << fStripEndToSpot[seid].AsString("c")
00819                  << endl
00820                  << "   new PixelSpot entry   "
00821                  << spotid.AsString("c")
00822                  << endl;
00823            }
00824          }
00825          
00826          if (isokay_pstose) {
00827            fStripEndToSpot[seid]   = spotid;
00828            // for multimap sake throw away the "spot" info in this direction
00829            PlexPixelSpotId pixelid = spotid;
00830            pixelid.SetSpot(0);
00831            fPixelToStripEnd.insert(make_pair(pixelid,seid));
00832          }
00833       }
00834 
00835       // build the maps:  PixelSpot <--> RawChannel
00836       for (UInt_t irow = 0; irow < nptorc; ++irow) {
00837          const PlexPixelToRawChannel* ptorc = ptorcResPtr.GetRow(irow);
00838          PlexPixelSpotId pixelid = ptorc->GetPlexPixelSpotId();
00839          RawChannelId       rcid = ptorc->GetRawChannelId();
00840          // the map has the {pedestal,spars,common} mode bits off
00841          rcid.ClearModeBits();
00842          
00843          // ensure that pixelid doesn't have "spot" field filled
00844          // in either direction
00845          pixelid.SetSpot(0);
00846          
00847          bool isokay_ptorc = true;
00848          if ( paranoia ) {
00849            if ( fPixelToChannel.find(pixelid) != fPixelToChannel.end() ) {
00850              isokay_ptorc = false;
00851              MSG("Plex",Msg::kInfo) 
00852                << "BuildPixelMaps Pixel "
00853                << pixelid.AsString("p") 
00854                << endl
00855                << "   attached to RawChannel "
00856                << fPixelToChannel[pixelid].AsString("ec")
00857                << endl
00858                << "   new RawChannel entry   "
00859                << rcid.AsString("ec")
00860                << endl;
00861            }
00862          }
00863 
00864          if (isokay_ptorc) {
00865            fPixelToChannel[pixelid] = rcid;
00866            fChannelToPixel.insert(make_pair(rcid,pixelid));
00867          }
00868       }
00869 
00870    }
00871 
00872    if ( PlexLoanPool::Instance()->PurgeDbiTableCache() ) {
00873      // now there should be no active clients so it should be
00874      // possible to purge to our heart's content
00875      if (pstoseTblCache) pstoseTblCache->Purge();
00876      if (ptorcTblCache) ptorcTblCache->Purge();
00877    }
00878 
00879    return;
00880 }
00881 
00882 //_____________________________________________________________________________
00883 void Plexus::BuildReadoutMap(const VldContext& vldc) const
00884 { 
00885    // build the basic map:  RawChannel --> ReadoutType
00886 
00887    if (kReadoutMap & fBuiltMaps) return;
00888    fBuiltMaps |= kReadoutMap;
00889    LoadRDBCHack();
00890 
00891    DbiCache* rcrtTblCache = 0;
00892 
00893    {
00894       // start of inner scope to that DbiResultPtr's will die, die, die
00895       // and thus Purge will see no remaining clients
00896 
00897       DbiResultPtr<PlexRawChannelReadoutType> rcrtResPtr(vldc);
00898 
00899       // update the fVldRange
00900       TrimVldRange("PlexRawChannelReadoutType",rcrtResPtr.GetValidityRec());
00901 
00902       // get a handle for the cache
00903       rcrtTblCache = rcrtResPtr.TableProxy().GetCache();
00904 
00905       // build the map:  RawChannel --> ReadoutType
00906       for (UInt_t irow = 0; irow < rcrtResPtr.GetNumRows(); ++irow) {
00907          const PlexRawChannelReadoutType* rcrt = rcrtResPtr.GetRow(irow);
00908          RawChannelId            rcid = rcrt->GetRawChannelId();
00909          ReadoutType::Readout_t rtype = rcrt->GetReadoutType();
00910          // the map has the {pedestal,spars,common} mode bits off
00911          rcid.ClearModeBits();
00912          
00913          fChannelToReadout[rcid] = rtype;
00914          fSpecialDescript[rcid] = rcrt->GetDescript();
00915       }
00916 
00917       // use RawChannel->Pixel to make additions
00918       BuildPixelMaps(vldc);
00919       typedef multimap<RawChannelId,PlexPixelSpotId>::const_iterator rc2ps_itr;
00920       for (rc2ps_itr irc2ps  = fChannelToPixel.begin();
00921            irc2ps != fChannelToPixel.end(); ++irc2ps) {
00922          RawChannelId rcid = irc2ps->first;
00923          // the map has the {pedestal,spars,common} mode bits off
00924          rcid.ClearModeBits();
00925          
00926          // Change NJT 29/8/03: Only set kScintStrip if there
00927          // is no previous type set. This ensures the DB always wins.
00928          // Useful for the 'UnconnectedPixel' type.
00929          if(fChannelToReadout.find(rcid)==fChannelToReadout.end()) 
00930            fChannelToReadout[rcid] = ReadoutType::kScintStrip;       
00931       }
00932 
00933    }
00934 
00935    if ( PlexLoanPool::Instance()->PurgeDbiTableCache() ) {
00936      // now there should be no active clients so it should be
00937      // possible to purge to our heart's content
00938      if (rcrtTblCache) rcrtTblCache->Purge();
00939    }
00940 
00941    // use RawChannel->PinDiode to make additions
00942    BuildPinDiodeMap(vldc);
00943    typedef map<RawChannelId,PlexPinDiodeId>::const_iterator rc2pd_itr;
00944    for (rc2pd_itr irc2pd  = fChannelToPinDiode.begin();
00945                   irc2pd != fChannelToPinDiode.end(); ++irc2pd) {
00946       RawChannelId rcid = irc2pd->first;
00947       // the map has the {pedestal,spars,common} mode bits off
00948       rcid.ClearModeBits();
00949 
00950       fChannelToReadout[rcid] = ReadoutType::kPinDiode;
00951    }
00952 
00953    return;
00954 }
00955 
00956 //_____________________________________________________________________________
00957 void Plexus::BuildPinDiodeMap(const VldContext& vldc) const
00958 { 
00959    // build the basic map:  RawChannel --> PinDiode
00960 
00961    if (kPinDiodeMap & fBuiltMaps) return;
00962    fBuiltMaps |= kPinDiodeMap;
00963    LoadRDBCHack();
00964 
00965    DbiCache* rc2pdTblCache = 0;
00966 
00967    {
00968       // start of inner scope to that DbiResultPtr's will die, die, die
00969       // and thus Purge will see no remaining clients
00970 
00971       DbiResultPtr<PlexRawChannelToPinDiode> rc2pdResPtr(vldc);
00972 
00973       // update the fVldRange
00974       TrimVldRange("PlexRawChannelToPinDiode",rc2pdResPtr.GetValidityRec());
00975 
00976       // get a handle for the cache
00977       rc2pdTblCache = rc2pdResPtr.TableProxy().GetCache();
00978 
00979       std::set<PlexPinDiodeId> pins_seen;  // local temp for paranoia checking
00980 
00981       // build the map:  RawChannel --> PinDiode
00982       for (UInt_t irow = 0; irow < rc2pdResPtr.GetNumRows(); ++irow) {
00983          const PlexRawChannelToPinDiode* rc2pd = rc2pdResPtr.GetRow(irow);
00984          RawChannelId    rcid = rc2pd->GetRawChannelId();
00985          PlexPinDiodeId pinid = rc2pd->GetPlexPinDiodeId();
00986 
00987          // the map has the {pedestal,spars,common} mode bits off
00988          rcid.ClearModeBits();
00989 
00990          // 
00991          if ( ! paranoia ) { fChannelToPinDiode[rcid] = pinid; }
00992          else {
00993            if ( fChannelToPinDiode.find(rcid) == fChannelToPinDiode.end() ) {
00994              if ( pins_seen.find(pinid) == pins_seen.end() ) {
00995                fChannelToPinDiode[rcid] = pinid;             
00996                pins_seen.insert(pinid);
00997              }
00998              else {
00999                RawChannelId rcid_already = GetRawChannelId(pinid);
01000                MSG("Plex",Msg::kInfo) 
01001                  << "BuildPinDiodeMap PinDiode "
01002                  << pinid.AsString("c") 
01003                  << endl
01004                  << "   attached to RawChannel "
01005                  << rcid_already.AsString("ec")
01006                  << endl
01007                  << "   new RawChannel entry   "
01008                  << rcid.AsString("ec")
01009                  << endl;
01010              }
01011            }
01012            else {
01013              MSG("Plex",Msg::kInfo) 
01014                << "BuildPinDiodeMap RawChannelId "
01015                << rcid.AsString("ec") 
01016                << endl
01017                << "    attached to PinDiode " 
01018                << fChannelToPinDiode[rcid].AsString("c")
01019                << endl
01020                << "    new PinDiode entry   "
01021                << pinid.AsString("c")
01022                << endl;
01023            }
01024          }
01025 
01026       }
01027 
01028    }
01029 
01030    if ( PlexLoanPool::Instance()->PurgeDbiTableCache() ) {
01031      // now there should be no active clients so it should be
01032      // possible to purge to our heart's content
01033      if (rc2pdTblCache) rc2pdTblCache->Purge();
01034    }
01035 
01036    return;
01037 }
01038 
01039 //_____________________________________________________________________________
01040 void Plexus::BuildLedMaps(const VldContext& vldc) const
01041 { 
01042    // build the basic map:  StripEndIds <--> LED <--> PinDiodes
01043 
01044    if (kLedMaps & fBuiltMaps) return;
01045    fBuiltMaps |= kLedMaps;
01046    LoadRDBCHack();
01047 
01048    DbiCache* pd2ledTblCache = 0;
01049    DbiCache* se2ledTblCache = 0;
01050 
01051    {
01052       // start of inner scope to that DbiResultPtr's will die, die, die
01053       // and thus Purge will see no remaining clients
01054 
01055       DbiResultPtr<PlexPinDiodeToLed> pd2ledResPtr(vldc);
01056       DbiResultPtr<PlexStripEndToLed> se2ledResPtr(vldc);
01057 
01058       // update the fVldRange
01059       TrimVldRange("PlexPinDiodeToLed",pd2ledResPtr.GetValidityRec());
01060       TrimVldRange("PlexStripEndToLed",se2ledResPtr.GetValidityRec());
01061 
01062       // get a handle for the cache
01063       pd2ledTblCache = pd2ledResPtr.TableProxy().GetCache();
01064       se2ledTblCache = se2ledResPtr.TableProxy().GetCache();
01065 
01066       // build the map:  PinDiode --> Led
01067       for (UInt_t irow = 0; irow < pd2ledResPtr.GetNumRows(); ++irow) {
01068          const PlexPinDiodeToLed* pd2led = pd2ledResPtr.GetRow(irow);
01069          PlexPinDiodeId pinid = pd2led->GetPlexPinDiodeId();
01070          PlexLedId      ledid = pd2led->GetPlexLedId();
01071          if ( ! paranoia ) { fPinDiodeToLed[pinid] = ledid; }
01072          else {
01073            if ( fPinDiodeToLed.find(pinid) == fPinDiodeToLed.end() ) {
01074              fPinDiodeToLed[pinid] = ledid;
01075            }
01076            else {
01077              MSG("Plex",Msg::kInfo) 
01078                << "BuildLedMaps PinDiode "
01079                << pinid.AsString("c") << " to Led "
01080                << fPinDiodeToLed[pinid].AsString("c")
01081                << ", new Led " << ledid.AsString("c")
01082                << endl;
01083            }
01084          }
01085       }
01086 
01087       // build the map:  StripEnd --> Led
01088       for (UInt_t irow = 0; irow < se2ledResPtr.GetNumRows(); ++irow) {
01089          const PlexStripEndToLed* se2led = se2ledResPtr.GetRow(irow);
01090          PlexStripEndId  seid = se2led->GetPlexStripEndId();
01091          PlexLedId      ledid = se2led->GetPlexLedId();
01092          if ( ! paranoia ) { fStripEndToLed[seid] = ledid; }
01093          else {
01094            if ( fStripEndToLed.find(seid) == fStripEndToLed.end() ) {
01095              fStripEndToLed[seid] = ledid;
01096            }
01097            else {
01098              if ( paranoia > 1 || seid.GetPlane() != 1023 )
01099                MSG("Plex",Msg::kInfo) 
01100                  << "BuildLedMaps StripEnd "
01101                  << seid.AsString("c") << " to Led "
01102                  << fStripEndToLed[seid].AsString("c")
01103                  << ", new Led " << ledid.AsString("c")
01104                  << endl;
01105            }
01106          }
01107       }
01108 
01109    }
01110 
01111    if ( PlexLoanPool::Instance()->PurgeDbiTableCache() ) {
01112      // now there should be no active clients so it should be
01113      // possible to purge to our heart's content
01114      if (pd2ledTblCache) pd2ledTblCache->Purge();
01115      if (se2ledTblCache) se2ledTblCache->Purge();
01116    }
01117 
01118    return;
01119 }
01120 
01121 //_____________________________________________________________________________
01122 void Plexus::PurgeComponents(UInt_t purgeMask)
01123 { 
01124   // clear out components of the plex 
01125   // generally done before writing it out to save space
01126 
01127   // clear both the map themselves and the flag bit indicating
01128   // whether the map is filled (used by lazy building)
01129 
01130 
01131   if (purgeMask & kPixelMaps) {
01132     fBuiltMaps &= ~kPixelMaps;
01133     fStripEndToSpot.clear();
01134     fPixelToStripEnd.clear();
01135     fPixelToChannel.clear();
01136     fChannelToPixel.clear();
01137   }
01138 
01139   if (purgeMask & kReadoutMap) {
01140     fBuiltMaps &= ~kReadoutMap;
01141     fChannelToReadout.clear();
01142     fSpecialDescript.clear();
01143   }
01144 
01145   if (purgeMask & kPinDiodeMap) {
01146     fBuiltMaps &= ~kPinDiodeMap;
01147     fChannelToPinDiode.clear();
01148   }
01149 
01150   if (purgeMask & kLedMaps) {
01151     fBuiltMaps &= ~kLedMaps;
01152     fPinDiodeToLed.clear();
01153     fStripEndToLed.clear();
01154   }
01155 
01156   if (purgeMask & kAllVectors) {
01157     fAllStripEnds.clear();
01158     fAllEastEnds.clear();
01159     fAllWestEnds.clear();
01160     fAllStrips.clear();
01161     fAllTubes.clear();
01162     fAllPixels.clear();
01163     fAllSpots.clear();
01164     fAllChannels.clear();
01165     fAllPinDiodes.clear();
01166     fAllLeds.clear();
01167   }
01168 
01169 }
01170 
01171 //_____________________________________________________________________________
01172 void Plexus::TrimVldRange(const char* tblName,
01173                           const DbiValidityRec* dbivrec) const
01174 { 
01175    // Trim VldRange based on DbiValidityRec range info
01176 
01177    if (dbivrec) {
01178       fVldRange.TrimTo(dbivrec->GetVldRange());
01179    } else {
01180       MSG("Plex",Msg::kWarning) 
01181          << "No DbiValidityRec for table " << tblName << endl;
01182    }
01183 }
01184 
01185 //_____________________________________________________________________________
01186 void Plexus::ValidateConsistency() const
01187 { 
01188    // Test tables for internal consistency
01189 
01190    typedef multimap<RawChannelId,PlexPixelSpotId>::const_iterator  rc2p_itr;
01191 
01192    RawChannelId rcid_last;
01193    rc2p_itr rcitr = fChannelToPixel.begin();
01194    rc2p_itr rcend = fChannelToPixel.end();
01195    while (rcitr != rcend) {
01196      RawChannelId rcid = rcitr->first;
01197      if (rcid != rcid_last) { // RawChannelId->PixelSpot is multimap
01198        PlexSEIdAltL altl = GetSEIdAltL(rcid,0,0,0);
01199        Bool_t printit = false;
01200 
01201        // make sure that far detector altl has 8 entries
01202        if (rcid.GetDetector() == DetectorType::kFar) {
01203          if ( altl.size() == 0 ) printit = true;
01204          else {
01205            PlexPlaneId plnid = altl.GetBestSEId();
01206            if ( altl.size() != 8 && !plnid.IsVetoShield() ) {
01207              MSG("Plex",Msg::kInfo) 
01208                << endl
01209                << " far detector PlexSEIdAltL.size() " << altl.size() 
01210                << " != 8" << endl;
01211              printit = true;
01212            }
01213          }
01214        }
01215 
01216        // test the alternative list for consistency
01217        Int_t error = altl.GetError(false);
01218        if (error) {
01219 
01220          printit = true;
01221          if (altl.empty()) {
01222            MSG("Plex",Msg::kInfo) 
01223              << " PlexSEIdAltL empty" 
01224              << endl;
01225            printit = false;
01226          }
01227          else {
01228            string etxt = " bad: ";
01229            if (error & PlexSEIdAltL::kBadDetector)  etxt += "detector ";
01230            if (error & PlexSEIdAltL::kBadEnd)       etxt += "end ";
01231            if (error & PlexSEIdAltL::kBadPlane)     etxt += "plane ";
01232            if (error & PlexSEIdAltL::kBadPlaneView) etxt += "view ";
01233            if (error & PlexSEIdAltL::kUnchecked)    etxt = " unchecked? ";
01234            MSG("Plex",Msg::kInfo) 
01235              << endl
01236              << " PlexSEIdAltL consistency error 0x"
01237              << hex << error << dec << etxt << endl;
01238          }
01239 
01240          pair<rc2p_itr,rc2p_itr> rc2p_limits =
01241            fChannelToPixel.equal_range(rcid);
01242          rc2p_itr next = rc2p_limits.first;  // range means 2nd is 1 too far
01243          if (++next == rc2p_limits.second) {
01244            // RawChannel only maps to one pixel
01245            MSG("Plex",Msg::kInfo)
01246              << " rcid " << rcid.AsString("ec") 
01247              << " single pixel: "
01248              << rc2p_limits.first->second.AsString("p") << endl;
01249          }
01250          else {
01251            // RawChannel maps to multiple pixels
01252            MSG("Plex",Msg::kInfo) 
01253              << " rcid " << rcid.AsString("ec") 
01254              << " pixel list: " << endl;
01255            for (rc2p_itr irc2p  = rc2p_limits.first;
01256                          irc2p != rc2p_limits.second; ++irc2p) {
01257              MSG("Plex",Msg::kInfo) 
01258                << "   " << irc2p->second.AsString("p") << endl;
01259            }
01260          }
01261 
01262        }
01263 
01264        if (printit) {
01265          // MSG("Plex",Msg::kInfo) << endl;
01266          altl.Print();
01267        }
01268 
01269      } // if new rcid
01270      // move along
01271      ++rcitr;
01272      rcid_last = rcid;
01273    } // while
01274 
01275    // test PinDiodes
01276    const std::vector<PlexPinDiodeId>& allpindiodes = GetAllPinDiodes();
01277    //if ( allpindiodes.size() != fChannelToPinDiode.size() )
01278    //  MSG("Plex",Msg::kInfo) 
01279    //    << "AllPinDiodes.size() = " << allpindiodes.size()
01280    //    << " vs. fChannelToPinDiode.size() = " << fChannelToPinDiode.size()
01281    //    << endl;
01282    if ( allpindiodes.size() != fPinDiodeToLed.size() )
01283      MSG("Plex",Msg::kInfo) 
01284        << "AllPinDiodes.size() = " << allpindiodes.size()
01285        << " vs. fPinDiodeToLed.size() = " << fPinDiodeToLed.size()
01286        << endl;
01287 
01288    // test Leds
01289    //const std::vector<PlexLedId>& allleds = GetAllLeds();
01290    //if ( allleds.size() != fStripEndToLed.size() )
01291    //  MSG("Plex",Msg::kInfo) 
01292    //    << "AllLeds.size() = " << allleds.size()
01293    //    << " vs. fStripEndToLed.size() = " << fStripEndToLed.size()
01294    //    << endl;
01295    //if ( allled.size() != fPinDiodeToLed.size() )
01296    //  MSG("Plex",Msg::kInfo) 
01297    //    << "AllLeds.size() = " << allleds.size()
01298    //    << " vs. fPinDiodeToLed.size() = " << fPinDiodeToLed.size()
01299    //    << endl;
01300 
01301 
01302 }
01303 
01304 //_____________________________________________________________________________

Generated on Thu Nov 1 15:53:23 2007 for loon by  doxygen 1.3.9.1