Belle II Software light-2505-deimos
SelectSubset< StoredClass > Class Template Reference

Class to create a subset of a given StoreArray together with the relations with other StoreArrays. More...

#include <SelectSubset.h>

Inheritance diagram for SelectSubset< StoredClass >:
Collaboration diagram for SelectSubset< StoredClass >:

Public Member Functions

 SelectSubset ()
 Constructor.
 
 ~SelectSubset ()
 Destructor.
 
void registerSubset (const StoreArray< StoredClass > &set, DataStore::EStoreFlags storeFlags=DataStore::c_ErrorIfAlreadyRegistered)
 Remove all non-selected objects from set.
 
void registerSubset (const StoreArray< StoredClass > &set, const std::string &subsetName, DataStore::EStoreFlags storeFlags=DataStore::c_ErrorIfAlreadyRegistered)
 Register the StoreArray<StoredClass> that will contain the subset of selected elements.
 
template<class T, class ... MoreArguments>
void inheritRelationsFrom (const StoreArray< T > &array, MoreArguments... moreArgs)
 Inherit relations pointing from Other to objects selected into this subset.
 
template<class T, class ... MoreArguments>
void inheritRelationsTo (const StoreArray< T > &array, MoreArguments... moreArgs)
 Inherit relations pointing from objects selected into this subset to Other.
 
void inheritAllRelations ()
 Automatically inherit all relations to or from the original set (if registered when calling this function).
 
void select (const std::function< bool(const StoredClass *)> &f)
 This method is the actual worker.
 
StoreAccessorBasegetSet () override
 Get accessor for original set.
 
StoreAccessorBasegetSubSet () override
 Get accessor for reduced set.
 
std::vector< std::string > getInheritFromArrays () const
 Get list of arrays we inherit relations from.
 
std::vector< std::string > getInheritToArrays () const
 Get list of arrays we inherit relations to.
 
bool getInheritToSelf () const
 Do we inherit relations from original set to itself?
 
void swapSetsAndDestroyOriginal ()
 Swap set and subset (+relations), and keep only the reduced set.
 

Protected Member Functions

std::map< int, int > copySetWithRelations (std::function< bool(const StoredClass *)> f)
 Selects the elements, fill the subset and copies all the relations in which the set is involved.
 
void copyRelationsToSelf ()
 Copy any set -> set relations between selected objects.
 
void inheritRelationsFrom ()
 Empty method to stop the recursion of the variadic template.
 
void inheritRelationsTo ()
 Empty method to stop the recursion of the variadic template.
 

Protected Attributes

StoreArray< StoredClass > * m_set = nullptr
 The array we use as input.
 
StoreArray< StoredClass > * m_subset = nullptr
 The array we create.
 
DataStore::EStoreFlags m_subsetFlags = DataStore::c_WriteOut
 Flags used for m_subset.
 
std::vector< std::string > m_inheritFromArrays
 array names we inherit relations from.
 
std::vector< std::string > m_inheritToArrays
 array names we inherit relations to.
 
bool m_inheritToSelf = false
 If true, relations from set objects to set objects are copied.
 
bool m_reduceExistingSet = false
 If true, non-selected candidates are removed from m_set, m_subset only exists temporarily.
 

Detailed Description

template<typename StoredClass>
class Belle2::SelectSubset< StoredClass >

Class to create a subset of a given StoreArray together with the relations with other StoreArrays.

The class SelectSubset selects a subset of objects contained in a given StoreArray creating at the same time a set of relations with objects contained in other StoreArrays that are the natural restrictions on the subset of the relations "from" or "to" the original one.

Creating a subset

Assuming you have a StoreArray called 'particles' that contains objects of type Particle you can use SelectSubset to select particles with a given feature and put them in another StoreArray called, as an example,'oddParticles'.

Instantiation

First you need to add a SelectSubset to your module as a member variable:

Initialization

In the initialize method of your module you have to initialize the SelectSubset

StoreArray< Particle > set( "particles" );
set.isRequired(); // or isOptional(). The choice is up to you.
m_selector.registerSubset( set, "oddParticles");
void registerSubset(const StoreArray< StoredClass > &set, DataStore::EStoreFlags storeFlags=DataStore::c_ErrorIfAlreadyRegistered)
Remove all non-selected objects from set.

The SelectSubset class will take care of creating the new StoreArray<Particle>, register it into the datastore with name "oddParticles" same durability and same persistent attributes of the original one.

Inheritance of relations can also be configured here, see "Relations" section below.

Selection

