Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow edm::soa::Table<> as a data product #20425

Merged
merged 3 commits into from Sep 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions DataFormats/TestObjects/BuildFile.xml
@@ -1,4 +1,5 @@
<use name="DataFormats/Common"/>
<flags GENREFLEX_FAILES_ON_WARNS="0"/>
<export>
<lib name="1"/>
</export>
42 changes: 42 additions & 0 deletions DataFormats/TestObjects/interface/TableTest.h
@@ -0,0 +1,42 @@
#ifndef DataFormats_TestObjects_TableTest_h
#define DataFormats_TestObjects_TableTest_h
// -*- C++ -*-
//
// Package: DataFormats/TestObjects
// Class : TableTest
//
/**\class TableTest TableTest.h "DataFormats/TestObjects/interface/TableTest.h"

Description: [one line class summary]

Usage:
<usage>

*/
//
// Original Author: Christopher Jones
// Created: Thu, 31 Aug 2017 15:09:27 GMT
//

// system include files
#include <string>

// user include files
#include "FWCore/SOA/interface/Column.h"
#include "FWCore/SOA/interface/Table.h"

// forward declarations
namespace edmtest {
//In an actual use of edm::soa::Table one would
// define the columns in a place that allows sharing
// of the definitions across many Tables

SOA_DECLARE_COLUMN(AnInt, int, "anInt");
SOA_DECLARE_COLUMN(AFloat, float, "aFloat");
SOA_DECLARE_COLUMN(AString, std::string, "aString");

using TableTest = edm::soa::Table<AnInt,AFloat,AString>;
}


#endif
6 changes: 6 additions & 0 deletions DataFormats/TestObjects/src/classes.h
Expand Up @@ -23,6 +23,8 @@
#include "DataFormats/TestObjects/interface/StreamTestThing.h"
#include "DataFormats/TestObjects/interface/StreamTestTmpl.h"

#include "DataFormats/TestObjects/interface/TableTest.h"

#include "DataFormats/TestObjects/interface/DeleteEarly.h"

#include "DataFormats/Common/interface/Holder.h"
Expand All @@ -33,6 +35,7 @@
#include "DataFormats/Provenance/interface/ProductID.h"

#include <list>
#include <algorithm>

