3 #pragma GCC diagnostic push
4 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
5 #pragma GCC diagnostic ignored "-Wunused-parameter"
6 #pragma GCC diagnostic ignored "-Wshadow"
7 #include <torch/script.h>
8 #pragma GCC diagnostic pop
50 #include <TMatrixFfwd.h>
52 #include <TMatrixTUtils.h>
69 template<
class T>
inline constexpr
T square(
const T&
x ) {
return x*
x; }
71 using assoc = std::pair<TrkrDefs::cluskey, TrkrDefs::hitkey>;
75 unsigned short iphi = 0;
76 unsigned short it = 0;
77 unsigned short adc = 0;
78 unsigned short edge = 0;
81 using vec_dVerbose = std::vector<std::vector<std::pair<int,int>>>;
84 bool gen_hits =
false;
87 torch::jit::script::Module module_pos;
95 unsigned int layer = 0;
97 unsigned int sector = 0;
99 float drift_velocity = 0;
100 unsigned short pads_per_sector = 0;
103 float seed_threshold = 0;
104 float edge_threshold = 0;
105 float min_err_squared = 0;
106 float min_clus_size = 0;
107 float min_adc_sum = 0;
108 bool do_assoc =
true;
109 bool do_wedge_emulation =
true;
110 bool do_singles =
true;
111 bool do_split =
true;
113 unsigned short phioffset = 0;
114 unsigned short tbins = 0;
115 unsigned short toffset = 0;
116 unsigned short maxHalfSizeT = 0;
117 unsigned short maxHalfSizePhi = 0;
118 double m_tdriftmax = 0;
119 double sampa_tbias = 0;
120 std::vector<assoc> association_vector;
121 std::vector<TrkrCluster*> cluster_vector;
122 std::vector<TrainingHits*> v_hits;
124 bool fillClusHitsVerbose =
false;
125 vec_dVerbose phivec_ClusHitsVerbose ;
126 vec_dVerbose zvec_ClusHitsVerbose ;
129 pthread_mutex_t mythreadlock;
131 void remove_hit(
double adc,
int phibin,
int tbin,
int edge, std::multimap<unsigned short, ihit> &all_hit_map, std::vector<std::vector<unsigned short>> &adcval)
133 typedef std::multimap<unsigned short, ihit>::iterator hit_iterator;
134 std::pair<hit_iterator, hit_iterator> iterpair = all_hit_map.equal_range(adc);
135 hit_iterator
it = iterpair.first;
136 for (; it != iterpair.second; ++
it) {
137 if (it->second.iphi == phibin && it->second.it == tbin) {
138 all_hit_map.erase(it);
143 adcval[phibin][tbin] = USHRT_MAX;
145 adcval[phibin][tbin] = 0;
148 void remove_hits(std::vector<ihit> &ihit_list, std::multimap<unsigned short, ihit> &all_hit_map,std::vector<std::vector<unsigned short>> &adcval)
150 for(
auto iter = ihit_list.begin(); iter != ihit_list.end();++iter){
151 unsigned short adc = iter->adc;
152 unsigned short phibin = iter->iphi;
153 unsigned short tbin = iter->it;
154 unsigned short edge = iter->edge;
155 remove_hit(adc,phibin,tbin,edge,all_hit_map,adcval);
159 void find_t_range(
int phibin,
int tbin,
const thread_data& my_data,
const std::vector<std::vector<unsigned short>> &adcval,
int& tdown,
int& tup,
int &touch,
int &edge){
161 const int FitRangeT= (int) my_data.maxHalfSizeT;
162 const int NTBinsMax = (
int) my_data.tbins;
165 for(
int it=0; it< FitRangeT; it++){
168 if(ct <= 0 || ct >= NTBinsMax){
174 if(adcval[phibin][ct] <= 0) {
177 if(adcval[phibin][ct] == USHRT_MAX) {
181 if(my_data.do_split){
184 if(adcval[phibin][ct]+adcval[phibin][ct+1] <
185 adcval[phibin][ct+2]+adcval[phibin][ct+3]){
194 for(
int it=0; it< FitRangeT; it++){
196 if(ct <= 0 || ct >= NTBinsMax){
201 if(adcval[phibin][ct] <= 0) {
204 if(adcval[phibin][ct] == USHRT_MAX) {
208 if(my_data.do_split){
210 if(adcval[phibin][ct]+adcval[phibin][ct-1] <
211 adcval[phibin][ct-2]+adcval[phibin][ct-3]){
223 void find_phi_range(
int phibin,
int tbin,
const thread_data& my_data,
const std::vector<std::vector<unsigned short>> &adcval,
int& phidown,
int& phiup,
int &touch,
int &edge)
226 int FitRangePHI = (int) my_data.maxHalfSizePhi;
227 int NPhiBinsMax = (
int) my_data.phibins;
230 for(
int iphi=0; iphi< FitRangePHI; iphi++){
231 int cphi = phibin + iphi;
232 if(cphi < 0 || cphi >= NPhiBinsMax){
239 if(adcval[cphi][tbin] <= 0) {
243 if(adcval[cphi][tbin] == USHRT_MAX) {
247 if(my_data.do_split){
248 if(cphi<NPhiBinsMax-4){
249 if(adcval[cphi][tbin]+adcval[cphi+1][tbin] <
250 adcval[cphi+2][tbin]+adcval[cphi+3][tbin]){
260 for(
int iphi=0; iphi< FitRangePHI; iphi++){
261 int cphi = phibin - iphi;
262 if(cphi < 0 || cphi >= NPhiBinsMax){
268 if(adcval[cphi][tbin] <= 0) {
272 if(adcval[cphi][tbin] == USHRT_MAX) {
276 if(my_data.do_split){
278 if(adcval[cphi][tbin]+adcval[cphi-1][tbin] <
279 adcval[cphi-2][tbin]+adcval[cphi-3][tbin]){
291 void get_cluster(
int phibin,
int tbin,
const thread_data& my_data,
const std::vector<std::vector<unsigned short>> &adcval, std::vector<ihit> &ihit_list,
int &touch,
int &edge)
297 find_t_range(phibin, tbin, my_data, adcval, tdown, tup, touch, edge);
300 for(
int it=tbin - tdown ; it<= tbin + tup; it++){
303 find_phi_range(phibin, it, my_data, adcval, phidown, phiup, touch, edge);
304 for (
int iphi = phibin - phidown; iphi <= (phibin + phiup); iphi++){
305 if(adcval[iphi][it]>0 && adcval[iphi][it]!=USHRT_MAX){
309 hit.adc = adcval[iphi][
it];
311 if((iphi == (phibin - phidown))||
312 (iphi == (phibin + phiup))){
316 ihit_list.push_back(hit);
323 void calc_cluster_parameter(
const int iphi_center,
const int it_center,
324 const std::vector<ihit> &ihit_list, thread_data& my_data,
int ntouch,
int nedge )
335 double adc_sum = 0.0;
339 double iphi_sum = 0.0;
340 double iphi2_sum = 0.0;
342 double radius = my_data.layergeom->get_radius();
345 int phibinlo = 666666;
348 int clus_size = ihit_list.size();
350 if(clus_size <= my_data.min_clus_size){
360 training_hits->
radius = radius;
361 training_hits->
phi = my_data.layergeom->get_phicenter(iphi_center+my_data.phioffset);
362 double center_t = my_data.layergeom->get_zcenter(it_center+my_data.toffset) + my_data.sampa_tbias;
363 training_hits->
z = (my_data.m_tdriftmax - center_t) * my_data.tGeometry->get_drift_velocity();
364 if(my_data.side == 0)
365 training_hits->
z = -training_hits->
z;
366 training_hits->
phistep = my_data.layergeom->get_phistep();
367 training_hits->
zstep = my_data.layergeom->get_zstep() * my_data.tGeometry->get_drift_velocity();
368 training_hits->
layer = my_data.layer;
369 training_hits->
ntouch = ntouch;
370 training_hits->
nedge = nedge;
371 training_hits->
v_adc.fill(0);
375 std::vector<TrkrDefs::hitkey> hitkeyvec;
378 std::map<int,unsigned int> m_phi {};
379 std::map<int,unsigned int> m_z {};
381 for(
auto iter = ihit_list.begin(); iter != ihit_list.end();++iter){
382 double adc = iter->adc;
384 if (adc <= 0)
continue;
387 int iphi = iter->iphi + my_data.phioffset;
388 int it = iter->it + my_data.toffset;
389 if(iphi > phibinhi) phibinhi = iphi;
390 if(iphi < phibinlo) phibinlo = iphi;
391 if(it > tbinhi) tbinhi =
it;
392 if(it < tbinlo) tbinlo =
it;
400 iphi_sum += iphi * adc;
401 iphi2_sum +=
square(iphi)*adc;
404 double t = my_data.layergeom->get_zcenter(it);
410 if (my_data.fillClusHitsVerbose) {
411 auto pnew = m_phi.try_emplace(iphi,adc);
412 if (!pnew.second) pnew.first->second += adc;
414 pnew = m_z.try_emplace(it,adc);
415 if (!pnew.second) pnew.first->second += adc;
421 hitkeyvec.push_back(hitkey);
424 if(gen_hits && training_hits)
426 int iphi_diff = iter->iphi - iphi_center;
427 int it_diff = iter->it - it_center;
428 if( std::abs(iphi_diff) <= nd && std::abs(it_diff) <= nd)
429 training_hits->
v_adc[(iphi_diff+nd)*(2*nd+1)+(it_diff+nd)] = adc;
433 if (adc_sum < my_data.min_adc_sum){
438 double clusiphi = iphi_sum / adc_sum;
439 double clusphi = my_data.layergeom->get_phi(clusiphi);
441 float clusx = radius * cos(clusphi);
442 float clusy = radius * sin(clusphi);
443 double clust = t_sum / adc_sum;
445 double zdriftlength = clust * my_data.tGeometry->get_drift_velocity();
447 double clusz = my_data.m_tdriftmax * my_data.tGeometry->get_drift_velocity() - zdriftlength;
448 if(my_data.side == 0)
451 const double phi_cov = (iphi2_sum/adc_sum -
square(clusiphi))* pow(my_data.layergeom->get_phistep(),2);
452 const double t_cov = t2_sum/adc_sum -
square(clust);
473 const double phi_err_square = (phibinhi == phibinlo) ?
474 square(radius*my_data.layergeom->get_phistep())/12:
475 square(radius)*phi_cov/(adc_sum*0.14);
477 const double t_err_square = (tbinhi == tbinlo) ?
478 square(my_data.layergeom->get_zstep())/12:
479 t_cov/(adc_sum*0.14);
481 char tsize = tbinhi - tbinlo + 1;
482 char phisize = phibinhi - phibinlo + 1;
492 clust = clust + my_data.sampa_tbias;
497 Acts::Vector3 local = surface->transform(my_data.tGeometry->geometry().getGeoContext()).inverse() * global;
503 bool b_made_cluster {
false };
508 if(sqrt(phi_err_square) > my_data.min_err_squared){
513 clus->setMaxAdc(max_adc);
514 clus->setEdge(nedge);
515 clus->setPhiSize(phisize);
516 clus->setZSize(tsize);
517 clus->setSubSurfKey(subsurfkey);
518 clus->setOverlap(ntouch);
519 clus->setLocalX(local(0));
520 clus->setLocalY(clust);
521 clus->setPhiError(sqrt(phi_err_square));
522 clus->setZError(sqrt(t_err_square * pow(my_data.tGeometry->get_drift_velocity(),2)));
523 my_data.cluster_vector.push_back(clus);
524 b_made_cluster =
true;
528 if(use_nn && clus_base && training_hits)
533 std::vector<torch::jit::IValue> inputs;
534 inputs.emplace_back(torch::stack({
535 torch::from_blob(std::vector<float>(training_hits->
v_adc.begin(), training_hits->
v_adc.end()).
data(), {1, 2*nd+1, 2*nd+1}, torch::kFloat32),
536 torch::full({1, 2*nd+1, 2*nd+1}, std::clamp((training_hits->
layer - 7) / 16, 0, 2), torch::kFloat32),
537 torch::full({1, 2*nd+1, 2*nd+1}, training_hits->
z / radius, torch::kFloat32)
541 at::Tensor ten_pos = module_pos.forward(inputs).toTensor();
542 float nn_phi = training_hits->
phi + std::clamp(ten_pos[0][0][0].item<float>(), -(
float)nd, (
float)nd) * training_hits->
phistep;
543 float nn_z = training_hits->
z + std::clamp(ten_pos[0][1][0].item<float>(), -(
float)nd, (
float)nd) * training_hits->
zstep;
544 float nn_x = radius * cos(nn_phi);
545 float nn_y = radius * sin(nn_phi);
548 Acts::Vector3 nn_local = surface->transform(my_data.tGeometry->geometry().geoContext).inverse() * nn_global;
550 float nn_t = my_data.m_tdriftmax - fabs(nn_z) / my_data.tGeometry->get_drift_velocity();
554 catch(
const c10::Error &
e)
556 std::cout <<
PHWHERE <<
"Error: Failed to execute NN modules" << std::endl;
560 if (my_data.fillClusHitsVerbose && b_made_cluster) {
562 my_data.phivec_ClusHitsVerbose .push_back( std::vector<std::pair<int,int>> {} );
563 my_data.zvec_ClusHitsVerbose .push_back( std::vector<std::pair<int,int>> {} );
565 auto& vphi = my_data.phivec_ClusHitsVerbose .back();
566 auto&
vz = my_data.zvec_ClusHitsVerbose .back();
568 for (
auto&
entry : m_phi ) vphi.push_back({
entry.first,
entry.second});
577 uint32_t
index = my_data.cluster_vector.size()-1;
578 for (
unsigned int i = 0;
i < hitkeyvec.size();
i++){
579 my_data.association_vector.emplace_back(index, hitkeyvec[
i]);
581 if(gen_hits && training_hits)
585 if(gen_hits && training_hits)
586 my_data.v_hits.emplace_back(training_hits);
590 void ProcessSectorData(thread_data* my_data) {
592 const auto&
pedestal = my_data->pedestal;
593 const auto&
phibins = my_data->phibins;
594 const auto& phioffset = my_data->phioffset;
595 const auto& tbins = my_data->tbins ;
596 const auto& toffset = my_data->toffset ;
597 const auto&
layer = my_data->layer ;
600 std::vector<std::vector<unsigned short>> adcval(
phibins, std::vector<unsigned short>(tbins, 0));
601 std::multimap<unsigned short, ihit> all_hit_map;
602 std::vector<ihit> hit_vect;
606 if(my_data->do_wedge_emulation){
608 int etacut = (tbins / 2.) - ((50 + (
layer - 7)) / 105.5) * (tbins / 2.);
613 int etacut = (tbins / 2.) - ((65 + ((40.5 / 26) * (
layer - 22))) / 105.5) * (tbins / 2.);
619 if( my_data->hitset!=
nullptr){
624 hitr != hitrangei.second;
645 if(tbinorg>tbinmax||tbinorg<tbinmin)
647 float_t fadc = (hitr->second->getAdc()) -
pedestal;
648 unsigned short adc = 0;
649 if(fadc>0) adc = (
unsigned short) fadc;
650 if(phibin >=
phibins)
continue;
651 if(tbin >= tbins)
continue;
654 if(adc>(my_data->seed_threshold)){
657 thisHit.iphi = phibin;
661 all_hit_map.insert(std::make_pair(adc, thisHit));
663 if(adc>my_data->edge_threshold){
664 adcval[phibin][tbin] = (
unsigned short) adc;
668 }
else if( my_data->rawhitset!=
nullptr){
681 for(
unsigned int nt = 0;nt<hitset->
m_tpchits[
nphi].size();nt++){
694 all_hit_map.insert(std::make_pair(val, thisHit));
696 adcval[
nphi][pindex++]=val;
707 all_hit_map.insert(std::make_pair(val, thisHit));
709 adcval[
nphi][pindex++]=val;
717 if(my_data->do_singles){
718 for(
auto ahit:all_hit_map){
719 ihit hiHit = ahit.second;
720 int iphi = hiHit.iphi;
722 unsigned short edge = hiHit.edge;
723 double adc = hiHit.adc;
725 if(adcval[iphi][it-1]==0&&
726 adcval[iphi][it+1]==0){
727 remove_hit(adc, iphi, it, edge, all_hit_map, adcval);
735 while(all_hit_map.size()>0){
737 auto iter = all_hit_map.rbegin();
738 if(iter == all_hit_map.rend()){
741 ihit hiHit = iter->second;
742 int iphi = hiHit.iphi;
747 std::vector<ihit> ihit_list;
750 get_cluster(iphi, it, *my_data, adcval, ihit_list, ntouch, nedge );
756 calc_cluster_parameter(iphi, it, ihit_list, *my_data, ntouch, nedge );
757 remove_hits(ihit_list,all_hit_map, adcval);
773 void *ProcessSector(
void *threadarg) {
775 auto my_data =
static_cast<thread_data*
>(threadarg);
776 ProcessSectorData(my_data);
777 pthread_exit(
nullptr);
788 bool reject_it =
false;
792 int PhiBinsSector = PhiBins/12;
795 double PhiBinSize = 2.0* radius * M_PI / (
double) PhiBins;
798 int sector_lo = sector * PhiBinsSector;
799 int sector_hi = sector_lo + PhiBinsSector - 1;
803 if(phibin < sector_lo + sector_fiducial_bins || phibin > sector_hi - sector_fiducial_bins)
827 std::cout <<
PHWHERE <<
"DST Node missing, doing nothing." << std::endl;
832 auto trkrclusters = findNode::getClass<TrkrClusterContainer>(dstNode,
"TRKR_CLUSTER");
841 dstNode->addNode(DetNode);
847 DetNode->
addNode(TrkrClusterContainerNode);
850 auto clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode,
"TRKR_CLUSTERHITASSOC");
851 if (!clusterhitassoc)
859 dstNode->addNode(DetNode);
867 auto training_container = findNode::getClass<TrainingHitsContainer>(dstNode,
"TRAINING_HITSET");
868 if (!training_container)
876 dstNode->addNode(DetNode);
882 DetNode->
addNode(TrainingHitsContainerNode);
889 const char *offline_main = std::getenv(
"OFFLINE_MAIN");
895 module_pos = torch::jit::load(net_model);
896 std::cout <<
PHWHERE <<
"Load NN module: " << net_model << std::endl;
898 catch(
const c10::Error &
e)
900 std::cout <<
PHWHERE <<
"Error: Cannot load module " << net_model << std::endl;
906 std::cout <<
PHWHERE <<
"Use traditional clustering" << std::endl;
911 mClusHitsVerbose = findNode::getClass<ClusHitsVerbosev1>(topNode,
"Trkr_SvtxClusHitsVerbose");
919 dstNode->addNode(DetNode);
923 DetNode->addNode(newNode);
940 std::cout <<
"TpcClusterizer::Process_Event" << std::endl;
946 std::cout <<
PHWHERE <<
"DST Node missing, doing nothing." << std::endl;
951 m_hits = findNode::getClass<TrkrHitSetContainer>(topNode,
"TRKR_HITSET");
954 std::cout <<
PHWHERE <<
"ERROR: Can't find node TRKR_HITSET" << std::endl;
959 m_rawhits = findNode::getClass<RawHitSetContainer>(topNode,
"TRKR_RAWHITSET");
962 std::cout <<
PHWHERE <<
"ERROR: Can't find node TRKR_HITSET" << std::endl;
968 m_clusterlist = findNode::getClass<TrkrClusterContainer>(topNode,
"TRKR_CLUSTER");
971 std::cout <<
PHWHERE <<
" ERROR: Can't find TRKR_CLUSTER." << std::endl;
976 m_clusterhitassoc = findNode::getClass<TrkrClusterHitAssoc>(topNode,
"TRKR_CLUSTERHITASSOC");
979 std::cout <<
PHWHERE <<
" ERROR: Can't find TRKR_CLUSTERHITASSOC" << std::endl;
984 m_training = findNode::getClass<TrainingHitsContainer>(topNode,
"TRAINING_HITSET");
987 std::cout <<
PHWHERE <<
" ERROR: Can't find TRAINING_HITSET." << std::endl;
992 findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode,
"CYLINDERCELLGEOM_SVTX");
995 std::cout <<
PHWHERE <<
"ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl;
999 m_tGeometry = findNode::getClass<ActsGeometry>(topNode,
1004 <<
"ActsGeometry not found on node tree. Exiting"
1014 int num_hitsets = 0;
1018 num_hitsets =
std::distance(hitsetrange.first,hitsetrange.second);
1021 num_hitsets =
std::distance(rawhitsetrange.first,rawhitsetrange.second);
1025 struct thread_pair_t
1032 std::vector<thread_pair_t> threads;
1033 threads.reserve( num_hitsets );
1035 pthread_attr_t attr;
1036 pthread_attr_init(&attr);
1037 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1039 if (pthread_mutex_init(&mythreadlock,
nullptr) != 0)
1041 printf(
"\n mutex init failed\n");
1048 hitsetitr != hitsetrange.second;
1059 thread_pair_t& thread_pair = threads.emplace_back();
1062 thread_pair.data.layergeom = layergeom;
1063 thread_pair.data.hitset = hitset;
1064 thread_pair.data.rawhitset =
nullptr;
1065 thread_pair.data.layer =
layer;
1066 thread_pair.data.pedestal =
pedestal;
1069 thread_pair.data.sector = sector;
1070 thread_pair.data.side = side;
1078 thread_pair.data.verbosity =
Verbosity();
1079 thread_pair.data.do_split =
do_split;
1083 unsigned short NPhiBins = (
unsigned short) layergeom->
get_phibins();
1084 unsigned short NPhiBinsSector = NPhiBins/12;
1085 unsigned short NTBins = (
unsigned short)layergeom->
get_zbins();
1086 unsigned short NTBinsSide = NTBins;
1087 unsigned short NTBinsMin = 0;
1088 unsigned short PhiOffset = NPhiBinsSector * sector;
1089 unsigned short TOffset = NTBinsMin;
1094 thread_pair.data.phibins = NPhiBinsSector;
1095 thread_pair.data.phioffset = PhiOffset;
1096 thread_pair.data.tbins = NTBinsSide;
1097 thread_pair.data.toffset = TOffset ;
1099 thread_pair.data.radius = layergeom->
get_radius();
1101 thread_pair.data.pads_per_sector = 0;
1102 thread_pair.data.phistep = 0;
1104 rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (
void *)&thread_pair.data);
1107 std::cout <<
"Error:unable to create thread," << rc << std::endl;
1110 int rc2 = pthread_join(thread_pair.thread,
nullptr);
1112 { std::cout <<
"Error:unable to join," << rc2 << std::endl; }
1115 const auto&
data( thread_pair.data );
1119 for( uint32_t index = 0; index <
data.cluster_vector.size(); ++
index )
1125 auto cluster =
data.cluster_vector[
index];
1131 for (
auto& hit :
data.phivec_ClusHitsVerbose[index]) {
1134 for (
auto& hit :
data.zvec_ClusHitsVerbose[index]) {
1142 for(
const auto& [index,hkey]:thread_pair.data.association_vector)
1156 hitsetitr != rawhitsetrange.second;
1169 thread_pair_t& thread_pair = threads.emplace_back();
1171 thread_pair.data.layergeom = layergeom;
1172 thread_pair.data.hitset =
nullptr;
1173 thread_pair.data.rawhitset =
dynamic_cast<RawHitSetv1 *
>(hitset);
1174 thread_pair.data.layer =
layer;
1175 thread_pair.data.pedestal =
pedestal;
1176 thread_pair.data.sector = sector;
1177 thread_pair.data.side = side;
1184 thread_pair.data.verbosity =
Verbosity();
1186 unsigned short NPhiBins = (
unsigned short) layergeom->
get_phibins();
1187 unsigned short NPhiBinsSector = NPhiBins/12;
1188 unsigned short NTBins = (
unsigned short)layergeom->
get_zbins();
1189 unsigned short NTBinsSide = NTBins;
1190 unsigned short NTBinsMin = 0;
1191 unsigned short PhiOffset = NPhiBinsSector * sector;
1192 unsigned short TOffset = NTBinsMin;
1197 thread_pair.data.phibins = NPhiBinsSector;
1198 thread_pair.data.phioffset = PhiOffset;
1199 thread_pair.data.tbins = NTBinsSide;
1200 thread_pair.data.toffset = TOffset ;
1227 rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (
void *)&thread_pair.data);
1232 std::cout <<
"Error:unable to create thread," << rc << std::endl;
1236 int rc2 = pthread_join(thread_pair.thread,
nullptr);
1238 { std::cout <<
"Error:unable to join," << rc2 << std::endl; }
1241 const auto&
data( thread_pair.data );
1245 for( uint32_t index = 0; index <
data.cluster_vector.size(); ++
index )
1251 auto cluster =
data.cluster_vector[
index];
1258 for(
const auto& [index,hkey]:thread_pair.data.association_vector)
1272 pthread_attr_destroy(&attr);
1276 for(
const auto& thread_pair:threads )
1278 int rc2 = pthread_join(thread_pair.thread,
nullptr);
1280 { std::cout <<
"Error:unable to join," << rc2 << std::endl; }
1283 const auto&
data( thread_pair.data );
1287 for( uint32_t index = 0; index <
data.cluster_vector.size(); ++
index )
1293 auto cluster =
data.cluster_vector[
index];
1300 for (
auto& hit :
data.phivec_ClusHitsVerbose[index]) {
1303 for (
auto& hit :
data.zvec_ClusHitsVerbose[index]) {
1312 for(
const auto& [index,hkey]:thread_pair.data.association_vector)
1321 for(
auto hiter = thread_pair.data.v_hits.begin(); hiter != thread_pair.data.v_hits.end(); hiter++)
1334 std::cout <<
"TPC Clusterizer found " <<
m_clusterlist->
size() <<
" Clusters " << std::endl;