16 #include <tpc/TpcDefs.h>
28 #include <phfield/PHFieldConfig.h>
29 #include <phfield/PHFieldConfigv2.h>
30 #include <phfield/PHFieldUtility.h>
32 #include <tpc/TpcDefs.h>
33 #include <tpc/TpcHit.h>
48 #include <Event/Event.h>
49 #include <Event/EventTypes.h>
50 #include <Event/packet.h>
53 #include <TClonesArray.h>
55 #include <TMatrixFfwd.h>
57 #include <TMatrixTUtils.h>
61 #include <boost/bimap.hpp>
62 #include <boost/bind.hpp>
63 #include <boost/format.hpp>
64 #include <boost/graph/adjacency_list.hpp>
65 #include <boost/graph/connected_components.hpp>
81 using namespace TpcPrototypeDefs::FEEv2;
86 , tpcCylinderCellGeom(nullptr)
87 , hitsetcontainer(nullptr)
88 , trkrclusters(nullptr)
89 , m_outputFileName(outputfilename)
91 , m_peventHeader(&m_eventHeader)
93 , m_IOClusters(nullptr)
95 , m_pchanHeader(&m_chanHeader)
97 , enableClustering(
true)
98 , m_clusteringZeroSuppression(50)
101 , m_XRayLocationX(-1)
102 , m_XRayLocationY(-1)
103 , m_pdfMaker(nullptr)
190 cout <<
PHWHERE <<
"DST Node missing, doing nothing." << endl;
198 cout <<
"TpcPrototypeUnpacker::InitRun - making pad plane"
203 const int field_ret =
InitField(topNode);
206 cout <<
"TpcPrototypeUnpacker::InitRun- Error - Failed field init with status = " << field_ret << endl;
210 string seggeonodename =
"CYLINDERCELLGEOM_SVTX";
211 tpcCylinderCellGeom = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode, seggeonodename.c_str());
227 hitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode,
"TRKR_HITSET");
245 trkrclusters = findNode::getClass<TrkrClusterContainer>(topNode,
"TRKR_CLUSTER");
261 DetNode->
addNode(TrkrClusterContainerNode);
266 cout <<
"TpcPrototypeUnpacker::InitRun - Making PHTFileServer " <<
m_outputFileName
276 TH1D*
h =
new TH1D(
"hNormalization",
277 "Normalization;Items;Summed quantity", 10, .5, 10.5);
279 h->GetXaxis()->SetBinLabel(i++,
"Event count");
280 h->GetXaxis()->SetBinLabel(i++,
"Collision count");
281 h->GetXaxis()->SetBinLabel(i++,
"TPC G4Hit");
282 h->GetXaxis()->SetBinLabel(i++,
"TPC G4Hit Edep");
283 h->GetXaxis()->SetBinLabel(i++,
"TPC Pad Hit");
284 h->GetXaxis()->SetBinLabel(i++,
"TPC Charge e");
285 h->GetXaxis()->SetBinLabel(i++,
"TPC Charge fC");
286 h->GetXaxis()->LabelsOption(
"v");
289 m_eventT =
new TTree(
"eventT",
"TPC FEE per-event Tree");
293 m_IOClusters =
new TClonesArray(
"TpcPrototypeUnpacker::ClusterData", 1000);
296 m_chanT =
new TTree(
"chanT",
"TPC FEE per-channel Tree");
336 cout <<
"TpcPrototypeUnpacker::End - write to " <<
m_outputFileName << endl;
342 for (
unsigned int i = 0;
i < hm->
nHistos();
i++)
346 TTree* T_Index =
new TTree(
"T_Index",
"T_Index");
365 TH1D* h_norm =
dynamic_cast<TH1D*
>(hm->
getHisto(
"hNormalization"));
368 Event*
event = findNode::getClass<Event>(topNode,
"PRDF");
369 if (
event ==
nullptr)
372 cout <<
"TpcPrototypeUnpacker::Process_Event - Event not found" << endl;
400 static const char* MAX_LENGTH =
"MAX_SAMPLES";
401 static const char* IS_PRESENT =
"IS_PRESENT";
402 static const char* BX_COUNTER =
"BX";
412 cout <<
"TpcPrototypeUnpacker::process_event - package dump" << endl;
416 int max_length[
kN_FEES] = {-1};
421 max_length[
i] =
p->iValue(
i, MAX_LENGTH);
423 catch (
const std::out_of_range&
e)
431 cout <<
"TpcPrototypeUnpacker::process_event - max_length[" <<
i <<
"]=" << max_length[
i] << endl;
438 for (
unsigned int fee = 0; fee <
kN_FEES; ++fee)
442 if (!
p->iValue(fee, IS_PRESENT))
446 cout <<
"TpcPrototypeUnpacker::process_event - missing fee[" << fee <<
"]=" << endl;
451 catch (
const std::out_of_range&
e)
453 cout <<
"TpcPrototypeUnpacker::process_event - out_of_range in p->iValue(" << fee <<
", IS_PRESENT)" << endl;
460 cout <<
"TpcPrototypeUnpacker::process_event - processing fee[" << fee <<
"]=" << endl;
471 cout <<
"TpcPrototypeUnpacker::process_event - processing fee["
472 << fee <<
"], chan[" <<
channel <<
"] NR_SAMPLES = "
473 <<
p->iValue(fee,
channel,
"NR_SAMPLES") << endl;
476 unsigned int real_t = 0;
477 uint32_t old_bx_count = 0;
479 uint32_t bx_count = 0;
487 bx_count =
p->iValue(fee,
channel,
t, BX_COUNTER);
492 catch (
const std::out_of_range& e)
499 if (bx_count >= old_bx_count + 128)
501 old_bx_count = bx_count;
506 assert(real_t < kSAMPLE_LENGTH);
528 cout <<
"TpcPrototypeUnpacker::process_event - "
539 cout <<
"data[" << sample <<
"] = " << int(
m_chanData[sample]) <<
" ";
572 h_norm->Fill(
"Event count", 1);
584 for (
unsigned int pad_radial = 0; pad_radial <
kMaxPadX; ++pad_radial)
590 for (
unsigned int pad_azimuth = 0; pad_azimuth <
kMaxPadY; ++pad_azimuth)
594 unsigned int adc =
static_cast<unsigned int>(
m_padPlaneData.
getData()[pad_azimuth][pad_radial][sample]);
602 hit = hitsetit->second->getHit(hitkey);
607 hitsetit->second->addHitSpecificKey(hitkey, hit);
611 cout <<
"TpcPrototypeUnpacker::exportDSTHits "
612 <<
" - Fatal error - hit with "
613 <<
" hitkey = " << hitkey <<
" already exist";
633 cout << __PRETTY_FUNCTION__ <<
" entry" << endl;
641 for (
const auto& iter : groups)
643 const int&
i = iter.first;
687 for (
int i = 0;
i < n_sample; ++
i)
705 map<int, double> parameters_constraints;
708 double peak_sample = NAN;
709 double pedstal = NAN;
710 map<int, double> parameters_io;
712 peak_sample, pedstal, parameters_io,
Verbosity());
714 parameters_constraints[1] = parameters_io[1];
715 parameters_constraints[2] = parameters_io[2];
716 parameters_constraints[3] = parameters_io[3];
717 parameters_constraints[5] = parameters_io[5];
718 parameters_constraints[6] = parameters_io[6];
754 double sum_peak_pad_azimuth = 0;
758 double peak_sample = NAN;
759 double pedstal = NAN;
760 map<int, double> parameters_io(parameters_constraints);
763 peak_sample, pedstal, parameters_io,
Verbosity());
767 sum_peak_pad_azimuth += peak * pad_y;
778 map<double, int> cluster_energy;
779 for (
auto& iter : m_clusters)
782 cluster_energy[-iter.second.peak] = iter.first;
788 for (
const auto& iter : cluster_energy)
813 const int NZBins = layergeom->
get_zbins();
822 cout <<
"TpcPrototypeUnpacker::exportDSTCluster - fatal error - cluster already exist which is not expected for prototype analysis. "
823 <<
"iclus = " << iclus <<
", ckey = " << ckey <<
". Offending cluster: " << endl;
833 const double radius = layergeom->
get_radius();
836 cout << __PRETTY_FUNCTION__ <<
" WARNING - cluster.avg_pad_azimuth = " << cluster.
avg_pad_azimuth <<
" < 0"
837 <<
", cluster.avg_pad_radial = " << cluster.
avg_pad_radial << endl;
843 cout << __PRETTY_FUNCTION__ <<
" WARNING - cluster.avg_pad_azimuth = " << cluster.
avg_pad_azimuth <<
" > " << NPhiBins
844 <<
", cluster.avg_pad_radial = " << cluster.
avg_pad_radial << endl;
852 cout << __PRETTY_FUNCTION__ <<
" WARNING - cluster.avg_pad_azimuth = " << cluster.
avg_pad_azimuth <<
" -> "
853 <<
" lower = " << lowery <<
" < 0"
854 <<
", cluster.avg_pad_radial = " << cluster.
avg_pad_radial << endl;
871 static const double phi_err = 170
e-4;
873 static const double z_err = 1000
e-4;
954 DIM[1][1] = phi_size * phi_size;
958 DIM[2][2] = z_size * z_size;
965 ERR[1][1] = phi_err * phi_err;
969 ERR[2][2] = z_err * z_err;
972 ROT[0][0] = cos(clusphi);
973 ROT[0][1] = -sin(clusphi);
975 ROT[1][0] = sin(clusphi);
976 ROT[1][1] = cos(clusphi);
982 TMatrixF ROT_T(3, 3);
983 ROT_T.Transpose(ROT);
985 TMatrixF COVAR_DIM(3, 3);
986 COVAR_DIM = ROT * DIM * ROT_T;
988 clus->
setSize(0, 0, COVAR_DIM[0][0]);
989 clus->
setSize(0, 1, COVAR_DIM[0][1]);
990 clus->
setSize(0, 2, COVAR_DIM[0][2]);
991 clus->
setSize(1, 0, COVAR_DIM[1][0]);
992 clus->
setSize(1, 1, COVAR_DIM[1][1]);
993 clus->
setSize(1, 2, COVAR_DIM[1][2]);
994 clus->
setSize(2, 0, COVAR_DIM[2][0]);
995 clus->
setSize(2, 1, COVAR_DIM[2][1]);
996 clus->
setSize(2, 2, COVAR_DIM[2][2]);
999 TMatrixF COVAR_ERR(3, 3);
1000 COVAR_ERR = ROT * ERR * ROT_T;
1002 clus->
setError(0, 0, COVAR_ERR[0][0]);
1003 clus->
setError(0, 1, COVAR_ERR[0][1]);
1004 clus->
setError(0, 2, COVAR_ERR[0][2]);
1005 clus->
setError(1, 0, COVAR_ERR[1][0]);
1006 clus->
setError(1, 1, COVAR_ERR[1][1]);
1007 clus->
setError(1, 2, COVAR_ERR[1][2]);
1008 clus->
setError(2, 0, COVAR_ERR[2][0]);
1009 clus->
setError(2, 1, COVAR_ERR[2][1]);
1010 clus->
setError(2, 2, COVAR_ERR[2][2]);
1016 cout << __PRETTY_FUNCTION__ <<
"Dump clusters after TpcPrototypeClusterizer" << endl;
1031 for (
auto& padrow : m_data)
1033 for (
auto& pad : padrow)
1035 fill(pad.begin(), pad.end(), 0);
1044 return (pad_x >= 0) and
1057 return m_data[pad_y][pad_x];
1062 std::vector<int> sorted_data(data);
1064 sort(sorted_data.begin(), sorted_data.end());
1066 const int pedestal = sorted_data[sorted_data.size() / 2];
1067 const int max = sorted_data.back();
1069 for (
auto& d : data)
1072 return make_pair(pedestal, max);
1093 using namespace boost;
1094 typedef adjacency_list<vecS, vecS, undirectedS> Graph;
1095 typedef bimap<Graph::vertex_descriptor, SampleID> VertexList;
1098 VertexList vertex_list;
1100 for (
unsigned int pad_azimuth = 0; pad_azimuth <
kMaxPadY; ++pad_azimuth)
1102 for (
unsigned int pad_radial = 0; pad_radial <
kMaxPadX; ++pad_radial)
1106 if (m_data[pad_azimuth][pad_radial][sample] > zero_suppression)
1108 SampleID id{(int) (pad_azimuth), (int) (pad_radial), (int) (sample)};
1109 Graph::vertex_descriptor
v = boost::add_vertex(
G);
1119 vector<SampleID> search_directions;
1120 search_directions.push_back(
SampleID{0, 0, 1});
1122 search_directions.push_back(
SampleID{1, 0, 0});
1124 for (
const auto&
it : vertex_list.right)
1127 const Graph::vertex_descriptor
v =
it.second;
1129 for (
const SampleID& search_direction : search_directions)
1133 next_id.
adjust(search_direction);
1135 auto next_it = vertex_list.right.find(next_id);
1136 if (next_it != vertex_list.right.end())
1138 add_edge(v, next_it->second,
G);
1146 std::vector<int> component(num_vertices(
G));
1147 connected_components(
G, &component[0]);
1152 assert(m_groups.size() == 0);
1154 for (
unsigned int i = 0;
i < component.size();
i++)
1156 comps.insert(component[
i]);
1157 m_groups.insert(make_pair(component[i], vertex_list.left.find(
vertex(i,
G))->second));
1162 for (
const int&
comp : comps)
1164 cout <<
"TpcPrototypeUnpacker::PadPlaneData::Clustering - find cluster " <<
comp <<
" containing ";
1165 const auto range = m_groups.equal_range(comp);
1167 for (
auto iter = range.first; iter != range.second; ++iter)
1170 cout <<
"adc[" <<
id.
pad_azimuth <<
"][" <<
id.pad_radial <<
"][" <<
id.sample <<
"] = " << m_data[
id.pad_azimuth][
id.pad_radial][
id.sample] <<
", ";
1179 static string histname(
"TpcPrototypeUnpacker_HISTOS");
1187 <<
"TpcPrototypeUnpacker::get_HistoManager - Making Fun4AllHistoManager "
1188 << histname << endl;
1200 cout <<
"Registering padplane " << endl;
1205 cout << __PRETTY_FUNCTION__ <<
" padplane registered and parameters updated" << endl;
1212 if (
Verbosity() >= 1) cout <<
"TpcPrototypeUnpacker::InitField - create magnetic field setup" << endl;
1214 unique_ptr<PHFieldConfig> default_field_cfg(
nullptr);