namespace DataFormats_TestObjects {
struct dictionary {
Expand Down Expand Up @@ -116,5 +119,8 @@ struct dictionary {

edm::Wrapper<edm::EventID> wrapperEventID;
edm::Wrapper<edm::ProductID> wrapperProductID;

//Test that the type did not change
static_assert(std::is_same<edmtest::TableTest,edm::soa::Table<edmtest::AnInt,edmtest::AFloat,edmtest::AString>>::value, "Definition of edmtest::TableTest changed");
};
}
9 changes: 9 additions & 0 deletions DataFormats/TestObjects/src/classes_def.xml
Expand Up @@ -231,4 +231,13 @@ exception when running testMissingDictionaryChecking_cfg.py.
<class name="edm::Wrapper<edmtest::MissingDictionaryTestA>"/>
<class name="edm::Wrapper<std::vector<edmtest::MissingDictionaryTestA> >"/>
<class name="edm::Wrapper<std::list<edmtest::MissingDictionaryTestA> >"/>

<!-- <class name="edm::soa::Table<edmtest::AnInt,edmtest::AFloat,edmtest::AString>" ClassVersion="3"/>

<class name="edm::soa::Table<edm::soa::Column<edmtest::kAnInt,int>, edm::soa::Column<edmtest::kAFloat,float>,edm::soa::Column<edmtest::kAString,std::string> >"/>
<class name="edm::Wrapper<edm::soa::Table<edm::soa::Column<edmtest::kAnInt,int>, edm::soa::Column<edmtest::kAFloat,float>,edm::soa::Column<edmtest::kAString,std::string> > >" persistent="false"/>
-->
<class name="edm::soa::Table<edmtest::AnInt, edmtest::AFloat,edmtest::AString >"/>
<class name="edm::Wrapper<edm::soa::Table<edmtest::AnInt, edmtest::AFloat,edmtest::AString > >" persistent="false"/>

</lcgdict>
6 changes: 5 additions & 1 deletion FWCore/Integration/test/BuildFile.xml
Expand Up @@ -17,6 +17,10 @@
<flags TEST_RUNNER_ARGS=" /bin/bash FWCore/Integration/test transRefTest.sh"/>
<use name="FWCore/Utilities"/>
</bin>
<bin file="TestIntegration.cpp" name="TestIntegrationTableTest">
<flags TEST_RUNNER_ARGS=" /bin/bash FWCore/Integration/test testTables.sh"/>
<use name="FWCore/Utilities"/>
</bin>
<bin file="TestIntegration.cpp" name="TestIntegrationProducedSource">
<flags TEST_RUNNER_ARGS=" /bin/bash FWCore/Integration/test inputSourceTest.sh"/>
<use name="FWCore/Utilities"/>
Expand Down Expand Up @@ -121,7 +125,7 @@
<use name="FWCore/ParameterSet"/>
<use name="FWCore/Framework"/>
</library>
<library file="ThingProducer.cc,ThingAlgorithm.cc,TrackOfThingsProducer.cc,ThinningThingProducer.cc,ThinningTestAnalyzer.cc,WhatsIt.cc,GadgetRcd.cc,AssociationMapProducer.cc,AssociationMapAnalyzer.cc,MissingDictionaryTestProducer.cc, WaitingThreadIntProducer.cc, ThingAnalyzer.cc" name="SomeTestModules">
<library file="ThingProducer.cc,ThingAlgorithm.cc,TrackOfThingsProducer.cc,ThinningThingProducer.cc,ThinningTestAnalyzer.cc,WhatsIt.cc,GadgetRcd.cc,AssociationMapProducer.cc,AssociationMapAnalyzer.cc,MissingDictionaryTestProducer.cc, WaitingThreadIntProducer.cc, ThingAnalyzer.cc, TableTestModules.cc" name="SomeTestModules">
<flags EDM_PLUGIN="1"/>
<use name="FWCore/Framework"/>
<use name="DataFormats/TestObjects"/>
Expand Down
84 changes: 84 additions & 0 deletions FWCore/Integration/test/TableTestModules.cc
@@ -0,0 +1,84 @@
#include "FWCore/Framework/interface/global/EDProducer.h"
#include "FWCore/Framework/interface/global/EDAnalyzer.h"
#include "DataFormats/TestObjects/interface/TableTest.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/LuminosityBlock.h"
#include "FWCore/Framework/interface/Run.h"
#include "FWCore/Framework/interface/MakerMacros.h"


namespace {
std::vector<float> doublesToFloats(std::vector<double> const& iDoubles) {
std::vector<float> t;
t.reserve(iDoubles.size());
for(double d: iDoubles) { t.push_back( static_cast<float>(d) ); }
return t;
}
}

namespace edmtest {

class TableTestProducer : public edm::global::EDProducer<> {
public:
TableTestProducer(edm::ParameterSet const& iConfig):
anInts_(iConfig.getParameter<std::vector<int>>("anInts")),
aFloats_(doublesToFloats(iConfig.getParameter<std::vector<double>>("aFloats"))),
aStrings_(iConfig.getParameter<std::vector<std::string>>("aStrings")) {
produces<edmtest::TableTest>();
}

void produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const final {
iEvent.put( std::make_unique<TableTest>(anInts_,aFloats_,aStrings_) );
}
private:
const std::vector<int> anInts_;
const std::vector<float> aFloats_;
const std::vector<std::string> aStrings_;
};

class TableTestAnalyzer : public edm::global::EDAnalyzer<> {
public:
TableTestAnalyzer(edm::ParameterSet const& iConfig):
anInts_(iConfig.getUntrackedParameter<std::vector<int>>("anInts")),
aFloats_(doublesToFloats(iConfig.getUntrackedParameter<std::vector<double>>("aFloats"))),
aStrings_(iConfig.getUntrackedParameter<std::vector<std::string>>("aStrings"))
{
tableToken_ = consumes<edmtest::TableTest>(iConfig.getUntrackedParameter<edm::InputTag>("table"));
if(anInts_.size() != aFloats_.size() or anInts_.size() != aStrings_.size()) {
throw cms::Exception("Configuration")<<"anInts_, aFloats_, and aStrings_ must have the same length";
}
}

void analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const&) const final {
edm::Handle<edmtest::TableTest> h;
iEvent.getByToken(tableToken_, h);

auto size = h->size();
if(size != anInts_.size()) {
throw cms::Exception("RuntimeError")<<"Table size ("<<size<<") does not equal expected size ("<<anInts_.size()<<")";
}

unsigned int index=0;
for(auto const& row : *h) {
if( anInts_[index] != row.get<edmtest::AnInt>() ) {
throw cms::Exception("RuntimeError")<<"index "<<index<<" anInt ="<<row.get<edmtest::AnInt>()<<" expected "<<anInts_[index];
}
if( aFloats_[index] != row.get<edmtest::AFloat>() ) {
throw cms::Exception("RuntimeError")<<"index "<<index<<" aFloat ="<<row.get<edmtest::AFloat>()<<" expected "<<aFloats_[index];
}
if( aStrings_[index] != row.get<edmtest::AString>() ) {
throw cms::Exception("RuntimeError")<<"index "<<index<<" aString ="<<row.get<edmtest::AString>()<<" expected "<<aStrings_[index];
}
++index;
}
}

private:
const std::vector<int> anInts_;
const std::vector<float> aFloats_;
const std::vector<std::string> aStrings_;
edm::EDGetTokenT<edmtest::TableTest> tableToken_;
};
}
DEFINE_FWK_MODULE(edmtest::TableTestProducer);
DEFINE_FWK_MODULE(edmtest::TableTestAnalyzer);
31 changes: 31 additions & 0 deletions FWCore/Integration/test/testTableTest_cfg.py
@@ -0,0 +1,31 @@
import FWCore.ParameterSet.Config as cms

