22 #include "StFttClusterMaker.h"
25 #include "StEvent/StFttRawHit.h"
26 #include "StEvent/StFttCluster.h"
27 #include "StEvent/StEvent.h"
28 #include "StEvent/StFttCollection.h"
30 #include "StFttDbMaker/StFttDb.h"
34 StFttClusterMaker::StFttClusterMaker(
const char* name )
41 LOG_DEBUG <<
"StFttClusterMaker::ctor" << endm;
45 StFttClusterMaker::~StFttClusterMaker()
52 StFttClusterMaker::Init()
54 LOG_INFO <<
"StFttClusterMaker::Init" << endm;
61 StFttClusterMaker::InitRun( Int_t runnumber )
63 mRunYear = ( runnumber + 727000 ) / 1000000 + 1999;
65 LOG_INFO <<
"runnumber: " << runnumber <<
" --> year: " << mRunYear << endm;
72 StFttClusterMaker::FinishRun( Int_t runnumber )
89 mEvent = (
StEvent*)GetInputDS(
"StEvent");
92 LOG_WARN<<
"No StEvent!"<<endm;
95 mFttCollection=mEvent->fttCollection();
97 LOG_WARN <<
"No StFttCollection" << endm;
101 mFttDb =
static_cast<StFttDb*
>(GetDataSet(
"fttDb"));
104 LOG_DEBUG <<
"Found " << mFttCollection->rawHits().size() <<
" Ftt Hits" << endm;
116 std::map< UChar_t, std::vector<StFttRawHit *> > hStripsPerRob;
117 std::map< UChar_t, std::vector<StFttRawHit *> > vStripsPerRob;
118 std::map< UChar_t, std::vector<StFttRawHit *> > dhStripsPerRob;
119 std::map< UChar_t, std::vector<StFttRawHit *> > dvStripsPerRob;
121 size_t nStripsHit = 0;
123 UChar_t rob = mFttDb->rob(
hit );
124 UChar_t so = mFttDb->orientation(
hit );
127 if ( !PassTimeCut(
hit ) )
continue;
129 if ( kFttHorizontal == so ){
130 hStripsPerRob[ rob ].push_back(
hit);
133 if ( kFttVertical == so ){
134 vStripsPerRob[ rob ].push_back(
hit);
137 if ( kFttDiagonalH == so ){
138 dhStripsPerRob[ rob ].push_back(
hit);
141 if ( kFttDiagonalV == so ){
142 dvStripsPerRob[ rob ].push_back(
hit);
147 size_t nClusters = 0;
148 LOG_DEBUG <<
"StFttClusterMaker::Make{ nStripsHit = " << nStripsHit <<
" }" << endm;
149 if ( nStripsHit > 0 ){
150 for ( UChar_t iRob = 1; iRob < StFttDb::nRob+1; iRob++ ){
152 auto hClusters = FindClusters( hStripsPerRob[iRob] );
155 mFttCollection->addCluster( clu );
158 auto vClusters = FindClusters( vStripsPerRob[iRob] );
161 mFttCollection->addCluster( clu );
164 auto hdClusters = FindClusters( dhStripsPerRob[iRob] );
167 mFttCollection->addCluster( clu );
170 auto vdClusters = FindClusters( dvStripsPerRob[iRob] );
173 mFttCollection->addCluster( clu );
178 LOG_DEBUG <<
"Found " << nClusters <<
" clusters this event" << endm;
183 void StFttClusterMaker::InjectTestData(){
184 mFttCollection->rawHits().clear();
187 hit->setMapping( 1, 1, 1, 23, kFttHorizontal );
188 mFttCollection->addRawHit( hit );
190 hit =
new StFttRawHit( 1, 1, 1, 1, 1, 90, 1, 1, 0 );
191 hit->setMapping( 1, 1, 1, 24, kFttHorizontal );
192 mFttCollection->addRawHit( hit );
194 hit =
new StFttRawHit( 1, 1, 1, 1, 1, 60, 1, 1, 0 );
195 hit->setMapping( 1, 1, 1, 27, kFttHorizontal );
196 mFttCollection->addRawHit( hit );
198 hit =
new StFttRawHit( 1, 1, 1, 1, 1, 95, 1, 1, 0 );
199 hit->setMapping( 1, 1, 1, 25, kFttHorizontal );
200 mFttCollection->addRawHit( hit );
202 hit =
new StFttRawHit( 1, 1, 1, 1, 1, 93, 1, 1, 0 );
203 hit->setMapping( 1, 1, 1, 26, kFttHorizontal );
204 mFttCollection->addRawHit( hit );
206 hit =
new StFttRawHit( 1, 1, 1, 1, 1, 19, 1, 1, 0 );
207 hit->setMapping( 1, 1, 1, 28, kFttHorizontal );
208 mFttCollection->addRawHit( hit );
228 bool StFttClusterMaker::PassTimeCut(
StFttRawHit * hit ){
229 if (mTimeCutMode == kTimeCutModeAcceptAll)
231 else if (mTimeCutMode == kTimeCutModeDB ) {
232 int timeCutMin = INT_MIN;
233 int timeCutMax = INT_MAX;
234 int hitTimeMode = (int)kHitCalibratedTime;
236 mFttDb->getTimeCut(hit, hitTimeMode, timeCutMin, timeCutMax);
237 LOG_DEBUG << TString::Format(
"StFttClusterMaker::PassTimeCut - DB gave hit time mode: %d, time cut min: %d, time cut max: %d", hitTimeMode, timeCutMin, timeCutMax ) << endm;
238 if (hitTimeMode == kHitCalibratedTime) {
239 return (hit->time() >= timeCutMin && hit->time() <= timeCutMax);
240 }
else if ( hitTimeMode == kHitTimebin ) {
241 return (hit->tb() >= timeCutMin && hit->tb() <= timeCutMax);
243 LOG_WARN <<
"StFttClusterMaker::PassTimeCut - Unknown hit time mode from database: " << hitTimeMode << endm;
244 LOG_WARN <<
"Accepting all hits" << endm;
247 }
else if (mTimeCutMode == kTimeCutModeCalibratedTime) {
248 return (hit->time() >= mTimeCutMin && hit->time() <= mTimeCutMax);
249 }
else if (mTimeCutMode == kTimeCutModeTimebin) {
250 return (hit->tb() >= mTimeCutMin && hit->tb() <= mTimeCutMax);
252 LOG_WARN <<
"StFttClusterMaker::PassTimeCut - Unknown time cut mode: " << mTimeCutMode << endm;
253 LOG_WARN <<
"Accepting all hits" << endm;
260 StFttRawHit * StFttClusterMaker::FindMaxAdc( std::vector<StFttRawHit *> hits,
size_t &pos ){
261 auto itMax = std::max_element(hits.begin(),
265 pos = (itMax - hits.begin());
266 if ( itMax == hits.end() )
return nullptr;
270 void StFttClusterMaker::SearchClusterEdges( std::vector< StFttRawHit * > hits,
272 size_t &left,
size_t &right ){
277 auto lastHitLeft = hits[start];
278 auto lastHitRight = hits[start];
280 bool searchRight =
true;
281 bool searchLeft =
true;
283 StFttRawHit *hitLeft =
nullptr, *hitRight =
nullptr;
285 while ( searchRight || searchLeft ){
286 LOG_DEBUG <<
"LEFT: " << left <<
", RIGHT: " << right <<
", start = " << start <<
", size=" << hits.size() << endm;
288 if ( right == hits.size() || right == hits.size() - 1 ){
293 hitRight = hits[right+1];
294 if ( hitRight->adc() > lastHitRight->adc() || hitRight->adc() < GetThresholdFor( hitRight ) ){
297 if ( hitRight->row() != lastHitRight->row() || abs( hitRight->strip() - lastHitRight->strip() ) > 1 ){
303 lastHitRight = hitRight;
312 hitLeft = hits[left-1];
313 if ( hitLeft->adc() > lastHitLeft->adc() || hitLeft->adc() < GetThresholdFor( hitLeft ) ){
316 if ( hitLeft->row() != lastHitLeft->row() || abs( hitLeft->strip() - lastHitLeft->strip() ) > 1 ){
322 lastHitLeft = hitLeft;
330 void StFttClusterMaker::CalculateClusterInfo(
StFttCluster * clu ){
332 clu->setNStrips( clu->rawHits().size() );
339 std::for_each (clu->rawHits().begin(), clu->rawHits().end(), [&](
const StFttRawHit *h) {
340 float x = ( h->strip() * 3.2 - 1.6 );
343 m1Sum += (h->adc() * x);
344 m2Sum += ( h->adc() * x * x );
348 LOG_INFO <<
"m0Sum = " << m0Sum << endm;
349 LOG_INFO <<
"m1Sum = " << m1Sum << endm;
350 LOG_INFO <<
"m2Sum = " << m2Sum << endm;
357 clu->setSumAdc( m0Sum );
358 clu->setX( m1Sum / m0Sum );
359 float var = (m2Sum - m1Sum*m1Sum / m0Sum) / m0Sum;
360 clu->setSigma( sqrt( var ) );
365 std::vector<StFttCluster*> StFttClusterMaker::FindClusters( std::vector< StFttRawHit * > hits ){
366 std::vector<StFttCluster*> clusters;
374 const bool dedup =
false;
378 return a->plane() < b->plane() ||
379 a->quadrant() < b->quadrant() ||
380 a->row() < b->row() ||
381 a->strip() < b->strip() ||
382 a->orientation() < b->orientation();
386 set<StFttRawHit*, decltype(cmp)> s(cmp);
387 unsigned size = hits.size();
388 for(
auto h : hits ) s.insert( h );
389 hits.assign( s.begin(), s.end() );
394 size_t indexA = a->orientation() + StFttDb::nStripOrientations * ( a->strip() + a->row() * StFttDb::maxStripPerRow);
395 size_t indexB = b->orientation() + StFttDb::nStripOrientations * ( b->strip() + b->row() * StFttDb::maxStripPerRow);
396 return indexA < indexB;
400 LOG_INFO <<
"We have " << hits.size() <<
" hits after removing duplicates" << endm;
405 size_t anchor = hits.size()+1;
406 auto maxAdcHit = FindMaxAdc( hits, anchor );
413 LOG_DEBUG <<
"CLUSTER FIND START WITH HITS:" << endm;
415 for (
auto *h : hits ){
416 LOG_DEBUG <<
"[" << i <<
"]" << *h;
422 clu->setPlane ( maxAdcHit->plane ( ) );
423 clu->setQuadrant ( maxAdcHit->quadrant ( ) );
424 clu->setRow ( maxAdcHit->row ( ) );
425 clu->setOrientation ( maxAdcHit->orientation ( ) );
428 size_t left = anchor, right = anchor;
429 SearchClusterEdges( hits, anchor, left, right);
431 LOG_DEBUG <<
"Cluster points ( " << left <<
", " << anchor <<
", " << right <<
" )" << endm;
435 for (
size_t i = left; i < right + 1; i++ ){
436 clu->addRawHit( hits[i] );
440 CalculateClusterInfo( clu );
443 LOG_INFO << *clu << endm;;
445 clusters.push_back( clu );
448 hits.erase( hits.begin() + left, hits.begin() + right + 1 );
449 maxAdcHit = FindMaxAdc( hits, anchor );
456 void StFttClusterMaker::ApplyHardwareMap(){
457 for (
StFttRawHit* rawHit : mFttCollection->rawHits() ) {
458 mFttDb->hardwareMap( rawHit );