File indexing completed on 2024-04-06 12:23:58
0001 #include "PhysicsTools/PatAlgos/interface/HemisphereAlgo.h"
0002
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004
0005 #include "DataFormats/Math/interface/deltaPhi.h"
0006 #include "DataFormats/Math/interface/deltaR.h"
0007
0008 using namespace std;
0009 using std::vector;
0010
0011 HemisphereAlgo::HemisphereAlgo(const std::vector<reco::CandidatePtr>& componentPtr_,
0012 const int seed_method,
0013 const int hemisphere_association_method)
0014 : Object(componentPtr_),
0015 Object_Group(),
0016 Axis1(),
0017 Axis2(),
0018 seed_meth(seed_method),
0019 hemi_meth(hemisphere_association_method),
0020 status(0) {
0021 for (int i = 0; i < (int)Object.size(); i++) {
0022 Object_Noseed.push_back(0);
0023 }
0024 }
0025
0026 vector<float> HemisphereAlgo::getAxis1() {
0027 if (status != 1) {
0028 this->reconstruct();
0029 }
0030 return Axis1;
0031 }
0032 vector<float> HemisphereAlgo::getAxis2() {
0033 if (status != 1) {
0034 this->reconstruct();
0035 }
0036 return Axis2;
0037 }
0038
0039 vector<int> HemisphereAlgo::getGrouping() {
0040 if (status != 1) {
0041 this->reconstruct();
0042 }
0043 return Object_Group;
0044 }
0045
0046 int HemisphereAlgo::reconstruct() {
0047 int vsize = (int)Object.size();
0048
0049 LogDebug("HemisphereAlgo") << " HemisphereAlgo method ";
0050
0051 Object_Group.clear();
0052 Axis1.clear();
0053 Axis2.clear();
0054
0055 for (int j = 0; j < vsize; j++) {
0056 Object_Group.push_back(0);
0057 }
0058
0059 for (int j = 0; j < 5; j++) {
0060 Axis1.push_back(0);
0061 Axis2.push_back(0);
0062 }
0063
0064 for (int i = 0; i < vsize; i++) {
0065 if ((*(Object)[i]).p() > (*Object[i]).energy() + 0.001) {
0066 edm::LogWarning("HemisphereAlgo") << "Object " << i << " has E = " << (*Object[i]).energy()
0067 << " less than P = " << (*Object[i]).p();
0068 }
0069 }
0070
0071 LogDebug("HemisphereAlgo") << " Seeding method = " << seed_meth;
0072 int I_Max = -1;
0073 int J_Max = -1;
0074
0075 if (seed_meth == 1) {
0076 float P_Max = 0.;
0077 float DeltaRP_Max = 0.;
0078
0079
0080 for (int i = 0; i < vsize; i++) {
0081 Object_Group[i] = 0;
0082 if (Object_Noseed[i] == 0 && P_Max < (*Object[i]).p()) {
0083 P_Max = (*Object[i]).p();
0084 I_Max = i;
0085 }
0086 }
0087
0088 Axis1[0] = (*Object[I_Max]).px() / (*Object[I_Max]).p();
0089 Axis1[1] = (*Object[I_Max]).py() / (*Object[I_Max]).p();
0090 Axis1[2] = (*Object[I_Max]).pz() / (*Object[I_Max]).p();
0091 Axis1[3] = (*Object[I_Max]).p();
0092 Axis1[4] = (*Object[I_Max]).energy();
0093
0094
0095 for (int i = 0; i < vsize; i++) {
0096 float DeltaR = deltaR((*Object[i]).eta(), (*Object[i]).phi(), (*Object[I_Max]).eta(), (*Object[I_Max]).phi());
0097
0098 if (Object_Noseed[i] == 0 && DeltaR > 0.5) {
0099 float DeltaRP = DeltaR * (*Object[i]).p();
0100 if (DeltaRP > DeltaRP_Max) {
0101 DeltaRP_Max = DeltaRP;
0102 J_Max = i;
0103 }
0104 }
0105 }
0106
0107 if (J_Max >= 0) {
0108 Axis2[0] = (*Object[J_Max]).px() / (*Object[J_Max]).p();
0109 Axis2[1] = (*Object[J_Max]).py() / (*Object[J_Max]).p();
0110 Axis2[2] = (*Object[J_Max]).pz() / (*Object[J_Max]).p();
0111 Axis2[3] = (*Object[J_Max]).p();
0112 Axis2[4] = (*Object[J_Max]).energy();
0113
0114 } else {
0115 return 0;
0116 }
0117 LogDebug("HemisphereAlgo") << " Axis 1 is Object = " << I_Max;
0118 LogDebug("HemisphereAlgo") << " Axis 2 is Object = " << J_Max;
0119
0120 } else if ((seed_meth == 2) | (seed_meth == 3)) {
0121 float Mass_Max = 0.;
0122 float InvariantMass = 0.;
0123
0124
0125 for (int i = 0; i < vsize; i++) {
0126 Object_Group[i] = 0;
0127 if (Object_Noseed[i] == 0) {
0128 for (int j = i + 1; j < vsize; j++) {
0129 if (Object_Noseed[j] == 0) {
0130
0131 if (seed_meth == 2) {
0132 InvariantMass =
0133 ((*Object[i]).energy() + (*Object[j]).energy()) * ((*Object[i]).energy() + (*Object[j]).energy()) -
0134 ((*Object[i]).px() + (*Object[j]).px()) * ((*Object[i]).px() + (*Object[j]).px()) -
0135 ((*Object[i]).py() + (*Object[j]).py()) * ((*Object[i]).py() + (*Object[j]).py()) -
0136 ((*Object[i]).pz() + (*Object[j]).pz()) * ((*Object[i]).pz() + (*Object[j]).pz());
0137 }
0138
0139 else if (seed_meth == 3) {
0140 float pti = sqrt((*Object[i]).px() * (*Object[i]).px() + (*Object[i]).py() * (*Object[i]).py());
0141 float ptj = sqrt((*Object[j]).px() * (*Object[j]).px() + (*Object[j]).py() * (*Object[j]).py());
0142 InvariantMass =
0143 2. * (pti * ptj - (*Object[i]).px() * (*Object[j]).px() - (*Object[i]).py() * (*Object[j]).py());
0144 }
0145 if (Mass_Max < InvariantMass) {
0146 Mass_Max = InvariantMass;
0147 I_Max = i;
0148 J_Max = j;
0149 }
0150 }
0151 }
0152 }
0153 }
0154
0155 if (J_Max > 0) {
0156 Axis1[0] = (*Object[I_Max]).px() / (*Object[I_Max]).p();
0157 Axis1[1] = (*Object[I_Max]).py() / (*Object[I_Max]).p();
0158 Axis1[2] = (*Object[I_Max]).pz() / (*Object[I_Max]).p();
0159
0160 Axis1[3] = (*Object[I_Max]).p();
0161 Axis1[4] = (*Object[I_Max]).energy();
0162
0163 Axis2[0] = (*Object[J_Max]).px() / (*Object[J_Max]).p();
0164 Axis2[1] = (*Object[J_Max]).py() / (*Object[J_Max]).p();
0165 Axis2[2] = (*Object[J_Max]).pz() / (*Object[J_Max]).p();
0166
0167 Axis2[3] = (*Object[J_Max]).p();
0168 Axis2[4] = (*Object[J_Max]).energy();
0169
0170 } else {
0171 return 0;
0172 }
0173 LogDebug("HemisphereAlgo") << " Axis 1 is Object = " << I_Max;
0174 LogDebug("HemisphereAlgo") << " Axis 2 is Object = " << J_Max;
0175
0176 } else {
0177 throw cms::Exception("Configuration") << "Please give a valid seeding method!";
0178 }
0179
0180
0181
0182
0183 LogDebug("HemisphereAlgo") << " Association method = " << hemi_meth;
0184
0185 int numLoop = 0;
0186 bool I_Move = true;
0187
0188 while (I_Move && (numLoop < 100)) {
0189 I_Move = false;
0190 numLoop++;
0191 LogDebug("HemisphereAlgo") << " Iteration = " << numLoop;
0192
0193 float Sum1_Px = 0.;
0194 float Sum1_Py = 0.;
0195 float Sum1_Pz = 0.;
0196 float Sum1_E = 0.;
0197 float Sum2_Px = 0.;
0198 float Sum2_Py = 0.;
0199 float Sum2_Pz = 0.;
0200 float Sum2_E = 0.;
0201
0202 if (hemi_meth == 1) {
0203 for (int i = 0; i < vsize; i++) {
0204 float P_Long1 = (*Object[i]).px() * Axis1[0] + (*Object[i]).py() * Axis1[1] + (*Object[i]).pz() * Axis1[2];
0205 float P_Long2 = (*Object[i]).px() * Axis2[0] + (*Object[i]).py() * Axis2[1] + (*Object[i]).pz() * Axis2[2];
0206 if (P_Long1 >= P_Long2) {
0207 if (Object_Group[i] != 1) {
0208 I_Move = true;
0209 }
0210 Object_Group[i] = 1;
0211 Sum1_Px += (*Object[i]).px();
0212 Sum1_Py += (*Object[i]).py();
0213 Sum1_Pz += (*Object[i]).pz();
0214 Sum1_E += (*Object[i]).energy();
0215 } else {
0216 if (Object_Group[i] != 2) {
0217 I_Move = true;
0218 }
0219 Object_Group[i] = 2;
0220 Sum2_Px += (*Object[i]).px();
0221 Sum2_Py += (*Object[i]).py();
0222 Sum2_Pz += (*Object[i]).pz();
0223 Sum2_E += (*Object[i]).energy();
0224 }
0225 }
0226
0227 } else if (hemi_meth == 2 || hemi_meth == 3) {
0228 for (int i = 0; i < vsize; i++) {
0229 if (i == I_Max) {
0230 Object_Group[i] = 1;
0231 Sum1_Px += (*Object[i]).px();
0232 Sum1_Py += (*Object[i]).py();
0233 Sum1_Pz += (*Object[i]).pz();
0234 Sum1_E += (*Object[i]).energy();
0235 } else if (i == J_Max) {
0236 Object_Group[i] = 2;
0237 Sum2_Px += (*Object[i]).px();
0238 Sum2_Py += (*Object[i]).py();
0239 Sum2_Pz += (*Object[i]).pz();
0240 Sum2_E += (*Object[i]).energy();
0241 } else {
0242 if (!I_Move) {
0243 float NewAxis1_Px = Axis1[0] * Axis1[3];
0244 float NewAxis1_Py = Axis1[1] * Axis1[3];
0245 float NewAxis1_Pz = Axis1[2] * Axis1[3];
0246 float NewAxis1_E = Axis1[4];
0247
0248 float NewAxis2_Px = Axis2[0] * Axis2[3];
0249 float NewAxis2_Py = Axis2[1] * Axis2[3];
0250 float NewAxis2_Pz = Axis2[2] * Axis2[3];
0251 float NewAxis2_E = Axis2[4];
0252
0253 if (Object_Group[i] == 1) {
0254 NewAxis1_Px = NewAxis1_Px - (*Object[i]).px();
0255 NewAxis1_Py = NewAxis1_Py - (*Object[i]).py();
0256 NewAxis1_Pz = NewAxis1_Pz - (*Object[i]).pz();
0257 NewAxis1_E = NewAxis1_E - (*Object[i]).energy();
0258
0259 } else if (Object_Group[i] == 2) {
0260 NewAxis2_Px = NewAxis2_Px - (*Object[i]).px();
0261 NewAxis2_Py = NewAxis2_Py - (*Object[i]).py();
0262 NewAxis2_Pz = NewAxis2_Pz - (*Object[i]).pz();
0263 NewAxis2_E = NewAxis2_E - (*Object[i]).energy();
0264 }
0265
0266 float mass1 =
0267 NewAxis1_E -
0268 (((*Object[i]).px() * NewAxis1_Px + (*Object[i]).py() * NewAxis1_Py + (*Object[i]).pz() * NewAxis1_Pz) /
0269 (*Object[i]).p());
0270
0271 float mass2 =
0272 NewAxis2_E -
0273 (((*Object[i]).px() * NewAxis2_Px + (*Object[i]).py() * NewAxis2_Py + (*Object[i]).pz() * NewAxis2_Pz) /
0274 (*Object[i]).p());
0275
0276 if (hemi_meth == 3) {
0277 mass1 *= NewAxis1_E / ((NewAxis1_E + (*Object[i]).energy()) * (NewAxis1_E + (*Object[i]).energy()));
0278
0279 mass2 *= NewAxis2_E / ((NewAxis2_E + (*Object[i]).energy()) * (NewAxis2_E + (*Object[i]).energy()));
0280 }
0281
0282 if (mass1 < mass2) {
0283 if (Object_Group[i] != 1) {
0284 I_Move = true;
0285 }
0286 Object_Group[i] = 1;
0287
0288 Sum1_Px += (*Object[i]).px();
0289 Sum1_Py += (*Object[i]).py();
0290 Sum1_Pz += (*Object[i]).pz();
0291 Sum1_E += (*Object[i]).energy();
0292 } else {
0293 if (Object_Group[i] != 2) {
0294 I_Move = true;
0295 }
0296 Object_Group[i] = 2;
0297 Sum2_Px += (*Object[i]).px();
0298 Sum2_Py += (*Object[i]).py();
0299 Sum2_Pz += (*Object[i]).pz();
0300 Sum2_E += (*Object[i]).energy();
0301 }
0302
0303 } else {
0304 if (Object_Group[i] == 1) {
0305 Sum1_Px += (*Object[i]).px();
0306 Sum1_Py += (*Object[i]).py();
0307 Sum1_Pz += (*Object[i]).pz();
0308 Sum1_E += (*Object[i]).energy();
0309 }
0310 if (Object_Group[i] == 2) {
0311 Sum2_Px += (*Object[i]).px();
0312 Sum2_Py += (*Object[i]).py();
0313 Sum2_Pz += (*Object[i]).pz();
0314 Sum2_E += (*Object[i]).energy();
0315 }
0316 }
0317 }
0318 }
0319 } else {
0320 throw cms::Exception("Configuration") << "Please give a valid hemisphere association method!";
0321 }
0322
0323
0324
0325 Axis1[3] = sqrt(Sum1_Px * Sum1_Px + Sum1_Py * Sum1_Py + Sum1_Pz * Sum1_Pz);
0326 if (Axis1[3] < 0.0001) {
0327 edm::LogWarning("HemisphereAlgo") << "ZERO objects in group 1! ";
0328 } else {
0329 Axis1[0] = Sum1_Px / Axis1[3];
0330 Axis1[1] = Sum1_Py / Axis1[3];
0331 Axis1[2] = Sum1_Pz / Axis1[3];
0332 Axis1[4] = Sum1_E;
0333 }
0334
0335 Axis2[3] = sqrt(Sum2_Px * Sum2_Px + Sum2_Py * Sum2_Py + Sum2_Pz * Sum2_Pz);
0336 if (Axis2[3] < 0.0001) {
0337 edm::LogWarning("HemisphereAlgo") << "ZERO objects in group 2!";
0338 } else {
0339 Axis2[0] = Sum2_Px / Axis2[3];
0340 Axis2[1] = Sum2_Py / Axis2[3];
0341 Axis2[2] = Sum2_Pz / Axis2[3];
0342 Axis2[4] = Sum2_E;
0343 }
0344
0345 LogDebug("HemisphereAlgo") << " Grouping = ";
0346 for (int i = 0; i < vsize; i++) {
0347 LogTrace("HemisphereAlgo") << " " << Object_Group[i];
0348 }
0349 LogTrace("HemisphereAlgo") << std::endl;
0350 }
0351
0352 status = 1;
0353 return 1;
0354 }