| # Gaudi Framework, version v21r9 |

Home |  | Generated: 3 May 2010

# RCWNTupleCnv.cpp

Go to the documentation of this file.

    00001 // $Id: RCWNTupleCnv.cpp,v 1.17 2007/05/29 13:06:17 mato Exp $
    00002 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
    00003
    00004 #define ALLOW_ALL_TYPES
    00005
    00006
    00007 // Include files
    00008 #include "GaudiKernel/xtoa.h"
    00009 #include "GaudiKernel/CnvFactory.h"
    00010 #include "GaudiKernel/INTupleSvc.h"
    00011 #include "GaudiKernel/MsgStream.h"
    00012 #include "GaudiKernel/NTuple.h"
    00013
    00014 // Compiler include files
    00015 #include <cstdio>
    00016 #include <utility> /* std::pair */
    00017 #include <list>
    00018 #include <vector>
    00019
    00020 #include "RCWNTupleCnv.h"
    00021
    00022 #include "TTree.h"
    00023 #include "TLeafI.h"
    00024 #include "TLeafF.h"
    00025 #include "TLeafD.h"
    00026
    00027 // Instantiation of a static factory class used by clients to create
    00028 // instances of this service
    00029 DECLARE_NAMESPACE_CONVERTER_FACTORY(RootHistCnv,RCWNTupleCnv)
    00030
    00031 //-----------------------------------------------------------------------------
    00032 template <class T> void analyzeItem(std::string typ,
    00033                                     const NTuple::_Data<T>* it,
    00034                                     std::string& desc,
    00035                                     std::string& block_name,
    00036                                     std::string& var_name,
    00037                                     long& lowerRange, long& upperRange,
    00038                                     long& size)
    00039 //-----------------------------------------------------------------------------
    00040 {
    00041
    00042   std::string full_name;
    00043   full_name = it->name();
    00044   RootHistCnv::parseName(full_name,block_name,var_name);
    00045
    00046   long item_size = (sizeof(T) < 4) ? 4 : sizeof(T);
    00047   long dimension = it->length();
    00048   long ndim = it->ndim()-1;
    00049   char text[132];
    00050   desc += var_name;
    00051   if ( it->hasIndex() || it->length() > 1 )   {
    00052     desc += "[";
    00053   }
    00054   if ( it->hasIndex() )   {
    00055     std::string ind_blk, ind_var;
    00056     std::string ind = it->index();
    00057     RootHistCnv::parseName(ind,ind_blk,ind_var);
    00058     if (ind_blk != block_name) {
    00059       std::cerr << "ERROR: Index for CWNT variable " << ind_var
    00060                 << " is in a differnt block: " << ind_blk << std::endl;
    00061     }
    00062     desc += ind_var;
    00063   }
    00064   else if ( it->dim(ndim) > 1 )   {
    00065     desc += ::_itoa(it->dim(ndim), text, 10);
    00066   }
    00067
    00068   for ( int i = ndim-1; i>=0; i-- ){
    00069     desc += "][";
    00070     desc += ::_itoa(it->dim(i), text, 10);
    00071   }
    00072   if ( it->hasIndex() || it->length() > 1 )   {
    00073     desc += "]";
    00074   }
    00075
    00076   if (it->range().lower() != it->range().min() &&
    00077       it->range().upper() != it->range().max() ) {
    00078     lowerRange = (long) it->range().lower();
    00079     upperRange = (long) it->range().upper();
    00080   } else {
    00081     lowerRange = 0;
    00082     upperRange = -1;
    00083   }
    00084   desc += typ;
    00085   size += item_size * dimension;
    00086 }
    00087
    00088 //-----------------------------------------------------------------------------
    00089 StatusCode RootHistCnv::RCWNTupleCnv::book(const std::string& desc,
    00090                                            INTuple* nt,
    00091                                            TTree*& rtree)
    00092 //-----------------------------------------------------------------------------
    00093 {
    00094   MsgStream log(msgSvc(), "RCWNTupleCnv");
    00095   rtree = new TTree(desc.c_str(), nt->title().c_str());
    00096   log << MSG::VERBOSE << "created tree id: " << rtree->GetName()
    00097       << "  title: "<< nt->title() << " desc: " << desc << endmsg;
    00098
    00099   // Loop over the items
    00100
    00101   std::string block_name,var_name;
    00102   long lowerRange, upperRange;
    00103   long size = 0;
    00104   long cursize, oldsize = 0;
    00105   std::vector<std::string> item_fullname;
    00106   //    std::vector<long> item_size,item_size2;
    00107   std::vector<long> item_buf_pos, item_buf_len, item_buf_end;
    00108   std::vector<long> item_range_lower, item_range_upper;
    00109   std::vector<std::pair<std::string,std::string> > item_name;
    00110
    00111
    00112   const INTuple::ItemContainer& cols = nt->items();
    00113   for (INTuple::ItemContainer::const_iterator i = cols.begin();
    00114        i != cols.end(); ++i )   {
    00115     std::string item = "";
    00116
    00117     switch( (*i)->type() )   {
    00118     case DataTypeInfo::INT:               // int
    00119       analyzeItem(rootVarType( (*i)->type() ),
    00120                   dynamic_cast<const NTuple::_Data<int>*>(*i),item,
    00121                   block_name,var_name,lowerRange,upperRange,size);
    00122       break;
    00123     case DataTypeInfo::SHORT:             // short
    00124       analyzeItem(rootVarType( (*i)->type() ),
    00125                   dynamic_cast<const NTuple::_Data<short>*>(*i),item,
    00126                   block_name,var_name,lowerRange,upperRange,size);
    00127       break;
    00128     case DataTypeInfo::LONG:              // long
    00129       analyzeItem(rootVarType( (*i)->type() ),
    00130                   dynamic_cast<const NTuple::_Data<long>*>(*i),item,
    00131                   block_name,var_name,lowerRange,upperRange,size);
    00132       break;
    00133     case DataTypeInfo::UCHAR:             // unsigned char
    00134       analyzeItem(rootVarType( (*i)->type() ),
    00135                   dynamic_cast<const NTuple::_Data<unsigned char>*>(*i),
    00136                   item, block_name,var_name,lowerRange,upperRange,size);
    00137       break;
    00138     case DataTypeInfo::USHORT:            // unsigned short
    00139       analyzeItem(rootVarType( (*i)->type() ),
    00140                   dynamic_cast<const NTuple::_Data<unsigned short>*>(*i),
    00141                   item, block_name,var_name,lowerRange,upperRange,size);
    00142       break;
    00143     case DataTypeInfo::UINT:              // unsigned int
    00144       analyzeItem(rootVarType( (*i)->type() ),
    00145                   dynamic_cast<const NTuple::_Data<unsigned int>*>(*i),
    00146                   item, block_name,var_name,lowerRange,upperRange,size);
    00147       break;
    00148     case DataTypeInfo::ULONG:             // unsigned long
    00149       analyzeItem(rootVarType( (*i)->type() ),
    00150                   dynamic_cast<const NTuple::_Data<unsigned long>*>(*i),
    00151                   item, block_name,var_name,lowerRange,upperRange,size);
    00152       break;
    00153     case DataTypeInfo::DOUBLE:            // double
    00154       analyzeItem(rootVarType( (*i)->type() ),
    00155                   dynamic_cast<const NTuple::_Data<double>*>(*i),item,
    00156                   block_name,var_name,lowerRange,upperRange,size);
    00157       break;
    00158     case DataTypeInfo::FLOAT:             // float
    00159       analyzeItem(rootVarType( (*i)->type() ),
    00160                   dynamic_cast<const NTuple::_Data<float>*>(*i),item,
    00161                   block_name,var_name,lowerRange,upperRange,size);
    00162       break;
    00163     default:
    00164       break;
    00165     }
    00166
    00167     item_name.push_back(std::pair<std::string,std::string>(block_name,item));
    00168     cursize = size - oldsize;
    00169
    00170 //      log << MSG::WARNING << "item: " << item << " blk: " << block_name
    00171 //      << " var: " << var_name << " rng: " << lowerRange << " "
    00172 //      << upperRange << " sz: " << size << " " << cursize
    00173 //      << " buf_pos: " << size-cursize << endmsg;
    00174
    00175     item_fullname.push_back(var_name);
    00176     item_buf_pos.push_back(size-cursize);
    00177     item_buf_len.push_back(cursize);
    00178     item_buf_end.push_back(size);
    00179     item_range_lower.push_back(lowerRange);
    00180     item_range_upper.push_back(upperRange);
    00181
    00182     oldsize = size;
    00183   }
    00184
    00185   char* buff = new char[size];
    00186   log << MSG::VERBOSE << "Created buffer size: " << size << " at "
    00187       << (void*)buff << endmsg;
    00188
    00189   // Zero out the buffer to make ROOT happy
    00190   memset (buff,0,size);
    00191
    00192   // Tell the ntuple where it is
    00193   nt->setBuffer(buff);
    00194
    00195   char *buf_pos = buff;
    00196
    00197   std::vector<std::pair<std::string,std::string> >::const_iterator itr,end;
    00198   end = item_name.end();
    00199
    00200   // Loop over items, creating a new branch for each one;
    00201   unsigned int i_item = 0;
    00202   for (itr=item_name.begin(); itr!=end; ++itr, ++i_item) {
    00203
    00204     buf_pos = buff + item_buf_pos[i_item];
    00205
    00206 //      log << MSG::WARNING << "adding TBranch " << i_item << "  "
    00207 //      << item_fullname[i_item]
    00208 //      << "  format: " << itr->second.c_str() << "  at "
    00209 //      << (void*) buf_pos << " (" << (void*) buff << "+"
    00210 //      << (void*)item_buf_pos[i_item] << ")"
    00211 //      << endmsg;
    00212
    00213 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
    00214     TBranch *br = new TBranch(rtree,
    00215 #else
    00216     TBranch *br = new TBranch(
    00217 #endif
    00218                               item_fullname[i_item].c_str(),
    00219                               buf_pos,
    00220                               itr->second.c_str()
    00221                               );
    00222
    00223     if (itr->first != "AUTO_BLK") {
    00224       std::string tit = itr->first;
    00225       tit = itr->first + "::" + br->GetTitle();
    00226       br->SetTitle(tit.c_str());
    00227     }
    00228
    00229     log << MSG::DEBUG << "adding TBranch  " << br->GetTitle() << "  at "
    00230         << (void*) buf_pos << endmsg;
    00231
    00232
    00233     // for index items with a limited range. Must be a TLeafI!
    00234     if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
    00235 //        log << MSG::VERBOSE << "\"" << item_fullname[i_item]
    00236 //        << "\" is range limited " << item_range_lower[i_item] << "  "
    00237 //        << item_range_upper[i_item] << endmsg;
    00238       TLeafI *index = 0;
    00239       TObject *tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
    00240       if (tobj->IsA()->InheritsFrom("TLeafI")) {
    00241         index = dynamic_cast<TLeafI*>(tobj);
    00242
    00243         if (index != 0) {
    00244           index->SetMaximum( item_range_upper[i_item] );
    00245           // FIXME -- add for next version of ROOT
    00246           // index->SetMinimum( item_range_lower[i_item] );
    00247         } else {
    00248           log << MSG::ERROR << "Could dynamic cast to TLeafI: "
    00249               << item_fullname[i_item] << endmsg;
    00250         }
    00251       }
    00252     }
    00253
    00254     rtree->GetListOfBranches()->Add(br);
    00255
    00256   }
    00257
    00258
    00259   log << MSG::INFO << "Booked TTree with ID: " << desc
    00260       << " \"" << nt->title() << "\" in directory "
    00261       << getDirectory() << endmsg;
    00262
    00263   return StatusCode::SUCCESS;
    00264
    00265 }
    00266
    00267 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    00268
    00269 //-----------------------------------------------------------------------------
    00270 StatusCode RootHistCnv::RCWNTupleCnv::writeData(TTree* rtree, INTuple* nt)
    00271 //-----------------------------------------------------------------------------
    00272 {
    00273   // Fill the tree;
    00274   const INTuple::ItemContainer& cols = nt->items();
    00275   char * tar = nt->buffer();
    00276   for (INTuple::ItemContainer::const_iterator i = cols.begin(); i != cols.end(); i++ )   {
    00277     switch( (*i)->type() )   {
    00278     case DataTypeInfo::BOOL:              // bool
    00279       tar += saveItem(tar, (bool*)(*i)->buffer(),   (*i)->length());
    00280       break;
    00281     case DataTypeInfo::CHAR:              // char
    00282       tar += saveItem(tar, (char*)(*i)->buffer(),   (*i)->length());
    00283       break;
    00284     case DataTypeInfo::SHORT:             // short
    00285       tar += saveItem(tar, (short*)(*i)->buffer(),  (*i)->length());
    00286       break;
    00287     case DataTypeInfo::INT:             // int
    00288       tar += saveItem(tar, (int*)(*i)->buffer(),    (*i)->length());
    00289       break;
    00290     case DataTypeInfo::LONG:             // long
    00291       tar += saveItem(tar, (long*)(*i)->buffer(),   (*i)->length());
    00292       break;
    00293     case DataTypeInfo::UCHAR:             // unsigned char
    00294       tar += saveItem(tar, (unsigned char*)(*i)->buffer(),  (*i)->length());
    00295       break;
    00296     case DataTypeInfo::USHORT:            // unsigned short
    00297       tar += saveItem(tar, (unsigned short*)(*i)->buffer(), (*i)->length());
    00298       break;
    00299     case DataTypeInfo::UINT:            // unsigned int
    00300       tar += saveItem(tar, (unsigned int*)(*i)->buffer(),   (*i)->length());
    00301       break;
    00302     case DataTypeInfo::ULONG:            // unsigned long
    00303       tar += saveItem(tar, (unsigned long*)(*i)->buffer(),  (*i)->length());
    00304       break;
    00305     case DataTypeInfo::FLOAT:            // float
    00306       tar += saveItem(tar, (float*)(*i)->buffer(), (*i)->length());
    00307       break;
    00308     case DataTypeInfo::DOUBLE:            // double
    00309       tar += saveItem(tar, (double*)(*i)->buffer(), (*i)->length());
    00310       break;
    00311     default:
    00312       break;
    00313     }
    00314   }
    00315
    00316   rtree->Fill();
    00317   nt->reset();
    00318   return StatusCode::SUCCESS;
    00319 }
    00320
    00321
    00322 //-----------------------------------------------------------------------------
    00323 StatusCode RootHistCnv::RCWNTupleCnv::readData(TTree* rtree,
    00324                                                INTuple* ntup,
    00325                                                long ievt)
    00326 //-----------------------------------------------------------------------------
    00327 {
    00328   MsgStream log(msgSvc(), "RCWNTupleCnv::readData");
    00329
    00330   if (ievt >= rtree->GetEntries()) {
    00331     log << MSG::ERROR << "no more entries in tree to read. max: "
    00332         << rtree->GetEntries() << "  current: " << ievt
    00333         << endmsg;
    00334     return StatusCode::FAILURE;
    00335   }
    00336
    00337   rtree->GetEvent(ievt);
    00338
    00339   ievt++;
    00340
    00341   INTuple::ItemContainer& cols = ntup->items();
    00342   char * src = ntup->buffer();
    00343
    00344   // copy data from ntup->buffer() to ntup->items()->buffer()
    00345
    00346   for (INTuple::ItemContainer::iterator i = cols.begin(); i != cols.end(); i++ )   {
    00347
    00348 //      log << MSG::WARNING << "  " << (*i)->name() << ": " << (void*) src
    00349 //      << "   " << (*i)->length() << "  ";
    00350
    00351 //      int *idat;
    00352 //      float *fdat;
    00353 //      long *ldat;
    00354
    00355
    00356     switch( (*i)->type() )   {
    00357     case DataTypeInfo::BOOL:              // bool
    00358       src += loadItem(src, (bool*)(*i)->buffer(), (*i)->length());
    00359       break;
    00360     case DataTypeInfo::CHAR:              // char
    00361       src += loadItem(src, (char*)(*i)->buffer(), (*i)->length());
    00362       break;
    00363     case DataTypeInfo::SHORT:             // short
    00364       src += loadItem(src, (short*)(*i)->buffer(), (*i)->length());
    00365       break;
    00366     case DataTypeInfo::INT:             // short
    00367 //        idat = (int*) src;
    00368 //        log << *idat << endmsg;
    00369       src += loadItem(src, (int*)(*i)->buffer(), (*i)->length());
    00370       break;
    00371     case DataTypeInfo::LONG:             // short
    00372 //        ldat = (long*) src;
    00373 //        log << *ldat << endmsg;
    00374       src += loadItem(src, (long*)(*i)->buffer(), (*i)->length());
    00375       break;
    00376     case DataTypeInfo::UCHAR:             // unsigned char
    00377       src += loadItem(src, (unsigned char*)(*i)->buffer(), (*i)->length());
    00378       break;
    00379     case DataTypeInfo::USHORT:            // unsigned short
    00380       src += loadItem(src, (unsigned short*)(*i)->buffer(), (*i)->length());
    00381       break;
    00382     case DataTypeInfo::UINT:            // unsigned short
    00383       src += loadItem(src, (unsigned int*)(*i)->buffer(), (*i)->length());
    00384       break;
    00385     case DataTypeInfo::ULONG:            // unsigned short
    00386       src += loadItem(src, (unsigned long*)(*i)->buffer(), (*i)->length());
    00387       break;
    00388     case DataTypeInfo::FLOAT:            // unsigned short
    00389 //        fdat = (float*) src;
    00390 //        log << (*fdat) << endmsg;
    00391       src += loadItem(src, (float*)(*i)->buffer(), (*i)->length());
    00392       break;
    00393     case DataTypeInfo::DOUBLE:            // unsigned short
    00394       src += loadItem(src, (double*)(*i)->buffer(), (*i)->length());
    00395       break;
    00396     default:
    00397       break;
    00398     }
    00399
    00400   }
    00401
    00402   return StatusCode::SUCCESS;
    00403 }
    00404
    00405
    00406 //-----------------------------------------------------------------------------
    00407 StatusCode RootHistCnv::RCWNTupleCnv::load(TTree* tree, INTuple*& refpObject )
    00408 //-----------------------------------------------------------------------------
    00409 {
    00410   MsgStream log(msgSvc(), "RCWNTupleCnv::load");
    00411
    00412   StatusCode status;
    00413
    00414   NTuple::Tuple *pObj = 0;
    00415
    00416   std::string title = tree->GetTitle();
    00417   log << MSG::VERBOSE << "loading CWNT " << title << " at: "
    00418         << tree << endmsg;
    00419
    00420   status = m_ntupleSvc->create(CLID_ColumnWiseTuple, title, pObj);
    00421   INTuple* ntup = dynamic_cast<INTuple*>(pObj);
    00422
    00423   INTupleItem* item=0;
    00424
    00425   std::string itemName, indexName, item_type, itemTitle, blockName;
    00426   // long numEnt, numVar;
    00427   long size, totsize=0;
    00428   std::list< std::pair<TLeaf*,int> > itemList;
    00429
    00430   // numEnt = (int)tree->GetEntries();
    00431   // numVar = tree->GetNbranches();
    00432
    00433   // loop over all branches (==leaves)
    00434   TObjArray* lbr = tree->GetListOfBranches();
    00435   TIter bitr ( lbr );
    00436   while ( TObject *tobjb = bitr() ) {
    00437
    00438     TBranch* br = (TBranch*)tobjb;
    00439     itemTitle = br->GetTitle();
    00440
    00441     int ipos = itemTitle.find("::");
    00442     if (ipos >= 0) {
    00443       blockName = itemTitle.substr(0,ipos);
    00444     } else {
    00445       blockName = "";
    00446     }
    00447
    00448     TObjArray* lf = br->GetListOfLeaves();
    00449
    00450     TIter litr ( lf );
    00451     while ( TObject *tobj = litr() ) {
    00452
    00453       bool hasRange=false;
    00454       int indexRange = 0;
    00455       int itemSize;
    00456       item = 0;
    00457
    00458       //      TLeaf* tl = (TLeaf*)tobj;
    00459       TLeaf* tl = dynamic_cast<TLeaf*> (tobj);
    00460       itemName = tl->GetName();
    00461
    00462       //        char* buf_pos = (char*)tl->GetValuePointer();
    00463       //        cout << " " << itemName << "  " << blockName << "  "
    00464       //             << (void*)buf_pos;
    00465
    00466
    00467       if (blockName != "") {
    00468         log << MSG::DEBUG << "loading NTuple item " << blockName << "/"
    00469             << itemName;
    00470       } else {
    00471         log << MSG::DEBUG << "loading NTuple item " << itemName;
    00472       }
    00473
    00474       int arraySize;
    00475       TLeaf* indexLeaf = tl->GetLeafCounter(arraySize);
    00476
    00477       if (arraySize == 0) {
    00478         log << MSG::ERROR << "TLeaf counter size = 0. This should not happen!"
    00479             << endmsg;
    00480       }
    00481
    00482       if (indexLeaf != 0) {
    00483         //index Arrays and Matrices
    00484
    00485         indexName = indexLeaf->GetName();
    00486         //        indexRange = tl->GetNdata();
    00487         indexRange = indexLeaf->GetMaximum();
    00488         itemSize = indexRange * tl->GetLenType() * arraySize;
    00489
    00490         log << "[" << indexName;
    00491
    00492         // Just for Matrices
    00493         if (arraySize != 1) {
    00494           log << "][" << arraySize;
    00495         }
    00496         log << "]";
    00497
    00498       } else {
    00499         itemSize = tl->GetLenType() * arraySize;
    00500
    00501         indexName = "";
    00502
    00503         if (arraySize == 1) {
    00504           // Simple items
    00505         } else {
    00506           // Arrays of constant size
    00507           log << "[" << arraySize << "]";
    00508         }
    00509       }
    00510
    00511       log << endmsg;
    00512
    00513       //        cout << "  index: " << indexName <<  endl;
    00514
    00515       //        size = tl->GetNdata() * tl->GetLenType();
    00516       size = itemSize;
    00517       totsize += size;
    00518
    00519       hasRange = tl->IsRange();
    00520
    00521       itemList.push_back(std::pair<TLeaf*,int>(tl,itemSize));
    00522
    00523
    00524       // Integer
    00525       if (tobj->IsA()->InheritsFrom("TLeafI")) {
    00526
    00527         TLeafI *tli = dynamic_cast<TLeafI*>(tobj);
    00528         if (tli->IsUnsigned()) {
    00529           unsigned long min=0, max=0;
    00530           if (hasRange) {
    00531             min = tli->GetMinimum();
    00532             max = tli->GetMaximum();
    00533           }
    00534
    00535           item = createNTupleItem(itemName, blockName, indexName, indexRange,
    00536                                   arraySize,
    00537                                   min, max, ntup);
    00538         } else {
    00539           long min=0, max=0;
    00540           if (hasRange) {
    00541             min = tli->GetMinimum();
    00542             max = tli->GetMaximum();
    00543           }
    00544
    00545           item = createNTupleItem(itemName, blockName, indexName, indexRange,
    00546                                   arraySize,
    00547                                   min, max, ntup);
    00548         }
    00549
    00550         // Float
    00551       } else if (tobj->IsA()->InheritsFrom("TLeafF")) {
    00552         float min=0., max=0.;
    00553
    00554         TLeafF *tlf = dynamic_cast<TLeafF*>(tobj);
    00555         if (hasRange) {
    00556           min = float(tlf->GetMinimum());
    00557           max = float(tlf->GetMaximum());
    00558         }
    00559
    00560         item = createNTupleItem(itemName, blockName, indexName, indexRange,
    00561                                 arraySize,
    00562                                 min, max, ntup);
    00563
    00564         // Double
    00565       } else if (tobj->IsA()->InheritsFrom("TLeafD")) {
    00566         double min=0., max=0.;
    00567
    00568         TLeafD *tld = dynamic_cast<TLeafD*>(tobj);
    00569         if (hasRange) {
    00570           min = tld->GetMinimum();
    00571           max = tld->GetMaximum();
    00572         }
    00573
    00574         item = createNTupleItem(itemName, blockName, indexName, indexRange,
    00575                                 arraySize,
    00576                                 min, max, ntup);
    00577
    00578
    00579       } else {
    00580         log << MSG::ERROR << "Uknown data type" << endmsg;
    00581       }
    00582
    00583
    00584       if (item) {
    00585         ntup->add(item);
    00586       } else {
    00587         log << MSG::ERROR
    00588             << "Unable to create ntuple item \""
    00589             <<  itemName << "\"" << endmsg;
    00590       }
    00591
    00592     } // end litr
    00593   }   // end bitr
    00594
    00595   log << MSG::DEBUG << "Total buffer size of NTuple: " << totsize
    00596       << " Bytes." << endmsg;
    00597
    00598   char* buf = new char[totsize];
    00599   char* bufpos = buf;
    00600
    00601   ntup->setBuffer(buf);
    00602
    00603   std::list< std::pair<TLeaf*,int> >::const_iterator iitr = itemList.begin();
    00604   int ts = 0;
    00605   for (; iitr!= itemList.end(); ++iitr) {
    00606     TLeaf* leaf = (*iitr).first;
    00607     int isize   = (*iitr).second;
    00608
    00609     log << MSG::VERBOSE << "setting TBranch " << leaf->GetBranch()->GetName()
    00610         << " buffer at " << (void*) bufpos << endmsg;
    00611
    00612     leaf->GetBranch()->SetAddress((void*)bufpos);
    00613
    00614 //        //testing
    00615 //        if (leaf->IsA()->InheritsFrom("TLeafI")) {
    00616 //      for (int ievt=0; ievt<5; ievt++) {
    00617 //        leaf->GetBranch()->GetEvent(ievt);
    00618 //        int *idat = (int*)bufpos;
    00619 //        log << MSG::WARNING << leaf->GetName() << ": " << ievt << "   "
    00620 //            << *idat << endmsg;
    00621
    00622 //      }
    00623 //        }
    00624
    00625     ts += isize;
    00626
    00627     bufpos += isize;
    00628   }
    00629
    00630   if (totsize != ts ) {
    00631     log << MSG::ERROR << "buffer size mismatch: " << ts << "  " << totsize
    00632         << endmsg;
    00633   }
    00634
    00635   refpObject = ntup;
    00636
    00637   return StatusCode::SUCCESS;
    00638 }
    00639
    00640