lcio/src/cpp/include
diff -u -r1.6 -r1.7
--- LCRTRelations.h 30 Nov 2006 14:03:42 -0000 1.6
+++ LCRTRelations.h 1 Dec 2006 14:10:09 -0000 1.7
@@ -6,546 +6,629 @@
#include <list>
#include <map>
+namespace lcrtrel_helper{
+ //------------------ internal helper typdefs, function and classes ----------
-//------------------ internal helper typdefs, function and classes ----------
+ /** Function pointer for delete function */
+ typedef void (*DeleteFPtr)(void*) ;
-/** Function pointer for delete function */
-typedef void (*DeleteFPtr)(void*) ;
+ /** Simple init function for simple pointers */
+ struct SimplePtrInit{ static void* init() { return 0 ; } } ;
-/** Simple init function for simple pointers */
-struct SimplePtrInit{ static void* init() { return 0 ; } } ;
+ /** Empty delete function for pointers w/o ownership */
+ struct NoDelete{ static void clean(void *v) { /* no_op */ } } ;
-/** Empty delete function for pointers w/o ownership */
-struct NoDelete{ static void clean(void *v) { /* no_op */ } } ;
+ /** Factory for objects of type T*/
+ template <class T>
+ struct CreationPtrInit{ static void* init() { return new T ; } } ;
-/** Factory for objects of type T*/
-template <class T>
-struct CreationPtrInit{ static void* init() { return new T ; } } ;
+ /** Delete function for pointers w/ ownership.*/
+ template <class T>
+ struct DeletePtr{ static void clean(void *v) { delete (T*) v ; } } ;
-/** Delete function for pointers w/ ownership.*/
-template <class T>
-struct DeletePtr{ static void clean(void *v) { delete (T*) v ; } } ;
+ /** Delete function for containers of owned objects */
+ template <class T>
+ struct DeleteElements{
-/** Delete function for containers of owned objects */
-template <class T>
-struct DeleteElements{
+ static void clean(void *v) {
+ T* vec = static_cast<T*>(v) ;
+ for( typename T::iterator it = vec->begin();it != vec->end(); ++it){
+ delete *it ;
+ }
+ delete vec ;
+ }
+ };
- static void clean(void *v) {
- T* vec = static_cast<T*>(v) ;
- for( typename T::iterator it = vec->begin();it != vec->end(); ++it){
- delete *it ;
- }
- delete vec ;
- }
-};
+ /** Map of pointers to extension obbjects*/
+ typedef std::map< unsigned , void * > PtrMap ;
-// typedef std::map< DeleteFPtr , void * > PtrMap ;
+ /** Vector of delete functions */
+ typedef std::vector< DeleteFPtr > DPtrVec ;
-/** Vector of delete functions */
-typedef std::vector< DeleteFPtr > DPtrVec ;
+ /** Vector of pointers to extension obbjects*/
+ //typedef std::vector< void * > PtrVec ;
-/** Vector of pointers to extension obbjects*/
-typedef std::vector< void * > PtrVec ;
-
-template <class U, class T , class I, class D, bool b>
-struct LCBaseTraits{
+ /** Base class for all extensions and relations */
+ template <class U, class T , class I, class D, bool b>
+ struct LCBaseTraits{
- typedef T* ptr ; // base pointer type
- typedef U tag ; // this ensures that a new class instance is created for every user extension
+ typedef T* ptr ; /**<base pointer type */
+ typedef U tag ; // this ensures that a new class instance is created for every user extension
- static const int allowed_to_call_ext = b ;
+ static const int allowed_to_call_ext = b ;
- static void clean(void *v) {
- D::clean( v ) ;
- }
- static ptr init() {
- return (ptr) I::init() ;
- }
- static DeleteFPtr deletePtr() { return &clean ; } ;
-};
-
-
-template <class U, class T , class I=SimplePtrInit, class D=NoDelete , bool b=1>
-struct LCBaseLinkTraits : public LCBaseTraits<U,T,I,D,b>{
-
- typedef LCBaseTraits<U,T,I,D,b> base ;
+ static void clean(void *v) {
+ D::clean( v ) ;
+ }
+ static ptr init() {
+ return (ptr) I::init() ;
+ }
+ static DeleteFPtr deletePtr() { return &clean ; } ;
+ };
- typedef T*& ext_type ; // return value of ext<>()
- typedef T* rel_type ; // return value of rel<>()
- typedef typename base::ptr obj_ptr ; // pointer to object
- static const bool is_container=false ;
-};
+ /** Base class for all extensions and relations of single objects */
+ template <class U, class T , class I=SimplePtrInit, class D=NoDelete , bool b=1>
+ struct LCBaseLinkTraits : public LCBaseTraits<U,T,I,D,b>{
-/** Special Extension that allows to write int extensions directly (not through a pointer !). */
-template <class U >
-struct LCIntExtension{ // FIXME: need to check on 64 bit architecture...
+ typedef LCBaseTraits<U,T,I,D,b> base ;
- typedef int ptr ; // base pointer type
+ typedef T*& ext_type ; // return value of ext<>()
+ typedef T* rel_type ; // return value of rel<>()
+ typedef typename base::ptr obj_ptr ; // pointer to object
- typedef U tag ; // this ensures that a new class instance is created for every user extension
+ static const bool is_container=false ;
+ };
- static const int allowed_to_call_ext = 1 ;
+ /** Base class for all containers of extensions and relations, vectors, lists,... */
+ template <class U, class T , class I=CreationPtrInit<T>, class D=DeletePtr<T> , bool b=1>
+ struct LCBaseLinkContainerTraits : public LCBaseTraits<U,T,I,D,b>{
- static void clean(void *v) { }
+ typedef LCBaseTraits<U,T,I,D,b> base ;
- static ptr init() {
- return 0 ;
- }
- static DeleteFPtr deletePtr() { return &clean ; } ;
+ typedef T* ext_type ; // return value of ext<>()
+ typedef const T* rel_type ; // return value of rel<>()
+ typedef typename T::value_type obj_ptr ; // pointer to object
- typedef int& ext_type ;
-};
+ typedef typename T::iterator iterator ;
+ typedef typename T::const_iterator const_iterator ;
+ static const bool is_container=true ;
+ };
-/** Special Extension that allows to write float extensions directly (not through a pointer !). */
-template <class U >
-struct LCFloatExtension{// FIXME: need to check on 64 bit architecture...
-
- typedef float ptr ; // base pointer type
- typedef U tag ; // this ensures that a new class instance is created for every user extension
+ /** Helper class for relations */
+ template <class U, class T>
+ struct RelationOneSide :
+ public LCBaseLinkTraits<U,T,SimplePtrInit,NoDelete,false> {};
- static const int allowed_to_call_ext = 1 ;
- static void clean(void *v) { }
-
- static ptr init() { return 0 ; }
-
- static DeleteFPtr deletePtr() { return &clean ; } ;
-
- typedef float& ext_type ; // return value of ext<>()
-};
-
-
-template <class U, class T , class I=CreationPtrInit<T>, class D=DeletePtr<T> , bool b=1>
-struct LCBaseLinkContainerTraits : public LCBaseTraits<U,T,I,D,b>{
+ /** Helper class for relations */
+ template <class U, class T>
+ struct RelationManySide :
+ public LCBaseLinkContainerTraits< U, std::list<T*>,
+ CreationPtrInit< std::list<T*> > ,
+ DeletePtr<std::list<T*> > ,false > {};
+
+ /** Helper class for relations */
+ template <class U> struct FromRelation{} ;
+
+ /** Helper class for relations */
+ template <class U> struct ToRelation{} ;
+
+
+ /** Helper class for biderectional relations provides the to and from type*/
+ template <class From, class To>
+ struct BiDirectional{
+ typedef From from ;
+ typedef To to ;
+ } ;
+
+
+ /** Helper functions that treat single objects and containers */
+ template <bool is_container>
+ struct objorcont{
- typedef LCBaseTraits<U,T,I,D,b> base ;
+ template <class T, class S>
+ inline static void add( T t, S s) { t->push_back( s ) ; }
- typedef T* ext_type ; // return value of ext<>()
- typedef const T* rel_type ; // return value of rel<>()
- typedef typename T::value_type obj_ptr ; // pointer to object
+ template <class T, class S>
+ inline static void remove( T t, S s) { t->remove( s ) ; }
+ };
- typedef typename T::iterator iterator ;
- typedef typename T::const_iterator const_iterator ;
- static const bool is_container=true ;
-};
+ /** Helper functions specialization for single objects*/
+ template <>
+ struct objorcont<false>{
-//-----------end of internal helper typdefs, function and classes ----------
+ template <class T, class S>
+ inline static void add( T& t, S s) { t = s ; }
-/** Simple Extension - pointer to an object of type T.
- * The class U needs to be the subclass type, e.g.<br>
- * struct MyAttributes : public LCExtension<MyAttributes,Attributes> {} ; <br>
- */
-template <class U, typename T>
-struct LCExtension : public LCBaseLinkTraits< U, T > {};
+ template <class T, class S>
+ inline static void remove( T& t, S s) { t = 0 ; }
+ };
-/** Simple Extension - pointer to an object of type T where the ownership is taken over
- * by the object holding the extension, i.e. it deletes the object when itself is deleted.
- * The class U needs to be the subclass type, e.g.<br>
- * struct MyAttributes : public LCExtension<MyAttributes,Attributes> {} ; <br>
- */
-template <class U, typename T>
-class LCOwnedExtension : public LCBaseLinkTraits< U, T , SimplePtrInit , DeletePtr<T> > {};
+ //-----------end of internal helper typdefs, function and classes ----------
-/** Extension vector holding pointers to objects of type T - no ownership of the objects is taken. */
-template <class U, class T>
-class LCExtensionVector :
- public LCBaseLinkContainerTraits< U, std::vector<T*>,
- CreationPtrInit< std::vector<T*> > ,
- DeletePtr<std::vector<T*> > > {};
+} // end namespace lcrtrel_helper
+namespace lcrtrel{
-/** Extension vector holding pointers to objects of type T - ownership of the objects is taken, i.e.
- * all objects pointed to in the vector are deleted when the object itself is deleted.
- */
-template <class U, class T>
-class LCOwnedExtensionVector :
- public LCBaseLinkContainerTraits< U, std::vector<T*>,
- CreationPtrInit< std::vector<T*> > ,
- DeleteElements< std::vector<T*> > > {};
+ using namespace lcrtrel_helper ;
+ /** Simple Extension - pointer to an object of type T.
+ * The class U needs to be the subclass type, e.g.<br>
+ * struct MyAttributes : public LCExtension<MyAttributes,Attributes> {} ; <br>
+ */
+ template <class U, typename T>
+ struct LCExtension : public LCBaseLinkTraits< U, T > {};
-/** Extension list holding pointers to objects of type T - no ownership of the objects is taken. */
-template <class U, class T>
-class LCExtensionList :
- public LCBaseLinkContainerTraits< U, std::list<T*>,
- CreationPtrInit< std::list<T*> > ,
- DeletePtr<std::list<T*> > > {};
+ /** Simple Extension - pointer to an object of type T where the ownership is taken over
+ * by the object holding the extension, i.e. it deletes the object when itself is deleted.
+ * The class U needs to be the subclass type, e.g.<br>
+ * struct MyAttributes : public LCExtension<MyAttributes,Attributes> {} ; <br>
+ */
+ template <class U, typename T>
+ class LCOwnedExtension : public LCBaseLinkTraits< U, T , SimplePtrInit , DeletePtr<T> > {};
-/** Extension list holding pointers to objects of type T - ownership of the objects is taken, i.e.
- * all objects pointed to in the vector are deleted when the object itself is deleted.
- */
-template <class U, class T>
-class LCOwnedExtensionList :
- public LCBaseLinkContainerTraits< U, std::list<T*>,
- CreationPtrInit< std::list<T*> > ,
- DeleteElements< std::list<T*> > > {};
+ /** Extension vector holding pointers to objects of type T - no ownership of the objects is taken. */
+ template <class U, class T>
+ class LCExtensionVector :
+ public LCBaseLinkContainerTraits< U, std::vector<T*>,
+ CreationPtrInit< std::vector<T*> > ,
+ DeletePtr<std::vector<T*> > > {};
-/** Helper class for relations */
-template <class U, class T>
-struct RelationOneSide :
- public LCBaseLinkTraits<U,T,SimplePtrInit,NoDelete,false> {};
+ /** Extension vector holding pointers to objects of type T - ownership of the objects is taken, i.e.
+ * all objects pointed to in the vector are deleted when the object itself is deleted.
+ */
+ template <class U, class T>
+ class LCOwnedExtensionVector :
+ public LCBaseLinkContainerTraits< U, std::vector<T*>,
+ CreationPtrInit< std::vector<T*> > ,
+ DeleteElements< std::vector<T*> > > {};
+
+
+ /** Extension list holding pointers to objects of type T - no ownership of the objects is taken. */
+ template <class U, class T>
+ class LCExtensionList :
+ public LCBaseLinkContainerTraits< U, std::list<T*>,
+ CreationPtrInit< std::list<T*> > ,
+ DeletePtr<std::list<T*> > > {};
+ /** Extension list holding pointers to objects of type T - ownership of the objects is taken, i.e.
+ * all objects pointed to in the vector are deleted when the object itself is deleted.
+ */
+ template <class U, class T>
+ class LCOwnedExtensionList :
+ public LCBaseLinkContainerTraits< U, std::list<T*>,
+ CreationPtrInit< std::list<T*> > ,
+ DeleteElements< std::list<T*> > > {};
-/** Helper class for relations */
-template <class U, class T>
-struct RelationManySide :
- public LCBaseLinkContainerTraits< U, std::list<T*>,
- CreationPtrInit< std::list<T*> > ,
- DeletePtr<std::list<T*> > ,false > {};
-/** Helper class for relations */
-template <class U> struct FromRelation{} ;
+ /** One to one relation between two objects of type From and To */
+ template <class U, class From, class To>
+ struct LC1To1Relation :
+ public BiDirectional<RelationOneSide<FromRelation<U>,From>,
+ RelationOneSide<ToRelation<U>,To> > {
-/** Helper class for relations */
-template <class U> struct ToRelation{} ;
+ } ;
+ /** One to many relation between one object of type From to many objects of type To */
+ template <class U, class From, class To>
+ struct LC1ToNRelation :
+ public BiDirectional<RelationOneSide<FromRelation<U>,From>,
+ RelationManySide<ToRelation<U>,To> > {
+ } ;
-/** Helper class for biderectional relations provides the to and from type*/
-template <class From, class To>
-struct BiDirectional{
- typedef From from ;
- typedef To to ;
-} ;
+ /** Many to many relation between objects of type From to objects of type To */
+ template <class U, class From, class To>
+ struct LCNToNRelation :
+ public BiDirectional<RelationManySide<FromRelation<U>,From>,
+ RelationManySide<ToRelation<U>,To> > {
+ } ;
+ /** Special Extension that allows to write int extensions directly (not through a pointer !). */
+ template <class U >
+ struct LCIntExtension{ // FIXME: need to check on 64 bit architecture...
+
+ typedef int ptr ; // base pointer type
+
+ typedef U tag ; // this ensures that a new class instance is created for every user extension
+
+ static const int allowed_to_call_ext = 1 ;
+
+ static void clean(void *v) { }
-/** One to one relation between two objects of type From and To */
-template <class U, class From, class To>
-struct LC1To1Relation :
- public BiDirectional<RelationOneSide<FromRelation<U>,From>,
- RelationOneSide<ToRelation<U>,To> > {
+ static ptr init() {
+ return 0 ;
+ }
+ static DeleteFPtr deletePtr() { return &clean ; } ;
-} ;
+ typedef int& ext_type ;
+ };
-/** One to many relation between one object of type From to many objects of type To */
-template <class U, class From, class To>
-struct LC1ToNRelation :
- public BiDirectional<RelationOneSide<FromRelation<U>,From>,
- RelationManySide<ToRelation<U>,To> > {
-} ;
-/** Many to many relation between objects of type From to objects of type To */
-template <class U, class From, class To>
-struct LCNToNRelation :
- public BiDirectional<RelationManySide<FromRelation<U>,From>,
- RelationManySide<ToRelation<U>,To> > {
-} ;
+ /** Special Extension that allows to write float extensions directly (not through a pointer !). */
+ template <class U >
+ struct LCFloatExtension{// FIXME: need to check on 64 bit architecture...
-//--------------------------------------------------------------------
+ typedef float ptr ; // base pointer type
+ typedef U tag ; // this ensures that a new class instance is created for every user extension
+ typedef float& ext_type ; // return value of ext<>()
+
+ static const int allowed_to_call_ext = 1 ;
+ static void clean(void *v) { }
+ static ptr init() { return 0 ; }
+ static DeleteFPtr deletePtr() { return &clean ; } ;
+ };
+ //--------------------------------------------------------------------
-class LCRTRelations ;
-/** Set the 1-to-1 relation between two objects - prexisting inconsistent relations
- involving the two objects are deleted to enforce a coinsistent set of from-to relations. */
-template <class R>
-void set_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t) ;
-/** Unset the 1-to-1 relation from f */
-template <class R>
-void unset_relation(typename R::from::obj_ptr f );
+ class LCRTRelations ;
+ /** Set the 1-to-1 relation between two objects - prexisting inconsistent relations
+ involving the two objects are deleted to enforce a consistent set of from-to relations. */
+ template <class R>
+ void set_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t) ;
-/** Add a link from f to t to an N-to-N relation ship */
-template <class R>
-void add_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t) ;
+ /** Unset the 1-to-1 relation from f */
+ template <class R>
+ void unset_relation(typename R::from::obj_ptr f );
-/** Remove the link from from f to t from the N-to-N relation ship */
-template <class R>
-void remove_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t) ;
+ /** Add a link from f to t to an N-to-N relation ship */
+ template <class R>
+ void add_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t) ;
-/** Removes all relations from the given object */
-template <class R>
-void remove_relations(typename R::from::obj_ptr f );
+ /** Remove the link from from f to t from the N-to-N relation ship */
+ template <class R>
+ void remove_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t) ;
-/** Merge the relations from f2 to f1 - after this call f1 will hold all
- * the relations and f2 will be empty.
- */
-template <class R>
-void merge_relations( typename R::from::obj_ptr f1,
- typename R::from::obj_ptr f2) ;
+ /** Removes all relations from the given object */
+ template <class R>
+ void remove_relations(typename R::from::obj_ptr f );
+ /** Merge the relations from f2 to f1 - after this call f1 will hold all
+ * the relations and f2 will be empty.
+ */
+ template <class R>
+ void merge_relations( typename R::from::obj_ptr f1,
+ typename R::from::obj_ptr f2) ;
-/** Base class for run time extensions to and relation between objects */
-class LCRTRelations{
-
- // declare functions for relation handling as friends
- template <class R>
- friend void set_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t);
- template <class R>
- friend void unset_relation(typename R::from::obj_ptr f );
- template <class R>
- friend void add_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t) ;
- template <class R>
- friend void remove_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t) ;
- template <class R>
- friend void remove_relations(typename R::from::obj_ptr f );
+ /** Base class that provides run time (user) extensions and relation between objects.
+ * Every subclass object of LCRTRelations (and thus LCObbject) will automatically have
+ * the following functionality:<br>
+ * <ul>
+ * <li>extension of the object with arbitrary (even non-LCObject) classes</li>
+ * <li>extension of single objects or vectors, lists of objects</li>
+ * <li>optionally ownership is taken for extension objects (memory management)</li>
+ * <li>relations to other subclasses of LCRTRelations:
+ * <ul>
+ * <li>one to one</li>
+ * <li>one to many</li>
+ * <li>many to many</li>
+ * </li></ul>
+ * </ul>
+ *
+ * The described functionality is provided through the two templated member functions:<br>
+ * ext<class V>() <br>
+ * rel<class V>() <br>
+ * the class V is a user defined so called traits class, that uniquely tags the
+ * extension/relationship and defines the types of the objects involved. <br>
+ * For extensions users have to subclass one of the following classes:<br>
+ * LCExtension, LCOwnedExtension, LCIntExtension, LCFloatExtension,<br>
+ * LCExtensionVector, LCExtensionList, LCOwnedExtensionVector, LCOwnedExtensionList. <br>
+ * For example
+ * the following defines a user extension of a vector of strings that are owned by the
+ * object (i.e. deleted when the object is deleted):<br>
+ * <p><b>
+ * struct ParticleIDs : LCOwnedExtensionVector<ParticleIDs, std::string> {};<br>
+ * </b>
+ * (note: the first template parameter has to be the class itself !)
+ * <p>
+ * This extension can then be used anywhere in the following code for all LCObjects, e.g.:<br>
+ * <p><b>
+ * MCParticle* mcp = dynamic_cast<MCParticle*>( mcpcol->getElementAt(i) ) ;<br>
+ * mcp->ext<ParticleIDs>()->push_back( new std::string("charged") ) ;<br>
+ * mcp->ext<ParticleIDs>()->push_back( new std::string("hadron") ) ;<br>
+ * mcp->ext<ParticleIDs>()->push_back( new std::string("pion") ) ;<br>
+ * </b><p>
+ * and be read out again: <br>
+ * <p><b>
+ * ParticleIDs::ext_type pidv = mcp->ext<ParticleIDs>() ;<br>
+ * for( ParticleIDs::const_iterator ipid = pidv->begin() ; ipid != pidv->end(); ++ipid){<br>
+ * std::cout << **ipid << ", " ;<br>
+ * }<br>
+ *</b><p>
+ * <p>
+ * Similarily the following defines a one to many relationship between Tracks and Clusters:<br>
+ * <p><b>
+ * struct TrkCluLink : LC1ToNRelation<TrkCluLink,Track,Cluster> {} ; <br>
+ * </b><p>
+ * Relations are allways biderectional, i.e. there is a <b>from</b> and a <b>to</b> side.
+ * They can then be set and modified with the following functions:<br>
+ * set_relation(), unset_relation(), add_relation(), <br>
+ * remove_relation(), remove_relations(),
+ * merge_relations(). <br>
+ * For example:<br>
+ * <p>
+ * <b>
+ * Track* trk = dynamic_cast<Track*> ( trkcol->getElementAt(j) ) ; <br>
+ * //... <br>
+ * Cluster* clu = dynamic_cast<Cluster*> ( clucol->getElementAt(k) ) ; <br>
+ * add_relation<TrkCluLink>( trk ,clu ); <br>
+ *</b><p>
+ * The many side can then be read out with a const_iterator and the one side with a
+ * normal pointer:<br>
+ * <p><b>
+ * Track* trk = clu->rel<TrkCluLink::from>() ; <br>
+ * //...<br>
+ TrkCluLink::to::rel_type clulist = trk->rel<TrkCluLink::to>() ; <br>
+ for( TrkCluLink::to::const_iterator iclu = clulist->begin() ; iclu != clulist->end() ; ++iclu ){ <br>
+ Cluster* clu = *iclu ; // iterator is of type pointer to container element <br>
+ std::cout << " assigned cluster with E = " << clu->getEnergy() << std::endl ; <br>
+ }
+ *</b>
+ * <p>
+ * More examples can be found in <b>$LCIO/src/cpp/src/EXAMPLES/lcrtrelations.cc</b>.
+ */
- template <class R>
- friend void merge_relations( typename R::from::obj_ptr f1,
- typename R::from::obj_ptr f2) ;
+ class LCRTRelations{
-public:
-
- /** Provides access to an extension object - the type and ownership is defined
- * by the class V which should be a subtype of LCExtension, LCOwnedExtension,
- * LCExtensionVector, LCExtensionList,...
- */
- template <class V>
- inline typename V::ext_type ext() {
+ // declare functions for relation handling as friends
+ template <class R>
+ friend void set_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t);
+ template <class R>
+ friend void unset_relation(typename R::from::obj_ptr f );
+
+ template <class R>
+ friend void add_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t) ;
+ template <class R>
+ friend void remove_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t) ;
+ template <class R>
+ friend void remove_relations(typename R::from::obj_ptr f );
+
+ template <class R>
+ friend void merge_relations( typename R::from::obj_ptr f1,
+ typename R::from::obj_ptr f2) ;
+
+ public:
+
+ /** Provides access to an extension object - the type and ownership is defined
+ * by the class V which should be a subtype of LCExtension, LCOwnedExtension,
+ * LCExtensionVector, LCExtensionList,...
+ */
+ template <class V>
+ inline typename V::ext_type ext() {
- static char check[ V::allowed_to_call_ext] ;
+ static char check[ V::allowed_to_call_ext] ;
- return ptr<V>() ;
- }
+ return ptr<V>() ;
+ }
- /** Provides read access to relations - the object types and their connectivity
- * are defined by the class V which has to be a subtype of either
- * LC1To1Relation, LC1ToNRelation or LCNToNRelation.
- */
- template <class V>
- inline typename V::rel_type rel() {
+ /** Provides read access to relations - the object types and their connectivity
+ * are defined by the class V which has to be a subtype of either
+ * LC1To1Relation, LC1ToNRelation or LCNToNRelation.
+ */
+ template <class V>
+ inline typename V::rel_type rel() {
- return ptr<V>() ;
- }
+ return ptr<V>() ;
+ }
- LCRTRelations() {
- _vec = new PtrVec( 32 ) ; // initialize to prevent from to many resizes
- }
+ // LCRTRelations() {
+ // _vec = new PtrVec( 32 ) ; // initialize to prevent from to many resizes
+ // }
+ // ~LCRTRelations() {
+ // for( unsigned i=0 ; i< cleaners().size() ; ++i){
+ // cleaners()[i]( _vec->operator[](i) ) ; // call the delete function
+ // }
+ // delete _vec ;
+ // }
- ~LCRTRelations() {
- for( unsigned i=0 ; i< cleaners().size() ; ++i){
- cleaners()[i]( _vec->operator[](i) ) ; // call the delete function
-
- }
- delete _vec ;
- }
-
-// ~LCRTRelations() {
-// for( PtrMap::iterator it = _map.begin() ;
-// it != _map.end() ; ++it ){
-// it->first( it->second ) ; // call the delete function
-// }
-// }
-
-// void print(){
-// std::cout << " ---- LCRTRelations -- : " << std::endl ;
-// typedef std::map< void * , void* > MyPtrMap ;
-// MyPtrMap& map = *(MyPtrMap*) &_map ;
-// for( MyPtrMap::iterator it = map.begin() ;
-// it != map.end() ; ++it ){
-// std::cout << " ---- key : " << &(it->first) << " value "
-// << (void*)it->second << std::endl ;
-// }
-// }
+ ~LCRTRelations() {
+ for( PtrMap::iterator it = _map.begin() ; it != _map.end() ; ++it ){
+ cleaners()[ it->first ] ( it->second ) ; // call the delete function
+ }
+ }
+
+ // void print(){
+ // std::cout << " ---- LCRTRelations -- : " << std::endl ;
+ // typedef std::map< void * , void* > MyPtrMap ;
+ // MyPtrMap& map = *(MyPtrMap*) &_map ;
+ // for( MyPtrMap::iterator it = map.begin() ;
+ // it != map.end() ; ++it ){
+ // std::cout << " ---- key : " << &(it->first) << " value "
+ // << (void*)it->second << std::endl ;
+ // }
+ // }
-protected:
+ protected:
- /** Returns the reference to the pointer to the extension/relation object */
- template <class V>
- inline typename V::ptr & ptr() {
+ // /** Returns the reference to the pointer to the extension/relation object */
+ // template <class V>
+ // inline typename V::ptr & ptr() {
- typedef std::vector< typename V::ptr > MyPtrVec ;
- MyPtrVec* vec = (MyPtrVec*) _vec ;
+ // typedef std::vector< typename V::ptr > MyPtrVec ;
+ // MyPtrVec* vec = (MyPtrVec*) _vec ;
- unsigned id = typeID<V>() ;
+ // unsigned id = typeID<V>() ;
- if( ! (vec->size() > id ) ) {
- vec->resize( id + 1 ) ;
- }
+ // if( ! (vec->size() > id ) ) {
+ // vec->resize( id + 1 ) ;
+ // }
- typename V::ptr& p = vec->operator[](id) ;
+ // typename V::ptr& p = vec->operator[](id) ;
- if( p == 0 )
- p = V::init() ;
+ // if( p == 0 )
+ // p = V::init() ;
- return p ;
- }
+ // return p ;
+ // }
-// /** Returns the reference to the pointer to the extension/relation object */
-// template <class V>
-// typename V::ptr & ptr() {
+
+
+ /** Returns the reference to the pointer to the extension/relation object */
+ template <class V>
+ typename V::ptr & ptr() {
-// typedef std::map< DeleteFPtr , typename V::ptr > MyPtrMap ;
+ typedef std::map< unsigned , typename V::ptr > MyPtrMap ;
-// MyPtrMap& map = *(MyPtrMap*) &_map ;
+ MyPtrMap* map = (MyPtrMap*) &_map ;
-// typename MyPtrMap::iterator it = map.find( V::deletePtr() ) ;
+ typename MyPtrMap::iterator it = map->find( typeID<V>() ) ;
-// if( it == map.end() )
-// it = map.insert( map.begin(),
-// std::make_pair( V::deletePtr(), V::init() )) ;
+ if( it == map->end() )
+ it = map->insert( map->begin(),
+ std::make_pair( typeID<V>() , V::init() )) ;
-// return it->second ;
-// }
+ return it->second ;
+ }
-private:
+ private:
- static DPtrVec& cleaners(){
- static DPtrVec v ;
- return v ;
- }
+ static DPtrVec& cleaners(){
+ static DPtrVec v ;
+ return v ;
+ }
- inline unsigned nextID(DeleteFPtr cp){
- static unsigned id(0) ;
+ inline unsigned nextID(DeleteFPtr cp){
+ static unsigned id(0) ;
-// std::cout << " ---- nextID " << id+1 << " - delete Ptr "
- // << cp << std::endl ;
+ // std::cout << " ---- nextID " << id+1 << " - delete Ptr "
+ // << cp << std::endl ;
- cleaners().push_back( cp ) ;
+ cleaners().push_back( cp ) ;
- return id++ ;
- }
+ return id++ ;
+ }
- template <class T>
- inline unsigned typeID(){
- static const unsigned uid = nextID( T::deletePtr() ) ;
+ template <class T>
+ inline unsigned typeID(){
+ static const unsigned uid = nextID( T::deletePtr() ) ;
- return uid ;
- } ;
-
- // PtrMap _map ;
+ return uid ;
+ } ;
- PtrVec* _vec ;
+ // PtrVec* _vec ;
+ PtrMap _map ;
-} ;
+ } ;
-//----------------------- relation function definitions -----------------------------------
+ //----------------------- relation function definitions -----------------------------------
-template <class R>
-void unset_relation(typename R::from::obj_ptr f){
+ template <class R>
+ void unset_relation(typename R::from::obj_ptr f){
- if( f != 0 ){
+ if( f != 0 ){
- LCRTRelations* t = f->LCRTRelations::rel<typename R::to>() ;
+ LCRTRelations* t = f->LCRTRelations::rel<typename R::to>() ;
- if( t != 0 )
- t->LCRTRelations::ptr<typename R::from>() = 0 ;
+ if( t != 0 )
+ t->LCRTRelations::ptr<typename R::from>() = 0 ;
- f->LCRTRelations::ptr<typename R::to>() = 0 ;
+ f->LCRTRelations::ptr<typename R::to>() = 0 ;
+ }
}
-}
-template <class R>
-void set_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t){
+ template <class R>
+ void set_relation(typename R::from::obj_ptr f, typename R::to::obj_ptr t){
- // clear old relations first
- unset_relation<R>( f ) ;
- unset_relation<R>(t->LCRTRelations::rel<typename R::from>() ) ;
+ // clear old relations first
+ unset_relation<R>( f ) ;
+ unset_relation<R>(t->LCRTRelations::rel<typename R::from>() ) ;
- f->LCRTRelations::ptr<typename R::to>() = t ;
- t->LCRTRelations::ptr<typename R::from>() = f ;
-}
-
-
-
-template <bool is_container>
-struct helper{
-
- template <class T, class S>
- inline static void add( T t, S s) { t->push_back( s ) ; }
-
- template <class T, class S>
- inline static void remove( T t, S s) { t->remove( s ) ; }
-};
+ f->LCRTRelations::ptr<typename R::to>() = t ;
+ t->LCRTRelations::ptr<typename R::from>() = f ;
+ }
-template <>
-struct helper<false>{
- template <class T, class S>
- inline static void add( T& t, S s) { t = s ; }
- template <class T, class S>
- inline static void remove( T& t, S s) { t = 0 ; }
-};
-template <class R>
-void add_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t){
+ template <class R>
+ void add_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t){
- f->LCRTRelations::ptr<typename R::to>()->push_back( t ) ;
+ f->LCRTRelations::ptr<typename R::to>()->push_back( t ) ;
-// std::cout << " ask to assign " << f << " to " << t << std::endl ;
- helper<R::from::is_container>::add( t->LCRTRelations::ptr<typename R::from>() , f ) ;
-}
+ // std::cout << " ask to assign " << f << " to " << t << std::endl ;
+ objorcont<R::from::is_container>::add( t->LCRTRelations::ptr<typename R::from>() , f ) ;
+ }
-template <class R>
-void remove_relation( typename R::from::obj_ptr f,
- typename R::to::obj_ptr t ) {
+ template <class R>
+ void remove_relation( typename R::from::obj_ptr f,
+ typename R::to::obj_ptr t ) {
- f->LCRTRelations::ptr<typename R::to>()->remove( t ) ;
+ f->LCRTRelations::ptr<typename R::to>()->remove( t ) ;
- helper<R::from::is_container>::remove( t->LCRTRelations::ptr<typename R::from>() , f ) ;
-}
+ objorcont<R::from::is_container>::remove( t->LCRTRelations::ptr<typename R::from>() , f ) ;
+ }
-template <class R>
-void remove_relations( typename R::from::obj_ptr f ) {
+ template <class R>
+ void remove_relations( typename R::from::obj_ptr f ) {
- typename R::to::ptr cl = f->LCRTRelations::ptr<typename R::to>() ;
+ typename R::to::ptr cl = f->LCRTRelations::ptr<typename R::to>() ;
- for( typename R::to::iterator it = cl->begin(); it!=cl->end(); ++it){
+ for( typename R::to::iterator it = cl->begin(); it!=cl->end(); ++it){
+ objorcont<R::from::is_container>::remove((*it)->LCRTRelations::ptr<typename R::from>(), f ) ;
-// (*it)->LCRTRelations::ptr<typename R::from>().remove( f ) ;
-
- helper<R::from::is_container>::remove((*it)->LCRTRelations::ptr<typename R::from>() , f ) ;
-
+ }
+ cl->clear() ;
}
- cl->clear() ;
-}
-template <class R>
-void merge_relations(typename R::from::obj_ptr f1,
- typename R::from::obj_ptr f2 ) {
+ template <class R>
+ void merge_relations(typename R::from::obj_ptr f1,
+ typename R::from::obj_ptr f2 ) {
- typename R::to::ptr lt2 = f2->LCRTRelations::ptr<typename R::to>() ;
+ typename R::to::ptr lt2 = f2->LCRTRelations::ptr<typename R::to>() ;
- for( typename R::to::iterator it = lt2->begin() ;it != lt2->end() ; it++ ){
+ for( typename R::to::iterator it = lt2->begin() ;it != lt2->end() ; it++ ){
[truncated at 1000 lines; 16 more skipped]
lcio/src/cpp/src/EXAMPLE
diff -u -r1.2 -r1.3
--- lcrtrelation.cc 30 Nov 2006 11:05:01 -0000 1.2
+++ lcrtrelation.cc 1 Dec 2006 14:10:10 -0000 1.3
@@ -6,69 +6,121 @@
#include "EVENT/Track.h"
#include "EVENT/Cluster.h"
-//static const char* FILEN = "recjob.slcio" ; // default file name
-static std::vector<std::string> FILEN ;
-
using namespace std ;
using namespace lcio ;
-struct TrkCluLink : LCNToNRelation<TrkCluLink,Track,Cluster> {} ;
+// ------ define some structs for extensions and relations:-----------
+
+// NB: the first template argument of the parent class has to the class itself !
+
+// a simple int extension
+struct Index : LCIntExtension<Index> {} ;
+
+// a vector of strings (pointers) that are owned by the object that is extended
+struct ParticleIDs : LCOwnedExtensionVector<ParticleIDs,std::string> {};
+
+
+// note extensions can be attched to any LCObject and be of any type, i.e. in particular
+// of user defined types:
+struct UserClass{
+ int someInt ;
+ float aFloat ;
+};
+struct MyUserExtension : LCOwnedExtension<MyUserExtension,UserClass> {} ;
+
+
+// relations have to specify the type of the objects from and to which they relate:
-struct Index : LCOwnedExtension<Index,int> {} ;
+// example: a one to many relationship between tracks and clusters:
+struct TrkCluLink : LC1ToNRelation<TrkCluLink,Track,Cluster> {} ;
-/** Example/test program for new LCIO runtime relations.
+// a many to many relationship between MCParticles
+struct ParentDaughter : LCNToNRelation<ParentDaughter,MCParticle,MCParticle> {} ;
+
+
+//-----------------------------------------------------------------------------------------
+
+/** Example/test program for new runtime extensions and relations
+ * requires recjob.slcio (from simjob/recjob).
*/
int main(int argc, char** argv ){
- // read file names from command line (only argument)
- if( argc < 2) {
- cout << " usage: anajob <input-file1> [[input-file2],...]" << endl ;
- exit(1) ;
- }
- for(int i=1 ; i < argc ; i++){
- FILEN.push_back( argv[i] ) ;
- }
- int nFiles = argc-1 ;
-
- LCReader* lcReader = LCFactory::getInstance()->createLCReader() ;
-
- cout << " will open and read from files: " << endl ;
- for(int i=0 ; i < nFiles ; i++){
- cout << " " << FILEN[i] << endl ;
- }
- // loop over the file and dump event data
+ LCReader* lcReader = LCFactory::getInstance()->createLCReader() ;
- lcReader->open( FILEN ) ;
+ lcReader->open( "recjob.slcio" ) ;
LCEvent* evt ;
int nEvents = 0 ;
//----------- the event loop -----------
- while( (evt = lcReader->readNextEvent()) != 0 && nEvents<10 ) {
+ while( (evt = lcReader->readNextEvent()) != 0 && nEvents < 1 ) {
-// LCTOOLS::dumpEvent( evt ) ;
- const StringVec* names = evt->getCollectionNames() ;
+ LCCollection* mcpcol = evt->getCollection("MCParticle" ) ;
+
+ int nmcp = mcpcol->getNumberOfElements() ;
- LCCollection* trkcol = 0 ;
- LCCollection* clucol = 0 ;
+ for(int i=0 ; i< nmcp ; i++ ){
- for(unsigned int i=0;i< names->size() ;++i){
+ MCParticle* mcp = dynamic_cast<MCParticle*>( mcpcol->getElementAt(i) ) ;
+
+
+ // ints can be assigned directly - w/o pointer !
+ // make every particle know it's index in the collection
+ mcp->ext<Index>() = i ;
+
+
+ // assign a user object to each particle:
+
+ mcp->ext<MyUserExtension>() = new UserClass ;
+
+ mcp->ext<MyUserExtension>()->someInt = i*42 ;
+ mcp->ext<MyUserExtension>()->aFloat = i*3.1415 ;
+
+ // assign some pid strings - note ownership is taken by particle
+
+ if( ! (i % 2) )
+
+ mcp->ext<ParticleIDs>()->push_back( new std::string("charged") ) ;
+
+ else
+
+ mcp->ext<ParticleIDs>()->push_back( new std::string("neutral") ) ;
- LCCollection* col = evt->getCollection( (*names)[i] ) ;
+ if( ! (i % 3) )
+
+ mcp->ext<ParticleIDs>()->push_back( new std::string("hadron") ) ;
+
+ else if( ! ((i+1) % 3) )
+
+ mcp->ext<ParticleIDs>()->push_back( new std::string("photon") ) ;
+
+ else if( ! ((i+2) % 3) )
+
+ mcp->ext<ParticleIDs>()->push_back( new std::string("electron") ) ;
+
+
+ // copy the parent - daughter relationship:
+
+ const MCParticleVec& daughters = mcp->getDaughters() ;
+
+ for(unsigned j=0 ; j< daughters.size() ; j++ ){
+
+ add_relation<ParentDaughter>( mcp, daughters[j] ) ;
+ }
- if( col->getTypeName() == LCIO::TRACK )
- trkcol = col ;
- if( col->getTypeName() == LCIO::CLUSTER )
- clucol = col ;
}
+
+
+ LCCollection* trkcol = evt->getCollection("SomeTracks" ) ;
+ LCCollection* clucol = evt->getCollection("SomeClusters" ) ;
if( trkcol && clucol ) {
@@ -80,43 +132,187 @@
Track* trk = dynamic_cast<Track*> ( trkcol->getElementAt(j) ) ;
- trk->ext<Index>() = new int(j) ;
+ // ints can be assigned directly - w/o pointer !
+ // make every track know it's index in the collection
+ trk->ext<Index>() = j ;
for(int k=0 ; k< nclu ; k++ ){
Cluster* clu = dynamic_cast<Cluster*> ( clucol->getElementAt(k) ) ;
+ // make every cluster know it's index in the collection
if( j == 0 )
- clu->ext<Index>() = new int(k) ;
-
- add_relation<TrkCluLink>( trk ,clu );
+ clu->ext<Index>() = k ;
- }
+ if( j % 2 && ( k == j || k == j-1 ) )
+ add_relation<TrkCluLink>( trk ,clu );
+ }
}
- // --- now print the relation:
+ // --- now print the relations:
+ std::cout << " ---- tracks assigned to clusters: " << std::endl ;
for(int j=0 ; j< ntrk ; j++ ){
- std::cout << " track " << j << " cluster relations: " ;
Track* trk = dynamic_cast<Track*> ( trkcol->getElementAt(j) ) ;
+ std::cout << " track " << trk->ext<Index>() << " assigned to clusters : " ;
+
TrkCluLink::to::rel_type clulist = trk->rel<TrkCluLink::to>() ;
for( TrkCluLink::to::const_iterator iclu = clulist->begin() ;
iclu != clulist->end() ; ++iclu ){
- Cluster* clu = *iclu ;
+ Cluster* clu = *iclu ; // iterator is of type pointer to container element
- std::cout << * clu->ext<Index>() << ", " ;
+ std::cout << clu->ext<Index>() << ", " ;
}
std::cout << std::endl ;
}
+
+ std::cout << " ----- now the inverse relation : " << std::endl ;
+
+ for(int k=0 ; k< nclu ; k++ ){
+
+ Cluster* clu = dynamic_cast<Cluster*> ( clucol->getElementAt(k) ) ;
+
+
+ Track* trk = clu->rel<TrkCluLink::from>() ;
+
+ std::cout << " cluster "
+ << clu->ext<Index>() << " assigned from track: "
+ << trk->ext<Index>() << std::endl ;
+ }
+
+ std::cout << std::endl ;
+
+
+ // print MCParticle extensions and relations:
+
+ std::cout << " ----- MCParticles in event : : " << std::endl ;
+ nmcp = ( nmcp < 10 ? nmcp : 10 ) ;
+
+ for(int i=0 ; i<nmcp ; i++ ){
+
+ MCParticle* mcp = dynamic_cast<MCParticle*>( mcpcol->getElementAt(i) ) ;
+
+ MCParticle* mcp0 ; // keep the first particle
+ if( i == 0 ) mcp0 = mcp ;
+
+ ParticleIDs::ext_type pidv = mcp->ext<ParticleIDs>() ;
+
+ std::cout << " --- particle " << mcp->ext<Index>() << " found to be : " ;
+
+ for( ParticleIDs::const_iterator ipid = pidv->begin() ; ipid != pidv->end(); ++ipid){
+
+ std::cout << **ipid << ", " ;
+ }
+
+ if( ( *(*pidv)[0] == "charged" && *(*pidv)[1] == "photon" ) ||
+ ( *(*pidv)[0] == "neutral" && *(*pidv)[1] == "electron") )
+
+ std::cout << " --- ooops ! " ;
+
+ std::cout << std::endl ;
+
+
+
+ std::cout << " --- particle " << mcp->ext<Index>() << " user extension : "
+ << " someInt: " << mcp->ext<MyUserExtension>()->someInt
+ << " aFloat: " << mcp->ext<MyUserExtension>()->aFloat
+ << std::endl ;
+
+
+ // now check that the runtime relation for daughters:
+
+ const MCParticleVec& daughters = mcp->getDaughters() ;
+
+ std::cout << " --- particle " << mcp->ext<Index>() << " daughters: "
+ << std::endl ;
+
+ std::cout << " --- from MCParticle: " ;
+
+ for(MCParticleVec::const_iterator idau = daughters.begin() ;
+ idau != daughters.end() ; ++idau){
+
+ std::cout << (*idau)->ext<Index>() << ", " ;
+ }
+ std::cout << std::endl ;
+
+
+ std::cout << " --- from runtime rel: " ;
+
+
+ ParentDaughter::to::rel_type daulist = mcp->rel<ParentDaughter::to>() ;
+
+ for( ParentDaughter::to::const_iterator idau = daulist->begin();
+ idau != daulist->end(); ++idau){
+
+ std::cout << (*idau)->ext<Index>() << ", " ;
+ }
+ std::cout << std::endl ;
+
+
+ std::cout << " --- particle " << mcp->ext<Index>() << " parents: "
+ << std::endl ;
+
+ std::cout << " --- from MCParticle: " ;
+
+
+ const MCParticleVec& parents = mcp->getParents() ;
+
+ for(MCParticleVec::const_iterator ipar = parents.begin() ;
+ ipar != parents.end() ; ++ipar){
+
+ std::cout << (*ipar)->ext<Index>() << ", " ;
+ }
+ std::cout << std::endl ;
+
+
+ std::cout << " --- from runtime rel: " ;
+
+
+ ParentDaughter::from::rel_type parlist = mcp->rel<ParentDaughter::from>() ;
+
+ for( ParentDaughter::from::const_iterator ipar = parlist->begin();
+ ipar != parlist->end(); ++ipar){
+
+ std::cout << (*ipar)->ext<Index>() << ", " ;
+ }
+ std::cout << std::endl ;
+
+
+ // for demonstration we can rearange the daughter relationships:
+ if(i>0)
+
+ merge_relations<ParentDaughter>( mcp0 , mcp ) ;
+ }
+
+ for(int i=0 ; i<nmcp ; i++ ){
+
+ MCParticle* mcp = dynamic_cast<MCParticle*>( mcpcol->getElementAt(i) ) ;
+
+ std::cout << " --- particle " << mcp->ext<Index>()
+ << " daughters after merging : " ;
+
+
+ ParentDaughter::to::rel_type daulist = mcp->rel<ParentDaughter::to>() ;
+
+ for( ParentDaughter::to::const_iterator idau = daulist->begin();
+ idau != daulist->end(); ++idau){
+
+ std::cout << (*idau)->ext<Index>() << ", " ;
+ }
+ std::cout << std::endl ;
+
+ }
+
+
} else {
std::cout << " couldn't find Track and Cluster collection in event !" << std::endl ;
}
@@ -125,10 +321,6 @@
}
// -------- end of event loop -----------
- cout << endl << " " << nEvents << " events read from files: " << endl ;
- for(int i=0 ; i < nFiles ; i++){
- cout << " " << FILEN[i] << endl ;
- }
lcReader->close() ;
delete lcReader ;