Anonymous avatar Anonymous committed 0ab112c Merge

sync w/ atlasoff

Comments (0)

Files changed (30)

File contents unchanged.

File contents unchanged.

File contents unchanged.

Add a comment to this file

python/AthenaRootBase.py

File contents unchanged.

Add a comment to this file

python/OutputStreamAthenaRoot.py

File contents unchanged.

Add a comment to this file

python/ReadAthenaRoot.py

File contents unchanged.

Add a comment to this file

share/tests/test_athena_ntuple_dumper.py

File contents unchanged.

share/tests/test_athena_variable_shape_ntuple.py

+from glob import glob
+if 1:
+    _cbntfiles = [
+        'root://eosatlas//eos/atlas/user/b/binet/utests/utests/filter-d3pd/ntuple.0.root',
+        'root://eosatlas//eos/atlas/user/b/binet/utests/utests/filter-d3pd/ntuple.1.root',
+        ]
+    # _cbntfiles = [
+    #     '/tmp/binet/data/ntuple.0.root',
+    #     '/tmp/binet/data/ntuple.1.root',
+    #     ]
+    
+if 0:
+    _cbntfiles = [
+        'root://eosatlas//eos/atlas/user/b/binet/utests/utests/filter-d3pd/small.ntuple.0.root',
+        'root://eosatlas//eos/atlas/user/b/binet/utests/utests/filter-d3pd/small.ntuple.1.root',
+        ]
+    _cbntfiles = [
+        '/tmp/binet/data/small.ntuple.0.root',
+        '/tmp/binet/data/small.ntuple.1.root',
+        ]
+if not 'FNAMES' in dir():
+    FNAMES = _cbntfiles[:]
+
+if not isinstance(FNAMES, (list,tuple)):
+    FNAMES = [FNAMES]
+    pass
+
+import AthenaRootComps.ReadAthenaRoot
+svcMgr.EventSelector.InputCollections = FNAMES
+svcMgr.EventSelector.TupleName = "egamma"
+
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+
+from AthenaPython import PyAthena
+StatusCode = PyAthena.StatusCode
+
+class MyAlg( PyAthena.Alg ):
+
+    def __init__(self, name='MyAlg', **kw):
+        kw['name'] = name
+        self.activeBranches = kw.get(
+            'activeBranches',
+            ['RunNumber',
+             'EventNumber',
+             'el_n',
+             'el_eta',
+             'el_jetcone_dr',
+             ])
+        super(MyAlg, self).__init__(**kw)
+        return
+
+    def initialize(self):
+        self.evtstore = PyAthena.py_svc('StoreGateSvc')
+        
+        return StatusCode.Success
+
+    def execute(self):
+        self.msg.info('running execute...')
+        #keys = self.evtstore.keys()
+        for br in self.activeBranches:
+            try:
+                o = self.evtstore[br]
+                if hasattr(o, 'at'):
+                    o = list(o)
+                    for i,v in enumerate(o):
+                        if hasattr(v, 'at') and not isinstance(v, (basestring,)):
+                            o[i] = list(v)
+                self.msg.info('%s: %r', br, o)
+            except Exception, err:
+                self.msg.info(' --> err for [%s]: %s' % (br, err))
+                pass
+        return StatusCode.Success
+
+    def finalize(self):
+        return StatusCode.Success
+
+    pass # MyAlg
+
+from AthenaCommon.AlgSequence import AlgSequence
+job = AlgSequence()
+job += MyAlg('py_alg')
+
+if 'BRANCHES' in dir():
+    job.py_alg.activeBranches = BRANCHES
+    pass
+
+if not 'EVTMAX' in dir():
+    EVTMAX=-1
+theApp.EvtMax = EVTMAX
+
+if not 'DOWRITE' in dir():
+    DOWRITE=1
+if DOWRITE:
+    svcMgr += CfgMgr.DecisionSvc()
+    import AthenaRootComps.WriteAthenaRoot as arcw
+    out = arcw.createNtupleOutputStream("StreamD3PD", "d3pd.root", "egamma")
+    if not 'OUTBRANCHES' in dir():
+        OUTBRANCHES=[
+            "el_n",
+            "el_eta",
+            "el_jetcone_dr",
+            ]
+    out.ItemList += OUTBRANCHES
+    out.ForceRead = True
+

src/RootAsciiDumperAlgHandle.cxx