process = cms.Process("TABLETEST")

process.source = cms.Source("EmptySource")

process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(2))

anInts = [1,2,3]
aFloats = [4.,5., 6.]
aStrings =["einie", "meanie", "meinie"]

process.tableTest = cms.EDProducer("edmtest::TableTestProducer",
anInts = cms.vint32(*anInts),
aFloats = cms.vdouble(*aFloats),
aStrings = cms.vstring(*aStrings) )

process.checkTable = cms.EDAnalyzer("edmtest::TableTestAnalyzer",
table = cms.untracked.InputTag("tableTest"),
anInts = cms.untracked.vint32(*anInts),
aFloats = cms.untracked.vdouble(*aFloats),
aStrings = cms.untracked.vstring(*aStrings) )

process.eventContent = cms.EDAnalyzer("EventContentAnalyzer")

process.p = cms.Path(process.checkTable, cms.Task(process.tableTest) )
#process.p = cms.Path(process.tableTest+process.eventContent+process.checkTable)

#process.add_(cms.Service("Tracer", dumpPathsAndConsumes= cms.untracked.bool(True) ) )

#process.add_(cms.Service("InitRootHandlers", DebugLevel = cms.untracked.int32(10)))
5 changes: 5 additions & 0 deletions FWCore/Integration/test/testTables.sh
@@ -0,0 +1,5 @@
#!/bin/sh

function die { echo $1: status $2 ; exit $2; }

cmsRun ${LOCAL_TEST_DIR}/testTableTest_cfg.py || die 'Failed in testTableTest_cfg.py' $?
31 changes: 21 additions & 10 deletions FWCore/SOA/interface/Column.h
Expand Up @@ -10,23 +10,33 @@
Description: Column describes a column in a Table

Usage:
Instances of the Column class are not intended to be used.
Class instances inheriting from the Column class are not intended to be used.
Instead, the specific Column type is used as a template argument
to a edm::soa::Table<> to describe a column in the table.

A column is defined by a name and a C++ type.

When declaring a Column template instantiation, the name
should be declared as a constexpr const char []

