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

RawRecord.cxx

Go to the documentation of this file.
00001 
00002 // $Id: RawRecord.cxx,v 1.19 2007/11/11 20:44:34 schubert Exp $
00003 //
00004 // RawRecord
00005 //
00006 // RawRecord is the top level object for raw MINOS data from the online
00007 // This is the primary key for I/O of records of raw data
00008 //
00009 // Author:  R. Hatcher 2000.04.19
00010 //
00012 
00013 #include "RawData/RawRecord.h"
00014 #include "RawData/RawHeader.h"
00015 #include "RawData/RawDataBlock.h"
00016 
00017 #include "RawData/RawBlockRegistry.h"
00018 #include "RawData/RawBlockProxy.h"
00019 
00020 #include <iostream>
00021 #include <cassert>
00022 #include <string>
00023 #include <map>
00024 
00025 #include "MessageService/MsgService.h"
00026 CVSID("$Id: RawRecord.cxx,v 1.19 2007/11/11 20:44:34 schubert Exp $");
00027 
00028 ClassImp(RawRecord)
00029 
00030 //_____________________________________________________________________________
00031 
00032 // No one record should keep track of how many times generic blocks
00033 // have been promoted, so this shouldn't be a data memeber of an object.
00034 // Not having it as a data member of the class (but rather simply
00035 // in the implementation file) avoids exposing it in the header.
00036 static std::map<std::string,unsigned long int> fgPromoteCount;
00037 
00038 //_____________________________________________________________________________
00039 RawRecord::RawRecord() : promotionChecked(false)
00040 {
00041    // Default constructor
00042 }
00043 
00044 //_____________________________________________________________________________
00045 RawRecord::RawRecord(RawHeader *rh) : RecMinos(rh), promotionChecked(false)
00046 {
00047    // normal ctor, adopt the RawHeader for ownership
00048 }
00049 
00050 
00051 //_____________________________________________________________________________
00052 RawRecord::~RawRecord()
00053 {
00054    // dtor, no explicit deletion of header -- done by RecMinos
00055 }
00056 
00057 //_____________________________________________________________________________
00058 const RawHeader *RawRecord::GetRawHeader() const
00059 {
00060 
00061    // Return the RawHeader
00062 
00063    const RawHeader* rawHeader =
00064      dynamic_cast<const RawHeader *>(RecMinos::GetHeader());
00065    
00066    if (!rawHeader) {
00067      const RecMinosHdr* recHeader = RecMinos::GetHeader();
00068      MSG("RawData",Msg::kWarning)
00069        << "RawRecord::GetRawHeader found no RawHeader*, "
00070        << "RecMinosHdr* was " << recHeader << endl;
00071    }
00072    return rawHeader;
00073 }
00074 //_____________________________________________________________________________
00075 const RawDataBlock *RawRecord::FindRawBlock(const char *classname,
00076                                             const char *objname) const
00077 {
00078 
00079 // Returns the *last* selected RawDataBlock.  If classname is a null ptr
00080 // or blank string, no class selection is done.  If classname is
00081 // provided, the qualifying object must InheritFrom() or be a classname.
00082 // The objname is optional, but, if filled, will further qualify the
00083 // selection by requiring agreement with the GetName() method of the
00084 // selected object.
00085 
00086 // RecMinos::FindComponent() returns a "const TObject *".  This gets
00087 // converted to a "RawDataBlock *" using dynamic_cast to make sure the
00088 // original is a "RawDataBlock *". 
00089 
00090   PromoteRawDataBlocks();  // make sure that blocks are specialized
00091 
00092   return dynamic_cast<const RawDataBlock *>
00093      (RecMinos::FindComponent(classname, objname));
00094 }
00095 
00096 //_____________________________________________________________________________
00097 TIter RawRecord::GetRawBlockIter(Bool_t dir) const
00098 {
00099 
00100    // Get an iterator over the raw blocks
00101 
00102    PromoteRawDataBlocks();  // make sure that blocks are specialized
00103 
00104    return TIter(&RecMinos::GetComponents(),dir);
00105 }
00106 
00107 //_____________________________________________________________________________
00108 void RawRecord::AdoptRawBlock(RawDataBlock *rawblock)
00109 {
00110    // Adopt (to own) a RawDataBlock derived object
00111 
00112    RecMinos::AdoptComponent(rawblock);
00113 }
00114 
00115 //_____________________________________________________________________________
00116 void RawRecord::Print(Option_t *option) const
00117 {
00118    // Print header, loop over raw blocks, print those
00119    // unless passed "l" option, then just list the blocks.
00120 
00121    if (fHeader) fHeader->Print();
00122    else cout << "RawRecord: has no header";
00123    cout << endl;  // header doesn't terminate the line
00124    GetJobHistory().Print();
00125    
00126    string opt = option;
00127    if ( opt.find("l") != string::npos ) ListBlocks();
00128    else {
00129      TIter iter = this->GetRawBlockIter();
00130      TObject *tobj = 0;
00131      while ((tobj = iter())) tobj->Print(option);
00132    }
00133 }
00134 
00135 //_____________________________________________________________________________
00136 void RawRecord::AdoptComponent(TObject* component)
00137 {
00138    // Adopt (to own) a random TObject derived object
00139    // RawRecord should only be adopting RawDataBlocks
00140    // so this will assert before actually adopting.
00141 
00142    MSG("Raw",Msg::kFatal)
00143       << "RawRecord::AdoptComponent(TObject*) was called"
00144       << endl;
00145    assert(0);
00146 
00147    RecMinos::AdoptComponent(component);
00148 }
00149 
00150 //_____________________________________________________________________________
00151 void RawRecord::PromoteRawDataBlocks() const
00152 {
00153    // Look through list of blocks for generic 'RawDataBlock' objects;
00154    // convert these to specialized blocks based on block id.
00155 
00156   if (promotionChecked) return;
00157 
00158   const TString generic = "RawDataBlock";
00159   RawBlockRegistry& rbr = RawBlockRegistry::Instance();
00160 
00161   Int_t last = fComponents.GetLast();
00162   for (Int_t idx=0; idx <= last; ++idx) {
00163 
00164     TObject* tobj = fComponents[idx];
00165     if ( ! tobj ) continue;
00166 
00167     RawDataBlock* rdb = dynamic_cast<RawDataBlock*>(tobj);
00168     if ( ! rdb ) {
00169       // protect against serious suprises
00170       MSG("Raw",Msg::kWarning)
00171         << "Element " << idx << " in fComponents was not a RawDataBlock!"
00172         << endl;
00173       continue; 
00174     }
00175 
00176     if (generic != rdb->ClassName()) continue;
00177 
00178     // if we're here then the block is unspecialized
00179 
00180     RawBlockId rbid    = rdb->GetBlockId();
00181     RawBlockProxy* rbp = rbr.LookUp(rbid.IsDCS(),rbid.GetMajor());
00182 
00183     if (rbp) {
00184       // create a block of the right type
00185       RawDataBlock *specialBlk = rbp->CreateRawDataBlock(rdb->GetData());
00186       
00187       // a bit of nasty code so that this method can be considered
00188       // logical const even though it changes fComponents
00189       // we do it by index so that no ordering is changed in any way
00190       
00191       TObjArray& writable = const_cast<TObjArray&>(fComponents);
00192       
00193       writable.RemoveAt(idx);          // remove generic version
00194       writable.AddAt(specialBlk,idx);  // replace with specialized copy
00195       delete rdb;                      // delete generic version
00196 
00197       std::string finalClass = specialBlk->ClassName();
00198       unsigned long int curcount = (++fgPromoteCount[finalClass]);
00199 
00200       const unsigned long int maxmsg = 10;
00201       if (curcount <= maxmsg)
00202         MSG("Raw",Msg::kInfo)
00203           << "RawRecord promoted generic 'RawDataBlock'"
00204           << " to '" << finalClass << "'"
00205           << endl;
00206       if (curcount == maxmsg)
00207         MSG("Raw",Msg::kInfo) << "... last message for " << finalClass << endl;
00208     }
00209     else {
00210       // couldn't find an appropriate block id in the registry
00211       MSG("Raw",Msg::kWarning) 
00212         << "No proxy for RawBlockId "
00213         << "0x" << hex << rbid.GetMajor() << dec
00214         << ", can not promote to specialized block."
00215         << endl;
00216     }
00217     
00218   }  // loop over entries
00219 
00220   promotionChecked = true;
00221 }
00222 //_____________________________________________________________________________
00223 const char* RawRecord::GetName() const
00224 {
00225   // Return the "name"
00226   // If the TNamed value has been set use that otherwise see if
00227   // one can determine a useful name from the stream recorded in
00228   // the registry.
00229 
00230   string recUserName = TNamed::GetName();
00231   if (recUserName != "") return recUserName.c_str();
00232   else{
00233     //MSG("Raw",Msg::kInfo) << "Record has no name" << endl;
00234     const char* unknownStream = "?stream?";
00235     const char* tmp = 0;
00236     string recStream(unknownStream);
00237 
00238     const Registry& reg = GetTempTags();
00239     if (reg.Get("stream",tmp)) recStream = tmp;
00240     if (recStream != unknownStream) {
00241       // this method is logical "const" but it does modify the object
00242       RawRecord* writeableSelf = const_cast<RawRecord*>(this);
00243       writeableSelf->SetName(recStream.c_str());
00244       //MSG("Raw",Msg::kInfo) << "Record has is now named \"" 
00245       //                      << TNamed::GetName() << "\"" << endl;
00246     }
00247   }
00248   return TNamed::GetName();
00249 }
00250 
00251 //_____________________________________________________________________________
00252 void RawRecord::ListBlocks() const
00253 {
00254   // Lump the classname and block id for all the elements in fComponents.
00255   // Avoid anything that would promote generic blocks.
00256 
00257   MSG("Raw",Msg::kInfo)
00258     << "   index ClassName                 RawBlockId" 
00259     << endl;
00260 
00261    Int_t last = fComponents.GetLast();
00262    for (Int_t idx=0; idx <= last; ++idx) {
00263      TObject* tobj = fComponents[idx];
00264      if ( ! tobj ) continue;
00265      RawDataBlock* rdb = dynamic_cast<RawDataBlock*>(tobj);
00266      if (rdb) {
00267        RawBlockId rbid = rdb->GetBlockId();
00268        MSG("Raw",Msg::kInfo)
00269          << "    [" << setw(2) << idx << "] " 
00270          << left << setw(25) << tobj->ClassName()
00271          << resetiosflags(ios::adjustfield) // reset "left"
00272          << " " << rbid
00273          << endl;
00274      }
00275      else {
00276        MSG("Raw",Msg::kInfo)
00277          << "    [" << setw(2) << idx << "] " 
00278          << left << setw(25) << tobj->ClassName()
00279          << resetiosflags(ios::adjustfield) // reset "left"
00280          << " is not a RawDataBlock."
00281          << endl;
00282      }
00283    }
00284    
00285    MSG("Raw",Msg::kInfo) << endl;
00286 }
00287 
00288 //_____________________________________________________________________________
00289 void RawRecord::PrintPromotionCount()
00290 {
00291   // Print the number of times each type of RawDataBlock had to
00292   // be promoted to the non-generic class type
00293 
00294   if (fgPromoteCount.empty()) {
00295     MSG("Raw",Msg::kInfo)
00296       << "RawRecord promoted no RawDataBlocks to derived types"
00297       << endl;
00298   }
00299   else {
00300     MSG("Raw",Msg::kInfo)
00301       << "RawRecord promoted RawDataBlocks to derived types:"
00302       << endl;
00303 
00304     std::map<std::string,unsigned long int>::const_iterator pc_itr = 
00305       fgPromoteCount.begin();
00306     while (pc_itr != fgPromoteCount.end()) {
00307       MSG("Raw",Msg::kInfo)
00308         << "   " << pc_itr->first << " " 
00309         << pc_itr->second << " times "
00310         << endl;
00311       pc_itr++;
00312     }
00313   }
00314 }
00315 
00316 //_____________________________________________________________________________

Generated on Sat Nov 21 22:47:31 2009 for loon by  doxygen 1.3.9.1