10 #include <Eigen/Dense> 16 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
24 LogDebug(
"TrackstersPCA_Eigen") <<
"------- Eigen -------" << std::endl;
27 LogDebug(
"TrackstersPCA_Eigen") <<
"start testing teackster with size:" << trackster.vertices().size() << std::endl;
32 barycenter << 0., 0., 0.;
34 filtered_barycenter << 0., 0., 0.;
43 trackster.setRawEnergy(0.
f);
44 trackster.setRawEmEnergy(0.
f);
45 trackster.setRawPt(0.
f);
46 trackster.setRawEmPt(0.
f);
48 size_t N = trackster.vertices().size();
52 float weights2_sum = 0.f;
54 std::vector<float> layerClusterEnergies;
56 for (
size_t i = 0;
i <
N; ++
i) {
57 auto fraction = 1.f / trackster.vertex_multiplicity(
i);
66 for (
size_t j = 0;
j < 3; ++
j)
69 layerClusterEnergies.push_back(
layerClusters[trackster.vertices(
i)].energy());
71 float raw_energy = trackster.raw_energy();
72 float inv_raw_energy = 1.f / raw_energy;
74 barycenter *= inv_raw_energy;
77 LogDebug(
"TrackstersPCA_Eigen") <<
"cleaning is :" <<
clean << std::endl;
79 std::vector<unsigned> filtered_idx;
80 float filtered_energy = 0;
81 float inv_filtered_energy = 0;
84 auto maxE_vertex =
std::distance(layerClusterEnergies.begin(),
85 std::max_element(layerClusterEnergies.begin(), layerClusterEnergies.end()));
91 auto vertices_in_layer = vertices_by_layer[
i];
92 if (vertices_in_layer.empty())
95 std::vector<float> energies_in_layer;
96 for (
auto vrt : vertices_in_layer)
97 energies_in_layer.push_back(
layerClusters[trackster.vertices(vrt)].energy());
99 unsigned maxEid_inLayer =
std::distance(energies_in_layer.begin(),
100 std::max_element(energies_in_layer.begin(), energies_in_layer.end()));
103 if ((
int)
i >= (
int)maxE_layer -
minLayer && (
int)
i <= (
int)maxE_layer + maxLayer) {
104 auto filtered_vert = vertices_in_layer[maxEid_inLayer];
105 filtered_idx.push_back(filtered_vert);
107 const auto &maxE_LC =
layerClusters[trackster.vertices(filtered_vert)];
108 fillPoint(maxE_LC, maxE_LC.energy() * (1.f / trackster.vertex_multiplicity(filtered_vert)));
109 for (
size_t j = 0;
j < 3; ++
j)
110 filtered_barycenter[
j] +=
point[
j];
111 filtered_energy += maxE_LC.energy();
114 inv_filtered_energy = 1. / filtered_energy;
115 filtered_barycenter *= inv_filtered_energy;
117 LogDebug(
"TrackstersPCA_Eigen") <<
"min, max " <<
minLayer <<
" " << maxLayer << std::endl;
119 std::pair<float, float> timeTrackster;
125 trackster.setTimeAndError(timeTrackster.first, timeTrackster.second);
126 LogDebug(
"TrackstersPCA") <<
"Use energy weighting: " << energyWeight << std::endl;
127 LogDebug(
"TrackstersPCA") <<
"\nTrackster characteristics: " << std::endl;
128 LogDebug(
"TrackstersPCA") <<
"Size: " <<
N << std::endl;
129 LogDebug(
"TrackstersPCA") <<
"Energy: " << trackster.raw_energy() << std::endl;
130 LogDebug(
"TrackstersPCA") <<
"raw_pt: " << trackster.raw_pt() << std::endl;
131 LogDebug(
"TrackstersPCA") <<
"Means: " << barycenter[0] <<
", " << barycenter[1] <<
", " << barycenter[2]
133 LogDebug(
"TrackstersPCA") <<
"Time: " << trackster.time() <<
" +/- " << trackster.timeError() << std::endl;
137 sigmas << 0., 0., 0.;
139 sigmasEigen << 0., 0., 0.;
145 auto calc_covM = [&](
size_t i) {
147 if (energyWeight && trackster.raw_energy()) {
149 (
clean ? inv_filtered_energy : inv_raw_energy);
150 if (trackster.vertex_multiplicity(
i) > 1)
152 <<
"trackster.vertex_multiplicity(i) :" << trackster.vertex_multiplicity(
i);
155 for (
size_t x = 0;
x < 3; ++
x) {
156 for (
size_t y = 0;
y <=
x; ++
y) {
158 (
point[
y] - (
clean ? filtered_barycenter[
y] : barycenter[
y]));
159 covM(
y,
x) = covM(
x,
y);
164 for (
size_t i : filtered_idx) {
168 for (
size_t i = 0;
i <
N; ++
i) {
173 covM *= 1.f / (1.f - weights2_sum);
176 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f>::RealVectorType eigenvalues_fromEigen;
177 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f>::EigenvectorsType eigenvectors_fromEigen;
178 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigensolver(covM);
180 eigenvalues_fromEigen = eigenvalues_fromEigen.Zero();
181 eigenvectors_fromEigen = eigenvectors_fromEigen.Zero();
183 eigenvalues_fromEigen = eigensolver.eigenvalues();
184 eigenvectors_fromEigen = eigensolver.eigenvectors();
188 auto calc_spread = [&](
size_t i) {
190 sigmas +=
weight * (
point - (
clean ? filtered_barycenter : barycenter)).cwiseAbs2();
192 eigenvectors_fromEigen * (
point - (
clean ? filtered_barycenter : barycenter));
193 if (energyWeight && raw_energy)
195 (
clean ? inv_filtered_energy : inv_raw_energy);
196 sigmasEigen +=
weight * (point_transformed.cwiseAbs2());
200 for (
size_t i : filtered_idx) {
204 for (
size_t i = 0;
i <
N; ++
i) {
209 sigmas /= (1.f - weights2_sum);
210 sigmasEigen /= (1.f - weights2_sum);
212 trackster.fillPCAVariables(eigenvalues_fromEigen,
213 eigenvectors_fromEigen,
219 LogDebug(
"TrackstersPCA") <<
"EigenValues from Eigen/Tr(cov): " << eigenvalues_fromEigen[2] / covM.trace() <<
", " 220 << eigenvalues_fromEigen[1] / covM.trace() <<
", " 221 << eigenvalues_fromEigen[0] / covM.trace() << std::endl;
222 LogDebug(
"TrackstersPCA") <<
"EigenValues from Eigen: " << eigenvalues_fromEigen[2] <<
", " 223 << eigenvalues_fromEigen[1] <<
", " << eigenvalues_fromEigen[0] << std::endl;
224 LogDebug(
"TrackstersPCA") <<
"EigenVector 3 from Eigen: " << eigenvectors_fromEigen(0, 2) <<
", " 225 << eigenvectors_fromEigen(1, 2) <<
", " << eigenvectors_fromEigen(2, 2) << std::endl;
226 LogDebug(
"TrackstersPCA") <<
"EigenVector 2 from Eigen: " << eigenvectors_fromEigen(0, 1) <<
", " 227 << eigenvectors_fromEigen(1, 1) <<
", " << eigenvectors_fromEigen(2, 1) << std::endl;
228 LogDebug(
"TrackstersPCA") <<
"EigenVector 1 from Eigen: " << eigenvectors_fromEigen(0, 0) <<
", " 229 << eigenvectors_fromEigen(1, 0) <<
", " << eigenvectors_fromEigen(2, 0) << std::endl;
230 LogDebug(
"TrackstersPCA") <<
"Original sigmas: " << sigmas[0] <<
", " << sigmas[1] <<
", " << sigmas[2]
232 LogDebug(
"TrackstersPCA") <<
"SigmasEigen in PCA space: " << sigmasEigen[2] <<
", " << sigmasEigen[1] <<
", " 233 << sigmasEigen[0] << std::endl;
234 LogDebug(
"TrackstersPCA") <<
"covM: \n" << covM << std::endl;
241 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
244 float tracksterTime = 0.;
245 float tracksterTimeErr = 0.;
247 auto project_lc_to_pca = [](
const std::array<float, 3> &
point,
const std::array<float, 3> &segment_end) {
248 float dot_product = 0.0;
249 float segment_dot = 0.0;
251 for (
int i = 0;
i < 3; ++
i) {
252 dot_product +=
point[
i] * segment_end[
i];
253 segment_dot += segment_end[
i] * segment_end[
i];
256 float projection = 0.0;
257 if (segment_dot != 0.0) {
258 projection = dot_product / segment_dot;
261 std::array<float, 3> closest_point;
262 for (
int i = 0;
i < 3; ++
i) {
263 closest_point[
i] = projection * segment_end[
i];
266 float distanceSquared = 0.f;
267 for (
int i = 0;
i < 3; ++
i) {
270 return distanceSquared;
274 for (
size_t i = 0;
i <
N; ++
i) {
279 timeE = 1.f /
pow(timeE, 2);
284 if (project_lc_to_pca({{
x,
y,
z}}, {{barycenter[0], barycenter[1], barycenter[2]}}) < 9.
f) {
285 float invz = 1.f /
z;
286 float deltaT = 1.f /
c *
287 std::sqrt(((barycenter[2] * invz - 1.
f) *
x) * ((barycenter[2] * invz - 1.
f) *
x) +
288 ((barycenter[2] * invz - 1.
f) *
y) * ((barycenter[2] * invz - 1.
f) *
y) +
289 (barycenter[2] -
z) * (barycenter[2] -
z));
292 tracksterTime +=
time * timeE;
293 tracksterTimeErr += timeE;
297 if (tracksterTimeErr > 0.
f)
298 return {tracksterTime / tracksterTimeErr, 1.f /
std::sqrt(tracksterTimeErr)};
300 return {-99.f, -1.f};
304 const edm::ValueMap<std::pair<float, float>> &layerClustersTime,
306 std::vector<float> times;
307 std::vector<float> timeErrors;
309 for (
size_t i = 0;
i <
N; ++
i) {
312 times.push_back(layerClustersTime.get(trackster.
vertices(
i)).
first);
313 timeErrors.push_back(1.
f /
pow(timeE, 2));
std::vector< std::vector< unsigned > > sortByLayer(const Trackster &ts, const std::vector< reco::CaloCluster > &layerClusters, const hgcal::RecHitTools &rhtools)
unsigned getLayerFromLC(const reco::CaloCluster &LC, const hgcal::RecHitTools &rhtools)
void assignPCAtoTracksters(std::vector< Trackster > &tracksters, const std::vector< reco::CaloCluster > &layerClusters, const edm::ValueMap< std::pair< float, float >> &layerClustersTime, double z_limit_em, hgcal::RecHitTools const &rhTools, bool computeLocalTime=false, bool energyWeight=true, bool clean=false, int minLayer=10, int maxLayer=10)
static void clean(char *s)
U second(std::pair< T, U > const &p)
std::pair< float, float > fixSizeHighestDensity(std::vector< float > &time, std::vector< float > weight=std::vector< float >(), unsigned int minNhits=3, float deltaT=0.210, float timeWidthBy=0.5)
std::pair< float, float > computeLocalTracksterTime(const Trackster &trackster, const std::vector< reco::CaloCluster > &layerClusters, const edm::ValueMap< std::pair< float, float >> &layerClustersTime, const Eigen::Vector3f &barycenter, size_t N)
Abs< T >::type abs(const T &t)
std::pair< float, float > computeTracksterTime(const Trackster &trackster, const edm::ValueMap< std::pair< float, float >> &layerClustersTime, size_t N)
std::vector< unsigned int > & vertices()
Power< A, B >::type pow(const A &a, const B &b)
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point