21 #include "TObjArray.h"
23 #include "St_base/StMessMgr.h"
25 #include "StEvent/StFmsHit.h"
36 const Float_t maxDistanceFromPeak = 0.3;
37 const Int_t minTowerCatag02 = 5;
38 const Float_t cutEcSigma[2][2] = {{2.1, 7.0}, {2.1, 2.0}};
39 const Float_t minEcSigma2Ph = 35.;
40 const Float_t maxEcSigma1Ph = 10.;
41 const Float_t minTowerEnergy = 0.01;
42 const Float_t minRatioPeakTower = 1.6;
44 const Float_t ExtremelyFaraway = 99999;
47 typedef TowerList::iterator TowerIter;
48 typedef TowerList::const_reverse_iterator TowerConstRIter;
49 typedef FMSCluster::ClusterList::iterator ClusterIter;
50 typedef FMSCluster::ClusterList::value_type ClusterPtr;
63 Bool_t couldBePeakTower(
const StFmsTower* tower, TowerList* nonPeakTowers) {
64 Bool_t couldBePeak(
true);
65 for (TowerIter i = nonPeakTowers->begin(); i != nonPeakTowers->end(); ++i) {
67 if (tower->isNeighbor(**i)) {
68 if (tower->hit()->energy() < minRatioPeakTower * (*i)->hit()->energy()) {
78 bool ascendingTowerEnergySorter(
const StFmsTower* a,
const StFmsTower* b) {
79 return a->hit()->energy() < b->hit()->energy();
83 bool descendingTowerEnergySorter(
const StFmsTower* a,
const StFmsTower* b) {
84 return a->hit()->energy() > b->hit()->energy();
88 bool towerEnergyIsAboveThreshold(
const StFmsTower* tower) {
89 return !(tower->hit()->energy() < minTowerEnergy);
100 bool towerIsNeighbor(
const StFmsTower*
test,
const StFmsTower* reference) {
101 if (towerEnergyIsAboveThreshold(test)) {
102 return test->isNeighbor(*reference);
113 TowerList filterTowersBelowEnergyThreshold(TowerList* towers) {
117 TowerIter newEnd = std::partition(towers->begin(), towers->end(),
118 std::ptr_fun(&towerEnergyIsAboveThreshold));
120 TowerList belowThreshold(newEnd, towers->end());
122 towers->erase(newEnd, towers->end());
123 return belowThreshold;
140 for (ClusterIter i = clusters->begin(); i != clusters->end(); ++i) {
141 (*i)->towers().sort(std::ptr_fun(&descendingTowerEnergySorter));
146 namespace FMSCluster {
195 if (kPeakTower == distance) {
231 typedef StFmsTowerCluster::Towers::const_iterator TowerIter;
232 for (TowerIter tower = towers.begin(); tower != towers.end(); ++
tower) {
237 mTower->
hit()->energy() < minRatioPeakTower *
238 (*tower)->hit()->energy()) {
264 bool inserted(
false);
274 double distNew =
separation(cluster, distance);
277 if (distNew < distOld) {
283 if (distNew <= distOld) {
303 double minDist = ExtremelyFaraway;
304 std::list<StFmsTowerCluster*>::iterator i;
306 float distance =
separation(*i, kClusterCenter);
308 if (distance < minDist) {
348 (sMaxEc - cutEcSigma[0][1])) {
349 if (sMaxEc > minEcSigma2Ph) {
355 cutEcSigma[1][0] * (sMaxEc - cutEcSigma[1][1])) {
356 if (sMaxEc < maxEcSigma1Ph) {
370 TowerList belowThreshold = filterTowersBelowEnergyThreshold(towers);
379 neighbors.sort(std::ptr_fun(&ascendingTowerEnergySorter));
385 TObjArray valleys(16);
386 valleys.SetOwner(
true);
387 unsigned nAssociations(0);
390 }
while (nAssociations > 0);
394 for (
auto i = clusters->begin(); i != clusters->end(); ++i) {
403 }
while (nAssociations > 0);
404 sortTowersEnergyDescending(clusters,
mNClusts);
406 for (ClusterIter i = clusters->begin(); i != clusters->end(); ++i) {
415 TowerList* neighbors,
418 towers->sort(std::ptr_fun(&descendingTowerEnergySorter));
419 while (!towers->empty() && clusters->size() <
kMaxNClusters) {
427 if (couldBePeakTower(high, neighbors)) {
431 clusters->back()->setIndex(high->
cluster());
432 clusters->back()->towers().push_back(high);
437 TowerIter neighborEnd =
438 std::stable_partition(towers->begin(), towers->end(),
439 std::bind2nd(std::ptr_fun(&towerIsNeighbor),
442 neighbors->insert(neighbors->end(), towers->begin(), neighborEnd);
443 towers->erase(towers->begin(), neighborEnd);
445 neighbors->push_back(high);
451 TowerIter towerIter = towers->begin();
452 while (towerIter != towers->end()) {
455 if (!couldBePeakTower(*towerIter, neighbors)) {
456 neighbors->push_back(*towerIter);
457 towers->erase(towerIter++);
463 return clusters->size();
467 TowerList* neighbors,
469 TObjArray* valleys)
const {
470 TowerList associated;
473 TowerConstRIter tower;
474 for (tower = neighbors->rbegin(); tower != neighbors->rend(); ++tower) {
476 std::unique_ptr<TowerClusterAssociation> association(
478 for (ClusterIter i = clusters->begin(); i != clusters->end(); ++i) {
479 association->add(i->get(), kPeakTower);
482 if (association->clusters()->size() == 1) {
484 association->clusters()->front()->towers().push_back(*tower);
485 associated.push_back(*tower);
486 }
else if (association->clusters()->size() > 1) {
489 valleys->Add(association.release());
490 associated.push_back(*tower);
494 for (TowerIter i = associated.begin(); i != associated.end(); ++i) {
495 neighbors->remove(*i);
497 return associated.size();
501 TowerList* neighbors,
503 TObjArray* valleys)
const {
504 unsigned size = neighbors->size();
505 for (Int_t i(0); i < valleys->GetEntriesFast(); ++i) {
512 neighbors->remove(association->
tower());
515 LOG_INFO <<
"Something is wrong! The following \"Valley\" tower does "
516 <<
"not belong to any cluster! Error!" << endm;
517 association->
tower()->Print();
520 return size - neighbors->size();
524 TowerList* neighbors,
526 TowerList associated;
527 TowerConstRIter tower;
528 for (tower = neighbors->rbegin(); tower != neighbors->rend(); ++tower) {
531 for (ClusterIter i = clusters->begin(); i != clusters->end(); ++i) {
535 association.
add(i->get(), kClusterCenter);
537 if (!association.
clusters()->empty()) {
539 (*tower)->setCluster(cluster->
index());
540 cluster->
towers().push_back(*tower);
541 associated.push_back(*tower);
544 for (TowerIter i = associated.begin(); i != associated.end(); ++i) {
545 neighbors->remove(*i);
547 return associated.size();
554 for (tower = towers->begin(); tower != towers->end(); ++tower) {
557 for (ClusterIter i = clusters->begin(); i != clusters->end(); ++i) {
558 association.
add(i->get(), kPeakTower);
562 association.
separation(cluster, kClusterCenter) < maxDistanceFromPeak) {
563 (*tower)->setCluster(cluster->
index());
564 cluster->
towers().push_back(*tower);
A cluster created by 2 photons.
double separation(const StFmsTower *tower)
Float_t mEnergyCutoff
Tower energy cutoff for cluster moments.
unsigned associateResidualTowersWithClusters(TowerList *neighbors, ClusterList *clusters) const
bool canAssociate(const StFmsTowerCluster *cluster)
std::list< StFmsTowerCluster * > mClusters
Associable clusters.
StFmsTower * mTower
Reference FMS tower.
A cluster created by 1 photon.
unsigned locateClusterSeeds(TowerList *towers, TowerList *neighbors, ClusterList *clusters) const
Declaration of StFmsCluster, a group of adjacent FMS hits.
int categorise(StFmsTowerCluster *cluster)
void associateSubThresholdTowersWithClusters(TowerList *towers, ClusterList *clusters) const
Declaration of StFmsTower, a simple FMS tower wrapper.
double separation(const StFmsTowerCluster *cluster, const ETowerClusterDistance distance)
std::list< FMSCluster::StFmsTower * > TowerList
void setMomentEnergyCutoff(float cutoff=0.5)
Declaration of StFmsClusterFinder, an FMS tower clustering algorithm.
unsigned associateTowersWithClusters(TowerList *neighbors, ClusterList *clusters, TObjArray *valleys) const
Int_t mNClusts
Counter for number of found clusters.
std::list< StFmsTower * > Towers
Shorthand for tower collection.
void setCluster(Int_t cluster)
Declaration of StFmsTowerCluster, a cluster of FMS towers.
std::list< StFmsTowerCluster * > * clusters()
Bool_t isNeighbor(const StFmsTower &tower) const
TowerClusterAssociation(StFmsTower *tower)
const StFmsTower * tower() const
std::list< std::unique_ptr< StFmsTowerCluster > > ClusterList
const StFmsHit * hit() const
void setNTowers(Int_t numbTower)
unsigned associateValleyTowersWithClusters(TowerList *neighbors, ClusterList *clusters, TObjArray *valleys) const
void calculateClusterMoments(StFmsTowerCluster *cluster) const
int findClusters(TowerList *towers, ClusterList *clusters)
bool add(StFmsTowerCluster *cluster, const ETowerClusterDistance distance)
void calculateClusterMoments(Float_t energyCutoff)
void setCategory(Int_t catag)
Could be 1- or 2-photon, needs to be fitted.
StFmsTowerCluster * nearestCluster()
static const unsigned kMaxNClusters
We stop looking after this many.