To create the subset you have to specify the selection criterium. You can do that in two possible ways.

via C++ function

You can define your C++ function and then use it. E.g:

bool
MySelectionFunction( const Particle * particle){
// this function tells if the particle is odd
return ( particle->UniqueId() % 2 ) == 1 ;
}
Class to store reconstructed particles.
Definition Particle.h:76

Then in the event method of your module:

m_selector.select( MySelectionFunction );
void select(const std::function< bool(const StoredClass *)> &f)
This method is the actual worker.

via C++ lambda function

You can specify a lambda expression as parameter of the select method. E.g.: in the event method of your code:

m_selector.select( []( const Particle * particle )
{ return ( particle->UniqueId() % 2 ) == 1 ; } );

with the advantage of an easy capture of module parameters. E.g. to count the number of rejected particles:

int rejected(0);
m_selector.select( [& rejected]( const Particle * particle )
{
if ( ( particle->UniqueId() % 2 ) == 1 )
return true;
rejected ++;
return false;
});
B2INFO("The selector rejected " << rejected << " particles." );

Relations

By default the class SelectSubset produces a one to one relation from the set to the subset by which you can interpret all the relations from and to the original set. E.g. The original StoreArray<Particle> is in relation To the StoreArray<MCParticle>. You can use the relation from the set to the subset and then from the set to the MCParticles. This can be quite tedious, so you can ask SelectSubset to produce the natural restrictions of the relations from and to the original set.

Automatic inheritance

If you want your subset to have the same relations as for the original set, you can simply use