+///////////////////////// -*- C++ -*- /////////////////////////////
+// RootAsciiDumperAlgHandle.cxx 
+// Implementation file for class RootAsciiDumperAlgHandle
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+
+// AthenaRootComps includes
+#include "RootAsciiDumperAlgHandle.h"
+
+// STL includes
+#include <sstream>
+#include <stdio.h>
+// to get the printing format specifiers (e.g. PRId64)
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
+// linux i/o includes
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+
+// SGTools
+#include "SGTools/BuiltinsClids.h"  // to put ints,... in evtstore
+#include "SGTools/StlVectorClids.h" // to put std::vectors... in evtstore
+
+namespace Athena {
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+RootAsciiDumperAlgHandle::RootAsciiDumperAlgHandle( const std::string& name, 
+			  ISvcLocator* pSvcLocator ) : 
+  ::AthAlgorithm( name, pSvcLocator ),
+  m_ofname(""),
+  m_ofd(-1),
+  m_nentries(0),
+  m_runnbr(),
+  m_evtnbr(),
+  m_el_n(),
+  m_el_eta(),
+  m_el_jetcone_dr()
+{
+  //
+  // Property declaration
+  // 
+  //declareProperty( "Property", m_nProperty );
+
+  declareProperty("AsciiFileName",
+                  m_ofname = "d3pd.ascii",
+                  "Name of the ascii file where the content of the "
+                  "ROOT n-tuple file will be dumped.");
+
+  declareProperty("RunNumber",
+                  m_runnbr = SG::RVar<uint32_t>("RunNumber"),
+                  "handle to the run-nbr in event (read)");
+
+  declareProperty("EventNumber",
+                  m_evtnbr = SG::RVar<uint32_t>("EventNumber"),
+                  "handle to the evt-nbr in event (read)");
+
+  declareProperty("el_n",
+                  m_el_n = SG::RVar<int32_t>("el_n"),
+                  "handle to the nbr of electrons in event (read)");
+
+  declareProperty("el_eta",
+                  m_el_eta = SG::RVar<std::vector<float> >("el_eta"),
+                  "handle to the eta of electrons in event (read)");
+
+  declareProperty("el_jetcone_dr",
+                  m_el_jetcone_dr = SG::RVar<std::vector<std::vector<float> > >("el_jetcone_dr"),
+                  "handle to the jetcone-dR of electrons in event (read)");
+
+}
+
+// Destructor
+///////////////
+RootAsciiDumperAlgHandle::~RootAsciiDumperAlgHandle()
+{}
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode RootAsciiDumperAlgHandle::initialize()
+{
+  ATH_MSG_INFO ("Initializing " << name() << "...");
+
+  ATH_MSG_INFO("dumping data into file ["
+               << m_ofname << "]...");
+  if (m_ofname.empty()) {
+    ATH_MSG_ERROR("cannot dump data into an empty file name!");
+    return StatusCode::FAILURE;
+  }
+  m_ofd = open(m_ofname.c_str(), 
+               O_WRONLY | O_CREAT | O_TRUNC,
+               S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+  if (m_ofd < 0) {
+    ATH_MSG_ERROR("problem opening file [" << m_ofname << "] with "
+                  "write permissions.");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode RootAsciiDumperAlgHandle::finalize()
+{
+  ATH_MSG_INFO ("Finalizing " << name() << "...");
+
+  if (m_ofd > 0) {
+    fflush(NULL);
+    if (close(m_ofd) < 0) {
+      ATH_MSG_WARNING("problem while closing [" << m_ofname << "]");
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode RootAsciiDumperAlgHandle::execute()
+{  
+  ATH_MSG_DEBUG ("Executing " << name() << "...");
+
+  uint64_t nevts = m_nentries;
+  m_nentries += 1;
+
+  if (!m_runnbr.ptr()) {
+    ATH_MSG_WARNING("could not retrieve [" << m_runnbr.name() 
+                    << "] from store");
+    return StatusCode::RECOVERABLE;
+  }
+
+  if (!m_evtnbr.ptr()) {
+    ATH_MSG_WARNING("could not retrieve [" << m_evtnbr.name() 
+                    << "] from store");
+    return StatusCode::RECOVERABLE;
+  }
+
+  if (!m_el_n.ptr()) {
+    ATH_MSG_WARNING("could not retrieve [" << m_el_n.name() 
+                    << "] from store");
+    return StatusCode::RECOVERABLE;
+  }
+
+  {
+    char* buf = 0;
+    int buf_sz = asprintf
+      (&buf,
+       "%03" PRId64 ".%s = %u\n"
+       "%03" PRId64 ".%s = %u\n"
+       "%03" PRId64 ".%s = %i\n",
+       nevts,
+       "RunNumber",
+       *m_runnbr,
+       nevts,
+       "EventNumber",
+       *m_evtnbr,
+       nevts,
+       "el_n",
+       *m_el_n);
+    write(m_ofd, buf, buf_sz);
+    free(buf);
+  }
+
+  if (*m_el_n > 0) {
+    if (!m_el_eta.ptr()) {
+      ATH_MSG_WARNING("could not retrieve [" << m_el_eta.name() 
+                      << "] from store");
+      return StatusCode::RECOVERABLE;
+    }
+    
+    if (!m_el_jetcone_dr.ptr()) { 
+      ATH_MSG_WARNING("could not retrieve [" << m_el_jetcone_dr.name() 
+                      << "] from store");
+      return StatusCode::RECOVERABLE;
+    }
+    
+    {
+      std::stringstream bufv;
+      for (int32_t ii = 0; ii < *m_el_n; ++ii) {
+        bufv << (*m_el_eta)[ii];
+        if (ii != (*m_el_n)-1) {
+          bufv << ", ";
+        }
+      }
+      char* buf = 0;
+      int buf_sz = asprintf
+        (&buf,
+         "%03" PRId64 ".%s = [%s]\n",
+         nevts,
+         "el_eta",
+         bufv.str().c_str());
+      write(m_ofd, buf, buf_sz);
+      free(buf);
+    }
+
+
+    {
+      std::stringstream bufv;
+      for (int32_t ii = 0; ii < *m_el_n; ++ii) {
+        bufv << "[";
+        for (std::size_t jj = 0, jjmax = (*m_el_jetcone_dr)[ii].size();
+             jj < jjmax;
+             ++jj) {
+          bufv << (*m_el_jetcone_dr)[ii][jj];
+          if (jj != jjmax-1) {
+            bufv << ", ";
+          }
+        }
+        bufv << "]";
+        if (ii != (*m_el_n)-1) {
+          bufv << ", ";
+        }
+      }
+      char* buf = 0;
+      int buf_sz = asprintf
+        (&buf,
+         "%03" PRId64 ".%s = [%s]\n",
+         nevts,
+         "el_jetcone_dr",
+         bufv.str().c_str());
+      write(m_ofd, buf, buf_sz);
+      free(buf);
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Protected methods: 
+/////////////////////////////////////////////////////////////////// 
+
+/////////////////////////////////////////////////////////////////// 
+// Const methods: 
+///////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Non-const methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace Athena

src/RootAsciiDumperAlgHandle.h

+///////////////////////// -*- C++ -*- /////////////////////////////
+// RootAsciiDumperAlgHandle.h 
+// Header file for class RootAsciiDumperAlgHandle
+// Author: S.Binet<binet@cern.ch>
+/////////////////////////////////////////////////////////////////// 
+#ifndef ATHENAROOTCOMPS_ATHENA_ROOTASCIIDUMPERALGHANDLE_H
+#define ATHENAROOTCOMPS_ATHENA_ROOTASCIIDUMPERALGHANDLE_H 1
+
+// STL includes
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+namespace Athena {
+
+class RootAsciiDumperAlgHandle
+  : public ::AthAlgorithm
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  RootAsciiDumperAlgHandle( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~RootAsciiDumperAlgHandle(); 
+
+  // Assignment operator: 
+  //RootAsciiDumperAlgHandle &operator=(const RootAsciiDumperAlgHandle &alg); 
+
+  // Athena algorithm's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  execute();
+  virtual StatusCode  finalize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  RootAsciiDumperAlgHandle();
+
+  /// ASCII output file name
+  std::string m_ofname;
+
+  /// file handle to the ASCII output file
+  int m_ofd;
+  
+  /// number of entries processed so-far
+  uint64_t m_nentries;
+
+  /// run number
+  SG::RVar<uint32_t> m_runnbr;
+
+  /// event number
+  SG::RVar<uint32_t> m_evtnbr;
+
+  /// number of electrons
+  SG::RVar<int32_t> m_el_n;
+
+  /// eta of electrons
+  SG::RVar<std::vector<float> > m_el_eta;
+
+  /// jetcone dR
+  SG::RVar<std::vector<std::vector<float> > > m_el_jetcone_dr;
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+} //> end namespace Athena
+#endif //> !ATHENAROOTCOMPS_ATHENA_ROOTASCIIDUMPERALGHANDLE_H

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

File contents unchanged.

Add a comment to this file

src/RootNtupleEventSelector.cxx

File contents unchanged.

Add a comment to this file

src/RootNtupleEventSelector.h

File contents unchanged.

src/RootNtupleOutputStream.cxx

+#include <cassert>
+#include <string>
+#include <vector>
+#include <fnmatch.h>
+
+// Framework include files
+#include "GaudiKernel/GaudiException.h"
+#include "GaudiKernel/Tokenizer.h"
+#include "GaudiKernel/AlgFactory.h"
+#include "GaudiKernel/IAlgManager.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IOpaqueAddress.h"
+#include "GaudiKernel/IProperty.h"
+#include "GaudiKernel/ClassID.h"
+
+#include "AthenaKernel/IClassIDSvc.h"
+#include "AthenaKernel/IAthenaOutputTool.h"
+#include "AthenaKernel/IAthenaOutputStreamTool.h"
+
+#include "StoreGate/StoreGateSvc.h"
+#include "SGTools/DataProxy.h"
+#include "SGTools/ProxyMap.h"
+#include "SGTools/SGIFolder.h"
+
+#include "RootNtupleOutputStream.h"
+
+namespace Athena {
+
+// Standard Constructor
+RootNtupleOutputStream::RootNtupleOutputStream(const std::string& name, ISvcLocator* pSvcLocator)
+  : FilteredAlgorithm(name, pSvcLocator),
+    m_dataStore("StoreGateSvc", name),
+    m_pCLIDSvc("ClassIDSvc", name),
+    // m_p2BWritten(string("SG::Folder/") + name + string("_TopFolder"), this),
+    // m_decoder(string("SG::Folder/") + name + string("_excluded"), this),
+    m_streamer(std::string("AthenaOutputStreamTool/") + 
+	       name + std::string("Tool"), this),
+   m_helperTools(this) 
+{
+  assert(pSvcLocator);
+  declareProperty("ItemList",               m_itemList);
+  declareProperty("OutputFile",             m_outputName="DidNotNameOutput.root");
+  declareProperty("EvtConversionSvc",       m_persName="EventPersistencySvc");
+  declareProperty("WritingTool",            m_streamer);
+  declareProperty("Store",                  m_dataStore);
+  declareProperty("ProcessingTag",          m_processTag=name);
+  declareProperty("ForceRead",              m_forceRead=false);
+  declareProperty("PersToPers",             m_persToPers=false);
+  declareProperty("ExemptPersToPers",       m_exemptPersToPers);
+  declareProperty("ProvideDef",             m_provideDef=false);
+  declareProperty("WriteOnExecute",         m_writeOnExecute=true);
+  declareProperty("WriteOnFinalize",        m_writeOnFinalize=false);
+  declareProperty("TakeItemsFromInput",     m_itemListFromTool=false);
+  // declareProperty("CheckNumberOfWrites",    m_checkNumberOfWrites=true);
+  declareProperty("CommitOnStop",           m_commitOnStop=false);
+  //declareProperty("ExcludeList",            m_excludeList);
+  declareProperty("HelperTools",            m_helperTools);
+
+  declareProperty("DynamicItemList",
+		  m_dynamicItemList = false,
+		  "dynamic output itemlist:\n" \
+		  "  if enabled rediscover object list to be written out at each event\n" \
+		  "  otherwise: reuse the one from the first event.");
+}
+
+// Standard Destructor
+RootNtupleOutputStream::~RootNtupleOutputStream() 
+{}
+
+// initialize data writer
+StatusCode 
+RootNtupleOutputStream::initialize() 
+{
+  ATH_MSG_DEBUG("In initialize");
+  if (!this->FilteredAlgorithm::initialize().isSuccess()) {
+    ATH_MSG_ERROR("could not initialize base class");
+    return StatusCode::FAILURE;
+  }
+
+  // Reset the number of events written
+  m_events = 0;
+
+  // set up the SG service:
+  if (!m_dataStore.retrieve().isSuccess()) {
+    ATH_MSG_FATAL("Could not locate default store");
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG("Found " << m_dataStore.type() << " store.");
+  }
+  assert(static_cast<bool>(m_dataStore));
+
+  // set up the CLID service:
+  if (!m_pCLIDSvc.retrieve().isSuccess()) {
+    ATH_MSG_FATAL("Could not locate default ClassIDSvc");
+    return StatusCode::FAILURE;
+  }
+  assert(static_cast<bool>(m_pCLIDSvc));
+
+  // Get Output Stream tool for writing
+  if (!m_streamer.retrieve().isSuccess()) {
+    ATH_MSG_FATAL("Can not find " << m_streamer);
+    return StatusCode::FAILURE;
+  }
+   
+  const bool extendProvenanceRecord = true;
+  if (!m_streamer->connectServices(m_dataStore.type(), 
+				   m_persName, 
+				   extendProvenanceRecord).isSuccess()) {
+    ATH_MSG_FATAL("Unable to connect services");
+    return StatusCode::FAILURE;
+  }
+
+  if (!m_helperTools.retrieve().isSuccess()) {
+    ATH_MSG_FATAL("Can not find " << m_helperTools);
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("Found " << m_helperTools << endreq << "Data output: " << m_outputName);
+
+  bool allgood = true;
+  for (std::vector<ToolHandle<IAthenaOutputTool> >::const_iterator 
+	 iter = m_helperTools.begin(),
+	 iend = m_helperTools.end();
+       iter != iend; 
+       ++iter) {
+    if (!(*iter)->postInitialize().isSuccess()) {
+      allgood = false;
+    }
+  }
+  if (!allgood) {
+    ATH_MSG_ERROR("problem in postInitialize of a helper tool");
+    return StatusCode::FAILURE;
+  }
+
+  // For 'write on finalize', we set up listener for 'LastInputFile'
+  // and perform write at this point. This happens at 'stop' of the
+  // event selector. RDS 04/2010
+  if (m_writeOnFinalize) {
+    // Set to be listener for end of event
+    ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", this->name());
+    if (!incSvc.retrieve().isSuccess()) {
+      ATH_MSG_ERROR("Cannot get the IncidentSvc");
+      return StatusCode::FAILURE;
+    } else {
+      ATH_MSG_DEBUG("Retrieved IncidentSvc");
+    }
+    incSvc->addListener(this, "MetaDataStop", 50);
+    ATH_MSG_DEBUG("Added MetaDataStop listener");
+  }
+  ATH_MSG_DEBUG("End initialize");
+  return StatusCode::SUCCESS;
+}
+
+void 
+RootNtupleOutputStream::handle(const Incident& inc) 
+{
+   ATH_MSG_DEBUG("handle() incident type: " << inc.type());
+   static const std::string s_METADATASTOP = "MetaDataStop";
+   if (inc.type() == s_METADATASTOP) {
+     // Moved preFinalize of helper tools to stop - want to optimize the
+     // output file in finalize RDS 12/2009
+     for (std::vector<ToolHandle<IAthenaOutputTool> >::const_iterator 
+	    iter = m_helperTools.begin(),
+	    iend = m_helperTools.end();
+	  iter != iend; 
+	  ++iter) {
+       if (!(*iter)->preFinalize().isSuccess()) {
+	 ATH_MSG_ERROR("Cannot finalize helper tool");
+       }
+     }
+     // Always force a final commit in stop - mainly applies to AthenaPool 
+     if (m_writeOnFinalize) {
+       if (!write().isSuccess()) {  // true mean write AND commit
+	 ATH_MSG_ERROR("Cannot write on finalize");
+       }
+     } else if (m_commitOnStop) {
+       // If we don't write on finalize, do final commit if requested
+       if (m_streamer->connectOutput(m_outputName).isFailure()) {
+	 ATH_MSG_ERROR("Cannot connect to output file: " << m_outputName);
+       } else if (m_streamer->commitOutput().isFailure()) {
+	 ATH_MSG_ERROR("commit failed!");
+       } else {
+	 ATH_MSG_INFO("Did final commit");
+       }
+     }
+   }
+   ATH_MSG_INFO("Records written: " << m_events);
+   ATH_MSG_DEBUG("Leaving handle");
+}
+
+// terminate data writer
+StatusCode 
+RootNtupleOutputStream::finalize() 
+{
+  bool failed = false;
+  ATH_MSG_DEBUG("finalize: Optimize output");
+  // Connect the output file to the service
+  if (!m_streamer->finalizeOutput().isSuccess()) {
+    failed = true;
+  }
+  ATH_MSG_DEBUG("finalize: end optimize output");
+  if (!m_helperTools.release().isSuccess()) {
+    failed = true;
+  }
+  if (!m_streamer.release().isSuccess()) {
+    failed = true;
+  }
+  return failed 
+    ? StatusCode::FAILURE 
+    : StatusCode::SUCCESS;
+}
+
+StatusCode
+RootNtupleOutputStream::execute() 
+{
+  bool failed = false;
+  for (std::vector<ToolHandle<IAthenaOutputTool> >::const_iterator 
+	 iter = m_helperTools.begin(),
+	 iend = m_helperTools.end();
+       iter != iend; 
+       ++iter) {
+    if (!(*iter)->preExecute().isSuccess()) {
+      failed = true;
+    }
+  }
+  if (m_writeOnExecute) {
+    if (!write().isSuccess()) {
+      failed = true;
+    }
+  }
+  for (std::vector<ToolHandle<IAthenaOutputTool> >::const_iterator 
+	 iter = m_helperTools.begin(),
+	 iend = m_helperTools.end();
+       iter != iend; 
+       ++iter) {
+    if(!(*iter)->postExecute().isSuccess()) {
+      failed = true;
+    }
+  }
+
+  return failed 
+    ? StatusCode::FAILURE 
+    : StatusCode::SUCCESS;
+}
+
+// Work entry point
+StatusCode
+RootNtupleOutputStream::write() 
+{
+  bool failed = false;
+  // Clear any previously existing item list
+  clearSelection();
+  // Test whether this event should be output
+  if (isEventAccepted()) {
+    // Connect the output file to the service
+    if (m_streamer->connectOutput(m_outputName).isSuccess()) {
+      // First check if there are any new items in the list
+      collectAllObjects();
+      StatusCode sc = m_streamer->streamObjects(m_objects);
+      // Do final check of streaming
+      if (!sc.isSuccess()) {
+	if (!sc.isRecoverable()) {
+	  ATH_MSG_FATAL("streamObjects failed.");
+	  failed = true;
+	} else {
+	  ATH_MSG_DEBUG("streamObjects failed.");
+	}
+      }
+      sc = m_streamer->commitOutput();
+      if (!sc.isSuccess()) {
+	ATH_MSG_FATAL("commitOutput failed.");
+	failed = true;
+      }
+      clearSelection();
+      if (!failed) {
+	m_events++;
+      }
+    }
+  }
+
+  return failed
+    ? StatusCode::FAILURE
+    : StatusCode::SUCCESS;
+}
+
+// Clear collected object list
+inline
+void 
+RootNtupleOutputStream::clearSelection()
+{
+  m_objects.resize(0);
+  if (m_dynamicItemList) {
+    m_selection.resize(0);
+  }
+}
+
+void
+RootNtupleOutputStream::collectAllObjects() 
+{
+  typedef std::vector<SG::FolderItem> Items_t;
+
+  if (!m_dynamicItemList && !m_selection.empty()) {
+    // reuse object list from previous event.
+  } else {
+
+    // if (m_itemListFromTool) {
+    //   //FIXME:
+    //   //   if (!m_streamer->getInputItemList(&*m_p2BWritten).isSuccess()) {
+    //   //     ATH_MSG_WARNING("collectAllObjects() could not get ItemList from Tool.");
+    //   //   }
+    // }
+
+    static const std::string s_plus = "+";
+    static const std::string s_dash = "-";
+    typedef std::vector<const SG::DataProxy*> Proxies_t;
+    Proxies_t proxies = m_dataStore->proxies();
+
+    const std::vector<std::string>& items = m_itemList.value();
+    std::vector<std::string> toremove; 
+    toremove.reserve(items.size());
+
+    Items_t selection; 
+    selection.reserve(items.size());
+
+    for (Proxies_t::const_iterator
+	   iproxy = proxies.begin(),
+	   iend = proxies.end();
+	 iproxy != iend;
+	 ++iproxy) {
+      const SG::DataProxy *proxy = *iproxy;
+      if (!proxy) {
+	continue;
+      }
+      for (std::vector<std::string>::const_iterator
+	     jkey = items.begin(),
+	     jend = items.end();
+	   jkey != jend;
+	   ++jkey) {
+	if (!jkey->empty()) {
+	  if ((*jkey)[0] == s_dash[0]) {
+	    toremove.push_back(jkey->substr(1, std::string::npos));
+	    continue;
+	  }
+	  std::string key = *jkey;
+	  if ((*jkey)[0] == s_plus[0]) {
+	    key = jkey->substr(1, std::string::npos);
+	  }
+	  int o = fnmatch(key.c_str(), 
+			  proxy->name().c_str(),
+			  FNM_PATHNAME);
+	  if (o == 0) {
+	    // accept
+	    selection.push_back(SG::FolderItem(proxy->clID(), proxy->name()));
+	    break;
+	  }
+	}
+      }
+    }
+
+    m_selection.reserve(selection.size());
+    if (toremove.empty()) {
+      m_selection = selection;
+    } else {
+      for(Items_t::const_iterator 
+	    isel=selection.begin(),
+	    iend=selection.end();
+	  isel != iend;
+	  ++isel) {
+	const std::string &name = isel->key();
+	bool keep = true;
+	for (std::vector<std::string>::const_iterator
+	       jkey = toremove.begin(),
+	       jend = toremove.end();
+	     jkey != jend;
+	     ++jkey) {
+	  const std::string& key = *jkey;
+	  int o = fnmatch(key.c_str(), 
+			  name.c_str(),
+			  FNM_PATHNAME);
+	  if (o == 0) {
+	    // reject
+	    keep = false;
+	    break;
+	  }
+	}
+	if (keep) {
+	  m_selection.push_back(*isel);
+	}
+      }
+    }
+  }
+
+  for (Items_t::const_iterator
+	 itr = m_selection.begin(),
+	 iend = m_selection.end();
+       itr != iend;
+       ++itr) {
+    const std::string &name = itr->key();
+    SG::DataProxy *proxy = m_dataStore->proxy(itr->id(), name);
+    if (NULL == proxy) {
+      continue;
+    }
+    if (m_forceRead && proxy->isValid()) {
+      if (!m_persToPers) {
+        if (NULL == proxy->accessData()) {
+          ATH_MSG_ERROR(" Could not get data object for id "
+                        << proxy->clID() << ",\"" << proxy->name());
+        }
+      } else if (true /*m_exemptPersToPers.find(item.id()) != m_exemptPersToPers.end()*/) {
+        if (NULL == proxy->accessData()) {
+          ATH_MSG_ERROR(" Could not get data object for id "
+                        << proxy->clID() << ",\"" << proxy->name());
+        }
+      }
+    }
+    DataObject *obj = proxy->object();
+    if (NULL != obj) {
+      m_objects.push_back(obj);
+      ATH_MSG_DEBUG(" Added object " << proxy->clID() << ",\"" << proxy->name() << "\"");
+	  // if (m_checkNumberOfWrites && !m_provideDef) {
+	  //   std::string tn;
+	  //   if (!m_pCLIDSvc->getTypeNameOfID(item.id(), tn).isSuccess()) {
+	  //     ATH_MSG_ERROR(" Could not get type name for id "
+	  // 		    << item.id() << ",\"" << itemProxy->name());
+	  //   } else {
+	  //     tn += '_' + itemProxy->name();
+	  //     CounterMapType::iterator cit = m_objectWriteCounter.find(tn);
+	  //     if (cit == m_objectWriteCounter.end()) {
+	  // 	// First time through
+	  // 	//std::pair<CounterMapType::iterator, bool> result =
+	  // 	m_objectWriteCounter.insert(CounterMapType::value_type(tn, 1));
+	  //     } else {
+	  // 	// set to next iteration (to avoid double counting)
+	  // 	// StreamTools will eliminate duplicates.
+	  // 	(*cit).second = m_events + 1;
+	  //     }
+	  //   }
+	  // }
+	// } else if (!m_forceRead && m_persToPers && proxy->isValid()) {
+	//   tAddr = itemProxy->transientAddress();
+    } //if data object there
+  }
+
+  return;
+}
+
+} //> ns Athena
+

src/RootNtupleOutputStream.h

+// Dear emacs, this is -*- C++ -*-
+#ifndef ATHENAROOTCOMPS_ROOTNTUPLEOUTPUTSTREAM_H
+#define ATHENAROOTCOMPS_ROOTNTUPLEOUTPUTSTREAM_H
+
+// STL include files
+#include <memory>
+#include <map>
+#include <set>
+#include <vector>
+#include <string>
+
+// fwk includes
+#include "GaudiKernel/IDataSelector.h"
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/IIncidentListener.h"
+#include "AthenaBaseComps/FilteredAlgorithm.h"
+
+// forward declarations
+template <class ConcreteAlgorithm> class AlgFactory;
+class IClassIDSvc;
+class StoreGateSvc;
+class IAthenaOutputStreamTool;
+class IAthenaOutputTool;
+
+namespace SG {
+   class DataProxy;
+   class IFolder;
+   class FolderItem;
+}
+
+namespace Athena {
+
+/** @class Athena::RootNtupleOutputStream
+   * @brief algorithm that marks for write data objects in SG
+   * 
+   * @author binet@cern.ch
+   * $Id$
+   */
+class RootNtupleOutputStream 
+  : virtual public IIncidentListener,
+            public FilteredAlgorithm
+{
+  friend class AlgFactory<Athena::RootNtupleOutputStream>;
+
+public:
+  typedef std::vector<SG::DataProxy*>     Items;
+
+protected:
+  /// handle to the @c StoreGateSvc store where the data we want to
+  /// write out resides
+  ServiceHandle<StoreGateSvc> m_dataStore;
+
+  /// Name of the persistency service capable to write data from the store
+  std::string              m_persName;
+  /// Name of the OutputStreamTool used for writing
+  StringProperty           m_writingTool;
+  /// Name of the output file
+  std::string              m_outputName;
+  /// tag of processing stage:
+  StringProperty           m_processTag;
+   
+  typedef ServiceHandle<IClassIDSvc> IClassIDSvc_t;
+  IClassIDSvc_t m_pCLIDSvc;
+   
+  /// Vector of item names
+  StringArrayProperty      m_itemList;
+  /// Collection of objects beeing selected
+  IDataSelector            m_objects;
+  /// Number of events written to this output stream
+  int                      m_events;
+  /// set to true to force read of data objects in item list
+  bool m_forceRead;
+  /// set to true to allow data objects being copied persistent to persistent (without SG retrieve).
+  bool m_persToPers;
+  std::vector<unsigned int> m_exemptPersToPers;
+  /// set to true to allow defaults being provided for non-existent data objects.
+  bool m_provideDef;
+  /// set to true to trigger streaming of data on execute()
+  bool m_writeOnExecute;
+  /// set to true to trigger streaming of data on finalize()
+  bool m_writeOnFinalize;
+  /// set to write out everything from input DataHeader
+  bool m_itemListFromTool;
+  // /// set to true to check for number of times each object is written
+  // bool m_checkNumberOfWrites;
+  /// set to true to assure an extra commit on stop 
+  bool m_commitOnStop;
+  // /// map to record number of writes per object
+  // typedef std::map<std::string, unsigned int>  CounterMapType;
+  // CounterMapType  m_objectWriteCounter;
+
+  /// dynamic output itemlist: 
+  ///   if enabled rediscover object list to be written out at each event
+  ///   otherwise: reuse the one from the first event.
+  bool m_dynamicItemList;
+
+  /// list of selected proxies.
+  std::vector<SG::FolderItem> m_selection;
+
+  /// pointer to AthenaOutputStreamTool
+  ToolHandle<IAthenaOutputStreamTool> m_streamer;
+  /// vector of AlgTools that that are executed by this stream
+  ToolHandleArray<IAthenaOutputTool> m_helperTools;
+
+protected:
+  /// Standard algorithm Constructor
+  RootNtupleOutputStream(const std::string& name, ISvcLocator* pSvcLocator); 
+  /// Standard Destructor
+  virtual ~RootNtupleOutputStream();
+
+public:
+  typedef std::vector<std::pair<std::string, std::string> > TypeKeyPairs;
+  /// \name implement IAlgorithm
+  //@{
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+  virtual StatusCode execute();
+  //@}
+  /// Stream the data
+  virtual StatusCode write();
+
+private:
+  /// Clear list of selected objects
+  void clearSelection();
+  /// Collect data objects for output streamer list
+  void collectAllObjects();
+  /// Return the list of selected objects
+  IDataSelector* selectedObjects() {
+    return &m_objects;
+  }
+  /// Incident service handle listening for LastInputFile
+  void handle(const Incident& incident);
+};
+
+} //> ns Athena
+
+#endif // ATHENAROOTCOMPS_ROOTNTUPLEOUTPUTSTREAM_H
Add a comment to this file

src/RootOutputStreamTool.cxx

File contents unchanged.

File contents unchanged.

File contents unchanged.

Add a comment to this file

src/TTreeEventContext.cxx

File contents unchanged.

Add a comment to this file

src/TTreeEventContext.h

File contents unchanged.

Add a comment to this file

src/TTreeEventSelector.cxx

File contents unchanged.

Add a comment to this file

src/components/AthenaRootComps_entries.cxx

File contents unchanged.

test/AthenaRootComps.xml

+<?xml version="1.0"?>
+<atn>
+   <TEST name="arc_rw" type="script" suite="athenarootcomps">
+      <package_atn>Control/AthenaRootComps</package_atn>
+      <options_atn>run_test_athena_ntuple_dumper.sh</options_atn>
+      <timelimit>30</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+   <TEST name="arc_variable_shape" type="script" suite="athenarootcomps">
+      <package_atn>Control/AthenaRootComps</package_atn>
+      <options_atn>run_test_athena_variable_shape_ntuple.sh</options_atn>
+      <timelimit>30</timelimit>
+      <author> Sebastien Binet </author>
+      <mailto> binet@cern.ch </mailto>
+      <expectations>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+
+</atn>
Add a comment to this file

test/run_test_athena_ntuple_dumper.sh

File contents unchanged.

test/run_test_athena_variable_shape_ntuple.sh

+#!/bin/sh
+
+function check_disappearing_branches()
+{
+echo "::: generate f1.root..."
+athena.py \
+    -c 'EVTMAX=10; BRANCHES=["RunNumber", "EventNumber", "el_n", "el_eta"]; OUTBRANCHES=["el_n","el_eta"]' \
+    AthenaRootComps/test_athena_variable_shape_ntuple.py \
+    >| log.001.txt \
+    || return 1
+/bin/cp d3pd.root f1.root || return 1
+acmd.py dump-root f1.root | grep "^egamma" | egrep "RunNumber|EventNumber|el_n" | tee f1.ascii || return 1
+cat f1.ascii| cut -d. -f3 >| f1.ascii.todiff || return 1
+
+echo "::: generate f2.root..."
+athena.py \
+    -c 'EVTMAX=10; BRANCHES=["RunNumber", "EventNumber", "el_n", "el_eta"]; OUTBRANCHES=["el_n"]' \
+    AthenaRootComps/test_athena_variable_shape_ntuple.py \
+    >| log.002.txt \
+    || return 1
+/bin/cp d3pd.root f2.root || return 1
+acmd.py dump-root f2.root | grep "^egamma" | egrep "RunNumber|EventNumber|el_n" | tee f2.ascii || return 1
+cat f2.ascii| cut -d. -f3 >| f2.ascii.todiff || return 1
+
+echo "::: generate f3.root..."
+athena.py \
+    -c 'EVTMAX=10; BRANCHES=["RunNumber", "EventNumber", "el_n", "el_eta"]; OUTBRANCHES=["el_n","el_eta"]' \
+    AthenaRootComps/test_athena_variable_shape_ntuple.py \
+    >| log.003.txt \
+    || return 1
+/bin/cp d3pd.root f3.root || return 1
+acmd.py dump-root f3.root | grep "^egamma" | egrep "RunNumber|EventNumber|el_n" | tee f3.ascii || return 1
+cat f3.ascii| cut -d. -f3 >| f3.ascii.todiff || return 1
+
+echo "::: generate merged.root..."
+athena.py \
+    -c 'EVTMAX=30; BRANCHES=["RunNumber", "EventNumber", "el_n", "el_eta"]; OUTBRANCHES=["el_n",]; FNAMES=["f1.root","f2.root","f3.root"]' \
+    AthenaRootComps/test_athena_variable_shape_ntuple.py \
+    >| log.004.txt \
+    || return 1
+/bin/cp d3pd.root f4.root || return 1
+acmd.py dump-root f4.root | grep "^egamma" | egrep "RunNumber|EventNumber|el_n" | tee f4.ascii || return 1
+cat f4.ascii| cut -d. -f3 >| f4.ascii.todiff || return 1
+
+echo "::: compare dump-root outputs..."
+cat f[123].ascii.todiff > merged.ascii.todiff || return 1
+diff -urN merged.ascii.todiff f4.ascii.todiff || return 1
+echo "::: compare dump-root outputs... [ok]"
+
+# echo "::: compare logfiles..."
+# cat log.00[123].txt | grep "py_alg" >| log.merged.txt.todiff || return 1
+# grep "py_alg" log.004.txt >| log.004.txt.todiff || return 1
+# diff -urN log.merged.txt.todiff log.004.txt.todiff || return 1
+# echo "::: compare logfiles... [ok]"
+
+return 0
+}
+
+check_disappearing_branches
+
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.