30 #include <TMatrixFfwd.h>
32 #include <TMatrixTUtils.h>
48 template<
class T>
inline constexpr
T square(
const T&
x ) {
return x*
x; }
50 using iphiz = std::pair<unsigned short, unsigned short>;
51 using ihit = std::pair<unsigned short, iphiz>;
52 using assoc = std::pair<uint32_t, TrkrDefs::hitkey> ;
59 unsigned int layer = 0;
61 unsigned int sector = 0;
65 unsigned short phioffset = 0;
66 unsigned short zbins = 0;
67 unsigned short zoffset = 0;
70 std::vector<assoc> association_vector;
71 std::vector<TrkrCluster*> cluster_vector;
74 pthread_mutex_t mythreadlock;
76 void remove_hit(
double adc,
int phibin,
int zbin, std::multimap<unsigned short, ihit> &all_hit_map, std::vector<std::vector<unsigned short>> &adcval)
78 typedef std::multimap<unsigned short, ihit>::iterator hit_iterator;
79 std::pair<hit_iterator, hit_iterator> iterpair = all_hit_map.equal_range(adc);
80 hit_iterator
it = iterpair.first;
81 for (; it != iterpair.second; ++
it) {
82 if (it->second.second.first == phibin && it->second.second.second == zbin) {
83 all_hit_map.erase(it);
87 adcval[phibin][zbin] = 0;
90 void remove_hits(std::vector<ihit> &ihit_list, std::multimap<unsigned short, ihit> &all_hit_map,std::vector<std::vector<unsigned short>> &adcval)
92 for(
auto iter = ihit_list.begin(); iter != ihit_list.end();++iter){
93 unsigned short adc = iter->first;
94 unsigned short phibin = iter->second.first;
95 unsigned short zbin = iter->second.second;
96 remove_hit(adc,phibin,zbin,all_hit_map,adcval);
100 void get_cluster(
int phibin,
int zbin,
const std::vector<std::vector<unsigned short>> &adcval, std::vector<ihit> &ihit_list)
103 const int& iphi = phibin;
104 const int& iz = zbin;
105 iphiz iCoord(std::make_pair(iphi,iz));
106 ihit thisHit(adcval[iphi][iz],iCoord);
107 ihit_list.push_back(thisHit);
110 void calc_cluster_parameter(std::vector<ihit> &ihit_list, thread_data& my_data)
115 double phi_sum = 0.0;
116 double adc_sum = 0.0;
118 double phi2_sum = 0.0;
120 double radius = my_data.layergeom->get_radius();
123 int phibinlo = 666666;
127 std::vector<TrkrDefs::hitkey> hitkeyvec;
128 for(
auto iter = ihit_list.begin(); iter != ihit_list.end();++iter){
129 double adc = iter->first;
131 if (adc <= 0)
continue;
133 int iphi = iter->second.first + my_data.phioffset;
134 int iz = iter->second.second + my_data.zoffset;
135 if(iphi > phibinhi) phibinhi = iphi;
136 if(iphi < phibinlo) phibinlo = iphi;
137 if(iz > zbinhi) zbinhi = iz;
138 if(iz < zbinlo) zbinlo = iz;
141 double phi_center = my_data.layergeom->get_phicenter(iphi);
142 phi_sum += phi_center * adc;
143 phi2_sum +=
square(phi_center)*adc;
146 double z = my_data.layergeom->get_zcenter(iz);
155 hitkeyvec.push_back(hitkey);
160 double clusphi = phi_sum / adc_sum;
161 double clusz = z_sum / adc_sum;
162 const double clusx = radius * std::cos(clusphi);
163 const double clusy = radius * std::sin(clusphi);
165 const double phi_cov = phi2_sum/adc_sum -
square(clusphi);
166 const double z_cov = z2_sum/adc_sum -
square(clusz);
170 const double phi_err_square = (phibinhi == phibinlo) ?
171 square(radius*my_data.layergeom->get_phistep())/12:
172 square(radius)*phi_cov/(adc_sum*0.14);
174 const double z_err_square = (zbinhi == zbinlo) ?
175 square(my_data.layergeom->get_zstep())/12:
176 z_cov/(adc_sum*0.14);
187 clusz -= (clusz<0) ? my_data.par0_neg:my_data.par0_pos;
212 clus->setSubSurfKey(subsurfkey);
214 Acts::Vector3 center = surface->center(my_data.tGeometry->geometry().getGeoContext())
218 const Acts::Vector3 normal = surface->normal(my_data.tGeometry->geometry().getGeoContext());
219 const double clusRadius = std::sqrt(
square(clusx) +
square(clusy));
220 const double rClusPhi = clusRadius * clusphi;
221 const double surfRadius = sqrt(center(0)*center(0) + center(1)*center(1));
222 const double surfPhiCenter = atan2(center[1], center[0]);
223 const double surfRphiCenter = surfPhiCenter * surfRadius;
224 const double surfZCenter = center[2];
225 auto local = surface->globalToLocal(my_data.tGeometry->geometry().getGeoContext(),
238 localPos(0) = rClusPhi - surfRphiCenter;
239 localPos(1) = clusz - surfZCenter;
242 clus->setLocalX(localPos(0));
243 clus->setLocalY(localPos(1));
244 clus->setActsLocalError(0,0, phi_err_square);
245 clus->setActsLocalError(1,0, 0);
246 clus->setActsLocalError(0,1, 0);
247 clus->setActsLocalError(1,1, z_err_square);
249 my_data.cluster_vector.push_back(clus);
254 if( my_data.do_assoc )
257 uint32_t
index = my_data.cluster_vector.size()-1;
258 for (
unsigned int i = 0;
i < hitkeyvec.size();
i++){
259 my_data.association_vector.push_back(std::make_pair(index, hitkeyvec[
i]));
264 void *ProcessSector(
void *threadarg) {
266 auto my_data = (
struct thread_data *) threadarg;
268 const auto&
pedestal = my_data->pedestal;
269 const auto&
phibins = my_data->phibins;
270 const auto& phioffset = my_data->phioffset;
271 const auto& zbins = my_data->zbins ;
272 const auto& zoffset = my_data->zoffset ;
278 std::vector<std::vector<unsigned short>> adcval(
phibins, std::vector<unsigned short>(zbins, 0));
279 std::multimap<unsigned short, ihit> all_hit_map;
280 std::vector<ihit> hit_vect;
283 hitr != hitrangei.second;
288 float_t fadc = (hitr->second->getAdc()) -
pedestal;
291 unsigned short adc = 0;
293 adc = (
unsigned short) fadc;
296 if(phibin >=
phibins)
continue;
298 if(zbin >= zbins)
continue;
301 iphiz iCoord(std::make_pair(phibin,zbin));
302 ihit thisHit(adc,iCoord);
304 all_hit_map.insert(std::make_pair(adc, thisHit));
307 adcval[phibin][zbin] = (
unsigned short) adc;
311 while(all_hit_map.size()>0){
313 auto iter = all_hit_map.rbegin();
314 if(iter == all_hit_map.rend()){
317 ihit hiHit = iter->second;
318 int iphi = hiHit.second.first;
319 int iz = hiHit.second.second;
324 std::vector<ihit> ihit_list;
325 get_cluster(iphi, iz, adcval, ihit_list);
331 calc_cluster_parameter(ihit_list, *my_data );
332 remove_hits(ihit_list,all_hit_map, adcval);
334 pthread_exit(
nullptr);
344 bool reject_it =
false;
348 int PhiBinsSector = PhiBins/12;
351 double PhiBinSize = 2.0* radius * M_PI / (
double) PhiBins;
354 int sector_lo = sector * PhiBinsSector;
355 int sector_hi = sector_lo + PhiBinsSector - 1;
359 if(phibin < sector_lo + sector_fiducial_bins || phibin > sector_hi - sector_fiducial_bins)
382 std::cout <<
PHWHERE <<
"DST Node missing, doing nothing." << std::endl;
387 auto trkrclusters = findNode::getClass<TrkrClusterContainer>(dstNode,
"TRKR_CLUSTER");
396 dstNode->addNode(DetNode);
402 DetNode->
addNode(TrkrClusterContainerNode);
405 auto clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode,
"TRKR_CLUSTERHITASSOC");
406 if (!clusterhitassoc)
414 dstNode->addNode(DetNode);
430 std::cout <<
"TpcSimpleClusterizer::Process_Event" << std::endl;
436 std::cout <<
PHWHERE <<
"DST Node missing, doing nothing." << std::endl;
441 m_hits = findNode::getClass<TrkrHitSetContainer>(topNode,
"TRKR_HITSET");
444 std::cout <<
PHWHERE <<
"ERROR: Can't find node TRKR_HITSET" << std::endl;
449 m_clusterlist = findNode::getClass<TrkrClusterContainer>(topNode,
"TRKR_CLUSTER");
452 std::cout <<
PHWHERE <<
" ERROR: Can't find TRKR_CLUSTER." << std::endl;
457 m_clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode,
"TRKR_CLUSTERHITASSOC");
460 std::cout <<
PHWHERE <<
" ERROR: Can't find TRKR_CLUSTERHITASSOC" << std::endl;
465 findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode,
"CYLINDERCELLGEOM_SVTX");
468 std::cout <<
PHWHERE <<
"ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl;
472 m_tGeometry = findNode::getClass<ActsGeometry>(topNode,
477 <<
"ActsGeometry not found on node tree. Exiting"
487 const int num_hitsets =
std::distance(hitsetrange.first,hitsetrange.second);
497 std::vector<thread_pair_t> threads;
498 threads.reserve( num_hitsets );
501 pthread_attr_init(&attr);
502 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
504 if (pthread_mutex_init(&mythreadlock,
nullptr) != 0)
506 printf(
"\n mutex init failed\n");
511 hitsetitr != hitsetrange.second;
521 thread_pair_t& thread_pair = threads.emplace_back();
523 thread_pair.data.layergeom = layergeom;
524 thread_pair.data.hitset = hitset;
525 thread_pair.data.layer =
layer;
526 thread_pair.data.pedestal =
pedestal;
527 thread_pair.data.sector = sector;
528 thread_pair.data.side = side;
531 thread_pair.data.par0_neg =
par0_neg;
532 thread_pair.data.par0_pos =
par0_pos;
534 unsigned short NPhiBins = (
unsigned short) layergeom->
get_phibins();
535 unsigned short NPhiBinsSector = NPhiBins/12;
536 unsigned short NZBins = (
unsigned short)layergeom->
get_zbins();
537 unsigned short NZBinsSide = NZBins/2;
538 unsigned short NZBinsMin = 0;
539 unsigned short PhiOffset = NPhiBinsSector * sector;
545 NZBinsMin = NZBins / 2;
548 unsigned short ZOffset = NZBinsMin;
550 thread_pair.data.phibins = NPhiBinsSector;
551 thread_pair.data.phioffset = PhiOffset;
552 thread_pair.data.zbins = NZBinsSide;
553 thread_pair.data.zoffset = ZOffset ;
555 int rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (
void *)&thread_pair.data);
557 std::cout <<
"Error:unable to create thread," << rc << std::endl;
561 pthread_attr_destroy(&attr);
564 for(
const auto& thread_pair:threads )
566 int rc2 = pthread_join(thread_pair.thread,
nullptr);
568 { std::cout <<
"Error:unable to join," << rc2 << std::endl; }
571 const auto&
data( thread_pair.data );
575 for( uint32_t index = 0; index <
data.cluster_vector.size(); ++
index )
581 auto cluster =
data.cluster_vector[
index];
588 for(
const auto& [index,hkey]:thread_pair.data.association_vector)
600 std::cout <<
"TPC Clusterizer found " <<
m_clusterlist->
size() <<
" Clusters " << std::endl;