m_selector.inheritAllRelations();
void inheritAllRelations()
Automatically inherit all relations to or from the original set (if registered when calling this func...

Manually specifying relations to inherit

Alternatively, you can specify the arrays you want to inherit from/to manually:

Relations to other StoreArrays

Assuming there is a relation from your original set to other arrays A and B, you can inherit these relations for all objects selected into your subset using:

m_selector.inheritRelationsTo(a, b);
//alternatively, you can also use multiple calls to the function
m_selector.inheritRelationsTo(a);
m_selector.inheritRelationsTo(b);
void inheritRelationsTo(const StoreArray< T > &array, MoreArguments... moreArgs)
Inherit relations pointing from objects selected into this subset to Other.

Relations from other StoreArrays

Relations pointing from objects in other arrays to objects in the original set can also be inherited in a very similar way:

m_selector.inheritRelationsFrom(c, d);
//alternatively, you can also use multiple calls to the function
m_selector.inheritRelationsFrom(c);
m_selector.inheritRelationsFrom(d);
void inheritRelationsFrom(const StoreArray< T > &array, MoreArguments... moreArgs)
Inherit relations pointing from Other to objects selected into this subset.

Relations from the StoreArray to itself

If there are relations from objects in the original set to other objects in the same array (e.g. Particles -> Particles), you can also inherit these by doing

m_selector.inheritRelationsFrom(set);
// or:
// m_selector.inheritRelationsTo(set);

Note that both objects related must pass the selection criteria, or there would be one missing partner in the relation.

Definition at line 193 of file SelectSubset.h.

Constructor & Destructor Documentation

◆ SelectSubset()

template<typename StoredClass>
SelectSubset ( )
inline

Constructor.

Definition at line 198 of file SelectSubset.h.

198: SelectSubsetBase() {};

◆ ~SelectSubset()

template<typename StoredClass>
~SelectSubset ( )
inline

Destructor.

Definition at line 201 of file SelectSubset.h.

202 {
203 delete m_set;
204 delete m_subset;
205 }

Member Function Documentation

◆ getInheritFromArrays()

std::vector< std::string > getInheritFromArrays ( ) const
inlineinherited

Get list of arrays we inherit relations from.

Definition at line 32 of file SelectSubset.h.

32{ return m_inheritFromArrays; }

◆ getInheritToArrays()

std::vector< std::string > getInheritToArrays ( ) const
inlineinherited

Get list of arrays we inherit relations to.

Definition at line 34 of file SelectSubset.h.

34{ return m_inheritToArrays; }

◆ getInheritToSelf()

bool getInheritToSelf ( ) const
inlineinherited

Do we inherit relations from original set to itself?

Definition at line 36 of file SelectSubset.h.

36{ return m_inheritToSelf; }

◆ getSet()

template<typename StoredClass>
StoreAccessorBase * getSet ( )
inlineoverridevirtual

Get accessor for original set.

Implements SelectSubsetBase.

Definition at line 325 of file SelectSubset.h.

325{ return m_set; }

◆ getSubSet()

template<typename StoredClass>
StoreAccessorBase * getSubSet ( )
inlineoverridevirtual

Get accessor for reduced set.

Implements SelectSubsetBase.

Definition at line 327 of file SelectSubset.h.

327{ return m_subset; }

◆ inheritAllRelations()

template<typename StoredClass>
void inheritAllRelations ( )
inline

Automatically inherit all relations to or from the original set (if registered when calling this function).

Equivalent to calling inheritRelationsFrom()/To() for all related arrays.

Note: Do not combine with inheritRelationsFrom() and inheritRelationsTo().

Definition at line 301 of file SelectSubset.h.

302 {
303 auto arrays = DataStore::Instance().getListOfRelatedArrays(*m_set);
304
305 for (std::string arrayName : arrays) {
306 StoreArray<TObject> array(arrayName, m_set->getDurability());
307 if (array == *m_subset)
308 continue; // from registerSubset(), ignore
309
310 if (array.optionalRelationTo(*m_set, m_set->getDurability()))
311 inheritRelationsFrom(array);
312 if (m_set->optionalRelationTo(array, m_set->getDurability()))
313 inheritRelationsTo(array);
314 }
315 }

◆ inheritRelationsFrom() [1/2]

template<typename StoredClass>
void inheritRelationsFrom ( )
inlineprotected

Empty method to stop the recursion of the variadic template.

Definition at line 337 of file SelectSubset.h.

337{ }

◆ inheritRelationsFrom() [2/2]

template<typename StoredClass>
template<class T, class ... MoreArguments>
void inheritRelationsFrom ( const StoreArray< T > & array,
MoreArguments... moreArgs )
inline

Inherit relations pointing from Other to objects selected into this subset.

You can specify an unlimited number of arrays as arguments to this function.

Definition at line 250 of file SelectSubset.h.

251 {
252 if (array.getName() == m_set->getName()) {
253 m_inheritToSelf = true;
254 inheritRelationsFrom(*m_subset, moreArgs...);
255 } else {
256 const_cast<StoreArray<T>&>(array).isRequired();
257
258 DataStore::EStoreFlags flags = m_subsetFlags;
259 if (m_subset->notWrittenOut() or array.notWrittenOut())
260 flags |= DataStore::c_DontWriteOut;
261 array.registerRelationTo(*m_subset, m_subset->getDurability(), flags);
262
263 if (array.getName() != m_subset->getName())
264 m_inheritFromArrays.push_back(array.getName());
265
266 inheritRelationsFrom(moreArgs ...);
267 }
268 }

◆ inheritRelationsTo() [1/2]

template<typename StoredClass>
void inheritRelationsTo ( )
inlineprotected

Empty method to stop the recursion of the variadic template.

Definition at line 339 of file SelectSubset.h.

339{ }

◆ inheritRelationsTo() [2/2]

template<typename StoredClass>
template<class T, class ... MoreArguments>
void inheritRelationsTo ( const StoreArray< T > & array,
MoreArguments... moreArgs )
inline

Inherit relations pointing from objects selected into this subset to Other.

You can specify an unlimited number of arrays as arguments to this function.

Definition at line 275 of file SelectSubset.h.

276 {
277 if (array.getName() == m_set->getName()) {
278 m_inheritToSelf = true;
279 inheritRelationsTo(*m_subset, moreArgs...);
280 } else {
281 const_cast<StoreArray<T>&>(array).isRequired();
282
283 DataStore::EStoreFlags flags = m_subsetFlags;
284 if (m_subset->notWrittenOut() or array.notWrittenOut())
285 flags |= DataStore::c_DontWriteOut;
286 m_subset->registerRelationTo(array, m_subset->getDurability(), flags);
287
288 if (array.getName() != m_subset->getName())
289 m_inheritToArrays.push_back(array.getName());
290
291 inheritRelationsTo(moreArgs ...);
292 }
293 }

◆ registerSubset() [1/2]

template<typename StoredClass>
void registerSubset ( const StoreArray< StoredClass > & set,
const std::string & subsetName,
DataStore::EStoreFlags storeFlags = DataStore::c_ErrorIfAlreadyRegistered )
inline

Register the StoreArray<StoredClass> that will contain the subset of selected elements.

Parameters
setThe StoreArray<StoredClass> from which the elements will be selected
subsetNameThe name of the StoreArray<StoredClass> that will contain the selected elements
storeFlagsORed combination of DataStore::EStoreFlags.

Definition at line 229 of file SelectSubset.h.

231 {
232 if (m_set or m_subset) {
233 B2FATAL("SelectSubset::registerSubset() can only be called once!");
234 }
235
236 m_set = new StoreArray<StoredClass>(set);
237
238 m_subset = new StoreArray<StoredClass>(subsetName, m_set->getDurability());
239 m_subset->registerInDataStore(storeFlags);
240 m_subsetFlags = storeFlags;
241
242 set.registerRelationTo(*m_subset, m_subset->getDurability(), storeFlags);
243 }

◆ registerSubset() [2/2]

template<typename StoredClass>
void registerSubset ( const StoreArray< StoredClass > & set,
DataStore::EStoreFlags storeFlags = DataStore::c_ErrorIfAlreadyRegistered )
inline

Remove all non-selected objects from set.

All relations registered so far are retained. TODO: consider moving this into StoreArray itself

Parameters
setThe StoreArray<StoredClass> from which to retain only selected elements
storeFlagsflags used for temporary arrays and relations. Should be changed from the default if you want multiple instances. c_DontWriteOut is always used.

Definition at line 215 of file SelectSubset.h.

217 {
218 m_reduceExistingSet = true;
219 registerSubset(set, set.getName() + "_tmpSubset", storeFlags | DataStore::c_DontWriteOut);
220
221 inheritAllRelations();
222 }

◆ swapSetsAndDestroyOriginal()

void swapSetsAndDestroyOriginal ( )
inherited

Swap set and subset (+relations), and keep only the reduced set.

Subset and associated relations will be empty afterwards.

Definition at line 14 of file SelectSubset.cc.

15{
16 StoreAccessorBase* set = getSet();
17 StoreAccessorBase* subset = getSubSet();
18
19 //replace set with subset
20 DataStore::Instance().replaceData(*subset, *set);
21
22 //swap relations
23 for (const std::string& fromArray : m_inheritFromArrays) {
24 RelationArray setRel(DataStore::relationName(fromArray, set->getName()));
25 RelationArray subsetRel(DataStore::relationName(fromArray, subset->getName()));
26 DataStore::Instance().replaceData(subsetRel, setRel);
27 }
28 for (const std::string& toArray : m_inheritToArrays) {
29 RelationArray setRel(DataStore::relationName(set->getName(), toArray));
30 RelationArray subsetRel(DataStore::relationName(subset->getName(), toArray));
31 DataStore::Instance().replaceData(subsetRel, setRel);
32 }
33}
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
Definition DataStore.h:180
void replaceData(const StoreAccessorBase &from, const StoreAccessorBase &to)
For two StoreAccessors of same type, move all data in 'from' into 'to', discarding previous contents ...
Definition DataStore.cc:342
std::vector< std::string > m_inheritFromArrays
array names we inherit relations from.
virtual StoreAccessorBase * getSubSet()=0
Get accessor for reduced set.
virtual StoreAccessorBase * getSet()=0
Get accessor for original set.
std::vector< std::string > m_inheritToArrays
array names we inherit relations to.
const std::string & getName() const
Return name under which the object is saved in the DataStore.

Member Data Documentation

◆ m_inheritFromArrays

std::vector<std::string> m_inheritFromArrays
protectedinherited

array names we inherit relations from.

Definition at line 54 of file SelectSubset.h.

◆ m_inheritToArrays

std::vector<std::string> m_inheritToArrays
protectedinherited

array names we inherit relations to.

Definition at line 56 of file SelectSubset.h.

◆ m_inheritToSelf

bool m_inheritToSelf = false
protectedinherited

If true, relations from set objects to set objects are copied.

(if both objects are selected!).

Definition at line 58 of file SelectSubset.h.

◆ m_reduceExistingSet

bool m_reduceExistingSet = false
protectedinherited

If true, non-selected candidates are removed from m_set, m_subset only exists temporarily.

Definition at line 60 of file SelectSubset.h.

◆ m_set

template<typename StoredClass>
StoreArray<StoredClass>* m_set = nullptr
protected

The array we use as input.

Definition at line 342 of file SelectSubset.h.

◆ m_subset

template<typename StoredClass>
StoreArray<StoredClass>* m_subset = nullptr
protected

The array we create.

Definition at line 344 of file SelectSubset.h.

◆ m_subsetFlags

template<typename StoredClass>
DataStore::EStoreFlags m_subsetFlags = DataStore::c_WriteOut
protected

Flags used for m_subset.

Definition at line 346 of file SelectSubset.h.


The documentation for this class was generated from the following file: