00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00016
00017 #include <cassert>
00018
00019 #include "Algorithm/AlgHandle.h"
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
00032 Int_t CandBase::fsNAlloc = 0;
00033
00034 Int_t CandBase::fgIndentLevel = 0;
00035 TString CandBase::fgIndentString = "";
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
00069 TNamed()
00070 , CandRefCounted()
00071 , fAlgConfigRef(cb.fAlgConfigRef)
00072 , fCandRecord(cb.fCandRecord)
00073 , fLocalHandle(0)
00074 , fCandUid(0)
00075 {
00076
00077
00078
00079
00080
00081 fsNAlloc++;
00082 assert (&cb != 0);
00083 fCandUid = new CandUid(*this, cb);
00084 }
00085
00086
00087 CandBase &CandBase::operator=(const CandBase &)
00088 {
00089 abort();
00090 return *this;
00091 }
00092
00093
00094 CandBase::~CandBase()
00095 {
00096 fDaughters.Delete();
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
00107 assert(&ch != 0);
00108 CandHandle *chnew = ch.DupHandle();
00109 chnew->SetMotherLink(fLocalHandle);
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);
00139 }
00140
00141
00142 Int_t CandBase::GetNDaughters() const
00143 {
00144 return fDaughters.GetEntries();
00145 }
00146
00147
00148 UInt_t CandBase::GetUidInt() const
00149 {
00150 return GetCandUid().GetUidInt();
00151 }
00152
00153
00154 Bool_t CandBase::HasOverlapWith(const CandBase & ) const
00155 {
00156 return kFALSE;
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
00170 TestDisplayCandBanner("CandBase");
00171 if (this->IsEqual(rhs)) return true;
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
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) {
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
00241
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;
00249 }
00250 if (CandHandle* newh =
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)) {
00266 delete newh;
00267 fDaughters.Compress();
00268 return kTRUE;
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;
00276 }
00277 return kFALSE;
00278 }
00279
00280
00281 void CandBase::SetCandRecord(CandRecord *cr)
00282 {
00283 if (cr == fCandRecord) return;
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;
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
00320
00321
00322
00323
00324
00325
00326
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();
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
00369
00370 static const TRegexp regexp("d*[0-9]",false);
00371 TSubString dn = opt(regexp);
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