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

MomNavigator.cxx

Go to the documentation of this file.
00001 
00002 // $Id: MomNavigator.cxx,v 1.18 2010/01/13 23:13:07 rhatcher Exp $
00003 //
00004 // MomNavigator.cxx
00005 //
00006 // Begin_Html<img src="../../pedestrians.gif" align=center>
00007 // <a href="../source_warning.html">Warning for beginners</a>.<br> 
00008 //
00009 // MomNavigator is the top level object for managing
00010 // related records (eg. raw records, candidate trees, truth info)
00011 //
00012 // Author:  R. Hatcher 2000.05.18
00013 //
00014 // Also see <a href="../../root_crib/index.html">The ROOT Crib</a> and 
00015 // <a href="../MinosObjectMap.html"> MinosObjectMap Classes</a>(part of
00016 // <a href="../index.html">The MINOS Class User Guide</a>)End_Html
00018 #include <cassert>
00019 
00020 #include "TClass.h"
00021 #include "TString.h"
00022 
00023 #include "MinosObjectMap/MomNavigator.h"
00024 #include "MessageService/MsgService.h"
00025 #include "Record/RecMinos.h"
00026 #include "Record/RecMinosHdr.h"
00027 #include "Record/RecRecord.h"
00028 
00029 CVSID("$Id: MomNavigator.cxx,v 1.18 2010/01/13 23:13:07 rhatcher Exp $");
00030 
00031 std::ostream& operator << (std::ostream& os, const MomNavigator& mom)
00032                                           { return mom.Print(os); }
00033 
00034 ClassImp(MomNavigator)
00035 
00036 //______________________________________________________________________
00037 MomNavigator::MomNavigator()
00038    : fFragmentArray(0)
00039 {
00040    // Default constructor
00041    MSG("Mom",Msg::kDebug) << "MomNavigator ctor " << this << endl;
00042   
00043    fFragmentArray = new TObjArray;
00044 }
00045 
00046 //______________________________________________________________________
00047 MomNavigator::~MomNavigator()
00048 {
00049    // delete all the owned sub-objects
00050    MSG("Mom",Msg::kDebug) << "MomNavigator dtor " << this << "\n" 
00051                           << *this << endl;
00052    if (fFragmentArray) fFragmentArray->Delete();//delete owned Fragments
00053    delete fFragmentArray;
00054 }
00055 
00056 //______________________________________________________________________
00057 void MomNavigator::AdoptFragment(TObject *Fragment)
00058 {
00059    // adopt (to own) a Fragment
00060 
00061    fFragmentArray->Add(Fragment);
00062 }
00063 
00064 //______________________________________________________________________
00065 TObject* MomNavigator::At(Int_t idx) const
00066 {
00067    // return pointer to the i-th Fragment 
00068    
00069    return fFragmentArray->At(idx);
00070 }
00071 
00072 //______________________________________________________________________
00073 TIter MomNavigator::FragmentIter() const
00074 {
00075    // return an iter over the Fragments
00076    
00077    return TIter(fFragmentArray);
00078 }
00079 
00080 //______________________________________________________________________
00081 Int_t MomNavigator::IndexOf(TObject *Fragment) 
00082 {
00083    // return the index of this object (if contained in the list)
00084    
00085    return fFragmentArray->IndexOf(Fragment);
00086 }
00087 
00088 //______________________________________________________________________
00089 TObject* MomNavigator::GetFragment(const char *classname,
00090                                    const char *username,
00091                                    const char *streamname) const {
00092 // Returns the first selected fragment.  If classname is a null ptr or
00093 // blank string, no class selection is done.  Any classname selection
00094 // is done by testing on the InheritsFrom() boolean, rather than
00095 // requiring agreement with the final derived class name.  The username
00096 // is optional, but, if filled, will further qualify the selection by
00097 // requiring agreement with the GetName() method of the fragment.  Note
00098 // that TNamed and TCollection objects both have SetName() methods to
00099 // allow the user to set a customized name.  General TObjects do not
00100 // have the SetName() method and default to the GetName() name returned
00101 // by the associated TClass object, i.e., the final derived class name.
00102 // If the fragment is a Record then the name of the input stream it
00103 // came from can be tested; non-Record objects will skip this test
00104 // (i.e. treated as always matched).
00105 
00106    TString classtr("");
00107    if (classname)
00108      classtr.Append(TString(classname).Strip(TString::kBoth));
00109    TString userstr("");
00110    if (username)
00111      userstr.Append(TString(username).Strip(TString::kBoth));
00112    TString streamstr("");
00113    if (streamname)
00114      streamstr.Append(TString(streamname).Strip(TString::kBoth));
00115 
00116    TIter fiter(fFragmentArray);
00117    TObject* fragment = 0;
00118    while ((fragment = fiter())) {
00119 
00120 // First check whether Fragment InheritsFrom "classname"
00121      if (classtr.IsNull() || fragment->IsA()->InheritsFrom(classtr)) {
00122 
00123 // Then check whether Fragment name equals "username"
00124        if (userstr.IsNull() || (userstr == fragment->GetName())) {
00125 
00126          // early out if no request of stream name match
00127          if (streamstr.IsNull()) return fragment;
00128 
00129 // Finally test the stream name (if it exists, and can be determined)
00130          Registry* iotags = 0;
00131          if ( RecMinos* record = dynamic_cast<RecMinos*>(fragment) ) {
00132            iotags = &(record->GetTempTags());
00133          }
00134          else if ( RecRecord* record = dynamic_cast<RecRecord*>(fragment) ) {
00135            iotags = &(record->GetTempTags());
00136          }
00137          if ( iotags ) {
00138            const char* tagstream = 0;
00139            if (iotags -> Get("stream",tagstream) 
00140                && strcmp(streamname,tagstream) == 0 ) return fragment;
00141          }
00142        }  // match username
00143      }  // match classname
00144    }  // loop over fragments
00145    return 0;
00146 }
00147 
00148 //______________________________________________________________________
00149 std::vector<TObject*> MomNavigator::GetFragmentList(const char* classname,
00150                                                     const char *username,
00151                                                     const char *streamname) const {
00152 // Returns the list of selected fragments satisfying the argument list.
00153 // If classname is a null ptr or
00154 // blank string, no class selection is done.  Any classname selection
00155 // is done by testing on the InheritsFrom() boolean, rather than
00156 // requiring agreement with the final derived class name.  The username
00157 // is optional, but, if filled, will further qualify the selection by
00158 // requiring agreement with the GetName() method of the fragment.  Note
00159 // that TNamed and TCollection objects both have SetName() methods to
00160 // allow the user to set a customized name.  General TObjects do not
00161 // have the SetName() method and default to the GetName() name returned
00162 // by the associated TClass object, i.e., the final derived class name.
00163 // If the fragment is a Record then the name of the input stream it
00164 // came from is tested and compared to the specified streamname (optional).
00165 //
00166 
00167    std::vector<TObject*> fragmentList;
00168   
00169    TString classtr("");
00170    if (classname)
00171      classtr.Append(TString(classname).Strip(TString::kBoth));
00172    TString userstr("");
00173    if (username)
00174      userstr.Append(TString(username).Strip(TString::kBoth));
00175    TString streamstr("");
00176    if (streamname)
00177      streamstr.Append(TString(streamname).Strip(TString::kBoth));
00178 
00179    TIter fiter(fFragmentArray);
00180    TObject* fragment = 0;
00181    while ((fragment = fiter())) {
00182 
00183 // First check whether Fragment InheritsFrom "classname"
00184      if (classtr.IsNull() || fragment->IsA()->InheritsFrom(classtr)) {
00185        // meets classname criteria
00186        if (userstr.IsNull() || (userstr == fragment->GetName())) {
00187          // meets username criteria
00188          if ( streamstr.IsNull() ) {
00189            // No request of stream name match
00190            fragmentList.push_back(fragment);
00191          }
00192          else {
00193            // Test the stream name (if it exists, and can be determined)
00194            Registry* iotags = 0;
00195            if ( RecMinos* record = dynamic_cast<RecMinos*>(fragment) ) {
00196              iotags = &(record->GetTempTags());
00197            }
00198            else if ( RecRecord* record = dynamic_cast<RecRecord*>(fragment) ) {
00199              iotags = &(record->GetTempTags());
00200            }
00201            if ( iotags ) {
00202              const char* tagstream = 0;
00203              if (iotags -> Get("stream",tagstream) 
00204                  && strcmp(streamname,tagstream) == 0 ) {
00205                fragmentList.push_back(fragment);
00206              }
00207            }
00208          }
00209        }  // match username
00210      }  // match classname
00211    }  // loop over fragments
00212    return fragmentList;
00213 }
00214                                 
00215   
00216 //______________________________________________________________________
00217 TObject* MomNavigator::GetFragmentByInputTag(const char *streamname,
00218       const char *treename, int treeindex, const char* filename) const {
00219 // Returns the selected fragment matching the specified input tags.  Null
00220 // is returned if none found.
00221 
00222    TIter fiter(fFragmentArray);
00223    TObject* fragment;
00224    while ((fragment = fiter())) {
00225      Registry* iotags = 0;
00226      if ( RecMinos* record = dynamic_cast<RecMinos*>(fragment) ) {
00227        iotags = &(record->GetTempTags());
00228      }
00229      else if ( RecRecord* record = dynamic_cast<RecRecord*>(fragment) ) {
00230        iotags = &(record->GetTempTags());
00231      }
00232      if ( iotags ) {
00233        const char* tagstream = 0;
00234        if(iotags->Get("stream",tagstream) && strcmp(streamname,tagstream)==0) {
00235          const char* tagtree = 0;
00236          if (iotags -> Get("tree",tagtree) && strcmp(treename,tagtree)==0 ) {
00237            int tagindex = -1;
00238            if (iotags -> Get("index",tagindex) && tagindex == treeindex ) {
00239              const char* tagfile = 0;
00240              if (iotags -> Get("file",tagfile) && strcmp(filename,tagfile)==0){
00241                return fragment;
00242              }
00243            }
00244          }
00245        }
00246      }
00247    }  // loop over fragments
00248 
00249    return 0; // no matching fragment found
00250 }
00251 
00252 
00253 //______________________________________________________________________
00254 void MomNavigator::Clear(Option_t * opt )
00255 {
00256    // Clear out all transient records 
00257    //
00258    // Since, *currently*, MomNavigator _owns_ the things in it's list
00259    // then it should be responsible for deleting the heap based objects
00260    // eventually when it is just a means of associating the objects
00261    // then that responsibility might change
00262 
00263   if ( !fFragmentArray ) return;
00264   MSG("Mom",Msg::kVerbose) << "MomNavigator::Clear. Mom contents at entry:\n" 
00265                            << *this << endl;
00266   
00267   // "optstr" is the string we'll match against.
00268   // Check if special additional flag is present, if it is remove it
00269   // and set the flag.
00270   TString optstr(opt);
00271   bool forceTransient = false;
00272   const TString fstring("?forceTransient");
00273   Ssiz_t ipos = optstr.Index(fstring);
00274   if ( ipos >= 0 ) {
00275     forceTransient = true;
00276     optstr.Remove(ipos,fstring.Length());
00277   }
00278 
00279   for ( int idx = fFragmentArray->GetEntriesFast()-1; idx >= 0; idx-- ) {
00280      TObject* fragment = fFragmentArray->At(idx);
00281      if ( !fragment ) continue;
00282 
00283      RecMinos* recminos = dynamic_cast<RecMinos*>(fragment);
00284      RecRecord* recrecord = dynamic_cast<RecRecord*>(fragment);
00285 
00286      // RWH 2010-01-13
00287      // If given a non-blank opt value, only drop fragments that match
00288      // that criteria based on stream, treename, 
00289      if ( optstr != "" ) {
00290        int ismatch = 0;
00291        TString fragClassName(fragment->ClassName());
00292        TString fragUserName(fragment->GetName());
00293 
00294        const Registry* reg = 0;
00295        if      (recminos)  reg = &(recminos->GetTempTags());
00296        else if (recrecord) reg = &(recrecord->GetTempTags());
00297        TString fragStream;
00298        const char* tmp = 0;
00299        if ( reg->Get("stream",tmp)) fragStream = tmp;
00300 
00301        if ( optstr == fragClassName ) ismatch = 0x01;
00302        if ( optstr == fragUserName  ) ismatch = 0x02;
00303        if ( optstr == fragStream    ) ismatch = 0x04;
00304        MSG("Mom",Msg::kDebug) << "MomNavigator::Clear(\"" << optstr << "\") "
00305                               << " class=\"" << fragClassName << "\""
00306                               << " user=\"" << fragUserName << "\""
00307                               << " stream=\"" << fragStream << "\""
00308                               << " ismatch=" << ismatch
00309                               << endl;
00310        if ( ismatch == 0 ) continue;  // not a match, don't drop fragment
00311        MSG("Mom",Msg::kDebug) << "drop the fragment" << endl;
00312      }
00313 
00314 
00315      bool isTransient = true;
00316      bool isPerOwned = false;
00317      if ( recminos ) {
00318        isTransient = recminos->IsTransient();
00319      }
00320      else if ( recrecord ) {
00321        isTransient = recrecord->IsTransient();
00322        isPerOwned = recrecord->IsPerOwned();
00323      }
00324      if ( isTransient || forceTransient ) {
00325        fFragmentArray->RemoveAt(idx); // remove does not delete object
00326        // If fragment is owned by persistency, only remove it from list
00327        if ( fragment && !isPerOwned ) delete fragment; 
00328        fragment = 0;
00329      }
00330    }
00331    fFragmentArray->Compress();
00332   
00333    MSG("Mom",Msg::kVerbose) << "MomNavigator::Clear. Mom contents at exit:\n"
00334                             << *this << endl;
00335 
00336 }
00337 
00338 std::ostream& MomNavigator::Print(std::ostream& os) const {
00339   //
00340   //  Purpose:  Print brief listing of mom contents on ostream.
00341   //
00342   //  Arguments: os ostream to display on.
00343   //
00344   //  Return:  ostream reference.
00345   //
00346   //  Contact:   S. Kasahara
00347   // 
00348 
00349   assert(fFragmentArray);
00350   
00351   Int_t nent = fFragmentArray->GetEntriesFast();
00352   if ( nent <= 0 ) {
00353     os << "Mom has no entries." << endl;
00354     return os;
00355   }
00356   
00357   os << "Mom contents listed by array index:" << endl;
00358   for (int idx = 0; idx < nent; idx++) {
00359     TObject* fragment = fFragmentArray->At(idx);
00360     if ( !fragment ) {
00361       os << idx << ")No object.";
00362     }
00363     else {
00364       os << idx << ")" << fragment->ClassName();
00365       Registry* iotags = 0;
00366       bool isTransient = true;
00367       bool isPerOwned = false;
00368       if ( RecMinos* record = dynamic_cast<RecMinos*>(fragment) ) {
00369         iotags = &(record->GetTempTags());
00370         isTransient = record -> IsTransient();
00371         const VldContext& vldc = record -> GetHeader() -> GetVldContext();
00372         os << " " <<  vldc;
00373       }
00374       else if ( RecRecord* record = dynamic_cast<RecRecord*>(fragment) ) {
00375         iotags = &(record->GetTempTags());
00376         isTransient = record -> IsTransient();
00377         isPerOwned = record -> IsPerOwned();
00378         const VldContext& vldc = (record -> GetHeader()).GetVldContext();
00379         os << " " << vldc;
00380       }
00381 
00382       if ( strcmp(fragment->GetName(),"") ) {
00383         os << ", TNamed " << fragment->GetName();
00384       }
00385       if ( iotags ) {
00386         const char* tagstream = 0;
00387         if(iotags->Get("stream",tagstream)) {
00388           os << ", InputStream " << tagstream;
00389         }
00390       }
00391       os << (( isTransient ) ? ", isTransient " : ", isNotTransient ");
00392       os << (( isPerOwned ) ? ", isPerOwned " : ", isNotPerOwned ");
00393     }
00394     os << endl;
00395   }
00396 
00397   return os;
00398 
00399 }
00400 
00401 void MomNavigator::Print(Option_t* /* option */) const {
00402   //
00403   //  Purpose:  Print header in form supported by TObject::Print.
00404   //
00405   //  Arguments: option (not used)
00406   //
00407   //  Return:  none.
00408   //
00409   //  Contact:   S. Kasahara
00410   // 
00411 
00412   Print(std::cout);
00413   return;
00414 
00415 }
00416 
00417 

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