How to write a new Cluster Finder


To create a new algorithm it is important to understand how the cluster finder works.


This file defines a simple enumerator for the many possible cluster algorithms. In order to add a new algorithm the user should add a new position in this enumerator

StPreEclMaker.h and .cxx

The cluster finder itself (StPreEclMaker) is a very simple maker. This maker is responsible only for creating the finder (in the Init() method) and call some basic functions in the Make() method.


This method just instantiates the finder. In the very beginning of Init() method, the code checks which algorithm is being requested and creates the proper finder.


The Make() method grabs the event (StEvent only) and exits if no event is found. If the event is found it calls 4 methods in the finder. These methods are:

  • mFinder->clear(); // to clear the previous event local cluster
  • mFinder->clear(StEvent*); // to clean any old cluster or pointer in StEvent
  • mFinder->findClusters(StEvent*); // to find the clusters in this event
  • mFinder->fillStEvent(StEvent*); // to fill StEvent with the new clusters
  • mFinder->fillHistograms(StEvent*); // to fill QA histograms

The modifications the user should do in StPreEclMaker.cxx are only to add the possibility of instantiating his/her finder in the StPreEclMaker::Init() method.

Creating a new cluster algorithm

Before creating a new cluster algorithm it is important to know the basic idea behind the code.  The basic classes are


There is an internal data format for the clusters in the code. The clusters are StEmcPreCluster which are derived from plain ROOT TObject. StEmcPreCluster is more complete than the regular StEvent cluster object (StEmcCluster) because it has methods to add and remove hits, split and merge clusters and well set matching id between different detectors.


This is a placeholder for the StEmcPreCluster objects that are created. This object derives from the regular ROOT TList object. It has methods to create, add, remove and delete StEmcPreClusters. StEmcPreCluster objects that are created or added to the collections are owned by the collection so be careful.


This is the basic finder class. Any cluster algorithm should inherit from this class. It already create the necessary collections for the clusters in each detector.

To create a new finder algorithm you should define a finder class that inherits from the StEmcVirtualFinder and overwrite the method findClusters(StEvent*). Lets suppose you want to create a StEmcMyFinder algorithm. You should create a class with, at least, the following:

#ifndef STAR_StEmcMyFinder
#define STAR_StEmcMyFinder

#include "StEmcVirtualFinder.h"

class StEvent;

class StEmcOldFinder : public StEmcVirtualFinder

virtual ~StEmcOldFinder();
virtual Bool_t findClusters(StEvent*);




#include "StEmcMyFinder.h"
#include "StEvent.h"
#include "StEventTypes.h"


// initialize your stuff in here
Bool_t StEmcMyFinder::findClusters(StEvent* event)
// check if there is an emc collection

StEmcCollection *emc = event->emcCollection();
if(!emc) return kFALSE;

// find your clusters

return kTRUE;

The method findClusters(StEvent*) is the method that StPreEclMaker will call in order to find clusters in the event. All the StEmcVirtualFinder methods are available for the user.

The user has 4 pre cluster collections available. They are named


where det =1, 2, 3 and 4 (btow, bprs, bsmde and bsmdp)

How to deal with clusters and collections

Lets suppose you identified a cluster in a given detector. How do I work with StEmcPreCluster objects and the collections? Please look at the code itself to be more familiar with the interface. The next lines will give basic instructions with the most common tools:

To create and add a cluster to the collection for the detector ´det´
StEmcPreCluster *cl = mColl[det-1]->newCluster();

This line creates a cluster in the collection and returns its pointer.

To remove and delete a cluster from a collection
mColl[det-1]->removeCluster(cl); // cl is the pointer to the cluster


mColl[det-1]->removeCluster(i); // i is the index of the cluster in the collection

This will remove AND delete the cluster.

To get the number of clusters in a collection

To add hits to a StEmcPreCluster (pointer to the cluster is called ´cl´)

where hit is a pointer to a StEmcRawHit object.

To add the content of a pre cluster ´cl1´ to a cluster ´cl´

The added cluster ´cl1´ is not deleted. This is very useful if you identified a spitted cluster and would like to merge them.

How to do matching in the cluster finder?
Depending on the cluster finder algorithm one can do clusters in one detector using the information in the other detector as seed. In this sense, it is important do have some kind of matching available in the cluster finder. In the original software scheme, StEpcMaker is the maker responsible for matching the clusters in the BEMC sub detectors. This maker is still in the chain.

Because of StEpcMaker, we CAN NOT create StEmcPoints in the cluster finder. This should be done *ONLY* by StEpcMaker. In order to have a solution for that, StEmcPreCluster object has a member that flags the cluster with matching information. This is done by setting a matching id in the cluster. Use the methods matchingId() and setMatchingId(Int_t).

The matching id is an integer number. If matching id = 0 (default value), no matching was done and the matching will be decided in StEpcMaker. If matching id is not equal to 0, StEpcMaker will create points with clusters with the same matching Id.

Using this procedure, we can develop advanced matching methods in the cluster finder algorithm.

How to plug your finder into the cluster finder

In order to plug your algorithm to the cluster finder you need to change two files in the main finder

This file defines an enumerator with the cluster finders. To add your algorithm in this enumerator add an entry in the enumerator definition, for example:

enum EmcClusterAlgorithm
{ kEmcClNoFinder = 0, kEmcClDefault = 1, kEmcClOld = 2, kEmcMyFinder = 3};

You should change the Init() method in StPreEclMaker in order to instantiate your finder. To instantiate your StEmcMyFinder object, add, in the Init() method of StPreEclMaker:

if(mAlg == kEmcClOld) mFinder = new StEmcOldFinder();
if(mAlg == kEmcMyFinder) mFinder = new StEmcMyFinder();