TEventList.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TEventList.cxx 35993 2010-10-01 10:58:32Z pcanal $
00002 // Author: Rene Brun   11/02/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // A TEventList object is a list of selected events (entries) in a TTree//
00015 //                                                                      //
00016 // A TEventList is automatically generated by TTree::Draw: example      //
00017 //      tree->Draw(">>elist1","x<0 && y> 0");                           //
00018 //         In this example, a TEventList object named "elist1" will be  //
00019 //         generated. (Previous contents are overwritten).              //
00020 //      tree->Draw(">>+elist1","x<0 && y> 0");                          //
00021 //         In this example, selected entries are added to the list.     //
00022 //                                                                      //
00023 // The TEventList object is added to the list of objects in the current //
00024 // directory.                                                           //
00025 // Use TTree:SetEventList(TEventList *list) to inform TTree that you    //
00026 // want to use the list as input. The following code gets a pointer to  //
00027 // the TEventList object created in the above commands:                 //
00028 //     TEventList *list = (TEventList*)gDirectory->Get("elist1");       //
00029 //                                                                      //
00030 // Use function Enter to enter an element in the list                   //
00031 // The function Add may be used to merge two lists.                     //
00032 // The function Subtract may be used to subtract two lists.             //
00033 // The function Reset may be used to reset a list.                      //
00034 // Use TEventList::Print(option) to print the contents.                 //
00035 //      (option "all" prints all the list entries).                     //
00036 //   Operators + and - correspond to functions Add and Subtract.        //
00037 // A TEventList object can be saved on a file via the Write function.   //
00038 //                                                                      //
00039 //////////////////////////////////////////////////////////////////////////
00040 
00041 #include "TEventList.h"
00042 #include "TCut.h"
00043 #include "TClass.h"
00044 #include "TFile.h"
00045 #include "TMath.h"
00046 
00047 ClassImp(TEventList)
00048 
00049 //______________________________________________________________________________
00050 TEventList::TEventList(): TNamed()
00051 {
00052 //*-*-*-*-*-*Default constructor for a EventList*-*-*-*-*-*-*-*-*-*-*-*-*
00053 //*-*        ==================================
00054 
00055    fN          = 0;
00056    fSize       = 100;
00057    fDelta      = 100;
00058    fList       = 0;
00059    fDirectory  = 0;
00060    fReapply    = kFALSE;
00061 }
00062 
00063 //______________________________________________________________________________
00064 TEventList::TEventList(const char *name, const char *title, Int_t initsize, Int_t delta)
00065   :TNamed(name,title), fReapply(kFALSE)
00066 {
00067    // Create a EventList.
00068    //
00069    // This Eventlist is added to the list of objects in current directory.
00070 
00071    fN = 0;
00072    if (initsize > 100) fSize  = initsize;
00073    else                fSize  = 100;
00074    if (delta > 100)    fDelta = delta;
00075    else                fDelta = 100;
00076    fList       = 0;
00077    fDirectory  = gDirectory;
00078    if (fDirectory) fDirectory->Append(this);
00079 }
00080 
00081 //______________________________________________________________________________
00082 TEventList::TEventList(const TEventList &list) : TNamed(list)
00083 {
00084    // Copy constructor.
00085 
00086    fN     = list.fN;
00087    fSize  = list.fSize;
00088    fDelta = list.fDelta;
00089    fList  = new Long64_t[fSize];
00090    for (Int_t i=0; i<fN; i++)
00091       fList[i] = list.fList[i];
00092    fReapply = list.fReapply;
00093    fDirectory = 0;
00094 }
00095 
00096 //______________________________________________________________________________
00097 TEventList::~TEventList()
00098 {
00099    // Default destructor for a EventList.
00100 
00101    delete [] fList;  fList = 0;
00102    if (fDirectory) fDirectory->Remove(this);
00103    fDirectory  = 0;
00104 }
00105 
00106 //______________________________________________________________________________
00107 void TEventList::Add(const TEventList *alist)
00108 {
00109    // Merge contents of alist with this list.
00110    //
00111    // Both alist and this list are assumed to be sorted prior to this call
00112 
00113    Int_t i;
00114    Int_t an = alist->GetN();
00115    if (!an) return;
00116    Long64_t *alst = alist->GetList();
00117    if (!fList) {
00118       fList = new Long64_t[an];
00119       for (i=0;i<an;i++) fList[i] = alst[i];
00120       fN = an;
00121       fSize = an;
00122       return;
00123    }
00124    Int_t newsize = fN + an;
00125    Long64_t *newlist = new Long64_t[newsize];
00126    Int_t newpos, alpos;
00127    newpos = alpos = 0;
00128    for (i=0;i<fN;i++) {
00129       while (alpos < an && fList[i] > alst[alpos]) {
00130          newlist[newpos] = alst[alpos];
00131          newpos++;
00132          alpos++;
00133       }
00134       if (alpos < an && fList[i] == alst[alpos]) alpos++;
00135       newlist[newpos] = fList[i];
00136       newpos++;
00137    }
00138    while (alpos < an) {
00139       newlist[newpos] = alst[alpos];
00140       newpos++;
00141       alpos++;
00142    }
00143    delete [] fList;
00144    fN    = newpos;
00145    fSize = newsize;
00146    fList = newlist;
00147 
00148    TCut orig = GetTitle();
00149    TCut added = alist->GetTitle();
00150    TCut updated = orig || added;
00151    SetTitle(updated.GetTitle());
00152 }
00153 
00154 //______________________________________________________________________________
00155 Bool_t TEventList::Contains(Long64_t entry)
00156 {
00157    // Return TRUE if list contains entry.
00158 
00159    if (GetIndex(entry) < 0) return kFALSE;
00160    return kTRUE;
00161 }
00162 
00163 //______________________________________________________________________________
00164 Bool_t TEventList::ContainsRange(Long64_t entrymin, Long64_t entrymax)
00165 {
00166    // Return TRUE if list contains entries from entrymin to entrymax included.
00167 
00168    Long64_t imax = TMath::BinarySearch(fN,fList,entrymax);
00169    //printf("ContainsRange: entrymin=%lld, entrymax=%lld,imax=%lld, fList[imax]=%lld\n",entrymin,entrymax,imax,fList[imax]);
00170    
00171    if (fList[imax] < entrymin) return kFALSE;
00172    return kTRUE;
00173 }
00174 
00175 //______________________________________________________________________________
00176 void TEventList::DirectoryAutoAdd(TDirectory* dir)
00177 {
00178    // Called by TKey and others to automatically add us to a directory when we are read from a file.
00179    
00180    SetDirectory(dir);
00181 }
00182 
00183 //______________________________________________________________________________
00184 void TEventList::Enter(Long64_t entry)
00185 {
00186    // Enter element entry into the list.
00187 
00188    if (!fList) {
00189       fList = new Long64_t[fSize];
00190       fList[0] = entry;
00191       fN = 1;
00192       return;
00193    }
00194    if (fN>0 && entry==fList[fN-1]) return;
00195    if (fN >= fSize) {
00196       Int_t newsize = TMath::Max(2*fSize,fN+fDelta);
00197       Resize(newsize-fSize);
00198    }
00199    if(fN==0 || entry>fList[fN-1]) {
00200       fList[fN] = entry;
00201       ++fN;
00202    } else {
00203       Int_t pos = TMath::BinarySearch(fN, fList, entry);
00204       if(pos>=0 && entry==fList[pos])
00205          return;
00206       ++pos;
00207       memmove( &(fList[pos+1]), &(fList[pos]), 8*(fN-pos));
00208       fList[pos] = entry;
00209       ++fN;
00210    }
00211 }
00212 
00213 //______________________________________________________________________________
00214 Long64_t TEventList::GetEntry(Int_t index) const
00215 {
00216    // Return value of entry at index in the list.
00217    // Return -1 if index is not in the list range.
00218 
00219    if (!fList)   return -1;
00220    if (index < 0 || index >= fN)   return -1;
00221    return fList[index];
00222 }
00223 
00224 //______________________________________________________________________________
00225 Int_t TEventList::GetIndex(Long64_t entry) const
00226 {
00227    // Return index in the list of element with value entry
00228    // array is supposed  to be sorted prior to this call.
00229    // If match is found, function returns position of element.
00230    // If no match found, function returns -1.
00231 
00232    Long64_t nabove, nbelow, middle;
00233    nabove = fN+1;
00234    nbelow = 0;
00235    while(nabove-nbelow > 1) {
00236       middle = (nabove+nbelow)/2;
00237       if (entry == fList[middle-1]) return middle-1;
00238       if (entry  < fList[middle-1]) nabove = middle;
00239       else                          nbelow = middle;
00240    }
00241    return -1;
00242 }
00243 
00244 //______________________________________________________________________________
00245 void TEventList::Intersect(const TEventList *alist)
00246 {
00247    // Remove elements from this list that are NOT present in alist.
00248 
00249    if (!alist) return;
00250    if (!fList) return;
00251 
00252    Long64_t *newlist = new Long64_t[fN];
00253    Int_t newpos = 0;
00254    Int_t i;
00255    for (i=0;i<fN;i++) {
00256       if (alist->GetIndex(fList[i]) >= 0) {
00257          newlist[newpos] = fList[i];
00258          newpos++;
00259       }
00260    }
00261    delete [] fList;
00262    fN    = newpos;
00263    fList = newlist;
00264 
00265    TCut orig = GetTitle();
00266    TCut removed = alist->GetTitle();
00267    TCut updated = orig && removed;
00268    SetTitle(updated.GetTitle());
00269 }
00270 
00271 //______________________________________________________________________________
00272 Int_t TEventList::Merge(TCollection *list)
00273 {
00274 // Merge entries in all the TEventList in the collection in this event list
00275 
00276    if (!list) return -1;
00277    TIter next(list);
00278 
00279    //first loop to count the number of entries
00280    TEventList *el;
00281    Int_t nevents = 0;
00282    while ((el = (TEventList*)next())) {
00283       if (!el->InheritsFrom(TEventList::Class())) {
00284          Error("Add","Attempt to add object of class: %s to a %s",el->ClassName(),this->ClassName());
00285          return -1;
00286       }
00287       Add(el);
00288       nevents += el->GetN();
00289    }
00290 
00291    return nevents;
00292 }
00293 
00294 //______________________________________________________________________________
00295 void TEventList::Print(Option_t *option) const
00296 {
00297 //          Print contents of this list
00298 
00299    printf("EventList:%s/%s, number of entries =%d, size=%d\n",GetName(),GetTitle(),fN,fSize);
00300    if (!strstr(option,"all")) return;
00301    Int_t i;
00302    Int_t nbuf = 0;
00303    char element[10];
00304    char *line = new char[100];
00305    snprintf(line,100,"%5d : ",0);
00306    for (i=0;i<fN;i++) {
00307       nbuf++;
00308       if (nbuf > 10) {
00309          printf("%s\n",line);
00310          snprintf(line,100,"%5d : ",i);
00311          nbuf = 1;
00312       }
00313       snprintf(element,10,"%7lld ",fList[i]);
00314       strlcat(line,element,100);
00315    }
00316    if (nbuf) printf("%s\n",line);
00317    delete [] line;
00318 }
00319 
00320 //______________________________________________________________________________
00321 void TEventList::Reset(Option_t *)
00322 {
00323 //          Reset number of entries in event list
00324 
00325    fN = 0;
00326 }
00327 
00328 //______________________________________________________________________________
00329 void TEventList::Resize(Int_t delta)
00330 {
00331 //          Resize list by delta entries
00332 
00333    if (!delta) delta = fDelta;
00334    fSize += delta;
00335    Long64_t *newlist = new Long64_t[fSize];
00336    for (Int_t i=0;i<fN;i++) newlist[i] = fList[i];
00337    delete [] fList;
00338    fList = newlist;
00339 }
00340 
00341 //______________________________________________________________________________
00342 void TEventList::SetDirectory(TDirectory *dir)
00343 {
00344    // Remove reference to this EventList from current directory and add
00345    // reference to new directory dir. dir can be 0 in which case the list
00346    // does not belong to any directory.
00347 
00348    if (fDirectory == dir) return;
00349    if (fDirectory) fDirectory->Remove(this);
00350    fDirectory = dir;
00351    if (fDirectory) fDirectory->Append(this);
00352 }
00353 
00354 //______________________________________________________________________________
00355 void TEventList::SetName(const char *name)
00356 {
00357    // Change the name of this TEventList
00358    
00359    //  TEventLists are named objects in a THashList.
00360    //  We must update the hashlist if we change the name
00361    if (fDirectory) fDirectory->Remove(this);
00362    fName = name;
00363    if (fDirectory) fDirectory->Append(this);
00364 }
00365 
00366 //______________________________________________________________________________
00367 void TEventList::Sort()
00368 {
00369 //          Sort list entries in increasing order
00370 
00371    Int_t    *index   = new Int_t[fN];
00372    Long64_t *newlist = new Long64_t[fSize];
00373    Int_t i,ind;
00374    TMath::Sort(fN,fList,index); //sort in decreasing order
00375    for (i=0;i<fN;i++) {
00376       ind = index[fN-i-1];
00377       newlist[i] = fList[ind];
00378    }
00379    for (i=fN;i<fSize;i++) {
00380       newlist[i] = 0;
00381    }
00382    delete [] index;
00383    delete [] fList;
00384    fList = newlist;
00385 }
00386 
00387 //______________________________________________________________________________
00388 void TEventList::Streamer(TBuffer &b)
00389 {
00390    // Stream an object of class TEventList.
00391 
00392    if (b.IsReading()) {
00393       UInt_t R__s, R__c;
00394       Version_t R__v = b.ReadVersion(&R__s, &R__c);
00395       fDirectory = 0;
00396       if (R__v > 1) {
00397          b.ReadClassBuffer(TEventList::Class(), this, R__v, R__s, R__c);
00398          ResetBit(kMustCleanup);
00399          return;
00400       }
00401       //====process old versions before automatic schema evolution
00402       TNamed::Streamer(b);
00403       b >> fN;
00404       b >> fSize;
00405       b >> fDelta;
00406       if (fN) {
00407          Int_t *tlist = new Int_t[fSize];
00408          b.ReadFastArray(tlist,fN);
00409          fList = new Long64_t[fSize];
00410          for (Int_t i=0;i<fN;i++) fList[i] = tlist[i];
00411          delete [] tlist;
00412       }
00413       ResetBit(kMustCleanup);
00414       b.CheckByteCount(R__s, R__c, TEventList::IsA());
00415       //====end of old versions
00416 
00417    } else {
00418       b.WriteClassBuffer(TEventList::Class(), this);
00419    }
00420 }
00421 
00422 //______________________________________________________________________________
00423 void TEventList::Subtract(const TEventList *alist)
00424 {
00425    // Remove elements from this list that are present in alist.
00426 
00427    if (!alist) return;
00428    if (!fList) return;
00429 
00430    Long64_t *newlist = new Long64_t[fN];
00431    Int_t newpos = 0;
00432    Int_t i;
00433    for (i=0;i<fN;i++) {
00434       if (alist->GetIndex(fList[i]) < 0) {
00435          newlist[newpos] = fList[i];
00436          newpos++;
00437       }
00438    }
00439    delete [] fList;
00440    fN    = newpos;
00441    fList = newlist;
00442 
00443    TCut orig = GetTitle();
00444    TCut removed = alist->GetTitle();
00445    TCut updated = orig && !removed;
00446    SetTitle(updated.GetTitle());
00447 }
00448 
00449 //______________________________________________________________________________
00450 TEventList& TEventList::operator=(const TEventList &list)
00451 {
00452    // Assingment.
00453 
00454    if (this != &list) {
00455       TNamed::operator=(list);
00456       if (fSize < list.fSize) {
00457          delete [] fList;
00458          fList  = new Long64_t[list.fSize];
00459       }
00460       fN     = list.fN;
00461       fSize  = list.fSize;
00462       fDelta = list.fDelta;
00463       for (Int_t i=0; i<fN; i++)
00464          fList[i] = list.fList[i];
00465    }
00466    return *this;
00467 }
00468 
00469 //______________________________________________________________________________
00470 TEventList operator+(const TEventList &list1, const TEventList &list2)
00471 {
00472    // Addition.
00473 
00474    TEventList newlist = list1;
00475    newlist.Add(&list2);
00476    return newlist;
00477 }
00478 
00479 //______________________________________________________________________________
00480 TEventList operator-(const TEventList &list1, const TEventList &list2)
00481 {
00482    // Substraction
00483 
00484    TEventList newlist = list1;
00485    newlist.Subtract(&list2);
00486    return newlist;
00487 }
00488 
00489 //______________________________________________________________________________
00490 TEventList operator*(const TEventList &list1, const TEventList &list2)
00491 {
00492    // Intersection.
00493 
00494    TEventList newlist = list1;
00495    newlist.Intersect(&list2);
00496    return newlist;
00497 }
00498 

Generated on Tue Jul 5 15:34:02 2011 for ROOT_528-00b_version by  doxygen 1.5.1