Classes inheriting from Column must declare a 'constexpr const char' array named 'kLabel'.
\code
namespace edm {
namespace soa {
constexpr const char kEta[] = "eta";
using Eta = Column<kEta,double>;
struct Eta : public Column<double,Eta> {
static constexpr const char * const kLabel = "eta";
};
}
}
\endcode
Alternatively, one can use the macro SOA_DECLARE_COLUMN
\code
namespace edm {
namespace soa {

SOA_DECLARE_COLUMN(Eta,double, "eta");

}
}

\endcode

*/
//
Expand All @@ -51,19 +61,18 @@ struct ColumnFillerHolder {
F m_f;
};

template <const char* LABEL, typename T>
template <typename T, typename INHERIT>
struct Column
{
using type = T;
static constexpr char const * const kLabel = LABEL;

static const char* const& label() {
static char const* const s_label(LABEL);
static char const* const s_label(INHERIT::kLabel);
return s_label;
}

template <typename F>
static ColumnFillerHolder<Column<LABEL,T>,F> filler(F&& iF) { return {iF}; }
static ColumnFillerHolder<INHERIT,F> filler(F&& iF) { return {iF}; }

private:
Column() = default;
Expand All @@ -74,4 +83,6 @@ struct Column

}
}
#define SOA_DECLARE_COLUMN(_ClassName_,_Type_,_String_) \
struct _ClassName_ : public edm::soa::Column<_Type_,_ClassName_> {static constexpr const char * const kLabel=_String_; }
#endif
10 changes: 8 additions & 2 deletions FWCore/SOA/interface/Table.h
Expand Up @@ -216,8 +216,14 @@ namespace soa {
return *(begin()+iRow);
}

const_iterator begin() const { return const_iterator{m_values}; }
const_iterator end() const { return const_iterator{m_values,size()}; }
const_iterator begin() const {
std::array<void const*, sizeof...(Args)> t;
for(size_t i = 0; i<size();++i) { t[i] = m_values[i]; }
return const_iterator{t}; }
const_iterator end() const {
std::array<void const*, sizeof...(Args)> t;
for(size_t i = 0; i<size();++i) { t[i] = m_values[i]; }
return const_iterator{t,size()}; }

iterator begin() { return iterator{m_values}; }
iterator end() { return iterator{m_values,size()}; }
Expand Down
33 changes: 10 additions & 23 deletions FWCore/SOA/test/table_t.cppunit.cpp
Expand Up @@ -48,29 +48,18 @@ class testTable: public CppUnit::TestFixture
};

namespace ts {
constexpr const char kEta[] = "eta";
using Eta = edm::soa::Column<kEta,float>;

constexpr const char kPhi[] = "phi";
using Phi = edm::soa::Column<kPhi,float>;

constexpr const char kEnergy[] = "energy";
using Energy = edm::soa::Column<kEnergy,double>;
struct Eta : public edm::soa::Column<float,Eta> {
static constexpr const char * const kLabel = "eta";
};

constexpr const char kID[] = "id";
using ID = edm::soa::Column<kID,int>;
SOA_DECLARE_COLUMN(Phi, float, "phi");
SOA_DECLARE_COLUMN(Energy, float, "energy");
SOA_DECLARE_COLUMN(ID, int, "id");
SOA_DECLARE_COLUMN(Label, std::string, "label");

constexpr const char kLabel[] = "label";
using Label = edm::soa::Column<kLabel,std::string>;

constexpr const char kPx[] = "p_x";
using Px = edm::soa::Column<kPx, double>;

constexpr const char kPy[] = "p_z";
using Py = edm::soa::Column<kPy, double>;

constexpr const char kPz[] = "p_z";
using Pz = edm::soa::Column<kPz, double>;
SOA_DECLARE_COLUMN(Px,double,"p_x");
SOA_DECLARE_COLUMN(Py,double,"p_y");
SOA_DECLARE_COLUMN(Pz,double,"p_z");

using ParticleTable = edm::soa::Table<Px, Py, Pz, Energy>;

Expand All @@ -81,8 +70,6 @@ namespace ts {

/* Creat a table that is a sub table of an existing one */
using MyOtherJetTable = edm::soa::RemoveColumn_t<MyJetTable, Phi>;


}

///registration of the test so that the runner can find it
Expand Down