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

CandBase.cxx

Go to the documentation of this file.
00001 
00002 // $Id: CandBase.cxx,v 1.30 2005/08/26 23:30:13 gmieg Exp $
00003 //
00004 // CandBase.cxx
00005 //
00006 // CandBase is the base class for Reconstruction Candidates.
00007 //
00008 // Each concrete CandBase must define a Dup function.
00009 // CandBase must grant friendship to class CandRefer.
00010 //
00011 // Adapted from Babar's BtaCandBase (written by Gautier Hamel de
00012 // Monchenault and Bob Jacobsen).
00013 //
00014 // Author:  G. Irwin 1/2000
00016 
00017 #include <cassert>
00018 
00019 #include "Algorithm/AlgHandle.h"                  // Needed for Root I/O
00020 #include "Candidate/CandBase.h"
00021 #include "Candidate/CandHandle.h"
00022 #include "Candidate/CH.h"
00023 #include "Candidate/CandUid.h"
00024 #include "MessageService/MsgService.h"
00025 #include "TRegexp.h"
00026 
00027 ClassImp(CandBase)
00028 
00029 template class CH<CandBase>;
00030 
00031 // Define static members
00032 Int_t CandBase::fsNAlloc = 0;            // Initializes fsNAlloc to zero
00033 
00034 Int_t   CandBase::fgIndentLevel = 0;          // Initialize indent level
00035 TString CandBase::fgIndentString = "";       // Initialize indent string
00036 TString CandBase::fgDataIndentString = "| "; 
00037 
00038 //______________________________________________________________________
00039 CVSID("$Id: CandBase.cxx,v 1.30 2005/08/26 23:30:13 gmieg Exp $");
00040 
00041 #include "Candidate/CandBase.tpl"
00042 
00043 //______________________________________________________________________
00044 CandBase::CandBase() :
00045   fAlgConfigRef(0)
00046 , fCandRecord(0)
00047 , fLocalHandle(0)
00048 , fCandUid(0)
00049 {
00050   fsNAlloc++;
00051   fCandUid = new CandUid(*this);
00052 }
00053 
00054 //______________________________________________________________________
00055 CandBase::CandBase(const AlgHandle &ah) :
00056   fAlgConfigRef(ah.GetAlgConfigRef())
00057 , fCandRecord(0)
00058 , fLocalHandle(0)
00059 , fCandUid(0)
00060 {
00061   fsNAlloc++;
00062   fCandUid = new CandUid(*this);
00063 }
00064 
00065 //______________________________________________________________________
00066 CandBase::CandBase(const CandBase &cb) :
00067 
00068 // NO, DON'T DO THIS!!! (gmieg 021025) TNamed(cb), CandRefCounted(cb)
00069   TNamed()
00070 , CandRefCounted()
00071 , fAlgConfigRef(cb.fAlgConfigRef)
00072 , fCandRecord(cb.fCandRecord)
00073 , fLocalHandle(0)
00074 , fCandUid(0)
00075 {
00076 
00077 // Base copy ctor dups owned pointers, but defers copying Daughter List.
00078 // Daughter List copy is made in the derived class Dup() function.
00079 // This is because base class copy constructor hasn't yet created
00080 // fLocalHandle with a CandHandle* of the full derived type.
00081   fsNAlloc++;
00082   assert (&cb != 0);
00083   fCandUid = new CandUid(*this, cb);
00084 }
00085 
00086 //______________________________________________________________________
00087 CandBase &CandBase::operator=(const CandBase &)    // Should not be used
00088 {
00089   abort();                             // This method should not be used
00090   return *this;
00091 }
00092 
00093 //______________________________________________________________________
00094 CandBase::~CandBase()
00095 {
00096   fDaughters.Delete();           // Delete all CandHandles in fDaughters
00097   delete fLocalHandle;  fLocalHandle = 0;
00098   delete fCandUid;      fCandUid = 0;
00099   fsNAlloc--;
00100 }
00101 
00102 //______________________________________________________________________
00103 const CandHandle *CandBase::AddDaughterLink(const CandHandle &ch)
00104 {
00105 
00106 // Assume pre-existing daughter check is already done.
00107   assert(&ch != 0);
00108   CandHandle *chnew = ch.DupHandle();
00109   chnew->SetMotherLink(fLocalHandle);  // Set the daughter's mother link
00110   chnew->SetCandRecord(fCandRecord);
00111   return chnew;
00112 }
00113 
00114 //______________________________________________________________________
00115 AlgConfig *CandBase::GetAlgConfig() const
00116 {
00117    return (AlgConfig *) (fAlgConfigRef.GetObject());
00118 }
00119 
00120 //______________________________________________________________________
00121 UInt_t CandBase::GetArchUidInt() const
00122 {
00123    return GetCandUid().GetArchUidInt();
00124 }
00125 
00126 //______________________________________________________________________
00127 const CandHandle *CandBase::GetDaughter(Int_t ndau) const
00128 {
00129   if ((ndau > -1) && (ndau < (fDaughters.GetLast()+1)))
00130     return (CandHandle *) fDaughters.At(ndau);
00131   else
00132     return 0;
00133 }
00134 
00135 //______________________________________________________________________
00136 TIter CandBase::GetDaughterIterator() const
00137 {
00138   return TIter(&fDaughters);                   // Daughter list Iterator
00139 }
00140 
00141 //______________________________________________________________________
00142 Int_t CandBase::GetNDaughters() const
00143 {
00144   return fDaughters.GetEntries();    // Counts occupied cells, not holes
00145 }
00146 
00147 //______________________________________________________________________
00148 UInt_t CandBase::GetUidInt() const
00149 {
00150    return GetCandUid().GetUidInt();
00151 }
00152 
00153 //______________________________________________________________________
00154 Bool_t CandBase::HasOverlapWith(const CandBase & /* candbase */) const
00155 {
00156   return kFALSE;                                // Needs to be filled in
00157 }
00158 
00159 //______________________________________________________________________
00160 Bool_t CandBase::IsComposite() const
00161 {
00162   return (GetNDaughters() > 1);
00163 }
00164 
00165 //______________________________________________________________________
00166 Bool_t CandBase::IsEquivalent(const TObject *rhs) const
00167 {
00168 
00169 // IsEquivalent does deep comparison for templated Test... methods
00170   TestDisplayCandBanner("CandBase");
00171   if (this->IsEqual(rhs)) return true;    // CandBases have same address
00172   Bool_t result = true;
00173   const CandBase* rCnd = dynamic_cast<const CandBase*>(rhs);
00174   if (rCnd == NULL) {
00175     MSG("VCand", Msg::kDebug)
00176         << "CandBase::IsEquivalent(): Comparison object not a CandBase."
00177                  << "  rhs->ClassName() = " << rhs->ClassName() << endl;
00178     return false;
00179   }
00180   
00181   result = TestEquality("fAlgConfigRef", this->fAlgConfigRef,
00182                                          rCnd->fAlgConfigRef) && result;
00183 
00184 // Compare fDaughters
00185   Bool_t all_daughters_ok = true;
00186   TIter thisIter = this->GetDaughterIterator();
00187   TIter rhsIter  = rCnd->GetDaughterIterator();
00188 
00189   TObject *thisObj;
00190   TObject *rhsObj;
00191 
00192   while ((thisObj = thisIter()) && (rhsObj  = rhsIter())) {
00193     CandHandle *thisCdh = dynamic_cast<CandHandle *>(thisObj);
00194     CandHandle *rhsCdh  = dynamic_cast<CandHandle *>(rhsObj);
00195     if (thisCdh == 0 || rhsCdh == 0) {
00196       MSG("VCand", Msg::kDebug)
00197            << "CandBase::IsEquivalent(): Bad daughter CandHandle found."
00198                   << "  thisObj->ClassName() = " << thisObj->ClassName()
00199                   << ".  rhsObj->ClassName() = " <<  rhsObj->ClassName()
00200                                                                 << endl;
00201       all_daughters_ok = false;
00202       continue;
00203     }
00204 
00205     if (thisCdh->GetMother() != this->fLocalHandle) {
00206       MSG("VCand", Msg::kError) << endl
00207                  << "Bad CandHandle found in LHS Daughter List." << endl
00208        << "CandHandle Mother pointer is not to LocalHandle of CandBase."
00209                                       << endl << "Mother ClassName() = "
00210                             << thisCdh->GetMother()->ClassName() << endl
00211              << "Mother GetName() = " << thisCdh->GetMother()->GetName()
00212                                  << endl << "LocalHandle ClassName() = "
00213                                       << this->fLocalHandle->ClassName()
00214                                    << endl << "LocalHandle GetName() = "
00215                                         << this->fLocalHandle->GetName()
00216                            << endl << "Needs to be understood!" << endl;
00217       all_daughters_ok = false;
00218     }
00219 
00220     if (*thisCdh != *rhsCdh) {    // Compares Candidate Object addresses
00221       MSG("VCand", Msg::kDebug) << "\tDaughter     [not ok]" << endl;
00222       all_daughters_ok = false;
00223     }
00224   }
00225 
00226   if (!all_daughters_ok) {
00227     MSG("VCand", Msg::kSynopsis) << "Daughters \t[not all ok]" << endl;
00228     return false;
00229   }
00230 
00231   MSG("VCand", Msg::kDebug) << "All daughters \t[ok]" << endl;
00232 
00233   return result;
00234 }
00235 
00236 //______________________________________________________________________
00237 Bool_t CandBase::RemoveDaughter(CandHandle *ch)
00238 {
00239 
00240 // Removes the first daughter encountered with the same CandHandle ref'd
00241 // object.  CandHandle caller is expected to have found the exact ch.
00242   if ((ch == 0)) {
00243     MSG("Cand", Msg::kError) << endl
00244        << "Failed attempt to remove null CandHandle from Daughter List."
00245     << endl << "LocalHandle ClassName() = " << fLocalHandle->ClassName()
00246         << endl << "LocalHandle GetName() = " << fLocalHandle->GetName()
00247                           << endl << "CandHandle not deleted."  << endl;
00248     return kFALSE;                                     // Failure return
00249   }
00250   if (CandHandle* newh =      // Guarantee Mother link pointer if cloned
00251                  dynamic_cast<CandHandle*>(fDaughters.FindObject(ch))) {
00252     if (newh->GetMother() != fLocalHandle) {
00253       MSG("Cand", Msg::kError) << endl
00254        << "Request to Remove bad CandHandle from Daughter List." << endl
00255        << "CandHandle mother pointer is not to LocalHandle of CandBase."
00256                                                                  << endl
00257             << "Mother ClassName() = " << newh->GetMother()->ClassName()
00258         << endl << "Mother GetName() = " << newh->GetMother()->GetName()
00259                                                                  << endl
00260             << "LocalHandle ClassName() = " << fLocalHandle->ClassName()
00261         << endl << "LocalHandle GetName() = " << fLocalHandle->GetName()
00262         << endl << "CandHandle Removed anyway.  Should be investigated!"
00263                                                                 << endl;
00264     }
00265     if (fDaughters.Remove(newh)) {  // Remove CandHandle from fDaughters
00266       delete newh;                        // Delete CandHandle ch object
00267       fDaughters.Compress();       // Squeeze out holes in Daughter list
00268       return kTRUE;                                    // Success return
00269     }
00270   }
00271   else {
00272     MSG("Cand", Msg::kError) << endl
00273            << "Failed to find and remove CandHandle from Daughter List."
00274                          << endl << "  CandHandle not deleted." << endl;
00275     return kFALSE;                                     // Failure return 
00276   }
00277   return kFALSE;                                          // Did nothing
00278 }
00279 
00280 //______________________________________________________________________
00281 void CandBase::SetCandRecord(CandRecord *cr)
00282 {
00283   if (cr == fCandRecord) return;   // New fCandRecord is same as old one
00284 
00285   fCandRecord = cr;
00286   TIter iterdau = GetDaughterIterator();
00287   CandHandle *dau;
00288   while ((dau = dynamic_cast<CandHandle *>(iterdau()))) {
00289     dau->SetCandRecord(cr);
00290   }
00291 }
00292 
00293 //______________________________________________________________________
00294 void CandBase::SetLocalHandle(CandHandle *ch)
00295 {
00296   assert (fLocalHandle == 0);
00297   fLocalHandle = ch;             // Handle supplied by derived Candidate
00298   assert (fLocalHandle != 0);
00299 }
00300 
00301 //______________________________________________________________________
00302 void CandBase::Trace(const char *c) const
00303 {
00304   MSG("Cand", Msg::kDebug)
00305            << "**********Begin CandBase::Trace(\"" << c << "\")" << endl
00306       << CandBase::GetNAlloc() << " CandBase objects allocated." << endl
00307                       << "UidInt = " << GetUidInt() << ", ArchUidInt = "
00308                                               << GetArchUidInt() << endl
00309                    << "No. of ref-counted CandHandles = " << GetNLinks()
00310                                  << " (LocalHandle not counted)" << endl
00311                    << "NDaughters = " << GetNDaughters() << endl << endl
00312             << "**********End CandBase::Trace(\"" << c << "\")" << endl;
00313 }
00314 
00315 //______________________________________________________________________
00316 std::ostream& CandBase::FormatToOStream(std::ostream& os,
00317                                         Option_t *option) const
00318 {
00319   // Format the Candidate (and Daughters) to a ostream
00320   // if option string contains:
00321   //    n    = include name
00322   //    t    = include title
00323   //    i    = include Uid's
00324   //    v[n] = verbosity level, v0 to suppresss data values 
00325   //    d[n] = include daughters to depth of [n] (infinite if no n)
00326   //           d0 means don't print daughters
00327 
00328   TString opt(option);
00329   bool doName  = opt.Contains("n");
00330   bool doTitle = opt.Contains("t");
00331   bool doUid   = opt.Contains("i");
00332 
00333   const TString& indent = GetIndentString();
00334 
00335   os << indent
00336      << this->ClassName() << " ";
00337   if (doName) {
00338     const TString name(this->GetName());
00339     if (name  != "") os << " Name: '" << this->GetName() << "'";
00340   }
00341   os << " Ndaughters " << this->GetNDaughters()
00342      << " NLinks " << this->GetNLinks(); // nlinks = nrefers + 1
00343   if (doTitle ) {
00344     const TString title(this->GetTitle());
00345     if (title != "") os << endl << indent 
00346                         << "   Title: '" << title << "'";
00347   }
00348   os << endl;
00349   if (doUid) {
00350     os << indent 
00351        << "   Uid " << this->GetUidInt() 
00352        << " ArchUid (ancestor) " << this->GetArchUidInt()
00353        << endl;
00354   }
00355   
00356   return os;
00357 }
00358 
00359 //______________________________________________________________________
00360 std::ostream& CandBase::FormatDaughtersToOStream(std::ostream& os,
00361                                                  Option_t *option) const
00362 {
00363   TString opt(option);
00364   bool nodaughters = opt.Contains("d0") || (GetNDaughters() == 0);
00365   if (!nodaughters) {
00366     TString optsub(opt);
00367 
00368 // here's where d[n] should be modified to d[n-1]
00369 // using wildcard would assume ^$
00370     static const TRegexp regexp("d*[0-9]",false);
00371     TSubString dn = opt(regexp);    // just finds the start of d[0-9]!!!
00372     int nlevels = -1;
00373     sscanf(dn.Data(),"d%d",&nlevels);
00374     if (nlevels>0) {
00375       TString oldn, newn;
00376       oldn += nlevels; 
00377       newn += (nlevels-1);
00378       optsub.ReplaceAll(oldn,newn);
00379     }
00380 
00381     const TString& indent = GetIndentString();
00382     os << indent << "Daughter List:" << endl;
00383     IncIndent();
00384     TIter itr = GetDaughterIterator();
00385     const TObject *obj;
00386     while ( ( obj = itr() ) ) {
00387       const CandHandle *cand = dynamic_cast<const CandHandle*>(obj);
00388       if (cand) cand->FormatToOStream(os,optsub);
00389     }
00390     DecIndent();
00391   }
00392   return os;
00393 }
00394 
00395 //______________________________________________________________________
00396 
00397 Int_t CandBase::ResizeIndent()
00398 { 
00399   fgIndentString.Resize(3*fgIndentLevel);
00400   return fgIndentLevel;
00401 }
00402 
00403 //______________________________________________________________________

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