ATLAS Offline Software
Loading...
Searching...
No Matches
IParticleCollHandleBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// //
8// Implementation of class IParticleCollHandleBase //
9// //
10// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11// Initial version: February 2008 //
12//
13// Updates:
14// - 2023, Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
15// //
17
18//Local includes
21#include "IParticleHandleBase.h"
23#include "AODSysCommonData.h"
24
25//VP1 base includes
32
33//SoCoin
34#include <Inventor/nodes/SoSeparator.h>
35#include <Inventor/nodes/SoMaterial.h>
36#include <Inventor/nodes/SoSwitch.h>
37#include "Inventor/nodes/SoDrawStyle.h"
38#include "Inventor/nodes/SoLightModel.h"
39
40//Athnea
43
44//Qt
45#include <QComboBox>
46#include <QTreeWidgetItem>
47#include <qdatetime.h>
48#include <vector>
49#include <QString>
50#include <sstream>
51
52//____________________________________________________________________
54public:
56
57 //Vector of iParticle handles:
58 std::vector<IParticleHandleBase*> handles;
59 // QList of xAOD handles
60 QList<AODHandleBase*> handlesList;
61
62 //For iteration:
63 std::vector<IParticleHandleBase*>::iterator itHandles;
64 std::vector<IParticleHandleBase*>::iterator itHandlesEnd;
65
66 // N.B. Material button defined in children.
67};
68
69
70
71//____________________________________________________________________
73const QString& name,
75 : AODCollHandleBase(cd,name,type), m_d(new Imp), // Need to add back ObjectType once simple way to create string is added to xAODBase
79 m_cut_pt_allowall(false),
80 m_cut_eta_allowall(false),
81 m_cut_phi_allowall(false),
83{
84 m_d->theclass = this;
85}
86
87//____________________________________________________________________
89{
90 messageVerbose("destructor start");
91
92 m_d->handles.clear();
93
94 // clean the QList<handle>
95 for(AODHandleBase* handle : m_d->handlesList) {
96 delete handle;
97 }
98
99 // delete the Imp instance
100 delete m_d;
101 messageVerbose("destructor end");
102}
103
104//____________________________________________________________________
106{
107 m_d->handles.reserve(n);
108}
109
110//____________________________________________________________________
112{
113 IParticleHandleBase* handle = dynamic_cast<IParticleHandleBase* >(ah);
114 if (!handle) {
115 message("ERROR - wrong handle type passed to IParticleCollHandleBase::addHandle!");
116 return;
117 }
118 m_d->handles.push_back(handle); // for the vector<handle>
119 m_d->handlesList << handle; // for the QList<handle>
120}
121
122//____________________________________________________________________
124{
125 m_d->itHandles = m_d->handles.begin();
126 m_d->itHandlesEnd = m_d->handles.end();
127}
128
129//____________________________________________________________________
131 if (m_d->itHandles==m_d->itHandlesEnd)
132 // if (m_d->itHandles==m_d->itHandlesEnd || m_d->itHandles!=m_d->handles.begin()) // Only use first handle (for debugging)
133 return 0;
134 else
135 return *(m_d->itHandles++);
136}
137
138//____________________________________________________________________
139QList<AODHandleBase*> IParticleCollHandleBase::getHandlesList() const
140{
141 messageVerbose("AODCollHandleBase::getHandlesList()");
142 return m_d->handlesList;
143}
144
145//____________________________________________________________________
147{
148 messageVerbose("IParticleCollHandleBase::cut()");
149
150 IParticleHandleBase* handle = dynamic_cast<IParticleHandleBase*>(ahand);
151
152 if (!handle) {
153 message("ERROR! IParticleCollHandleBase::cut() - passed in a handle of the wrong type! ");
154 return false;
155 }
156
158 return false;
159
160 messageVerbose("m_cut_pt_allowall: " + QString::number(m_cut_pt_allowall) + " - m_cut_eta_allowall: " + QString::number(m_cut_eta_allowall) + " - m_cut_phi_allowall: " + QString::number(m_cut_phi_allowall) );
161
163 {
164 messageVerbose("evaluating cut...");
165
166 messageVerbose("m_cut_allowedEta: " + m_cut_allowedEta.toString() + " - excludeInterval: " + QString::number(m_cut_allowedEta.excludeInterval()) );
167
168
169 // Trk::GlobalMomentum mom(handle->momentum());
170 Amg::Vector3D mom(handle->momentum());
171 // std::cout<<"mom mag2: "<<mom.mag2()<<std::endl;
172
173 // convention is that if interval is real and negative, then P cut rather than pT
174 bool isPCut = (!m_cut_allowedPtSq.noLowerBound() && m_cut_allowedPtSq.lower()<=0)
175 || (!m_cut_allowedPtSq.noUpperBound() && m_cut_allowedPtSq.upper()<=0);
176
177 messageVerbose("mom.eta(): " + QString::number(mom.eta()) );
178
179 if (mom.mag2()!=0.0) {
180
181 // *** PT CUT ***
182 if (!m_cut_pt_allowall&&!isPCut && !m_cut_allowedPtSq.contains(mom.perp2()))
183 return false;
184 if (!m_cut_pt_allowall&& isPCut && !m_cut_allowedPtSq.contains(-mom.mag2()))
185 return false;
186
187 // *** ETA CUT ***
188 // if (!m_cut_eta_allowall&&!m_cut_allowedEta.contains(mom.pseudoRapidity())){
189 if (!m_cut_eta_allowall && !m_cut_allowedEta.contains(mom.eta())){ // migration to Amg (Eigen)
190 messageVerbose("eta cut not passed...");
191 return false;
192 }
193
194 // *** PHI CUT ***
195 if (!m_cut_phi_allowall) {
196 double phi = VP1LinAlgUtils::phiFromXY(mom.x(), mom.y() );
197 messageVerbose("value oh handle's phi: " + QString::number(phi));
198 bool ok(false);
199 for (const VP1Interval& phirange : m_cut_allowedPhi) {
200 if (phirange.contains(phi)||phirange.contains(phi+2*M_PI)||phirange.contains(phi-2*M_PI)) {
201 ok = true;
202 break;
203 }
204 }
205 if (!ok)
206 return false;
207 }
208 }
209 messageVerbose("IParticleCollHandleBase::cut() - mom.mag2() == 0.0!!!");
210
211 }
212
213 messageVerbose("IParticleCollHandleBase::cut() - Returning true!");
214 return true;
215}
216
217//____________________________________________________________________
219{
220 messageVerbose("IParticleCollHandleBase::setCutAllowedPt()");
221
222 if (!allowedpt.isSane())
223 return;
224
225 //why do we need to do this? Why does it matter if it's negative?
226 //double minptsq = allowedpt.lower() <= 0.0 ? -std::numeric_limits<double>::infinity() : allowedpt.lower()*allowedpt.lower();
227 //VP1Interval allowedptsq(minptsq,allowedpt.upper()*allowedpt.upper());
228
229 //Modified code from EJWM
230 double signMin = allowedpt.lower()<0.0 ? -1.0 : 1.0;
231 double signMax = allowedpt.upper()<0.0 ? -1.0 : 1.0;
232 double minptsq = allowedpt.lower() == -std::numeric_limits<double>::infinity() ? -std::numeric_limits<double>::infinity() : signMin*(allowedpt.lower()*allowedpt.lower());
233 double maxptsq = allowedpt.upper() == std::numeric_limits<double>::infinity() ? std::numeric_limits<double>::infinity() : signMax*(allowedpt.upper()*allowedpt.upper());
234
235 VP1Interval allowedptsq(minptsq,maxptsq);
236 // std::cout<<"allowedptsq:isAllR"<<allowedptsq.isAllR()<<std::endl;
237 // std::cout<<"allowedptsq.isEmpty()"<<allowedptsq.isEmpty()<<std::endl;
238
239
240 if (m_cut_allowedPtSq==allowedptsq)
241 return;
242 m_cut_pt_allowall = allowedptsq.isAllR();
243 m_cut_etaptphi_allwillfail = allowedptsq.isEmpty() || m_cut_allowedEta.isEmpty() || m_cut_allowedPhi.isEmpty();
244
245 if (!m_cut_allowedPtSq.contains(allowedptsq)&&!allowedptsq.contains(m_cut_allowedPtSq)) {
246 m_cut_allowedPtSq = allowedptsq;
248 return;
249 }
250 bool relaxcut = allowedptsq.contains(m_cut_allowedPtSq);
251 m_cut_allowedPtSq = allowedptsq;
252 if (relaxcut)
254 else
256}
257
258//____________________________________________________________________
260{
261 messageVerbose("signal received in setCutAllowedEta ("+allowedEta.toString()+")");
262 if (!allowedEta.isSane())
263 return;
264
265 if (m_cut_allowedEta==allowedEta)
266 return;
267 m_cut_eta_allowall = allowedEta.isAllR();
268 m_cut_etaptphi_allwillfail = allowedEta.isEmpty() || m_cut_allowedPtSq.isEmpty() || m_cut_allowedPhi.isEmpty();
269
270 if (!m_cut_allowedEta.contains(allowedEta)&&!allowedEta.contains(m_cut_allowedEta)) {
271 m_cut_allowedEta = allowedEta;
273 return;
274 }
275 bool relaxcut = allowedEta.contains(m_cut_allowedEta);
276 m_cut_allowedEta = allowedEta;
277 if (relaxcut)
279 else
281}
282
283//____________________________________________________________________
284void IParticleCollHandleBase::setCutAllowedPhi(const QList<VP1Interval>& allowedPhi)
285{
286 messageVerbose("IParticleCollHandleBase::setCutAllowedPhi() - signal received in setCutAllowedPhi.");
287
288 if (m_cut_allowedPhi==allowedPhi)
289 return;
290 m_cut_allowedPhi = allowedPhi;
291
292 m_cut_phi_allowall = m_cut_allowedPhi.count()==1 && m_cut_allowedPhi.at(0).isAllR();
294
295 if (m_cut_phi_allowall) {
297 return;
298 }
301 return;
302 }
304 recheckCutStatusOfAllNotVisibleHandles(); // Redundant, but needed! TODO: check why it is needed. Without this, when disabling and then re-enabling a phi sector, the corresponding jet is not shown, as the handles were not traversed. This fixes ATLASVPONE-626, look at that ticket for details: https://its.cern.ch/jira/browse/ATLASVPONE-626
305 return;
306}
307
308
309//____________________________________________________________________
310void IParticleCollHandleBase::setState(const QByteArray&state)
311{
312 VP1Deserialise des(state);
314 if (des.version()!=0&&des.version()!=1) {
315 messageDebug("Warning: Ignoring state with wrong version");
316 return;
317 }
318 bool vis = des.restoreBool();
319
320 QByteArray matState = des.restoreByteArray();
321 // m_d->matButton->restoreFromState(matState);
322 QByteArray extraWidgetState = des.version()>=1 ? des.restoreByteArray() : QByteArray();
323 setVisible(vis);
324
325 if (extraWidgetState!=QByteArray())
326 setExtraWidgetsState(extraWidgetState);
327}
328
329//____________________________________________________________________
331{
332 messageDebug("IParticleCollHandleBase::persistifiableState() - start...");
333
334 // if (!m_d->matButton) {
335 // message("ERROR: persistifiableState() called before init()");
336 // return QByteArray();
337 // }
338 VP1Serialise serialise(1/*version*/);
339 serialise.disableUnsavedChecks();
340
341 // SAVE THE CHECKED/UNCHECKED STATUS OF THE COLLECTION
342 serialise.save(visible());
343
344 // SAVE THE MATERIAL BUTTON
345 // Q_ASSERT(m_d->matButton&&"Did you forget to call init() on this VP1StdCollection?");
346 // serialise.save(m_d->matButton->saveState());
347
348 // SAVE THE EXTRA-STATES
349 serialise.save(extraWidgetsState());//version 1+
350
351 messageDebug("IParticleCollHandleBase::persistifiableState() - end.");
352 return serialise.result();
353}
#define M_PI
Scalar phi() const
phi method
AODCollHandleBase(AODSysCommonData *, const QString &name, xAOD::Type::ObjectType)
void recheckCutStatusOfAllNotVisibleHandles()
void recheckCutStatusOfAllVisibleHandles()
void setExtraWidgetsState(const QByteArray &)
QByteArray extraWidgetsState() const
const QString & name() const
std::vector< IParticleHandleBase * >::iterator itHandles
std::vector< IParticleHandleBase * > handles
std::vector< IParticleHandleBase * >::iterator itHandlesEnd
virtual void setState(const QByteArray &)
Provide specific implementation.
QList< VP1Interval > m_cut_allowedPhi
IParticleCollHandleBase(AODSysCommonData *, const QString &name, xAOD::Type::ObjectType)
virtual AODHandleBase * getNextHandle()
void setCutAllowedPt(const VP1Interval &)
virtual void hintNumberOfHandlesInEvent(unsigned)
virtual bool cut(AODHandleBase *)
QList< AODHandleBase * > getHandlesList() const
void setCutAllowedPhi(const QList< VP1Interval > &)
void setCutAllowedEta(const VP1Interval &)
virtual QByteArray persistifiableState() const
Provide specific implementation.
virtual Amg::Vector3D momentum() const
QByteArray restoreByteArray()
void disableUnrestoredChecks()
qint32 version() const
void messageVerbose(const QString &) const
void message(const QString &) const
void messageDebug(const QString &) const
double lower() const
bool isEmpty() const
QString toString() const
bool isSane() const
bool isAllR() const
bool contains(const double &x) const
double upper() const
static double phiFromXY(const double &x, const double &y)
Eigen::Matrix< double, 3, 1 > Vector3D
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32