| File: | cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root/TStorage.h |
| Warning: | line 111, column 19 The left operand of '==' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /************************************************************************** | |||
| 2 | * basf2 (Belle II Analysis Software Framework) * | |||
| 3 | * Author: The Belle II Collaboration * | |||
| 4 | * * | |||
| 5 | * See git log for contributors and copyright holders. * | |||
| 6 | * This file is licensed under LGPL-3.0, see LICENSE.md. * | |||
| 7 | **************************************************************************/ | |||
| 8 | ||||
| 9 | #include <alignment/modules/SetRecoTrackMomentum/SetRecoTrackMomentumModule.h> | |||
| 10 | ||||
| 11 | #include <framework/geometry/BFieldManager.h> | |||
| 12 | #include <framework/geometry/B2Vector3.h> | |||
| 13 | ||||
| 14 | using namespace Belle2; | |||
| 15 | ||||
| 16 | //----------------------------------------------------------------- | |||
| 17 | // Register the Module | |||
| 18 | //----------------------------------------------------------------- | |||
| 19 | REG_MODULE(SetRecoTrackMomentum)namespace { struct ModuleProxySetRecoTrackMomentum: public ModuleProxyBase { ModuleProxySetRecoTrackMomentum(): ModuleProxyBase("SetRecoTrackMomentum" , "" "alignment") {} virtual ::Belle2::Module* createInstance () const override final { return new SetRecoTrackMomentumModule (); } } proxySetRecoTrackMomentumModule; }; | |||
| 20 | ||||
| 21 | //----------------------------------------------------------------- | |||
| 22 | // Implementation | |||
| 23 | //----------------------------------------------------------------- | |||
| 24 | ||||
| 25 | SetRecoTrackMomentumModule::SetRecoTrackMomentumModule() : Module() | |||
| 26 | { | |||
| 27 | // Set module properties | |||
| 28 | setDescription(R"DOC(Set momentum magnitude for RecoTracks seed to given value (for runs without magnetic field) | |||
| 29 | ||||
| 30 | Take the momentum direction from seed and update its magnitude to artificial value for all RecoTracks - needed for tracks without magnetic field. | |||
| 31 | By default activated automatically, when zero B-field is detected at the origin | |||
| 32 | )DOC"); | |||
| 33 | ||||
| 34 | // Parameter definitions | |||
| 35 | addParam("automatic", m_automatic, "Detect the B-field at origin automatically - disable module if non-zero", true); | |||
| 36 | addParam("momentum", m_momentum, "Default momentum magnitude (GeV/c) to set for seed of RecoTracks", 10.); | |||
| 37 | ||||
| 38 | } | |||
| 39 | ||||
| 40 | void SetRecoTrackMomentumModule::initialize() | |||
| 41 | { | |||
| 42 | m_tracks.isRequired(); | |||
| 43 | } | |||
| 44 | ||||
| 45 | void SetRecoTrackMomentumModule::event() | |||
| 46 | { | |||
| 47 | // In automatic mode, do nothing if B-field > 0 at origin | |||
| 48 | if (m_automatic && BFieldManager::getInstance().getField(0., 0., 0.).R() > 1.e-14) { | |||
| ||||
| 49 | return; | |||
| 50 | } | |||
| 51 | ||||
| 52 | for (auto& track : m_tracks) { | |||
| 53 | B2Vector3D mom = track.getMomentumSeed(); | |||
| 54 | mom = 1. / mom.Mag() * m_momentum * mom; | |||
| 55 | ||||
| 56 | track.setPositionAndMomentum(track.getPositionSeed(), mom); | |||
| 57 | } | |||
| 58 | } | |||
| 59 | ||||
| 60 |
| 1 | /************************************************************************** |
| 2 | * basf2 (Belle II Analysis Software Framework) * |
| 3 | * Author: The Belle II Collaboration * |
| 4 | * * |
| 5 | * See git log for contributors and copyright holders. * |
| 6 | * This file is licensed under LGPL-3.0, see LICENSE.md. * |
| 7 | **************************************************************************/ |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | #include <framework/datastore/StoreArray.h> |
| 12 | #include <framework/datastore/RelationsObject.h> |
| 13 | #include <framework/core/FrameworkExceptions.h> |
| 14 | #include <framework/geometry/VectorUtil.h> |
| 15 | |
| 16 | #include <genfit/Track.h> |
| 17 | |
| 18 | #include <tracking/dataobjects/RecoHitInformation.h> |
| 19 | |
| 20 | #include <Math/Vector3D.h> |
| 21 | |
| 22 | #include <optional> |
| 23 | #include <string> |
| 24 | #include <vector> |
| 25 | |
| 26 | namespace genfit { |
| 27 | class TrackCand; |
| 28 | class AbsTrackRep; |
| 29 | } |
| 30 | |
| 31 | namespace Belle2 { |
| 32 | |
| 33 | class RecoTrackGenfitAccess; |
| 34 | |
| 35 | BELLE2_DEFINE_EXCEPTION(NoTrackFitResult, "No track fit result available for this hit (e.g. DAF has removed it).")class NoTrackFitResult : public std::runtime_error { public: NoTrackFitResult (): std::runtime_error(""), m_format("No track fit result available for this hit (e.g. DAF has removed it)." ) { } ~NoTrackFitResult() noexcept {} virtual const char * what () const noexcept override { m_finalStr = m_format.str(); return m_finalStr.c_str(); } template <class T> NoTrackFitResult & operator<<(const T& param) { m_format % param ; return *this; } private: boost::format m_format; mutable std ::string m_finalStr; }; |
| 36 | BELLE2_DEFINE_EXCEPTION(NoStateOnPlaneFound, "No measured state on plane for any track point found.")class NoStateOnPlaneFound : public std::runtime_error { public : NoStateOnPlaneFound(): std::runtime_error(""), m_format("No measured state on plane for any track point found." ) { } ~NoStateOnPlaneFound() noexcept {} virtual const char * what() const noexcept override { m_finalStr = m_format.str() ; return m_finalStr.c_str(); } template <class T> NoStateOnPlaneFound & operator<<(const T& param) { m_format % param ; return *this; } private: boost::format m_format; mutable std ::string m_finalStr; }; |
| 37 | |
| 38 | /** This is the Reconstruction Event-Data Model Track. |
| 39 | * |
| 40 | * This class collects hits, saves the track parameters and can be used with a TrackFitter to perform |
| 41 | * fits to the hits. It can be created from a genfit::TrackCand and converted to a genfit::Track, |
| 42 | * but it is better to use this class directly in the modules, because it offers a more datastore-suited interface. |
| 43 | * |
| 44 | * The RecoTrack itself does only store a genfit::Track internally. All hit content is stored as a relation to |
| 45 | * the hits. For each of these relations to a detector hit, there is also a relation to a RecoHitInformation, |
| 46 | * to store additional information. However, the user does not need to access these relation by himself, |
| 47 | * but can use the accessor functions of the RecoTrack. |
| 48 | * |
| 49 | * Typically, a RecoTrack object is created with a position and momentum seed and a charge. |
| 50 | * |
| 51 | * RecoTrack recoTrack(position, momentum, charge, ...) |
| 52 | * |
| 53 | * Then, hits are added |
| 54 | * |
| 55 | * recoTrack.addCDCHit(cdcHit, rlInformation, ...) |
| 56 | * .... |
| 57 | * |
| 58 | * After that, the hits can either be accessed: |
| 59 | * |
| 60 | * recoTrack.getCDCHitList(); |
| 61 | * recoTrack.getRightLeftInformation(cdcHit); |
| 62 | * |
| 63 | * or the track can be fitted: |
| 64 | * |
| 65 | * TrackFitter fitter; |
| 66 | * fitter.fit(recoTrack); |
| 67 | * |
| 68 | * See also the TrackFitter class for possibilities to fit. After the track is fitted properly, the |
| 69 | * hit points with measurements can be used to extrapolate the track |
| 70 | * |
| 71 | * recoTrack.getHitPointsWithMeasurement(); |
| 72 | * |
| 73 | * See the recoTrack.cc test for an overview on the hit information accessor methods. |
| 74 | */ |
| 75 | class RecoTrack : public RelationsObject { |
| 76 | /// The RecoTrackGenfitAccess need to access the genfit track (which is intended)! |
| 77 | friend class RecoTrackGenfitAccess; |
| 78 | |
| 79 | private: |
| 80 | /// Copy the definitions from the RecoHitInformation to this class. |
| 81 | typedef RecoHitInformation::RightLeftInformation RightLeftInformation; |
| 82 | /// Copy the definitions from the RecoHitInformation to this class. |
| 83 | typedef RecoHitInformation::RecoHitDetector TrackingDetector; |
| 84 | /// Copy the definitions from the RecoHitInformation to this class. |
| 85 | typedef RecoHitInformation::OriginTrackFinder OriginTrackFinder; |
| 86 | /// Copy the definitions from the RecoHitInformation to this class. |
| 87 | typedef RecoHitInformation::UsedCDCHit UsedCDCHit; |
| 88 | /// Copy the definitions from the RecoHitInformation to this class. |
| 89 | typedef RecoHitInformation::UsedSVDHit UsedSVDHit; |
| 90 | /// Copy the definitions from the RecoHitInformation to this class. |
| 91 | typedef RecoHitInformation::UsedPXDHit UsedPXDHit; |
| 92 | /// Copy the definitions from the RecoHitInformation to this class. |
| 93 | typedef RecoHitInformation::UsedBKLMHit UsedBKLMHit; |
| 94 | /// Copy the definitions from the RecoHitInformation to this class. |
| 95 | typedef RecoHitInformation::UsedEKLMHit UsedEKLMHit; |
| 96 | |
| 97 | public: |
| 98 | /** |
| 99 | * Enum for the matching status of this reco track (set by the matching modules in the tracking package). |
| 100 | */ |
| 101 | enum MatchingStatus { |
| 102 | c_undefined, //until the matcher module sets it |
| 103 | c_matched, // hit pattern and charge are both correct |
| 104 | c_matchedWrongCharge, // hit pattern is correct, but the charge is wrong |
| 105 | c_clone, //a clone with the correct charge |
| 106 | c_cloneWrongCharge, //a clone with the wrong charge |
| 107 | c_background, |
| 108 | c_ghost |
| 109 | }; |
| 110 | |
| 111 | /** |
| 112 | * Convenience method which registers all relations required to fully use |
| 113 | * a RecoTrack. If you create a new RecoTrack StoreArray, call this method |
| 114 | * in the initialize() method of your module. Note that the BKLM and EKLM |
| 115 | * relations may not be registered because the KLM modules are loaded after |
| 116 | * tracking; in this case, a second call of this method is required after |
| 117 | * creation of the BKLM and EKLM hits store arrays. |
| 118 | * @param recoTracks Reference to the store array where the new RecoTrack list is located |
| 119 | * @param pxdHitsStoreArrayName name of the StoreArray holding the PXDClusters lists |
| 120 | * @param svdHitsStoreArrayName name of the StoreArray holding the SVDClusters lists |
| 121 | * @param cdcHitsStoreArrayName name of the StoreArray holding the CDCHits lists |
| 122 | * @param bklmHitsStoreArrayName name of the StoreArray holding the BKLMHits lists |
| 123 | * @param eklmHitsStoreArrayName name of the StoreArray holding the EKLMHits lists |
| 124 | * @param recoHitInformationStoreArrayName name of the StoreArray holding RecoHitInformation lists |
| 125 | */ |
| 126 | static void registerRequiredRelations( |
| 127 | StoreArray<RecoTrack>& recoTracks, |
| 128 | std::string const& pxdHitsStoreArrayName = "", |
| 129 | std::string const& svdHitsStoreArrayName = "", |
| 130 | std::string const& cdcHitsStoreArrayName = "", |
| 131 | std::string const& bklmHitsStoreArrayName = "", |
| 132 | std::string const& eklmHitsStoreArrayName = "", |
| 133 | std::string const& recoHitInformationStoreArrayName = ""); |
| 134 | |
| 135 | /// Empty constructor for ROOT. Do not use! |
| 136 | RecoTrack() { } |
| 137 | |
| 138 | /** |
| 139 | * Construct a RecoTrack with the given seed helix parameters and the given names for the hits. |
| 140 | * If you do not provide information for the hit store array names, the standard parameters are used. |
| 141 | * @param seedPosition A position on the helix of the track seed. Only the perigee of the helix will be saved. |
| 142 | * @param seedMomentum The seed momentum of the helix on the given position. |
| 143 | * @param seedCharge The seed charge of the helix |
| 144 | * @param storeArrayNameOfPXDHits The name of the store array where the related PXD hits are stored. |
| 145 | * @param storeArrayNameOfSVDHits The name of the store array where the related SVD hits are stored. |
| 146 | * @param storeArrayNameOfCDCHits The name of the store array where the related CDC hits are stored. |
| 147 | * @param storeArrayNameOfBKLMHits The name of the store array where the related BKLM hits are stored. |
| 148 | * @param storeArrayNameOfEKLMHits The name of the store array where the related EKLM hits are stored. |
| 149 | * @param storeArrayNameOfRecoHitInformation The name of the store array where the related hit information are stored. |
| 150 | */ |
| 151 | RecoTrack(const ROOT::Math::XYZVector& seedPosition, const ROOT::Math::XYZVector& seedMomentum, const short int seedCharge, |
| 152 | const std::string& storeArrayNameOfPXDHits = "", |
| 153 | const std::string& storeArrayNameOfSVDHits = "", |
| 154 | const std::string& storeArrayNameOfCDCHits = "", |
| 155 | const std::string& storeArrayNameOfBKLMHits = "", |
| 156 | const std::string& storeArrayNameOfEKLMHits = "", |
| 157 | const std::string& storeArrayNameOfRecoHitInformation = ""); |
| 158 | |
| 159 | /** Delete the copy construtr. */ |
| 160 | RecoTrack(const RecoTrack&) = delete; |
| 161 | /** Delete the copy construtr. */ |
| 162 | RecoTrack& operator=(RecoTrack const&) = delete; |
| 163 | |
| 164 | /** |
| 165 | * Create a reco track from a genfit::TrackCand and save it to the given store array. |
| 166 | * @param trackCand The genfit::TrackCand from which to create the new object. |
| 167 | * @param storeArrayNameOfRecoTracks The store array where the new object should be saved. |
| 168 | * @param storeArrayNameOfPXDHits The name of the store array where the related PXD hits are stored. |
| 169 | * @param storeArrayNameOfSVDHits The name of the store array where the related SVD hits are stored. |
| 170 | * @param storeArrayNameOfCDCHits The name of the store array where the related CDC hits are stored. |
| 171 | * @param storeArrayNameOfBKLMHits The name of the store array where the related BKLM hits are stored. |
| 172 | * @param storeArrayNameOfEKLMHits The name of the store array where the related EKLM hits are stored. |
| 173 | * @param storeArrayNameOfRecoHitInformation The name of the store array where the related hit information are stored. |
| 174 | * @param recreateSortingParameters The VXDTF does not set the sorting parameters correctly (they are all 0). |
| 175 | * This flag can be used to recover the parameters. |
| 176 | * @return The newly created reco track. |
| 177 | * @todo Let the track finders determine the cov seed. |
| 178 | */ |
| 179 | static RecoTrack* createFromTrackCand(const genfit::TrackCand& trackCand, |
| 180 | const std::string& storeArrayNameOfRecoTracks = "", |
| 181 | const std::string& storeArrayNameOfPXDHits = "", |
| 182 | const std::string& storeArrayNameOfSVDHits = "", |
| 183 | const std::string& storeArrayNameOfCDCHits = "", |
| 184 | const std::string& storeArrayNameOfBKLMHits = "", |
| 185 | const std::string& storeArrayNameOfEKLMHits = "", |
| 186 | const std::string& storeArrayNameOfRecoHitInformation = "", |
| 187 | const bool recreateSortingParameters = false |
| 188 | ); |
| 189 | |
| 190 | /** |
| 191 | * Create a genfit::TrackCand out of this reco track and copy all information to the track candidate. |
| 192 | */ |
| 193 | genfit::TrackCand createGenfitTrackCand() const; |
| 194 | |
| 195 | /** |
| 196 | * Append a new RecoTrack to the given store array and copy its general properties, but not the hits themself. |
| 197 | * The position, momentum, charge etc. are set to the given parameters. |
| 198 | */ |
| 199 | RecoTrack* copyToStoreArrayUsing(StoreArray<RecoTrack>& storeArray, const ROOT::Math::XYZVector& position, |
| 200 | const ROOT::Math::XYZVector& momentum, short charge, |
| 201 | const TMatrixDSym& covariance, double timeSeed) const; |
| 202 | |
| 203 | /** |
| 204 | * Append a new RecoTrack to the given store array and copy its general properties, but not the hits themself. |
| 205 | * The position, momentum and charge are set to the seed values of this reco track. |
| 206 | */ |
| 207 | RecoTrack* copyToStoreArrayUsingSeeds(StoreArray<RecoTrack>& storeArray) const; |
| 208 | |
| 209 | /** |
| 210 | * Append a new RecoTrack to the given store array and copy its general properties, but not the hits themself. |
| 211 | * The position, momentum and charge are set to the seed values of this reco track, if it was not fitted |
| 212 | * or to the values at the first hit. |
| 213 | */ |
| 214 | RecoTrack* copyToStoreArray(StoreArray<RecoTrack>& storeArray) const; |
| 215 | |
| 216 | /** |
| 217 | * Add all hits from another RecoTrack to this RecoTrack. |
| 218 | * @param recoTrack : Pointer to the RecoTrack where the hits are copied from |
| 219 | * @param sortingParameterOffset : This number will be added to the sortingParameter of all hits copied |
| 220 | * from recoTrack. Set this to (largest sorting parameter) + 1 in order to add hits at the end of |
| 221 | * this reco track. |
| 222 | * @param reversed : add the hits in a reversed order - each sorting parameter is set to |
| 223 | * maximal sorting parameter - sorting parameter + offset |
| 224 | * @param optionalMinimalWeight : if set, do only copy hits with a weight above this (if fitted already with the DAF). |
| 225 | * @return The number of hits copied. |
| 226 | */ |
| 227 | size_t addHitsFromRecoTrack(const RecoTrack* recoTrack, unsigned int sortingParameterOffset = 0, |
| 228 | bool reversed = false, std::optional<double> optionalMinimalWeight = std::nullopt); |
| 229 | |
| 230 | /** |
| 231 | * Adds a cdc hit with the given information to the reco track. |
| 232 | * You only have to provide the hit and the sorting parameter, all other parameters have default value. |
| 233 | * @param cdcHit The pointer to a stored CDCHit in the store array you provided earlier, which you want to add. |
| 234 | * @param sortingParameter The index of the hit. It starts with 0 with the first hit. |
| 235 | * @param rightLeftInformation The right left information (if you know it). |
| 236 | * @param foundByTrackFinder Which track finder has found the hit? |
| 237 | * @return True if the hit was not already added to the track. |
| 238 | */ |
| 239 | bool addCDCHit(const UsedCDCHit* cdcHit, const unsigned int sortingParameter, |
| 240 | RightLeftInformation rightLeftInformation = RightLeftInformation::c_undefinedRightLeftInformation, |
| 241 | OriginTrackFinder foundByTrackFinder = OriginTrackFinder::c_undefinedTrackFinder) |
| 242 | { |
| 243 | return addHit(cdcHit, rightLeftInformation, foundByTrackFinder, sortingParameter); |
| 244 | } |
| 245 | |
| 246 | /** |
| 247 | * Adds a pxd hit with the given information to the reco track. |
| 248 | * You only have to provide the hit and the sorting parameter, all other parameters have default value. |
| 249 | * @param pxdHit The pointer to a stored PXDHit/Cluster in the store array you provided earlier, which you want to add. |
| 250 | * @param sortingParameter The index of the hit. It starts with 0 with the first hit. |
| 251 | * @param foundByTrackFinder Which track finder has found the hit? |
| 252 | * @return True if the hit was not already added to the track. |
| 253 | */ |
| 254 | bool addPXDHit(const UsedPXDHit* pxdHit, const unsigned int sortingParameter, |
| 255 | OriginTrackFinder foundByTrackFinder = OriginTrackFinder::c_undefinedTrackFinder) |
| 256 | { |
| 257 | return addHit(pxdHit, foundByTrackFinder, sortingParameter); |
| 258 | } |
| 259 | |
| 260 | /** |
| 261 | * Adds a svd hit with the given information to the reco track. |
| 262 | * You only have to provide the hit and the sorting parameter, all other parameters have default value. |
| 263 | * @param svdHit The pointer to a stored SVDHit in the store array you provided earlier, which you want to add. |
| 264 | * @param sortingParameter The index of the hit. It starts with 0 with the first hit. |
| 265 | * @param foundByTrackFinder Which track finder has found the hit? |
| 266 | * @return True if the hit was not already added to the track. |
| 267 | */ |
| 268 | bool addSVDHit(const UsedSVDHit* svdHit, const unsigned int sortingParameter, |
| 269 | OriginTrackFinder foundByTrackFinder = OriginTrackFinder::c_undefinedTrackFinder) |
| 270 | { |
| 271 | return addHit(svdHit, foundByTrackFinder, sortingParameter); |
| 272 | } |
| 273 | |
| 274 | /** |
| 275 | * Adds a bklm hit with the given information to the reco track. |
| 276 | * You only have to provide the hit and the sorting parameter, all other parameters have default value. |
| 277 | * @param bklmHit The pointer to a stored BKLMHit in the store array you provided earlier, which you want to add. |
| 278 | * @param sortingParameter The index of the hit. It starts with 0 with the first hit. |
| 279 | * @param foundByTrackFinder Which track finder has found the hit? |
| 280 | * @return True if the hit was not already added to the track. |
| 281 | */ |
| 282 | bool addBKLMHit(const UsedBKLMHit* bklmHit, const unsigned int sortingParameter, |
| 283 | OriginTrackFinder foundByTrackFinder = OriginTrackFinder::c_undefinedTrackFinder) |
| 284 | { |
| 285 | return addHit(bklmHit, foundByTrackFinder, sortingParameter); |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * Adds an eklm hit with the given information to the reco track. |
| 290 | * You only have to provide the hit and the sorting parameter, all other parameters have default value. |
| 291 | * @param eklmHit The pointer to a stored BKLMHit in the store array you provided earlier, which you want to add. |
| 292 | * @param sortingParameter The index of the hit. It starts with 0 with the first hit. |
| 293 | * @param foundByTrackFinder Which track finder has found the hit? |
| 294 | * @return True if the hit was not already added to the track. |
| 295 | */ |
| 296 | bool addEKLMHit(const UsedEKLMHit* eklmHit, const unsigned int sortingParameter, |
| 297 | OriginTrackFinder foundByTrackFinder = OriginTrackFinder::c_undefinedTrackFinder) |
| 298 | { |
| 299 | return addHit(eklmHit, foundByTrackFinder, sortingParameter); |
| 300 | } |
| 301 | |
| 302 | /** |
| 303 | * Return the reco hit information for a generic hit from the storeArray. |
| 304 | * @param hit the hit to look for. |
| 305 | * @return The connected RecoHitInformation or a nullptr when the hit is not connected to the track. |
| 306 | */ |
| 307 | template<class HitType> |
| 308 | RecoHitInformation* getRecoHitInformation(HitType* hit) const |
| 309 | { |
| 310 | RelationVector<RecoHitInformation> relatedHitInformationToHit = hit->template getRelationsFrom<RecoHitInformation> |
| 311 | (m_storeArrayNameOfRecoHitInformation); |
| 312 | |
| 313 | for (RecoHitInformation& recoHitInformation : relatedHitInformationToHit) { |
| 314 | // cppcheck-suppress useStlAlgorithm |
| 315 | if (recoHitInformation.getRelatedFrom<RecoTrack>(this->getArrayName()) == this) { |
| 316 | // cppcheck-suppress returnDanglingLifetime |
| 317 | return &recoHitInformation; |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | return nullptr; |
| 322 | } |
| 323 | |
| 324 | // Hits Information Questioning |
| 325 | /// Return the tracking detector of a given hit (every type) or throws an exception of the hit is not related to the track. |
| 326 | template <class HitType> |
| 327 | TrackingDetector getTrackingDetector(const HitType* hit) const |
| 328 | { |
| 329 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 330 | return recoHitInformation->getTrackingDetector(); |
| 331 | } |
| 332 | |
| 333 | /// Return the right left information of a given hit (every type) or throws an exception of the hit is not related to the track. |
| 334 | template <class HitType> |
| 335 | RightLeftInformation getRightLeftInformation(const HitType* hit) const |
| 336 | { |
| 337 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 338 | return recoHitInformation->getRightLeftInformation(); |
| 339 | } |
| 340 | |
| 341 | /// Return the found by track finder flag for the given hit (every type) or throws an exception of the hit is not related to the track. |
| 342 | template <class HitType> |
| 343 | OriginTrackFinder getFoundByTrackFinder(const HitType* hit) const |
| 344 | { |
| 345 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 346 | return recoHitInformation->getFoundByTrackFinder(); |
| 347 | } |
| 348 | |
| 349 | /// Return the sorting parameter for a given hit (every type) or throws an exception of the hit is not related to the track. |
| 350 | template <class HitType> |
| 351 | unsigned int getSortingParameter(const HitType* hit) const |
| 352 | { |
| 353 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 354 | return recoHitInformation->getSortingParameter(); |
| 355 | } |
| 356 | |
| 357 | /// Set the right left information or throws an exception of the hit is not related to the track. Will set the dirty flag! |
| 358 | template <class HitType> |
| 359 | void setRightLeftInformation(const HitType* hit, RightLeftInformation rightLeftInformation) |
| 360 | { |
| 361 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 362 | recoHitInformation->setRightLeftInformation(rightLeftInformation); |
| 363 | setDirtyFlag(); |
| 364 | } |
| 365 | |
| 366 | /// Set the found by track finder flag or throws an exception of the hit is not related to the track. |
| 367 | template <class HitType> |
| 368 | void setFoundByTrackFinder(const HitType* hit, OriginTrackFinder originTrackFinder) |
| 369 | { |
| 370 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 371 | recoHitInformation->setFoundByTrackFinder(originTrackFinder); |
| 372 | } |
| 373 | |
| 374 | /// Set the sorting parameter or throws an exception of the hit is not related to the track. Will set the dirty flag! |
| 375 | template <class HitType> |
| 376 | void setSortingParameter(const HitType* hit, unsigned int sortingParameter) |
| 377 | { |
| 378 | RecoHitInformation* recoHitInformation = getRecoHitInformationSafely(hit); |
| 379 | recoHitInformation->setSortingParameter(sortingParameter); |
| 380 | setDirtyFlag(); |
| 381 | } |
| 382 | |
| 383 | /** Get a pointer to the TrackPoint that was created from this hit. Can be a nullptr if no measurement was already created. |
| 384 | * Please be aware that refitting may or may not recreate the track points and older pointers can be invalidated. |
| 385 | * Also, pruning a RecoTrack will also delete most of the TrackPoints. |
| 386 | */ |
| 387 | const genfit::TrackPoint* getCreatedTrackPoint(const RecoHitInformation* recoHitInformation) const; |
| 388 | |
| 389 | // Hits Added Questioning |
| 390 | /// Returns true if the track has pxd hits. |
| 391 | bool hasPXDHits() const { return getRelatedFrom<UsedPXDHit>(m_storeArrayNameOfPXDHits) != nullptr; } |
| 392 | |
| 393 | /// Returns true if the track has svd hits. |
| 394 | bool hasSVDHits() const { return getRelatedFrom<UsedSVDHit>(m_storeArrayNameOfSVDHits) != nullptr; } |
| 395 | |
| 396 | /// Returns true if the track has cdc hits. |
| 397 | bool hasCDCHits() const { return getRelatedFrom<UsedCDCHit>(m_storeArrayNameOfCDCHits) != nullptr; } |
| 398 | |
| 399 | /// Returns true if the track has bklm hits. |
| 400 | bool hasBKLMHits() const { return getRelatedFrom<UsedBKLMHit>(m_storeArrayNameOfBKLMHits) != nullptr; } |
| 401 | |
| 402 | /// Returns true if the track has eklm hits. |
| 403 | bool hasEKLMHits() const { return getRelatedFrom<UsedEKLMHit>(m_storeArrayNameOfEKLMHits) != nullptr; } |
| 404 | |
| 405 | /// Returns true if the given hit is in the track. |
| 406 | template <class HitType> |
| 407 | bool hasHit(const HitType* hit) const |
| 408 | { |
| 409 | const RelationVector<RecoTrack>& relatedTracksToHit = hit->template getRelationsTo<RecoTrack>(getArrayName()); |
| 410 | return std::find_if(relatedTracksToHit.begin(), relatedTracksToHit.end(), [this](const RecoTrack & recoTrack) { |
| 411 | return &recoTrack == this; |
| 412 | }) != relatedTracksToHit.end(); |
| 413 | } |
| 414 | |
| 415 | // Hits Questioning |
| 416 | /// Return the number of pxd hits. |
| 417 | unsigned int getNumberOfPXDHits() const { return getNumberOfHitsOfGivenType<UsedPXDHit>(m_storeArrayNameOfPXDHits); } |
| 418 | |
| 419 | /// Return the number of svd hits. |
| 420 | unsigned int getNumberOfSVDHits() const { return getNumberOfHitsOfGivenType<UsedSVDHit>(m_storeArrayNameOfSVDHits); } |
| 421 | |
| 422 | /// Return the number of cdc hits. |
| 423 | unsigned int getNumberOfCDCHits() const { return getNumberOfHitsOfGivenType<UsedCDCHit>(m_storeArrayNameOfCDCHits); } |
| 424 | |
| 425 | /// Return the number of bklm hits. |
| 426 | unsigned int getNumberOfBKLMHits() const { return getNumberOfHitsOfGivenType<UsedBKLMHit>(m_storeArrayNameOfBKLMHits); } |
| 427 | |
| 428 | /// Return the number of eklm hits. |
| 429 | unsigned int getNumberOfEKLMHits() const { return getNumberOfHitsOfGivenType<UsedEKLMHit>(m_storeArrayNameOfEKLMHits); } |
| 430 | |
| 431 | /// Return the number of cdc + svd + pxd + bklm + eklm hits. |
| 432 | unsigned int getNumberOfTotalHits() const |
| 433 | { |
| 434 | return getNumberOfPXDHits() + getNumberOfSVDHits() + getNumberOfCDCHits() + |
| 435 | getNumberOfBKLMHits() + getNumberOfEKLMHits(); |
| 436 | } |
| 437 | |
| 438 | /// Return the number of cdc + svd + pxd hits. |
| 439 | unsigned int getNumberOfTrackingHits() const |
| 440 | { |
| 441 | return getNumberOfPXDHits() + getNumberOfSVDHits() + getNumberOfCDCHits(); |
| 442 | } |
| 443 | |
| 444 | /// Return an unsorted list of pxd hits. |
| 445 | std::vector<Belle2::RecoTrack::UsedPXDHit*> getPXDHitList() const { return getHitList<UsedPXDHit>(m_storeArrayNameOfPXDHits); } |
| 446 | |
| 447 | /// Return an unsorted list of svd hits. |
| 448 | std::vector<Belle2::RecoTrack::UsedSVDHit*> getSVDHitList() const { return getHitList<UsedSVDHit>(m_storeArrayNameOfSVDHits); } |
| 449 | |
| 450 | /// Return an unsorted list of cdc hits. |
| 451 | std::vector<Belle2::RecoTrack::UsedCDCHit*> getCDCHitList() const { return getHitList<UsedCDCHit>(m_storeArrayNameOfCDCHits); } |
| 452 | |
| 453 | /// Return an unsorted list of bklm hits. |
| 454 | std::vector<Belle2::RecoTrack::UsedBKLMHit*> getBKLMHitList() const { return getHitList<UsedBKLMHit>(m_storeArrayNameOfBKLMHits); } |
| 455 | |
| 456 | /// Return an unsorted list of eklm hits. |
| 457 | std::vector<Belle2::RecoTrack::UsedEKLMHit*> getEKLMHitList() const { return getHitList<UsedEKLMHit>(m_storeArrayNameOfEKLMHits); } |
| 458 | |
| 459 | /// Return a sorted list of pxd hits. Sorted by the sortingParameter. |
| 460 | std::vector<Belle2::RecoTrack::UsedPXDHit*> getSortedPXDHitList() const { return getSortedHitList<UsedPXDHit>(m_storeArrayNameOfPXDHits); } |
| 461 | |
| 462 | /// Return a sorted list of svd hits. Sorted by the sortingParameter. |
| 463 | std::vector<Belle2::RecoTrack::UsedSVDHit*> getSortedSVDHitList() const { return getSortedHitList<UsedSVDHit>(m_storeArrayNameOfSVDHits); } |
| 464 | |
| 465 | /// Return a sorted list of cdc hits. Sorted by the sortingParameter. |
| 466 | std::vector<Belle2::RecoTrack::UsedCDCHit*> getSortedCDCHitList() const { return getSortedHitList<UsedCDCHit>(m_storeArrayNameOfCDCHits); } |
| 467 | |
| 468 | /// Return a sorted list of bklm hits. Sorted by the sortingParameter. |
| 469 | std::vector<Belle2::RecoTrack::UsedBKLMHit*> getSortedBKLMHitList() const { return getSortedHitList<UsedBKLMHit>(m_storeArrayNameOfBKLMHits); } |
| 470 | |
| 471 | /// Return a sorted list of eklm hits. Sorted by the sortingParameter. |
| 472 | std::vector<Belle2::RecoTrack::UsedEKLMHit*> getSortedEKLMHitList() const { return getSortedHitList<UsedEKLMHit>(m_storeArrayNameOfEKLMHits); } |
| 473 | |
| 474 | // Seed Helix Functionality |
| 475 | /// Return the position seed stored in the reco track. ATTENTION: This is not the fitted position. |
| 476 | ROOT::Math::XYZVector getPositionSeed() const |
| 477 | { |
| 478 | const TVectorD& seed = m_genfitTrack.getStateSeed(); |
| 479 | return ROOT::Math::XYZVector(seed(0), seed(1), seed(2)); |
| 480 | } |
| 481 | |
| 482 | /// Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum. |
| 483 | ROOT::Math::XYZVector getMomentumSeed() const |
| 484 | { |
| 485 | const TVectorD& seed = m_genfitTrack.getStateSeed(); |
| 486 | return ROOT::Math::XYZVector(seed(3), seed(4), seed(5)); |
| 487 | } |
| 488 | |
| 489 | /// Return the state seed in the form posX, posY, posZ, momX, momY, momZ. ATTENTION: This is not the fitted state. |
| 490 | const TVectorD& getStateSeed() const |
| 491 | { |
| 492 | return m_genfitTrack.getStateSeed(); |
| 493 | } |
| 494 | |
| 495 | /** |
| 496 | * Returns genfit track. |
| 497 | * const casting of the return reference is forbidden! |
| 498 | * If you need to modify genfit track, please use RecoTrackGenfitAccess::getGenfitTrack(RecoTrack& recoTrack). |
| 499 | * @return const reference to genfit track |
| 500 | */ |
| 501 | const genfit::Track& getGenfitTrack() const {return m_genfitTrack;} |
| 502 | |
| 503 | /// Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge. |
| 504 | short int getChargeSeed() const { return m_charge; } |
| 505 | |
| 506 | /// Return the time seed stored in the reco track. ATTENTION: This is not the fitted time. |
| 507 | double getTimeSeed() const { return m_genfitTrack.getTimeSeed(); } |
| 508 | |
| 509 | /// Return the track time of the outgoing arm |
| 510 | float getOutgoingArmTime() |
| 511 | { |
| 512 | if (!m_isArmTimeComputed) estimateArmTime(); |
| 513 | return m_outgoingArmTime; |
| 514 | } |
| 515 | |
| 516 | /// Return the error of the track time of the outgoing arm |
| 517 | float getOutgoingArmTimeError() |
| 518 | { |
| 519 | if (!m_isArmTimeComputed) estimateArmTime(); |
| 520 | return m_outgoingArmTimeError; |
| 521 | } |
| 522 | |
| 523 | /// Return the track time of the ingoing arm |
| 524 | float getIngoingArmTime() |
| 525 | { |
| 526 | if (!m_isArmTimeComputed) estimateArmTime(); |
| 527 | return m_ingoingArmTime; |
| 528 | } |
| 529 | |
| 530 | /// Return the error of the track time of the ingoing arm |
| 531 | float getIngoingArmTimeError() |
| 532 | { |
| 533 | if (!m_isArmTimeComputed) estimateArmTime(); |
| 534 | return m_ingoingArmTimeError; |
| 535 | } |
| 536 | |
| 537 | /// Return the difference between the track times of the ingoing and outgoing arms |
| 538 | float getInOutArmTimeDifference() |
| 539 | { |
| 540 | if (!m_isArmTimeComputed) estimateArmTime(); |
| 541 | return m_ingoingArmTime - m_outgoingArmTime; |
| 542 | } |
| 543 | |
| 544 | /// Return the error of the difference between the track times of the ingoing and outgoing arms |
| 545 | float getInOutArmTimeDifferenceError() |
| 546 | { |
| 547 | if (!m_isArmTimeComputed) estimateArmTime(); |
| 548 | return std::sqrt(m_ingoingArmTimeError * m_ingoingArmTimeError + m_outgoingArmTimeError * |
| 549 | m_outgoingArmTimeError); |
| 550 | } |
| 551 | |
| 552 | /// Check if the ingoing arm time is set |
| 553 | bool hasIngoingArmTime() |
| 554 | { |
| 555 | return m_hasIngoingArmTime; |
| 556 | } |
| 557 | |
| 558 | /// Check if the outgoing arm time is set |
| 559 | bool hasOutgoingArmTime() |
| 560 | { |
| 561 | return m_hasOutgoingArmTime; |
| 562 | } |
| 563 | |
| 564 | /// Return the number of clusters used to estimate the outgoing arm time |
| 565 | int getNSVDHitsOfOutgoingArm() |
| 566 | { |
| 567 | return m_nSVDHitsOfOutgoingArm; |
| 568 | } |
| 569 | |
| 570 | /// Return the number of clusters used to estimate the ingoing arm time |
| 571 | int getNSVDHitsOfIngoingArm() |
| 572 | { |
| 573 | return m_nSVDHitsOfIngoingArm; |
| 574 | } |
| 575 | |
| 576 | /** Flip the direction of the RecoTrack by inverting the momentum vector and the charge. |
| 577 | * In addition, also the ingoing and outgoing arms and arm times are swapped. |
| 578 | * @param representation Track representation to be used to get the MeasuredStateOnPlane at the last hit |
| 579 | */ |
| 580 | void flipTrackDirectionAndCharge(const genfit::AbsTrackRep* representation = nullptr); |
| 581 | |
| 582 | /// Return the position, the momentum and the charge of the first measured state on plane or - if unfitted - the seeds. |
| 583 | std::tuple<ROOT::Math::XYZVector, ROOT::Math::XYZVector, short> extractTrackState() const; |
| 584 | |
| 585 | /// Set the position and momentum seed of the reco track. ATTENTION: This is not the fitted position or momentum. |
| 586 | void setPositionAndMomentum(const ROOT::Math::XYZVector& positionSeed, const ROOT::Math::XYZVector& momentumSeed) |
| 587 | { |
| 588 | m_genfitTrack.setStateSeed(XYZToTVector(positionSeed), XYZToTVector(momentumSeed)); |
| 589 | deleteFittedInformation(); |
| 590 | } |
| 591 | |
| 592 | /// Set the charge seed stored in the reco track. ATTENTION: This is not the fitted charge. |
| 593 | void setChargeSeed(const short int chargeSeed) |
| 594 | { |
| 595 | m_charge = chargeSeed; |
| 596 | deleteFittedInformation(); |
| 597 | } |
| 598 | |
| 599 | /// Set the time seed. ATTENTION: This is not the fitted time. |
| 600 | void setTimeSeed(const double timeSeed) |
| 601 | { |
| 602 | m_genfitTrack.setTimeSeed(timeSeed); |
| 603 | deleteFittedInformation(); |
| 604 | } |
| 605 | |
| 606 | /// Return the covariance matrix of the seed. ATTENTION: This is not the fitted covariance. |
| 607 | const TMatrixDSym& getSeedCovariance() const { return m_genfitTrack.getCovSeed(); } |
| 608 | |
| 609 | /// Set the covariance of the seed. ATTENTION: This is not the fitted covariance. |
| 610 | void setSeedCovariance(const TMatrixDSym& seedCovariance) { m_genfitTrack.setCovSeed(seedCovariance); } |
| 611 | |
| 612 | // Fitting |
| 613 | /// Returns true if the last fit with the given representation was successful. |
| 614 | bool wasFitSuccessful(const genfit::AbsTrackRep* representation = nullptr) const; |
| 615 | |
| 616 | /// Return the track fit status for the given representation or for the cardinal one. You are not allowed to modify or delete it! |
| 617 | const genfit::FitStatus* getTrackFitStatus(const genfit::AbsTrackRep* representation = nullptr) const |
| 618 | { |
| 619 | checkDirtyFlag(); |
| 620 | return m_genfitTrack.getFitStatus(representation); |
| 621 | } |
| 622 | |
| 623 | /// Check, if there is a fit status for the given representation or for the cardinal one. |
| 624 | bool hasTrackFitStatus(const genfit::AbsTrackRep* representation = nullptr) const; |
| 625 | |
| 626 | /// Get a pointer to the cardinal track representation. You are not allowed to modify or delete it! |
| 627 | genfit::AbsTrackRep* getCardinalRepresentation() const |
| 628 | { |
| 629 | checkDirtyFlag(); |
| 630 | return m_genfitTrack.getCardinalRep(); |
| 631 | } |
| 632 | |
| 633 | /// Return a list of track representations. You are not allowed to modify or delete them! |
| 634 | const std::vector<genfit::AbsTrackRep*>& getRepresentations() const |
| 635 | { |
| 636 | checkDirtyFlag(); |
| 637 | return m_genfitTrack.getTrackReps(); |
| 638 | } |
| 639 | |
| 640 | /** Return an already created track representation of the given reco track for the PDG. You |
| 641 | * are not allowed to modify this TrackRep! Will return nulltpr if a trackRep is not available |
| 642 | * for the given pdgCode. |
| 643 | * |
| 644 | * @param pdgCode PDG code of the track representations, only positive PDG numbers are allowed |
| 645 | */ |
| 646 | genfit::AbsTrackRep* getTrackRepresentationForPDG(int pdgCode) const; |
| 647 | |
| 648 | /** |
| 649 | * Return a list of all RecoHitInformations associated with the RecoTrack. This is especially useful when |
| 650 | * you want to iterate over all (fitted) hits in a track without caring whether its a CDC, VXD etc hit. |
| 651 | * @param getSorted if true, the list of RecoHitInformations will be returned sorted by the Sorting parameter |
| 652 | * in an ascending order. If false, the hits will be returned unsorted. |
| 653 | */ |
| 654 | std::vector<RecoHitInformation*> getRecoHitInformations(bool getSorted = false) const; |
| 655 | |
| 656 | /** Return genfit's MeasuredStateOnPlane for the first hit in a fit |
| 657 | * useful for extrapolation of measurements to other locations |
| 658 | * Const version. |
| 659 | */ |
| 660 | const genfit::MeasuredStateOnPlane& getMeasuredStateOnPlaneFromFirstHit(const genfit::AbsTrackRep* representation = nullptr) const; |
| 661 | |
| 662 | /** Return genfit's MeasuredStateOnPlane for the last hit in a fit |
| 663 | * useful for extrapolation of measurements to other locations |
| 664 | * Const version. |
| 665 | */ |
| 666 | const genfit::MeasuredStateOnPlane& getMeasuredStateOnPlaneFromLastHit(const genfit::AbsTrackRep* representation = nullptr) const; |
| 667 | |
| 668 | /** |
| 669 | * Return genfit's MeasuredStateOnPlane on plane for associated with one RecoHitInformation. The caller needs to ensure that |
| 670 | * recoHitInfo->useInFit() is true and the a fit has been performed on the track, a.k.a. hasTrackFitStatus() == true |
| 671 | */ |
| 672 | const genfit::MeasuredStateOnPlane& getMeasuredStateOnPlaneFromRecoHit(const RecoHitInformation* recoHitInfo, |
| 673 | const genfit::AbsTrackRep* representation = nullptr) const; |
| 674 | |
| 675 | /** Return genfit's MasuredStateOnPlane, that is closest to the given point |
| 676 | * useful for extrapolation of measurements other locations |
| 677 | */ |
| 678 | const genfit::MeasuredStateOnPlane& getMeasuredStateOnPlaneClosestTo(const ROOT::Math::XYZVector& closestPoint, |
| 679 | const genfit::AbsTrackRep* representation = nullptr); |
| 680 | |
| 681 | /** Prune the genfit track, e.g. remove all track points with measurements, but the first and the last one. |
| 682 | * Also, set the flags of the corresponding RecoHitInformation to pruned. Only to be used in the prune module. |
| 683 | */ |
| 684 | void prune(); |
| 685 | |
| 686 | /** |
| 687 | * This function calculates the track time of the ingoing and outgoing arms and their difference. |
| 688 | * If they do not exists they are set to NAN by default |
| 689 | */ |
| 690 | void estimateArmTime(); |
| 691 | |
| 692 | /** |
| 693 | * This function returns true if the arm direction is Outgoing |
| 694 | * and false if the arm direction is Ingoing. |
| 695 | * The detector sequences considered are: |
| 696 | * outgoing arm: PXD-SVD-CDC, PXD-SVD, SVD-CDC; |
| 697 | * ingoing arm: CDC-SVD-PXD, CDC-SVD, SVD-PXD; |
| 698 | * pre and post are defined w.r.t SVD, so they can be PXD, CDC or undefined if one of the two is missing |
| 699 | */ |
| 700 | bool isOutgoingArm(RecoHitInformation::RecoHitDetector pre = RecoHitInformation::RecoHitDetector::c_undefinedTrackingDetector, |
| 701 | RecoHitInformation::RecoHitDetector post = RecoHitInformation::RecoHitDetector::c_undefinedTrackingDetector); |
| 702 | |
| 703 | /// Return a list of measurements and track points, which can be used e.g. to extrapolate. You are not allowed to modify or delete them! |
| 704 | const std::vector<genfit::TrackPoint*>& getHitPointsWithMeasurement() const |
| 705 | { |
| 706 | checkDirtyFlag(); |
| 707 | return m_genfitTrack.getPointsWithMeasurement(); |
| 708 | } |
| 709 | |
| 710 | /// This returns true, if a hit was added after the last fit and measurement creation and a refit should be done. |
| 711 | bool getDirtyFlag() const { return m_dirtyFlag; } |
| 712 | |
| 713 | /// Set to true, if you want to rebuild the measurements and do the fit independent on changes of the hit content. |
| 714 | /** |
| 715 | * You can use this setting if you want to use other measurement creators than before (probably non-default settings) |
| 716 | * or different fitting algorithms. |
| 717 | */ |
| 718 | void setDirtyFlag(const bool& dirtyFlag = true) |
| 719 | { |
| 720 | m_dirtyFlag = dirtyFlag; |
| 721 | if (dirtyFlag) { |
| 722 | deleteFittedInformation(); |
| 723 | } |
| 724 | } |
| 725 | |
| 726 | // Store Array Names |
| 727 | /// Name of the store array of the pxd hits. |
| 728 | const std::string& getStoreArrayNameOfPXDHits() const { return m_storeArrayNameOfPXDHits; } |
| 729 | |
| 730 | /// Name of the store array of the svd hits. |
| 731 | const std::string& getStoreArrayNameOfSVDHits() const { return m_storeArrayNameOfSVDHits; } |
| 732 | |
| 733 | /// Name of the store array of the cdc hits. |
| 734 | const std::string& getStoreArrayNameOfCDCHits() const { return m_storeArrayNameOfCDCHits; } |
| 735 | |
| 736 | /// Name of the store array of the bklm hits. |
| 737 | const std::string& getStoreArrayNameOfBKLMHits() const { return m_storeArrayNameOfBKLMHits; } |
| 738 | |
| 739 | /// Name of the store array of the eklm hits. |
| 740 | const std::string& getStoreArrayNameOfEKLMHits() const { return m_storeArrayNameOfEKLMHits; } |
| 741 | |
| 742 | /// Name of the store array of the reco hit information. |
| 743 | const std::string& getStoreArrayNameOfRecoHitInformation() const { return m_storeArrayNameOfRecoHitInformation; } |
| 744 | |
| 745 | /// Revert the sorting order of the RecoHitInformation |
| 746 | void revertRecoHitInformationSorting() |
| 747 | { |
| 748 | const uint recoHitInformationSize = getRecoHitInformations().size(); |
| 749 | for (auto RecoHitInfo : getRecoHitInformations()) { |
| 750 | // The "-1" ensures that the sorting parameter still is in range 0...size-1 instead of 1...size |
| 751 | RecoHitInfo->setSortingParameter(recoHitInformationSize - RecoHitInfo->getSortingParameter() - 1); |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | /** |
| 756 | * Call a function on all hits of the given type in the store array, that are related to this track. |
| 757 | * @param storeArrayNameOfHits The store array the hits should come from. |
| 758 | * @param mapFunction Call this function for every hit (with its reco hit information) |
| 759 | * @param pickFunction Use only those hits where the function returns true. |
| 760 | */ |
| 761 | template<class HitType> |
| 762 | void mapOnHits(const std::string& storeArrayNameOfHits, |
| 763 | std::function<void(RecoHitInformation&, HitType*)> const& mapFunction, |
| 764 | std::function<bool(const RecoHitInformation&, const HitType*)> const& pickFunction) |
| 765 | { |
| 766 | RelationVector<RecoHitInformation> relatedHitInformation = getRelationsTo<RecoHitInformation> |
| 767 | (m_storeArrayNameOfRecoHitInformation); |
| 768 | |
| 769 | for (RecoHitInformation& hitInformation : relatedHitInformation) { |
| 770 | HitType* const hit = hitInformation.getRelatedTo<HitType>(storeArrayNameOfHits); |
| 771 | if (hit != nullptr && pickFunction(hitInformation, hit)) { |
| 772 | mapFunction(hitInformation, hit); |
| 773 | } |
| 774 | } |
| 775 | } |
| 776 | |
| 777 | /** |
| 778 | * Call a function on all hits of the given type in the store array, that are related to this track. Const version. |
| 779 | * @param storeArrayNameOfHits The store array the hits should come from. |
| 780 | * @param mapFunction Call this function for every hit (with its reco hit information) |
| 781 | * @param pickFunction Use only those hits where the function returns true. |
| 782 | */ |
| 783 | template<class HitType> |
| 784 | void mapOnHits(const std::string& storeArrayNameOfHits, |
| 785 | std::function<void(const RecoHitInformation&, const HitType*)> const& mapFunction, |
| 786 | std::function<bool(const RecoHitInformation&, const HitType*)> const& pickFunction) const |
| 787 | { |
| 788 | RelationVector<RecoHitInformation> relatedHitInformation = getRelationsTo<RecoHitInformation> |
| 789 | (m_storeArrayNameOfRecoHitInformation); |
| 790 | |
| 791 | for (const RecoHitInformation& hitInformation : relatedHitInformation) { |
| 792 | const HitType* const hit = hitInformation.getRelatedTo<HitType>(storeArrayNameOfHits); |
| 793 | if (hit != nullptr && pickFunction(hitInformation, hit)) { |
| 794 | mapFunction(hitInformation, hit); |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | /** |
| 800 | * Call a function on all hits of the given type in the store array, that are related to this track. |
| 801 | * @param storeArrayNameOfHits The store array the hits should come from. |
| 802 | * @param mapFunction Call this function for every hit (with its reco hit information) |
| 803 | */ |
| 804 | template<class HitType> |
| 805 | void mapOnHits(const std::string& storeArrayNameOfHits, |
| 806 | std::function<void(RecoHitInformation&, HitType*)> const& mapFunction) |
| 807 | { |
| 808 | mapOnHits<HitType>(storeArrayNameOfHits, mapFunction, [](const RecoHitInformation&, const HitType*) -> bool { return true; }); |
| 809 | } |
| 810 | |
| 811 | /** |
| 812 | * Call a function on all hits of the given type in the store array, that are related to this track. Const version. |
| 813 | * @param storeArrayNameOfHits The store array the hits should come from. |
| 814 | * @param mapFunction Call this function for every hit (with its reco hit information) |
| 815 | */ |
| 816 | template<class HitType> |
| 817 | void mapOnHits(const std::string& storeArrayNameOfHits, |
| 818 | std::function<void(const RecoHitInformation&, const HitType*)> const& mapFunction) const |
| 819 | { |
| 820 | mapOnHits<HitType>(storeArrayNameOfHits, mapFunction, [](const RecoHitInformation&, const HitType*) -> bool { return true; }); |
| 821 | } |
| 822 | |
| 823 | // Matching status |
| 824 | /// Return the matching status set by the TrackMatcher module |
| 825 | MatchingStatus getMatchingStatus() const |
| 826 | { |
| 827 | return m_matchingStatus; |
| 828 | } |
| 829 | |
| 830 | /// Set the matching status (used by the TrackMatcher module) |
| 831 | void setMatchingStatus(MatchingStatus matchingStatus) |
| 832 | { |
| 833 | m_matchingStatus = matchingStatus; |
| 834 | } |
| 835 | |
| 836 | /// Get the quality index attached to this RecoTrack given by one of the reconstruction algorithms. 0 means likely fake. |
| 837 | float getQualityIndicator() const |
| 838 | { |
| 839 | return m_qualityIndicator; |
| 840 | } |
| 841 | |
| 842 | /// Set the quality index attached to this RecoTrack. 0 means likely fake. |
| 843 | void setQualityIndicator(const float qualityIndicator) |
| 844 | { |
| 845 | m_qualityIndicator = qualityIndicator; |
| 846 | } |
| 847 | |
| 848 | /// Get the 1st flipping quality attached to this RecoTrack as a reference for flipping. |
| 849 | float getFlipQualityIndicator() const |
| 850 | { |
| 851 | return m_flipqualityIndicator; |
| 852 | } |
| 853 | |
| 854 | /// Set the 1st flipping quality attached to this RecoTrack. |
| 855 | void setFlipQualityIndicator(const float qualityIndicator) |
| 856 | { |
| 857 | m_flipqualityIndicator = qualityIndicator; |
| 858 | } |
| 859 | /// Get the 2nd flipping quality attached to this RecoTrack as a reference for flipping. |
| 860 | float get2ndFlipQualityIndicator() const |
| 861 | { |
| 862 | return m_2ndFlipqualityIndicator; |
| 863 | } |
| 864 | |
| 865 | /// Set the 2nd flipping quality attached to this RecoTrack. |
| 866 | void set2ndFlipQualityIndicator(const float qualityIndicator) |
| 867 | { |
| 868 | m_2ndFlipqualityIndicator = qualityIndicator; |
| 869 | } |
| 870 | /** |
| 871 | * Delete all fitted information for all representations. |
| 872 | * |
| 873 | * This function is needed, when you want to start the fitting "from scratch". |
| 874 | * After this function, a fit will recreate all measurements and fitted information. |
| 875 | * Please be aware that any pointers will be invalid after that! |
| 876 | */ |
| 877 | void deleteFittedInformation(); |
| 878 | |
| 879 | /** |
| 880 | * Delete all fitted information for the given representations. |
| 881 | * |
| 882 | * This function is needed, when you want to start the fitting "from scratch". |
| 883 | * After this function, a fit will recreate all measurements and fitted information. |
| 884 | * Please be aware that any pointers will be invalid after that! |
| 885 | */ |
| 886 | void deleteFittedInformationForRepresentation(const genfit::AbsTrackRep* rep); |
| 887 | |
| 888 | /// Get useful information on EventDisplay |
| 889 | std::string getInfoHTML() const override; |
| 890 | |
| 891 | private: |
| 892 | /// Internal storage for the genfit track. |
| 893 | genfit::Track m_genfitTrack; |
| 894 | /// Storage for the charge. All other helix parameters are saved in the genfit::Track. |
| 895 | short int m_charge = 1; |
| 896 | /// Store array name of added PXD hits. |
| 897 | std::string m_storeArrayNameOfPXDHits = ""; |
| 898 | /// Store array name of added SVD hits. |
| 899 | std::string m_storeArrayNameOfSVDHits = ""; |
| 900 | /// Store array name of added CDC hits. |
| 901 | std::string m_storeArrayNameOfCDCHits = ""; |
| 902 | /// Store array name of added BKLM hits. |
| 903 | std::string m_storeArrayNameOfBKLMHits = ""; |
| 904 | /// Store array name of added EKLM hits. |
| 905 | std::string m_storeArrayNameOfEKLMHits = ""; |
| 906 | /// Store array of added RecoHitInformation. |
| 907 | std::string m_storeArrayNameOfRecoHitInformation = ""; |
| 908 | /// Quality index for classification of fake vs. MC-matched Tracks. |
| 909 | float m_qualityIndicator = NAN(__builtin_nanf ("")); |
| 910 | /// Quality index for flipping. |
| 911 | float m_flipqualityIndicator = NAN(__builtin_nanf ("")); |
| 912 | /// Quality index for flipping. |
| 913 | float m_2ndFlipqualityIndicator = NAN(__builtin_nanf ("")); |
| 914 | /// Track time of the outgoing arm |
| 915 | float m_outgoingArmTime = NAN(__builtin_nanf ("")); |
| 916 | /// Error of the track time of the outgoing arm |
| 917 | float m_outgoingArmTimeError = NAN(__builtin_nanf ("")); |
| 918 | /// Track time of the ingoing arm |
| 919 | float m_ingoingArmTime = NAN(__builtin_nanf ("")); |
| 920 | /// Error of the track time of the ingoing arm |
| 921 | float m_ingoingArmTimeError = NAN(__builtin_nanf ("")); |
| 922 | /// Flag used in the MCRecoTracksMatcherModule |
| 923 | MatchingStatus m_matchingStatus = MatchingStatus::c_undefined; |
| 924 | /// Number of SVD clusters of the outgoing arm |
| 925 | int m_nSVDHitsOfOutgoingArm = 0; |
| 926 | /// Number of SVD clusters of the ingoing arm |
| 927 | int m_nSVDHitsOfIngoingArm = 0; |
| 928 | /// Bool is hits were added to track after fitting and the measurements should be recalculated. |
| 929 | /// will be true after ROOT deserialization, which means the measurements will be recreated |
| 930 | bool m_dirtyFlag = true; |
| 931 | /// true if the arms times are already computed, false otherwise |
| 932 | bool m_isArmTimeComputed = false; |
| 933 | /// Internal storage of the final ingoing arm time is set |
| 934 | bool m_hasIngoingArmTime = false; |
| 935 | /// Internal storage of the final outgoing arm time is set |
| 936 | bool m_hasOutgoingArmTime = false; |
| 937 | |
| 938 | /** |
| 939 | * Add a generic hit with the given parameters for the reco hit information. |
| 940 | * @param hit a generic hit. |
| 941 | * @param params for the constructor of the reco hit information. |
| 942 | * @return true if the hit was new. |
| 943 | */ |
| 944 | template<class HitType, class ...Args> |
| 945 | bool addHit(const HitType* hit, Args&& ... params) |
| 946 | { |
| 947 | if (hasHit(hit)) { |
| 948 | return false; |
| 949 | } |
| 950 | |
| 951 | StoreArray<RecoHitInformation> recoHitInformations(m_storeArrayNameOfRecoHitInformation); |
| 952 | RecoHitInformation* newRecoHitInformation = recoHitInformations.appendNew(hit, params...); |
| 953 | |
| 954 | addHitWithHitInformation(hit, newRecoHitInformation); |
| 955 | |
| 956 | return true; |
| 957 | } |
| 958 | |
| 959 | /** |
| 960 | * Add the needed relations for adding a generic hit with the given hit information and reset track time information. |
| 961 | * @param hit The hit to add |
| 962 | * @param recoHitInformation The reco hit information of the hit. |
| 963 | */ |
| 964 | template <class HitType> |
| 965 | void addHitWithHitInformation(const HitType* hit, RecoHitInformation* recoHitInformation) |
| 966 | { |
| 967 | hit->addRelationTo(this); |
| 968 | addRelationTo(recoHitInformation); |
| 969 | |
| 970 | m_isArmTimeComputed = false; |
| 971 | m_hasIngoingArmTime = false; |
| 972 | m_hasOutgoingArmTime = false; |
| 973 | m_outgoingArmTime = NAN(__builtin_nanf ("")); |
| 974 | m_ingoingArmTime = NAN(__builtin_nanf ("")); |
| 975 | m_outgoingArmTimeError = NAN(__builtin_nanf ("")); |
| 976 | m_ingoingArmTimeError = NAN(__builtin_nanf ("")); |
| 977 | |
| 978 | setDirtyFlag(); |
| 979 | } |
| 980 | |
| 981 | /// Returns the reco hit information for a given hit or throws an exception if the hit is not related to the track. |
| 982 | template <class HitType> |
| 983 | RecoHitInformation* getRecoHitInformationSafely(HitType* hit) const |
| 984 | { |
| 985 | RecoHitInformation* recoHitInformation = getRecoHitInformation(hit); |
| 986 | if (recoHitInformation == nullptr) { |
| 987 | B2FATAL("Queried hit is not in the reco track! Did you prune it?")do { { LogVariableStream varStream; varStream << "Queried hit is not in the reco track! Did you prune it?" ; Belle2::LogSystem::Instance().sendMessage(Belle2::LogMessage (Belle2::LogConfig::c_Fatal, std::move(varStream), "alignment" , __PRETTY_FUNCTION__, "include/tracking/dataobjects/RecoTrack.h" , 987, 0)); }; exit(1); } while(false); |
| 988 | } else { |
| 989 | return recoHitInformation; |
| 990 | } |
| 991 | } |
| 992 | |
| 993 | /** |
| 994 | * Get the number of hits for the given hit type in the store array that are related to this track. |
| 995 | * @param storeArrayNameOfHits The StoreArray to look for. |
| 996 | */ |
| 997 | template <class HitType> |
| 998 | unsigned int getNumberOfHitsOfGivenType(const std::string& storeArrayNameOfHits) const |
| 999 | { |
| 1000 | return getRelationsFrom<HitType>(storeArrayNameOfHits).size(); |
| 1001 | } |
| 1002 | |
| 1003 | /** |
| 1004 | * Return a sorted list of hits of the given type in the store array that are related to this track. |
| 1005 | * @param storeArrayNameOfHits The StoreArray to look for. |
| 1006 | */ |
| 1007 | template<class HitType> |
| 1008 | std::vector<HitType*> getSortedHitList(const std::string& storeArrayNameOfHits) const |
| 1009 | { |
| 1010 | const RelationVector<RecoHitInformation>& relatedHitInformation = getRelationsTo<RecoHitInformation> |
| 1011 | (m_storeArrayNameOfRecoHitInformation); |
| 1012 | |
| 1013 | std::vector<const RecoHitInformation*> relatedHitInformationAsVector; |
| 1014 | relatedHitInformationAsVector.reserve(relatedHitInformation.size()); |
| 1015 | for (const RecoHitInformation& hitInformation : relatedHitInformation) { |
| 1016 | // cppcheck-suppress useStlAlgorithm |
| 1017 | relatedHitInformationAsVector.push_back(&hitInformation); |
| 1018 | } |
| 1019 | std::sort(relatedHitInformationAsVector.begin(), relatedHitInformationAsVector.end(), [](const RecoHitInformation * a, |
| 1020 | const RecoHitInformation * b) -> bool { |
| 1021 | return a->getSortingParameter() < b->getSortingParameter(); |
| 1022 | }); |
| 1023 | |
| 1024 | std::vector<HitType*> hitList; |
| 1025 | hitList.reserve(relatedHitInformationAsVector.size()); |
| 1026 | for (const RecoHitInformation* hitInformation : relatedHitInformationAsVector) { |
| 1027 | HitType* relatedHit = hitInformation->getRelatedTo<HitType>(storeArrayNameOfHits); |
| 1028 | if (relatedHit != nullptr) { |
| 1029 | hitList.push_back(relatedHit); |
| 1030 | } |
| 1031 | } |
| 1032 | return hitList; |
| 1033 | } |
| 1034 | |
| 1035 | /** |
| 1036 | * Return an unsorted list of hits of the given type in the store array that are related to this track. |
| 1037 | * @param storeArrayNameOfHits The StoreArray to look for. |
| 1038 | */ |
| 1039 | template<class HitType> |
| 1040 | std::vector<HitType*> getHitList(const std::string& storeArrayNameOfHits) const |
| 1041 | { |
| 1042 | RelationVector<HitType> relatedHits = getRelationsFrom<HitType>(storeArrayNameOfHits); |
| 1043 | std::vector<HitType*> hitList; |
| 1044 | hitList.reserve(relatedHits.size()); |
| 1045 | for (HitType& hit : relatedHits) { |
| 1046 | // cppcheck-suppress useStlAlgorithm |
| 1047 | hitList.push_back(&hit); |
| 1048 | } |
| 1049 | // cppcheck-suppress returnDanglingLifetime |
| 1050 | return hitList; |
| 1051 | } |
| 1052 | |
| 1053 | /// Swap arm times, booleans and nSVDHits |
| 1054 | void swapArmTimes() |
| 1055 | { |
| 1056 | std::swap(m_outgoingArmTime, m_ingoingArmTime); |
| 1057 | std::swap(m_hasOutgoingArmTime, m_hasIngoingArmTime); |
| 1058 | std::swap(m_nSVDHitsOfOutgoingArm, m_nSVDHitsOfIngoingArm); |
| 1059 | } |
| 1060 | |
| 1061 | /// Helper: Check the dirty flag and produce a warning, whenever a fit result is accessed. |
| 1062 | void checkDirtyFlag() const |
| 1063 | { |
| 1064 | if (m_dirtyFlag) { |
| 1065 | B2DEBUG(100, "Dirty flag is set. The result may not be in sync with the latest changes. Refit the track to be sure.")do { if (Belle2::LogSystem::debugEnabled()) do { if (Belle2:: LogSystem::Instance().isLevelEnabled(Belle2::LogConfig::c_Debug , 100, "alignment")) { { LogVariableStream varStream; varStream << "Dirty flag is set. The result may not be in sync with the latest changes. Refit the track to be sure." ; Belle2::LogSystem::Instance().sendMessage(Belle2::LogMessage (Belle2::LogConfig::c_Debug, std::move(varStream), "alignment" , __PRETTY_FUNCTION__, "include/tracking/dataobjects/RecoTrack.h" , 1065, 100)); }; } } while(false); } while(false); |
| 1066 | } |
| 1067 | } |
| 1068 | |
| 1069 | /** Making this class a ROOT class.*/ |
| 1070 | ClassDefOverride(RecoTrack, 15)private: static_assert(std::is_integral<decltype(15)>:: value, "ClassDef(Inline) macro: the specified class version number is not an integer." ); Bool_t CheckTObjectHashConsistency() const override { static std::atomic<UChar_t> recurseBlocker(0); if (__builtin_expect (!!(recurseBlocker >= 2), 1)) { return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } else if (recurseBlocker == 1) { return false; } else if (recurseBlocker++ == 0) { :: ROOT::Internal::THashConsistencyHolder<decltype(*this)> ::fgHashConsistency = ::ROOT::Internal::HasConsistentHashMember ("RecoTrack") || ::ROOT::Internal::HasConsistentHashMember(*IsA ()); ++recurseBlocker; return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } return false; } public: static constexpr Version_t Class_Version() { return 15 ; } TClass *IsA() const override { return RecoTrack::Class(); } void ShowMembers(TMemberInspector &insp) const override { ::ROOT::Class_ShowMembers(RecoTrack::Class(), this, insp); } void StreamerNVirtual(TBuffer &ClassDef_StreamerNVirtual_b ) { RecoTrack::Streamer(ClassDef_StreamerNVirtual_b); } static const char *DeclFileName() { return "include/tracking/dataobjects/RecoTrack.h" ; } private: static atomic_TClass_ptr fgIsA; public: static int ImplFileLine(); static const char *ImplFileName(); static const char *Class_Name(); static TClass *Dictionary(); static TClass *Class(); void Streamer(TBuffer&) override; static int DeclFileLine () { return 1070; }; |
| 1071 | }; |
| 1072 | |
| 1073 | /** |
| 1074 | * This class allows access to the genfit::Track of the RecoTrack. |
| 1075 | * |
| 1076 | * This class allows direct access to the most holy part of the RecoTrack. The design of the RecoTrack is such, that this should not be required. |
| 1077 | * However, some interfaces require a genfit::Track, e.g. the genfit rave interface, and the access to the genfit::Track member is required. |
| 1078 | * This should only be used when no other solution works. |
| 1079 | */ |
| 1080 | class RecoTrackGenfitAccess { |
| 1081 | public: |
| 1082 | /** |
| 1083 | * Give access to the RecoTrack's genfit::Track. |
| 1084 | * |
| 1085 | * @param recoTrack Track to unpack |
| 1086 | * @return genfit::Track of the RecoTrack. |
| 1087 | */ |
| 1088 | static genfit::Track& getGenfitTrack(RecoTrack& recoTrack); |
| 1089 | |
| 1090 | /** Set the genfit track of a Recotrack copying the information from another genfit track. |
| 1091 | * This is used by the fit&refit, since the original genfit track must be |
| 1092 | * updated with the refitted object obtained after the flip |
| 1093 | * |
| 1094 | * @param recoTrack : RecoTrack whose Track we want to update |
| 1095 | * @param track : input genfit::Track which we want to copy inside the RecoTrack |
| 1096 | */ |
| 1097 | static void swapGenfitTrack(RecoTrack& recoTrack, const genfit::Track* track); |
| 1098 | |
| 1099 | /** |
| 1100 | * Checks if a TrackRap for the PDG id of the RecoTrack (and its charge conjugate) does |
| 1101 | * already exit and returns it if available. If no TrackRep is available, a new RKTrackRep |
| 1102 | * is added to the genfit::Track. This ensures that a TrackRep with the same PDG id |
| 1103 | * (and its charge conjugate) is not available two times in the genfit::Track. |
| 1104 | * |
| 1105 | * By convention, only one TrackRep for one particle type can exist |
| 1106 | * inside of a RecoTrack, no matter the charge. So there can only be a electron or positron TrackRep, |
| 1107 | * but not both. |
| 1108 | * |
| 1109 | * @param recoTrack Track to add TrackRep to |
| 1110 | * @param PDGcode : code of the hypothesis which is negative or positive, depending on |
| 1111 | * the charge of the hypothesis particle. |
| 1112 | */ |
| 1113 | static genfit::AbsTrackRep* createOrReturnRKTrackRep(RecoTrack& recoTrack, int PDGcode); |
| 1114 | }; |
| 1115 | |
| 1116 | } |
| 1 | /************************************************************************** |
| 2 | * basf2 (Belle II Analysis Software Framework) * |
| 3 | * Author: The Belle II Collaboration * |
| 4 | * * |
| 5 | * See git log for contributors and copyright holders. * |
| 6 | * This file is licensed under LGPL-3.0, see LICENSE.md. * |
| 7 | **************************************************************************/ |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | /* ROOT headers. */ |
| 12 | #include <Math/Vector3D.h> |
| 13 | #include <Math/Vector2D.h> |
| 14 | #include <Math/VectorUtil.h> |
| 15 | #include <TVector3.h> |
| 16 | |
| 17 | namespace Belle2 { |
| 18 | |
| 19 | /** |
| 20 | * Helper function to convert XYZVector to TVector3 |
| 21 | */ |
| 22 | static constexpr auto XYZToTVector = [](const ROOT::Math::XYZVector& a) |
| 23 | { |
| 24 | return TVector3(a.X(), a.Y(), a.Z()); |
| 25 | }; |
| 26 | |
| 27 | namespace VectorUtil { |
| 28 | |
| 29 | /** |
| 30 | * Set vector by polar coordinates. |
| 31 | * @param[out] vector Vector. |
| 32 | * @param[in] mag Magnitude. |
| 33 | * @param[in] theta Polar angle. |
| 34 | * @param[in] phi Azimuthal angle. |
| 35 | */ |
| 36 | inline void setMagThetaPhi(ROOT::Math::XYZVector& vector, |
| 37 | double mag, double theta, double phi) |
| 38 | { |
| 39 | const double amag = std::abs(mag); |
| 40 | const double sinTheta = std::sin(theta); |
| 41 | const double x = amag * sinTheta * std::cos(phi); |
| 42 | const double y = amag * sinTheta * std::sin(phi); |
| 43 | const double z = amag * std::cos(theta); |
| 44 | vector.SetXYZ(x, y, z); |
| 45 | } |
| 46 | |
| 47 | /** |
| 48 | * Set vector magnitude mag |
| 49 | * @param[inout] vector Vector |
| 50 | * @param[in] mag Magnitude |
| 51 | */ |
| 52 | inline void setMag(ROOT::Math::XYZVector& vector, double mag) |
| 53 | { |
| 54 | setMagThetaPhi(vector, mag, vector.Theta(), vector.Phi()); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Set vector azimuthal angle theta |
| 59 | * @param[inout] vector Vector |
| 60 | * @param[in] theta Azimuthal angle |
| 61 | */ |
| 62 | inline void setTheta(ROOT::Math::XYZVector& vector, double theta) |
| 63 | { |
| 64 | setMagThetaPhi(vector, vector.R(), theta, vector.Phi()); |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Set vector polar angle phi |
| 69 | * @param[inout] vector Vector |
| 70 | * @param[in] phi Polar angle |
| 71 | */ |
| 72 | inline void setPhi(ROOT::Math::XYZVector& vector, double phi) |
| 73 | { |
| 74 | setMagThetaPhi(vector, vector.R(), vector.Theta(), phi); |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * Set vector by polar coordinates. |
| 79 | * @param[out] vector Vector. |
| 80 | * @param[in] pt Magnitude in xy-plane. |
| 81 | * @param[in] theta Polar angle. |
| 82 | * @param[in] phi Azimuthal angle. |
| 83 | */ |
| 84 | inline void setPtThetaPhi(ROOT::Math::XYZVector& vector, |
| 85 | double pt, double theta, double phi) |
| 86 | { |
| 87 | const double aPt = std::abs(pt); |
| 88 | const double x = aPt * std::cos(phi); |
| 89 | const double y = aPt * std::sin(phi); |
| 90 | const double tanTheta = std::tan(theta); |
| 91 | const double z = tanTheta ? aPt / tanTheta : 0; |
| 92 | vector.SetXYZ(x, y, z); |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Calculate CosTheta between two vectors |
| 97 | * @param[in] v1 Vector v1 |
| 98 | * @param[in] v2 Vector v2 |
| 99 | * \return cosine of Angle between the two vectors |
| 100 | * \f[ \cos \theta = \frac { \vec{v1} \cdot \vec{v2} }{ | \vec{v1} | | \vec{v2} | } \f] |
| 101 | * |
| 102 | * There is a function with the same name in ROOT::Math::VectorUtil. However, that function only works for 3-vectors, and does not |
| 103 | * use the Mag2 method nor the Dot method to calculate the two properties as it is allowed to provide two different vector types |
| 104 | * (like v1 being cartesian and v2 being polar) and would only work for 3-vectors. |
| 105 | * However, we also need a 2D version, thus, this custom implementation. |
| 106 | */ |
| 107 | template <class Vector> |
| 108 | double CosTheta(const Vector& v1, const Vector& v2) |
| 109 | { |
| 110 | const double v1_r2 = v1.Mag2(); |
| 111 | const double v2_r2 = v2.Mag2(); |
| 112 | const double ptot2 = v1_r2 * v2_r2; |
| 113 | if (ptot2 == 0) { |
| 114 | return 0.0; |
| 115 | } |
| 116 | const double pdot = v1.Dot(v2); |
| 117 | double arg = pdot / std::sqrt(ptot2); |
| 118 | if (arg > 1.0) |
| 119 | arg = 1.0; |
| 120 | if (arg < -1.0) |
| 121 | arg = -1.0; |
| 122 | return arg; |
| 123 | } |
| 124 | |
| 125 | |
| 126 | /** |
| 127 | * Calculate the angle (theta in the formula below) between two vectors |
| 128 | * @param[in] v1 Vector v1 |
| 129 | * @param[in] v2 Vector v2 |
| 130 | * \return Angle between the two vectors |
| 131 | * \f[ \theta = \cos ^{-1} \frac { \vec{v1} \cdot \vec{v2} }{ | \vec{v1} | | \vec{v2} | } \f] |
| 132 | * |
| 133 | * There is a function with the same name in ROOT::Math::VectorUtil. However, that function only works for 3-vectors as it calls the |
| 134 | * ROOT version of CosTheta (see above). Thus, we need a custom version to be able to use it for 2D vectors, too. |
| 135 | */ |
| 136 | template <class Vector> |
| 137 | double Angle(const Vector& v1, const Vector& v2) |
| 138 | { |
| 139 | return std::acos(CosTheta(v1, v2)); |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Calculates the part of vector v1 that is orthogonal to the vector v2 |
| 144 | * @param[in] v1 Vector v1 |
| 145 | * @param[in] relativeTo Vector to calculate the orthognal component relative to |
| 146 | * \return Part of v1 that is orthogonal to relativeTo |
| 147 | * Adapted from tracking/trackingUtilities/geometry/Vector2D: |
| 148 | * https://gitlab.desy.de/belle2/software/basf2/-/blob/main/tracking/trackingUtilities/geometry/include/Vector2D.h?ref_type=heads#L445 |
| 149 | * |
| 150 | * Vector2D orthogonalVector(const Vector2D& relativeTo) const |
| 151 | * { |
| 152 | * return relativeTo.scaled(relativeTo.cross(*this) / relativeTo.normSquared()).orthogonal(); |
| 153 | * } |
| 154 | * with v1 = *this. |
| 155 | */ |
| 156 | inline ROOT::Math::XYVector orthogonalVector(const ROOT::Math::XYVector& v1, const ROOT::Math::XYVector& relativeTo) |
| 157 | { |
| 158 | const double cross = relativeTo.X() * v1.Y() - relativeTo.Y() * v1.X(); // = relativeTo.cross(*this) |
| 159 | const ROOT::Math::XYVector tmp = relativeTo * (cross / |
| 160 | relativeTo.Mag2()); // = relativeTo.scaled(cross / relativeTo.normSquared()) |
| 161 | return ROOT::Math::XYVector(-tmp.Y(), tmp.X()); // = .orthogonal() |
| 162 | } |
| 163 | |
| 164 | /** |
| 165 | * Calculates the part of this vector that is parallel to the given vector |
| 166 | * |
| 167 | * Functions with the same name exist in both the Vector2D and Vector3D classes in |
| 168 | * tracking/trackingUtilities/geometry, and the implementation for both is |
| 169 | * VectorXD parallelVector(const VectorXD& relativTo) const |
| 170 | * { |
| 171 | * return relativTo.scaled(relativTo.dot(*this) / relativTo.normSquared()); |
| 172 | * } |
| 173 | * |
| 174 | * There exists a similar function called ProjVector in ROOT::Math::VectorUtil, but that only works for 3D vectors, |
| 175 | * while this implementation also covers 2D vectors. |
| 176 | * The existence of this generalised version is mentioned in both the trackingUtilities Vector2D and Vector3D classes in the |
| 177 | * documentation of the according parallelVector method. |
| 178 | */ |
| 179 | template<class aVector> |
| 180 | inline aVector parallelVector(const aVector& v1, const aVector& v2) |
| 181 | { |
| 182 | const double v2Mag2 = v2.Mag2(); |
| 183 | if (v2Mag2 == 0) |
| 184 | return aVector(); |
| 185 | const double dotp = v1.Dot(v2); // = relativTo.dot(*this) |
| 186 | const aVector tmp = v2 * (dotp / v2Mag2); // = relativTo.scaled(dotp / relativTo.normSquared()) |
| 187 | return tmp; |
| 188 | } |
| 189 | |
| 190 | } |
| 191 | |
| 192 | } |
| 1 | // @(#)root/physics:$Id$ |
| 2 | // Author: Pasha Murat, Peter Malzacher 12/02/99 |
| 3 | |
| 4 | /************************************************************************* |
| 5 | * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * |
| 6 | * All rights reserved. * |
| 7 | * * |
| 8 | * For the licensing terms see $ROOTSYS/LICENSE. * |
| 9 | * For the list of contributors see $ROOTSYS/README/CREDITS. * |
| 10 | *************************************************************************/ |
| 11 | #ifndef ROOT_TVector3 |
| 12 | #define ROOT_TVector3 |
| 13 | |
| 14 | #include "TError.h" |
| 15 | #include "TVector2.h" |
| 16 | #include "TMatrix.h" |
| 17 | #include "TMath.h" |
| 18 | |
| 19 | class TRotation; |
| 20 | |
| 21 | |
| 22 | class TVector3 : public TObject { |
| 23 | |
| 24 | public: |
| 25 | |
| 26 | typedef Double_t Scalar; // to be able to use it with the ROOT::Math::VectorUtil functions |
| 27 | |
| 28 | TVector3(); |
| 29 | |
| 30 | TVector3(Double_t x, Double_t y, Double_t z); |
| 31 | // The constructor. |
| 32 | |
| 33 | TVector3(const Double_t *); |
| 34 | TVector3(const Float_t *); |
| 35 | // Constructors from an array |
| 36 | |
| 37 | TVector3(const TVector3 &); |
| 38 | // The copy constructor. |
| 39 | |
| 40 | ~TVector3() override {}; |
| 41 | // Destructor |
| 42 | |
| 43 | Double_t operator () (int) const; |
| 44 | inline Double_t operator [] (int) const; |
| 45 | // Get components by index (Geant4). |
| 46 | |
| 47 | Double_t & operator () (int); |
| 48 | inline Double_t & operator [] (int); |
| 49 | // Set components by index. |
| 50 | |
| 51 | inline Double_t x() const; |
| 52 | inline Double_t y() const; |
| 53 | inline Double_t z() const; |
| 54 | inline Double_t X() const; |
| 55 | inline Double_t Y() const; |
| 56 | inline Double_t Z() const; |
| 57 | inline Double_t Px() const; |
| 58 | inline Double_t Py() const; |
| 59 | inline Double_t Pz() const; |
| 60 | // The components in cartesian coordinate system. |
| 61 | |
| 62 | inline void SetX(Double_t); |
| 63 | inline void SetY(Double_t); |
| 64 | inline void SetZ(Double_t); |
| 65 | inline void SetXYZ(Double_t x, Double_t y, Double_t z); |
| 66 | void SetPtEtaPhi(Double_t pt, Double_t eta, Double_t phi); |
| 67 | void SetPtThetaPhi(Double_t pt, Double_t theta, Double_t phi); |
| 68 | |
| 69 | inline void GetXYZ(Double_t *carray) const; |
| 70 | inline void GetXYZ(Float_t *carray) const; |
| 71 | // Get the components into an array |
| 72 | // not checked! |
| 73 | |
| 74 | Double_t Phi() const; |
| 75 | // The azimuth angle. returns phi from -pi to pi |
| 76 | |
| 77 | Double_t Theta() const; |
| 78 | // The polar angle. |
| 79 | |
| 80 | inline Double_t CosTheta() const; |
| 81 | // Cosine of the polar angle. |
| 82 | |
| 83 | inline Double_t Mag2() const; |
| 84 | // The magnitude squared (rho^2 in spherical coordinate system). |
| 85 | |
| 86 | Double_t Mag() const { return TMath::Sqrt(Mag2()); } |
| 87 | // The magnitude (rho in spherical coordinate system). |
| 88 | |
| 89 | void SetPhi(Double_t); |
| 90 | // Set phi keeping mag and theta constant (BaBar). |
| 91 | |
| 92 | void SetTheta(Double_t); |
| 93 | // Set theta keeping mag and phi constant (BaBar). |
| 94 | |
| 95 | inline void SetMag(Double_t); |
| 96 | // Set magnitude keeping theta and phi constant (BaBar). |
| 97 | |
| 98 | inline Double_t Perp2() const; |
| 99 | // The transverse component squared (R^2 in cylindrical coordinate system). |
| 100 | |
| 101 | inline Double_t Pt() const; |
| 102 | Double_t Perp() const; |
| 103 | // The transverse component (R in cylindrical coordinate system). |
| 104 | |
| 105 | inline void SetPerp(Double_t); |
| 106 | // Set the transverse component keeping phi and z constant. |
| 107 | |
| 108 | inline Double_t Perp2(const TVector3 &) const; |
| 109 | // The transverse component w.r.t. given axis squared. |
| 110 | |
| 111 | inline Double_t Pt(const TVector3 &) const; |
| 112 | Double_t Perp(const TVector3 &) const; |
| 113 | // The transverse component w.r.t. given axis. |
| 114 | |
| 115 | inline Double_t DeltaPhi(const TVector3 &) const; |
| 116 | Double_t DeltaR(const TVector3 &) const; |
| 117 | inline Double_t DrEtaPhi(const TVector3 &) const; |
| 118 | inline TVector2 EtaPhiVector() const; |
| 119 | void SetMagThetaPhi(Double_t mag, Double_t theta, Double_t phi); |
| 120 | |
| 121 | inline TVector3 & operator = (const TVector3 &); |
| 122 | // Assignment. |
| 123 | |
| 124 | inline Bool_t operator == (const TVector3 &) const; |
| 125 | inline Bool_t operator != (const TVector3 &) const; |
| 126 | // Comparisons (Geant4). |
| 127 | |
| 128 | inline TVector3 & operator += (const TVector3 &); |
| 129 | // Addition. |
| 130 | |
| 131 | inline TVector3 & operator -= (const TVector3 &); |
| 132 | // Subtraction. |
| 133 | |
| 134 | inline TVector3 operator - () const; |
| 135 | // Unary minus. |
| 136 | |
| 137 | inline TVector3 & operator *= (Double_t); |
| 138 | // Scaling with real numbers. |
| 139 | |
| 140 | TVector3 Unit() const; |
| 141 | // Unit vector parallel to this. |
| 142 | |
| 143 | inline TVector3 Orthogonal() const; |
| 144 | // Vector orthogonal to this (Geant4). |
| 145 | |
| 146 | inline Double_t Dot(const TVector3 &) const; |
| 147 | // Scalar product. |
| 148 | |
| 149 | inline TVector3 Cross(const TVector3 &) const; |
| 150 | // Cross product. |
| 151 | |
| 152 | Double_t Angle(const TVector3 &) const; |
| 153 | // The angle w.r.t. another 3-vector. |
| 154 | |
| 155 | Double_t PseudoRapidity() const; |
| 156 | // Returns the pseudo-rapidity, i.e. -ln(tan(theta/2)) |
| 157 | |
| 158 | inline Double_t Eta() const; |
| 159 | |
| 160 | void RotateX(Double_t); |
| 161 | // Rotates the Hep3Vector around the x-axis. |
| 162 | |
| 163 | void RotateY(Double_t); |
| 164 | // Rotates the Hep3Vector around the y-axis. |
| 165 | |
| 166 | void RotateZ(Double_t); |
| 167 | // Rotates the Hep3Vector around the z-axis. |
| 168 | |
| 169 | void RotateUz(const TVector3&); |
| 170 | // Rotates reference frame from Uz to newUz (unit vector) (Geant4). |
| 171 | |
| 172 | void Rotate(Double_t, const TVector3 &); |
| 173 | // Rotates around the axis specified by another Hep3Vector. |
| 174 | |
| 175 | TVector3 & operator *= (const TRotation &); |
| 176 | TVector3 & Transform(const TRotation &); |
| 177 | // Transformation with a Rotation matrix. |
| 178 | |
| 179 | inline TVector2 XYvector() const; |
| 180 | |
| 181 | void Print(Option_t* option="") const override; |
| 182 | |
| 183 | private: |
| 184 | |
| 185 | Double_t fX, fY, fZ; |
| 186 | // The components. |
| 187 | |
| 188 | ClassDefOverride(TVector3,3)private: static_assert(std::is_integral<decltype(3)>::value , "ClassDef(Inline) macro: the specified class version number is not an integer." ); Bool_t CheckTObjectHashConsistency() const override { static std::atomic<UChar_t> recurseBlocker(0); if (__builtin_expect (!!(recurseBlocker >= 2), 1)) { return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } else if (recurseBlocker == 1) { return false; } else if (recurseBlocker++ == 0) { :: ROOT::Internal::THashConsistencyHolder<decltype(*this)> ::fgHashConsistency = ::ROOT::Internal::HasConsistentHashMember ("TVector3") || ::ROOT::Internal::HasConsistentHashMember(*IsA ()); ++recurseBlocker; return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } return false; } public: static constexpr Version_t Class_Version() { return 3 ; } TClass *IsA() const override { return TVector3::Class(); } void ShowMembers(TMemberInspector &insp) const override { ::ROOT::Class_ShowMembers(TVector3::Class(), this, insp); } void StreamerNVirtual(TBuffer &ClassDef_StreamerNVirtual_b) { TVector3::Streamer(ClassDef_StreamerNVirtual_b); } static const char *DeclFileName() { return "/cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root/TVector3.h" ; } private: static atomic_TClass_ptr fgIsA; public: static int ImplFileLine(); static const char *ImplFileName(); static const char *Class_Name(); static TClass *Dictionary(); static TClass *Class(); void Streamer(TBuffer&) override; static int DeclFileLine () { return 188; } // A 3D physics vector |
| 189 | |
| 190 | // make TLorentzVector a friend class |
| 191 | friend class TLorentzVector; |
| 192 | }; |
| 193 | |
| 194 | TVector3 operator + (const TVector3 &, const TVector3 &); |
| 195 | // Addition of 3-vectors. |
| 196 | |
| 197 | TVector3 operator - (const TVector3 &, const TVector3 &); |
| 198 | // Subtraction of 3-vectors. |
| 199 | |
| 200 | Double_t operator * (const TVector3 &, const TVector3 &); |
| 201 | // Scalar product of 3-vectors. |
| 202 | |
| 203 | TVector3 operator * (const TVector3 &, Double_t a); |
| 204 | TVector3 operator * (Double_t a, const TVector3 &); |
| 205 | // Scaling of 3-vectors with a real number |
| 206 | |
| 207 | TVector3 operator * (const TMatrix &, const TVector3 &); |
| 208 | |
| 209 | |
| 210 | inline Double_t & TVector3::operator[] (int i) { return operator()(i); } |
| 211 | inline Double_t TVector3::operator[] (int i) const { return operator()(i); } |
| 212 | |
| 213 | inline Double_t TVector3::x() const { return fX; } |
| 214 | inline Double_t TVector3::y() const { return fY; } |
| 215 | inline Double_t TVector3::z() const { return fZ; } |
| 216 | inline Double_t TVector3::X() const { return fX; } |
| 217 | inline Double_t TVector3::Y() const { return fY; } |
| 218 | inline Double_t TVector3::Z() const { return fZ; } |
| 219 | inline Double_t TVector3::Px() const { return fX; } |
| 220 | inline Double_t TVector3::Py() const { return fY; } |
| 221 | inline Double_t TVector3::Pz() const { return fZ; } |
| 222 | |
| 223 | inline void TVector3::SetX(Double_t xx) { fX = xx; } |
| 224 | inline void TVector3::SetY(Double_t yy) { fY = yy; } |
| 225 | inline void TVector3::SetZ(Double_t zz) { fZ = zz; } |
| 226 | |
| 227 | inline void TVector3::SetXYZ(Double_t xx, Double_t yy, Double_t zz) { |
| 228 | fX = xx; |
| 229 | fY = yy; |
| 230 | fZ = zz; |
| 231 | } |
| 232 | |
| 233 | inline void TVector3::GetXYZ(Double_t *carray) const { |
| 234 | carray[0] = fX; |
| 235 | carray[1] = fY; |
| 236 | carray[2] = fZ; |
| 237 | } |
| 238 | |
| 239 | inline void TVector3::GetXYZ(Float_t *carray) const { |
| 240 | carray[0] = fX; |
| 241 | carray[1] = fY; |
| 242 | carray[2] = fZ; |
| 243 | } |
| 244 | |
| 245 | //////////////////////////////////////////////////////////////////////////////// |
| 246 | /// Constructors |
| 247 | inline TVector3::TVector3() |
| 248 | : fX(0.0), fY(0.0), fZ(0.0) {} |
| 249 | |
| 250 | inline TVector3::TVector3(const TVector3 & p) : TObject(p), |
| 251 | fX(p.fX), fY(p.fY), fZ(p.fZ) {} |
| 252 | |
| 253 | inline TVector3::TVector3(Double_t xx, Double_t yy, Double_t zz) |
| 254 | : fX(xx), fY(yy), fZ(zz) {} |
| 255 | |
| 256 | inline TVector3::TVector3(const Double_t * x0) |
| 257 | : fX(x0[0]), fY(x0[1]), fZ(x0[2]) {} |
| 258 | |
| 259 | inline TVector3::TVector3(const Float_t * x0) |
| 260 | : fX(x0[0]), fY(x0[1]), fZ(x0[2]) {} |
| 261 | |
| 262 | |
| 263 | inline Double_t TVector3::operator () (int i) const { |
| 264 | switch(i) { |
| 265 | case 0: |
| 266 | return fX; |
| 267 | case 1: |
| 268 | return fY; |
| 269 | case 2: |
| 270 | return fZ; |
| 271 | default: |
| 272 | Error("operator()(i)", "bad index (%d) returning 0",i); |
| 273 | } |
| 274 | return 0.; |
| 275 | } |
| 276 | |
| 277 | inline Double_t & TVector3::operator () (int i) { |
| 278 | switch(i) { |
| 279 | case 0: |
| 280 | return fX; |
| 281 | case 1: |
| 282 | return fY; |
| 283 | case 2: |
| 284 | return fZ; |
| 285 | default: |
| 286 | Error("operator()(i)", "bad index (%d) returning &fX",i); |
| 287 | } |
| 288 | return fX; |
| 289 | } |
| 290 | |
| 291 | inline TVector3 & TVector3::operator = (const TVector3 & p) { |
| 292 | fX = p.fX; |
| 293 | fY = p.fY; |
| 294 | fZ = p.fZ; |
| 295 | return *this; |
| 296 | } |
| 297 | |
| 298 | inline Bool_t TVector3::operator == (const TVector3& v) const { |
| 299 | return (v.fX==fX && v.fY==fY && v.fZ==fZ) ? kTRUE : kFALSE; |
| 300 | } |
| 301 | |
| 302 | inline Bool_t TVector3::operator != (const TVector3& v) const { |
| 303 | return (v.fX!=fX || v.fY!=fY || v.fZ!=fZ) ? kTRUE : kFALSE; |
| 304 | } |
| 305 | |
| 306 | inline TVector3& TVector3::operator += (const TVector3 & p) { |
| 307 | fX += p.fX; |
| 308 | fY += p.fY; |
| 309 | fZ += p.fZ; |
| 310 | return *this; |
| 311 | } |
| 312 | |
| 313 | inline TVector3& TVector3::operator -= (const TVector3 & p) { |
| 314 | fX -= p.fX; |
| 315 | fY -= p.fY; |
| 316 | fZ -= p.fZ; |
| 317 | return *this; |
| 318 | } |
| 319 | |
| 320 | inline TVector3 TVector3::operator - () const { |
| 321 | return TVector3(-fX, -fY, -fZ); |
| 322 | } |
| 323 | |
| 324 | inline TVector3& TVector3::operator *= (Double_t a) { |
| 325 | fX *= a; |
| 326 | fY *= a; |
| 327 | fZ *= a; |
| 328 | return *this; |
| 329 | } |
| 330 | |
| 331 | inline Double_t TVector3::Dot(const TVector3 & p) const { |
| 332 | return fX*p.fX + fY*p.fY + fZ*p.fZ; |
| 333 | } |
| 334 | |
| 335 | inline TVector3 TVector3::Cross(const TVector3 & p) const { |
| 336 | return TVector3(fY*p.fZ-p.fY*fZ, fZ*p.fX-p.fZ*fX, fX*p.fY-p.fX*fY); |
| 337 | } |
| 338 | |
| 339 | inline Double_t TVector3::Mag2() const { return fX*fX + fY*fY + fZ*fZ; } |
| 340 | |
| 341 | |
| 342 | inline TVector3 TVector3::Orthogonal() const { |
| 343 | Double_t xx = fX < 0.0 ? -fX : fX; |
| 344 | Double_t yy = fY < 0.0 ? -fY : fY; |
| 345 | Double_t zz = fZ < 0.0 ? -fZ : fZ; |
| 346 | if (xx < yy) { |
| 347 | return xx < zz ? TVector3(0,fZ,-fY) : TVector3(fY,-fX,0); |
| 348 | } else { |
| 349 | return yy < zz ? TVector3(-fZ,0,fX) : TVector3(fY,-fX,0); |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | inline Double_t TVector3::Perp2() const { return fX*fX + fY*fY; } |
| 354 | |
| 355 | |
| 356 | inline Double_t TVector3::Pt() const { return Perp(); } |
| 357 | |
| 358 | inline Double_t TVector3::Perp2(const TVector3 & p) const { |
| 359 | Double_t tot = p.Mag2(); |
| 360 | Double_t ss = Dot(p); |
| 361 | Double_t per = Mag2(); |
| 362 | if (tot > 0.0) per -= ss*ss/tot; |
| 363 | if (per < 0) per = 0; |
| 364 | return per; |
| 365 | } |
| 366 | |
| 367 | inline Double_t TVector3::Pt(const TVector3 & p) const { |
| 368 | return Perp(p); |
| 369 | } |
| 370 | |
| 371 | inline Double_t TVector3::CosTheta() const { |
| 372 | Double_t ptot = Mag(); |
| 373 | return ptot == 0.0 ? 1.0 : fZ/ptot; |
| 374 | } |
| 375 | |
| 376 | inline void TVector3::SetMag(Double_t ma) { |
| 377 | Double_t factor = Mag(); |
| 378 | if (factor == 0) { |
| 379 | Warning("SetMag","zero vector can't be stretched"); |
| 380 | } else { |
| 381 | factor = ma/factor; |
| 382 | SetX(fX*factor); |
| 383 | SetY(fY*factor); |
| 384 | SetZ(fZ*factor); |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | inline void TVector3::SetPerp(Double_t r) { |
| 389 | Double_t p = Perp(); |
| 390 | if (p != 0.0) { |
| 391 | fX *= r/p; |
| 392 | fY *= r/p; |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | inline Double_t TVector3::DeltaPhi(const TVector3 & v) const { |
| 397 | return TVector2::Phi_mpi_pi(Phi()-v.Phi()); |
| 398 | } |
| 399 | |
| 400 | inline Double_t TVector3::Eta() const { |
| 401 | return PseudoRapidity(); |
| 402 | } |
| 403 | |
| 404 | inline Double_t TVector3::DrEtaPhi(const TVector3 & v) const{ |
| 405 | return DeltaR(v); |
| 406 | } |
| 407 | |
| 408 | |
| 409 | inline TVector2 TVector3::EtaPhiVector() const { |
| 410 | return TVector2 (Eta(),Phi()); |
| 411 | } |
| 412 | |
| 413 | inline TVector2 TVector3::XYvector() const { |
| 414 | return TVector2(fX,fY); |
| 415 | } |
| 416 | |
| 417 | |
| 418 | #endif |
| 1 | // @(#)root/base:$Id$ |
| 2 | // Author: Rene Brun 26/12/94 |
| 3 | |
| 4 | /************************************************************************* |
| 5 | * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * |
| 6 | * All rights reserved. * |
| 7 | * * |
| 8 | * For the licensing terms see $ROOTSYS/LICENSE. * |
| 9 | * For the list of contributors see $ROOTSYS/README/CREDITS. * |
| 10 | *************************************************************************/ |
| 11 | |
| 12 | #ifndef ROOT_TObject |
| 13 | #define ROOT_TObject |
| 14 | |
| 15 | |
| 16 | // #include "RConfigure.h" // included via Rtypes.h |
| 17 | #include "Rtypes.h" |
| 18 | #include "TStorage.h" |
| 19 | #include "TVersionCheck.h" |
| 20 | |
| 21 | #include <stdarg.h> |
| 22 | #include <string> |
| 23 | #include <iosfwd> |
| 24 | |
| 25 | #ifdef WIN32 |
| 26 | #undef RemoveDirectory |
| 27 | #endif |
| 28 | |
| 29 | class TList; |
| 30 | class TBrowser; |
| 31 | class TBuffer; |
| 32 | class TObjArray; |
| 33 | class TMethod; |
| 34 | class TTimer; |
| 35 | |
| 36 | namespace ROOT { |
| 37 | namespace Internal { |
| 38 | bool DeleteChangesMemoryImpl(); |
| 39 | }} |
| 40 | |
| 41 | class TObject { |
| 42 | |
| 43 | private: |
| 44 | UInt_t fUniqueID; ///< object unique identifier |
| 45 | UInt_t fBits; ///< bit field status word |
| 46 | |
| 47 | static Longptr_t fgDtorOnly; ///< object for which to call dtor only (i.e. no delete) |
| 48 | static Bool_t fgObjectStat; ///< if true keep track of objects in TObjectTable |
| 49 | |
| 50 | static void AddToTObjectTable(TObject *); |
| 51 | |
| 52 | protected: |
| 53 | void MakeZombie() { fBits |= kZombie; } |
| 54 | virtual void DoError(int level, const char *location, const char *fmt, va_list va) const; |
| 55 | |
| 56 | static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs = "", Bool_t empty_line = kTRUE); |
| 57 | |
| 58 | static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Bool_t empty_line = kFALSE); |
| 59 | |
| 60 | static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option = nullptr); |
| 61 | |
| 62 | public: |
| 63 | //----- Global bits (can be set for any object and should not be reused). |
| 64 | //----- Bits 0 - 13 are reserved as global bits. Bits 14 - 23 can be used |
| 65 | //----- in different class hierarchies (make sure there is no overlap in |
| 66 | //----- any given hierarchy). |
| 67 | enum EStatusBits { |
| 68 | kCanDelete = BIT(0)(1ULL << (0)), ///< if object in a list can be deleted |
| 69 | // 2 is taken by TDataMember |
| 70 | kMustCleanup = BIT(3)(1ULL << (3)), ///< if object destructor must call RecursiveRemove() |
| 71 | kIsReferenced = BIT(4)(1ULL << (4)), ///< if object is referenced by a TRef or TRefArray |
| 72 | kHasUUID = BIT(5)(1ULL << (5)), ///< if object has a TUUID (its fUniqueID=UUIDNumber) |
| 73 | kCannotPick = BIT(6)(1ULL << (6)), ///< if object in a pad cannot be picked |
| 74 | // 7 is taken by TAxis and TClass. |
| 75 | kNoContextMenu = BIT(8)(1ULL << (8)), ///< if object does not want context menu |
| 76 | // 9, 10 are taken by TH1, TF1, TAxis and a few others |
| 77 | // 12 is taken by TAxis |
| 78 | kInvalidObject = BIT(13)(1ULL << (13)) ///< if object ctor succeeded but object should not be used |
| 79 | }; |
| 80 | |
| 81 | enum EDeprecatedStatusBits { |
| 82 | kObjInCanvas = BIT(3)(1ULL << (3)) ///< for backward compatibility only, use kMustCleanup |
| 83 | }; |
| 84 | |
| 85 | //----- Private bits, clients can only test but not change them |
| 86 | enum { |
| 87 | kIsOnHeap = 0x01000000, ///< object is on heap |
| 88 | kNotDeleted = 0x02000000, ///< object has not been deleted |
| 89 | kZombie = 0x04000000, ///< object ctor failed |
| 90 | kInconsistent = 0x08000000, ///< class overload Hash but does call RecursiveRemove in destructor |
| 91 | // kCheckedHash = 0x10000000, ///< CheckedHash has check for the consistency of Hash/RecursiveRemove |
| 92 | kBitMask = 0x00ffffff |
| 93 | }; |
| 94 | |
| 95 | //----- Write() options |
| 96 | enum { |
| 97 | kSingleKey = BIT(0)(1ULL << (0)), ///< write collection with single key |
| 98 | kOverwrite = BIT(1)(1ULL << (1)), ///< overwrite existing object with same name |
| 99 | kWriteDelete = BIT(2)(1ULL << (2)), ///< write object, then delete previous key with same name |
| 100 | }; |
| 101 | |
| 102 | protected: |
| 103 | enum { // DeprectatedWriteOptions |
| 104 | ///< Used to request that the class specific implementation of `TObject::Write` |
| 105 | ///< just prepare the objects to be ready to be written but do not actually write |
| 106 | ///< them into the TBuffer. This is just for example by TBufferMerger to request |
| 107 | ///< that the TTree inside the file calls `TTree::FlushBaskets` (outside of the merging lock) |
| 108 | ///< and TBufferMerger will later ask for the write (inside the merging lock). |
| 109 | ///< To take advantage of this feature the class needs to overload `TObject::Write` |
| 110 | ///< and use this enum value accordingly. (See `TTree::Write` and `TObject::Write`) |
| 111 | ///< Do not use, this feature will be migrate to the Merge function (See TClass and TTree::Merge) |
| 112 | kOnlyPrepStep = BIT(3)(1ULL << (3)) |
| 113 | }; |
| 114 | |
| 115 | public: |
| 116 | |
| 117 | TObject(); |
| 118 | TObject(const TObject &object); |
| 119 | TObject &operator=(const TObject &rhs); |
| 120 | virtual ~TObject(); |
| 121 | |
| 122 | virtual void AppendPad(Option_t *option=""); |
| 123 | virtual void Browse(TBrowser *b); |
| 124 | virtual const char *ClassName() const; |
| 125 | virtual void Clear(Option_t * /*option*/ ="") { } |
| 126 | ULong_t CheckedHash(); // Not virtual |
| 127 | virtual TObject *Clone(const char *newname="") const; |
| 128 | virtual Int_t Compare(const TObject *obj) const; |
| 129 | virtual void Copy(TObject &object) const; |
| 130 | virtual void Delete(Option_t *option=""); // *MENU* |
| 131 | virtual Int_t DistancetoPrimitive(Int_t px, Int_t py); |
| 132 | virtual void Draw(Option_t *option=""); |
| 133 | virtual void DrawClass() const; // *MENU* |
| 134 | virtual TObject *DrawClone(Option_t *option="") const; // *MENU* |
| 135 | virtual void Dump() const; // *MENU* |
| 136 | virtual void Execute(const char *method, const char *params, Int_t *error = nullptr); |
| 137 | virtual void Execute(TMethod *method, TObjArray *params, Int_t *error = nullptr); |
| 138 | virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py); |
| 139 | virtual TObject *FindObject(const char *name) const; |
| 140 | virtual TObject *FindObject(const TObject *obj) const; |
| 141 | virtual Option_t *GetDrawOption() const; |
| 142 | virtual UInt_t GetUniqueID() const; |
| 143 | virtual const char *GetName() const; |
| 144 | virtual const char *GetIconName() const; |
| 145 | virtual Option_t *GetOption() const { return ""; } |
| 146 | virtual char *GetObjectInfo(Int_t px, Int_t py) const; |
| 147 | virtual const char *GetTitle() const; |
| 148 | virtual Bool_t HandleTimer(TTimer *timer); |
| 149 | Bool_t HasInconsistentHash() const; |
| 150 | virtual ULong_t Hash() const; |
| 151 | virtual Bool_t InheritsFrom(const char *classname) const; |
| 152 | virtual Bool_t InheritsFrom(const TClass *cl) const; |
| 153 | virtual void Inspect() const; // *MENU* |
| 154 | virtual Bool_t IsFolder() const; |
| 155 | virtual Bool_t IsEqual(const TObject *obj) const; |
| 156 | virtual Bool_t IsSortable() const { return kFALSE; } |
| 157 | |
| 158 | R__ALWAYS_INLINEinline __attribute__((always_inline)) Bool_t IsOnHeap() const { return TestBit(kIsOnHeap); } |
| 159 | R__ALWAYS_INLINEinline __attribute__((always_inline)) Bool_t IsZombie() const { return TestBit(kZombie); } |
| 160 | |
| 161 | virtual Bool_t Notify(); |
| 162 | virtual void ls(Option_t *option="") const; |
| 163 | virtual void Paint(Option_t *option=""); |
| 164 | virtual void Pop(); |
| 165 | virtual void Print(Option_t *option="") const; |
| 166 | virtual Int_t Read(const char *name); |
| 167 | virtual void RecursiveRemove(TObject *obj); |
| 168 | virtual void SaveAs(const char *filename="",Option_t *option="") const; // *MENU* |
| 169 | virtual void SavePrimitive(std::ostream &out, Option_t *option = ""); |
| 170 | virtual void SetDrawOption(Option_t *option=""); // *MENU* |
| 171 | virtual void SetUniqueID(UInt_t uid); |
| 172 | virtual void UseCurrentStyle(); |
| 173 | virtual Int_t Write(const char *name = nullptr, Int_t option = 0, Int_t bufsize = 0); |
| 174 | virtual Int_t Write(const char *name = nullptr, Int_t option = 0, Int_t bufsize = 0) const; |
| 175 | |
| 176 | /// IsDestructed |
| 177 | /// |
| 178 | /// \note This function must be non-virtual as it can be used on destructed (but |
| 179 | /// not yet modified) memory. This is used for example in TClonesArray to record |
| 180 | /// the element that have been destructed but not deleted and thus are ready for |
| 181 | /// re-use (by operator new with placement). |
| 182 | /// |
| 183 | /// \return true if this object's destructor has been run. |
| 184 | Bool_t IsDestructed() const { return !TestBit(kNotDeleted); } |
| 185 | |
| 186 | //----- operators |
| 187 | void *operator new(size_t sz) { return TStorage::ObjectAlloc(sz); } |
| 188 | void *operator new[](size_t sz) { return TStorage::ObjectAllocArray(sz); } |
| 189 | void *operator new(size_t sz, void *vp) { return TStorage::ObjectAlloc(sz, vp); } |
| 190 | void *operator new[](size_t sz, void *vp) { return TStorage::ObjectAlloc(sz, vp); } |
| 191 | void operator delete(void *ptr); |
| 192 | void operator delete[](void *ptr); |
| 193 | #ifdef R__SIZEDDELETE |
| 194 | // Sized deallocation. |
| 195 | void operator delete(void*, size_t); |
| 196 | void operator delete[](void*, size_t); |
| 197 | #endif |
| 198 | void operator delete(void *ptr, void *vp); |
| 199 | void operator delete[](void *ptr, void *vp); |
| 200 | |
| 201 | //----- bit manipulation |
| 202 | void SetBit(UInt_t f, Bool_t set); |
| 203 | void SetBit(UInt_t f) { fBits |= f & kBitMask; } |
| 204 | void ResetBit(UInt_t f) { fBits &= ~(f & kBitMask); } |
| 205 | R__ALWAYS_INLINEinline __attribute__((always_inline)) Bool_t TestBit(UInt_t f) const { return (Bool_t) ((fBits & f) != 0); } |
| 206 | Int_t TestBits(UInt_t f) const { return (Int_t) (fBits & f); } |
| 207 | void InvertBit(UInt_t f) { fBits ^= f & kBitMask; } |
| 208 | |
| 209 | //---- error handling |
| 210 | virtual void Info(const char *method, const char *msgfmt, ...) const |
| 211 | #if defined(__GNUC__4) |
| 212 | __attribute__((format(printf, 3, 4))) /* 1 is the this pointer */ |
| 213 | #endif |
| 214 | ; |
| 215 | virtual void Warning(const char *method, const char *msgfmt, ...) const |
| 216 | #if defined(__GNUC__4) |
| 217 | __attribute__((format(printf, 3, 4))) /* 1 is the this pointer */ |
| 218 | #endif |
| 219 | ; |
| 220 | virtual void Error(const char *method, const char *msgfmt, ...) const |
| 221 | #if defined(__GNUC__4) |
| 222 | __attribute__((format(printf, 3, 4))) /* 1 is the this pointer */ |
| 223 | #endif |
| 224 | ; |
| 225 | virtual void SysError(const char *method, const char *msgfmt, ...) const |
| 226 | #if defined(__GNUC__4) |
| 227 | __attribute__((format(printf, 3, 4))) /* 1 is the this pointer */ |
| 228 | #endif |
| 229 | ; |
| 230 | virtual void Fatal(const char *method, const char *msgfmt, ...) const |
| 231 | #if defined(__GNUC__4) |
| 232 | __attribute__((format(printf, 3, 4))) /* 1 is the this pointer */ |
| 233 | #endif |
| 234 | ; |
| 235 | |
| 236 | void AbstractMethod(const char *method) const; |
| 237 | void MayNotUse(const char *method) const; |
| 238 | void Obsolete(const char *method, const char *asOfVers, const char *removedFromVers) const; |
| 239 | |
| 240 | //---- static functions |
| 241 | static Longptr_t GetDtorOnly(); |
| 242 | static void SetDtorOnly(void *obj); |
| 243 | static Bool_t GetObjectStat(); |
| 244 | static void SetObjectStat(Bool_t stat); |
| 245 | |
| 246 | friend class TClonesArray; // needs to reset kNotDeleted in fBits |
| 247 | friend bool ROOT::Internal::DeleteChangesMemoryImpl(); |
| 248 | |
| 249 | ClassDef(TObject,1)private: static_assert(std::is_integral<decltype(1)>::value , "ClassDef(Inline) macro: the specified class version number is not an integer." ); virtual Bool_t CheckTObjectHashConsistency() const { static std::atomic<UChar_t> recurseBlocker(0); if (__builtin_expect (!!(recurseBlocker >= 2), 1)) { return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } else if (recurseBlocker == 1) { return false; } else if (recurseBlocker++ == 0) { :: ROOT::Internal::THashConsistencyHolder<decltype(*this)> ::fgHashConsistency = ::ROOT::Internal::HasConsistentHashMember ("TObject") || ::ROOT::Internal::HasConsistentHashMember(*IsA ()); ++recurseBlocker; return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } return false; } public: static constexpr Version_t Class_Version() { return 1 ; } virtual TClass *IsA() const { return TObject::Class(); } virtual void ShowMembers(TMemberInspector &insp) const { ::ROOT:: Class_ShowMembers(TObject::Class(), this, insp); } void StreamerNVirtual (TBuffer &ClassDef_StreamerNVirtual_b) { TObject::Streamer (ClassDef_StreamerNVirtual_b); } static const char *DeclFileName () { return "/cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root/TObject.h" ; } private: static atomic_TClass_ptr fgIsA; public: static int ImplFileLine(); static const char *ImplFileName(); static const char *Class_Name(); static TClass *Dictionary(); static TClass *Class(); virtual void Streamer(TBuffer&) ; static int DeclFileLine () { return 249; } //Basic ROOT object |
| 250 | }; |
| 251 | |
| 252 | //////////////////////////////////////////////////////////////////////////////// |
| 253 | /// TObject constructor. It sets the two data words of TObject to their |
| 254 | /// initial values. The unique ID is set to 0 and the status word is |
| 255 | /// set depending if the object is created on the stack or allocated |
| 256 | /// on the heap. Depending on the ROOT environment variable "Root.ObjStat" |
| 257 | /// (see TEnv) the object is added to the global TObjectTable for |
| 258 | /// bookkeeping. |
| 259 | |
| 260 | inline TObject::TObject() : fBits(kNotDeleted) // Need to leave fUniqueID unset |
| 261 | { |
| 262 | // This will be reported by valgrind as uninitialized memory reads for |
| 263 | // object created on the stack, use $ROOTSYS/etc/valgrind-root.supp |
| 264 | TStorage::UpdateIsOnHeap(fUniqueID, fBits); |
| 265 | |
| 266 | fUniqueID = 0; |
| 267 | |
| 268 | #ifdef R__WIN32 |
| 269 | if (R__unlikely(GetObjectStat())__builtin_expect(!!(GetObjectStat()), 0)) TObject::AddToTObjectTable(this); |
| 270 | #else |
| 271 | if (R__unlikely(fgObjectStat)__builtin_expect(!!(fgObjectStat), 0)) TObject::AddToTObjectTable(this); |
| 272 | #endif |
| 273 | } |
| 274 | |
| 275 | //////////////////////////////////////////////////////////////////////////////// |
| 276 | /// TObject copy ctor. |
| 277 | |
| 278 | inline TObject::TObject(const TObject &obj) |
| 279 | { |
| 280 | fBits = obj.fBits; |
| 281 | |
| 282 | // This will be reported by valgrind as uninitialized memory reads for |
| 283 | // object created on the stack, use $ROOTSYS/etc/valgrind-root.supp |
| 284 | TStorage::UpdateIsOnHeap(fUniqueID, fBits); |
| 285 | |
| 286 | fBits &= ~kIsReferenced; |
| 287 | fBits &= ~kCanDelete; |
| 288 | |
| 289 | // Set only after used in above call |
| 290 | fUniqueID = obj.fUniqueID; // when really unique don't copy |
| 291 | |
| 292 | #ifdef R__WIN32 |
| 293 | if (R__unlikely(GetObjectStat())__builtin_expect(!!(GetObjectStat()), 0)) TObject::AddToTObjectTable(this); |
| 294 | #else |
| 295 | if (R__unlikely(fgObjectStat)__builtin_expect(!!(fgObjectStat), 0)) TObject::AddToTObjectTable(this); |
| 296 | #endif |
| 297 | } |
| 298 | |
| 299 | //////////////////////////////////////////////////////////////////////////////// |
| 300 | /// TObject assignment operator. |
| 301 | |
| 302 | inline TObject &TObject::operator=(const TObject &rhs) |
| 303 | { |
| 304 | if (R__likely(this != &rhs)__builtin_expect(!!(this != &rhs), 1)) { |
| 305 | fUniqueID = rhs.fUniqueID; // when really unique don't copy |
| 306 | if (IsOnHeap()) { // test uses fBits so don't move next line |
| 307 | fBits = rhs.fBits; |
| 308 | fBits |= kIsOnHeap; |
| 309 | } else { |
| 310 | fBits = rhs.fBits; |
| 311 | fBits &= ~kIsOnHeap; |
| 312 | } |
| 313 | fBits &= ~kIsReferenced; |
| 314 | fBits &= ~kCanDelete; |
| 315 | } |
| 316 | return *this; |
| 317 | } |
| 318 | |
| 319 | |
| 320 | //////////////////////////////////////////////////////////////////////////////// |
| 321 | /// @brief Check and record whether this class has a consistent |
| 322 | /// Hash/RecursiveRemove setup (*) and then return the regular Hash value for |
| 323 | /// this object. The intent is for this routine to be called instead of directly |
| 324 | /// calling the function Hash during "insert" operations. See TObject::HasInconsistenTObjectHash(); |
| 325 | /// |
| 326 | /// (*) The setup is consistent when all classes in the class hierarchy that overload |
| 327 | /// TObject::Hash do call ROOT::CallRecursiveRemoveIfNeeded in their destructor. |
| 328 | /// i.e. it is safe to call the Hash virtual function during the RecursiveRemove operation. |
| 329 | |
| 330 | inline ULong_t TObject::CheckedHash() |
| 331 | { |
| 332 | // Testing and recording whether we already called HasInconstistentTObjectHash |
| 333 | // for this object could save some cpu cycles in some circuntances (at the cost |
| 334 | // of reserving yet another bit). |
| 335 | // For each insert (CheckedHash is called only for insert in THashList/THashTable), it |
| 336 | // cost one memory fetch, one arithmetic operation and one branching. |
| 337 | // This save a virtual function call which itself contains a static variable memory |
| 338 | // fetch, a branching (of whether the static was already set or not). |
| 339 | // Given that a virtual function call is essentially 2 memory fetches (virtual table |
| 340 | // location and then content), one arithmetic operation and one function call/jump), |
| 341 | // we guess-estimate that the version recording-then-testing-prior-check would start |
| 342 | // saving cpu cycle when each object is inserted in average 1.5 times in a THashList/THashTable. |
| 343 | |
| 344 | // if ( !fBits & kCheckedHash) { |
| 345 | if (!CheckTObjectHashConsistency()) |
| 346 | fBits |= kInconsistent; |
| 347 | // fBits &= kChecked; |
| 348 | //} |
| 349 | return Hash(); |
| 350 | } |
| 351 | |
| 352 | //////////////////////////////////////////////////////////////////////////////// |
| 353 | /// @brief Return true is the type of this object is *known* to have an |
| 354 | /// inconsistent setup for Hash and RecursiveRemove (i.e. missing call to |
| 355 | /// RecursiveRemove in destructor). |
| 356 | /// |
| 357 | /// Note: Since the consistency is only tested for during inserts, this |
| 358 | /// routine will return true for object that have never been inserted |
| 359 | /// whether or not they have a consistent setup. This has no negative |
| 360 | /// side-effect as searching for the object with the right or wrong |
| 361 | /// Hash will always yield a not-found answer (Since anyway no hash |
| 362 | /// can be guaranteed unique, there is always a check) |
| 363 | |
| 364 | inline Bool_t TObject::HasInconsistentHash() const |
| 365 | { |
| 366 | return fBits & kInconsistent; |
| 367 | } |
| 368 | |
| 369 | // Global bits (can be set for any object and should not be reused). |
| 370 | // Only here for backward compatibility reasons. |
| 371 | // For detailed description see TObject::EStatusBits above. |
| 372 | enum EObjBits { |
| 373 | kCanDelete = TObject::kCanDelete, |
| 374 | kMustCleanup = TObject::kMustCleanup, |
| 375 | kObjInCanvas = TObject::kObjInCanvas, |
| 376 | kIsReferenced = TObject::kIsReferenced, |
| 377 | kHasUUID = TObject::kHasUUID, |
| 378 | kCannotPick = TObject::kCannotPick, |
| 379 | kNoContextMenu = TObject::kNoContextMenu, |
| 380 | kInvalidObject = TObject::kInvalidObject |
| 381 | }; |
| 382 | |
| 383 | namespace cling { |
| 384 | std::string printValue(TObject *val); |
| 385 | } |
| 386 | |
| 387 | namespace ROOT { |
| 388 | |
| 389 | namespace Internal { |
| 390 | bool DeleteChangesMemory(); |
| 391 | } // Internal |
| 392 | |
| 393 | namespace Detail { |
| 394 | |
| 395 | |
| 396 | /// @brief Check if the TObject's memory has been deleted. |
| 397 | /// @warning This should be only used for error mitigation as the answer is only |
| 398 | /// sometimes correct. It actually just checks whether the object has been |
| 399 | /// deleted, so this will falsely return true for an object that has |
| 400 | /// been destructed but its memory has not been deleted. This will return an |
| 401 | /// undefined value if the memory is re-used between the deletion and the check. |
| 402 | /// i.e. This is useful to prevent a segmentation fault in case where the problem |
| 403 | /// can be detected when the deletion and the usage are 'close-by' |
| 404 | /// @warning In enviroment where delete taints (changes) the memory, this function |
| 405 | /// always returns false as the marker left by ~TObject will be overwritten. |
| 406 | /// @param obj The memory to check |
| 407 | /// @return true if the object has been destructed and it can be inferred that it has been deleted |
| 408 | R__ALWAYS_INLINEinline __attribute__((always_inline)) bool HasBeenDeleted(const TObject *obj) { |
| 409 | return !ROOT::Internal::DeleteChangesMemory() && obj->IsDestructed(); |
| 410 | } |
| 411 | |
| 412 | }} // ROOT::Details |
| 413 | |
| 414 | #endif |
| 1 | // @(#)root/base:$Id$ | |||
| 2 | // Author: Fons Rademakers 29/07/95 | |||
| 3 | ||||
| 4 | /************************************************************************* | |||
| 5 | * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * | |||
| 6 | * All rights reserved. * | |||
| 7 | * * | |||
| 8 | * For the licensing terms see $ROOTSYS/LICENSE. * | |||
| 9 | * For the list of contributors see $ROOTSYS/README/CREDITS. * | |||
| 10 | *************************************************************************/ | |||
| 11 | ||||
| 12 | #ifndef ROOT_TStorage | |||
| 13 | #define ROOT_TStorage | |||
| 14 | ||||
| 15 | ||||
| 16 | ////////////////////////////////////////////////////////////////////////// | |||
| 17 | // // | |||
| 18 | // TStorage // | |||
| 19 | // // | |||
| 20 | // Storage manager. // | |||
| 21 | // // | |||
| 22 | ////////////////////////////////////////////////////////////////////////// | |||
| 23 | ||||
| 24 | // #include "RConfigure.h" // included via Rtypes.h | |||
| 25 | #include "Rtypes.h" | |||
| 26 | ||||
| 27 | typedef void (*FreeHookFun_t)(void*, void *addr, size_t); | |||
| 28 | typedef void *(*ReAllocFun_t)(void*, size_t); | |||
| 29 | typedef void *(*ReAllocCFun_t)(void*, size_t, size_t); | |||
| 30 | typedef char *(*ReAllocCharFun_t)(char*, size_t, size_t); | |||
| 31 | ||||
| 32 | ||||
| 33 | class TStorage { | |||
| 34 | ||||
| 35 | private: | |||
| 36 | static size_t fgMaxBlockSize; // largest block allocated | |||
| 37 | static FreeHookFun_t fgFreeHook; // function called on free | |||
| 38 | static void *fgFreeHookData; // data used by this function | |||
| 39 | static ReAllocCFun_t fgReAllocCHook; // custom ReAlloc with length check | |||
| 40 | static Bool_t fgHasCustomNewDelete; // true if using ROOT's new/delete | |||
| 41 | ||||
| 42 | //----- Private bits, clients can only test but not change them | |||
| 43 | enum { | |||
| 44 | kIsOnHeap = 0x01000000, ///< object is on heap | |||
| 45 | }; | |||
| 46 | ||||
| 47 | public: | |||
| 48 | static const UInt_t kObjectAllocMemValue = 0x99999999; | |||
| 49 | // magic number for ObjectAlloc | |||
| 50 | ||||
| 51 | public: | |||
| 52 | virtual ~TStorage() { } | |||
| 53 | ||||
| 54 | static FreeHookFun_t GetFreeHook(); | |||
| 55 | static void *GetFreeHookData(); | |||
| 56 | static size_t GetMaxBlockSize(); | |||
| 57 | static void *Alloc(size_t size); | |||
| 58 | static void Dealloc(void *ptr); | |||
| 59 | static void *ReAlloc(void *vp, size_t size, size_t oldsize); | |||
| 60 | static char *ReAllocChar(char *vp, size_t size, size_t oldsize); | |||
| 61 | static Int_t *ReAllocInt(Int_t *vp, size_t size, size_t oldsize); | |||
| 62 | static void *ObjectAlloc(size_t size); | |||
| 63 | static void *ObjectAllocArray(size_t size); | |||
| 64 | static void *ObjectAlloc(size_t size, void *vp); | |||
| 65 | static void ObjectDealloc(void *vp); | |||
| 66 | #ifdef R__SIZEDDELETE | |||
| 67 | static void ObjectDealloc(void *vp, size_t size); | |||
| 68 | #endif | |||
| 69 | static void ObjectDealloc(void *vp, void *ptr); | |||
| 70 | ||||
| 71 | static void EnterStat(size_t size, void *p); | |||
| 72 | static void RemoveStat(void *p); | |||
| 73 | static void PrintStatistics(); | |||
| 74 | static void SetMaxBlockSize(size_t size); | |||
| 75 | static void SetFreeHook(FreeHookFun_t func, void *data); | |||
| 76 | static void SetReAllocHooks(ReAllocFun_t func1, ReAllocCFun_t func2); | |||
| 77 | static void SetCustomNewDelete(); | |||
| 78 | static void EnableStatistics(int size= -1, int ix= -1); | |||
| 79 | ||||
| 80 | static Bool_t HasCustomNewDelete(); | |||
| 81 | ||||
| 82 | static Bool_t FilledByObjectAlloc(volatile const UInt_t* const member); | |||
| 83 | static void UpdateIsOnHeap(volatile const UInt_t &uniqueID, volatile UInt_t &bits); | |||
| 84 | ||||
| 85 | ClassDef(TStorage,0)private: static_assert(std::is_integral<decltype(0)>::value , "ClassDef(Inline) macro: the specified class version number is not an integer." ); virtual Bool_t CheckTObjectHashConsistency() const { static std::atomic<UChar_t> recurseBlocker(0); if (__builtin_expect (!!(recurseBlocker >= 2), 1)) { return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } else if (recurseBlocker == 1) { return false; } else if (recurseBlocker++ == 0) { :: ROOT::Internal::THashConsistencyHolder<decltype(*this)> ::fgHashConsistency = ::ROOT::Internal::HasConsistentHashMember ("TStorage") || ::ROOT::Internal::HasConsistentHashMember(*IsA ()); ++recurseBlocker; return ::ROOT::Internal::THashConsistencyHolder <decltype(*this)>::fgHashConsistency; } return false; } public: static constexpr Version_t Class_Version() { return 0 ; } virtual TClass *IsA() const { return TStorage::Class(); } virtual void ShowMembers(TMemberInspector &insp) const { ::ROOT::Class_ShowMembers(TStorage::Class(), this, insp); } void StreamerNVirtual(TBuffer &ClassDef_StreamerNVirtual_b) { TStorage::Streamer(ClassDef_StreamerNVirtual_b); } static const char *DeclFileName() { return "/cvmfs/belle.cern.ch/el9/externals/v02-04-00/include/root/TStorage.h" ; } private: static atomic_TClass_ptr fgIsA; public: static int ImplFileLine(); static const char *ImplFileName(); static const char *Class_Name(); static TClass *Dictionary(); static TClass *Class(); virtual void Streamer(TBuffer&) ; static int DeclFileLine () { return 85; } //Storage manager class | |||
| 86 | }; | |||
| 87 | ||||
| 88 | inline Bool_t TStorage::FilledByObjectAlloc(volatile const UInt_t *const member) { | |||
| 89 | //called by TObject's constructor to determine if object was created by call to new | |||
| 90 | ||||
| 91 | // This technique is necessary as there is one stack per thread | |||
| 92 | // and we can not rely on comparison with the current stack memory position. | |||
| 93 | // Note that a false positive (this routine returning true for an object | |||
| 94 | // created on the stack) requires the previous stack value to have been | |||
| 95 | // set to exactly kObjectAllocMemValue at exactly the right position (i.e. | |||
| 96 | // where this object's fUniqueID is located. | |||
| 97 | // The consequence of a false positive will be visible if and only if | |||
| 98 | // the object is auto-added to a TDirectory (i.e. TTree, TH*, TGraph, | |||
| 99 | // TEventList) or explicitly added to the directory by the user | |||
| 100 | // and | |||
| 101 | // the TDirectory (or TFile) object is created on the stack *before* | |||
| 102 | // the object. | |||
| 103 | // The consequence would be that those objects would be deleted twice, once | |||
| 104 | // by the TDirectory and once automatically when going out of scope | |||
| 105 | // (and thus quite visible). A false negative (which is not possible with | |||
| 106 | // this implementation) would have been a silent memory leak. | |||
| 107 | ||||
| 108 | // This will be reported by valgrind as uninitialized memory reads for | |||
| 109 | // object created on the stack, use $ROOTSYS/etc/valgrind-root.supp | |||
| 110 | R__INTENTIONALLY_UNINIT_BEGIN | |||
| 111 | return *member == kObjectAllocMemValue; // NOLINT | |||
| ||||
| 112 | R__INTENTIONALLY_UNINIT_END | |||
| 113 | } | |||
| 114 | ||||
| 115 | // Assign the kIsOnHeap bit in 'bits' based on the pattern seen in uniqueID. | |||
| 116 | // See Storage::FilledByObjectAlloc for details. | |||
| 117 | // This routine is marked as inline with attribute noinline so that it never | |||
| 118 | // inlined and thus can be used in a valgrind suppression file to suppress | |||
| 119 | // the known/intentional uninitialized memory read but still be a 'quick' | |||
| 120 | // function call to avoid losing performance at object creation. | |||
| 121 | // Moving the function into the source file, results in doubling of the | |||
| 122 | // overhead (compared to inlining) | |||
| 123 | R__NEVER_INLINEinline __attribute__((noinline)) void TStorage::UpdateIsOnHeap(volatile const UInt_t &uniqueID, volatile UInt_t &bits) { | |||
| 124 | if (TStorage::FilledByObjectAlloc(&uniqueID)) | |||
| 125 | bits = bits | kIsOnHeap; | |||
| 126 | else | |||
| 127 | bits = bits & ~kIsOnHeap; | |||
| 128 | } | |||
| 129 | ||||
| 130 | ||||
| 131 | inline size_t TStorage::GetMaxBlockSize() { return fgMaxBlockSize; } | |||
| 132 | ||||
| 133 | inline void TStorage::SetMaxBlockSize(size_t size) { fgMaxBlockSize = size; } | |||
| 134 | ||||
| 135 | inline FreeHookFun_t TStorage::GetFreeHook() { return fgFreeHook; } | |||
| 136 | ||||
| 137 | namespace ROOT { | |||
| 138 | namespace Internal { | |||
| 139 | using FreeIfTMapFile_t = bool(void*); | |||
| 140 | using GetMapFileMapllocDesc_t = void *(void*); | |||
| 141 | R__EXTERNextern FreeIfTMapFile_t *gFreeIfTMapFile; | |||
| 142 | R__EXTERNextern GetMapFileMapllocDesc_t *gGetMapFileMallocDesc; | |||
| 143 | R__EXTERNextern void *gMmallocDesc; | |||
| 144 | } | |||
| 145 | } | |||
| 146 | ||||
| 147 | #endif |