From 370be031fd2ad56ea37f0bd3e33326771c667aef Mon Sep 17 00:00:00 2001 From: morsch Date: Thu, 21 May 2009 19:31:23 +0000 Subject: [PATCH] Fastjet headers --- JETAN/fastjet/CDFJetCluPlugin.hh | 15 + JETAN/fastjet/CDFMidPointPlugin.hh | 15 + JETAN/fastjet/FjClusterSequence.hh | 83 ++ JETAN/fastjet/FjPseudoJet.hh | 52 + JETAN/fastjet/fastjet/ActiveAreaSpec.hh | 45 + JETAN/fastjet/fastjet/AreaDefinition.hh | 152 +++ JETAN/fastjet/fastjet/CDFJetCluPlugin.hh | 107 ++ JETAN/fastjet/fastjet/CDFMidPointPlugin.hh | 169 ++++ JETAN/fastjet/fastjet/CircularRange.hh | 109 +++ JETAN/fastjet/fastjet/ClusterSequence.hh | 919 ++++++++++++++++++ .../ClusterSequence1GhostPassiveArea.hh | 101 ++ .../fastjet/ClusterSequenceActiveArea.hh | 221 +++++ ...ClusterSequenceActiveAreaExplicitGhosts.hh | 235 +++++ JETAN/fastjet/fastjet/ClusterSequenceArea.hh | 244 +++++ .../fastjet/ClusterSequenceAreaBase.hh | 257 +++++ .../fastjet/ClusterSequencePassiveArea.hh | 93 ++ .../fastjet/ClusterSequenceVoronoiArea.hh | 117 +++ .../fastjet/ClusterSequenceWithArea.hh | 45 + JETAN/fastjet/fastjet/EECambridgePlugin.hh | 87 ++ JETAN/fastjet/fastjet/Error.hh | 65 ++ JETAN/fastjet/fastjet/GhostedAreaSpec.hh | 197 ++++ JETAN/fastjet/fastjet/JadePlugin.hh | 101 ++ JETAN/fastjet/fastjet/JetDefinition.hh | 437 +++++++++ JETAN/fastjet/fastjet/NNH.hh | 368 +++++++ JETAN/fastjet/fastjet/NestedDefsPlugin.hh | 79 ++ JETAN/fastjet/fastjet/PseudoJet.hh | 339 +++++++ JETAN/fastjet/fastjet/RangeDefinition.hh | 169 ++++ JETAN/fastjet/fastjet/SISConeBasePlugin.hh | 179 ++++ JETAN/fastjet/fastjet/SISConePlugin.hh | 214 ++++ .../fastjet/fastjet/SISConeSphericalPlugin.hh | 188 ++++ JETAN/fastjet/fastjet/config.h | 12 + JETAN/fastjet/fastjet/config_auto.h | 89 ++ JETAN/fastjet/fastjet/config_win.h | 11 + JETAN/fastjet/fastjet/internal/BasicRandom.hh | 181 ++++ .../fastjet/fastjet/internal/ClosestPair2D.hh | 234 +++++ .../fastjet/internal/ClosestPair2DBase.hh | 129 +++ .../fastjet/internal/Dnn2piCylinder.hh | 267 +++++ .../fastjet/internal/Dnn3piCylinder.hh | 257 +++++ .../fastjet/internal/Dnn4piCylinder.hh | 126 +++ JETAN/fastjet/fastjet/internal/DnnPlane.hh | 163 ++++ .../internal/DynamicNearestNeighbours.hh | 171 ++++ .../fastjet/internal/LimitedWarning.hh | 66 ++ JETAN/fastjet/fastjet/internal/MinHeap.hh | 90 ++ JETAN/fastjet/fastjet/internal/SearchTree.hh | 751 ++++++++++++++ .../fastjet/fastjet/internal/Triangulation.hh | 100 ++ JETAN/fastjet/fastjet/internal/Voronoi.hh | 320 ++++++ JETAN/fastjet/fastjet/internal/base.hh | 40 + JETAN/fastjet/fastjet/internal/numconsts.hh | 53 + JETAN/fastjet/fastjet/version.hh | 43 + JETAN/fastjet/siscone/area.h | 139 +++ JETAN/fastjet/siscone/circulator.h | 90 ++ JETAN/fastjet/siscone/config.h | 59 ++ JETAN/fastjet/siscone/defines.h | 128 +++ JETAN/fastjet/siscone/geom_2d.h | 179 ++++ JETAN/fastjet/siscone/hash.h | 122 +++ JETAN/fastjet/siscone/momentum.h | 157 +++ JETAN/fastjet/siscone/protocones.h | 271 ++++++ JETAN/fastjet/siscone/quadtree.h | 124 +++ JETAN/fastjet/siscone/ranlux.h | 49 + JETAN/fastjet/siscone/reference.h | 111 +++ JETAN/fastjet/siscone/siscone.h | 131 +++ JETAN/fastjet/siscone/siscone_error.h | 64 ++ JETAN/fastjet/siscone/spherical/geom_2d.h | 111 +++ JETAN/fastjet/siscone/spherical/hash.h | 114 +++ JETAN/fastjet/siscone/spherical/momentum.h | 312 ++++++ JETAN/fastjet/siscone/spherical/protocones.h | 262 +++++ JETAN/fastjet/siscone/spherical/siscone.h | 131 +++ JETAN/fastjet/siscone/spherical/split_merge.h | 401 ++++++++ JETAN/fastjet/siscone/spherical/vicinity.h | 149 +++ JETAN/fastjet/siscone/split_merge.h | 401 ++++++++ JETAN/fastjet/siscone/vicinity.h | 156 +++ 71 files changed, 12166 insertions(+) create mode 100644 JETAN/fastjet/CDFJetCluPlugin.hh create mode 100644 JETAN/fastjet/CDFMidPointPlugin.hh create mode 100644 JETAN/fastjet/FjClusterSequence.hh create mode 100644 JETAN/fastjet/FjPseudoJet.hh create mode 100644 JETAN/fastjet/fastjet/ActiveAreaSpec.hh create mode 100644 JETAN/fastjet/fastjet/AreaDefinition.hh create mode 100644 JETAN/fastjet/fastjet/CDFJetCluPlugin.hh create mode 100644 JETAN/fastjet/fastjet/CDFMidPointPlugin.hh create mode 100644 JETAN/fastjet/fastjet/CircularRange.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequence.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequence1GhostPassiveArea.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequenceActiveArea.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequenceArea.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequenceAreaBase.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequencePassiveArea.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequenceVoronoiArea.hh create mode 100644 JETAN/fastjet/fastjet/ClusterSequenceWithArea.hh create mode 100644 JETAN/fastjet/fastjet/EECambridgePlugin.hh create mode 100644 JETAN/fastjet/fastjet/Error.hh create mode 100644 JETAN/fastjet/fastjet/GhostedAreaSpec.hh create mode 100644 JETAN/fastjet/fastjet/JadePlugin.hh create mode 100644 JETAN/fastjet/fastjet/JetDefinition.hh create mode 100644 JETAN/fastjet/fastjet/NNH.hh create mode 100644 JETAN/fastjet/fastjet/NestedDefsPlugin.hh create mode 100644 JETAN/fastjet/fastjet/PseudoJet.hh create mode 100644 JETAN/fastjet/fastjet/RangeDefinition.hh create mode 100644 JETAN/fastjet/fastjet/SISConeBasePlugin.hh create mode 100644 JETAN/fastjet/fastjet/SISConePlugin.hh create mode 100644 JETAN/fastjet/fastjet/SISConeSphericalPlugin.hh create mode 100644 JETAN/fastjet/fastjet/config.h create mode 100644 JETAN/fastjet/fastjet/config_auto.h create mode 100644 JETAN/fastjet/fastjet/config_win.h create mode 100644 JETAN/fastjet/fastjet/internal/BasicRandom.hh create mode 100644 JETAN/fastjet/fastjet/internal/ClosestPair2D.hh create mode 100644 JETAN/fastjet/fastjet/internal/ClosestPair2DBase.hh create mode 100644 JETAN/fastjet/fastjet/internal/Dnn2piCylinder.hh create mode 100644 JETAN/fastjet/fastjet/internal/Dnn3piCylinder.hh create mode 100644 JETAN/fastjet/fastjet/internal/Dnn4piCylinder.hh create mode 100644 JETAN/fastjet/fastjet/internal/DnnPlane.hh create mode 100644 JETAN/fastjet/fastjet/internal/DynamicNearestNeighbours.hh create mode 100644 JETAN/fastjet/fastjet/internal/LimitedWarning.hh create mode 100644 JETAN/fastjet/fastjet/internal/MinHeap.hh create mode 100644 JETAN/fastjet/fastjet/internal/SearchTree.hh create mode 100644 JETAN/fastjet/fastjet/internal/Triangulation.hh create mode 100644 JETAN/fastjet/fastjet/internal/Voronoi.hh create mode 100644 JETAN/fastjet/fastjet/internal/base.hh create mode 100644 JETAN/fastjet/fastjet/internal/numconsts.hh create mode 100644 JETAN/fastjet/fastjet/version.hh create mode 100644 JETAN/fastjet/siscone/area.h create mode 100644 JETAN/fastjet/siscone/circulator.h create mode 100644 JETAN/fastjet/siscone/config.h create mode 100644 JETAN/fastjet/siscone/defines.h create mode 100644 JETAN/fastjet/siscone/geom_2d.h create mode 100644 JETAN/fastjet/siscone/hash.h create mode 100644 JETAN/fastjet/siscone/momentum.h create mode 100644 JETAN/fastjet/siscone/protocones.h create mode 100644 JETAN/fastjet/siscone/quadtree.h create mode 100644 JETAN/fastjet/siscone/ranlux.h create mode 100644 JETAN/fastjet/siscone/reference.h create mode 100644 JETAN/fastjet/siscone/siscone.h create mode 100644 JETAN/fastjet/siscone/siscone_error.h create mode 100644 JETAN/fastjet/siscone/spherical/geom_2d.h create mode 100644 JETAN/fastjet/siscone/spherical/hash.h create mode 100644 JETAN/fastjet/siscone/spherical/momentum.h create mode 100644 JETAN/fastjet/siscone/spherical/protocones.h create mode 100644 JETAN/fastjet/siscone/spherical/siscone.h create mode 100644 JETAN/fastjet/siscone/spherical/split_merge.h create mode 100644 JETAN/fastjet/siscone/spherical/vicinity.h create mode 100644 JETAN/fastjet/siscone/split_merge.h create mode 100644 JETAN/fastjet/siscone/vicinity.h diff --git a/JETAN/fastjet/CDFJetCluPlugin.hh b/JETAN/fastjet/CDFJetCluPlugin.hh new file mode 100644 index 00000000000..88f8b466946 --- /dev/null +++ b/JETAN/fastjet/CDFJetCluPlugin.hh @@ -0,0 +1,15 @@ +// for backwards compatibility fastjet/CDFJetCluPlugin.hh can also be +// accessed through this file without specifying "fastjet/"; this is +// however deprecated for new code, and is not guaranteed to work from +// release 3.x onwards +#ifndef __BACKWARD_WARNING__ +#define __BACKWARD_WARNING__ +#warning This file includes at least one deprecated FastJet header. \ +Please consider including FastJet plugins using "fastjet/...Plugin.hh" \ +For backwards compatibility fastjet/...Plugin.hh can also be accessed \ +through this file without specifying "fastjet/"; this is however \ +deprecated for new work, and is not guaranteed to work from release \ +3.x onwards. +#endif + +#include "fastjet/CDFJetCluPlugin.hh" diff --git a/JETAN/fastjet/CDFMidPointPlugin.hh b/JETAN/fastjet/CDFMidPointPlugin.hh new file mode 100644 index 00000000000..edf77b78212 --- /dev/null +++ b/JETAN/fastjet/CDFMidPointPlugin.hh @@ -0,0 +1,15 @@ +// for backwards compatibility fastjet/CDFMidPointPlugin.hh can also be +// accessed through this file without specifying "fastjet/"; this is +// however deprecated for new code, and is not guaranteed to work from +// release 3.x onwards +#ifndef __BACKWARD_WARNING__ +#define __BACKWARD_WARNING__ +#warning This file includes at least one deprecated FastJet header. \ +Please consider including FastJet plugins using "fastjet/...Plugin.hh" \ +For backwards compatibility fastjet/...Plugin.hh can also be accessed \ +through this file without specifying "fastjet/"; this is however \ +deprecated for new work, and is not guaranteed to work from release \ +3.x onwards. +#endif + +#include "fastjet/CDFMidPointPlugin.hh" diff --git a/JETAN/fastjet/FjClusterSequence.hh b/JETAN/fastjet/FjClusterSequence.hh new file mode 100644 index 00000000000..88a9f4f5662 --- /dev/null +++ b/JETAN/fastjet/FjClusterSequence.hh @@ -0,0 +1,83 @@ +//STARTHEADER +// $Id: FjClusterSequence.hh 945 2007-11-09 08:46:04Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FJCLUSTERSEQUENCE_HH__ +#define __FJCLUSTERSEQUENCE_HH__ + + +#ifndef __BACKWARD_WARNING_V1__ +#define __BACKWARD_WARNING_V1__ +#warning This file includes at least one deprecated FastJet header from v1. \ +All fastjet components (including plugins) should now be accessed by including fastjet/... +#endif // __BACKWARD_WARNING_V1__ + +#include "fastjet/ClusterSequence.hh" + + +/// typedef which provides backwards compatibility for +/// user programs based on the v1 interface +typedef fastjet::ClusterSequence FjClusterSequence; + +/// typedef which provides backwards compatibility for +/// user programs based on the v1 interface +typedef fastjet::Strategy FjStrategy; + + +// below follow redefinitions of all the strategy constants +// to allow a v1 legacy user to access the strategy names +// as before + +/// experimental ... +const FjStrategy N2MinHeapTiled = fastjet::N2MinHeapTiled; +/// fastest from about 50..10^4 +const FjStrategy N2Tiled = fastjet::N2Tiled; +/// legacy +const FjStrategy N2PoorTiled = fastjet::N2PoorTiled; +/// fastest below 50 +const FjStrategy N2Plain = fastjet::N2Plain; +/// worse even than the usual N^3 algorithms +const FjStrategy N3Dumb = fastjet::N3Dumb; +/// automatic selection of the best (based on N) +const FjStrategy Best = fastjet::Best; +/// best of the NlnN variants -- best overall for N>10^4 +const FjStrategy NlnN = fastjet::NlnN; +/// legacy N ln N using 3pi coverage of cylinder +const FjStrategy NlnN3pi = fastjet::NlnN3pi; +/// legacy N ln N using 4pi coverage of cylinder +const FjStrategy NlnN4pi = fastjet::NlnN4pi; +/// Chan's closest pair method (in a variant with 4pi coverage), +/// for use exclusively with the Cambridge algorithm +const FjStrategy NlnNCam4pi = fastjet::NlnNCam4pi; +const FjStrategy NlnNCam2pi2R = fastjet::NlnNCam2pi2R; +const FjStrategy NlnNCam = fastjet::NlnNCam; // 2piMultD + + +#endif //__FJCLUSTERSEQUENCE_HH__ diff --git a/JETAN/fastjet/FjPseudoJet.hh b/JETAN/fastjet/FjPseudoJet.hh new file mode 100644 index 00000000000..8a8a6d11b81 --- /dev/null +++ b/JETAN/fastjet/FjPseudoJet.hh @@ -0,0 +1,52 @@ +//STARTHEADER +// $Id: FjPseudoJet.hh 945 2007-11-09 08:46:04Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FJPSEUDOJET_HH__ +#define __FJPSEUDOJET_HH__ + +#ifndef __BACKWARD_WARNING_V1__ +#define __BACKWARD_WARNING_V1__ +#warning This file includes at least one deprecated FastJet header from v1. \ +All fastjet components (including plugins) should now be accessed by including fastjet/... +#endif // __BACKWARD_WARNING_V1__ + + +#include "fastjet/PseudoJet.hh" + +/// typedef which provides backwards compatibility for +/// user programs based on the v1 interface +typedef fastjet::PseudoJet FjPseudoJet; + +/// thought not officially "declared" in the docuementation, +/// this was used in the v1 fastjet_timing.cc example program, +/// so in order to ensure that it still compiles we define it... +const double twopi = fastjet::twopi; + +#endif //__FJPSEUDOJET_HH__ diff --git a/JETAN/fastjet/fastjet/ActiveAreaSpec.hh b/JETAN/fastjet/fastjet/ActiveAreaSpec.hh new file mode 100644 index 00000000000..f97acc44403 --- /dev/null +++ b/JETAN/fastjet/fastjet/ActiveAreaSpec.hh @@ -0,0 +1,45 @@ +//STARTHEADER +// $Id: ActiveAreaSpec.hh 633 2007-05-10 15:59:09Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_ACTIVEAREASPEC_HH__ +#define __FASTJET_ACTIVEAREASPEC_HH__ +#include "fastjet/GhostedAreaSpec.hh" + + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// just provide a typedef for backwards compatibility with programs +/// based on versions 2.0 and 2.1 of fastjet +typedef GhostedAreaSpec ActiveAreaSpec; + +} // fastjet namespace + +#endif // __FASTJET_ACTIVEAREASPEC_HH__ diff --git a/JETAN/fastjet/fastjet/AreaDefinition.hh b/JETAN/fastjet/fastjet/AreaDefinition.hh new file mode 100644 index 00000000000..e1bb0e7a9c4 --- /dev/null +++ b/JETAN/fastjet/fastjet/AreaDefinition.hh @@ -0,0 +1,152 @@ +//STARTHEADER +// $Id: AreaDefinition.hh 635 2007-05-10 18:37:10Z salam $ +// +// Copyright (c) 2006-2007, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_AREADEFINITION_HH__ +#define __FASTJET_AREADEFINITION_HH__ + +#include "fastjet/GhostedAreaSpec.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +// +/// class for holding a "Voronoi area" specification; an area will be +/// assigned to each particle, which is the area of the intersection +/// of the particle's Voronoi cell with a circle of radius +/// R*effective_Rfact. +/// +class VoronoiAreaSpec { +public: + + /// default constructor (effective_Rfact = 1); + VoronoiAreaSpec() : _effective_Rfact(1.0) {}; + + /// constructor that allows you to set effective_Rfact. + VoronoiAreaSpec(double effective_Rfact) : + _effective_Rfact(effective_Rfact) {}; + + /// return the value of effective_Rfact + double effective_Rfact() const {return _effective_Rfact;} + + /// return a textual description of the area definition. + std::string description() const; + +private: + double _effective_Rfact; +}; + + +/// the different types of area that are supported +enum AreaType {invalid_area = -1, + active_area = 0, active_area_explicit_ghosts = 1, + one_ghost_passive_area = 10, passive_area = 11, + voronoi_area=20}; + + +//---------------------------------------------------------------------- +/// class that holds a generic area definition +/// +class AreaDefinition { +public: + + /// default constructor, which provides a ghosted active area, with + /// sensible defaults for the ghosts. + AreaDefinition() { + _area_type = active_area; + _ghost_spec = GhostedAreaSpec(); + } + + /// constructor for an area definition based on an area type and a + /// ghosted area specification + AreaDefinition(AreaType type, const GhostedAreaSpec & spec) { + _ghost_spec = spec; + _area_type = type; + assert(type != voronoi_area); + } + + /// constructor for an area definition based on an area type and a + /// voronoi area specification (type must be voronoi_area) + AreaDefinition(AreaType type, const VoronoiAreaSpec & spec) { + _voronoi_spec = spec; + _area_type = type; + assert(type == voronoi_area); + } + + /// constructor for an area definition based on an area type and + /// which attempts to provide sensible defaults for everything else + AreaDefinition(AreaType type) { + _area_type = type; + if (type == voronoi_area) { + _voronoi_spec = VoronoiAreaSpec(); + } else { + _ghost_spec = GhostedAreaSpec(); + } + } + + /// constructor for an area definition based on an ghosted area + /// specification, and an option to select which ghosted area you want + AreaDefinition(const GhostedAreaSpec & spec, AreaType type = active_area) { + _ghost_spec = spec; + _area_type = type; + assert(type != voronoi_area); + } + + /// constructor for an area definition based on a voronoi area + /// specification + AreaDefinition(const VoronoiAreaSpec & spec) { + _voronoi_spec = spec; + _area_type = voronoi_area; + } + + /// return a description of the current area definition + std::string description() const; + + /// return info about the type of area being used by this defn + AreaType area_type() const {return _area_type;} + + /// return a reference to the active area spec + const GhostedAreaSpec & ghost_spec() const {return _ghost_spec;} + GhostedAreaSpec & ghost_spec() {return _ghost_spec;} + + /// return a reference to the voronoi area spec + const VoronoiAreaSpec & voronoi_spec() const {return _voronoi_spec;} + +private: + + AreaType _area_type; + GhostedAreaSpec _ghost_spec; + VoronoiAreaSpec _voronoi_spec; +}; + +} // fastjet namespace + + +#endif // __FASTJET_AREADEFINITION_HH__ diff --git a/JETAN/fastjet/fastjet/CDFJetCluPlugin.hh b/JETAN/fastjet/fastjet/CDFJetCluPlugin.hh new file mode 100644 index 00000000000..8cd11cd6548 --- /dev/null +++ b/JETAN/fastjet/fastjet/CDFJetCluPlugin.hh @@ -0,0 +1,107 @@ +//STARTHEADER +// $Id: CDFJetCluPlugin.hh 1493 2009-03-11 19:15:17Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __CDFJETCLUPLUGIN_HH__ +#define __CDFJETCLUPLUGIN_HH__ + +#include "fastjet/JetDefinition.hh" +#include "fastjet/PseudoJet.hh" +#include + +// questionable whether this should be in fastjet namespace or not... + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// a plugin for fastjet-v2.1 that provides an interface to the CDF +/// jetclu algorithm +class CDFJetCluPlugin : public JetDefinition::Plugin { +public: + /// a compact constructor + CDFJetCluPlugin (double cone_radius, + double overlap_threshold, + double seed_threshold = 1.0, + int iratch = 1) : + _seed_threshold ( seed_threshold ), + _cone_radius ( cone_radius ), + _adjacency_cut ( 2 ), + _max_iterations ( 100 ), + _iratch ( iratch ), + _overlap_threshold ( overlap_threshold ) {} + + /// a constructor that looks like the one provided by CDF + CDFJetCluPlugin ( + double seed_threshold , + double cone_radius , + int adjacency_cut , + int max_iterations , + int iratch , + double overlap_threshold) : + _seed_threshold (seed_threshold ), + _cone_radius (cone_radius ), + _adjacency_cut (adjacency_cut ), + _max_iterations (max_iterations ), + _iratch (iratch ), + _overlap_threshold (overlap_threshold ) {} + + // some functions to return info about parameters + double seed_threshold () const {return _seed_threshold ;} + double cone_radius () const {return _cone_radius ;} + int adjacency_cut () const {return _adjacency_cut ;} + int max_iterations () const {return _max_iterations ;} + int iratch () const {return _iratch ;} + double overlap_threshold () const {return _overlap_threshold ;} + + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const; + /// the plugin mechanism's standard way of accessing the jet radius + virtual double R() const {return cone_radius();} + + +private: + + double _seed_threshold ; + double _cone_radius ; + int _adjacency_cut ; + int _max_iterations ; + int _iratch ; + double _overlap_threshold; + + /// given a jet try inserting its energy into the map -- if that + /// energy entry already exists, modify the jet infinitesimally so + /// as ensure that the jet energy is unique + void _insert_unique (PseudoJet & jet, std::map & jetmap) const; + +}; + +} // fastjet namespace + +#endif // __CDFJETCLUPLUGIN_HH__ diff --git a/JETAN/fastjet/fastjet/CDFMidPointPlugin.hh b/JETAN/fastjet/fastjet/CDFMidPointPlugin.hh new file mode 100644 index 00000000000..60de1d44ae5 --- /dev/null +++ b/JETAN/fastjet/fastjet/CDFMidPointPlugin.hh @@ -0,0 +1,169 @@ +//STARTHEADER +// $Id: CDFMidPointPlugin.hh 1186 2008-04-04 16:15:39Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __CDFMIDPOINTPLUGIN_HH__ +#define __CDFMIDPOINTPLUGIN_HH__ + +#include "fastjet/JetDefinition.hh" + +// questionable whether this should be in fastjet namespace or not... + +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +// +/// CDFMidPointPlugin is a plugin for fastjet (v2.1 upwards) that +/// provides an interface to the CDF version of Run-II iterative cone +/// algorithm with midpoint seeds (also known as the Iterative Legacy +/// Cone Algorithm, ILCA). +/// +/// The CDF code has been taken from Joey Huston's webpage +/// http://www.pa.msu.edu/~huston/Les_Houches_2005/Les_Houches_SM.html +/// +/// Note that the CDF midpoint code contains options that go beyond +/// those described in the Tevatron run-II document (hep-ex/0005012), +/// notably search-cones, as described in hep-ph/0111434, and +/// midpoints bewteen multiplets of stable cones. +/// +/// Additionally, the version of the CDF midpoint code distributed +/// here has been modified by the FastJet authors, so as to allow one +/// to choose the scale used in the split-merge step. +// +//---------------------------------------------------------------------- +class CDFMidPointPlugin : public JetDefinition::Plugin { +public: + /// the choice of scale to be used in the split-merge step + // NB: just replicates what we've added to the CDF midpoint code + enum SplitMergeScale {SM_pt, SM_Et, SM_mt, SM_pttilde}; + + /// + /// A CDFMidPointPlugin constructor that looks like the one provided + /// by CDF. Its arguments should have the following meaning: + /// + /// - seed_threshold: minimum pt for a particle to be considered + /// a seed of the iteration. + /// + /// - cone_radius: standard meaning + /// + /// - cone_area_fraction: stable-cones are searched for with a + /// radius Rsearch = R * sqrt(cone_area_fraction), and then + /// expanded to size R afterwards; note (hep-ph/0610012) that this + /// introduces IR unsafety at NLO for X+2-jet observables (where X + /// any hard object). + /// + /// - max_pair_size: "midpoints" can be added between pairs of + /// stable cones, triplets of stable cones, etc.; max_pair_size + /// indicates the maximum number of stable cones that are + /// assembled when adding midpoints. + /// + /// - max_iterations: the maximum number of iterations to carry out + /// when looking for a stable cone. + /// + /// - overlap_threshold: if + /// (overlapping_Et)/(Et_of_softer_protojet) < overlap_threshold, + /// overlapping jets are split, otherwise they are merged. + /// + /// - sm_scale: a choice for the scale to be used in the split-merge + /// step (both for ordering the momenta and quantifying the + /// overlap); the three options are + /// + /// . SM_pt: pt (default -- source of small IR safety issue in purely + /// hadronic events) + /// + /// . SM_Et: Et (not boost invariant, reduces to mt at zero rapidity and + /// to pt and infinite rapidity) + /// + /// . SM_mt: transverse mass = sqrt(m^2+pt^2) + /// + CDFMidPointPlugin ( + double seed_threshold , + double cone_radius , + double cone_area_fraction , + int max_pair_size , + int max_iterations , + double overlap_threshold , + SplitMergeScale sm_scale = SM_pt) : + _seed_threshold (seed_threshold ), + _cone_radius (cone_radius ), + _cone_area_fraction (cone_area_fraction ), + _max_pair_size (max_pair_size ), + _max_iterations (max_iterations ), + _overlap_threshold (overlap_threshold ), + _sm_scale (sm_scale) {} + + /// a compact constructor + /// + /// NB: as of version 2.4, the default value for the + /// overlap_threshold threshold has been removed, to avoid + /// misleading people into using the value of 0.5 without thinking, + /// which is known to have adverse effects in high-noise + /// environments. A recommended value is 0.75. + CDFMidPointPlugin (double cone_radius, + double overlap_threshold,// = 0.5, + double seed_threshold = 1.0, + double cone_area_fraction = 1.0) : + _seed_threshold (seed_threshold ), + _cone_radius (cone_radius ), + _cone_area_fraction (cone_area_fraction ), + _max_pair_size (2 ), + _max_iterations (100 ), + _overlap_threshold (overlap_threshold ), + _sm_scale (SM_pt) {} + + + // some functions to return info about parameters + double seed_threshold () const {return _seed_threshold ;} + double cone_radius () const {return _cone_radius ;} + double cone_area_fraction () const {return _cone_area_fraction ;} + int max_pair_size () const {return _max_pair_size ;} + int max_iterations () const {return _max_iterations ;} + double overlap_threshold () const {return _overlap_threshold ;} + + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const; + /// the plugin mechanism's standard way of accessing the jet radius + virtual double R() const {return cone_radius();} + +private: + + double _seed_threshold ; + double _cone_radius ; + double _cone_area_fraction; + int _max_pair_size ; + int _max_iterations ; + double _overlap_threshold ; + SplitMergeScale _sm_scale ; +}; + +} // fastjet namespace + +#endif // __CDFMIDPOINTPLUGIN_HH__ diff --git a/JETAN/fastjet/fastjet/CircularRange.hh b/JETAN/fastjet/fastjet/CircularRange.hh new file mode 100644 index 00000000000..c744a95a456 --- /dev/null +++ b/JETAN/fastjet/fastjet/CircularRange.hh @@ -0,0 +1,109 @@ +//STARTHEADER +// $Id: CircularRange.hh 1502 2009-04-06 10:33:14Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_CIRCULARRANGE_HH__ +#define __FASTJET_CIRCULARRANGE_HH__ + +#include "fastjet/RangeDefinition.hh" +#include "fastjet/Error.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +class CircularRange : public fastjet::RangeDefinition { +public: + /// constructor + CircularRange() {_set_invalid_rapphi();} + + /// initialise CircularRange with a jet + CircularRange(const fastjet::PseudoJet & jet, double distance) { + _distance = distance; + _rapjet = jet.rap(); + _phijet = jet.phi(); + _total_area = fastjet::pi*_distance*_distance; } + + /// initialise CircularRange with a (rap,phi) point + CircularRange(double rap, double phi, double distance) { + _distance = distance; + _rapjet = rap; + _phijet = phi; + _total_area = fastjet::pi*_distance*_distance; } + + /// initialise CircularRange with just the radius parameter + CircularRange(double distance) { + _set_invalid_rapphi(); + _distance = distance; + _total_area = fastjet::pi*_distance*_distance; } + + /// destructor + virtual ~CircularRange() {} + + /// return description of range + virtual inline std::string description() const { + std::ostringstream ostr; + ostr << "CircularRange: within distance "<< _distance << " of given jet or point." ; + return ostr.str(); } + + /// returns true since this range is localizable (i.e. set_position + /// does something meaningful) + virtual inline bool is_localizable() const { return true; } + + /// return bool according to whether (rap,phi) is in range + virtual inline bool is_in_range(double rap, double phi) const { + if (! _rapphi_are_valid()) { + throw Error("Circular range used without a center having being defined (use set_position())"); + } + double deltaphi = _phijet - phi; + if ( deltaphi > pi) { deltaphi -= twopi; } + else if ( deltaphi < -pi) { deltaphi += twopi; } + bool inrange = ( (rap-_rapjet)*(rap-_rapjet) + + deltaphi*deltaphi <= _distance*_distance ); + return inrange; } + + /// return the minimal and maximal rapidity of this range + virtual inline void get_rap_limits(double & rapmin, double & rapmax) const { + rapmin = _rapjet - _distance; + rapmax = _rapjet + _distance; } + +private: + double _distance; + + /// value for phi that marks it as invalid + const static double _invalid_phi = -1000.0; + /// set internal phi so as to mark things as invalid + void _set_invalid_rapphi() {_phijet = _invalid_phi;} + /// true if rap,phi are valid (tests only phi) + bool _rapphi_are_valid() const {return _phijet != _invalid_phi;} + +}; + +} // fastjet namespace + +#endif // __FASTJET_CIRCULARRANGE_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequence.hh b/JETAN/fastjet/fastjet/ClusterSequence.hh new file mode 100644 index 00000000000..be54673c053 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequence.hh @@ -0,0 +1,919 @@ +//STARTHEADER +// $Id: ClusterSequence.hh 1435 2009-02-12 21:11:04Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +//---------------------------------------------------------------------- +// here's where we put the main page for fastjet (as explained in the +// Doxygen faq) +//...................................................................... +/*! \mainpage FastJet code documentation + * + * These pages provide automatically generated documentation for the + * FastJet package. + * + * For further information and normal documentation, see the main FastJet page. + */ +//---------------------------------------------------------------------- + +#ifndef __FASTJET_CLUSTERSEQUENCE_HH__ +#define __FASTJET_CLUSTERSEQUENCE_HH__ + +#include +#include +#include "fastjet/internal/DynamicNearestNeighbours.hh" +#include "fastjet/PseudoJet.hh" +#include +#include +#include +#include +#include +#include // needed to get double std::abs(double) +#include "fastjet/Error.hh" +#include "fastjet/JetDefinition.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + + +/// deals with clustering +class ClusterSequence { + + + public: + + /// default constructor + ClusterSequence () {} + + /// create a clustersequence starting from the supplied set + /// of pseudojets and clustering them with the long-invariant + /// kt algorithm (E-scheme recombination) with the supplied + /// value for R. + /// + /// If strategy=DumbN3 a very stupid N^3 algorithm is used for the + /// clustering; otherwise strategy = NlnN* uses cylinders algorithms + /// with some number of pi coverage. If writeout_combinations=true a + /// summary of the recombination sequence is written out + template ClusterSequence (const std::vector & pseudojets, + const double & R = 1.0, + const Strategy & strategy = Best, + const bool & writeout_combinations = false); + + + /// create a clustersequence starting from the supplied set + /// of pseudojets and clustering them with jet definition specified + /// by jet_def (which also specifies the clustering strategy) + template ClusterSequence ( + const std::vector & pseudojets, + const JetDefinition & jet_def, + const bool & writeout_combinations = false); + + // virtual ClusterSequence destructor, in case any derived class + // thinks of needing a destructor at some point + virtual ~ClusterSequence (); //{} + + // NB: in the routines that follow, for extracting lists of jets, a + // list structure might be more efficient, if sometimes a little + // more awkward to use (at least for old fortran hands). + + /// return a vector of all jets (in the sense of the inclusive + /// algorithm) with pt >= ptmin. Time taken should be of the order + /// of the number of jets returned. + std::vector inclusive_jets (const double & ptmin = 0.0) const; + + /// return the number of jets (in the sense of the exclusive + /// algorithm) that would be obtained when running the algorithm + /// with the given dcut. + int n_exclusive_jets (const double & dcut) const; + + /// return a vector of all jets (in the sense of the exclusive + /// algorithm) that would be obtained when running the algorithm + /// with the given dcut. + std::vector exclusive_jets (const double & dcut) const; + + /// return a vector of all jets when the event is clustered (in the + /// exclusive sense) to exactly njets. + std::vector exclusive_jets (const int & njets) const; + + /// return the dmin corresponding to the recombination that went from + /// n+1 to n jets (sometimes known as d_{n n+1}). + double exclusive_dmerge (const int & njets) const; + + /// return the maximum of the dmin encountered during all recombinations + /// up to the one that led to an n-jet final state; identical to + /// exclusive_dmerge, except in cases where the dmin do not increase + /// monotonically. + double exclusive_dmerge_max (const int & njets) const; + + /// return the ymin corresponding to the recombination that went from + /// n+1 to n jets (sometimes known as y_{n n+1}). + double exclusive_ymerge (int njets) const {return exclusive_dmerge(njets) / Q2();} + + /// same as exclusive_dmerge_max, but normalised to squared total energy + double exclusive_ymerge_max (int njets) const {return exclusive_ymerge_max(njets)/Q2();} + + /// the number of exclusive jets at the given ycut + int n_exclusive_jets_ycut (double ycut) const {return n_exclusive_jets(ycut*Q2());} + + /// the exclusive jets obtained at the given ycut + std::vector exclusive_jets_ycut (double ycut) const { + int njets = n_exclusive_jets_ycut(ycut); + return exclusive_jets(njets); + } + + + //int n_exclusive_jets (const PseudoJet & jet, const double & dcut) const; + + /// return a vector of all subjets of the current jet (in the sense + /// of the exclusive algorithm) that would be obtained when running + /// the algorithm with the given dcut. + /// + /// Time taken is O(m ln m), where m is the number of subjets that + /// are found. If m gets to be of order of the total number of + /// constituents in the jet, this could be substantially slower than + /// just getting that list of constituents. + std::vector exclusive_subjets (const PseudoJet & jet, + const double & dcut) const; + + /// return the size of exclusive_subjets(...); still n ln n with same + /// coefficient, but marginally more efficient than manually taking + /// exclusive_subjets.size() + int n_exclusive_subjets(const PseudoJet & jet, + const double & dcut) const; + + /// return the list of subjets obtained by unclustering the supplied + /// jet down to n subjets (or all constituents if there are fewer + /// than n). + /// + /// requires n ln n time + std::vector exclusive_subjets (const PseudoJet & jet, + int nsub) const; + + /// return the dij that was present in the merging nsub+1 -> nsub + /// subjets inside this jet. + double exclusive_subdmerge(const PseudoJet & jet, int nsub) const; + + /// return the maximum dij that occurred in the whole event at the + /// stage that the nsub+1 -> nsub merge of subjets occurred inside + /// this jet. + double exclusive_subdmerge_max(const PseudoJet & jet, int nsub) const; + + //std::vector exclusive_jets (const PseudoJet & jet, + // const int & njets) const; + //double exclusive_dmerge (const PseudoJet & jet, const int & njets) const; + + /// returns the sum of all energies in the event (relevant mainly for e+e-) + double Q() const {return _Q;} + /// return Q()^2 + double Q2() const {return _Q*_Q;} + + /// returns true iff the object is included in the jet. + /// + /// NB: this is only sensible if the object is already registered + /// within the cluster sequence, so you cannot use it with an input + /// particle to the CS (since the particle won't have the history + /// index set properly). + /// + /// For nice clustering structures it should run in O(ln(N)) time + /// but in worst cases (certain cone plugins) it can take O(n) time, + /// where n is the number of particles in the jet. + bool object_in_jet(const PseudoJet & object, const PseudoJet & jet) const; + + /// if the jet has parents in the clustering, it returns true + /// and sets parent1 and parent2 equal to them. + /// + /// if it has no parents it returns false and sets parent1 and + /// parent2 to zero + bool has_parents(const PseudoJet & jet, PseudoJet & parent1, + PseudoJet & parent2) const; + + /// if the jet has a child then return true and give the child jet + /// otherwise return false and set the child to zero + bool has_child(const PseudoJet & jet, PseudoJet & child) const; + + /// Version of has_child that sets a pointer to the child if the child + /// exists; + bool has_child(const PseudoJet & jet, const PseudoJet * & childp) const; + + /// if this jet has a child (and so a partner) return true + /// and give the partner, otherwise return false and set the + /// partner to zero + bool has_partner(const PseudoJet & jet, PseudoJet & partner) const; + + + /// return a vector of the particles that make up jet + std::vector constituents (const PseudoJet & jet) const; + + + /// output the supplied vector of jets in a format that can be read + /// by an appropriate root script; the format is: + /// jet-n jet-px jet-py jet-pz jet-E + /// particle-n particle-rap particle-phi particle-pt + /// particle-n particle-rap particle-phi particle-pt + /// ... + /// #END + /// ... [i.e. above repeated] + void print_jets_for_root(const std::vector & jets, + std::ostream & ostr = std::cout) const; + + /// print jets for root to the file labelled filename, with an + /// optional comment at the beginning + void print_jets_for_root(const std::vector & jets, + const std::string & filename, + const std::string & comment = "") const; + +// Not yet. Perhaps in a future release. +// /// print out all inclusive jets with pt > ptmin +// virtual void print_jets (const double & ptmin=0.0) const; + + /// add on to subjet_vector the constituents of jet (for internal use mainly) + void add_constituents (const PseudoJet & jet, + std::vector & subjet_vector) const; + + /// return the enum value of the strategy used to cluster the event + inline Strategy strategy_used () const {return _strategy;} + std::string strategy_string () const; + + /// return a reference to the jet definition + const JetDefinition & jet_def() const {return _jet_def;} + + /// returns the scale associated with a jet as required for this + /// clustering algorithm (kt^2 for the kt-algorithm, 1 for the + /// Cambridge algorithm). [May become virtual at some point] + double jet_scale_for_algorithm(const PseudoJet & jet) const; + + //----- next follow functions designed specifically for plugins, which + // may only be called when plugin_activated() returns true + + /// record the fact that there has been a recombination between + /// jets()[jet_i] and jets()[jet_k], with the specified dij, and + /// return the index (newjet_k) allocated to the new jet, whose + /// momentum is assumed to be the 4-vector sum of that of jet_i and + /// jet_j + void plugin_record_ij_recombination(int jet_i, int jet_j, double dij, + int & newjet_k) { + assert(plugin_activated()); + _do_ij_recombination_step(jet_i, jet_j, dij, newjet_k); + } + + /// as for the simpler variant of plugin_record_ij_recombination, + /// except that the new jet is attributed the momentum and + /// user_index of newjet + void plugin_record_ij_recombination(int jet_i, int jet_j, double dij, + const PseudoJet & newjet, + int & newjet_k); + + /// record the fact that there has been a recombination between + /// jets()[jet_i] and the beam, with the specified diB; when looking + /// for inclusive jets, any iB recombination will returned to the user + /// as a jet. + void plugin_record_iB_recombination(int jet_i, double diB) { + assert(plugin_activated()); + _do_iB_recombination_step(jet_i, diB); + } + + /// a class intended to serve as a base in case a plugin needs to + /// associate extra information with a ClusterSequence (see + /// SISConePlugin.* for an example). + class Extras { + public: + virtual ~Extras() {} + virtual std::string description() const {return "This is a dummy extras class that contains no extra information! Derive from it if you want to use it to provide extra information from a plugin jet finder";} + }; + + /// the plugin can associated some extra information with the + /// ClusterSequence object by calling this function + inline void plugin_associate_extras(std::auto_ptr extras_in) { + _extras = extras_in; + } + + /// returns true when the plugin is allowed to run the show. + inline bool plugin_activated() const {return _plugin_activated;} + + /// returns a pointer to the extras object (may be null) + const Extras * extras() const {return _extras.get();} + + /// allows a plugin to run a templated clustering (nearest-neighbour heuristic) + /// + /// This has N^2 behaviour on "good" distance, but a worst case behaviour + /// of N^3 (and many algs trigger the worst case behaviour) + /// + /// + /// For more details on how this works, see GenBriefJet below + template void plugin_simple_N2_cluster () { + assert(plugin_activated()); + _simple_N2_cluster(); + } + + //---------------------------------------------------------------------- + /// class to help with a generic clustering sequence + class GenBriefJet { + public: + /// function that initialises the GenBriefJet given a PseudoJet. + /// + /// In a derived class, this member has a responsability to call + /// + /// - set_scale_squared + /// - set_geom_iB + /// + /// The clustering will be performed by finding the minimum of + /// + /// diB = scale_squared[i] * geom_iB * _invR2 + /// dij = min(scale_squared[i],scale_squared[j]) * geom_ij * _invR2 + /// + virtual void init(const PseudoJet & jet) = 0; + + /// Returns the "geometric" part of distance between this jet + /// and jet_j + virtual double geom_ij(const GenBriefJet * jet_j) const = 0; + + void set_scale_squared(double scale_squared) {kt2 = scale_squared;} + void set_geom_iB(double diB) {NN_dist = diB; NN = NULL;} + + public: // formally public: but users should think of it as private! + double NN_dist; // dij + double kt2; // squared scale + GenBriefJet * NN; // pointer to nearest neighbour + int _jets_index; // index of this jet + }; + + +public: + /// set the default (static) jet finder across all current and future + /// ClusterSequence objects -- deprecated and obsolescent (i.e. may be + /// suppressed in a future release). + static void set_jet_algorithm (JetAlgorithm jet_algorithm) {_default_jet_algorithm = jet_algorithm;} + /// same as above for backward compatibility + static void set_jet_finder (JetAlgorithm jet_algorithm) {_default_jet_algorithm = jet_algorithm;} + + + /// a single element in the clustering history (see vector _history + /// below). + struct history_element{ + int parent1; /// index in _history where first parent of this jet + /// was created (InexistentParent if this jet is an + /// original particle) + + int parent2; /// index in _history where second parent of this jet + /// was created (InexistentParent if this jet is an + /// original particle); BeamJet if this history entry + /// just labels the fact that the jet has recombined + /// with the beam) + + int child; /// index in _history where the current jet is + /// recombined with another jet to form its child. It + /// is Invalid if this jet does not further + /// recombine. + + int jetp_index; /// index in the _jets vector where we will find the + /// PseudoJet object corresponding to this jet + /// (i.e. the jet created at this entry of the + /// history). NB: if this element of the history + /// corresponds to a beam recombination, then + /// jetp_index=Invalid. + + double dij; /// the distance corresponding to the recombination + /// at this stage of the clustering. + + double max_dij_so_far; /// the largest recombination distance seen + /// so far in the clustering history. + }; + + enum JetType {Invalid=-3, InexistentParent = -2, BeamJet = -1}; + + /// allow the user to access the internally stored _jets() array, + /// which contains both the initial particles and the various + /// intermediate and final stages of recombination. + /// + /// The first n_particles() entries are the original particles, + /// in the order in which they were supplied to the ClusterSequence + /// constructor. It can be useful to access them for example when + /// examining whether a given input object is part of a specific + /// jet, via the objects_in_jet(...) member function (which only takes + /// PseudoJets that are registered in the ClusterSequence). + /// + /// One of the other (internal uses) is related to the fact + /// because we don't seem to be able to access protected elements of + /// the class for an object that is not "this" (at least in case where + /// "this" is of a slightly different kind from the object, both + /// derived from ClusterSequence). + const std::vector & jets() const; + + /// allow the user to access the raw internal history. + /// + /// This is present (as for jets()) in part so that protected + /// derived classes can access this information about other + /// ClusterSequences. + /// + /// A user who wishes to follow the details of the ClusterSequence + /// can also make use of this information (and should consult the + /// history_element documentation for more information), but should + /// be aware that these internal structures may evolve in future + /// FastJet versions. + const std::vector & history() const; + + /// returns the number of particles that were provided to the + /// clustering algorithm (helps the user find their way around the + /// history and jets objects if they weren't paying attention + /// beforehand). + unsigned int n_particles() const; + + /// returns a vector of size n_particles() which indicates, for + /// each of the initial particles (in the order in which they were + /// supplied), which of the supplied jets it belongs to; if it does + /// not belong to any of the supplied jets, the index is set to -1; + std::vector particle_jet_indices(const std::vector &) const; + + /// routine that returns an order in which to read the history + /// such that clusterings that lead to identical jet compositions + /// but different histories (because of degeneracies in the + /// clustering order) will have matching constituents for each + /// matching entry in the unique_history_order. + /// + /// The order has the property that an entry's parents will always + /// appear prior to that entry itself. + /// + /// Roughly speaking the order is such that we first provide all + /// steps that lead to the final jet containing particle 1; then we + /// have the steps that lead to reconstruction of the jet containing + /// the next-lowest-numbered unclustered particle, etc... + /// [see GPS CCN28-12 for more info -- of course a full explanation + /// here would be better...] + std::vector unique_history_order() const; + + /// return the set of particles that have not been clustered. For + /// kt and cam/aachen algorithms this should always be null, but for + /// cone type algorithms it can be non-null; + std::vector unclustered_particles() const; + + /// transfer the sequence contained in other_seq into our own; + /// any plugin "extras" contained in the from_seq will be lost + /// from there. + void transfer_from_sequence(ClusterSequence & from_seq); + + +protected: + static JetAlgorithm _default_jet_algorithm; + JetDefinition _jet_def; + + /// returns true if the jet has a history index contained within + /// the range of this CS + bool _potentially_valid(const PseudoJet & jet) const { + return jet.cluster_hist_index() >= 0 + && jet.cluster_hist_index() < int(_history.size()); + } + + /// transfer the vector of input jets into our own vector + /// _jets (with some reserved space for future growth). + template void _transfer_input_jets( + const std::vector & pseudojets); + + /// This is the routine that will do all the initialisation and + /// then run the clustering (may be called by various constructors). + /// It assumes _jets contains the momenta to be clustered. + void _initialise_and_run (const JetDefinition & jet_def, + const bool & writeout_combinations); + + /// This is an alternative routine for initialising and running the + /// clustering, provided for legacy purposes. The jet finder is that + /// specified in the static member _default_jet_algorithm. + void _initialise_and_run (const double & R, + const Strategy & strategy, + const bool & writeout_combinations); + + /// fills in the various member variables with "decanted" options from + /// the jet_definition and writeout_combinations variables + void _decant_options(const JetDefinition & jet_def, + const bool & writeout_combinations); + + /// fill out the history (and jet cross refs) related to the initial + /// set of jets (assumed already to have been "transferred"), + /// without any clustering + void _fill_initial_history(); + + /// carry out the recombination between the jets numbered jet_i and + /// jet_j, at distance scale dij; return the index newjet_k of the + /// result of the recombination of i and j. + void _do_ij_recombination_step(const int & jet_i, const int & jet_j, + const double & dij, int & newjet_k); + + /// carry out an recombination step in which _jets[jet_i] merges with + /// the beam, + void _do_iB_recombination_step(const int & jet_i, const double & diB); + + + /// This contains the physical PseudoJets; for each PseudoJet one + /// can find the corresponding position in the _history by looking + /// at _jets[i].cluster_hist_index(). + std::vector _jets; + + + /// this vector will contain the branching history; for each stage, + /// _history[i].jetp_index indicates where to look in the _jets + /// vector to get the physical PseudoJet. + std::vector _history; + + /// set subhist to be a set pointers to history entries corresponding to the + /// subjets of this jet; one stops going working down through the + /// subjets either when + /// - there is no further to go + /// - one has found maxjet entries + /// - max_dij_so_far <= dcut + /// By setting maxjet=0 one can use just dcut; by setting dcut<0 + /// one can use jet maxjet + void get_subhist_set(std::set & subhist, + const PseudoJet & jet, double dcut, int maxjet) const; + + bool _writeout_combinations; + int _initial_n; + double _Rparam, _R2, _invR2; + double _Q; + Strategy _strategy; + JetAlgorithm _jet_algorithm; + + + private: + + bool _plugin_activated; + std::auto_ptr _extras; // things the plugin might want to add + + void _really_dumb_cluster (); + void _delaunay_cluster (); + //void _simple_N2_cluster (); + template void _simple_N2_cluster (); + void _tiled_N2_cluster (); + void _faster_tiled_N2_cluster (); + + // + void _minheap_faster_tiled_N2_cluster(); + + // things needed specifically for Cambridge with Chan's 2D closest + // pairs method + void _CP2DChan_cluster(); + void _CP2DChan_cluster_2pi2R (); + void _CP2DChan_cluster_2piMultD (); + void _CP2DChan_limited_cluster(double D); + void _do_Cambridge_inclusive_jets(); + + void _add_step_to_history(const int & step_number, const int & parent1, + const int & parent2, const int & jetp_index, + const double & dij); + + /// internal routine associated with the construction of the unique + /// history order (following children in the tree) + void _extract_tree_children(int pos, std::valarray &, + const std::valarray &, std::vector &) const; + + /// internal routine associated with the construction of the unique + /// history order (following parents in the tree) + void _extract_tree_parents (int pos, std::valarray &, + const std::valarray &, std::vector &) const; + + + // these will be useful shorthands in the Voronoi-based code + typedef std::pair TwoVertices; + typedef std::pair DijEntry; + typedef std::multimap DistMap; + + /// currently used only in the Voronoi based code + void _add_ktdistance_to_map(const int & ii, + DistMap & DijMap, + const DynamicNearestNeighbours * DNN); + + /// for making sure the user knows what it is they're running... + void _print_banner(); + /// will be set by default to be true for the first run + static bool _first_time; + + /// record the number of warnings provided about the exclusive + /// algorithm -- so that we don't print it out more than a few + /// times. + static int _n_exclusive_warnings; + + //---------------------------------------------------------------------- + /// the fundamental structure which contains the minimal info about + /// a jet, as needed for our plain N^2 algorithm -- the idea is to + /// put all info that will be accessed N^2 times into an array of + /// BriefJets... + struct BriefJet { + double eta, phi, kt2, NN_dist; + BriefJet * NN; + int _jets_index; + }; + + + /// structure analogous to BriefJet, but with the extra information + /// needed for dealing with tiles + class TiledJet { + public: + double eta, phi, kt2, NN_dist; + TiledJet * NN, *previous, * next; + int _jets_index, tile_index, diJ_posn; + // routines that are useful in the minheap version of tiled + // clustering ("misuse" the otherwise unused diJ_posn, so as + // to indicate whether jets need to have their minheap entries + // updated). + inline void label_minheap_update_needed() {diJ_posn = 1;} + inline void label_minheap_update_done() {diJ_posn = 0;} + inline bool minheap_update_needed() const {return diJ_posn==1;} + }; + + //-- some of the functions that follow are templates and will work + //as well for briefjet and tiled jets + + /// set the kinematic and labelling info for jeta so that it corresponds + /// to _jets[_jets_index] + template void _bj_set_jetinfo( J * const jet, + const int _jets_index) const; + + /// "remove" this jet, which implies updating links of neighbours and + /// perhaps modifying the tile structure + void _bj_remove_from_tiles( TiledJet * const jet) const; + + /// return the distance between two BriefJet objects + template double _bj_dist(const J * const jeta, + const J * const jetb) const; + + // return the diJ (multiplied by _R2) for this jet assuming its NN + // info is correct + template double _bj_diJ(const J * const jeta) const; + + /// for testing purposes only: if in the range head--tail-1 there is a + /// a jet which corresponds to hist_index in the history, then + /// return a pointer to that jet; otherwise return tail. + template inline J * _bj_of_hindex( + const int hist_index, + J * const head, J * const tail) + const { + J * res; + for(res = head; res_jets_index].cluster_hist_index() == hist_index) {break;} + } + return res; + } + + + //-- remaining functions are different in various cases, so we + // will use templates but are not sure if they're useful... + + /// updates (only towards smaller distances) the NN for jeta without checking + /// whether in the process jeta itself might be a new NN of one of + /// the jets being scanned -- span the range head to tail-1 with + /// assumption that jeta is not contained in that range + template void _bj_set_NN_nocross(J * const jeta, + J * const head, const J * const tail) const; + + /// reset the NN for jeta and DO check whether in the process jeta + /// itself might be a new NN of one of the jets being scanned -- + /// span the range head to tail-1 with assumption that jeta is not + /// contained in that range + template void _bj_set_NN_crosscheck(J * const jeta, + J * const head, const J * const tail) const; + + + + /// number of neighbours that a tile will have (rectangular geometry + /// gives 9 neighbours). + static const int n_tile_neighbours = 9; + //---------------------------------------------------------------------- + /// The fundamental structures to be used for the tiled N^2 algorithm + /// (see CCN27-44 for some discussion of pattern of tiling) + struct Tile { + /// pointers to neighbouring tiles, including self + Tile * begin_tiles[n_tile_neighbours]; + /// neighbouring tiles, excluding self + Tile ** surrounding_tiles; + /// half of neighbouring tiles, no self + Tile ** RH_tiles; + /// just beyond end of tiles + Tile ** end_tiles; + /// start of list of BriefJets contained in this tile + TiledJet * head; + /// sometimes useful to be able to tag a tile + bool tagged; + }; + std::vector _tiles; + double _tiles_eta_min, _tiles_eta_max; + double _tile_size_eta, _tile_size_phi; + int _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max; + + // reasonably robust return of tile index given ieta and iphi, in particular + // it works even if iphi is negative + inline int _tile_index (int ieta, int iphi) const { + // note that (-1)%n = -1 so that we have to add _n_tiles_phi + // before performing modulo operation + return (ieta-_tiles_ieta_min)*_n_tiles_phi + + (iphi+_n_tiles_phi) % _n_tiles_phi; + } + + // routines for tiled case, including some overloads of the plain + // BriefJet cases + int _tile_index(const double & eta, const double & phi) const; + void _tj_set_jetinfo ( TiledJet * const jet, const int _jets_index); + void _bj_remove_from_tiles(TiledJet * const jet); + void _initialise_tiles(); + void _print_tiles(TiledJet * briefjets ) const; + void _add_neighbours_to_tile_union(const int tile_index, + std::vector & tile_union, int & n_near_tiles) const; + void _add_untagged_neighbours_to_tile_union(const int tile_index, + std::vector & tile_union, int & n_near_tiles); + + + //---------------------------------------------------------------------- + /// fundamental structure for e+e- clustering + struct EEBriefJet { + double NN_dist; // obligatorily present + double kt2; // obligatorily present == E^2 in general + EEBriefJet * NN; // must be present too + int _jets_index; // must also be present! + //........................................................... + double nx, ny, nz; // our internal storage for fast distance calcs + }; + + /// to help instantiation + void _dummy_N2_cluster_instantiation(); + +}; + + +//********************************************************************** +//************** START OF INLINE MATERIAL ****************** +//********************************************************************** + + +//---------------------------------------------------------------------- +// Transfer the initial jets into our internal structure +template void ClusterSequence::_transfer_input_jets( + const std::vector & pseudojets) { + + // this will ensure that we can point to jets without difficulties + // arising. + _jets.reserve(pseudojets.size()*2); + + // insert initial jets this way so that any type L that can be + // converted to a pseudojet will work fine (basically PseudoJet + // and any type that has [] subscript access to the momentum + // components, such as CLHEP HepLorentzVector). + for (unsigned int i = 0; i < pseudojets.size(); i++) { + _jets.push_back(pseudojets[i]);} + +} + +//---------------------------------------------------------------------- +// initialise from some generic type... Has to be made available +// here in order for it the template aspect of it to work... +template ClusterSequence::ClusterSequence ( + const std::vector & pseudojets, + const double & R, + const Strategy & strategy, + const bool & writeout_combinations) { + + // transfer the initial jets (type L) into our own array + _transfer_input_jets(pseudojets); + + // run the clustering + _initialise_and_run(R,strategy,writeout_combinations); +} + + +//---------------------------------------------------------------------- +/// constructor of a jet-clustering sequence from a vector of +/// four-momenta, with the jet definition specified by jet_def +template ClusterSequence::ClusterSequence ( + const std::vector & pseudojets, + const JetDefinition & jet_def, + const bool & writeout_combinations) { + + // transfer the initial jets (type L) into our own array + _transfer_input_jets(pseudojets); + + // run the clustering + _initialise_and_run(jet_def,writeout_combinations); +} + + +inline const std::vector & ClusterSequence::jets () const { + return _jets; +} + +inline const std::vector & ClusterSequence::history () const { + return _history; +} + +inline unsigned int ClusterSequence::n_particles() const {return _initial_n;} + + + +//---------------------------------------------------------------------- +template inline void ClusterSequence::_bj_set_jetinfo( + J * const jetA, const int _jets_index) const { + jetA->eta = _jets[_jets_index].rap(); + jetA->phi = _jets[_jets_index].phi_02pi(); + jetA->kt2 = jet_scale_for_algorithm(_jets[_jets_index]); + jetA->_jets_index = _jets_index; + // initialise NN info as well + jetA->NN_dist = _R2; + jetA->NN = NULL; +} + + + + +//---------------------------------------------------------------------- +template inline double ClusterSequence::_bj_dist( + const J * const jetA, const J * const jetB) const { + double dphi = std::abs(jetA->phi - jetB->phi); + double deta = (jetA->eta - jetB->eta); + if (dphi > pi) {dphi = twopi - dphi;} + return dphi*dphi + deta*deta; +} + +//---------------------------------------------------------------------- +template inline double ClusterSequence::_bj_diJ(const J * const jet) const { + double kt2 = jet->kt2; + if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}} + return jet->NN_dist * kt2; +} + + +//---------------------------------------------------------------------- +// set the NN for jet without checking whether in the process you might +// have discovered a new nearest neighbour for another jet +template inline void ClusterSequence::_bj_set_NN_nocross( + J * const jet, J * const head, const J * const tail) const { + double NN_dist = _R2; + J * NN = NULL; + if (head < jet) { + for (J * jetB = head; jetB != jet; jetB++) { + double dist = _bj_dist(jet,jetB); + if (dist < NN_dist) { + NN_dist = dist; + NN = jetB; + } + } + } + if (tail > jet) { + for (J * jetB = jet+1; jetB != tail; jetB++) { + double dist = _bj_dist(jet,jetB); + if (dist < NN_dist) { + NN_dist = dist; + NN = jetB; + } + } + } + jet->NN = NN; + jet->NN_dist = NN_dist; +} + + +//---------------------------------------------------------------------- +template inline void ClusterSequence::_bj_set_NN_crosscheck(J * const jet, + J * const head, const J * const tail) const { + double NN_dist = _R2; + J * NN = NULL; + for (J * jetB = head; jetB != tail; jetB++) { + double dist = _bj_dist(jet,jetB); + if (dist < NN_dist) { + NN_dist = dist; + NN = jetB; + } + if (dist < jetB->NN_dist) { + jetB->NN_dist = dist; + jetB->NN = jet; + } + } + jet->NN = NN; + jet->NN_dist = NN_dist; +} + + + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCE_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequence1GhostPassiveArea.hh b/JETAN/fastjet/fastjet/ClusterSequence1GhostPassiveArea.hh new file mode 100644 index 00000000000..b1f8d005264 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequence1GhostPassiveArea.hh @@ -0,0 +1,101 @@ +//STARTHEADER +// $Id: ClusterSequence1GhostPassiveArea.hh 1134 2008-03-15 17:05:16Z salam $ +// +// Copyright (c) 2005-2007, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCE1GHOSTPASSIVEAREA_HH__ +#define __FASTJET_CLUSTERSEQUENCE1GHOSTPASSIVEAREA_HH__ + + +#include "fastjet/PseudoJet.hh" +#include "fastjet/ClusterSequenceAreaBase.hh" +#include "fastjet/ClusterSequenceActiveArea.hh" +#include +#include + +namespace fastjet { // defined in fastjet/internal/base.hh + +//using namespace std; + +/// Class that behaves essentially like ClusterSequence except +/// that it also provides access to the area of a jet (which +/// will be a random quantity... Figure out what to do about seeds +/// later...) +class ClusterSequence1GhostPassiveArea : public ClusterSequenceActiveArea { +public: + + ClusterSequence1GhostPassiveArea() {} + + /// constructor based on JetDefinition and 1GhostPassiveAreaSpec + template ClusterSequence1GhostPassiveArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations = false) ; + + /// return an estimate for the number of empty jets -- one uses the + /// AreaBase one rather than the ActiveArea one (which for which we + /// do not have the information). + virtual double n_empty_jets(const RangeDefinition & range) const { + return ClusterSequenceAreaBase::n_empty_jets(range); + } + +protected: + /// does the initialisation and running specific to the passive + /// areas class + void _initialise_and_run_1GPA (const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations = false); + +private: + + void _run_1GPA(const GhostedAreaSpec & area_spec); +}; + + + + +template ClusterSequence1GhostPassiveArea::ClusterSequence1GhostPassiveArea +(const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations) { + + // transfer the initial jets (type L) into our own array + _transfer_input_jets(pseudojets); + + // run the clustering for passive areas + _initialise_and_run_1GPA(jet_def, area_spec, writeout_combinations); + +} + + + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCE1GHOSTPASSIVEAREA_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequenceActiveArea.hh b/JETAN/fastjet/fastjet/ClusterSequenceActiveArea.hh new file mode 100644 index 00000000000..5cc4812cec7 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequenceActiveArea.hh @@ -0,0 +1,221 @@ +//STARTHEADER +// $Id: ClusterSequenceActiveArea.hh 1134 2008-03-15 17:05:16Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEACTIVEAREA_HH__ +#define __FASTJET_CLUSTERSEQUENCEACTIVEAREA_HH__ + + +#include "fastjet/PseudoJet.hh" +#include "fastjet/ClusterSequenceAreaBase.hh" +#include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh" +#include +#include + +//------------ backwards compatibility with version 2.1 ------------- +// for backwards compatibility make ActiveAreaSpec name available +#include "fastjet/ActiveAreaSpec.hh" +#include "fastjet/ClusterSequenceWithArea.hh" +//-------------------------------------------------------------------- + + +namespace fastjet { // defined in fastjet/internal/base.hh + +//using namespace std; + +/// Class that behaves essentially like ClusterSequence except +/// that it also provides access to the area of a jet (which +/// will be a random quantity... Figure out what to do about seeds +/// later...) +class ClusterSequenceActiveArea : public ClusterSequenceAreaBase { +public: + + /// default constructor + ClusterSequenceActiveArea() {} + + /// constructor based on JetDefinition and GhostedAreaSpec + template ClusterSequenceActiveArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations = false) ; + + virtual double area (const PseudoJet & jet) const { + return _average_area[jet.cluster_hist_index()];}; + virtual double area_error (const PseudoJet & jet) const { + return _average_area2[jet.cluster_hist_index()];}; + + virtual PseudoJet area_4vector (const PseudoJet & jet) const { + return _average_area_4vector[jet.cluster_hist_index()];}; + + /// enum providing a variety of tentative strategies for estimating + /// the background (e.g. non-jet) activity in a highly populated event; the + /// one that has been most extensively tested is median. + enum mean_pt_strategies{median=0, non_ghost_median, pttot_over_areatot, + pttot_over_areatot_cut, mean_ratio_cut, play, + median_4vector}; + + /// return the transverse momentum per unit area according to one + /// of the above strategies; for some strategies (those with "cut" + /// in their name) the parameter "range" allows one to exclude a + /// subset of the jets for the background estimation, those that + /// have pt/area > median(pt/area)*range. + /// + /// NB: This call is OBSOLETE; use media_pt_per_unit_area from the + // ClusterSequenceAreaBase class instead + double pt_per_unit_area(mean_pt_strategies strat=median, + double range=2.0 ) const; + + // following code removed -- now dealt with by AreaBase class (and + // this definition here conflicts with it). +// /// fits a form pt_per_unit_area(y) = a + b*y^2 in the range +// /// abs(y) & unique_hist_order, + const ClusterSequenceActiveAreaExplicitGhosts & ); + + /// child classes benefit from having these at their disposal + std::valarray _average_area, _average_area2; + std::valarray _average_area_4vector; + + /// returns true if there are any particles whose transverse momentum + /// if so low that there's a risk of the ghosts having modified the + /// clustering sequence + bool has_dangerous_particles() const {return _has_dangerous_particles;} + +private: + + + double _non_jet_area, _non_jet_area2, _non_jet_number; + + double _maxrap_for_area; // max rap where we put ghosts + double _safe_rap_for_area; // max rap where we trust jet areas + + bool _has_dangerous_particles; + + + /// routine for extracting the tree in an order that will be independent + /// of any degeneracies in the recombination sequence that don't + /// affect the composition of the final jets + void _extract_tree(std::vector &) const; + /// do the part of the extraction associated with pos, working + /// through its children and their parents + void _extract_tree_children(int pos, std::valarray &, const std::valarray &, std::vector &) const; + /// do the part of the extraction associated with the parents of pos. + void _extract_tree_parents (int pos, std::valarray &, const std::valarray &, std::vector &) const; + + /// check if two jets have the same momentum to within the + /// tolerance (and if pt's are not the same we're forgiving and + /// look to see if the energy is the same) + void _throw_unless_jets_have_same_perp_or_E(const PseudoJet & jet, + const PseudoJet & refjet, + double tolerance, + const ClusterSequenceActiveAreaExplicitGhosts & jets_ghosted_seq + ) const; + + /// since we are playing nasty games with seeds, we should warn + /// the user a few times + //static int _n_seed_warnings; + //const static int _max_seed_warnings = 10; + + // record the number of repeats + int _area_spec_repeat; + + /// a class for our internal storage of ghost jets + class GhostJet : public PseudoJet { + public: + GhostJet(const PseudoJet & j, double a) : PseudoJet(j), area(a){} + double area; + }; + + std::vector _ghost_jets; + std::vector _unclustered_ghosts; +}; + + + + +template ClusterSequenceActiveArea::ClusterSequenceActiveArea +(const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations) { + + // transfer the initial jets (type L) into our own array + _transfer_input_jets(pseudojets); + + // run the clustering for active areas + _initialise_and_run_AA(jet_def, area_spec, writeout_combinations); + +} + + + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEACTIVEAREA_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh b/JETAN/fastjet/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh new file mode 100644 index 00000000000..94f624db86e --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh @@ -0,0 +1,235 @@ +//STARTHEADER +// $Id: ClusterSequenceActiveAreaExplicitGhosts.hh 1303 2008-10-29 16:42:09Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEACTIVEAREAEXPLICITGHOSTS_HH_ +#define __FASTJET_CLUSTERSEQUENCEACTIVEAREAEXPLICITGHOSTS_HH_ + +#include "fastjet/PseudoJet.hh" +#include "fastjet/ClusterSequenceAreaBase.hh" +#include "fastjet/GhostedAreaSpec.hh" +#include "fastjet/internal/LimitedWarning.hh" +#include +#include + +namespace fastjet { // defined in fastjet/internal/base.hh + +//====================================================================== +/// Class that behaves essentially like ClusterSequence except +/// that it also provides access to the area of a jet (which +/// will be a random quantity... Figure out what to do about seeds +/// later...) +class ClusterSequenceActiveAreaExplicitGhosts : + public ClusterSequenceAreaBase { +public: + /// constructor using a GhostedAreaSpec to specify how the area is + /// to be measured + template ClusterSequenceActiveAreaExplicitGhosts + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations = false) + : ClusterSequenceAreaBase() { + std::vector * ghosts = NULL; + _initialise(pseudojets,jet_def,&area_spec,ghosts,0.0, + writeout_combinations); } + + template ClusterSequenceActiveAreaExplicitGhosts + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const std::vector & ghosts, + double ghost_area, + const bool & writeout_combinations = false) + : ClusterSequenceAreaBase() { + const GhostedAreaSpec * area_spec = NULL; + _initialise(pseudojets,jet_def,area_spec,&ghosts,ghost_area, + writeout_combinations); } + + + /// does the actual work of initialisation + template void _initialise + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec * area_spec, + const std::vector * ghosts, + double ghost_area, + const bool & writeout_combinations); + + //vector constituents (const PseudoJet & jet) const; + + /// returns the number of hard particles (i.e. those supplied by the user). + unsigned int n_hard_particles() const; + + /// returns the area of a jet + virtual double area (const PseudoJet & jet) const; + + /// returns a four vector corresponding to the sum (E-scheme) of the + /// ghost four-vectors composing the jet area, normalised such that + /// for a small contiguous area the p_t of the extended_area jet is + /// equal to area of the jet. + virtual PseudoJet area_4vector (const PseudoJet & jet) const; + + /// true if a jet is made exclusively of ghosts + virtual bool is_pure_ghost(const PseudoJet & jet) const; + + /// true if the entry in the history index corresponds to a + /// ghost; if hist_ix does not correspond to an actual particle + /// (i.e. hist_ix < 0), then the result is false. + bool is_pure_ghost(int history_index) const; + + /// this class does have explicit ghosts + virtual bool has_explicit_ghosts() const {return true;} + + /// return the total area, up to |y| _is_pure_ghost; + std::vector _areas; + std::vector _area_4vectors; + + // things related to checks for dangerous particles + double _max_ghost_perp2; + bool _has_dangerous_particles; + static LimitedWarning _warnings; + + //static int _n_warn_dangerous_particles; + //static const int _max_warn_dangerous_particles = 5; + + + unsigned int _initial_hard_n; + + /// adds the "ghost" momenta, which will be used to estimate + /// the jet area + void _add_ghosts(const GhostedAreaSpec & area_spec); + + /// another way of adding ghosts + template void _add_ghosts ( + const std::vector & ghosts, + double ghost_area); + + /// routine to be called after the processing is done so as to + /// establish summary information on all the jets (areas, whether + /// pure ghost, etc.) + void _post_process(); + +}; + + +//---------------------------------------------------------------------- +// initialise from some generic type... Has to be made available +// here in order for the template aspect of it to work... +template void ClusterSequenceActiveAreaExplicitGhosts::_initialise + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec * area_spec, + const std::vector * ghosts, + double ghost_area, + const bool & writeout_combinations) { + // don't reserve space yet -- will be done below + + // insert initial jets this way so that any type L that can be + // converted to a pseudojet will work fine (basically PseudoJet + // and any type that has [] subscript access to the momentum + // components, such as CLHEP HepLorentzVector). + for (unsigned int i = 0; i < pseudojets.size(); i++) { + PseudoJet mom(pseudojets[i]); + //mom.set_user_index(0); // for user's particles (user index now lost...) + _jets.push_back(mom); + _is_pure_ghost.push_back(false); + } + + _initial_hard_n = _jets.size(); + + if (area_spec != NULL) { + _add_ghosts(*area_spec); + } else { + _add_ghosts(*ghosts, ghost_area); + } + + if (writeout_combinations) { + std::cout << "# Printing particles including ghosts\n"; + for (unsigned j = 0; j < _jets.size(); j++) { + printf("%5u %20.13f %20.13f %20.13e\n", + j,_jets[j].rap(),_jets[j].phi_02pi(),_jets[j].kt2()); + } + std::cout << "# Finished printing particles including ghosts\n"; + } + + // this will ensure that we can still point to jets without + // difficulties arising! + _jets.reserve(_jets.size()*2); + + // run the clustering + _initialise_and_run(jet_def,writeout_combinations); + + // set up all other information + _post_process(); +} + + +inline unsigned int ClusterSequenceActiveAreaExplicitGhosts::n_hard_particles() const {return _initial_hard_n;} + + +//---------------------------------------------------------------------- +/// add an explicitly specified bunch of ghosts +template void ClusterSequenceActiveAreaExplicitGhosts::_add_ghosts ( + const std::vector & ghosts, + double ghost_area) { + + + for (unsigned i = 0; i < ghosts.size(); i++) { + _is_pure_ghost.push_back(true); + _jets.push_back(ghosts[i]); + } + // and record some info about ghosts + _ghost_area = ghost_area; + _n_ghosts = ghosts.size(); +} + + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEACTIVEAREAEXPLICITGHOSTS_HH_ diff --git a/JETAN/fastjet/fastjet/ClusterSequenceArea.hh b/JETAN/fastjet/fastjet/ClusterSequenceArea.hh new file mode 100644 index 00000000000..97cf76bdf23 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequenceArea.hh @@ -0,0 +1,244 @@ +//STARTHEADER +// $Id: ClusterSequenceArea.hh 1303 2008-10-29 16:42:09Z salam $ +// +// Copyright (c) 2006-2007, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEAREA_HH__ +#define __FASTJET_CLUSTERSEQUENCEAREA_HH__ + +#include "fastjet/ClusterSequenceAreaBase.hh" +#include "fastjet/ClusterSequenceActiveArea.hh" +#include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh" +#include "fastjet/ClusterSequencePassiveArea.hh" +#include "fastjet/ClusterSequenceVoronoiArea.hh" +#include "fastjet/AreaDefinition.hh" + +namespace fastjet { + +/// General class for user to obtain ClusterSequence with additional +/// area information. +/// +/// Based on the area_def, it automatically dispatches the work to the +/// appropriate actual ClusterSequenceAreaBase-derived-class to do the +/// real work. +class ClusterSequenceArea : public ClusterSequenceAreaBase { +public: + /// main constructor + template ClusterSequenceArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const AreaDefinition & area_def_in) : _area_def(area_def_in) { + initialize_and_run_cswa(pseudojets, jet_def); + } + + /// constructor with a GhostedAreaSpec + template ClusterSequenceArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec) : _area_def(area_spec){ + initialize_and_run_cswa(pseudojets, jet_def); + } + + /// constructor with a VoronoiAreaSpec + template ClusterSequenceArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const VoronoiAreaSpec & area_spec) : _area_def(area_spec){ + initialize_and_run_cswa(pseudojets, jet_def); + } + + /// return a reference to the area definition + const AreaDefinition & area_def() const {return _area_def;} + + + /// return the area associated with the given jet + virtual double area (const PseudoJet & jet) const { + return _area_base->area(jet);} + + /// return the error (uncertainty) associated with the determination + /// of the area of this jet + virtual double area_error (const PseudoJet & jet) const { + return _area_base->area_error(jet);} + + /// return the 4-vector area + virtual PseudoJet area_4vector(const PseudoJet & jet) const { + return _area_base->area_4vector(jet);} + + // /// return the total area, up to |y|empty_area(maxrap);} + // + // /// return something similar to the number of pure ghost jets + // /// in the given rapidity range in an active area case. + // /// For the local implementation we return empty_area/(0.55 pi R^2), + // /// based on measured properties of ghost jets with kt and cam. Note + // /// that the number returned is a double. + // virtual double n_empty_jets(double maxrap) const { + // return _area_base->n_empty_jets(maxrap); + + /// return the total area, in the given rap-phi range, that is free of jets + virtual double empty_area(const RangeDefinition & range) const { + return _area_base->empty_area(range);} + + /// return something similar to the number of pure ghost jets + /// in the given rap-phi range in an active area case. + /// For the local implementation we return empty_area/(0.55 pi R^2), + /// based on measured properties of ghost jets with kt and cam. Note + /// that the number returned is a double. + virtual double n_empty_jets(const RangeDefinition & range) const { + return _area_base->n_empty_jets(range); + } + + /// true if a jet is made exclusively of ghosts + virtual bool is_pure_ghost(const PseudoJet & jet) const { + return _area_base->is_pure_ghost(jet); + } + + /// true if this ClusterSequence has explicit ghosts + virtual bool has_explicit_ghosts() const { + return _area_base->has_explicit_ghosts(); + } + + + /// overload version of what's in the ClusterSequenceAreaBase class, which + /// additionally checks compatibility between "range" and region in which + /// ghosts are thrown. + virtual void get_median_rho_and_sigma(const std::vector & all_jets, + const RangeDefinition & range, + bool use_area_4vector, + double & median, double & sigma, + double & mean_area, + bool all_are_incl = false) const { + _warn_if_range_unsuitable(range); + ClusterSequenceAreaBase::get_median_rho_and_sigma( + all_jets, range, use_area_4vector, + median, sigma, mean_area, all_are_incl); + } + + /// overload version of what's in the ClusterSequenceAreaBase class, + /// which actually just does the same thing as the base version (but + /// since we've overridden the 5-argument version above, we have to + /// override the 4-argument version too. + virtual void get_median_rho_and_sigma(const RangeDefinition & range, + bool use_area_4vector, + double & median, double & sigma) const { + ClusterSequenceAreaBase::get_median_rho_and_sigma(range,use_area_4vector, + median,sigma); + } + + /// overload version of what's in the ClusterSequenceAreaBase class, + /// which actually just does the same thing as the base version (but + /// since we've overridden the multi-argument version above, we have to + /// override the 5-argument version too. + virtual void get_median_rho_and_sigma(const RangeDefinition & range, + bool use_area_4vector, + double & median, double & sigma, + double & mean_area) const { + ClusterSequenceAreaBase::get_median_rho_and_sigma(range,use_area_4vector, + median,sigma, mean_area); + } + + + /// overload version of what's in the ClusterSequenceAreaBase class, which + /// additionally checks compatibility between "range" and region in which + /// ghosts are thrown. + virtual void parabolic_pt_per_unit_area(double & a, double & b, + const RangeDefinition & range, + double exclude_above=-1.0, + bool use_area_4vector=false) const { + _warn_if_range_unsuitable(range); + ClusterSequenceAreaBase::parabolic_pt_per_unit_area( + a,b,range, exclude_above, use_area_4vector); + } + + +private: + + /// print a warning if the range is unsuitable for the current + /// calculation of the area (e.g. because ghosts do not extend + /// far enough). + void _warn_if_range_unsuitable(const RangeDefinition & range) const; + + template void initialize_and_run_cswa ( + const std::vector & pseudojets, + const JetDefinition & jet_def); + + std::auto_ptr _area_base; + AreaDefinition _area_def; + static LimitedWarning _range_warnings; + +}; + +//---------------------------------------------------------------------- +template void ClusterSequenceArea::initialize_and_run_cswa( + const std::vector & pseudojets, + const JetDefinition & jet_def) + { + + ClusterSequenceAreaBase * _area_base_ptr; + switch(_area_def.area_type()) { + case active_area: + _area_base_ptr = new ClusterSequenceActiveArea(pseudojets, + jet_def, + _area_def.ghost_spec()); + break; + case active_area_explicit_ghosts: + _area_base_ptr = new ClusterSequenceActiveAreaExplicitGhosts(pseudojets, + jet_def, + _area_def.ghost_spec()); + break; + case voronoi_area: + _area_base_ptr = new ClusterSequenceVoronoiArea(pseudojets, + jet_def, + _area_def.voronoi_spec()); + break; + case one_ghost_passive_area: + _area_base_ptr = new ClusterSequence1GhostPassiveArea(pseudojets, + jet_def, + _area_def.ghost_spec()); + break; + case passive_area: + _area_base_ptr = new ClusterSequencePassiveArea(pseudojets, + jet_def, + _area_def.ghost_spec()); + break; + default: + std::cerr << "Error: unrecognized area_type in ClusterSequenceArea:" + << _area_def.area_type() << std::endl; + exit(-1); + } + // now copy across the information from the area base class + _area_base = std::auto_ptr(_area_base_ptr); + transfer_from_sequence(*_area_base); +} + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEAREA_HH__ + + diff --git a/JETAN/fastjet/fastjet/ClusterSequenceAreaBase.hh b/JETAN/fastjet/fastjet/ClusterSequenceAreaBase.hh new file mode 100644 index 00000000000..ec0b5e78785 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequenceAreaBase.hh @@ -0,0 +1,257 @@ +//STARTHEADER +// $Id: ClusterSequenceAreaBase.hh 1503 2009-04-06 11:32:52Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEAREABASE_HH__ +#define __FASTJET_CLUSTERSEQUENCEAREABASE_HH__ + +#include "fastjet/ClusterSequence.hh" +#include "fastjet/internal/LimitedWarning.hh" +#include "fastjet/RangeDefinition.hh" + +namespace fastjet { + +/// base class that sets interface for extensions of ClusterSequence +/// that provide information about the area of each jet; +/// +/// the virtual functions here all return 0, since no area determination +/// is implemented. +class ClusterSequenceAreaBase : public ClusterSequence { +public: + + /// a constructor which just carries out the construction of the + /// parent class + template ClusterSequenceAreaBase + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const bool & writeout_combinations = false) : + ClusterSequence(pseudojets, jet_def, writeout_combinations) {} + + + /// default constructor + ClusterSequenceAreaBase() {} + + + /// destructor + virtual ~ClusterSequenceAreaBase() {} + + + /// return the area associated with the given jet; this base class + /// returns 0. + virtual double area (const PseudoJet & jet) const {return 0.0;} + + /// return the error (uncertainty) associated with the determination + /// of the area of this jet; this base class returns 0. + virtual double area_error (const PseudoJet & jet) const {return 0.0;} + + /// return a PseudoJet whose 4-vector is defined by the following integral + /// + /// \int drap d\phi PseudoJet("rap,phi,pt=one") * + /// * Theta("rap,phi inside jet boundary") + /// + /// where PseudoJet("rap,phi,pt=one") is a 4-vector with the given + /// rapidity (rap), azimuth (phi) and pt=1, while Theta("rap,phi + /// inside jet boundary") is a function that is 1 when rap,phi + /// define a direction inside the jet boundary and 0 otherwise. + /// + /// This base class returns a null 4-vector. + virtual PseudoJet area_4vector(const PseudoJet & jet) const { + return PseudoJet(0.0,0.0,0.0,0.0);} + + /// true if a jet is made exclusively of ghosts + /// + /// NB: most area classes do not give any explicit ghost jets, but + /// some do, and they should replace this function with their own + /// version. + virtual bool is_pure_ghost(const PseudoJet & jet) const { + return false; + } + + /// returns true if ghosts are explicitly included within + /// jets for this ClusterSequence; + /// + /// Derived classes that do include explicit ghosts should provide + /// an alternative version of this routine and set it properly. + virtual bool has_explicit_ghosts() const { + return false; + } + + /// return the total area, within range, that is free of jets, in + /// general based on the inclusive jets + virtual double empty_area(const RangeDefinition & range) const; + + /// return the total area, within range, that is free of jets, based + /// on the supplied all_jets + double empty_area_from_jets(const std::vector & all_jets, + const RangeDefinition & range) const; + + /// return something similar to the number of pure ghost jets + /// in the given range in an active area case. + /// For the local implementation we return empty_area/(0.55 pi R^2), + /// based on measured properties of ghost jets with kt and cam. Note + /// that the number returned is a double. + virtual double n_empty_jets(const RangeDefinition & range) const { + double R = jet_def().R(); + return empty_area(range)/(0.55*pi*R*R); + } + + /// the median of (pt/area) for jets contained within range, + /// making use also of the info on n_empty_jets + double median_pt_per_unit_area(const RangeDefinition & range) const; + + /// the median of (pt/area_4vector) for jets contained within + /// making use also of the info on n_empty_jets + double median_pt_per_unit_area_4vector(const RangeDefinition & range) const; + + /// the function that does the work for median_pt_per_unit_area and + /// median_pt_per_unit_area_4vector: + /// - something_is_area_4vect = false -> use plain area + /// - something_is_area_4vect = true -> use 4-vector area + double median_pt_per_unit_something( + const RangeDefinition & range, bool use_area_4vector) const; + + /// using jets withing range (and with 4-vector areas if + /// use_area_4vector), calculate the median pt/area, as well as an + /// "error" (uncertainty), which is defined as the 1-sigma + /// half-width of the distribution of pt/A, obtained by looking for + /// the point below which we have (1-0.6827)/2 of the jets + /// (including empty jets). + /// + /// The subtraction for a jet with uncorrected pt pt^U and area A is + /// + /// pt^S = pt^U - median*A +- sigma*sqrt(A) + /// + /// where the error is only that associated with the fluctuations + /// in the noise and not that associated with the noise having + /// caused changes in the hard-particle content of the jet. + /// + /// NB: subtraction may also be done with 4-vector area of course, + /// and this is recommended for jets with larger values of R, as + /// long as rho has also been determined with a 4-vector area; + /// using a scalar area causes one to neglect terms of relative + /// order $R^2/8$ in the jet $p_t$. + virtual void get_median_rho_and_sigma(const RangeDefinition & range, + bool use_area_4vector, + double & median, double & sigma, + double & mean_area) const; + + /// a more advanced version of get_median_rho_and_sigma, which allows + /// one to use any "view" of the event containing all jets (so that, + /// e.g. one might use Cam on a different resolution scale without + /// have to rerun the algorithm). + /// + /// By default it will assume that "all" are not inclusive jets, + /// so that in dealing with empty area it has to calculate + /// the number of empty jets based on the empty area and the + /// the observed of jets rather than a surmised area + /// + /// Note that for small effective radii, this can cause problems + /// because the harder jets get an area >> + /// and so the estimate comes out all wrong. In these situations + /// it is highly advisable to use an area with explicit ghosts, since + /// then the "empty" jets are actually visible. + virtual void get_median_rho_and_sigma(const std::vector & all_jets, + const RangeDefinition & range, + bool use_area_4vector, + double & median, double & sigma, + double & mean_area, + bool all_are_inclusive = false) const; + + /// same as the full version of get_median_rho_and_error, but without + /// access to the mean_area + virtual void get_median_rho_and_sigma(const RangeDefinition & range, + bool use_area_4vector, + double & median, double & sigma) const { + double mean_area; + get_median_rho_and_sigma(range, use_area_4vector, + median, sigma, mean_area); + } + + + /// fits a form pt_per_unit_area(y) = a + b*y^2 in the range "range". + /// exclude_above allows one to exclude large values of pt/area from fit. + /// (if negative, the cut is discarded) + /// use_area_4vector = true uses the 4vector areas. + virtual void parabolic_pt_per_unit_area(double & a, double & b, + const RangeDefinition & range, + double exclude_above=-1.0, + bool use_area_4vector=false) const; + + /// return a vector of all subtracted jets, using area_4vector, given rho. + /// Only inclusive_jets above ptmin are subtracted and returned. + /// the ordering is the same as that of sorted_by_pt(cs.inclusive_jets()), + /// i.e. not necessarily ordered in pt once subtracted + std::vector subtracted_jets(const double rho, + const double ptmin=0.0) const; + + /// return a vector of subtracted jets, using area_4vector. + /// Only inclusive_jets above ptmin are subtracted and returned. + /// the ordering is the same as that of sorted_by_pt(cs.inclusive_jets()), + /// i.e. not necessarily ordered in pt once subtracted + std::vector subtracted_jets(const RangeDefinition & range, + const double ptmin=0.0) const; + + /// return a subtracted jet, using area_4vector, given rho + PseudoJet subtracted_jet(const PseudoJet & jet, + const double rho) const; + + /// return a subtracted jet, using area_4vector; note + /// that this is potentially inefficient if repeatedly used for many + /// different jets, because rho will be recalculated each time + /// around. + PseudoJet subtracted_jet(const PseudoJet & jet, + const RangeDefinition & range) const; + + /// return the subtracted pt, given rho + double subtracted_pt(const PseudoJet & jet, + const double rho, + bool use_area_4vector=false) const; + + /// return the subtracted pt; note that this is + /// potentially inefficient if repeatedly used for many different + /// jets, because rho will be recalculated each time around. + double subtracted_pt(const PseudoJet & jet, + const RangeDefinition & range, + bool use_area_4vector=false) const; + + +private: + /// handle warning messages + static LimitedWarning _warnings; + + /// check the jet algorithm is suitable (and if not issue a warning) + void _check_jet_alg_good_for_median() const; + +}; + + + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEAREABASE_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequencePassiveArea.hh b/JETAN/fastjet/fastjet/ClusterSequencePassiveArea.hh new file mode 100644 index 00000000000..e075607d368 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequencePassiveArea.hh @@ -0,0 +1,93 @@ +//STARTHEADER +// $Id: ClusterSequencePassiveArea.hh 1134 2008-03-15 17:05:16Z salam $ +// +// Copyright (c) 2005-2007, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEPASSIVEAREA_HH__ +#define __FASTJET_CLUSTERSEQUENCEPASSIVEAREA_HH__ + + +#include "fastjet/PseudoJet.hh" +#include "fastjet/ClusterSequence1GhostPassiveArea.hh" +#include +#include + +namespace fastjet { // defined in fastjet/internal/base.hh + +//using namespace std; + +/// Class that behaves essentially like ClusterSequence except +/// that it also provides access to the area of a jet (which +/// will be a random quantity... Figure out what to do about seeds +/// later...) +class ClusterSequencePassiveArea : public ClusterSequence1GhostPassiveArea { +public: + + /// constructor based on JetDefinition and PassiveAreaSpec + template ClusterSequencePassiveArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations = false) ; + + /// return an empty area that's appropriate to the passive area + /// determination carried out + virtual double empty_area(const RangeDefinition & range) const; + +private: + + /// does the initialisation and running specific to the passive + /// areas class + void _initialise_and_run_PA (const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations = false); + +}; + + + + +template ClusterSequencePassiveArea::ClusterSequencePassiveArea +(const std::vector & pseudojets, + const JetDefinition & jet_def, + const GhostedAreaSpec & area_spec, + const bool & writeout_combinations) { + + // transfer the initial jets (type L) into our own array + _transfer_input_jets(pseudojets); + + // run the clustering for passive areas + _initialise_and_run_PA(jet_def, area_spec, writeout_combinations); + +} + + + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEPASSIVEAREA_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequenceVoronoiArea.hh b/JETAN/fastjet/fastjet/ClusterSequenceVoronoiArea.hh new file mode 100644 index 00000000000..ad4ec638023 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequenceVoronoiArea.hh @@ -0,0 +1,117 @@ +//STARTHEADER +// $Id: ClusterSequenceVoronoiArea.hh 621 2007-05-09 10:34:30Z salam $ +// +// Copyright (c) 2005-2007, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEVORONOIAREA_HH__ +#define __FASTJET_CLUSTERSEQUENCEVORONOIAREA_HH__ + +#include "fastjet/PseudoJet.hh" +#include "fastjet/AreaDefinition.hh" +#include "fastjet/ClusterSequenceAreaBase.hh" +#include +#include + +namespace fastjet { // defined in fastjet/internal/base.hh + +/** + * \class ClusterSequenceVoronoiArea + * Handle the computation of Voronoi jet area. + */ +class ClusterSequenceVoronoiArea : public ClusterSequenceAreaBase { +public: + /// template ctor + /// \param pseudojet list of jets (template type) + /// \param jet_def jet definition + /// \param effective_Rfact effective radius + /// \param writeout_combinations ?????? + template ClusterSequenceVoronoiArea + (const std::vector & pseudojets, + const JetDefinition & jet_def, + const VoronoiAreaSpec & spec = VoronoiAreaSpec(), + const bool & writeout_combinations = false); + + /// default dtor + ~ClusterSequenceVoronoiArea(); + + /// return the area associated with the given jet + virtual inline double area(const PseudoJet & jet) const { + return _voronoi_area[jet.cluster_hist_index()];}; + + /// return a 4-vector area associated with the given jet -- stricly + /// this is not the exact 4-vector area, but rather an approximation + /// made of sums of centres of all Voronoi cells in jet, each + /// contributing with a normalisation equal to the area of the cell + virtual inline PseudoJet area_4vector(const PseudoJet & jet) const { + return _voronoi_area_4vector[jet.cluster_hist_index()];}; + + /// return the error of the area associated with the given jet + /// (0 by definition for a voronoi area) + virtual inline double area_error(const PseudoJet & jet) const { + return 0.0;}; + + /// passive area calculator -- to be defined in the .cc file (it will do + /// the true hard work) + class VoronoiAreaCalc; + + +private: + /// initialisation of the Voronoi Area + void _initializeVA(); + + std::vector _voronoi_area; ///< vector containing the result + std::vector _voronoi_area_4vector; ///< vector containing approx 4-vect areas + VoronoiAreaCalc *_pa_calc; ///< area calculator + double _effective_Rfact; ///< effective radius +}; + + + + +/// template constructor need to be specified in the header! +//---------------------------------------------------------------------- +template ClusterSequenceVoronoiArea::ClusterSequenceVoronoiArea +(const std::vector &pseudojets, + const JetDefinition &jet_def, + const VoronoiAreaSpec & spec, + const bool & writeout_combinations) : + _effective_Rfact(spec.effective_Rfact()) { + + // transfer the initial jets (type L) into our own array + _transfer_input_jets(pseudojets); + + // run the clustering + _initialise_and_run(jet_def,writeout_combinations); + + // the jet clustering's already been done, now worry about areas... + _initializeVA(); +} + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEVORONOIAREA_HH__ diff --git a/JETAN/fastjet/fastjet/ClusterSequenceWithArea.hh b/JETAN/fastjet/fastjet/ClusterSequenceWithArea.hh new file mode 100644 index 00000000000..24b77cbfeb9 --- /dev/null +++ b/JETAN/fastjet/fastjet/ClusterSequenceWithArea.hh @@ -0,0 +1,45 @@ +//STARTHEADER +// $Id: ClusterSequenceWithArea.hh 699 2007-06-04 20:20:42Z salam $ +// +// Copyright (c) 2006-2007, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLUSTERSEQUENCEWITHAREA_HH__ +#define __FASTJET_CLUSTERSEQUENCEWITHAREA_HH__ + +#include "fastjet/ClusterSequenceAreaBase.hh" + +namespace fastjet { + +//----- backwards compatibility with version 2.1 --------------- +typedef ClusterSequenceAreaBase ClusterSequenceWithArea; + +} // fastjet namespace + +#endif // __FASTJET_CLUSTERSEQUENCEWITHAREA_HH__ + + diff --git a/JETAN/fastjet/fastjet/EECambridgePlugin.hh b/JETAN/fastjet/fastjet/EECambridgePlugin.hh new file mode 100644 index 00000000000..9ccfbee9671 --- /dev/null +++ b/JETAN/fastjet/fastjet/EECambridgePlugin.hh @@ -0,0 +1,87 @@ +#ifndef __EECAMBRIDGEPLUGIN_HH__ +#define __EECAMBRIDGEPLUGIN_HH__ + +//STARTHEADER +// $Id: EECambridgePlugin.hh 1491 2009-03-11 17:04:38Z salam $ +// +// Copyright (c) 2009, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#include "fastjet/JetDefinition.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +// forward declaration to reduce includes +class ClusterSequence; + +//---------------------------------------------------------------------- +// +/// EECambridgePlugin is a plugin for fastjet (v2.4 upwards) +/// +/// It implements the Cambridge algorithm, as defined in +/// +/// Better jet clustering algorithms +/// Yuri Dokshitzer, Garth Leder, Stefano Moretti, Bryan Webber +/// JHEP 9708 (1997) 001 +/// http://www-spires.slac.stanford.edu/spires/find/hep/www?rawcmd=FIND+j+JHEPA%2C9708%2C001 +/// +/// On construction one must supply a ycut value. +/// +/// To get the jets at the end call ClusterSequence::inclusive_jets(); +/// +class EECambridgePlugin : public JetDefinition::Plugin { +public: + /// Main constructor for the EECambridge Plugin class. + /// It takes the dimensionless parameter ycut (the Q value for normalisation + /// of the kt-distances is taken from the sum of all particle energies). + EECambridgePlugin (double ycut) : _ycut(ycut) {} + + /// copy constructor + EECambridgePlugin (const EECambridgePlugin & plugin) { + *this = plugin; + } + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const; + + double ycut() const {return _ycut;} + + /// the plugin mechanism's standard way of accessing the jet radius. + /// This must be set to return something sensible, even if R + /// does not make sense for this algorithm! + virtual double R() const {return 1.0;} + +private: + double _ycut; +}; + +} // fastjet namespace + +#endif // __EECAMBRIDGEPLUGIN_HH__ + diff --git a/JETAN/fastjet/fastjet/Error.hh b/JETAN/fastjet/fastjet/Error.hh new file mode 100644 index 00000000000..c73fb92c87b --- /dev/null +++ b/JETAN/fastjet/fastjet/Error.hh @@ -0,0 +1,65 @@ +//STARTHEADER +// $Id: Error.hh 389 2006-12-14 18:29:16Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + + +#ifndef __FASTJET_ERROR_HH__ +#define __FASTJET_ERROR_HH__ + +#include +#include +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// class corresponding to errors that will be thrown by fastjet +class Error { +public: + // constructors + Error() {;}; + Error(const std::string & message) { + _message = message; + if (_print_errors) std::cerr << "fastjet::Error: "< +#include +#include "fastjet/PseudoJet.hh" +#include "fastjet/internal/BasicRandom.hh" + +// +#define STATIC_GENERATOR 1 + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// namespace to hold default parameters for the active area spec +namespace gas { + const double def_ghost_maxrap = 6.0; + const int def_repeat = 1; + const double def_ghost_area = 0.01; + const double def_grid_scatter = 1.0; + const double def_kt_scatter = 0.1; + const double def_mean_ghost_kt = 1e-100; +} + +//---------------------------------------------------------------------- +/// Class that defines the parameters that go into the measurement +/// of active jet areas. +class GhostedAreaSpec { +public: + /// default constructor + GhostedAreaSpec(): _ghost_maxrap (gas::def_ghost_maxrap), + _ghost_rap_offset(0.0), + _repeat (gas::def_repeat), + _ghost_area (gas::def_ghost_area), + _grid_scatter (gas::def_grid_scatter), + _kt_scatter (gas::def_kt_scatter), + _mean_ghost_kt(gas::def_mean_ghost_kt), + _actual_ghost_area(-1.0) {_initialize();}; + + /// explicit constructor + explicit GhostedAreaSpec(double ghost_maxrap, + int repeat = gas::def_repeat, + double ghost_area = gas::def_ghost_area, + double grid_scatter = gas::def_grid_scatter, + double kt_scatter = gas::def_kt_scatter, + double mean_ghost_kt = gas::def_mean_ghost_kt + ): + _ghost_maxrap(ghost_maxrap), + _ghost_rap_offset(0.0), + _repeat(repeat), + _ghost_area(ghost_area), + _grid_scatter(grid_scatter), + _kt_scatter(kt_scatter), + _mean_ghost_kt(mean_ghost_kt), + _actual_ghost_area(-1.0) {_initialize();}; + + /// explicit constructor + explicit GhostedAreaSpec(double ghost_minrap, + double ghost_maxrap, + int repeat = gas::def_repeat, + double ghost_area = gas::def_ghost_area, + double grid_scatter = gas::def_grid_scatter, + double kt_scatter = gas::def_kt_scatter, + double mean_ghost_kt = gas::def_mean_ghost_kt + ): + _ghost_maxrap (0.5*(ghost_maxrap - ghost_minrap)), + _ghost_rap_offset(0.5*(ghost_maxrap + ghost_minrap)), + _repeat(repeat), + _ghost_area(ghost_area), + _grid_scatter(grid_scatter), + _kt_scatter(kt_scatter), + _mean_ghost_kt(mean_ghost_kt), + _actual_ghost_area(-1.0) {_initialize();}; + + + /// does the initialization of actual ghost parameters + void _initialize(); + + // for accessing values set by the user + inline double ghost_etamax() const {return _ghost_maxrap;}; + inline double ghost_maxrap() const {return _ghost_maxrap;}; + inline double ghost_area () const {return _ghost_area ;}; + inline double grid_scatter() const {return _grid_scatter;}; + inline double kt_scatter () const {return _kt_scatter ;}; + inline double mean_ghost_kt() const {return _mean_ghost_kt ;}; + inline int repeat () const {return _repeat ;}; + + // for accessing values + inline double actual_ghost_area() const {return _actual_ghost_area;}; + inline int n_ghosts() const {return _n_ghosts;}; + + // when explicitly modifying values, sometimes call the initializer + inline void set_ghost_area (double val) {_ghost_area = val; _initialize();}; + inline void set_ghost_etamax(double val) {_ghost_maxrap = val; _initialize();}; + inline void set_ghost_maxrap(double val) {_ghost_maxrap = val; _initialize();}; + inline void set_grid_scatter(double val) {_grid_scatter = val; }; + inline void set_kt_scatter (double val) {_kt_scatter = val; }; + inline void set_mean_ghost_kt(double val){_mean_ghost_kt = val; }; + inline void set_repeat (int val) {_repeat = val; }; + + /// return nphi (ghosts layed out (-nrap, 0..nphi-1), (-nrap+1,0..nphi-1), + /// ... (nrap,0..nphi-1) + inline int nphi() const {return _nphi;} + inline int nrap() const {return _nrap;} + + /// get all relevant information about the status of the + /// random number generator, so that it can be reset subsequently + /// with set_random_status. + inline void get_random_status(std::vector & __iseed) const { + _random_generator.get_status(__iseed);} + + /// set the status of the random number generator, as obtained + /// previously with get_random_status. Note that the random + /// generator is a static member of the class, i.e. common to all + /// instances of the class --- so if you modify the random for this + /// instance, you modify it for all instances. + inline void set_random_status(const std::vector & __iseed) { + _random_generator.set_status(__iseed);} + + inline void checkpoint_random() {get_random_status(_random_checkpoint);} + inline void restore_checkpoint_random() {set_random_status(_random_checkpoint);} + + /// for a summary + std::string description() const; + + /// push the ghost 4-momenta onto the back of the vector of PseudoJets + void add_ghosts(std::vector & ) const; + + /// very deprecated public access to a random number + /// from the internal generator + inline double random_at_own_risk() const {return _our_rand();}; + /// very deprecated public access to the generator itself + inline BasicRandom & generator_at_own_risk() const { + return _random_generator;} + +private: + + // quantities that determine nature and distribution of ghosts + double _ghost_maxrap; + double _ghost_rap_offset; + int _repeat ; + double _ghost_area ; + double _grid_scatter; + double _kt_scatter ; + double _mean_ghost_kt; + + // derived quantities + double _actual_ghost_area, _dphi, _drap; + int _n_ghosts, _nphi, _nrap; + + + std::vector _random_checkpoint; + static BasicRandom _random_generator; + //mutable BasicRandom _random_generator; + + inline double _our_rand() const {return _random_generator();}; + +}; + +////---------------------------------------------------------------------- +//class 1GhostPassiveAreaSpec : public GhostedAreaSpec { +//public: +//} + +} // fastjet namespace + +#endif // __FASTJET_GHOSTEDAREASPEC_HH__ diff --git a/JETAN/fastjet/fastjet/JadePlugin.hh b/JETAN/fastjet/fastjet/JadePlugin.hh new file mode 100644 index 00000000000..06ebf4d7aa8 --- /dev/null +++ b/JETAN/fastjet/fastjet/JadePlugin.hh @@ -0,0 +1,101 @@ +#ifndef __JADEPLUGIN_HH__ +#define __JADEPLUGIN_HH__ + +//STARTHEADER +// $Id: JadePlugin.hh 1491 2009-03-11 17:04:38Z salam $ +// +// Copyright (c) 2009, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#include "fastjet/JetDefinition.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +// forward declaration to reduce includes +class ClusterSequence; + +//---------------------------------------------------------------------- +// +/// JadePlugin is a plugin for fastjet (v2.4 upwards) +/// +/// It implements the JADE algorithm, which is an e+e- sequential +/// recombination algorithm with interparticle distance +/// +/// dij = 2 E_i E_j (1 - cos theta_ij) +/// +/// or equivalently +/// +/// yij = dij/E_{vis}^2 +/// +/// This corresponds to the distance measured used in +/// +/// "Experimental Investigation of the Energy Dependence of the Strong Coupling Strength." +/// JADE Collaboration (S. Bethke et al.) +/// Phys.Lett.B213:235,1988 +/// +/// The JADE article carries out particle recombinations in the +/// E-scheme (4-vector recombination), which is the default procedure for this +/// plugin. +/// +/// NOTE: other widely used schemes include E0, P, P0; however they also +/// involve modifications to the distance measure. Be sure of +/// what you're doing before running a JADE type algorithm. +/// +/// To access the jets with a given ycut value (clustering stops once +/// all yij > ycut), use +/// +/// vector jets = cluster_sequence.exclusive_jets_ycut(ycut); +/// +/// and related routines. +/// +class JadePlugin : public JetDefinition::Plugin { +public: + /// Main constructor for the Jade Plugin class. + JadePlugin (){} + + /// copy constructor + JadePlugin (const JadePlugin & plugin) { + *this = plugin; + } + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const; + + /// the plugin mechanism's standard way of accessing the jet radius. + /// This must be set to return something sensible, even if R + /// does not make sense for this algorithm! + virtual double R() const {return 1.0;} + +private: + +}; + +} // fastjet namespace + +#endif // __JADEPLUGIN_HH__ + diff --git a/JETAN/fastjet/fastjet/JetDefinition.hh b/JETAN/fastjet/fastjet/JetDefinition.hh new file mode 100644 index 00000000000..8cc3159e048 --- /dev/null +++ b/JETAN/fastjet/fastjet/JetDefinition.hh @@ -0,0 +1,437 @@ +//STARTHEADER +// $Id: JetDefinition.hh 1402 2009-01-21 18:03:54Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_JETDEFINITION_HH__ +#define __FASTJET_JETDEFINITION_HH__ + +#include +#include "fastjet/internal/numconsts.hh" +#include "fastjet/PseudoJet.hh" +#include +#include + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// return a string containing information about the release +// NB: (implemented in ClusterSequence.cc but defined here because +// this is a visible location) +std::string fastjet_version_string(); + +//====================================================================== +/// the various options for the algorithmic strategy to adopt in +/// clustering events with kt and cambridge style algorithms. +enum Strategy { + /// fastest form about 500..10^4 + N2MinHeapTiled = -4, + /// fastest from about 50..500 + N2Tiled = -3, + /// legacy + N2PoorTiled = -2, + /// fastest below 50 + N2Plain = -1, + /// worse even than the usual N^3 algorithms + N3Dumb = 0, + /// automatic selection of the best (based on N) + Best = 1, + /// best of the NlnN variants -- best overall for N>10^4 + NlnN = 2, + /// legacy N ln N using 3pi coverage of cylinder + NlnN3pi = 3, + /// legacy N ln N using 4pi coverage of cylinder + NlnN4pi = 4, + /// Chan's closest pair method (in a variant with 4pi coverage), + /// for use exclusively with the Cambridge algorithm + NlnNCam4pi = 14, + NlnNCam2pi2R = 13, + NlnNCam = 12, // 2piMultD + /// the plugin has been used... + plugin_strategy = 999 +}; + + +//====================================================================== +/// the various families of jet-clustering algorithm +enum JetAlgorithm { + /// the longitudinally invariant kt algorithm + kt_algorithm=0, + /// the longitudinally invariant variant of the cambridge algorithm + /// (aka Aachen algoithm). + cambridge_algorithm=1, + /// like the k_t but with distance measures + /// dij = min(1/kti^2,1/ktj^2) Delta R_{ij}^2 / R^2 + /// diB = 1/kti^2 + antikt_algorithm=2, + /// like the k_t but with distance measures + /// dij = min(kti^{2p},ktj^{2p}) Delta R_{ij}^2 / R^2 + /// diB = 1/kti^{2p} + /// where p = extra_param() + genkt_algorithm=3, + /// a version of cambridge with a special distance measure for particles + /// whose pt is < extra_param() + cambridge_for_passive_algorithm=11, + /// a version of genkt with a special distance measure for particles + /// whose pt is < extra_param() [relevant for passive areas when p<=0] + genkt_for_passive_algorithm=13, + //................................................................. + /// the e+e- kt algorithm + ee_kt_algorithm=50, + /// the e+e- genkt algorithm (R > 2 and p=1 gives ee_kt) + ee_genkt_algorithm=53, + //................................................................. + /// any plugin algorithm supplied by the user + plugin_algorithm = 99 +}; + +/// make standard Les Houches nomenclature JetAlgorithm (algorithm is general +/// recipe without the parameters) backward-compatible with old JetFinder +typedef JetAlgorithm JetFinder; + +/// provide other possible names for the Cambridge/Aachen algorithm? +const JetAlgorithm aachen_algorithm = cambridge_algorithm; +const JetAlgorithm cambridge_aachen_algorithm = cambridge_algorithm; + +//====================================================================== +/// the various recombination schemes +enum RecombinationScheme { + /// summing the 4-momenta + E_scheme=0, + /// pt weighted recombination of y,phi (and summing of pt's) + /// with preprocessing to make things massless by rescaling E=|\vec p| + pt_scheme=1, + /// pt^2 weighted recombination of y,phi (and summing of pt's) + /// with preprocessing to make things massless by rescaling E=|\vec p| + pt2_scheme=2, + /// pt weighted recombination of y,phi (and summing of pt's) + /// with preprocessing to make things massless by rescaling |\vec p|->=E + Et_scheme=3, + /// pt^2 weighted recombination of y,phi (and summing of pt's) + /// with preprocessing to make things massless by rescaling |\vec p|->=E + Et2_scheme=4, + /// pt weighted recombination of y,phi (and summing of pt's), with + /// no preprocessing + BIpt_scheme=5, + /// pt^2 weighted recombination of y,phi (and summing of pt's) + /// no preprocessing + BIpt2_scheme=6, + /// for the user's external scheme + external_scheme = 99 +}; + + + + +// forward declaration, needed in order to specify interface for the +// plugin. +class ClusterSequence; + + + + +//====================================================================== +/// class that is intended to hold a full definition of the jet +/// clusterer +class JetDefinition { + +public: + + /// forward declaration of a class that allows the user to introduce + /// their own plugin + class Plugin; + + // forward declaration of a class that will provide the + // recombination scheme facilities and/or allow a user to + // extend these facilities + class Recombiner; + + + + /// constructor with alternative ordering or arguments -- note that + /// we have not provided a default jet finder, to avoid ambiguous + /// JetDefinition() constructor. + JetDefinition(JetAlgorithm jet_algorithm, + double R, + RecombinationScheme recomb_scheme = E_scheme, + Strategy strategy = Best) { + *this = JetDefinition(jet_algorithm, R, strategy, recomb_scheme, 1); + } + + /// constructor for algorithms that have no free parameters + /// (e.g. ee_kt_algorithm) + JetDefinition(JetAlgorithm jet_algorithm, + RecombinationScheme recomb_scheme = E_scheme, + Strategy strategy = Best) { + double dummyR = 0.0; + *this = JetDefinition(jet_algorithm, dummyR, strategy, recomb_scheme, 0); + } + + /// constructor for algorithms that require R + one extra parameter to be set + /// (the gen-kt series for example) + JetDefinition(JetAlgorithm jet_algorithm, + double R, + double xtra_param, + RecombinationScheme recomb_scheme = E_scheme, + Strategy strategy = Best) { + *this = JetDefinition(jet_algorithm, R, strategy, recomb_scheme, 2); + set_extra_param(xtra_param); + } + + + /// constructor in a form that allows the user to provide a pointer + /// to an external recombiner class (which must remain valid for the + /// life of the JetDefinition object). + JetDefinition(JetAlgorithm jet_algorithm, + double R, + const Recombiner * recombiner, + Strategy strategy = Best) { + *this = JetDefinition(jet_algorithm, R, external_scheme, strategy); + _recombiner = recombiner; + } + + + /// constructor for case with 0 parameters (ee_kt_algorithm) and + /// and external recombiner + JetDefinition(JetAlgorithm jet_algorithm, + const Recombiner * recombiner, + Strategy strategy = Best) { + *this = JetDefinition(jet_algorithm, external_scheme, strategy); + _recombiner = recombiner; + } + + /// constructor allowing the extra parameter to be set and a pointer to + /// a recombiner + JetDefinition(JetAlgorithm jet_algorithm, + double R, + double xtra_param, + const Recombiner * recombiner, + Strategy strategy = Best) { + *this = JetDefinition(jet_algorithm, R, external_scheme, strategy); + _recombiner = recombiner; + set_extra_param(xtra_param); + } + + /// a default constructor + JetDefinition() { + *this = JetDefinition(kt_algorithm, 1.0); + } + + /// constructor based on a pointer to a user's plugin; the object + /// pointed to must remain valid for the whole duration of existence + /// of the JetDefinition and any related ClusterSequences + JetDefinition(const Plugin * plugin) { + _plugin = plugin; + _strategy = plugin_strategy; + _Rparam = _plugin->R(); + _jet_algorithm = plugin_algorithm; + set_recombination_scheme(E_scheme); + } + + + /// constructor to fully specify a jet-definition (together with + /// information about how algorithically to run it). + /// + /// the ordering of arguments here is old and deprecated (except + /// as the common constructor for internal use) + JetDefinition(JetAlgorithm jet_algorithm, + double R, + Strategy strategy, + RecombinationScheme recomb_scheme = E_scheme, + int nparameters = 1); +// : +// _jet_algorithm(jet_algorithm), _Rparam(R), _strategy(strategy) { +// // the largest sensible value for R +// if (jet_algorithm != ee_kt_algorithm && +// jet_algorithm != ee_genkt_algorithm) assert(_Rparam <= 0.5*pi); +// assert(_jet_algorithm != plugin_algorithm && +// _strategy != plugin_strategy); +// _plugin = NULL; +// set_recombination_scheme(recomb_scheme); +// set_extra_param(0.0); // make sure it's defined +// } + + + /// set the recombination scheme to the one provided + void set_recombination_scheme(RecombinationScheme); + + /// set the recombiner class to the one provided + void set_recombiner(const Recombiner * recomb) { + _recombiner = recomb; + _default_recombiner = DefaultRecombiner(external_scheme); + } + + /// return a pointer to the plugin + const Plugin * plugin() const {return _plugin;}; + + /// return information about the definition... + JetAlgorithm jet_algorithm () const {return _jet_algorithm ;} + /// same as above for backward compatibility + JetAlgorithm jet_finder () const {return _jet_algorithm ;} + double R () const {return _Rparam ;} + // a general purpose extra parameter, whose meaning depends on + // the algorithm, and may often be unused. + double extra_param () const {return _extra_param ;} + Strategy strategy () const {return _strategy ;} + RecombinationScheme recombination_scheme() const { + return _default_recombiner.scheme();} + + /// (re)set the jet finder + void set_jet_algorithm(JetAlgorithm njf) {_jet_algorithm = njf;} + /// same as above for backward compatibility + void set_jet_finder(JetAlgorithm njf) {_jet_algorithm = njf;} + /// (re)set the general purpose extra parameter + void set_extra_param(double xtra_param) {_extra_param = xtra_param;} + + /// return a pointer to the currently defined recombiner (it may + /// be the internal one) + const Recombiner * recombiner() const { + return _recombiner == 0 ? & _default_recombiner : _recombiner;} + + /// return a textual description of the current jet definition + std::string description() const; + + +public: + //====================================================================== + /// An abstract base class that will provide the recombination scheme + /// facilities and/or allow a user to extend these facilities + class Recombiner { + public: + /// return a textual description of the recombination scheme + /// implemented here + virtual std::string description() const = 0; + + /// recombine pa and pb and put result into pab + virtual void recombine(const PseudoJet & pa, const PseudoJet & pb, + PseudoJet & pab) const = 0; + + /// routine called to preprocess each input jet (to make all input + /// jets compatible with the scheme requirements (e.g. massless). + virtual void preprocess(PseudoJet & p) const {}; + + /// a destructor to be replaced if necessary in derived classes... + virtual ~Recombiner() {}; + + /// pa += pb in the given recombination scheme. Not virtual -- the + /// user should have no reason to want to redefine this! + inline void plus_equal(PseudoJet & pa, const PseudoJet & pb) const { + // put result in a temporary location in case the recombiner + // does something funny (ours doesn't, but who knows about the + // user's) + PseudoJet pres; + recombine(pa,pb,pres); + pa = pres; + } + + }; + + + //====================================================================== + /// A class that will provide the recombination scheme facilities and/or + /// allow a user to extend these facilities + class DefaultRecombiner : public Recombiner { + public: + DefaultRecombiner(RecombinationScheme recomb_scheme = E_scheme) : + _recomb_scheme(recomb_scheme) {} + + virtual std::string description() const; + + /// recombine pa and pb and put result into pab + virtual void recombine(const PseudoJet & pa, const PseudoJet & pb, + PseudoJet & pab) const; + + virtual void preprocess(PseudoJet & p) const; + + /// return the index of the recombination scheme + RecombinationScheme scheme() const {return _recomb_scheme;} + + private: + RecombinationScheme _recomb_scheme; + }; + + + //====================================================================== + /// a class that allows a user to introduce their own "plugin" jet + /// finder + class Plugin{ + public: + /// return a textual description of the jet-definition implemented + /// in this plugin + virtual std::string description() const = 0; + + /// given a ClusterSequence that has been filled up with initial + /// particles, the following function should fill up the rest of the + /// ClusterSequence, using the following member functions of + /// ClusterSequence: + /// - plugin_do_ij_recombination(...) + /// - plugin_do_iB_recombination(...) + virtual void run_clustering(ClusterSequence &) const = 0; + + virtual double R() const = 0; + + /// return true if there is specific support for the measurement + /// of passive areas, in the sense that areas determined from all + /// particles below the ghost separation scale will be a passive + /// area. [If you don't understand this, ignore it!] + virtual bool supports_ghosted_passive_areas() const {return false;} + + /// set the ghost separation scale for passive area determinations + /// in future runs (strictly speaking that makes the routine + /// a non const, so related internal info must be stored as a mutable) + virtual void set_ghost_separation_scale(double scale) const; + virtual double ghost_separation_scale() const {return 0.0;} + + /// a destructor to be replaced if necessary in derived classes... + virtual ~Plugin() {}; + }; + +private: + + + JetAlgorithm _jet_algorithm; + double _Rparam; + double _extra_param ; ///< parameter whose meaning varies according to context + Strategy _strategy ; + + const Plugin * _plugin; + + // when we use our own recombiner it's useful to point to it here + // so that we don't have to worry about deleting it etc... + DefaultRecombiner _default_recombiner; + const Recombiner * _recombiner; + +}; + + + + + + +} // fastjet namespace + +#endif // __FASTJET_JETDEFINITION_HH__ diff --git a/JETAN/fastjet/fastjet/NNH.hh b/JETAN/fastjet/fastjet/NNH.hh new file mode 100644 index 00000000000..0cd980e6eca --- /dev/null +++ b/JETAN/fastjet/fastjet/NNH.hh @@ -0,0 +1,368 @@ +#ifndef __NNH_HH__ +#define __NNH_HH__ + +//STARTHEADER +// $Id: NNH.hh 1491 2009-03-11 17:04:38Z salam $ +// +// Copyright (c) 2009, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#include + + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// dummy class, used as a default template argument +class _NoInfo {}; + +/// template that will help initialise a BJ with a PseudoJet and extra information +template class NNHInfo { +public: + NNHInfo() : _info(NULL) {} + NNHInfo(I * info) : _info(info) {} + template void init_jet(NNBJ * briefjet, const fastjet::PseudoJet & jet, int index) { briefjet->init(jet, index, _info);} +private: + I * _info; +}; + +/// Specialisation of NNHInfo for cases where there is no extra info +template<> class NNHInfo<_NoInfo> { +public: + NNHInfo() {} + NNHInfo(_NoInfo * info) {} + template void init_jet(NNBJ * briefjet, const fastjet::PseudoJet & jet, int index) { briefjet->init(jet, index);} +}; + + +//---------------------------------------------------------------------- +/// Class to help solve closest pair problems with generic interparticle +/// distances and a beam distance, using Anderberg's Nearest Neighbour +/// Heuristic. +/// +/// It is templated with a BJ (brief jet) class --- BJ should +/// basically cache the minimal amount of information that is needed +/// to efficient calculate interparticle distances and particle-beam +/// distances. +/// +/// This class can be used with or without an extra "Information" template, +//// i.e. NNB or NNH +/// +/// For the NNH class to function in the case, BJ must provide three member functions +/// +/// - void BJ::init(const PseudoJet & jet); // initialise with a PseudoJet +/// - double BJ::distance(const BJ * other_bj_jet); // distance between this and other_bj_jet +/// - double BJ::beam_distance() ; // distance to the beam +/// +/// For the NNH version to function, the BJ::init(...) member +/// must accept an extra argument +/// +/// - void BJ::init(const PseudoJet & jet, I * info); // initialise with a PseudoJet + info +/// +/// where info might be a pointer to a class that contains, e.g., information +/// about R, or other parameters of the jet algorithm +/// +/// For an example of how the NNH class is used, see the Jade (and +/// EECambridge) plugins +/// +/// NB: the NNH algorithm is expected N^2, but has a worst case of +/// N^3. Many QCD problems tend to place one closer to the N^3 end of +/// the spectrum than one would like. There is scope for further +/// progress (cf Eppstein, Cardinal & Eppstein), nevertheless the +/// current class is already significantly faster than standard N^3 +/// implementations. +/// +/// +/// Implementation note: this class derives from NNHInfo, which deals +/// with storing any information that + +template class NNH : public NNHInfo { +public: + + /// constructor with an initial set of jets (which will be assigned indices + /// 0 ... jets.size()-1 + NNH(const std::vector & jets) {start(jets);} + NNH(const std::vector & jets, I * info) : NNHInfo(info) {start(jets);} + + void start(const std::vector & jets); + + /// return the dij_min and indices iA, iB, for the corresponding jets. + /// If iB < 0 then iA recombines with the beam + double dij_min(int & iA, int & iB); + + /// remove the jet pointed to by index iA + void remove_jet(int iA); + + /// merge the jets pointed to by indices A and B and replace them with + /// jet, assigning it an index jet_index. + void merge_jets(int iA, int iB, const PseudoJet & jet, int jet_index); + + /// a destructor + ~NNH() { + delete[] briefjets; + } + +private: + class NNBJ; // forward declaration + + /// establish the nearest neighbour for jet, and cross check constistency + /// of distances for the other jets that are encountered. Assumes + /// jet not contained within begin...end + void set_NN_crosscheck(NNBJ * jet, NNBJ * begin, NNBJ * end); + + /// establish the nearest neighbour for jet; don't cross check other jets' + /// distances and allow jet to be contained within begin...end + void set_NN_nocross (NNBJ * jet, NNBJ * begin, NNBJ * end); + + /// contains the briefjets + NNBJ * briefjets; + + /// semaphores for the current extent of our structure + NNBJ * head, * tail; + + /// currently active number of jets + int n; + + /// where_is[i] contains a pointer to the jet with index i + std::vector where_is; + + /// a class that wraps around the BJ, supplementing it with extra information + /// such as pointers to neighbours, etc. + class NNBJ : public BJ { + public: + void init(const PseudoJet & jet, int index) { + BJ::init(jet); + other_init(index); + } + void init(const PseudoJet & jet, int index, I * info) { + BJ::init(jet, info); + other_init(index); + } + void other_init(int index) { + _index = index; + NN_dist = BJ::beam_distance(); + NN = NULL; + } + int index() const {return _index;} + + double NN_dist; + NNBJ * NN; + + private: + int _index; + }; + +}; + + + +//---------------------------------------------------------------------- +template void NNH::start(const std::vector & jets) { + n = jets.size(); + briefjets = new NNBJ[n]; + where_is.resize(2*n); + + NNBJ * jetA = briefjets; + + // initialise the basic jet info + for (int i = 0; i< n; i++) { + //jetA->init(jets[i], i); + init_jet(jetA, jets[i], i); + where_is[i] = jetA; + jetA++; // move on to next entry of briefjets + } + tail = jetA; // a semaphore for the end of briefjets + head = briefjets; // a nicer way of naming start + + // now initialise the NN distances: jetA will run from 1..n-1; and + // jetB from 0..jetA-1 + for (jetA = head + 1; jetA != tail; jetA++) { + // set NN info for jetA based on jets running from head..jetA-1, + // checking in the process whether jetA itself is an undiscovered + // NN of one of those jets. + set_NN_crosscheck(jetA, head, jetA); + } + //std::cout << "OOOO " << briefjets[1].NN_dist << " " << briefjets[1].NN - briefjets << std::endl; +} + + +//---------------------------------------------------------------------- +template double NNH::dij_min(int & iA, int & iB) { + // find the minimum of the diJ on this round + double diJ_min = briefjets[0].NN_dist; + int diJ_min_jet = 0; + for (int i = 1; i < n; i++) { + if (briefjets[i].NN_dist < diJ_min) { + diJ_min_jet = i; + diJ_min = briefjets[i].NN_dist; + } + } + + // return information to user about recombination + NNBJ * jetA = & briefjets[diJ_min_jet]; + //std::cout << jetA - briefjets << std::endl; + iA = jetA->index(); + iB = jetA->NN ? jetA->NN->index() : -1; + return diJ_min; +} + + +//---------------------------------------------------------------------- +// remove jetA from the list +template void NNH::remove_jet(int iA) { + NNBJ * jetA = where_is[iA]; + // now update our nearest neighbour info and diJ table + // first reduce size of table + tail--; n--; + // Copy last jet contents and diJ info into position of jetA + *jetA = *tail; + // update the info on where the given index is stored + where_is[jetA->index()] = jetA; + + for (NNBJ * jetI = head; jetI != tail; jetI++) { + // see if jetI had jetA or jetB as a NN -- if so recalculate the NN + if (jetI->NN == jetA) set_NN_nocross(jetI, head, tail); + + // if jetI's NN is the new tail then relabel it so that it becomes jetA + if (jetI->NN == tail) {jetI->NN = jetA;} + } +} + + +//---------------------------------------------------------------------- +template void NNH::merge_jets(int iA, int iB, + const PseudoJet & jet, int index) { + + NNBJ * jetA = where_is[iA]; + NNBJ * jetB = where_is[iB]; + + // If necessary relabel A & B to ensure jetB < jetA, that way if + // the larger of them == newtail then that ends up being jetA and + // the new jet that is added as jetB is inserted in a position that + // has a future! + if (jetA < jetB) swap(jetA,jetB); + + // initialise jetB based on the new jet + //jetB->init(jet, index); + init_jet(jetB, jet, index); + // and record its position (making sure we have the space) + if (index >= int(where_is.size())) where_is.resize(2*index); + where_is[jetB->index()] = jetB; + + // now update our nearest neighbour info + // first reduce size of table + tail--; n--; + // Copy last jet contents into position of jetA + *jetA = *tail; + // update the info on where the tail's index is stored + where_is[jetA->index()] = jetA; + + for (NNBJ * jetI = head; jetI != tail; jetI++) { + // see if jetI had jetA or jetB as a NN -- if so recalculate the NN + if (jetI->NN == jetA || jetI->NN == jetB) { + set_NN_nocross(jetI, head, tail); + } + + // check whether new jetB is closer than jetI's current NN and + // if need be update things + double dist = jetI->distance(jetB); + if (dist < jetI->NN_dist) { + if (jetI != jetB) { + jetI->NN_dist = dist; + jetI->NN = jetB; + } + } + if (dist < jetB->NN_dist) { + if (jetI != jetB) { + jetB->NN_dist = dist; + jetB->NN = jetI; + } + } + + // if jetI's NN is the new tail then relabel it so that it becomes jetA + if (jetI->NN == tail) {jetI->NN = jetA;} + } +} + + +//---------------------------------------------------------------------- +// this function assumes that jet is not contained within begin...end +template void NNH::set_NN_crosscheck(NNBJ * jet, + NNBJ * begin, NNBJ * end) { + double NN_dist = jet->beam_distance(); + NNBJ * NN = NULL; + for (NNBJ * jetB = begin; jetB != end; jetB++) { + double dist = jet->distance(jetB); + if (dist < NN_dist) { + NN_dist = dist; + NN = jetB; + } + if (dist < jetB->NN_dist) { + jetB->NN_dist = dist; + jetB->NN = jet; + } + } + jet->NN = NN; + jet->NN_dist = NN_dist; +} + + +//---------------------------------------------------------------------- +// set the NN for jet without checking whether in the process you might +// have discovered a new nearest neighbour for another jet +template void NNH::set_NN_nocross( + NNBJ * jet, NNBJ * begin, NNBJ * end) { + double NN_dist = jet->beam_distance(); + NNBJ * NN = NULL; + if (head < jet) { + for (NNBJ * jetB = head; jetB != jet; jetB++) { + double dist = jet->distance(jetB); + if (dist < NN_dist) { + NN_dist = dist; + NN = jetB; + } + } + } + if (tail > jet) { + for (NNBJ * jetB = jet+1; jetB != tail; jetB++) { + double dist = jet->distance (jetB); + if (dist < NN_dist) { + NN_dist = dist; + NN = jetB; + } + } + } + jet->NN = NN; + jet->NN_dist = NN_dist; +} + + + + +} // fastjet namespace + + +#endif // __NNH_HH__ diff --git a/JETAN/fastjet/fastjet/NestedDefsPlugin.hh b/JETAN/fastjet/fastjet/NestedDefsPlugin.hh new file mode 100644 index 00000000000..8bf91e4d26b --- /dev/null +++ b/JETAN/fastjet/fastjet/NestedDefsPlugin.hh @@ -0,0 +1,79 @@ +//STARTHEADER +// $Id: NestedDefsPlugin.hh 1394 2009-01-17 05:08:31Z soyez $ +// +// Copyright (c) 2007-2008, Matteo Cacciari, Gavin Salam and Gregory Soyez +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __NESTEDALGSPLUGIN_HH__ +#define __NESTEDALGSPLUGIN_HH__ + +#include "fastjet/JetDefinition.hh" +#include +#include +#include + +// questionable whether this should be in fastjet namespace or not... +namespace fastjet { // defined in fastjet/internal/base.hh + +// another forward declaration to reduce includes +class PseudoJet; + +//---------------------------------------------------------------------- +// +/// NestedAglsPlugin is a plugin for fastjet (v2.4 upwards) that, given +/// a list of jet definitions, performs the clustering by feeding the +/// particles to the first algorithm and then, successively feeding the +/// output to the next algorithm in the list. +// +class NestedDefsPlugin : public JetDefinition::Plugin { +public: + /// Main constructor for the NestedDefs Plugin class. + /// + /// The argument is an initialised list of jet algorithms + NestedDefsPlugin (std::list &defs) : + _defs(defs){} + + /// copy constructor + NestedDefsPlugin (const NestedDefsPlugin & plugin) { + *this = plugin; + } + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const; + /// the plugin mechanism's standard way of accessing the jet radius + /// here we return the R of the last alg in the list + virtual double R() const {return _defs.rbegin()->R();} + +private: + std::list _defs; +}; + +} // fastjet namespace + +#endif // __SISCONEPLUGIN_HH__ + diff --git a/JETAN/fastjet/fastjet/PseudoJet.hh b/JETAN/fastjet/fastjet/PseudoJet.hh new file mode 100644 index 00000000000..4ca32ecd17b --- /dev/null +++ b/JETAN/fastjet/fastjet/PseudoJet.hh @@ -0,0 +1,339 @@ +//STARTHEADER +// $Id: PseudoJet.hh 1510 2009-04-13 08:48:41Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_PSEUDOJET_HH__ +#define __FASTJET_PSEUDOJET_HH__ + +#include +#include +#include +#include +#include +#include "fastjet/internal/numconsts.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +//using namespace std; + +/// Used to protect against parton-level events where pt can be zero +/// for some partons, giving rapidity=infinity. KtJet fails in those cases. +const double MaxRap = 1e5; + +/// Class to contain pseudojets, including minimal information of use to +/// to jet-clustering routines. +class PseudoJet { + + public: + PseudoJet() {}; + /// construct a pseudojet from explicit components + PseudoJet(const double px, const double py, const double pz, const double E); + /// constructor from any object that has px,py,pz,E = some_four_vector[0--3], + template PseudoJet(const L & some_four_vector) ; + + // first "const double &" says that result is a reference to the + // stored value and that we will not change that stored value. + // + // second "const" says that "this" will not be modified by these + // functions. + inline double E() const {return _E;} + inline double e() const {return _E;} // like CLHEP + inline double px() const {return _px;} + inline double py() const {return _py;} + inline double pz() const {return _pz;} + + /// returns phi (in the range 0..2pi) + inline double phi() const {return phi_02pi();} + + /// returns phi in the range -pi..pi + inline double phi_std() const { + return _phi > pi ? _phi-twopi : _phi;} + + /// returns phi in the range 0..2pi + inline double phi_02pi() const {return _phi;} + + /// returns the rapidity or some large value when the rapidity + /// is infinite + inline double rap() const {return _rap;} + + /// the same as rap() + inline double rapidity() const {return _rap;} // like CLHEP + + /// returns the pseudo-rapidity or some large value when the + /// rapidity is infinite + double pseudorapidity() const; + double eta() const {return pseudorapidity();} + + /// returns the squared transverse momentum + inline double kt2() const {return _kt2;} + /// returns the squared transverse momentum + inline double perp2() const {return _kt2;} // like CLHEP + /// returns the scalar transverse momentum + inline double perp() const {return sqrt(_kt2);} // like CLHEP + /// returns the squared invariant mass // like CLHEP + inline double m2() const {return (_E+_pz)*(_E-_pz)-_kt2;} + /// returns the squared transverse mass = kt^2+m^2 + inline double mperp2() const {return (_E+_pz)*(_E-_pz);} + /// returns the transverse mass = sqrt(kt^2+m^2) + inline double mperp() const {return sqrt(std::abs(mperp2()));} + /// returns the invariant mass + /// (If m2() is negative then -sqrt(-m2()) is returned, as in CLHEP) + inline double m() const; + /// return px^2+py^2+pz^2 + inline double modp2() const {return _kt2+_pz*_pz;} + /// return the transverse energy + inline double Et() const {return (_kt2==0) ? 0.0 : _E/sqrt(1.0+_pz*_pz/_kt2);} + /// return the transverse energy squared + inline double Et2() const {return (_kt2==0) ? 0.0 : _E*_E/(1.0+_pz*_pz/_kt2);} + + /// returns component i, where X==0, Y==1, Z==2, E==3 + double operator () (int i) const ; + /// returns component i, where X==0, Y==1, Z==2, E==3 + inline double operator [] (int i) const { return (*this)(i); }; // this too + + + // taken from CLHEP + enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES }; + + + /// transform this jet (given in the rest frame of prest) into a jet + /// in the lab frame [NOT FULLY TESTED] + PseudoJet & boost(const PseudoJet & prest); + /// transform this jet (given in lab) into a jet in the rest + /// frame of prest [NOT FULLY TESTED] + PseudoJet & unboost(const PseudoJet & prest); + + /// return the cluster_hist_index, intended to be used by clustering + /// routines. + inline int cluster_hist_index() const {return _cluster_hist_index;} + /// set the cluster_hist_index, intended to be used by clustering routines. + inline void set_cluster_hist_index(const int index) {_cluster_hist_index = index;} + + /// alternative name for cluster_hist_index() [perhaps more meaningful] + inline int cluster_sequence_history_index() const { + return cluster_hist_index();} + /// alternative name for set_cluster_hist_index(...) [perhaps more + /// meaningful] + inline void set_cluster_sequence_history_index(const int index) { + set_cluster_hist_index(index);} + + + /// return the user_index, intended to allow the user to "add" information + inline int user_index() const {return _user_index;} + /// set the user_index, intended to allow the user to "add" information + inline void set_user_index(const int index) {_user_index = index;} + + /// return a valarray containing the four-momentum (components 0-2 + /// are 3-mom, component 3 is energy). + std::valarray four_mom() const; + + /// returns kt distance (R=1) between this jet and another + double kt_distance(const PseudoJet & other) const; + + /// returns squared cylinder (rap-phi) distance between this jet and another + double plain_distance(const PseudoJet & other) const; + /// returns squared cylinder (rap-phi) distance between this jet and + /// another + inline double squared_distance(const PseudoJet & other) const { + return plain_distance(other);} + + /// returns other.phi() - this.phi(), constrained to be in + /// range -pi .. pi + double delta_phi_to(const PseudoJet & other) const; + + //// this seemed to compile except if it was used + //friend inline double + // kt_distance(const PseudoJet & jet1, const PseudoJet & jet2) { + // return jet1.kt_distance(jet2);} + + /// returns distance between this jet and the beam + inline double beam_distance() const {return _kt2;} + + + void operator*=(double); + void operator/=(double); + void operator+=(const PseudoJet &); + void operator-=(const PseudoJet &); + + /// reset the 4-momentum according to the supplied components and + /// put the user and history indices back to their default values + inline void reset(double px, double py, double pz, double E); + + /// reset the PseudoJet to be equal to psjet (including its + /// indices); NB if the argument is derived from a PseudoJet then + /// the "reset" used will be the templated version (which does not + /// know about indices...) + inline void reset(const PseudoJet & psjet) { + (*this) = psjet; + } + + /// reset the 4-momentum according to the supplied generic 4-vector + /// (accessible via indexing, [0]==px,...[3]==E) and put the user + /// and history indices back to their default values. + template inline void reset(const L & some_four_vector) { + reset(some_four_vector[0], some_four_vector[1], + some_four_vector[2], some_four_vector[3]); + } + + private: + // NB: following order must be kept for things to behave sensibly... + double _px,_py,_pz,_E; + double _phi, _rap, _kt2; + int _cluster_hist_index, _user_index; + /// calculate phi, rap, kt2 based on the 4-momentum components + void _finish_init(); + /// set the indices to default values + void _reset_indices(); + + //vertex_type * vertex0, vertex1; +}; + + +//---------------------------------------------------------------------- +// routines for basic binary operations + +PseudoJet operator+(const PseudoJet &, const PseudoJet &); +PseudoJet operator-(const PseudoJet &, const PseudoJet &); +PseudoJet operator*(double, const PseudoJet &); +PseudoJet operator*(const PseudoJet &, double); +PseudoJet operator/(const PseudoJet &, double); + +inline double dot_product(const PseudoJet & a, const PseudoJet & b) { + return a.E()*b.E() - a.px()*b.px() - a.py()*b.py() - a.pz()*b.pz(); +} + +/// returns true if the momenta of the two input jets are identical +bool have_same_momentum(const PseudoJet &, const PseudoJet &); + +/// return a pseudojet with the given pt, y, phi and mass +PseudoJet PtYPhiM(double pt, double y, double phi, double m = 0.0); + +//---------------------------------------------------------------------- +// Routines to do with providing sorted arrays of vectors. + +/// return a vector of jets sorted into decreasing transverse momentum +std::vector sorted_by_pt(const std::vector & jets); + +/// return a vector of jets sorted into increasing rapidity +std::vector sorted_by_rapidity(const std::vector & jets); + +/// return a vector of jets sorted into decreasing energy +std::vector sorted_by_E(const std::vector & jets); + +/// return a vector of jets sorted into increasing pz +std::vector sorted_by_pz(const std::vector & jets); + +//---------------------------------------------------------------------- +// some code to help sorting + +/// sort the indices so that values[indices[0->n-1]] is sorted +/// into increasing order +void sort_indices(std::vector & indices, + const std::vector & values); + +/// given a vector of values with a one-to-one correspondence with the +/// vector of objects, sort objects into an order such that the +/// associated values would be in increasing order (but don't actually +/// touch the values vector in the process). +template std::vector objects_sorted_by_values(const std::vector & objects, + const std::vector & values); + +/// a class that helps us carry out indexed sorting. +class IndexedSortHelper { +public: + inline IndexedSortHelper (const std::vector * reference_values) { + _ref_values = reference_values; + }; + inline int operator() (const int & i1, const int & i2) const { + return (*_ref_values)[i1] < (*_ref_values)[i2]; + }; +private: + const std::vector * _ref_values; +}; + + +//---------------------------------------------------------------------- +/// constructor from any object that has px,py,pz,E = some_four_vector[0--3], +// NB: do not know if it really needs to be inline, but when it wasn't +// linking failed with g++ (who knows what was wrong...) +template inline PseudoJet::PseudoJet(const L & some_four_vector) { + + _px = some_four_vector[0]; + _py = some_four_vector[1]; + _pz = some_four_vector[2]; + _E = some_four_vector[3]; + _finish_init(); + // some default values for these two indices + _reset_indices(); +} + + +//---------------------------------------------------------------------- +inline void PseudoJet::_reset_indices() { + set_cluster_hist_index(-1); + set_user_index(-1); +} + +//---------------------------------------------------------------------- +/// specialization of the "reset" template for case where something +/// is reset to a pseudojet -- it then takes the user and history +/// indices from the psjet +// template<> inline void PseudoJet::reset(const PseudoJet & psjet) { +// (*this) = psjet; +// } + +////// fun and games... +////template class FJVector : public L { +////// /** Default Constructor: create jet with no constituents */ +////// Vector(); +//// +////}; +//// + +// taken literally from CLHEP +inline double PseudoJet::m() const { + double mm = m2(); + return mm < 0.0 ? -std::sqrt(-mm) : std::sqrt(mm); +} + + +inline void PseudoJet::reset(double px, double py, double pz, double E) { + _px = px; + _py = py; + _pz = pz; + _E = E; + _finish_init(); + _reset_indices(); +} + + +} // fastjet namespace + +#endif // __FASTJET_PSEUDOJET_HH__ diff --git a/JETAN/fastjet/fastjet/RangeDefinition.hh b/JETAN/fastjet/fastjet/RangeDefinition.hh new file mode 100644 index 00000000000..b13aef5e809 --- /dev/null +++ b/JETAN/fastjet/fastjet/RangeDefinition.hh @@ -0,0 +1,169 @@ +//STARTHEADER +// $Id: RangeDefinition.hh 1404 2009-01-21 18:43:57Z salam $ +// +// Copyright (c) 2005-2007, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_RANGEDEFINITION_HH__ +#define __FASTJET_RANGEDEFINITION_HH__ + +#include "fastjet/PseudoJet.hh" +#include "fastjet/Error.hh" +#include +#include +#include + +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +// +/// class for holding a range definition specification, given by limits +/// on rapidity and azimuth. +/// +class RangeDefinition { +public: + /// default constructor + RangeDefinition() {} + + /// constructor for a range definition given by |y| 0.0 ); + _rapmax = rapmax; + _rapmin = -rapmax; + _phimin = 0.0; + _phimax = twopi; + _total_area = 2.0*rapmax*twopi; + _phispan = _phimax-_phimin; } + + /// destructor does nothing + virtual ~RangeDefinition() {} + + /// constructor for a range definition given by + /// rapmin <= y <= rapmax, phimin <= phi <= phimax + RangeDefinition(double rapmin, double rapmax, + double phimin = 0.0, double phimax = twopi) { + assert ( rapmin < rapmax); + assert ( phimin < phimax); + assert ( phimin > -twopi ); + assert ( phimax < 2*twopi); + _rapmax = rapmax; + _rapmin = rapmin; + _phimin = phimin; + _phimax = phimax; + if (_phimax-_phimin > twopi) + _total_area = (_rapmax - _rapmin)*twopi; + else + _total_area = (_rapmax - _rapmin)*(_phimax - _phimin); + _phispan = _phimax-_phimin; } + + /// returns true if the range is localizable (i.e. set_position is + /// meant to do something meaningful). + /// + /// This version of the class is not localizable and so it returns + /// false. + /// + /// For localizable classes override this function with a function + /// that returns true + virtual inline bool is_localizable() const { return false; } + + + /// place the range on the rap-phi position + /// + /// THIS DOES NOT DO ANYTHING FOR THIS CLASS AND IS ONLY THERE + /// TO FACILITATE DERIVED CLASSES + /// + /// DON'T NECESSARILY COUNT ON IT IN THE FUTURE EITHER??? + inline void set_position(const double & rap, const double & phi) { + if (! is_localizable() ) { + std::ostringstream err; + err << description() << + "\nThis range is not localizable. set_position() should not be used on it."; + throw fastjet::Error(err.str()); + } else { + _rapjet = rap; + _phijet = phi; + } + } + + /// place the range on the jet position + inline void set_position(const PseudoJet & jet) { + set_position(jet.rap(),jet.phi()); + } + + /// return bool according to whether the jet is within the given range + inline bool is_in_range(const PseudoJet & jet) const { + double rap = jet.rap(); + double phi = jet.phi(); + return is_in_range(rap,phi); + } + + /// return bool according to whether a (rap,phi) point is in range + virtual inline bool is_in_range(double rap, double phi) const { + double dphi=phi-_phimin; + if (dphi >= twopi) dphi -= twopi; + if (dphi < 0) dphi += twopi; + return ( rap >= _rapmin && + rap <= _rapmax && + dphi <= _phispan ); + } + + /// return the minimal and maximal rapidity of this range; remember to + /// replace this if you write a derived class with more complex ranges; + virtual inline void get_rap_limits(double & rapmin, double & rapmax) const { + rapmin = _rapmin; + rapmax = _rapmax; + } + + /// area of the range region + virtual inline double area() const { return _total_area; } + + /// textual description of range + virtual inline std::string description() const { + std::ostringstream ostr; + ostr << "Range: " << _rapmin << " <= y <= " << _rapmax << ", " + << _phimin << " <= phi <= " << _phimax ; + return ostr.str(); +} + +protected: + double _total_area; // total area of specified range + + /// calculate, and set _total_area, by calculating which of points on + /// a grid (npoints * npoints from -rapmax..rapmax,0..2pi) are contained + /// in the range; it takes a reasonable time with rapmax = 10, + /// npoints = 100. + void _numerical_total_area(double rapmax, int npoints) ; + double _rapjet,_phijet; // jet position. only used in localizable derived classes + +private: + double _rapmin,_rapmax,_phimin,_phimax,_phispan; + +}; + +} // fastjet namespace + +#endif // __FASTJET_RANGEDEFINITION_HH__ diff --git a/JETAN/fastjet/fastjet/SISConeBasePlugin.hh b/JETAN/fastjet/fastjet/SISConeBasePlugin.hh new file mode 100644 index 00000000000..f50ecbe9292 --- /dev/null +++ b/JETAN/fastjet/fastjet/SISConeBasePlugin.hh @@ -0,0 +1,179 @@ +#ifndef __SISCONEBASEPLUGIN_HH__ +#define __SISCONEBASEPLUGIN_HH__ + +#include "fastjet/JetDefinition.hh" +#include "fastjet/ClusterSequence.hh" +#include +#include +#include + +#include + +// questionable whether this should be in fastjet namespace or not... +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +// +/// SISConeBasePlugin is a plugin for fastjet (v2.1 upwards) that +/// provides a base interface to SISCone-type cone jet finder by +/// Gregory Soyez and Gavin Salam. +/// +/// This is a purely virtual class that needs to be overloaded +/// for the specific implementations of SISCone (i.e. regular or +/// spherical as of July 16th 2008). +/// +/// any derived plugin MUST overload the following methods: +/// description() +/// run_siscone_clustering() +/// reset_stored_plugin() +/// +/// For further details, see the derived plugins or +/// http://projects.hepforge.com/siscone +// +class SISConeBasePlugin : public JetDefinition::Plugin { +public: + /// default ctor + SISConeBasePlugin (){ + _use_jet_def_recombiner = false; + } + + /// copy constructor + SISConeBasePlugin (const SISConeBasePlugin & plugin) { + *this = plugin; + } + + /// the cone radius + double cone_radius () const {return _cone_radius ;} + + /// Fraction of overlap energy in a jet above which jets are merged + /// and below which jets are split. + double overlap_threshold () const {return _overlap_threshold ;} + + /// the maximum number of passes of stable-cone searching (<=0 is same + /// as infinity). + int n_pass_max () const {return _n_pass_max ;} + + /// set the "split_merge_stopping_scale": if the scale variable for + /// all protojets is below this, then stop the split-merge procedure + /// and keep only those jets found so far. This is useful in + /// determination of areas of hard jets because it can be used to + /// avoid running the split-merging on the pure ghost-part of the + /// event. + void set_split_merge_stopping_scale(double scale) { + _split_merge_stopping_scale = scale;} + + /// return the value of the split_merge_stopping_scale (see + /// set_split_merge_stopping_scale(...) for description) + double split_merge_stopping_scale() {return _split_merge_stopping_scale;} + + /// allow the user to decide if one uses the jet_def's own recombination scheme + void set_use_jet_def_recombiner(bool choice) {_use_jet_def_recombiner = choice;} + + /// indicate if the jet_def's recombination scheme is being used + bool use_jet_def_recombiner() const {return _use_jet_def_recombiner;} + + /// indicates whether caching is turned on or not. + bool caching() const {return _caching ;} + + /// the plugin mechanism's standard way of accessing the jet radius + virtual double R() const {return cone_radius();} + + /// return true since there is specific support for the measurement + /// of passive areas, in the sense that areas determined from all + /// particles below the ghost separation scale will be a passive + /// area. + virtual bool supports_ghosted_passive_areas() const { + return true; + } + + /// set the ghost separation scale for passive area determinations + /// _just_ in the next run (strictly speaking that makes the routine + /// a non const, so related internal info must be stored as a mutable) + virtual void set_ghost_separation_scale(double scale) const { + _ghost_sep_scale = scale; + } + + virtual double ghost_separation_scale() const { + return _ghost_sep_scale; + } + + // the things that one MUST overload required by base class + //--------------------------------------------------------- + + /// plugin description + virtual std::string description () const =0; + + /// really do the clustering work + virtual void run_clustering(ClusterSequence &) const = 0; + +protected: + double _cone_radius, _overlap_threshold; + int _n_pass_max; + bool _caching;//, _split_merge_on_transverse_mass; + double _split_merge_stopping_scale; + bool _use_jet_def_recombiner; + + mutable double _ghost_sep_scale; + + // the part that HAS to be overloaded + /// call the re-clustering itself + virtual void reset_stored_plugin() const =0; + +}; + + +//====================================================================== +/// Class that provides extra information about a SISCone clustering +/// the only thing that needs to be done for thee derived classes +/// is to define '_jet_def_plugin', implement +/// jet_def_plugin(); +/// and add the corresponding plugin class as a friend +class SISConeBaseExtras : public ClusterSequence::Extras { +public: + + /// constructor + // it just initialises the pass information + SISConeBaseExtras(int nparticles) : _pass(nparticles*2,-1) {} + + /// purely virtual destructor + inline virtual ~SISConeBaseExtras()=0; + + /// returns a reference to the vector of stable cones (aka protocones) + const std::vector & stable_cones() const {return _protocones;} + + /// an old name for getting the vector of stable cones (aka protocones) + const std::vector & protocones() const {return _protocones;} + + /// return the # of the pass at which a given jet was found; will + /// return -1 if the pass is invalid + int pass(const PseudoJet & jet) const {return _pass[jet.cluster_hist_index()];} + + /// return a brief summary of the contents of the extras object + /// (specifically, the number of protocones. + std::string description() const{ + std::ostringstream ostr; + ostr << "This SISCone clustering found " << protocones().size() + << " stable protocones"; + return ostr.str(); + }; + + /// return the smallest difference in squared distance encountered + /// during splitting between a particle and two overlapping + /// protojets. + inline double most_ambiguous_split() const {return _most_ambiguous_split;} + +protected: + std::vector _protocones; + std::vector _pass; + double _most_ambiguous_split; + const SISConeBasePlugin * _jet_def_plugin; +}; + +/// give the destructor its required implementation +inline SISConeBaseExtras::~SISConeBaseExtras(){} + + +} // fastjet namespace + +#endif // __SISCONEBASEPLUGIN_HH__ + diff --git a/JETAN/fastjet/fastjet/SISConePlugin.hh b/JETAN/fastjet/fastjet/SISConePlugin.hh new file mode 100644 index 00000000000..aa204244522 --- /dev/null +++ b/JETAN/fastjet/fastjet/SISConePlugin.hh @@ -0,0 +1,214 @@ +#ifndef __SISCONEPLUGIN_HH__ +#define __SISCONEPLUGIN_HH__ + +#include "SISConeBasePlugin.hh" + +// forward declaration of the siscone classes we'll need +namespace siscone{ + class Csiscone; +} + + +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +// +/// SISConePlugin is a plugin for fastjet (v2.1 upwards) that provides +/// an interface to the seedless infrared safe cone jet finder by +/// Gregory Soyez and Gavin Salam. +/// +/// SISCone uses geometrical techniques to exhaustively consider all +/// possible distinct cones. It then finds out which ones are stable +/// and sends the result to the Tevatron Run-II type split-merge +/// procedure for overlapping cones. +/// +/// Four parameters govern the "physics" of the algorithm: +/// +/// - the cone_radius (this should be self-explanatory!) +/// +/// - the overlap_threshold is the parameter which dictates how much +/// two jets must overlap (pt_overlap/min(pt1,pt2)) if they are to be +/// merged +/// +/// - Not all particles are in stable cones in the first round of +/// searching for stable cones; one can therefore optionally have the +/// the jet finder carry out additional passes of searching for +/// stable cones among particles that were in no stable cone in +/// previous passes --- the maximum number of passes carried out is +/// n_pass_max. If this is zero then additional passes are carried +/// out until no new stable cones are found. +/// +/// - Protojet ptmin: protojets that are below this ptmin +/// (default = 0) are discarded before each iteration of the +/// split-merge loop. +/// +/// One parameter governs some internal algorithmic shortcuts: +/// +/// - if "caching" is turned on then the last event clustered by +/// siscone is stored -- if the current event is identical and the +/// cone_radius and n_pass_mass are identical, then the only part of +/// the clustering that needs to be rerun is the split-merge part, +/// leading to significant speed gains; there is a small (O(N) storage +/// and speed) penalty for caching, so it should be kept off +/// (default) if only a single overlap_threshold is used. +/// +/// The final jets can be accessed by requestion the +/// inclusive_jets(...) from the ClusterSequence object. Note that +/// these PseudoJets have their user_index() set to the index of the +/// pass in which they were found (first pass = 0). NB: This does not +/// currently work for jets that consist of a single particle. +/// +/// For further information on the details of the algorithm see the +/// SISCone paper, arXiv:0704.0292 [JHEP 0705:086,2007]. +/// +/// For documentation about the implementation, see the +/// siscone/doc/html/index.html file. +// +class SISConePlugin : public SISConeBasePlugin{ +public: + + /// enum for the different split-merge scale choices; + /// Note that order _must_ be the same as in siscone + enum SplitMergeScale {SM_pt, ///< transverse momentum (E-scheme), IR unsafe + SM_Et, ///< transverse energy (E-scheme), not long. boost invariant + ///< original run-II choice [may not be implemented] + SM_mt, ///< transverse mass (E-scheme), IR safe except + ///< in decays of two identical narrow heavy particles + SM_pttilde ///< pt-scheme pt = \sum_{i in jet} |p_{ti}|, should + ///< be IR safe in all cases + }; + + + /// Main constructor for the SISCone Plugin class. + /// + /// Note: wrt version prior to 2.4 this constructor differs in that a + /// the default value has been removed for overlap_threshold. The + /// former has been removed because the old default of 0.5 was found + /// to be unsuitable in high-noise environments; so the user should + /// now explicitly think about the value for this -- we recommend + /// 0.75. + /// + SISConePlugin (double cone_radius, + double overlap_threshold, + int n_pass_max = 0, + double protojet_ptmin = 0.0, + bool caching = false, + SplitMergeScale split_merge_scale = SM_pttilde, + double split_merge_stopping_scale = 0.0){ + _cone_radius = cone_radius; + _overlap_threshold = overlap_threshold; + _n_pass_max = n_pass_max; + _protojet_ptmin = protojet_ptmin; + _caching = caching; + _split_merge_scale = split_merge_scale; + _split_merge_stopping_scale = split_merge_stopping_scale; + _ghost_sep_scale = 0.0; + _use_pt_weighted_splitting = false;} + + + /// Backwards compatible constructor for the SISCone Plugin class + SISConePlugin (double cone_radius, + double overlap_threshold, + int n_pass_max, + double protojet_ptmin, + bool caching , + bool split_merge_on_transverse_mass){ + _cone_radius = cone_radius; + _overlap_threshold = overlap_threshold; + _n_pass_max = n_pass_max; + _protojet_ptmin = protojet_ptmin; + _caching = caching; + _split_merge_stopping_scale = 0.0; + _split_merge_scale = split_merge_on_transverse_mass ? SM_mt : SM_pttilde; + _ghost_sep_scale = 0.0;} + + /// backwards compatible constructor for the SISCone Plugin class + /// (avoid using this in future). + SISConePlugin (double cone_radius, + double overlap_threshold, + int n_pass_max, + bool caching ) { + _cone_radius = cone_radius; + _overlap_threshold = overlap_threshold; + _n_pass_max = n_pass_max; + _protojet_ptmin = 0.0; + _caching = caching; + _split_merge_scale = SM_mt; + _split_merge_stopping_scale = 0.0; + _ghost_sep_scale = 0.0; + _use_pt_weighted_splitting = false;} + + /// minimum pt for a protojet to be considered in the split-merge step + /// of the algorithm + double protojet_ptmin () const {return _protojet_ptmin ;} + + /// return the scale to be passed to SISCone as the protojet_ptmin + /// -- if we have a ghost separation scale that is above the + /// protojet_ptmin, then the ghost_separation_scale becomes the + /// relevant one to use here + double protojet_or_ghost_ptmin () const {return std::max(_protojet_ptmin, + _ghost_sep_scale);} + + /// indicates scale used in split-merge + SplitMergeScale split_merge_scale() const {return _split_merge_scale;} + /// sets scale used in split-merge + void set_split_merge_scale(SplitMergeScale sms) {_split_merge_scale = sms;} + + /// indicates whether the split-merge orders on transverse mass or not. + /// retained for backwards compatibility with 2.1.0b3 + bool split_merge_on_transverse_mass() const {return _split_merge_scale == SM_mt ;} + void set_split_merge_on_transverse_mass(bool val) { + _split_merge_scale = val ? SM_mt : SM_pt;} + + /// indicates whether the split-merge orders on transverse mass or not. + /// retained for backwards compatibility with 2.1.0b3 + bool split_merge_use_pt_weighted_splitting() const {return _use_pt_weighted_splitting;} + void set_split_merge_use_pt_weighted_splitting(bool val) { + _use_pt_weighted_splitting = val;} + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const ; + +protected: + virtual void reset_stored_plugin() const; + +private: + double _protojet_ptmin; + SplitMergeScale _split_merge_scale; + + bool _use_pt_weighted_splitting; + + // part needed for the cache + // variables for caching the results and the input + static std::auto_ptr stored_plugin; + static std::auto_ptr > stored_particles; + static std::auto_ptr stored_siscone; +}; + + +//====================================================================== +/// Class that provides extra information about a SISCone clustering +class SISConeExtras : public SISConeBaseExtras { +public: + /// constructor + // it just initialises the pass information + SISConeExtras(int nparticles) + : SISConeBaseExtras(nparticles){} + + /// access to the siscone jet def plugin (more convenient than + /// getting it from the original jet definition, because here it's + /// directly of the right type (rather than the base type) + const SISConePlugin* jet_def_plugin() const { + return dynamic_cast(_jet_def_plugin); + } + +private: + // let us be written to by SISConePlugin + friend class SISConePlugin; +}; + +} // fastjet namespace + +#endif // __SISCONEPLUGIN_HH__ + diff --git a/JETAN/fastjet/fastjet/SISConeSphericalPlugin.hh b/JETAN/fastjet/fastjet/SISConeSphericalPlugin.hh new file mode 100644 index 00000000000..237a418185d --- /dev/null +++ b/JETAN/fastjet/fastjet/SISConeSphericalPlugin.hh @@ -0,0 +1,188 @@ +#ifndef __SISCONESPHERICALPLUGIN_HH__ +#define __SISCONESPHERICALPLUGIN_HH__ + +#include "SISConeBasePlugin.hh" + +// forward declaration of the siscone classes we'll need +namespace siscone_spherical{ + class CSphsiscone; +}; + +// questionable whether this should be in fastjet namespace or not... +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +// +/// SISConeSphericalPlugin is a plugin for fastjet (v2.1 upwards) that +/// provides an interface to the seedless infrared safe cone jet +/// finder by Gregory Soyez and Gavin Salam. +/// +/// This is the version of SISCone using spherical coordinates. Compared +/// to the original cylindrical version: +/// +/// - Particles are within a cone if their opening angle relative to the +/// centre of the cone is less than R +/// +/// - The split-merge step uses the total energy in the protojet as the +/// ordering and overlap-measure variable +/// +/// - The IR safety of the split-merge step is _not_ guaranteed for +/// events consisting of two back-to-back identical heavy particles +/// that decay. This is because of potential degeneracies in the +/// ordering for the split-merge step. +/// +/// For moderate values of R the problem should not be too severe +/// (or may even be absent for some values of the overlap +/// parameter), however the user should be aware of the issue. +/// +/// The default split-merge scale may change at a later date to +/// resolve this issue. +/// +/// +/// SISCone uses geometrical techniques to exhaustively consider all +/// possible distinct cones. It then finds out which ones are stable +/// and sends the result to the Tevatron Run-II type split-merge +/// procedure for overlapping cones. +/// +/// Four parameters govern the "physics" of the algorithm: +/// +/// - the cone_radius (this should be self-explanatory!) +/// +/// - the overlap_threshold is the parameter which dictates how much +/// two jets must overlap (E_overlap/min(E1,E2)) if they are to be +/// merged +/// +/// - Not all particles are in stable cones in the first round of +/// searching for stable cones; one can therefore optionally have the +/// the jet finder carry out additional passes of searching for +/// stable cones among particles that were in no stable cone in +/// previous passes --- the maximum number of passes carried out is +/// n_pass_max. If this is zero then additional passes are carried +/// out until no new stable cones are found. +/// +/// - Protojet Emin: protojets that are below this Emin +/// (default = 0) are discarded before each iteration of the +/// split-merge loop. +/// +/// One parameter governs some internal algorithmic shortcuts: +/// +/// - if "caching" is turned on then the last event clustered by +/// siscone is stored -- if the current event is identical and the +/// cone_radius and n_pass_max are identical, then the only part of +/// the clustering that needs to be rerun is the split-merge part, +/// leading to significant speed gains; there is a small (O(N) storage +/// and speed) penalty for caching, so it should be kept off +/// (default) if only a single overlap_threshold is used. +/// +/// The final jets can be accessed by requestion the +/// inclusive_jets(...) from the ClusterSequence object. Note that +/// these PseudoJets have their user_index() set to the index of the +/// pass in which they were found (first pass = 0). NB: This does not +/// currently work for jets that consist of a single particle. +/// +/// For further information on the details of the algorithm see the +/// SISCone paper, arXiv:0704.0292 [JHEP 0705:086,2007]. +/// +/// For documentation about the implementation, see the +/// siscone/doc/html/index.html file. +// +class SISConeSphericalPlugin : public SISConeBasePlugin{ +public: + + /// enum for the different split-merge scale choices; + /// Note that order _must_ be the same as in siscone + enum SplitMergeScale {SM_E, ///< Energy (IR unsafe with momentum conservation) + SM_Etilde ///< sum_{i \in jet} E_i [1+sin^2(theta_iJ)] + }; + + + /// Main constructor for the SISConeSpherical Plugin class. + /// + /// + SISConeSphericalPlugin (double cone_radius, + double overlap_threshold, + int n_pass_max = 0, + double protojet_Emin = 0.0, + bool caching = false, + SplitMergeScale split_merge_scale = SM_Etilde, + double split_merge_stopping_scale = 0.0){ + _cone_radius =cone_radius; + _overlap_threshold =overlap_threshold; + _n_pass_max =n_pass_max; + _protojet_Emin =protojet_Emin; + _caching =caching; + _split_merge_scale =split_merge_scale; + _split_merge_stopping_scale = split_merge_stopping_scale; + _ghost_sep_scale = 0.0; + _use_E_weighted_splitting = false; + } + + /// minimum energy for a protojet to be considered in the split-merge step + /// of the algorithm + double protojet_Emin () const {return _protojet_Emin ;} + + /// return the scale to be passed to SISCone as the protojet_Emin + /// -- if we have a ghost separation scale that is above the + /// protojet_ptmin, then the ghost_separation_scale becomes the + /// relevant one to use here + double protojet_or_ghost_Emin () const {return std::max(_protojet_Emin, + _ghost_sep_scale);} + + /// indicates scale used in split-merge + SplitMergeScale split_merge_scale() const {return _split_merge_scale;} + /// sets scale used in split-merge + void set_split_merge_scale(SplitMergeScale sms) {_split_merge_scale = sms;} + + /// indicate if the splittings are done using the anti-kt distance + bool split_merge_use_E_weighted_splitting() const {return _use_E_weighted_splitting;} + void set_split_merge_use_E_weighted_splitting(bool val) { + _use_E_weighted_splitting = val;} + + /// overload the default as we don't provide support + /// for passive areas. + virtual bool supports_ghosted_passive_areas() const {return true;} + + // the things that are required by base class + virtual std::string description () const; + virtual void run_clustering(ClusterSequence &) const ; + +protected: + virtual void reset_stored_plugin() const; + +private: + double _protojet_Emin; + SplitMergeScale _split_merge_scale; + bool _use_E_weighted_splitting; + + // part needed for the cache + // variables for caching the results and the input + static std::auto_ptr stored_plugin; + static std::auto_ptr > stored_particles; + static std::auto_ptr stored_siscone; +}; + +//====================================================================== +/// Class that provides extra information about a SISCone clustering +class SISConeSphericalExtras : public SISConeBaseExtras { +public: + /// constructor + // it just initialises the pass information + SISConeSphericalExtras(int nparticles) + : SISConeBaseExtras(nparticles){} + + /// access to the siscone jet def plugin (more convenient than + /// getting it from the original jet definition, because here it's + /// directly of the right type (rather than the base type) + const SISConeSphericalPlugin* jet_def_plugin() const { + return dynamic_cast(_jet_def_plugin); + } + +private: + // let us be written to by SISConePlugin + friend class SISConeSphericalPlugin; +}; + +} // fastjet namespace + +#endif // __SISCONEPLUGIN_HH__ + diff --git a/JETAN/fastjet/fastjet/config.h b/JETAN/fastjet/fastjet/config.h new file mode 100644 index 00000000000..7fee558164e --- /dev/null +++ b/JETAN/fastjet/fastjet/config.h @@ -0,0 +1,12 @@ +#ifndef __FASTJET_CONFIG_H__ +#define __FASTJET_CONFIG_H__ + +// by default, use an automatically generated config_auto.h +// unless it's a windows machine in which case +#ifndef WIN32 +#include "config_auto.h" +#else +#include "fastjet/config_win.h" +#endif // WIN32 + +#endif // __FASTJET_CONFIG_H__ diff --git a/JETAN/fastjet/fastjet/config_auto.h b/JETAN/fastjet/fastjet/config_auto.h new file mode 100644 index 00000000000..63303d14a95 --- /dev/null +++ b/JETAN/fastjet/fastjet/config_auto.h @@ -0,0 +1,89 @@ +/* include/fastjet/config_auto.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* The ATLASCone plugin is enabled */ +/* #undef ENABLE_PLUGIN_ATLASCONE */ + +/* The CDFJetClu and CDFMidPoint plugins are enabled */ +#define ENABLE_PLUGIN_CDFCONES + +/* The CMSIterativeCone plugin is enabled */ +/* #undef ENABLE_PLUGIN_CMSITERATIVECONE */ + +/* The D0RunIICone plugin is enabled */ +/* #undef ENABLE_PLUGIN_D0RUNIICONE */ + +/* The EECambridge plugin is enabled */ +#define ENABLE_PLUGIN_EECAMBRIDGE + +/* The Jade plugin is enabled */ +#define ENABLE_PLUGIN_JADE + +/* The NestedDefs plugin is enabled */ +#define ENABLE_PLUGIN_NESTEDDEFS + +/* The PxCone plugin is enabled */ +/* #undef ENABLE_PLUGIN_PXCONE */ + +/* The SISCone plugin is enabled */ +#define ENABLE_PLUGIN_SISCONE + +/* The TrackJet plugin is enabled */ +/* #undef ENABLE_PLUGIN_TRACKJET */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "fastjet" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "FastJet" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "FastJet 2.4.0" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "fastjet" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.4.0" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "2.4.0" diff --git a/JETAN/fastjet/fastjet/config_win.h b/JETAN/fastjet/fastjet/config_win.h new file mode 100644 index 00000000000..c11f1119e8a --- /dev/null +++ b/JETAN/fastjet/fastjet/config_win.h @@ -0,0 +1,11 @@ +#define PACKAGE_STRING "FastJet 2.4.0" +#define PACKAGE_VERSION "2.4.0" + +/* The CDFJetClu and CDFMidPoint plugins are enabled by default*/ +#define ENABLE_PLUGIN_CDFCONES + +/* The PxCone plugin is disabled by default*/ +#undef ENABLE_PLUGIN_PXCONE + +/* The SISCone plugin is enabled by default*/ +#define ENABLE_PLUGIN_SISCONE diff --git a/JETAN/fastjet/fastjet/internal/BasicRandom.hh b/JETAN/fastjet/fastjet/internal/BasicRandom.hh new file mode 100644 index 00000000000..82f091474ae --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/BasicRandom.hh @@ -0,0 +1,181 @@ +// Simple random number generator class taken from nlojet++. +// Some doxygen-style comments added by Gavin Salam, August 2006. +// $Id: BasicRandom.hh 621 2007-05-09 10:34:30Z salam $ +// +// Copyright (C) 2002 Zoltan Nagy +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#ifndef __FASTJET_BASICRANDOM_HH__ +#define __FASTJET_BASICRANDOM_HH__ 1 + +// Standard includes +#include +#include +#include +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +template class BasicRandom { +public: + typedef _Tp value_type; + typedef unsigned int size_type; + typedef value_type* pointer; + + // give pseudo random numbers + value_type operator() (); + void operator() (size_type, pointer); + + // (re)initialize the random number generator + void randomize(void *); + + // minimum and maximum values + static value_type min(); + static value_type max(); + + // print the informations about the generator to the stream + void print_info(std::ostream& __os = std::cout); +}; + +// default random generator +int __default_random_generator(int *__iseed); + + +// specializations +template<> +class BasicRandom +{ +public: + typedef int value_type; + typedef unsigned int size_type; + typedef value_type* pointer; + + // constructors + explicit BasicRandom(int __s1 = 12345, int __s2 = 67890) { + _M_iseed[0] = __s1; + _M_iseed[1] = __s2; + } + + // give pseudo random numbers + value_type operator() () { + return __default_random_generator(_M_iseed); + } + + void operator() (size_type __n, pointer __res) { + for(size_type __i = 0; __i < __n; __i++) + __res[__i] = __default_random_generator(_M_iseed); + } + + // (re)initialize the random number generator + void randomize(void *__iseed) { + int *__new_seed = (int*) __iseed; + _M_iseed[0] = __new_seed[0]; + _M_iseed[1] = __new_seed[1]; + } + + void set_status(const std::vector & __iseed) { + assert(__iseed.size() >= 2); + _M_iseed[0] = __iseed[0]; + _M_iseed[1] = __iseed[1]; + } + + void get_status(std::vector & __iseed) { + __iseed.resize(2); + __iseed[0] = _M_iseed[0]; + __iseed[1] = _M_iseed[1]; + } + + // minimum and maximum values + inline static value_type min() { return 0;} + inline static value_type max() { return 2147483647;} + + // print the informations about the generator to the stream + void print_info(std::ostream& __os = std::cout) { + __os<<"BasicRandom : "<<_M_iseed[0]<<", "<<_M_iseed[1]< class BasicRandom { +public: + typedef double value_type; + typedef unsigned int size_type; + typedef value_type* pointer; + + /// constructor that takes two integers to specify the seed + explicit BasicRandom(int __s1 = 12345, int __s2 = 67890) { + _M_iseed[0] = __s1; + _M_iseed[1] = __s2; + } + + /// return a single pseudorandom double number, in the range 0.0 to 1.0 + /// (not sure whether this range is open or closed) + value_type operator() () { + return 4.6566128752457969241e-10*__default_random_generator(_M_iseed); + } + + /// given a pointer __res to the beginning of an array, fill that array + /// with __n random numbers + void operator() (size_type __n, pointer __res) { + for(size_type __i = 0; __i < __n; __i++) + __res[__i] = this -> operator()(); + } + + /// (re)initialize the random number generator from an array of seeds + void randomize(void *__iseed) { + int *__new_seed = (int*) __iseed; + _M_iseed[0] = __new_seed[0]; + _M_iseed[1] = __new_seed[1]; + } + + void set_status(const std::vector & __iseed) { + assert(__iseed.size() >= 2); + _M_iseed[0] = __iseed[0]; + _M_iseed[1] = __iseed[1]; + } + + void get_status(std::vector & __iseed) { + __iseed.resize(2); + __iseed[0] = _M_iseed[0]; + __iseed[1] = _M_iseed[1]; + } + + /// minimum value returned by the generator + inline static value_type min() { return 0.0;} + /// maximum value returned by the generator + inline static value_type max() { return 1.0;} + + /// print information about the generator to the stream + void print_info(std::ostream& __os = std::cout) { + __os<<"BasicRandom : "<<_M_iseed[0]<<", "<<_M_iseed[1]< _G_random_int; +extern BasicRandom _G_random_double; + + +} // fastjet namespace + +#endif // __FASTJET_BASICRANDOM_HH__ + diff --git a/JETAN/fastjet/fastjet/internal/ClosestPair2D.hh b/JETAN/fastjet/fastjet/internal/ClosestPair2D.hh new file mode 100644 index 00000000000..8c76e4cc1ff --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/ClosestPair2D.hh @@ -0,0 +1,234 @@ +//STARTHEADER +// $Id: ClosestPair2D.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLOSESTPAIR2D__HH__ +#define __FASTJET_CLOSESTPAIR2D__HH__ + +#include +#include +#include +#include "fastjet/internal/ClosestPair2DBase.hh" +#include "fastjet/internal/SearchTree.hh" +#include "fastjet/internal/MinHeap.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +/// concrete implementation for finding closest pairs in 2D -- will +/// use Chan's (hopefully efficient) shuffle based structures +class ClosestPair2D : public ClosestPair2DBase { +public: + /// constructor from a vector of 2D positions -- number of objects + /// after insertion and deletion must never exceed positions.size(); + /// objects are given IDs that correspond to their index in the vector + /// of positions + ClosestPair2D(const std::vector & positions, + const Coord2D & left_corner, const Coord2D & right_corner) { + _initialize(positions, left_corner, right_corner, positions.size()); + }; + + /// constructor which allows structure to grow beyond positions.size(), up + /// to max_size + ClosestPair2D(const std::vector & positions, + const Coord2D & left_corner, const Coord2D & right_corner, + const unsigned int max_size) { + _initialize(positions, left_corner, right_corner, max_size); + }; + + /// provides the IDs of the closest pair as well as the distance between + /// them + void closest_pair(unsigned int & ID1, unsigned int & ID2, + double & distance2) const; + + /// removes the entry labelled by ID from the object; + void remove(unsigned int ID); + + /// inserts the position into the closest pair structure and returns the + /// ID that has been allocated for the object. + unsigned int insert(const Coord2D &); + + /// removes ID1 and ID2 and inserts position, returning the ID + /// corresponding to position... + virtual unsigned int replace(unsigned int ID1, unsigned int ID2, + const Coord2D & position); + + /// replaces IDs_to_remove with points at the new_positions + /// indicating the IDs allocated to the new points in new_IDs + virtual void replace_many(const std::vector & IDs_to_remove, + const std::vector & new_positions, + std::vector & new_IDs); + + // mostly for checking how things are working... + inline void print_tree_depths(std::ostream & outdev) const { + outdev << _trees[0]->max_depth() << " " + << _trees[1]->max_depth() << " " + << _trees[2]->max_depth() << "\n"; + }; + + unsigned int size(); + +private: + + void _initialize(const std::vector & positions, + const Coord2D & left_corner, const Coord2D & right_corner, + const unsigned int max_size); + + static const unsigned int _nshift = 3; + + class Point; // will be defined below + + /// since sets of three objects will crop up repeatedly, useful + /// to have a triplet class? + template class triplet { + public: + inline const T & operator[](unsigned int i) const {return _contents[i];}; + inline T & operator[](unsigned int i) {return _contents[i];}; + private: + T _contents[_nshift]; + }; + + + /// class that will take care of ordering of shuffles for us + class Shuffle { + public: + unsigned int x, y; + Point * point; + bool operator<(const Shuffle &) const; + void operator+=(unsigned int shift) {x += shift; y+= shift;}; + }; + + typedef SearchTree Tree; + typedef Tree::circulator circulator; + typedef Tree::const_circulator const_circulator; + + + triplet > _trees; + std::auto_ptr _heap; + std::vector _points; + std::stack _available_points; + + /// points that are "under review" in some way + std::vector _points_under_review; + + // different statuses for review + static const unsigned int _remove_heap_entry = 1; + static const unsigned int _review_heap_entry = 2; + static const unsigned int _review_neighbour = 4; + + /// add a label to a point as to the nature of review needed + /// (includes adding it to list of points needing review) [doesn't + /// affect other labels already set for the point] + void _add_label(Point * point, unsigned int review_flag); + + /// sets the label for the point to be exclusively this + /// review flag (and adds it to list of points needing review + /// if not already there) + void _set_label(Point * point, unsigned int review_flag); + + /// for all entries of the _points_under_review[] vector, carry out + /// the actions indicated by its review flag; the points are + /// then removed from _points_under_review[] and their flags + /// set to zero + void _deal_with_points_to_review(); + + /// carry out the search-tree related operations of point removal + void _remove_from_search_tree(Point * point_to_remove); + + /// carry out the search-tree related operations of point insertion + void _insert_into_search_tree(Point * new_point); + + /// takes a point and creates a shuffle with the given shift + void _point2shuffle(Point & , Shuffle & , unsigned int shift); + + /// pieces needed for converting coordinates to integer + Coord2D _left_corner; + double _range; + + int _ID(const Point *) const; + + triplet _shifts; // absolute shifts + triplet _rel_shifts; // shifts relative to previous shift + + unsigned int _cp_search_range; +}; + + +//---------------------------------------------------------------------- +/// class for representing all info needed about a point +class ClosestPair2D::Point { +public: + /// the point's coordinates + Coord2D coord; + /// a pointer to its closest neighbour in our structure + Point * neighbour; + /// the corresponding squared distance + double neighbour_dist2; + /// circulators for each of the shifts of the shuffles + triplet circ; + + /// indicates that something special is currently happening to this point + unsigned int review_flag; + + /// returns the distance between two of these objects + double distance2(const Point & other) const { + return coord.distance2(other.coord); + }; + + /// creates a shuffle for us with a given shift + //void set_shuffle(Shuffle & shuffle); +}; + + +//---------------------------------------------------------------------- +/// returns true if floor(ln_base2(x)) < floor(ln_base2(y)), using +/// Chan's neat trick... +inline bool floor_ln2_less(unsigned x, unsigned y) { + if (x>y) return false; + return (x < (x^y)); // beware of operator precedence... +} + + +//---------------------------------------------------------------------- +/// returns the ID for the specified point... +inline int ClosestPair2D::_ID(const Point * point) const { + return point - &(_points[0]); +} + + +// +inline unsigned int ClosestPair2D::size() { + return _points.size() - _available_points.size(); +} + + + +} // fastjet namespace + +#endif // __FASTJET_CLOSESTPAIR2D__HH__ diff --git a/JETAN/fastjet/fastjet/internal/ClosestPair2DBase.hh b/JETAN/fastjet/fastjet/internal/ClosestPair2DBase.hh new file mode 100644 index 00000000000..1f33ce502f1 --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/ClosestPair2DBase.hh @@ -0,0 +1,129 @@ +//STARTHEADER +// $Id: ClosestPair2DBase.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_CLOSESTPAIR2DBASE__HH__ +#define __FASTJET_CLOSESTPAIR2DBASE__HH__ + +#include +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +//---------------------------------------------------------------------- +/// class for representing 2d coordinates and carrying out some basic +/// operations on them +class Coord2D { +public: + double x, y; + + Coord2D() {}; + + Coord2D(double a, double b): x(a), y(b) {}; + + /// return the vector difference between two coordinates + Coord2D operator-(const Coord2D & other) const { + return Coord2D(x - other.x, y - other.y);}; + + /// return the vector sum between two coordinates + Coord2D operator+(const Coord2D & other) const { + return Coord2D(x + other.x, y + other.y);}; + + /// return the product of the coordinate with the factor + Coord2D operator*(double factor) const {return Coord2D(factor*x,factor*y);}; + friend Coord2D operator*(double factor, const Coord2D & coord) { + return Coord2D(factor*coord.x,factor*coord.y); + } + + /// division of each component of coordinate + Coord2D operator/(double divisor) const { + return Coord2D(x / divisor, y / divisor);}; + + /// return the squared distance between two coordinates + friend double distance2(const Coord2D & a, const Coord2D & b) { + double dx = a.x - b.x, dy = a.y-b.y; + return dx*dx+dy*dy; + }; + /// return the squared distance between two coordinates + double distance2(const Coord2D & b) const { + double dx = x - b.x, dy = y-b.y; + return dx*dx+dy*dy; + }; +}; + + +//---------------------------------------------------------------------- +/// abstract base class for finding closest pairs in 2D +class ClosestPair2DBase { +public: + /// provides the IDs of the closest pair as well as the squared + /// distance between them + virtual void closest_pair(unsigned int & ID1, unsigned int & ID2, + double & distance2) const = 0; + + /// removes the entry labelled by ID from the object; + virtual void remove(unsigned int ID) = 0; + + /// inserts the position into the closest pair structure and returns the + /// ID that has been allocated for the object. + virtual unsigned int insert(const Coord2D & position) = 0; + + /// replaces the specified ID1 and ID2 with something at a new position + /// assuming that ID1 and ID2 are in sequence wrt position; it returns + /// the ID of the new object... + virtual unsigned int replace(unsigned int ID1, unsigned int ID2, + const Coord2D & position) { + remove(ID1); + remove(ID2); + unsigned new_ID = insert(position); + return(new_ID); + }; + + /// replaces IDs_to_remove with points at the new_positions + /// indicating the IDs allocated to the new points in new_IDs + virtual void replace_many(const std::vector & IDs_to_remove, + const std::vector & new_positions, + std::vector & new_IDs) { + for(unsigned i = 0; i < IDs_to_remove.size(); i++) { + remove(IDs_to_remove[i]);} + new_IDs.resize(0); + for(unsigned i = 0; i < new_positions.size(); i++) { + new_IDs.push_back(insert(new_positions[i]));} + } + + virtual unsigned int size() = 0; + + virtual ~ClosestPair2DBase() {}; + +}; + + +} // fastjet namespace + +#endif // __FASTJET_CLOSESTPAIR2DBASE__HH__ diff --git a/JETAN/fastjet/fastjet/internal/Dnn2piCylinder.hh b/JETAN/fastjet/fastjet/internal/Dnn2piCylinder.hh new file mode 100644 index 00000000000..41d72517bc2 --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/Dnn2piCylinder.hh @@ -0,0 +1,267 @@ +//STARTHEADER +// $Id: Dnn2piCylinder.hh 431 2007-01-20 10:44:55Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef DROP_CGAL // in case we do not have the code for CGAL +#ifndef __FASTJET_DNN2PICYLINDER_HH__ +#define __FASTJET_DNN2PICYLINDER_HH__ + +#include "fastjet/internal/DynamicNearestNeighbours.hh" +#include "fastjet/internal/DnnPlane.hh" +#include "fastjet/internal/numconsts.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + + +/// class derived from DynamicNearestNeighbours that provides an +/// implementation for the surface of cylinder (using one +/// DnnPlane object spanning 0--2pi). +class Dnn2piCylinder : public DynamicNearestNeighbours { + public: + /// empty initaliser + Dnn2piCylinder() {} + + /// Initialiser from a set of points on an Eta-Phi plane, where + /// eta can have an arbitrary ranges and phi must be in range + /// 0 <= phi < 2pi; + /// + /// NB: this class is more efficient than the plain Dnn4piCylinder + /// class, but can give wrong answers when the nearest neighbour is + /// further away than 2pi (in this case a point's nearest neighbour + /// becomes itself, because it is considered to be a distance 2pi + /// away). For the kt-algorithm (e.g.) this is actually not a + /// problem (the distance need only be accurate when it is less than + /// R), so we can tell the routine to ignore this problem -- + /// alternatively the routine will crash if it detects it occurring + /// (only when finding the nearest neighbour index, not its + /// distance). + Dnn2piCylinder(const std::vector &, + const bool & ignore_nearest_is_mirror = false, + const bool & verbose = false ); + + /// Returns the index of the nearest neighbour of point labelled + /// by ii (assumes ii is valid) + int NearestNeighbourIndex(const int & ii) const ; + + /// Returns the distance to the nearest neighbour of point labelled + /// by index ii (assumes ii is valid) + double NearestNeighbourDistance(const int & ii) const ; + + /// Returns true iff the given index corresponds to a point that + /// exists in the DNN structure (meaning that it has been added, and + /// not removed in the meantime) + bool Valid(const int & index) const; + + void RemoveAndAddPoints(const std::vector & indices_to_remove, + const std::vector & points_to_add, + std::vector & indices_added, + std::vector & indices_of_updated_neighbours); + + ~Dnn2piCylinder(); + + private: + + // our extras to help us navigate, find distance, etc. + const static int INEXISTENT_VERTEX=-3; + + bool _verbose; + + bool _ignore_nearest_is_mirror; + + /// Picture of how things will work... Copy 0--pi part of the 0--2pi + /// cylinder into a region 2pi--2pi+ a bit of a Euclidean plane. Below we + /// show points labelled by + that have a mirror image in this + /// manner, while points labelled by * do not have a mirror image. + /// + /// | . | + /// | . | + /// | . | + /// | . | + /// | 2 . | + /// | * . | + /// | + . + | + /// | 0 . 1 | + /// | . | + /// 0 2pi 2pi + a bit + /// + /// Each "true" point has its true "cylinder" index (the index that + /// is known externally to this class) as well as euclidean plane + /// indices (main_index and mirror index in the MirrorVertexInfo + /// structure), which are private concepts of this class. + /// + /// In above picture our structures would hold the following info + /// (the picture shows the euclidean-plane numbering) + /// + /// _mirror_info[cylinder_index = 0] = (0, 1) + /// _mirror_info[cylinder_index = 1] = (2, INEXISTENT_VERTEX) + /// + /// We also need to be able to go from the euclidean plane indices + /// back to the "true" cylinder index, and for this purpose we use + /// the std::vector _cylinder_index_of_plane_vertex[...], which in the above example has + /// the following contents + /// + /// _cylinder_index_of_plane_vertex[0] = 0 + /// _cylinder_index_of_plane_vertex[1] = 0 + /// _cylinder_index_of_plane_vertex[2] = 1 + /// + + /// + struct MirrorVertexInfo { + /// index of the given point (appearing in the range 0--2pi) in the + /// 0--2pi euclidean plane structure (position will coincide with + /// that on the 0--2pi cylinder, but index labelling it will be + /// different) + int main_index; + /// index of the mirror point (appearing in the range 2pi--3pi) in the + /// 0--3pi euclidean plane structure + int mirror_index; + }; + + // for each "true" vertex we have reference to indices in the euclidean + // plane structure + std::vector _mirror_info; + // for each index in the euclidean 0--2pi plane structure we want to + // be able to get back to the "true" vertex index on the overall + // 0--2pi cylinder structure + std::vector _cylinder_index_of_plane_vertex; + + // NB: we define POINTERS here because the initialisation gave + // us problems (things crashed!), perhaps because in practice + // we were making a copy without being careful and defining + // a proper copy constructor. + DnnPlane * _DNN; + + /// given a phi value in the 0--pi range return one + /// in the 2pi--3pi range; whereas if it is in the pi-2pi range then + /// remap it to be inthe range (-pi)--0. + inline EtaPhi _remap_phi(const EtaPhi & point) { + double phi = point.second; + if (phi < pi) { phi += twopi ;} else {phi -= twopi;} + return EtaPhi(point.first, phi);} + + + //---------------------------------------------------------------------- + /// Actions here are similar to those in the + /// Dnn3piCylinder::_RegisterCylinderPoint case, however here we do + /// NOT create the mirror point -- instead we initialise the structure + /// as if there were no need for the mirror point. + /// + /// ADDITIONALLY push the cylinder_point onto the vector plane_points. + void _RegisterCylinderPoint (const EtaPhi & cylinder_point, + std::vector & plane_points); + + /// For each plane point specified in the vector plane_indices, + /// establish whether there is a need to create a mirror point + /// according to the following criteria: + /// + /// . phi < pi + /// . mirror does not already exist + /// . phi < NearestNeighbourDistance + /// (if this is not true then there is no way that its mirror point + /// could have a nearer neighbour). + /// + /// If conditions all hold, then create the mirror point, insert it + /// into the _DNN structure, adjusting any nearest neighbours, and + /// return the list of plane points whose nearest neighbours have + /// changed (this will include the new neighbours that have just been + /// added) + void _CreateNecessaryMirrorPoints( + const std::vector & plane_indices, + std::vector & updated_plane_points); + +}; + + +// here follow some inline implementations of the simpler of the +// functions defined above + +//---------------------------------------------------------------------- +/// Note: one of the difficulties of the 0--2pi mapping is that +/// a point may have its mirror copy as its own nearest neighbour +/// (if no other point is within a distance of 2pi). This does +/// not matter for the kt_algorithm with +/// reasonable values of radius, but might matter for a general use +/// of this algorithm -- depending on whether or not the user has +/// initialised the class with instructions to ignore this problem the +/// program will detect and ignore it, or crash. +inline int Dnn2piCylinder::NearestNeighbourIndex(const int & current) const { + int main_index = _mirror_info[current].main_index; + int mirror_index = _mirror_info[current].mirror_index; + int plane_index; + if (mirror_index == INEXISTENT_VERTEX ) { + plane_index = _DNN->NearestNeighbourIndex(main_index); + } else { + plane_index = ( + _DNN->NearestNeighbourDistance(main_index) < + _DNN->NearestNeighbourDistance(mirror_index)) ? + _DNN->NearestNeighbourIndex(main_index) : + _DNN->NearestNeighbourIndex(mirror_index) ; + } + int this_cylinder_index = _cylinder_index_of_plane_vertex[plane_index]; + // either the user has acknowledged the fact that they may get the + // mirror copy as the closest point, or crash if it should occur + // that mirror copy is the closest point. + assert(_ignore_nearest_is_mirror || this_cylinder_index != current); + //if (this_cylinder_index == current) { + // cerr << "WARNING point "<NearestNeighbourDistance(main_index); + } else { + return ( + _DNN->NearestNeighbourDistance(main_index) < + _DNN->NearestNeighbourDistance(mirror_index)) ? + _DNN->NearestNeighbourDistance(main_index) : + _DNN->NearestNeighbourDistance(mirror_index) ; + } + +} + +inline bool Dnn2piCylinder::Valid(const int & index) const { + return (_DNN->Valid(_mirror_info[index].main_index)); +} + + +inline Dnn2piCylinder::~Dnn2piCylinder() { + delete _DNN; +} + + +} // fastjet namespace + +#endif // __FASTJET_DNN2PICYLINDER_HH__ +#endif //DROP_CGAL diff --git a/JETAN/fastjet/fastjet/internal/Dnn3piCylinder.hh b/JETAN/fastjet/fastjet/internal/Dnn3piCylinder.hh new file mode 100644 index 00000000000..01aabbc9a30 --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/Dnn3piCylinder.hh @@ -0,0 +1,257 @@ +//STARTHEADER +// $Id: Dnn3piCylinder.hh 431 2007-01-20 10:44:55Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef DROP_CGAL // in case we do not have the code for CGAL +#ifndef __FASTJET_DNN3PICYLINDER_HH__ +#define __FASTJET_DNN3PICYLINDER_HH__ + +#include "fastjet/internal/DynamicNearestNeighbours.hh" +#include "fastjet/internal/DnnPlane.hh" +#include "fastjet/internal/numconsts.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// class derived from DynamicNearestNeighbours that provides an +/// implementation for the surface of cylinder (using one +/// DnnPlane object spanning 0--3pi). +class Dnn3piCylinder : public DynamicNearestNeighbours { + public: + /// empty initaliser + Dnn3piCylinder() {} + + /// Initialiser from a set of points on an Eta-Phi plane, where + /// eta can have an arbitrary ranges and phi must be in range + /// 0 <= phi < 2pi; + /// + /// NB: this class is more efficient than the plain Dnn4piCylinder + /// class, but can give wrong answers when the nearest neighbour is + /// further away than 2pi (in this case a point's nearest neighbour + /// becomes itself, because it is considered to be a distance 2pi + /// away). For the kt-algorithm (e.g.) this is actually not a + /// problem (the distance need only be accurate when it is less than + /// R), so we can tell the routine to ignore this problem -- + /// alternatively the routine will crash if it detects it occurring + /// (only when finding the nearest neighbour index, not its + /// distance). + Dnn3piCylinder(const std::vector &, + const bool & ignore_nearest_is_mirror = false, + const bool & verbose = false ); + + /// Returns the index of the nearest neighbour of point labelled + /// by ii (assumes ii is valid) + int NearestNeighbourIndex(const int & ii) const ; + + /// Returns the distance to the nearest neighbour of point labelled + /// by index ii (assumes ii is valid) + double NearestNeighbourDistance(const int & ii) const ; + + /// Returns true iff the given index corresponds to a point that + /// exists in the DNN structure (meaning that it has been added, and + /// not removed in the meantime) + bool Valid(const int & index) const; + + void RemoveAndAddPoints(const std::vector & indices_to_remove, + const std::vector & points_to_add, + std::vector & indices_added, + std::vector & indices_of_updated_neighbours); + + ~Dnn3piCylinder(); + + private: + + // our extras to help us navigate, find distance, etc. + const static int INEXISTENT_VERTEX=-3; + + bool _verbose; + + bool _ignore_nearest_is_mirror; + + /// Picture of how things will work... Copy 0--pi part of the 0--2pi + /// cylinder into a region 2pi--3pi of a Euclidean plane. Below we + /// show points labelled by + that have a mirror image in this + /// manner, while points labelled by * do not have a mirror image. + /// + /// | . | + /// | . | + /// | . | + /// | . | + /// | 2 . | + /// | * . | + /// | + . + | + /// | 0 . 1 | + /// | . | + /// 0 2pi 3pi + /// + /// Each "true" point has its true "cylinder" index (the index that + /// is known externally to this class) as well as euclidean plane + /// indices (main_index and mirror index in the MirrorVertexInfo + /// structure), which are private concepts of this class. + /// + /// In above picture our structures would hold the following info + /// (the picture shows the euclidean-plane numbering) + /// + /// _mirror_info[cylinder_index = 0] = (0, 1) + /// _mirror_info[cylinder_index = 1] = (2, INEXISTENT_VERTEX) + /// + /// We also need to be able to go from the euclidean plane indices + /// back to the "true" cylinder index, and for this purpose we use + /// the vector _cylinder_index_of_plane_vertex[...], which in the above example has + /// the following contents + /// + /// _cylinder_index_of_plane_vertex[0] = 0 + /// _cylinder_index_of_plane_vertex[1] = 0 + /// _cylinder_index_of_plane_vertex[2] = 1 + /// + + /// + struct MirrorVertexInfo { + /// index of the given point (appearing in the range 0--2pi) in the + /// 0--3pi euclidean plane structure (position will coincide with + /// that on the 0--2pi cylinder, but index labelling it will be + /// different) + int main_index; + /// index of the mirror point (appearing in the range 2pi--3pi) in the + /// 0--3pi euclidean plane structure + int mirror_index; + }; + + // for each "true" vertex we have reference to indices in the euclidean + // plane structure + std::vector _mirror_info; + // for each index in the euclidean 0--3pi plane structure we want to + // be able to get back to the "true" vertex index on the overall + // 0--2pi cylinder structure + std::vector _cylinder_index_of_plane_vertex; + + // NB: we define POINTERS here because the initialisation gave + // us problems (things crashed!), perhaps because in practice + // we were making a copy without being careful and defining + // a proper copy constructor. + DnnPlane * _DNN; + + /// given a phi value in the 0--2pi range return one + /// in the pi--3pi range. + inline EtaPhi _remap_phi(const EtaPhi & point) { + double phi = point.second; + if (phi < pi) { phi += twopi ;} + return EtaPhi(point.first, phi);} + + + //---------------------------------------------------------------------- + /// What on earth does this do? + /// + /// Example: last true "cylinder" index was 15 + /// last plane index was 23 + /// + /// Then: _cylinder_index_of_plane_vertex.size() = 24 and + /// _mirror_info.size() = 16 + /// + /// IF cylinder_point's phi < pi then + /// create: _mirror_info[16] = (main_index = 24, mirror_index=25) + /// _cylinder_index_of_plane_vertex[24] = 16 + /// _cylinder_index_of_plane_vertex[25] = 16 + /// ELSE + /// create: _mirror_info[16] = (main_index = 24, mirror_index=INEXISTENT..) + /// _cylinder_index_of_plane_vertex[24] = 16 + /// + /// ADDITIONALLY push the cylinder_point (and if it exists the mirror + /// copy) onto the vector plane_points. + void _RegisterCylinderPoint (const EtaPhi & cylinder_point, + std::vector & plane_points); +}; + + +// here follow some inline implementations of the simpler of the +// functions defined above + +//---------------------------------------------------------------------- +/// Note: one of the difficulties of the 0--3pi mapping is that +/// a point may have its mirror copy as its own nearest neighbour +/// (if no other point is within a distance of 2pi). This does +/// not matter for the kt_algorithm with +/// reasonable values of radius, but might matter for a general use +/// of this algorithm -- depending on whether or not the user has +/// initialised the class with instructions to ignore this problem the +/// program will detect and ignore it, or crash. +inline int Dnn3piCylinder::NearestNeighbourIndex(const int & current) const { + int main_index = _mirror_info[current].main_index; + int mirror_index = _mirror_info[current].mirror_index; + int plane_index; + if (mirror_index == INEXISTENT_VERTEX ) { + plane_index = _DNN->NearestNeighbourIndex(main_index); + } else { + plane_index = ( + _DNN->NearestNeighbourDistance(main_index) < + _DNN->NearestNeighbourDistance(mirror_index)) ? + _DNN->NearestNeighbourIndex(main_index) : + _DNN->NearestNeighbourIndex(mirror_index) ; + } + int this_cylinder_index = _cylinder_index_of_plane_vertex[plane_index]; + // either the user has acknowledged the fact that they may get the + // mirror copy as the closest point, or crash if it should occur + // that mirror copy is the closest point. + assert(_ignore_nearest_is_mirror || this_cylinder_index != current); + //if (this_cylinder_index == current) { + // std::cerr << "WARNING point "<NearestNeighbourDistance(main_index); + } else { + return ( + _DNN->NearestNeighbourDistance(main_index) < + _DNN->NearestNeighbourDistance(mirror_index)) ? + _DNN->NearestNeighbourDistance(main_index) : + _DNN->NearestNeighbourDistance(mirror_index) ; + } + +} + +inline bool Dnn3piCylinder::Valid(const int & index) const { + return (_DNN->Valid(_mirror_info[index].main_index)); +} + + +inline Dnn3piCylinder::~Dnn3piCylinder() { + delete _DNN; +} + + +} // fastjet namespace + +#endif // __FASTJET_DNN3PICYLINDER_HH__ +#endif // DROP_CGAL diff --git a/JETAN/fastjet/fastjet/internal/Dnn4piCylinder.hh b/JETAN/fastjet/fastjet/internal/Dnn4piCylinder.hh new file mode 100644 index 00000000000..1dea8c68714 --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/Dnn4piCylinder.hh @@ -0,0 +1,126 @@ +//STARTHEADER +// $Id: Dnn4piCylinder.hh 431 2007-01-20 10:44:55Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef DROP_CGAL // in case we do not have the code for CGAL +#ifndef __FASTJET_DNN4PICYLINDER_HH__ +#define __FASTJET_DNN4PICYLINDER_HH__ + +#include "fastjet/internal/DynamicNearestNeighbours.hh" +#include "fastjet/internal/DnnPlane.hh" +#include "fastjet/internal/numconsts.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// class derived from DynamicNearestNeighbours that provides an +/// implementation for the surface of cylinder (using two copies of +/// DnnPlane, one running from 0--2pi, the other from pi--3pi). +class Dnn4piCylinder : public DynamicNearestNeighbours { + public: + /// empty initaliser + Dnn4piCylinder() {} + + /// Initialiser from a set of points on an Eta-Phi plane, where + /// eta can have an arbitrary ranges and phi must be in range + /// 0 <= phi < 2pi + Dnn4piCylinder(const std::vector &, const bool & verbose = false ); + + /// Returns the index of the nearest neighbour of point labelled + /// by ii (assumes ii is valid) + int NearestNeighbourIndex(const int & ii) const ; + + /// Returns the distance to the nearest neighbour of point labelled + /// by index ii (assumes ii is valid) + double NearestNeighbourDistance(const int & ii) const ; + + /// Returns true iff the given index corresponds to a point that + /// exists in the DNN structure (meaning that it has been added, and + /// not removed in the meantime) + bool Valid(const int & index) const; + + void RemoveAndAddPoints(const std::vector & indices_to_remove, + const std::vector & points_to_add, + std::vector & indices_added, + std::vector & indices_of_updated_neighbours); + + ~Dnn4piCylinder(); + + private: + + bool _verbose; + + // NB: we define POINTERS here because the initialisation gave + // us problems (things crashed!), perhaps because in practice + // we were making a copy without being careful and defining + // a proper copy constructor. + DnnPlane * _DNN1, * _DNN2; + + /// given a phi value in the 0--2pi range return one + /// in the pi--3pi range. + inline EtaPhi _remap_phi(const EtaPhi & point) { + double phi = point.second; + if (phi < pi) { phi += twopi ;} + return EtaPhi(point.first, phi);} + +}; + + +// here follow some inline implementations of the simpler of the +// functions defined above + +inline int Dnn4piCylinder::NearestNeighbourIndex(const int & current) const { + return (_DNN1->NearestNeighbourDistance(current) < + _DNN2->NearestNeighbourDistance(current)) ? + _DNN1->NearestNeighbourIndex(current) : + _DNN2->NearestNeighbourIndex(current) ; +} + +inline double Dnn4piCylinder::NearestNeighbourDistance(const int & current) const { + return (_DNN1->NearestNeighbourDistance(current) < + _DNN2->NearestNeighbourDistance(current)) ? + _DNN1->NearestNeighbourDistance(current) : + _DNN2->NearestNeighbourDistance(current) ; +} + +inline bool Dnn4piCylinder::Valid(const int & index) const { + return (_DNN1->Valid(index) && _DNN2->Valid(index)); +} + + +inline Dnn4piCylinder::~Dnn4piCylinder() { + delete _DNN1; + delete _DNN2; +} + + +} // fastjet namespace + +#endif // __FASTJET_DNN4PICYLINDER_HH__ +#endif // DROP_CGAL diff --git a/JETAN/fastjet/fastjet/internal/DnnPlane.hh b/JETAN/fastjet/fastjet/internal/DnnPlane.hh new file mode 100644 index 00000000000..7cfc55b13fa --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/DnnPlane.hh @@ -0,0 +1,163 @@ +//STARTHEADER +// $Id: DnnPlane.hh 431 2007-01-20 10:44:55Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef DROP_CGAL // in case we do not have the code for CGAL + +#ifndef __FASTJET_DNNPLANE_HH__ +#define __FASTJET_DNNPLANE_HH__ + +#include "fastjet/internal/Triangulation.hh" +#include "fastjet/internal/DynamicNearestNeighbours.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + + +/// class derived from DynamicNearestNeighbours that provides an +/// implementation for the Euclidean plane +class DnnPlane : public DynamicNearestNeighbours { + public: + /// empty initaliser + DnnPlane() {} + + /// Initialiser from a set of points on an Eta-Phi plane, where both + /// eta and phi can have arbitrary ranges + DnnPlane(const std::vector &, const bool & verbose = false ); + + + /// Returns the index of the nearest neighbour of point labelled + /// by ii (assumes ii is valid) + int NearestNeighbourIndex(const int & ii) const ; + + /// Returns the distance to the nearest neighbour of point labelled + /// by index ii (assumes ii is valid) + double NearestNeighbourDistance(const int & ii) const ; + + /// Returns true iff the given index corresponds to a point that + /// exists in the DNN structure (meaning that it has been added, and + /// not removed in the meantime) + bool Valid(const int & index) const; + + void RemoveAndAddPoints(const std::vector & indices_to_remove, + const std::vector & points_to_add, + std::vector & indices_added, + std::vector & indices_of_updated_neighbours); + + /// returns the EtaPhi of point with index i. + EtaPhi etaphi(const int i) const; + /// returns the eta point with index i. + double eta(const int i) const; + /// returns the phi point with index i. + double phi(const int i) const; + + private: + + /// Structure containing a vertex_handle and cached information on + /// the nearest neighbour. + struct SuperVertex { + Vertex_handle vertex; // NULL indicates inexistence... + double NNdistance; + int NNindex; + // later on for cylinder put a second vertex? + }; + + std::vector _supervertex; + //set _vertex_set; + bool _verbose; + + static const bool _crash_on_coincidence = true; + //static const bool _crash_on_coincidence = false; + + Triangulation _TR; /// CGAL object for dealing with triangulations + + /// calculates and returns the euclidean distance between points p1 + /// and p2 + inline double _euclid_distance(const Point& p1, const Point& p2) const { + double distx= p1.x()-p2.x(); + double disty= p1.y()-p2.y(); + return distx*distx+disty*disty; + } + + //---------------------------------------------------------------------- + /// Determines the index and distance of the nearest neighbour to + /// point j and puts the information into the _supervertex entry for j + void _SetNearest(const int & j); + + //---------------------------------------------------------------------- + /// Determines and stores the nearest neighbour of j. + /// + /// For each voronoi neighbour D of j if the distance between j and D + /// is less than D's own nearest neighbour, then update the + /// nearest-neighbour info in D; push D's index onto + /// indices_of_updated_neighbours + /// + /// Note that j is NOT pushed onto indices_of_updated_neighbours -- + /// if you want it there, put it there yourself. + void _SetAndUpdateNearest(const int & j, + std::vector & indices_of_updated_neighbours); + + /// given a vertex_handle returned by CGAL on insertion of a new + /// points, crash if it turns out that it corresponds to a vertex + /// that we already knew about (usually because two points coincide) + void _CrashIfVertexPresent(const Vertex_handle & vertex, + const int & its_index); + +}; + + +// here follow some inline implementations of the simpler of the +// functions defined above + +inline int DnnPlane::NearestNeighbourIndex(const int & ii) const { + return _supervertex[ii].NNindex;} + +inline double DnnPlane::NearestNeighbourDistance(const int & ii) const { + return _supervertex[ii].NNdistance;} + +inline bool DnnPlane::Valid(const int & index) const { + if (index >= 0 && index < static_cast(_supervertex.size())) { + return (_supervertex[index].vertex != NULL);} else {return false;} } + +inline EtaPhi DnnPlane::etaphi(const int i) const { + Point * p = & (_supervertex[i].vertex->point()); + return EtaPhi(p->x(),p->y()); } + +inline double DnnPlane::eta(const int i) const { + return _supervertex[i].vertex->point().x(); } + +inline double DnnPlane::phi(const int i) const { + return _supervertex[i].vertex->point().y(); } + + +} // fastjet namespace + +#endif // __FASTJET_DNNPLANE_HH__ + +#endif // DROP_CGAL diff --git a/JETAN/fastjet/fastjet/internal/DynamicNearestNeighbours.hh b/JETAN/fastjet/fastjet/internal/DynamicNearestNeighbours.hh new file mode 100644 index 00000000000..b226a21e048 --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/DynamicNearestNeighbours.hh @@ -0,0 +1,171 @@ +//STARTHEADER +// $Id: DynamicNearestNeighbours.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_DYNAMICNEARESTNEIGHBOURS_HH__ +#define __FASTJET_DYNAMICNEARESTNEIGHBOURS_HH__ + +#include +#include +#include +#include +#include +#include "fastjet/internal/numconsts.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// Shortcut for dealing with eta-phi coordinates. +//typedef std::pair EtaPhi; + +/// use a class instead of a pair so that phi can be sanitized +/// and put into proper range on initialization. +class EtaPhi { +public: + double first, second; + EtaPhi() {} + EtaPhi(double a, double b) {first = a; second = b;} + /// put things into the desired range. + void sanitize() { + if (second < 0) second += twopi; + if (second >= twopi) second -= twopi; + } + +}; + +/// class corresponding to errors that will be thrown by Dynamic +/// Nearest Neighbours code +class DnnError { +public: + // constructors + DnnError() {;}; + DnnError(const std::string & message) { + _message = message; std::cerr << message << std::endl;}; + + std::string message() const {return _message;}; + +private: + std::string _message; +}; + + +/// +/// Abstract base class for quick location of nearest neighbours in a set of +/// points, with facilities for adding and removing points from the +/// set after initialisation. Derived classes will be +/// named according to the convention DnnSomeName (e.g. DnnPlane). +/// +/// The main purpose of this abstract base class is to define the +/// general interface of a whole set of classes that deal with +/// nearest-neighbour location on different 2-d geometries and with +/// various underlying data structures and algorithms. +/// +class DynamicNearestNeighbours { + +public: + /// Dummy initialiser --- does nothing! + //virtual DynamicNearestNeighbours() {}; + + /// Initialiser --- sets up the necessary structures to allow efficient + /// nearest-neighbour finding on the std::vector of input points + //virtual DynamicNearestNeighbours(const std::vector &, + // const bool & verbose = false ) = 0; + + /// Returns the index of the nearest neighbour of point labelled + /// by ii (assumes ii is valid) + virtual int NearestNeighbourIndex(const int & ii) const = 0; + + /// Returns the distance to the nearest neighbour of point labelled + /// by index ii (assumes ii is valid) + virtual double NearestNeighbourDistance(const int & ii) const = 0; + + /// Returns true iff the given index corresponds to a point that + /// exists in the DNN structure (meaning that it has been added, and + /// not removed in the meantime) + virtual bool Valid(const int & index) const = 0; + + /// remove the points labelled by the std::vector indices_to_remove, and + /// add the points specified by the std::vector points_to_add + /// (corresponding indices will be calculated automatically); the + /// idea behind this routine is that the points to be added will + /// somehow be close to the one or other of the points being removed + /// and this can be used by the implementation to provide hints for + /// inserting the new points in whatever structure it is using. In a + /// kt-algorithm the points being added will be a result of a + /// combination of the points to be removed -- hence the proximity + /// is (more or less) guaranteed. + virtual void RemoveAndAddPoints(const std::vector & indices_to_remove, + const std::vector & points_to_add, + std::vector & indices_added, + std::vector & indices_of_updated_neighbours) = 0; + + + /// Remove the point labelled by index and return the list of + /// points whose nearest neighbours have changed in the process + inline void RemovePoint (const int & index, + std::vector & indices_of_updated_neighbours) { + std::vector indices_added; + std::vector points_to_add; + std::vector indices_to_remove(1); + indices_to_remove[0] = index; + RemoveAndAddPoints(indices_to_remove, points_to_add, indices_added, + indices_of_updated_neighbours + );}; + + + /// Removes the two points labelled by index1, index2 and adds in the + /// a point with coordinates newpoint; it returns an index for the new + /// point (index 3) and a std::vector of indices of neighbours whose + /// nearest neighbour has changed (the list includes index3, i.e. the new + /// point). + inline void RemoveCombinedAddCombination( + const int & index1, const int & index2, + const EtaPhi & newpoint, + int & index3, + std::vector & indices_of_updated_neighbours) { + std::vector indices_added(1); + std::vector points_to_add(1); + std::vector indices_to_remove(2); + indices_to_remove[0] = index1; + indices_to_remove[1] = index2; + points_to_add[0] = newpoint; + RemoveAndAddPoints(indices_to_remove, points_to_add, indices_added, + indices_of_updated_neighbours + ); + index3 = indices_added[0]; + }; + + /// destructor -- here it is now implemented + virtual ~DynamicNearestNeighbours () {} +}; + + +} // fastjet namespace + +#endif // __FASTJET_DYNAMICNEARESTNEIGHBOURS_HH__ diff --git a/JETAN/fastjet/fastjet/internal/LimitedWarning.hh b/JETAN/fastjet/fastjet/internal/LimitedWarning.hh new file mode 100644 index 00000000000..3dc82c0281e --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/LimitedWarning.hh @@ -0,0 +1,66 @@ +//STARTHEADER +// $Id: LimitedWarning.hh 699 2007-06-04 20:20:42Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_LIMITEDWARNING_HH__ +#define __FASTJET_LIMITEDWARNING_HH__ + +#include +#include + +/// class to provide facilities for giving warnings up to some maximum +/// number of times +class LimitedWarning { +public: + + /// constructor that provides a default maximum number of warnings + LimitedWarning() : _max_warn(_max_warn_default), _n_warn_so_far(0) {} + + /// constructor that provides a used-set max number of warnings + LimitedWarning(int max_warn) : _max_warn(max_warn), _n_warn_so_far(0) {} + + /// output a warning to ostr + void warn(const std::string & warning, std::ostream & ostr = std::cerr) { + if (_n_warn_so_far < _max_warn) { + ostr << "WARNING: "; + ostr << warning; + _n_warn_so_far++; + if (_n_warn_so_far == _max_warn) ostr << " (LAST SUCH WARNING)"; + ostr << std::endl; + } + } + +private: + int _max_warn, _n_warn_so_far; + static const int _max_warn_default = 5; + +}; + +#endif // __FASTJET_LIMITEDWARNING_HH__ diff --git a/JETAN/fastjet/fastjet/internal/MinHeap.hh b/JETAN/fastjet/fastjet/internal/MinHeap.hh new file mode 100644 index 00000000000..6f4b9baca2b --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/MinHeap.hh @@ -0,0 +1,90 @@ +//STARTHEADER +// $Id: MinHeap.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_MINHEAP__HH__ +#define __FASTJET_MINHEAP__HH__ + +#include +#include +#include +#include +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +//====================================================================== +/// A class which provides a "heap"-like structure that allows +/// access to a the minimal value of a dynamically changing set of numbers +class MinHeap { +public: + /// construct a MinHeap from the vector of values, allowing future + /// expansion to a maximum size max_size; + MinHeap (const std::vector & values, unsigned int max_size) : + _heap(max_size) {_initialise(values);}; + + /// constructor in which the the maximum size is the size of the values array + MinHeap (const std::vector & values) : + _heap(values.size()) {_initialise(values);}; + + /// return the location of the minimal value on the heap + inline unsigned int minloc() const { + return (_heap[0].minloc) - &(_heap[0]);}; + + /// return the minimal value on the heap + inline double minval() const {return _heap[0].minloc->value;}; + + inline double operator[](int i) const {return _heap[i].value;}; + + /// remove the value at the specified location (i.e. replace it with + /// the largest possible value). + void remove(unsigned int loc) { + update(loc,std::numeric_limits::max());}; + + /// update the value at the specified location + void update(unsigned int, double); + +private: + + struct ValueLoc{ + double value; + ValueLoc * minloc; + }; + + std::vector _heap; + + void _initialise(const std::vector & values); + + +}; + + +} // fastjet namespace + +#endif // __FASTJET_MINHEAP__HH__ diff --git a/JETAN/fastjet/fastjet/internal/SearchTree.hh b/JETAN/fastjet/fastjet/internal/SearchTree.hh new file mode 100644 index 00000000000..93841dda6aa --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/SearchTree.hh @@ -0,0 +1,751 @@ +//STARTHEADER +// $Id: SearchTree.hh 1203 2008-04-28 16:10:36Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef __FASTJET_SEARCHTREE_HH__ +#define __FASTJET_SEARCHTREE_HH__ + +#include +#include +#include +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + + +//====================================================================== +/// This is the class for a search tree designed to be especially efficient +/// when looking for successors and predecessors (to be used in Chan's +/// CP algorithm). It has the requirement that the maximum size of the +/// search tree must be known in advance. +template class SearchTree { +public: + + class Node; + class circulator; + class const_circulator; + + /// constructor for a search tree from an ordered vector + SearchTree(const std::vector & init); + + /// constructor for a search tree from an ordered vector allowing + /// for future growth beyond the current size, up to max_size + SearchTree(const std::vector & init, unsigned int max_size); + + /// remove the node corresponding to node_index from the search tree + void remove(unsigned node_index); + void remove(typename SearchTree::Node * node); + void remove(typename SearchTree::circulator & circ); + + /// insert the supplied value into the tree and return a pointer to + /// the relevant SearchTreeNode. + //Node * insert(const T & value); + circulator insert(const T & value); + + const Node & operator[](int i) const {return _nodes[i];}; + + /// return the number of elements currently in the search tree + unsigned int size() const {return _nodes.size() - _available_nodes.size();} + + /// check that the structure we've obtained makes sense... + void verify_structure(); + void verify_structure_linear() const; + void verify_structure_recursive(const Node * , const Node * , const Node * ) const; + + /// print out all elements... + void print_elements(); + + // tracking the depth may have some speed overhead -- so leave it + // out for the time being... +#ifdef TRACK_DEPTH + /// the max depth the tree has ever reached + inline unsigned int max_depth() const {return _max_depth;}; +#else + inline unsigned int max_depth() const {return 0;}; +#endif + + int loc(const Node * node) const ; + + /// return predecessor by walking through the tree + Node * _find_predecessor(const Node *); + /// return successor by walking through the tree + Node * _find_successor(const Node *); + + const Node & operator[](unsigned int i) const {return _nodes[i];}; + + /// return a circulator to some place in the tree (with a circulator + /// you don't care where...) + const_circulator somewhere() const; + circulator somewhere(); + +private: + + void _initialize(const std::vector & init); + + std::vector _nodes; + std::vector _available_nodes; + Node * _top_node; + unsigned int _n_removes; + + + /// recursive routine for doing the initial connections assuming things + /// are ordered. Assumes this_one's parent is labelled, and was + /// generated at a scale "scale" -- connections will be carried out + /// including left edge and excluding right edge + void _do_initial_connections(unsigned int this_one, unsigned int scale, + unsigned int left_edge, unsigned int right_edge, + unsigned int depth); + + +#ifdef TRACK_DEPTH + unsigned int _max_depth; +#endif + +}; + + +//====================================================================== +template class SearchTree::Node{ +public: + Node() {}; /// default constructor + + + /// returns tree if all the tree-related links are set to null for this node + bool treelinks_null() const { + return ((parent==0) && (left==0) && (right==0));}; + + /// set all the tree-related links are set to null for this node + inline void nullify_treelinks() { + parent = NULL; + left = NULL; + right = NULL; + }; + + /// if my parent exists, determine whether I am it's left or right + /// node and set the relevant link equal to XX. + void reset_parents_link_to_me(Node * XX); + + T value; + Node * left; + Node * right; + Node * parent; + Node * successor; + Node * predecessor; +}; + +//---------------------------------------------------------------------- +template void SearchTree::Node::reset_parents_link_to_me(typename SearchTree::Node * XX) { + if (parent == NULL) {return;} + if (parent->right == this) {parent->right = XX;} + else {parent->left = XX;} +} + + + +//====================================================================== +template class SearchTree::circulator{ +public: + + // so that it can access out _node object; + friend class SearchTree::const_circulator; + friend class SearchTree; + + circulator() : _node(NULL) {} + + circulator(Node * node) : _node(node) {} + + const T * operator->() const {return &(_node->value);} + T * operator->() {return &(_node->value);} + const T & operator*() const {return _node->value;} + T & operator*() {return _node->value;} + + /// prefix increment (structure copied from stl_bvector.h) + circulator & operator++() { + _node = _node->successor; + return *this;} + + /// postfix increment ["int" argument tells compiler it's postfix] + /// (structure copied from stl_bvector.h) + circulator operator++(int) { + circulator tmp = *this; + _node = _node->successor; + return tmp;} + + /// prefix decrement (structure copied from stl_bvector.h) + circulator & operator--() { + _node = _node->predecessor; + return *this;} + + /// postfix decrement ["int" argument tells compiler it's postfix] + /// (structure copied from stl_bvector.h) + circulator operator--(int) { + circulator tmp = *this; + _node = _node->predecessor; + return tmp;} + + /// return a circulator referring to the next node + circulator next() const { + return circulator(_node->successor);} + + /// return a circulator referring to the previous node + circulator previous() const { + return circulator(_node->predecessor);} + + bool operator!=(const circulator & other) const {return other._node != _node;} + bool operator==(const circulator & other) const {return other._node == _node;} + +private: + Node * _node; +}; + + +//====================================================================== +template class SearchTree::const_circulator{ +public: + + const_circulator() : _node(NULL) {} + + const_circulator(const Node * node) : _node(node) {} + const_circulator(const circulator & circ) :_node(circ._node) {} + + const T * operator->() {return &(_node->value);} + const T & operator*() const {return _node->value;} + + /// prefix increment (structure copied from stl_bvector.h) + const_circulator & operator++() { + _node = _node->successor; + return *this;} + + /// postfix increment ["int" argument tells compiler it's postfix] + /// (structure copied from stl_bvector.h) + const_circulator operator++(int) { + const_circulator tmp = *this; + _node = _node->successor; + return tmp;} + + + /// prefix decrement (structure copied from stl_bvector.h) + const_circulator & operator--() { + _node = _node->predecessor; + return *this;} + + /// postfix decrement ["int" argument tells compiler it's postfix] + /// (structure copied from stl_bvector.h) + const_circulator operator--(int) { + const_circulator tmp = *this; + _node = _node->predecessor; + return tmp;} + + /// return a circulator referring to the next node + const_circulator next() const { + return const_circulator(_node->successor);} + + /// return a circulator referring to the previous node + const_circulator previous() const { + return const_circulator(_node->predecessor);} + + + + bool operator!=(const const_circulator & other) const {return other._node != _node;} + bool operator==(const const_circulator & other) const {return other._node == _node;} + +private: + const Node * _node; +}; + + + + +//---------------------------------------------------------------------- +/// initialise from a sorted initial array allowing for a larger +/// maximum size of the array... +template SearchTree::SearchTree(const std::vector & init, + unsigned int max_size) : + _nodes(max_size) { + + _available_nodes.reserve(max_size); + _available_nodes.resize(max_size - init.size()); + for (unsigned int i = init.size(); i < max_size; i++) { + _available_nodes[i-init.size()] = &(_nodes[i]); + } + + _initialize(init); +} + +//---------------------------------------------------------------------- +/// initialise from a sorted initial array +template SearchTree::SearchTree(const std::vector & init) : + _nodes(init.size()), _available_nodes(0) { + + // reserve space for the list of available nodes + _available_nodes.reserve(init.size()); + _initialize(init); +} + +//---------------------------------------------------------------------- +/// do the actual hard work of initialization +template void SearchTree::_initialize(const std::vector & init) { + + _n_removes = 0; + unsigned n = init.size(); + assert(n>=1); + + // reserve space for the list of available nodes + //_available_nodes.reserve(); + +#ifdef TRACK_DEPTH + _max_depth = 0; +#endif + + + // validate the input + for (unsigned int i = 1; i inline int SearchTree::loc(const Node * node) const {return node == NULL? + -999 : node - &(_nodes[0]);} + + +//---------------------------------------------------------------------- +/// Recursive creation of connections, assuming the _nodes vector is +/// completely filled and ordered +template void SearchTree::_do_initial_connections( + unsigned int this_one, + unsigned int scale, + unsigned int left_edge, + unsigned int right_edge, + unsigned int depth + ) { + +#ifdef TRACK_DEPTH + // keep track of tree depth for checking things stay reasonable... + _max_depth = max(depth, _max_depth); +#endif + + //std::cout << this_one << " "<< scale<< std::endl; + unsigned int ref_new_scale = (scale+1)/2; + + // work through children to our left + unsigned new_scale = ref_new_scale; + bool did_child = false; + while(true) { + int left = this_one - new_scale; // be careful here to use signed int... + // if there is something unitialised to our left, link to it + if (left >= static_cast(left_edge) + && _nodes[left].treelinks_null() ) { + _nodes[left].parent = &(_nodes[this_one]); + _nodes[this_one].left = &(_nodes[left]); + // create connections between left_edge and this_one + _do_initial_connections(left, new_scale, left_edge, this_one, depth+1); + did_child = true; + break; + } + // reduce the scale so as to try again + unsigned int old_new_scale = new_scale; + new_scale = (old_new_scale + 1)/2; + // unless we've reached end of tree + if (new_scale == old_new_scale) break; + } + if (!did_child) {_nodes[this_one].left = NULL;} + + + // work through children to our right + new_scale = ref_new_scale; + did_child = false; + while(true) { + unsigned int right = this_one + new_scale; + if (right < right_edge && _nodes[right].treelinks_null()) { + _nodes[right].parent = &(_nodes[this_one]); + _nodes[this_one].right = &(_nodes[right]); + // create connections between this_one+1 and right_edge + _do_initial_connections(right, new_scale, this_one+1,right_edge,depth+1); + did_child = true; + break; + } + // reduce the scale so as to try again + unsigned int old_new_scale = new_scale; + new_scale = (old_new_scale + 1)/2; + // unless we've reached end of tree + if (new_scale == old_new_scale) break; + } + if (!did_child) {_nodes[this_one].right = NULL;} + +} + + + +//---------------------------------------------------------------------- +template void SearchTree::remove(unsigned int node_index) { + remove(&(_nodes[node_index])); +} + +//---------------------------------------------------------------------- +template void SearchTree::remove(circulator & circ) { + remove(circ._node); +} + +//---------------------------------------------------------------------- +// Useful reference for this: +// http://en.wikipedia.org/wiki/Binary_search_tree#Deletion +template void SearchTree::remove(typename SearchTree::Node * node) { + + // we don't remove things from the tree if we've reached the last + // elements... (is this wise?) + assert(size() > 1); // switch this to throw...? + assert(!node->treelinks_null()); + + // deal with relinking predecessor and successor + node->predecessor->successor = node->successor; + node->successor->predecessor = node->predecessor; + + if (node->left == NULL && node->right == NULL) { + // node has no children, so remove it by nullifying the pointer + // from the parent + node->reset_parents_link_to_me(NULL); + + } else if (node->left != NULL && node->right == NULL){ + // make parent point to my child + node->reset_parents_link_to_me(node->left); + // and child to parent + node->left->parent = node->parent; + // sort out the top node... + if (_top_node == node) {_top_node = node->left;} + + } else if (node->left == NULL && node->right != NULL){ + // make parent point to my child + node->reset_parents_link_to_me(node->right); + // and child to parent + node->right->parent = node->parent; + // sort out the top node... + if (_top_node == node) {_top_node = node->right;} + + } else { + // we have two children; we will put a replacement in our place + Node * replacement; + //SearchTree::Node * replacements_child; + // chose predecessor or successor (one, then other, then first, etc...) + bool use_predecessor = (_n_removes % 2 == 1); + if (use_predecessor) { + // Option 1: put predecessor in our place, and have its parent + // point to its left child (as a predecessor it has no right child) + replacement = node->predecessor; + assert(replacement->right == NULL); // guaranteed if it's our predecessor + // we have to be careful of replacing certain links when the + // replacement is this node's child + if (replacement != node->left) { + if (replacement->left != NULL) { + replacement->left->parent = replacement->parent;} + replacement->reset_parents_link_to_me(replacement->left); + replacement->left = node->left; + } + replacement->parent = node->parent; + replacement->right = node->right; + } else { + // Option 2: put successor in our place, and have its parent + // point to its right child (as a successor it has no left child) + replacement = node->successor; + assert(replacement->left == NULL); // guaranteed if it's our successor + if (replacement != node->right) { + if (replacement->right != NULL) { + replacement->right->parent = replacement->parent;} + replacement->reset_parents_link_to_me(replacement->right); + replacement->right = node->right; + } + replacement->parent = node->parent; + replacement->left = node->left; + } + node->reset_parents_link_to_me(replacement); + + // make sure node's original children now point to the replacement + if (node->left != replacement) {node->left->parent = replacement;} + if (node->right != replacement) {node->right->parent = replacement;} + + // sort out the top node... + if (_top_node == node) {_top_node = replacement;} + } + + // make sure we leave something nice and clean... + node->nullify_treelinks(); + node->predecessor = NULL; + node->successor = NULL; + + // for bookkeeping (and choosing whether to use pred. or succ.) + _n_removes++; + // for when we next need access to a free node... + _available_nodes.push_back(node); +} + + +//---------------------------------------------------------------------- +//template typename SearchTree::Node * SearchTree::insert(const T & value) { + +//---------------------------------------------------------------------- +template typename SearchTree::circulator SearchTree::insert(const T & value) { + // make sure we don't exceed allowed number of nodes... + assert(_available_nodes.size() > 0); + + Node * node = _available_nodes.back(); + _available_nodes.pop_back(); + node->value = value; + + Node * location = _top_node; + Node * old_location = NULL; + bool on_left = true; // (init not needed -- but soothes g++4) + // work through tree until we reach its end +#ifdef TRACK_DEPTH + unsigned int depth = 0; +#endif + while(location != NULL) { +#ifdef TRACK_DEPTH + depth++; +#endif + old_location = location; + on_left = value < location->value; + if (on_left) {location = location->left;} + else {location = location->right;} + } +#ifdef TRACK_DEPTH + _max_depth = max(depth, _max_depth); +#endif + // now create tree links + node->parent = old_location; + if (on_left) {node->parent->left = node;} + else {node->parent->right = node;} + node->left = NULL; + node->right = NULL; + // and create predecessor / successor links + node->predecessor = _find_predecessor(node); + if (node->predecessor != NULL) { + // it exists, so make use of its info (will include a cyclic case, + // when successor is round the bend) + node->successor = node->predecessor->successor; + node->predecessor->successor = node; + node->successor->predecessor = node; + } else { + // deal with case when we are left-most edge of tree (then successor + // will exist...) + node->successor = _find_successor(node); + assert(node->successor != NULL); // can only happen if we're sole element + // (but not allowed, since tree size>=1) + node->predecessor = node->successor->predecessor; + node->successor->predecessor = node; + node->predecessor->successor = node; + } + + return circulator(node); +} + + +//---------------------------------------------------------------------- +template void SearchTree::verify_structure() { + + // do a check running through all elements + verify_structure_linear(); + + // do a recursive check down tree from top + + // first establish the extremities + const Node * left_limit = _top_node; + while (left_limit->left != NULL) {left_limit = left_limit->left;} + const Node * right_limit = _top_node; + while (right_limit->right != NULL) {right_limit = right_limit->right;} + + // then actually do recursion + verify_structure_recursive(_top_node, left_limit, right_limit); +} + + +//---------------------------------------------------------------------- +template void SearchTree::verify_structure_recursive( + const typename SearchTree::Node * element, + const typename SearchTree::Node * left_limit, + const typename SearchTree::Node * right_limit) const { + + assert(!(element->value < left_limit->value)); + assert(!(right_limit->value < element->value)); + + const Node * left = element->left; + if (left != NULL) { + assert(!(element->value < left->value)); + if (left != left_limit) { + // recurse down the tree with this element as the right-hand limit + verify_structure_recursive(left, left_limit, element);} + } + + const Node * right = element->right; + if (right != NULL) { + assert(!(right->value < element->value)); + if (right != right_limit) { + // recurse down the tree with this element as the left-hand limit + verify_structure_recursive(right, element, right_limit);} + } +} + +//---------------------------------------------------------------------- +template void SearchTree::verify_structure_linear() const { + + //print_elements(); + + unsigned n_top = 0; + unsigned n_null = 0; + for(unsigned i = 0; i < _nodes.size(); i++) { + const typename SearchTree::Node * node = &(_nodes[i]); + // make sure node is defined + if (node->treelinks_null()) {n_null++; continue;} + + // make sure of the number of "top" nodes + if (node->parent == NULL) { + n_top++; + //assert(node->left != NULL); + //assert(node->right != NULL); + } else { + // make sure that I am a child of my parent... + //assert((node->parent->left == node) || (node->parent->right == node)); + assert((node->parent->left == node) ^ (node->parent->right == node)); + } + + // when there is a left child make sure it's value is ordered + // (note use of !(bleft != NULL) { + assert(!(node->value < node->left->value ));} + + // when there is a right child make sure it's value is ordered + if (node->right != NULL) { + assert(!(node->right->value < node->value ));} + + } + assert(n_top == 1 || (n_top == 0 && size() <= 1) ); + assert(n_null == _available_nodes.size() || + (n_null == _available_nodes.size() + 1 && size() == 1)); +} + + +//---------------------------------------------------------------------- +template typename SearchTree::Node * SearchTree::_find_predecessor(const typename SearchTree::Node * node) { + + typename SearchTree::Node * newnode; + if (node->left != NULL) { + // go down left, and then down right as far as possible. + newnode = node->left; + while(newnode->right != NULL) {newnode = newnode->right;} + return newnode; + } else { + const typename SearchTree::Node * lastnode = node; + newnode = node->parent; + // go up the tree as long as we're going right (when we go left then + // we've found something smaller, so stop) + while(newnode != NULL) { + if (newnode->right == lastnode) {return newnode;} + lastnode = newnode; + newnode = newnode->parent; + } + return newnode; + } +} + + +//---------------------------------------------------------------------- +template typename SearchTree::Node * SearchTree::_find_successor(const typename SearchTree::Node * node) { + + typename SearchTree::Node * newnode; + if (node->right != NULL) { + // go down right, and then down left as far as possible. + newnode = node->right; + while(newnode->left != NULL) {newnode = newnode->left;} + return newnode; + } else { + const typename SearchTree::Node * lastnode = node; + newnode = node->parent; + // go up the tree as long as we're going left (when we go right then + // we've found something larger, so stop) + while(newnode != NULL) { + if (newnode->left == lastnode) {return newnode;} + lastnode = newnode; + newnode = newnode->parent; + } + return newnode; + } +} + + +//---------------------------------------------------------------------- +// print out all the elements for visual checking... +template void SearchTree::print_elements() { + typename SearchTree::Node * base_node = &(_nodes[0]); + typename SearchTree::Node * node = base_node; + + int n = _nodes.size(); + for(; node - base_node < n ; node++) { + printf("%4d parent:%4d left:%4d right:%4d pred:%4d succ:%4d value:%10.6f\n",loc(node), loc(node->parent), loc(node->left), loc(node->right), loc(node->predecessor),loc(node->successor),node->value); + } +} + +//---------------------------------------------------------------------- +template typename SearchTree::circulator SearchTree::somewhere() { + return circulator(_top_node); +} + + +//---------------------------------------------------------------------- +template typename SearchTree::const_circulator SearchTree::somewhere() const { + return const_circulator(_top_node); +} + + +} // fastjet namespace + +#endif // __FASTJET_SEARCHTREE_HH__ diff --git a/JETAN/fastjet/fastjet/internal/Triangulation.hh b/JETAN/fastjet/fastjet/internal/Triangulation.hh new file mode 100644 index 00000000000..4418dce5f6c --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/Triangulation.hh @@ -0,0 +1,100 @@ +//STARTHEADER +// $Id: Triangulation.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + +#ifndef DROP_CGAL // in case we do not have the code for CGAL +#ifndef __FASTJET_TRIANGULATION__ +#define __FASTJET_TRIANGULATION__ + +// file: examples/Triangulation_2/Voronoi.C +#include +#include +#include +#include +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +/// the basic geometrical kernel that lies at the base of all CGAL +/// operations +#ifdef CGAL_SIMPLE_KERNEL +struct K : CGAL::Simple_cartesian {}; +#else +struct K : CGAL::Exact_predicates_inexact_constructions_kernel {}; +#endif // CGAL_SIMPLE_KERNEL + +// our extras to help us navigate, find distance, etc. +const int INFINITE_VERTEX=-1; +const int NEW_VERTEX=-2; +const double HUGE_DOUBLE=1e300; + +/// A class to provide an "int" with an initial value. +class InitialisedInt { + private: + int _val; + public: + inline InitialisedInt () {_val=NEW_VERTEX;}; + inline InitialisedInt& operator= (int value) {_val = value; return *this;}; + inline int val() const {return _val;}; +}; + + +// We can have triangulations with and without hierarchies -- those with +// are able to guarantee N ln N time for the construction of a large +// triangulation, whereas those without go as N^{3/2} for points +// sufficiently uniformly distributed in a plane. +// +//#define NOHIERARCHY +#ifdef NOHIERARCHY +typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; +typedef CGAL::Triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Delaunay_triangulation_2 Triangulation; +#else +typedef CGAL::Triangulation_vertex_base_with_info_2 Vbb; +typedef CGAL::Triangulation_hierarchy_vertex_base_2 Vb; +typedef CGAL::Triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Delaunay_triangulation_2 Dt; +typedef CGAL::Triangulation_hierarchy_2
Triangulation; +#endif + +typedef Triangulation::Vertex_handle Vertex_handle; +typedef Triangulation::Point Point; /// CGAL Point structure +typedef Triangulation::Vertex_circulator Vertex_circulator; +typedef Triangulation::Face_circulator Face_circulator; +typedef Triangulation::Face_handle Face_handle; + + + +} // fastjet namespace + +#endif // __FASTJET_TRIANGULATION__ +#endif // DROP_CGAL diff --git a/JETAN/fastjet/fastjet/internal/Voronoi.hh b/JETAN/fastjet/fastjet/internal/Voronoi.hh new file mode 100644 index 00000000000..5e664be8925 --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/Voronoi.hh @@ -0,0 +1,320 @@ +#ifndef __FASTJET__VORONOI_H__ +#define __FASTJET__VORONOI_H__ + +//STARTHEADER +// $Id: Voronoi.hh 1161 2008-04-01 20:29:38Z soyez $ +// +// Copyright (c) 1994 by AT&T Bell Laboratories (see below) +// +// +//---------------------------------------------------------------------- +// This file is included as part of FastJet but was mostly written by +// S. Fortune in C, put into C++ with memory management by S +// O'Sullivan, and with further interface and memeory management +// modifications by Gregory Soyez. +// +// Permission to use, copy, modify, and distribute this software for +// any purpose without fee is hereby granted, provided that this +// entire notice is included in all copies of any software which is or +// includes a copy or modification of this software and in all copies +// of the supporting documentation for such software. THIS SOFTWARE IS +// BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY. +// IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY REPRESENTATION +// OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS +// SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. +// +//---------------------------------------------------------------------- +//ENDHEADER + + +/* +* The author of this software is Steven Fortune. +* Copyright (c) 1994 by AT&T Bell Laboratories. +* Permission to use, copy, modify, and distribute this software for any +* purpose without fee is hereby granted, provided that this entire notice +* is included in all copies of any software which is or includes a copy +* or modification of this software and in all copies of the supporting +* documentation for such software. +* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY +* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY +* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. +*/ + +/* +* This code was originally written by Stephan Fortune in C code. I, +* Shane O'Sullivan, have since modified it, encapsulating it in a C++ +* class and, fixing memory leaks and adding accessors to the Voronoi +* Edges. Permission to use, copy, modify, and distribute this +* software for any purpose without fee is hereby granted, provided +* that this entire notice is included in all copies of any software +* which is or includes a copy or modification of this software and in +* all copies of the supporting documentation for such software. THIS +* SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY +* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE +* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR +* PURPOSE. +*/ + +#include "fastjet/ClusterSequenceWithArea.hh" +#include +#include +#include +#include + +#define DELETED -2 +#define le 0 +#define re 1 + +//using namespace std; + +namespace fastjet { // defined in fastjet/internal/base.hh + +/** + * \class Point + * class to handle a 2d point + */ +class Point{ +public: + /// defailt ctor + Point() : x(0.0), y(0.0) {} + + /// ctor with initialisation + Point(double _x, double _y) : x(_x), y(_y) {} + + /// addition + inline Point operator + (const Point &p) const{ + return Point(x+p.x, y+p.y); + } + + /// subtraction + inline Point operator - (const Point &p) const{ + return Point(x-p.x, y-p.y); + } + + /// scalar multiplication + inline Point operator * (const double t) const{ + return Point(x*t, y*t); + } + + /// vector coordinates + double x,y; +}; + + +/// norm of a vector +inline double norm(const Point p){ + return p.x*p.x+p.y*p.y; +} + + +/// 2D vector product +inline double vector_product(const Point &p1, const Point &p2){ + return p1.x*p2.y-p1.y*p2.x; +} + + +/// scalar product +inline double scalar_product(const Point &p1, const Point &p2){ + return p1.x*p2.x+p1.y*p2.y; +} + + +/** + * \class GraphEdge + * handle an edge of the Voronoi Diagram. + */ +class GraphEdge{ +public: + /// coordinates of the extreme points + double x1,y1,x2,y2; + + /// indices of the parent sites that define the edge + int point1, point2; + + /// pointer to the next edge + GraphEdge* next; +}; + + +/** + * \class Site + * structure used both for particle sites and for vertices. + */ +class Site{ + public: + Point coord; + int sitenbr; + int refcnt; +}; + + + +class Freenode{ +public: + Freenode *nextfree; +}; + + +class FreeNodeArrayList{ +public: + Freenode* memory; + FreeNodeArrayList* next; +}; + + +class Freelist{ +public: + Freenode *head; + int nodesize; +}; + +class Edge{ +public: + double a,b,c; + Site *ep[2]; + Site *reg[2]; + int edgenbr; +}; + + +class Halfedge{ +public: + Halfedge *ELleft, *ELright; + Edge *ELedge; + int ELrefcnt; + char ELpm; + Site *vertex; + volatile double ystar; + Halfedge *PQnext; +}; + + +class VoronoiDiagramGenerator{ +public: + VoronoiDiagramGenerator(); + ~VoronoiDiagramGenerator(); + + bool generateVoronoi(std::vector *_parent_sites, + double minX, double maxX, double minY, double maxY, + double minDist=0); + + inline void resetIterator(){ + iteratorEdges = allEdges; + } + + bool getNext(GraphEdge **e){ + if(iteratorEdges == 0) + return false; + + *e = iteratorEdges; + iteratorEdges = iteratorEdges->next; + return true; + } + + std::vector *parent_sites; + int n_parent_sites; + +private: + void cleanup(); + void cleanupEdges(); + char *getfree(Freelist *fl); + Halfedge *PQfind(); + int PQempty(); + + Halfedge **ELhash; + Halfedge *HEcreate(), *ELleft(), *ELright(), *ELleftbnd(); + Halfedge *HEcreate(Edge *e,int pm); + + Point PQ_min(); + Halfedge *PQextractmin(); + void freeinit(Freelist *fl,int size); + void makefree(Freenode *curr,Freelist *fl); + void geominit(); + void plotinit(); + bool voronoi(int triangulate); + void ref(Site *v); + void deref(Site *v); + void endpoint(Edge *e,int lr,Site * s); + + void ELdelete(Halfedge *he); + Halfedge *ELleftbnd(Point *p); + Halfedge *ELright(Halfedge *he); + void makevertex(Site *v); + void out_triple(Site *s1, Site *s2,Site * s3); + + void PQinsert(Halfedge *he,Site * v, double offset); + void PQdelete(Halfedge *he); + bool ELinitialize(); + void ELinsert(Halfedge *lb, Halfedge *newHe); + Halfedge * ELgethash(int b); + Halfedge *ELleft(Halfedge *he); + Site *leftreg(Halfedge *he); + void out_site(Site *s); + bool PQinitialize(); + int PQbucket(Halfedge *he); + void clip_line(Edge *e); + char *myalloc(unsigned n); + int right_of(Halfedge *el,Point *p); + + Site *rightreg(Halfedge *he); + Edge *bisect(Site *s1, Site *s2); + double dist(Site *s,Site *t); + Site *intersect(Halfedge *el1, Halfedge *el2, Point *p=0); + + void out_bisector(Edge *e); + void out_ep(Edge *e); + void out_vertex(Site *v); + Site *nextone(); + + void pushGraphEdge(double x1, double y1, double x2, double y2, + Site *s1, Site *s2); + + void openpl(); + void circle(double x, double y, double radius); + void range(double minX, double minY, double maxX, double maxY); + + Freelist hfl; + Halfedge *ELleftend, *ELrightend; + int ELhashsize; + + int triangulate, sorted, plot, debug; + double xmin, xmax, ymin, ymax, deltax, deltay; + + Site *sites; + int nsites; + int siteidx; + int sqrt_nsites; + int nvertices; + Freelist sfl; + Site *bottomsite; + + int nedges; + Freelist efl; + int PQhashsize; + Halfedge *PQhash; + int PQcount; + int PQmin; + + int ntry, totalsearch; + double pxmin, pxmax, pymin, pymax, cradius; + int total_alloc; + + double borderMinX, borderMaxX, borderMinY, borderMaxY; + + FreeNodeArrayList* allMemoryList; + FreeNodeArrayList* currentMemoryBlock; + + GraphEdge* allEdges; + GraphEdge* iteratorEdges; + + double minDistanceBetweenSites; +}; + +int scomp(const void *p1,const void *p2); + + +} // fastjet namespace + +#endif diff --git a/JETAN/fastjet/fastjet/internal/base.hh b/JETAN/fastjet/fastjet/internal/base.hh new file mode 100644 index 00000000000..f68b44290cc --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/base.hh @@ -0,0 +1,40 @@ + +//STARTHEADER +// $Id: base.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_FASTJET_BASE_HH__ +#define __FASTJET_FASTJET_BASE_HH__ + +// define this for easier readability (and obfuscation?) in +// a range of places +// #define FASTJET_BEGIN_NAMESPACE namespace fastjet { +// #define FASTJET_END_NAMESPACE } + +#endif // __FASTJET_FASTJET_BASE_HH__ diff --git a/JETAN/fastjet/fastjet/internal/numconsts.hh b/JETAN/fastjet/fastjet/internal/numconsts.hh new file mode 100644 index 00000000000..3844459770f --- /dev/null +++ b/JETAN/fastjet/fastjet/internal/numconsts.hh @@ -0,0 +1,53 @@ +//STARTHEADER +// $Id: numconsts.hh 293 2006-08-17 19:38:38Z salam $ +// +// Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + + + +#ifndef __FASTJET_NUMCONSTS__ +#define __FASTJET_NUMCONSTS__ + +#include "fastjet/internal/base.hh" + +namespace fastjet { // defined in fastjet/internal/base.hh + +// some common useful constants! + +const double pi = 3.141592653589793238462643383279502884197; +const double twopi = 6.283185307179586476925286766559005768394; +const double pisq = 9.869604401089358618834490999876151135314; +const double zeta2 = 1.644934066848226436472415166646025189219; +const double zeta3 = 1.202056903159594285399738161511449990765; +const double eulergamma = 0.577215664901532860606512090082402431042; +const double ln2 = 0.693147180559945309417232121458176568076; + + +} // fastjet namespace + +#endif // __FASTJET_NUMCONSTS__ diff --git a/JETAN/fastjet/fastjet/version.hh b/JETAN/fastjet/fastjet/version.hh new file mode 100644 index 00000000000..178fac2dcc1 --- /dev/null +++ b/JETAN/fastjet/fastjet/version.hh @@ -0,0 +1,43 @@ +//STARTHEADER +// $Id: version.hh 939 2007-11-08 12:18:08Z salam $ +// +// Copyright (c) 2005-2007, Matteo Cacciari and Gavin Salam +// +//---------------------------------------------------------------------- +// This file is part of FastJet. +// +// FastJet is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// The algorithms that underlie FastJet have required considerable +// development and are described in hep-ph/0512210. If you use +// FastJet as part of work towards a scientific publication, please +// include a citation to the FastJet paper. +// +// FastJet is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FastJet; if not, write to the Free Software +// Foundation, Inc.: +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//---------------------------------------------------------------------- +//ENDHEADER + +#ifndef __FASTJET_VERSION_HH__ +#define __FASTJET_VERSION_HH__ + +#include +#include "fastjet/config.h" + +namespace fastjet { + +const char* fastjet_version = PACKAGE_VERSION; + +} // fastjet namespace + +#endif // __FASTJET_VERSION_HH__ diff --git a/JETAN/fastjet/siscone/area.h b/JETAN/fastjet/siscone/area.h new file mode 100644 index 00000000000..4ceb3c2b219 --- /dev/null +++ b/JETAN/fastjet/siscone/area.h @@ -0,0 +1,139 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: area.h // +// Description: header file for the computation of jet area // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 149 $// +// $Date:: 2007-03-15 00:13:58 +0100 (Thu, 15 Mar 2007) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SISCONE_AREA_H__ +#define __SISCONE_AREA_H__ + +#include "momentum.h" +#include "siscone.h" + +namespace siscone{ + +/** + * \class Cjet_area + * real Jet information, including its area(s) + * + * This class contains information for one single jet. + * That is, first, its momentum carrying information + * about its centre and pT, and second, its particle + * contents. + * Compared to the Cjet class, it also includes the + * passive and active areas of the jet computed using + * the Carea class. + */ +class Cjet_area : public Cjet{ + public: + /// default ctor + Cjet_area(); + + /// jet-initialised ctor + Cjet_area(Cjet &j); + + /// default dtor + ~Cjet_area(); + + // area information + double passive_area; ///< passive area + double active_area; ///< active area +}; + +/** + * \class Carea + * class for the computation of jet areas. + * + * This is the class user should use whenever you want to compute + * the jet area (passive and active). . + * It uses the SISCone algorithm to perform the jet analysis. + */ +class Carea : public Csiscone{ + public: + /// default ctor + Carea(); + + /// default dtor + ~Carea(); + + /** + * compute the jet areas from a given particle set. + * The parameters of this method are the ones which control the jet clustering alghorithn. + * Note that the pt_min is not allowed here soince the jet-area determination involves soft + * particles/jets and thus is used internally. + * \param _particles list of particles + * \param _radius cone radius + * \param _f shared energy threshold for splitting&merging + * \param _n_pass_max maximum number of passes (0=full search, the default) + * \param _split_merge_scale the scale choice for the split-merge procedure + * NOTE: SM_pt leads to IR unsafety for some events with momentum conservation. + * SM_Et is IR safe but not boost invariant and not implemented(!) + * SM_mt is IR safe for hadronic events, but not for decays of two + * back-to-back particles of identical mass + * SM_pttilde + * is always IR safe, and also boost invariant (default) + * \param _hard_only when this is set on, only hard jets are computed + * and not the purely ghosted jets (default: false) + * \return the number of jets (including pure-ghost ones if they are included) + */ + int compute_areas(std::vector &_particles, double _radius, double _f, + int _n_pass_max=0, Esplit_merge_scale _split_merge_scale=SM_pttilde, + bool _hard_only=false); + + /** + * compute the jet active areas from a given particle set. + * The parameters of this method are the ones which control the jet clustering alghorithn. + * Note that the pt_min is not allowed here soince the jet-area determination involves soft + * particles/jets and thus is used internally. + * See compute_areas for paramters definition. + * \return the number of jets (including pure-ghost ones if they are included) + */ + int compute_active_areas(std::vector &_particles, double _radius, double _f, + int _n_pass_max=0, Esplit_merge_scale _split_merge_scale=SM_pttilde, + bool _hard_only=false); + + /** + * compute the jet passive areas from a given particle set. + * The parameters of this method are the ones which control the jet clustering alghorithn. + * Note that the pt_min is not allowed here soince the jet-area determination involves soft + * particles/jets and thus is used internally. + * See compute_areas for paramters definition. + */ + int compute_passive_areas(std::vector &_particles, double _radius, double _f, + int _n_pass_max=0, Esplit_merge_scale _split_merge_scale=SM_pttilde); + + int grid_size; ///< size of the grid we add soft particles on (N_soft=(grid_size^2)) + double grid_eta_max; ///< maximal value of eta we add soft particles on + double grid_shift; ///< fractional (random) displacement of the points om the grid + + double pt_soft; ///< pt of the soft particles added + double pt_shift; ///< amplitude of the pt random shift + double pt_soft_min; ///< pt_min used in SM to compute passive areas + + /// jets with their areas + std::vector jet_areas; +}; + +} +#endif diff --git a/JETAN/fastjet/siscone/circulator.h b/JETAN/fastjet/siscone/circulator.h new file mode 100644 index 00000000000..14f0aafc993 --- /dev/null +++ b/JETAN/fastjet/siscone/circulator.h @@ -0,0 +1,90 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: circulator.h // +// Description: header file for circulator (circulator class) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 103 $// +// $Date:: 2007-02-18 17:07:34 +0100 (Sun, 18 Feb 2007) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __CIRCULATOR_H__ +#define __CIRCULATOR_H__ + +namespace siscone{ + +/// \class circulator +/// a circulator that is foreseen to take as template member either a +/// pointer or an iterator; +template class circulator { + +public: + /// ctor with iniitalisation from iterators + /// \param here the current position + /// \param begin the first position + /// \param end the last position + inline circulator(T here, T begin, T end) : m_here(here), m_begin(begin), m_end(end) {} + + /// copy ctor + /// \param other the circulator to copy + inline circulator(const circulator & other) : m_here(other.m_here), m_begin(other.m_begin), m_end(other.m_end) {} + + /// set just the position without resetting the begin and end elements + /// \param other the circulator to grab position from + void set_position(const circulator & other) {m_here = other.m_here;} + + /// set just the position without resetting the begin and end elements + /// \param pointer the iterator to use as the new position + void set_position(T pointer) {m_here = pointer;} + + /// get the current object + T operator()() {return m_here;} + + /// position incrementation + inline circulator & operator++() { + ++m_here; + if (m_here == m_end) m_here = m_begin; + return *this; + } + + /// position decrementation + inline circulator & operator--() { + if (m_here == m_begin) m_here = m_end; + --m_here; + return *this; + } + + /// check if the current elements are the same + /// NB: for efficiency, this checks only the here element + /// \param other the circulator to compare to the current one + bool operator==(const circulator & other) const {return m_here == other.m_here;} + + /// check if the current elements are different + /// NB: for efficiency, this checks only the here element + /// \param other the circulator to compare to the current one + bool operator!=(const circulator & other) const {return m_here != other.m_here;} + +private: + T m_here, m_begin, m_end; ///< the current, beginning and ending iterators/pointers +}; + +} + +#endif // __CIRCULATOR_H__ diff --git a/JETAN/fastjet/siscone/config.h b/JETAN/fastjet/siscone/config.h new file mode 100644 index 00000000000..46660e40678 --- /dev/null +++ b/JETAN/fastjet/siscone/config.h @@ -0,0 +1,59 @@ +/* siscone/config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "siscone" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "SISCone" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "SISCone 2.0.0" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "siscone" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.0.0" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "2.0.0" diff --git a/JETAN/fastjet/siscone/defines.h b/JETAN/fastjet/siscone/defines.h new file mode 100644 index 00000000000..54c1f9c831c --- /dev/null +++ b/JETAN/fastjet/siscone/defines.h @@ -0,0 +1,128 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: defines.h // +// Description: header file for generic parameters definitions // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 225 $// +// $Date:: 2008-05-20 16:59:47 +0200 (Tue, 20 May 2008) $// +/////////////////////////////////////////////////////////////////////////////// + +//! \file defines.h +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +/// program name +// we get "SISCone" by calling +// siscone::siscone_package_name +// defined in siscone.h +// Otherwise, config.h +// It is also defined as "PACKAGE_NAME" in config.h but this method +// might lead to conflicts +//#define PROGRAM PACKAGE_NAME + +// program version +// we get it from +// siscone::siscone_version +// defined in siscone.h +// It is also defined as "VERSION" in config.h but this method +// might lead to conflicts + +/// perform final stability check using the quadtree +/// With the following define enabled, the final check for stability +/// is performed using the quadtree rather than the explicit list of +/// particles (see Cstable_cone::proceed_with_stability()) +//#define USE_QUADTREE_FOR_STABILITY_TEST + + +/// threshold for recomoutation of the cone (see Cstable_cones::update_cone()) +/// When traversing cone candidates along the angular ordering, +/// the momentum of the protojet candidate is computed incrementally +/// from the particles that enter and leave the cone. +/// When the cumulative change in "|px|+|py|" exceeds the cone "|px|+|py|" +/// we explicitely recompute the cone contents +#define PT_TSHOLD 1000.0 + + +/// The following parameter controls collinear safety. For the set of +/// particles used in the search of stable cones, we gather particles +/// if their distance in eta and phi is smaller than EPSILON_COLLINEAR. +/// +/// NB: for things to behave sensibly one requires +/// 1e-15 << EPSILON_COCIRCULAR << EPSILON_COLLINEAR << 1 +/// +/// among the scales that appear in practice (e.g. in deciding to use +/// special strategies), we have EPSILON_COLLINEAR, EPSILON_COCIRCULAR, +/// sqrt(EPSILON_COCIRCULAR) and EPSILON_COLLINEAR / EPSILON_COCIRCULAR. +/// +#define EPSILON_COLLINEAR 1e-8 + + +/// The following parameter controls cocircular situations. +/// When consecutive particles in the ordered vicinity list are separated +/// (in angle) by less that that limit, we consider that we face a situation +/// of cocircularity. +#define EPSILON_COCIRCULAR 1e-12 + + +/// The following define enables you to allow for identical protocones +/// to be merged automatically after each split-merge step before +/// anything else happens. Whether this happens depends on teh value +/// of the merge_identical_protocones flag in Csplit_merge. +/// +/// It we allow such a merging and define allow +/// MERGE_IDENTICAL_PROTOCONES_DEFAULT_TRUE then the +/// 'merge_identical_protocones' flag in Csplit_merge to be set to +/// 'true'. It may be manually reset to false in which case the +/// merging of identical protocones (protojets) will be turned off. +/// +/// Note that this merging identical protocones makes the algorithm +/// infrared-unsafe, so it should be disabled except for testing +/// purposes. +//#define ALLOW_MERGE_IDENTICAL_PROTOCONES +//#define MERGE_IDENTICAL_PROTOCONES_DEFAULT_TRUE + + +/// if EPSILON_SPLITMERGE is defined then, during the split-merge +/// step, when two jets are found with PTs that are identical to +/// within a relative difference of EPSILON_SPLITMERGE they are +/// compared element-by-element to see where the differences are, and +/// one then uses pt1^2-pt2^2 = (pt1-pt2).(pt1+pt2) as an estimator of +/// which is harder. NB: in unfortunate cases, this can take the split +/// merge step up to N n * ln N time, though on normal events there +/// don't seem to have been any major problems yet. +#define EPSILON_SPLITMERGE 1e-12 + +/// definition of 2*M_PI which is useful a bit everyhere! +const double twopi = 6.283185307179586476925286766559005768394; + +/// debugging information +//#define DEBUG_STABLE_CONES ///< debug messages in stable cones search +//#define DEBUG_SPLIT_MERGE ///< debug messages in split-merge +//#define DEBUG ///< all debug messages ! + +// in case all debug massages allowed, allow them in practice ! +#ifdef DEBUG +#define DEBUG_STABLE_CONES +#define DEBUG_SPLIT_MERGE +#endif + +#endif // __DEFINES_H__ + diff --git a/JETAN/fastjet/siscone/geom_2d.h b/JETAN/fastjet/siscone/geom_2d.h new file mode 100644 index 00000000000..f0dda4ff481 --- /dev/null +++ b/JETAN/fastjet/siscone/geom_2d.h @@ -0,0 +1,179 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: geom_2d.h // +// Description: header file for two-dimensional geometry tools // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 268 $// +// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __GEOM_2D_H__ +#define __GEOM_2D_H__ + +#include +#include +#include "defines.h" + +#ifndef M_PI +#define M_PI 3.141592653589793238462643383279502884197 +#endif + +namespace siscone{ + +/// return a result that corresponds to phi, but in the +/// range (-pi..pi]; the result is only correct if -3pi < phi <= 3pi +inline double phi_in_range(double phi) { + if (phi <= -M_PI) phi += twopi; + else if (phi > M_PI) phi -= twopi; + return phi; +} + +/// return the difference between the two phi values, +/// placed in the correct range (-pi..pi], , assuming that phi1,phi2 +/// are already in the correct range. +inline double dphi(double phi1, double phi2) { + return phi_in_range(phi1-phi2); +} + + +/// return the absolute difference between the two phi values, +/// placed in the correct range, assuming that phi1,phi2 are already +/// in the correct range. +inline double abs_dphi(double phi1, double phi2) { + double delta = fabs(phi1-phi2); + return delta > M_PI ? twopi-delta : delta; +} + +/// return the square of the argument +inline double pow2(double x) {return x*x;} + + +/** + * \class Ctwovect + * \brief class for holding a two-vector + */ +class Ctwovect { +public: + /// default ctor + Ctwovect() : x(0.0), y(0.0) {} + + /// ctor with initialisation + /// \param _x first coordinate + /// \param _y second coordinate + Ctwovect(double _x, double _y) : x(_x), y(_y) {} + + /// vector coordinates + double x, y; + + /// norm (modulud square) of the vector + inline double mod2() const {return pow2(x)+pow2(y);} + + /// modulus of the vector + inline double modulus() const {return sqrt(mod2());} +}; + + +/// dot product of two 2-vectors +/// \param a first 2-vect +/// \param b second 2-vect +/// \return a.b is returned +inline double dot_product(const Ctwovect & a, const Ctwovect & b) { + return a.x*b.x + a.y*b.y; +} + + +/// cross product of two 2-vectors +/// \param a first 2-vect +/// \param b second 2-vect +/// \return a x b is returned +inline double cross_product(const Ctwovect & a, const Ctwovect & b) { + return a.x*b.y - a.y*b.x; +} + + +/** + * \class Ceta_phi_range + * \brief class for holding a covering range in eta-phi + * + * This class deals with ranges in the eta-phi plane. It + * implements methods to test if two ranges overlap and + * to take the union of two overlapping intervals. + */ +class Ceta_phi_range{ +public: + /// default ctor + Ceta_phi_range(); + + /// ctor with initialisation + /// we initialise with a centre (in eta,phi) and a radius + /// \param c_eta eta coordinate of the centre + /// \param c_phi phi coordinate of the centre + /// \param R radius + Ceta_phi_range(double c_eta, double c_phi, double R); + + /// assignment of range + /// \param r range to assign to current one + Ceta_phi_range& operator = (const Ceta_phi_range &r); + + /// add a particle to the range + /// \param eta eta coordinate of the particle + /// \param phi phi coordinate of the particle + /// \return 0 on success, 1 on error + int add_particle(const double eta, const double phi); + + /// eta range as a binary coding of covered cells + unsigned int eta_range; + + /// phi range as a binary coding of covered cells + unsigned int phi_range; + + // extremal value for eta + static double eta_min; ///< minimal value for eta + static double eta_max; ///< maximal value for eta + +private: + /// return the cell index corrsponding to an eta value + inline unsigned int get_eta_cell(double eta){ + return (unsigned int) (1 << ((int) (32*((eta-eta_min)/(eta_max-eta_min))))); + } + + /// return the cell index corrsponding to a phi value + inline unsigned int get_phi_cell(double phi){ + return (unsigned int) (1 << ((int) (32*phi/twopi+16)%32)); + } +}; + +/// test overlap +/// \param r1 first range +/// \param r2 second range +/// \return true if overlap, false otherwise. +bool is_range_overlap(const Ceta_phi_range &r1, const Ceta_phi_range &r2); + +/// compute union +/// Note: we assume that the two intervals overlap +/// \param r1 first range +/// \param r2 second range +/// \return union of the two ranges +const Ceta_phi_range range_union(const Ceta_phi_range &r1, const Ceta_phi_range &r2); + +} + +#endif diff --git a/JETAN/fastjet/siscone/hash.h b/JETAN/fastjet/siscone/hash.h new file mode 100644 index 00000000000..7f8c310881e --- /dev/null +++ b/JETAN/fastjet/siscone/hash.h @@ -0,0 +1,122 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: hash.h // +// Description: header file for classes hash_element and hash_cones // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 224 $// +// $Date:: 2008-05-16 19:58:30 +0200 (Fri, 16 May 2008) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __HASH_H__ +#define __HASH_H__ + +#include "momentum.h" +#include "reference.h" + +namespace siscone{ + +/** + * \class hash_element + * information on store cones candidates. + * + * We store in this class the information used to count all + * protocones in a first pass. This first pass only count + * cones with different references and test their stbility + * with the parent-child particles (border particles). + */ +class hash_element{ + public: + Creference ref; ///< reference + double eta; ///< centre: eta coordinate + double phi; ///< centre: phi coordinate + bool is_stable; ///< true if stable w.r.t. "border particles" + + hash_element *next; ///< pointer to the next element +}; + +/** + * \class hash_cones + * list of cones candidates. + * + * We store in this class all the hash_elements and give + * functions to manipulate them. + */ +class hash_cones{ + public: + /// constructor with initialisation + /// \param _Np number of particles + /// \param _R2 cone radius (squared) + hash_cones(int _Np, double _R2); + + /// destructor + ~hash_cones(); + + /** + * insert a new candidate into the hash. + * \param v 4-momentum of te cone to add + * \param parent parent particle defining the cone + * \param child child particle defining the cone + * \param p_io whether the parent has to belong to the cone or not + * \param c_io whether the child has to belong to the cone or not + * \return 0 on success, 1 on error + */ + int insert(Cmomentum *v, Cmomentum *parent, Cmomentum *child, bool p_io, bool c_io); + + /** + * insert a new candidate into the hash. + * \param v 4-momentum of te cone to add + * Note, in this case, we assume stability. We also assume + * that eta and phi are computed for v + * \return 0 on success, 1 on error + */ + int insert(Cmomentum *v); + + /// the cone data itself + hash_element **hash_array; + + /// number of elements + int n_cones; + + /// number of occupied cells +#ifdef DEBUG_STABLE_CONES + int n_occupied_cells; +#endif + + /// number of cells-1 + int mask; + + /// circle radius (squared) + /// NOTE: need to be set before any call to 'insert' + double R2; + + /** + * test if a particle is inside a cone of given centre. + * check if the particle of coordinates 'v' is inside the circle of radius R + * centered at 'centre'. + * \param centre centre of the circle + * \param v particle to test + * \return true if inside, false if outside + */ + inline bool is_inside(Cmomentum *centre, Cmomentum *v); +}; + +} +#endif diff --git a/JETAN/fastjet/siscone/momentum.h b/JETAN/fastjet/siscone/momentum.h new file mode 100644 index 00000000000..0705c2b735b --- /dev/null +++ b/JETAN/fastjet/siscone/momentum.h @@ -0,0 +1,157 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: momentum.h // +// Description: header file for 4-momentum class Cmomentum // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 163 $// +// $Date:: 2007-04-26 22:31:02 +0200 (Thu, 26 Apr 2007) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __VECTOR_H__ +#define __VECTOR_H__ + +#include +#include +#include "reference.h" +#include "geom_2d.h" +#include "defines.h" + +namespace siscone{ + +/** + * \class Cmomentum + * \brief base class for dynamic coordinates management + * + * This class contains the information for particle or group of + * particles management. + * It includes all Lorentz properties as well as tools for summing them. + * Note: 'sums' over phi angles are indeed averages. This allows to + * deal with periodicity at each step + */ +class Cmomentum{ + public: + /// default ctor + Cmomentum(); + + /// ctor with initialisation + Cmomentum(double _px, double _py, double _pz, double _E); + + /// ctor with detailed initialisation + Cmomentum(double _eta, double _phi, Creference _ref); + + /// default dtor + ~Cmomentum(); + + /// computes pT + inline double perp() const {return sqrt(perp2());} + + /// computes pT^2 + inline double perp2() const {return px*px+py*py;} + + /// computes m + inline double mass() const {return sqrt(mass2());} + + /// computes m^2 + inline double mass2() const {return perpmass2()-perp2();} + + /// transverse mass, mt = sqrt(pt^2+m^2) = sqrt(E^2 - pz^2) + inline double perpmass() const {return sqrt((E-pz)*(E+pz));} + + /// transverse mass squared, mt^2 = pt^2+m^2 = E^2 - pz^2 + inline double perpmass2() const {return (E-pz)*(E+pz);} + + /// computes transverse energy + inline double Et() const {return E/sqrt(1.0+pz*pz/perp2());} + + /// computes transverse energy (squared) + inline double Et2() const {return E*E/(1.0+pz*pz/perp2());} + + /// assignment of vectors + Cmomentum& operator = (const Cmomentum &v); + + /// addition of vectors + /// !!! WARNING !!! no updating of eta and phi !!! + const Cmomentum operator + (const Cmomentum &v); + + /// incrementation of vectors + /// !!! WARNING !!! no updating of eta and phi !!! + Cmomentum& operator += (const Cmomentum &v); + + /// decrementation of vectors + /// !!! WARNING !!! no updating of eta and phi !!! + Cmomentum& operator -= (const Cmomentum &v); + + /// build eta-phi from 4-momentum info + /// !!! WARNING !!! + /// !!! computing eta and phi is time-consuming !!! + /// !!! use this whenever you need eta or phi !!! + /// !!! automatically called for single-particle !!! + void build_etaphi(); + + double px; ///< x-momentum + double py; ///< y-momentum + double pz; ///< z-momentum + double E; ///< energy + + double eta; ///< particle pseudo-rapidity + double phi; ///< particle azimuthal angle + int parent_index; ///< particle number in the parent list + int index; ///< internal particle number + + ////////////////////////////////////////////// + // the following part is used for checksums // + ////////////////////////////////////////////// + Creference ref; ///< reference number for the vector +}; + +/// ordering of two vectors +/// this is by default done w.r.t. their references +bool operator < (const Cmomentum &v1, const Cmomentum &v2); + +/// ordering of vectors in eta (e.g. used in collinear tests) +bool momentum_eta_less(const Cmomentum &v1, const Cmomentum &v2); + +/// ordering of vectors in pt +bool momentum_pt_less(const Cmomentum &v1, const Cmomentum &v2); + + +////////////////////////// +// some handy utilities // +////////////////////////// + +/// get distance between to eta-phi points +/// \param eta eta coordinate of first point +/// \param phi phi coordinate of first point +/// \param v vector defining the second point +inline double get_distance(double eta, double phi, Cmomentum *v){ + double dx, dy; + + dx = eta - v->eta; + dy = fabs(phi - v->phi); + if (dy>M_PI) + dy -= twopi; + + return dx*dx+dy*dy; +} + +} + +#endif diff --git a/JETAN/fastjet/siscone/protocones.h b/JETAN/fastjet/siscone/protocones.h new file mode 100644 index 00000000000..2300bc6b8f5 --- /dev/null +++ b/JETAN/fastjet/siscone/protocones.h @@ -0,0 +1,271 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: protocones.h // +// Description: header file for stable cones determination (Cstable_cones) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 224 $// +// $Date:: 2008-05-16 19:58:30 +0200 (Fri, 16 May 2008) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __PROTOCONES_H__ +#define __PROTOCONES_H__ + +#include "momentum.h" +#include "vicinity.h" +#include +#include +#include +#include "hash.h" + +#include "defines.h" + +namespace siscone{ + +/** + * \class Cborder_store + * + * class for storing a border momentum (in context of co-circularity + * checks). + + * This class essentially calculates angle of border point w.r.t. + * circle center (eta & phi), and provides a store of information + * about whether we are currently including this point in the + * candidate + */ +class Cborder_store{ +public: + /// default ctor + Cborder_store(Cmomentum * momentum, double centre_eta, double centre_phi) : + mom(momentum), is_in(false) { + angle = atan2(mom->phi - centre_phi, mom->eta - centre_eta); + } + + Cmomentum * mom; ///< particle momentum + double angle; ///< angle w.r.t. circle centre + bool is_in; ///< inclusion status of the particle +}; + + +/// allows easy sorting of Cborder_store objects (which need to be +/// ordered in angle). +inline bool operator<(const Cborder_store & a, const Cborder_store & b) { + return a.angle < b.angle; +} + + +/** + * \class Cstable_cones + * \brief Computes the list of stable comes from a particle list. + * + * This class does the first fundamental task of te cone algorithm: + * it is used to compute the list of stable cones given a list + * of particles. + */ +class Cstable_cones : public Cvicinity{ + public: + /// default ctor + Cstable_cones(); + + /// ctor with initialisation (sse init for details) + Cstable_cones(std::vector &_particle_list); + + /// default dtor + ~Cstable_cones(); + + /** + * initialisation + * \param _particle_list list of particles + */ + void init(std::vector &_particle_list); + + /** + * compute stable cones. + * This function really does the job i.e. computes + * the list of stable cones (in a seedless way) + * \param _radius radius of the cones + * \return The number of stable cones found is returned + */ + int get_stable_cones(double _radius); + + /// list of stable cones + std::vector protocones; + + /// list of candidates + hash_cones *hc; + + /// total number of tested cones + int nb_tot; +#ifdef DEBUG_STABLE_CONES + int nb_hash_cones, nb_hash_occupied; +#endif + + protected: + /// cone radius + double R; + + /// cone radius SQUARED + double R2; + + private: + /// cone with a given particle as parent + /// this reduction to a single vector assumes we trust the checksums + Cmomentum cone; + + /// child particle, taken in the 'vicinity' list + Cmomentum *child; + + /// centre of the tested cone + Cvicinity_elm *centre; + + /// index in the particle list; + unsigned int centre_idx; + + /// first cone used in the vicinity list + unsigned int first_cone; + + /** + * initialise the cone. + * We take the first particle in the angular ordering to compute this one + * \return 0 on success, 1 on error + */ + int init_cone(); + + /** + * test cones. + * We check if the cone(s) build with the present parent and child + * are stable + * \return 0 on success 1 on error + */ + int test_cone(); + + /** + * update the cone + * go to the next child for that parent and update 'cone' appropriately + * \return 0 if update candidate found, 1 otherwise + */ + int update_cone(); + + /* + * run through the vicinity of the current parent and for each child + * indicate which members are cocircular... + */ + void prepare_cocircular_lists(); + + /** + * check if we are in a situation of cocircularity. + * if it is the case, update and test in the corresponding way + * \return 'false' if no cocircularity detected, 'true' otherwise + * Note that if cocircularity is detected, we need to + * recall 'update' from 'update' !!! + */ + bool cocircular_check(); + + /** + * Routine for testing cocircular configurations in p^3 time, + * rather than 2^p time; + */ + void test_cone_cocircular(Cmomentum & borderless_cone, + std::list & border_list); + + /** + * carry out the computations needed for the stability check of the + * candidate, using the border_vect to indicate which particles + * should / should not be in the stable cone; if the cone is stable + * insert it into the hash. + */ + void test_stability(Cmomentum & candidate, + const std::vector & border_vect); + + /** + * compute the cone contents by going once around the full set of + * circles and tracking the entry/exit status each time -- this sets + * up the inclusion information, which can then be directly used to + * calculate the cone momentum. + */ + void compute_cone_contents(); + + /** + * compute the cone momentum from particle list. + * in this version, we use the 'pincluded' information + * from the Cviinity class + */ + void recompute_cone_contents(); + + /* + * if we have gone beyond the acceptable threshold of change, compute + * the cone momentum from particle list. in this version, we use the + * 'pincluded' information from the Cvicinity class, but we don't + * change the member cone, only the locally supplied one + */ + void recompute_cone_contents_if_needed(Cmomentum & this_cone, double & this_dpt); + + /** + * compute stability of all enumerated candidates. + * For all candidate cones which are stable w.r.t. their border particles, + * pass the last test: stability with quadtree intersection + */ + int proceed_with_stability(); + + /* + * circle intersection. + * computes the intersection with a circle of given centre and radius. + * The output takes the form of a checkxor of the intersection's particles + * - cx circle centre x coordinate + * - cy circle centre y coordinate + * return the checkxor for the intersection + ******************************************************************/ + Creference circle_intersect(double cx, double cy); + + /// present candidate cone + Cmomentum cone_candidate; + + /// in case of co-circular points, vector for them + std::vector child_list; + + /// list of cocircular enclusures already studied + /// first element if cone contents, second is cone border + std::vector< std::pair > multiple_centre_done; + + // information for updating cone contents to avoid rounding errors + double dpt; ///< sums of Delta P_t + + /** + * test if a particle is inside a cone of given centre. + * check if the particle of coordinates 'v' is inside the circle of radius R + * centered at 'centre'. + * \param centre centre of the circle + * \param v particle to test + * \return true if inside, false if outside + */ + inline bool is_inside(Cmomentum *centre, Cmomentum *v); +}; + +/* + * compute the absolute value of the difference between 2 angles. + * We take care of the 2pi periodicity + * \param angle1 first angle + * \param angle2 second angle + * \return the absolute value of the difference between the angles + *****************************************************************/ +inline double abs_dangle(double &angle1, double &angle2); + +} +#endif diff --git a/JETAN/fastjet/siscone/quadtree.h b/JETAN/fastjet/siscone/quadtree.h new file mode 100644 index 00000000000..37159bc8e40 --- /dev/null +++ b/JETAN/fastjet/siscone/quadtree.h @@ -0,0 +1,124 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: quadtree.h // +// Description: header file for quadtree management (Cquadtree class) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 123 $// +// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __QUADTREE_H__ +#define __QUADTREE_H__ + +#include "momentum.h" +#include + +namespace siscone{ + +/** + * \class Cquadtree + * \brief Implementation of a 2D quadtree. + * + * This class implements the traditional two-dimensional quadtree. + * The elements at each node are of 'Cmomentum' type. + */ +class Cquadtree{ + public: + /// default ctor + Cquadtree(); + + /// ctor with initialisation (see init for details) + Cquadtree(double _x, double _y, double _half_size_x, double _half_size_y); + + /// default destructor + /// at destruction, everything is destroyed except + /// physical values at the leaves + ~Cquadtree(); + + /** + * init the tree. + * By initializing the tree, we mean setting the cell parameters + * and preparing the object to act as a seed for a new tree. + * \param _x x-position of the center + * \param _y y-position of the center + * \param _half_size_x x-size of the cell + * \param _half_size_y y-size of the cell + * \return 0 on success, 1 on error. Note that if the cell or its + * parent is already filled, we return an error. + */ + int init(double _x, double _y, double _half_size_x, double _half_size_y); + + /** + * adding a particle to the tree. + * This method adds one vector to the quadtree structure which + * is updated consequently. + * \param v_add vector to add + * \return 0 on success 1 on error + */ + int add(Cmomentum *v_add); + + /** + * circle intersection. + * computes the intersection with a circle of given centre and radius. + * The output takes the form of a quadtree with all squares included + * in the circle. + * \param cx circle centre x coordinate + * \param cy circle centre y coordinate + * \param cR2 circle radius SQUARED + * \return the checksum for that intersection + */ + Creference circle_intersect(double cx, double cy, double cR2); + + /** + * output a data file for drawing the grid. + * This can be used to output a data file containing all the + * grid subdivisions. The file contents is as follows: + * first and second columns give center of the cell, the third + * gives the size. + * \param flux opened stream to write to + * \return 0 on success, 1 on error + */ + int save(FILE *flux); + + /** + * output a data file for drawing the tree leaves. + * This can be used to output a data file containing all the + * tree leaves. The file contents is as follows: + * first and second columns give center of the cell, the third + * gives the size. + * \param flux opened stream to write to + * \return 0 on success, 1 on error + */ + int save_leaves(FILE *flux); + + double centre_x; ///< x-position of the centre of the cell + double centre_y; ///< y-position of the centre of the cell + double half_size_x; ///< HALF size of the cell + double half_size_y; ///< HALF size of the cell + + Cmomentum *v; ///< physical contents + + Cquadtree* children[2][2]; ///< sub-cells ( 0,1->left-right; 0,1->bottom,top) + bool has_child; ///< true if not a leaf +}; + +} +#endif diff --git a/JETAN/fastjet/siscone/ranlux.h b/JETAN/fastjet/siscone/ranlux.h new file mode 100644 index 00000000000..428156e7812 --- /dev/null +++ b/JETAN/fastjet/siscone/ranlux.h @@ -0,0 +1,49 @@ +//! \file ranlux.h + +#ifndef __RANLUX_H__ +#define __RANLUX_H__ + +/* This is a lagged fibonacci generator with skipping developed by Luescher. + The sequence is a series of 24-bit integers, x_n, + + x_n = d_n + b_n + + where d_n = x_{n-10} - x_{n-24} - c_{n-1}, b_n = 0 if d_n >= 0 and + b_n = 2^24 if d_n < 0, c_n = 0 if d_n >= 0 and c_n = 1 if d_n < 0, + where after 24 samples a group of p integers are "skipped", to + reduce correlations. By default p = 199, but can be increased to + 365. + + The period of the generator is around 10^171. + + From: M. Luescher, "A portable high-quality random number generator + for lattice field theory calculations", Computer Physics + Communications, 79 (1994) 100-110. + + Available on the net as hep-lat/9309020 at http://xxx.lanl.gov/ + + See also, + + F. James, "RANLUX: A Fortran implementation of the high-quality + pseudo-random number generator of Luscher", Computer Physics + Communications, 79 (1994) 111-114 + + Kenneth G. Hamilton, F. James, "Acceleration of RANLUX", Computer + Physics Communications, 101 (1997) 241-248 + + Kenneth G. Hamilton, "Assembler RANLUX for PCs", Computer Physics + Communications, 101 (1997) 249-253 */ + +namespace siscone{ + +/// initialize 'ranlux' generator +void ranlux_init(); + +/// generate random value (24 bits) +unsigned long int ranlux_get(); + +/// save state of the generator +void ranlux_print_state(); + +} +#endif diff --git a/JETAN/fastjet/siscone/reference.h b/JETAN/fastjet/siscone/reference.h new file mode 100644 index 00000000000..8d4e2d5883a --- /dev/null +++ b/JETAN/fastjet/siscone/reference.h @@ -0,0 +1,111 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: reference.h // +// Description: header file for checkxor management (Creference class) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 123 $// +// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __REFERENCE_H__ +#define __REFERENCE_H__ + +namespace siscone{ + +/** + * \class Creference + * \brief references used for checksums. + * + * This class implements some reference variable + * that can be used for checksums. Those checksums + * are useful to disentengle between contents of two + * cones without looking into their explicit particle + * contents. + */ +class Creference{ + public: + /// default constructor + Creference(); + + /// create a random reference + void randomize(); + + /// test emptyness + bool is_empty(); + + /// test non-emptyness + bool not_empty(); + + /// assignment of reference + Creference& operator = (const Creference &r); + + /// addition of reference + Creference operator + (const Creference &r); + + /// incrementation of reference + Creference& operator += (const Creference &r); + + /// decrementation of reference + Creference& operator -= (const Creference &r); + + /// accessing the reference + inline unsigned int operator[] (int i) {return ref[i];} + + unsigned int ref[3]; ///< actual data for the reference +}; + +/// addition of two references +Creference operator + (Creference &r1, Creference &r2); + +/// equality test of two references +bool operator == (const Creference &r1, const Creference &r2); + +/// difference test of two references +bool operator != (const Creference &r1, const Creference &r2); + +/// ordering of two references +bool operator < (const Creference &r1, const Creference &r2); + + +//=============== inline material ================ + +// equality test for two references +//---------------------------------- +inline bool operator == (const Creference &r1, const Creference &r2){ + return (r1.ref[0]==r2.ref[0]) && (r1.ref[1]==r2.ref[1]) && (r1.ref[2]==r2.ref[2]); +} + +// difference test for two references +//---------------------------------- +inline bool operator != (const Creference &r1, const Creference &r2){ + return (r1.ref[0]!=r2.ref[0]) || (r1.ref[1]!=r2.ref[1]) || (r1.ref[2]!=r2.ref[2]); +} + +// difference test for two references +//---------------------------------- +inline bool operator < (const Creference &r1, const Creference &r2){ + return (r1.ref[0] &_particles, double _radius, double _f, + int _n_pass_max=0, double _ptmin=0.0, + Esplit_merge_scale _split_merge_scale=SM_pttilde); + + /** + * recompute the jets with a different overlap parameter. + * we use the same particles and R as in the preceeding call. + * \param _f shared energy threshold for splitting&merging + * \param _ptmin minimum pT of the protojets + * \param _split_merge_scale the scale choice for the split-merge procedure + * split--merge variable + * NOTE: using pt leads to IR unsafety for some events with momentum + * conservation. So we strongly advise not to change the default + * value. + * \return the number of jets found, -1 if recomputation not allowed. + */ + int recompute_jets(double _f, double _ptmin = 0.0, + Esplit_merge_scale _split_merge_scale=SM_pttilde); + + /// list of protocones found pass-by-pass + std::vector > protocones_list; + + // random number initialisation + static bool init_done; ///< check random generator initialisation + +#ifdef DEBUG_STABLE_CONES + int nb_hash_cones_total, nb_hash_occupied_total; +#endif + + private: + bool rerun_allowed; ///< is recompute_jets allowed ? +}; + + +// finally, a bunch of functions to access to +// basic information (package name, version) +//--------------------------------------------- + +/** + * return SISCone package name. + * This is nothing but "SISCone", it is a replacement to the + * PACKAGE_NAME string defined in config.h and which is not + * public by default. + * \return the SISCone name as a string + */ +std::string siscone_package_name(); + +/** + * return SISCone version number. + * \return a string of the form "X.Y.Z" with possible additional tag + * (alpha, beta, devel) to mention stability status + */ +std::string siscone_version(); + +} +#endif diff --git a/JETAN/fastjet/siscone/siscone_error.h b/JETAN/fastjet/siscone/siscone_error.h new file mode 100644 index 00000000000..b2737bbe467 --- /dev/null +++ b/JETAN/fastjet/siscone/siscone_error.h @@ -0,0 +1,64 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: siscone_error.h // +// Description: header file for SISCone error messages (Csiscone_error) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 268 $// +// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SISCONE_ERROR_H__ +#define __SISCONE_ERROR_H__ + +#include +#include + +namespace siscone{ + +/// \class Csiscone_error +/// class corresponding to errors that will be thrown by siscone +class Csiscone_error { +public: + /// default ctor + Csiscone_error() {;}; + + /// ctor with a given error message + /// \param message the error message to be printed + Csiscone_error(const std::string & message) { + m_message = message; + if (m_print_errors) std::cerr << "siscone::Csiscone_error: "< +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.141592653589793238462643383279502884197 +#endif + +namespace siscone_spherical{ + +/** + * \class CSphtheta_phi_range + * \brief class for holding a covering range in eta-phi + * + * This class deals with ranges in the eta-phi plane. It + * implements methods to test if two ranges overlap and + * to take the union of two overlapping intervals. + */ +class CSphtheta_phi_range{ +public: + /// default ctor + CSphtheta_phi_range(); + + /// ctor with initialisation + /// we initialise with a centre (in theta,phi) and a radius + /// \param c_theta theta coordinate of the centre + /// \param c_phi phi coordinate of the centre + /// \param R radius + CSphtheta_phi_range(double c_theta, double c_phi, double R); + + /// assignment of range + /// \param r range to assign to current one + CSphtheta_phi_range& operator = (const CSphtheta_phi_range &r); + + /// add a particle to the range + /// \param theta theta coordinate of the particle + /// \param phi phi coordinate of the particle + /// \return 0 on success, 1 on error + int add_particle(const double theta, const double phi); + + /// theta range as a binary coding of covered cells + unsigned int theta_range; + + /// phi range as a binary coding of covered cells + unsigned int phi_range; + + /// extremal value for theta + static double theta_min; ///< minimal value for theta (set to 0) + static double theta_max; ///< maximal value for theta (set to pi) + +private: + /// return the cell index corrsponding to an theta value + inline unsigned int get_theta_cell(double theta){ + return (unsigned int) (1 << ((int) (32*((theta-theta_min)/(theta_max-theta_min))))); + } + + /// return the cell index corrsponding to a phi value + inline unsigned int get_phi_cell(double phi){ + return (unsigned int) (1 << ((int) (32*phi/twopi+16)%32)); + } +}; + +/// test overlap +/// \param r1 first range +/// \param r2 second range +/// \return true if overlap, false otherwise. +bool is_range_overlap(const CSphtheta_phi_range &r1, const CSphtheta_phi_range &r2); + +/// compute union +/// Note: we assume that the two intervals overlap +/// \param r1 first range +/// \param r2 second range +/// \return union of the two ranges +const CSphtheta_phi_range range_union(const CSphtheta_phi_range &r1, const CSphtheta_phi_range &r2); + +} + +#endif diff --git a/JETAN/fastjet/siscone/spherical/hash.h b/JETAN/fastjet/siscone/spherical/hash.h new file mode 100644 index 00000000000..fe679669d70 --- /dev/null +++ b/JETAN/fastjet/siscone/spherical/hash.h @@ -0,0 +1,114 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: hash.h // +// Description: header file for classes hash_element and hash_cones // +// This file is part of the SISCone project. // +// WARNING: this is not the main SISCone trunk but // +// an adaptation to spherical coordinates // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 268 $// +// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPH_HASH_H__ +#define __SPH_HASH_H__ + +#include "momentum.h" + +namespace siscone_spherical{ + +/** + * \class sph_hash_element + * information on store cones candidates. + * + * We store in this class the information used to count all + * protocones in a first pass. This first pass only count + * cones with different references and test their stbility + * with the parent-child particles (border particles). + */ +class sph_hash_element{ + public: + CSph3vector centre; ///< centre of the cone + bool is_stable; ///< true if stable w.r.t. "border particles" + + sph_hash_element *next; ///< pointer to the next element +}; + +/** + * \class sph_hash_cones + * list of cones candidates. + * + * We store in this class all the hash_elements and give + * functions to manipulate them. + */ +class sph_hash_cones{ + public: + /// constructor with initialisation + /// \param _Np number of particles + /// \param _R2 cone radius (squared) + sph_hash_cones(int _Np, double _R2); + + /// destructor + ~sph_hash_cones(); + + /** + * insert a new candidate into the hash. + * \param v 4-momentum of te cone to add + * \param parent parent particle defining the cone + * \param child child particle defining the cone + * \param p_io whether the parent has to belong to the cone or not + * \param c_io whether the child has to belong to the cone or not + * \return 0 on success, 1 on error + */ + int insert(CSphmomentum *v, CSphmomentum *parent, CSphmomentum *child, bool p_io, bool c_io); + + /** + * insert a new candidate into the hash. + * \param v 4-momentum of te cone to add + * Note, in this case, we assume stability. We also assume + * that eta and phi are computed for v + * \return 0 on success, 1 on error + */ + int insert(CSphmomentum *v); + + /// the cone data itself + sph_hash_element **hash_array; + + /// number of elements + int n_cones; + + /// number of occupied cells +#ifdef DEBUG_STABLE_CONES + int n_occupied_cells; +#endif + + /// number of cells-1 + int mask; + + /// circle radius (squared) + /// NOTE: need to be set before any call to 'insert' + double R2; + + /// its squreed tangent + double tan2R; +}; + +} +#endif diff --git a/JETAN/fastjet/siscone/spherical/momentum.h b/JETAN/fastjet/siscone/spherical/momentum.h new file mode 100644 index 00000000000..040434153ab --- /dev/null +++ b/JETAN/fastjet/siscone/spherical/momentum.h @@ -0,0 +1,312 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: momentum.h // +// Description: header file for 4-momentum class Cmomentum // +// This file is part of the SISCone project. // +// WARNING: this is not the main SISCone trunk but // +// an adaptation to spherical coordinates // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 256 $// +// $Date:: 2008-07-14 13:52:16 +0200 (Mon, 14 Jul 2008) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPH_VECTOR_H__ +#define __SPH_VECTOR_H__ + +#include +#include +#include +#include "geom_2d.h" +#include + +namespace siscone_spherical{ + +/** + * \class CSph3vector + * \brief base class for managing the spatial part of Cmomentum (defined after) + * + * This class contains the information for particle or group of + * particles management. + * It is adapted to use spherical geometry, where, for our purposes, + * the only time-consuming operation we need is the computation of + * the norm. To compute it once-and-for-all and store it in a local + * variable, you should call the 'build_norm' method. + * On top of that, the angle phi is computed from the x-axis + * and theta from the "north pole". + */ +class CSph3vector{ + public: + /// default ctor + CSph3vector(); + + /// ctor with initialisation + CSph3vector(double _px, double _py, double _pz); + + /// default dtor + ~CSph3vector(); + + /// assignment of vectors + CSph3vector& operator = (const CSph3vector &v); + + /// addition of vectors + /// WARNING= norm is not updated + const CSph3vector operator + (const CSph3vector &v); + + /// subtraction of vectors + /// WARNING= norm is not updated + const CSph3vector operator - (const CSph3vector &v); + + /// division by a constant + /// WARNING= norm is not updated + const CSph3vector operator / (const double &r); + + /// incrementation of vectors + /// WARNING= norm is not updated + CSph3vector& operator += (const CSph3vector &v); + + /// decrementation of vectors + /// WARNING= norm is not updated + CSph3vector& operator -= (const CSph3vector &v); + + /// multiplication by a constant + /// WARNING= norm is not updated + CSph3vector& operator *= (const double &r); + + /// division by a constant + /// WARNING= norm is not updated + CSph3vector& operator /= (const double &r); + + /// computes pT + inline double perp() const {return sqrt(perp2());} + + /// computes pT^2 + inline double perp2() const {return px*px+py*py;} + + /// 3-vect norm + inline double norm() const {return sqrt(px*px+py*py+pz*pz);} + + /// 3-vect norm squared + inline double norm2() const {return px*px+py*py+pz*pz;} + + /// 3-vect azimuthal angle + inline double phi() const {return atan2(py, px);} + + /// 3-vect polar angle + inline double theta() const {return atan2(perp(),pz);} + + /// build the spatial normfrom 4-momentum info + /// !!! WARNING !!! + /// !!! computing the norm is the only time-consuming !!! + /// !!! information we need in all computations. !!! + /// !!! use this whenever you need repeated access !!! + /// !!! to the norm to store it in the local variable !!! + void build_norm(); + + /// just a useful tool to store theta and phi + /// locally (in _theta and _phi) in case you need + /// repeated access + void build_thetaphi(); + + /// for this direction, compute the two reference directions + /// used to measure angles + void get_angular_directions(CSph3vector &angular_dir1, CSph3vector &angular_dir2); + + double px; ///< x-momentum + double py; ///< y-momentum + double pz; ///< z-momentum + + double _norm; ///< particle spatial norm (available ONLY after a call to build_norm) + double _theta; ///< particle theta angle (available ONLY after a call to build_thetaphi) + double _phi; ///< particle phi angle (available ONLY after a call to build_thetaphi) + + ////////////////////////////////////////////// + // the following part is used for checksums // + ////////////////////////////////////////////// + siscone::Creference ref; ///< reference number for the vector +}; + +/** + * \class CSphmomentum + * \brief base class for dynamic coordinates management + * + * This class contains the information for particle or group of + * particles management. + * It is adapted to use spherical geometry, where, for our purposes, + * the only time-consuming operation we need is the computation of + * the norm. To compute it once-and-for-all and store it in a local + * variable, you should call the 'build_norm' method. + * On top of that, the angle phi is computed from the x-axis + * and theta from the "north pole". + */ +class CSphmomentum : public CSph3vector{ + public: + /// default ctor + CSphmomentum(); + + /// init from a 3-vect + CSphmomentum(CSph3vector &init, double E=0.0); + + /// ctor with initialisation + CSphmomentum(double _px, double _py, double _pz, double _E); + + /// ctor with detailed initialisation + //CSphmomentum(double _eta, double _phi, siscone::Creference _ref); + + /// default dtor + ~CSphmomentum(); + + /// computes m + inline double mass() const {return sqrt(mass2());} + + /// computes m^2 + inline double mass2() const {return perpmass2()-perp2();} + + /// transverse mass, mt = sqrt(pt^2+m^2) = sqrt(E^2 - pz^2) + inline double perpmass() const {return sqrt((E-pz)*(E+pz));} + + /// transverse mass squared, mt^2 = pt^2+m^2 = E^2 - pz^2 + inline double perpmass2() const {return (E-pz)*(E+pz);} + + /// computes transverse energy + inline double Et() const {return E/sqrt(1.0+pz*pz/perp2());} + + /// computes transverse energy (squared) + inline double Et2() const {return E*E/(1.0+pz*pz/perp2());} + + /// assignment of vectors + CSphmomentum& operator = (const CSphmomentum &v); + + /// addition of vectors + /// !!! WARNING !!! no updating of eta and phi !!! + const CSphmomentum operator + (const CSphmomentum &v); + + /// incrementation of vectors + /// !!! WARNING !!! no updating of eta and phi !!! + CSphmomentum& operator += (const CSphmomentum &v); + + /// decrementation of vectors + /// !!! WARNING !!! no updating of eta and phi !!! + CSphmomentum& operator -= (const CSphmomentum &v); + + double E; ///< energy + + int parent_index; ///< particle number in the parent list + int index; ///< internal particle number +}; + +/// ordering of two vectors +/// this is by default done w.r.t. their references +bool operator < (const CSphmomentum &v1, const CSphmomentum &v2); + +/// ordering of vectors in eta (e.g. used in collinear tests) +bool momentum_theta_less(const CSphmomentum &v1, const CSphmomentum &v2); + +/// ordering of vectors in pt +bool momentum_pt_less(const CSphmomentum &v1, const CSphmomentum &v2); + + +////////////////////////// +// some handy utilities // +////////////////////////// + +/// square +inline double sqr(double x){return x*x;} + +/// dot product for te spatial 3-vect +/// \param v1 first 4-vect +/// \param v2 second 4-vect +inline double dot_product3(const CSph3vector &v1, const CSph3vector &v2){ + //double tmp = v1.px*v2.px + v1.py*v2.py + v1.pz*v2.pz; + //if (!isfinite(tmp)){ + // std::cout << "dot_product inf: " << std::endl; + // std::cout << " angles: " << v1._theta << " " << v1._phi << " and " << v2._theta << " " << v2._phi << std::endl; + // std::cout << " moms : " << v1.px << " " << v1.py << " " << v1.pz + // << " and " << v2.px << " " << v2.py << " " << v2.pz << std::endl; + //} + return v1.px*v2.px + v1.py*v2.py + v1.pz*v2.pz; +} + +/// cross product for the spatial 3-vect +/// \param v1 first 4-vect +/// \param v2 second 4-vect +inline CSph3vector cross_product3(const CSph3vector &v1, const CSph3vector &v2){ + //CSph3vector tmp; + //tmp.px = v1.py*v2.pz-v1.pz*v2.py; + //tmp.py = v1.pz*v2.px-v1.px*v2.pz; + //tmp.pz = v1.px*v2.py-v1.py*v2.px; + //return tmp; + return CSph3vector(v1.py*v2.pz-v1.pz*v2.py, + v1.pz*v2.px-v1.px*v2.pz, + v1.px*v2.py-v1.py*v2.px); +} + +/// squared norm of the cross product for the spatial 3-vect (energy is set to 0) +/// \param v1 first 4-vect +/// \param v2 second 4-vect +inline double norm2_cross_product3(const CSph3vector &v1, const CSph3vector &v2){ + return sqr(v1.py*v2.pz-v1.pz*v2.py) + sqr(v1.pz*v2.px-v1.px*v2.pz) + sqr(v1.px*v2.py-v1.py*v2.px); +} + +/// get tangent squared of the spherical distance between two vectors +/// \param v1 vector defining the first point +/// \param v2 vector defining the second point +inline double get_tan2_distance(const CSphmomentum &v1, const CSphmomentum &v2){ + return norm2_cross_product3(v1,v2)/sqr(dot_product3(v1,v2)); +} + +/// get spherical distance between to vectors +/// \param v1 vector defining the first point +/// \param v2 vector defining the second point +inline double get_distance(const CSph3vector *v1, const CSph3vector *v2){ + return atan2(sqrt(norm2_cross_product3(*v1,*v2)), dot_product3(*v1,*v2)); +} + +/// return true if the two points are distant by less than get spherical distance between two vectors +/// \param v1 vector defining the first point +/// \param v2 vector defining the second point +/// \param tan2R tangent squared of the max distance +/// WARNING: using the tangent here is dangerous for R>pi/2. +/// this never happens per se for "regular R" but +/// it may in the vicinity computation as we're using +/// 2R there. +inline bool is_closer(const CSph3vector *v1, const CSph3vector *v2, const double tan2R){ + double dot = dot_product3(*v1,*v2); + return (dot>=0) && (norm2_cross_product3(*v1,*v2)<=tan2R*dot*dot); +} + +/// return true if the two points are distant by less than get spherical distance between to vectors +/// \param v1 vector defining the first point +/// \param v2 vector defining the second point +/// \param tan2R tangent squared of the max distance +/// safer version but computes the norm +inline bool is_closer_safer(const CSph3vector *v1, const CSph3vector *v2, const double cosR){ + return dot_product3(*v1,*v2)>=cosR*sqrt(v1->norm2()*v2->norm2()); + //double dot = dot_product3(*v1,*v2); + //return (dot>=0) && (norm2_cross_product3(*v1,*v2) +#include +#include +#include "hash.h" + +#include + +namespace siscone_spherical{ + +/** + * \class CSphborder_store + * + * class for storing a border momentum (in context of co-circularity + * checks). + + * This class essentially calculates angle of border point w.r.t. + * circle center (eta & phi), and provides a store of information + * about whether we are currently including this point in the + * candidate + */ +class CSphborder_store{ +public: + /// default ctor + CSphborder_store(CSphmomentum * momentum, CSph3vector ¢re, CSph3vector &angl_dir1, CSph3vector &angl_dir2) : + mom(momentum), is_in(false) { + CSph3vector diff = (*momentum) - centre; + angle = atan2(dot_product3(diff, angl_dir2), dot_product3(diff, angl_dir1)); +#ifdef DEBUG_STABLE_CONES + std::cout << " adding point " << momentum->_theta << ", " << momentum->_phi + << " at an angle of " << angle << std::endl; +#endif + } + + CSphmomentum * mom; ///< particle momentum + double angle; ///< angle w.r.t. circle centre + bool is_in; ///< inclusion status of the particle +}; + + +/// allows easy sorting of CSphborder_store objects (which need to be +/// ordered in angle). +inline bool operator<(const CSphborder_store & a, const CSphborder_store & b) { + return a.angle < b.angle; +} + + +/** + * \class CSphstable_cones + * \brief Computes the list of stable comes from a particle list. + * + * This class does the first fundamental task of te cone algorithm: + * it is used to compute the list of stable cones given a list + * of particles. + */ +class CSphstable_cones : public CSphvicinity{ + public: + /// default ctor + CSphstable_cones(); + + /// ctor with initialisation (sse init for details) + CSphstable_cones(std::vector &_particle_list); + + /// default dtor + ~CSphstable_cones(); + + /** + * initialisation + * \param _particle_list list of particles + */ + void init(std::vector &_particle_list); + + /** + * compute stable cones. + * This function really does the job i.e. computes + * the list of stable cones (in a seedless way) + * \param _radius radius of the cones + * \return The number of stable cones found is returned + */ + int get_stable_cones(double _radius); + + /// list of stable cones + std::vector protocones; + + /// list of candidates + sph_hash_cones *hc; + + /// total number of tested cones + int nb_tot; +#ifdef DEBUG_STABLE_CONES + int nb_hash_cones, nb_hash_occupied; +#endif + + protected: + /// cone radius + double R; + + /// cone radius SQUARED + double R2; + + /// squared tangent of the cone radius + double tan2R; + + private: + /// cone with a given particle as parent + /// this reduction to a single vector assumes we trust the checksums + CSphmomentum cone; + + /// child particle, taken in the 'vicinity' list + CSphmomentum *child; + + /// centre of the tested cone + CSphvicinity_elm *centre; + + /// index in the particle list; + unsigned int centre_idx; + + /// first cone used in the vicinity list + unsigned int first_cone; + + /** + * initialise the cone. + * We take the first particle in the angular ordering to compute this one + * \return 0 on success, 1 on error + */ + int init_cone(); + + /** + * test cones. + * We check if the cone(s) build with the present parent and child + * are stable + * \return 0 on success 1 on error + */ + int test_cone(); + + /** + * update the cone + * go to the next child for that parent and update 'cone' appropriately + * \return 0 if update candidate found, 1 otherwise + */ + int update_cone(); + + /* + * run through the vicinity of the current parent and for each child + * indicate which members are cocircular... + */ + void prepare_cocircular_lists(); + + /** + * check if we are in a situation of cocircularity. + * if it is the case, update and test in the corresponding way + * \return 'false' if no cocircularity detected, 'true' otherwise + * Note that if cocircularity is detected, we need to + * recall 'update' from 'update' !!! + */ + bool cocircular_check(); + + /** + * Routine for testing cocircular configurations in p^3 time, + * rather than 2^p time; + */ + void test_cone_cocircular(CSphmomentum & borderless_cone, + std::list & border_list); + + /** + * carry out the computations needed for the stability check of the + * candidate, using the border_vect to indicate which particles + * should / should not be in the stable cone; if the cone is stable + * insert it into the hash. + */ + void test_stability(CSphmomentum & candidate, + const std::vector & border_vect); + + /** + * compute the cone contents by going once around the full set of + * circles and tracking the entry/exit status each time -- this sets + * up the inclusion information, which can then be directly used to + * calculate the cone momentum. + */ + void compute_cone_contents(); + + /** + * compute the cone momentum from particle list. + * in this version, we use the 'pincluded' information + * from the CSphvicinity class + */ + void recompute_cone_contents(); + + /* + * if we have gone beyond the acceptable threshold of change, compute + * the cone momentum from particle list. in this version, we use the + * 'pincluded' information from the CSphvicinity class, but we don't + * change the member cone, only the locally supplied one + */ + void recompute_cone_contents_if_needed(CSphmomentum & this_cone, double & this_dpt); + + /** + * compute stability of all enumerated candidates. + * For all candidate cones which are stable w.r.t. their border particles, + * pass the last test: stability with quadtree intersection + */ + int proceed_with_stability(); + + /* + * circle intersection. + * computes the intersection with a circle of given centre and radius. + * The output takes the form of a checkxor of the intersection's particles + * - cx circle centre x coordinate + * - cy circle centre y coordinate + * return the checkxor for the intersection + ******************************************************************/ + siscone::Creference circle_intersect(CSph3vector &cone_centre); + + /// present candidate cone + CSphmomentum cone_candidate; + + /// in case of co-circular points, vector for them + std::vector child_list; + + /// list of cocircular enclusures already studied + /// first element if cone contents, second is cone border + std::vector< std::pair > multiple_centre_done; + + // information for updating cone contents to avoid rounding errors + double dpt; ///< sums of Delta P_t +}; + +} +#endif diff --git a/JETAN/fastjet/siscone/spherical/siscone.h b/JETAN/fastjet/siscone/spherical/siscone.h new file mode 100644 index 00000000000..9ff6646e9a2 --- /dev/null +++ b/JETAN/fastjet/siscone/spherical/siscone.h @@ -0,0 +1,131 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: siscone.h // +// Description: header file for the main SISCone class // +// This file is part of the SISCone project. // +// WARNING: this is not the main SISCone trunk but // +// an adaptation to spherical coordinates // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 261 $// +// $Date:: 2008-07-23 17:54:30 +0200 (Wed, 23 Jul 2008) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPH_SISCONE_H__ +#define __SPH_SISCONE_H__ + +#include "protocones.h" +#include "split_merge.h" + +namespace siscone_spherical{ + +/** + * \class CSphsiscone + * final class: gather everything to compute the jet contents. + * + * This is the class user should use. + * It computes the jet contents of a list of particles + * given a cone radius and a threshold for splitting/merging. + * + * After the call to 'perform', the vector jets is filled with + * the jets found. the 'contents' field of each jets contains + * the indices of the particles included in that jet. + */ +class CSphsiscone : public CSphstable_cones, public CSphsplit_merge{ + public: + /// default ctor + CSphsiscone(); + + /// default dtor + ~CSphsiscone(); + + /** + * compute the jets from a given particle set. + * We are doing multiple passes such pass n_pass looks for jets among + * all particles not put into jets during previous passes. + * By default the number of passes is infinite (0). + * \param _particles list of particles + * \param _radius cone radius + * \param _f shared energy threshold for splitting&merging + * \param _n_pass_max maximum number of passes (0=full search) + * \param _Emin minimum energy of the protojets + * \param _split_merge_scale the scale choice for the split-merge procedure + * NOTE: SM_Etilde + * is always IR safe + * SM_E + * is IR unsafe for events with mom. conservation + * + * \return the number of jets found. + */ + int compute_jets(std::vector &_particles, double _radius, double _f, + int _n_pass_max=0, double _Emin=0.0, + Esplit_merge_scale _split_merge_scale=SM_Etilde); + + /** + * recompute the jets with a different overlap parameter. + * we use the same particles and R as in the preceeding call. + * \param _f shared energy threshold for splitting&merging + * \param _Emin minimum energy of the protojets + * \param _split_merge_scale the scale choice for the split-merge procedure + * split--merge variable + * NOTE: using pt leads to IR unsafety for some events with momentum + * conservation. So we strongly advise not to change the default + * value. + * \return the number of jets found, -1 if recomputation not allowed. + */ + int recompute_jets(double _f, double _Emin = 0.0, + Esplit_merge_scale _split_merge_scale=SM_Etilde); + + /// list of protocones found pass-by-pass + std::vector > protocones_list; + + // random number initialisation + static bool init_done; ///< check random generator initialisation + +#ifdef DEBUG_STABLE_CONES + int nb_hash_cones_total, nb_hash_occupied_total; +#endif + + private: + bool rerun_allowed; ///< is recompute_jets allowed ? +}; + + +// finally, a bunch of functions to access to +// basic information (package name, version) +//--------------------------------------------- + +/** + * return SISCone package name. + * This is nothing but "SISCone", it is a replacement to the + * PACKAGE_NAME string defined in config.h and which is not + * public by default. + * \return the SISCone name as a string + */ +std::string siscone_package_name(); + +/** + * return SISCone version number. + * \return a string of the form "X.Y.Z" with possible additional tag + * (alpha, beta, devel) to mention stability status + */ +std::string siscone_version(); + +} +#endif diff --git a/JETAN/fastjet/siscone/spherical/split_merge.h b/JETAN/fastjet/siscone/spherical/split_merge.h new file mode 100644 index 00000000000..1458c463dfb --- /dev/null +++ b/JETAN/fastjet/siscone/spherical/split_merge.h @@ -0,0 +1,401 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: split_merge.h // +// Description: header file for splitting/merging (contains the CJet class) // +// This file is part of the SISCone project. // +// WARNING: this is not the main SISCone trunk but // +// an adaptation to spherical coordinates // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 268 $// +// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPH_SPLIT_MERGE_H__ +#define __SPH_SPLIT_MERGE_H__ + +#include +#include "geom_2d.h" +#include "momentum.h" +#include +#include +#include +#include +#include + +namespace siscone_spherical{ + +/** + * \class CSphjet + * real Jet information. + * + * This class contains information for one single jet. + * That is, first, its momentum carrying information + * about its centre and pT, and second, its particle + * contents + */ +class CSphjet{ + public: + /// default ctor + CSphjet(); + + /// default dtor + ~CSphjet(); + + CSphmomentum v; ///< jet momentum + double E_tilde; ///< sum of E_i [1+sin^2(theta_iJ)] + int n; ///< number of particles inside + std::vector contents; ///< particle contents (list of indices) + + /// ordering variable used for ordering and overlap in the + /// split--merge. This variable is automatically set either to + /// E_tilde or E depending on the siscone parameter. + /// + /// Note that the default behaviour is E_tilde and that other + /// choices may lead to infrared unsafe situations. + /// + /// Note: we use the square of the varible rather than the variable + /// itself + /// + /// Note 2: for the overlap computation, we shall use the jet energy! + double sm_var2; + + /// covered range in eta-phi + CSphtheta_phi_range range; + + /// pass at which the jet has been found + /// It starts at 0 (first pass), -1 means infinite rapidity + int pass; +}; + +/// ordering of jets in pt +///bool jets_pt_less(const CSphjet &j1, const CSphjet &j2); + +/// ordering of jets in energy (e.g. used in final jets ordering) +bool jets_E_less(const CSphjet &j1, const CSphjet &j2); + + +/// the choices of scale variable that can be used in the split-merge +/// step, both for ordering the protojets and for measuing their +/// overlap; E is defined in E-scheme (4-momentum) recombination; +/// Etilde = \sum_{i\in jet} E_i [1+sin^2(theta_{i,jet})] +/// +/// NB: if one changes the order here, one _MUST_ also change the order +/// in the SISCone plugin +enum Esplit_merge_scale { + SM_E, ///< Energy (IR unsafe with momentum conservation) + SM_Etilde ///< sum_{i \in jet} E_i [1+sin^2(theta_iJ)] +}; + +/// return the name of the split-merge scale choice +std::string split_merge_scale_name(Esplit_merge_scale sms); + +/** + * \class CSphsplit_merge_ptcomparison + * a class that allows us to carry out comparisons of pt of jets, using + * information from exact particle contents where necessary. + */ +class CSphsplit_merge_ptcomparison{ +public: + /// default ctor + CSphsplit_merge_ptcomparison() : + particles(0), split_merge_scale(SM_Etilde){}; + + /// return the name corresponding to the SM scale variable + std::string SM_scale_name() const { + return split_merge_scale_name(split_merge_scale);} + + std::vector * particles; ///< pointer to the list of particles + std::vector * particles_norm2; ///< pointer to the particles's norm^2 + + /// comparison of 2 CSphjet + bool operator()(const CSphjet &jet1, const CSphjet &jet2) const; + + /** + * get the difference between 2 jets, calculated such that rounding + * errors will not affect the result even if the two jets have + * almost the same content (so that the difference is below the + * rounding errors) + * + * \param j1 first jet + * \param j2 second jet + * \param v jet1-jet2 + * \param E_tilde jet1-jet2 E_tilde + */ + void get_difference(const CSphjet &j1, const CSphjet &j2, CSphmomentum *v, double *E_tilde) const; + + /// the following parameter controls the variable we're using for + /// the split-merge process i.e. the variable we use for + /// 1. ordering jet candidates; + /// 2. computing the overlap fraction of two candidates. + /// The default value uses Etilde. The other alternative is E + /// NOTE: Modifying the default choice can have nasty effects: + /// - using E is IR-safe for QCD jets but the IR unsafety remains + /// for back-to-back jets of unstable narrow-width particles + /// (e.g. Higgs). + /// Therefore, keeping the default value is strongly advised. + Esplit_merge_scale split_merge_scale; +}; + + +// iterator types +/// iterator definition for the jet candidates structure +typedef std::multiset::iterator cjet_iterator; + +/// iterator definition for the jet structure +typedef std::vector::iterator jet_iterator; + + + +/** + * \class CSphsplit_merge + * Class used to split and merge jets. + */ +class CSphsplit_merge{ + public: + /// default ctor + CSphsplit_merge(); + + /// default dtor + ~CSphsplit_merge(); + + + ////////////////////////////// + // initialisation functions // + ////////////////////////////// + + /** + * initialisation function + * \param _particles list of particles + * \param protocones list of protocones (initial jet candidates) + * \param R2 cone radius (squared) + * \param Emin minimal energy allowed for jets + * \return 0 on success, 1 on error + */ + int init(std::vector &_particles, std::vector *protocones, double R2, double Emin=0.0); + + /** + * initialisation function for particle list + * \param _particles list of particles + * \return 0 on success, 1 on error + */ + int init_particles(std::vector &_particles); + + /** + * build initial list of left particles + */ + int init_pleft(); + + /** + * use an energy-dependent boundary for splitting + * When called with true, the criterium for splitting two protojets + * will be to compare D1^2/kt1^2 vs. D2^2/kt2^2, the (anti-)kt-weighted + * distance instead of the plain distance D1^2 vs. D2^2. + * This can be set in order to produce more circular hard jets, + * with the same underlying philosophy as for the anti-kt algorithm. + * We thus expect a behaviour closer to the IterativeCone one. + * By default, we use the standard D1^2 vs. D2^2 comparison and this + * function is not called. + */ + inline int set_E_weighted_splitting(bool _use_E_weighted_splitting){ + use_E_weighted_splitting = _use_E_weighted_splitting; + return 0; + } + + //////////////////////// + // cleaning functions // + //////////////////////// + + /// partial clearance + int partial_clear(); + + /// full clearance + int full_clear(); + + + ///////////////////////////////// + // main parts of the algorithm // + ///////////////////////////////// + + /** + * build the list 'p_uncol_hard' from p_remain by clustering + * collinear particles + * note that thins in only used for stable-cone detection + * so the parent_index field is unnecessary + * + * Note that soft particles are not removed here + * This is just a remnant from the trunk version + */ + int merge_collinear_and_remove_soft(); + + /** + * add a list of protocones + * \param protocones list of protocones (initial jet candidates) + * \param R2 cone radius (squared) + * \param Emin minimal emergy allowed for jets + * \return 0 on success, 1 on error + */ + int add_protocones(std::vector *protocones, double R2, double Emin=0.0); + + /** + * really do the splitting and merging + * At the end, the vector jets is filled with the jets found. + * the 'contents' field of each jets contains the indices + * of the particles included in that jet. + * \param overlap_tshold threshold for splitting/merging transition + * \param Emin minimal energy allowed for jets + * \return the number of jets is returned + */ + int perform(double overlap_tshold, double Emin=0.0); + + + ////////////////////////////// + // save and debug functions // + ////////////////////////////// + + /// save final jets + /// \param flux stream to save the jet contentss + int save_contents(FILE *flux); + + /// show jets/candidates status + int show(); + + // particle information + int n; ///< number of particles + std::vector particles; ///< list of particles + std::vector particles_norm2; ///< norm^2 of the particle (3-vect part) + int n_left; ///< numer of particles that does not belong to any jet + std::vector p_remain; ///< list of particles remaining to deal with + std::vector p_uncol_hard; ///< list of particles remaining with collinear clustering + int n_pass; ///< index of the run + + /// minimal difference in squared distance between a particle and + /// two overlapping protojets when doing a split (useful when + /// testing approx. collinear safety) + double most_ambiguous_split; + + // jets information + std::vector jets; ///< list of jets + + // working entries + int *indices; ///< maximal size array for indices works + int idx_size; ///< number of elements in indices1 + + /// The following flag indicates that identical protocones + /// are to be merged automatically each time around the split-merge + /// loop and before anything else happens. + /// + /// This flag is only effective if ALLOW_MERGE_IDENTICAL_PROTOCONES + /// is set in 'defines.h' + /// Note that this lead to infrared-unsafety so it is disabled + /// by default + bool merge_identical_protocones; + + /// member used for detailed comparisons of pt's + CSphsplit_merge_ptcomparison ptcomparison; + + /// stop split--merge when the SM_var of the hardest protojet + /// is below this cut-off. + /// This is not collinear-safe so you should not use this + /// variable unless you really know what you are doing + /// Note that the cut-off is set on the variable squared. + double SM_var2_hardest_cut_off; + + /// Energy cutoff for the particles to put in p_uncol_hard + /// this is meant to allow removing soft particles in the + /// stable-cone search. + double stable_cone_soft_E2_cutoff; + + private: + /** + * get the overlap between 2 jets + * \param j1 first jet + * \param j2 second jet + * \param v returned overlap^2 (determined by the choice of SM variable) + * \return true if overlapping, false if disjoint + */ + bool get_overlap(const CSphjet &j1, const CSphjet &j2, double *v); + + + /** + * split the two given jets. + * during this procedure, the jets j1 & j2 are replaced + * by 2 new jets. Common particles are associted to the + * closest initial jet. + * \param it_j1 iterator of the first jet in 'candidates' + * \param it_j2 iterator of the second jet in 'candidates' + * \param j1 first jet (CSphjet instance) + * \param j2 second jet (CSphjet instance) + * \return true on success, false on error + */ + bool split(cjet_iterator &it_j1, cjet_iterator &it_j2); + + /** + * merge the two given jet. + * during this procedure, the jets j1 & j2 are replaced + * by 1 single jets containing both of them. + * \param it_j1 iterator of the first jet in 'candidates' + * \param it_j2 iterator of the second jet in 'candidates' + * \return true on success, false on error + */ + bool merge(cjet_iterator &it_j1, cjet_iterator &it_j2); + + /** + * Check whether or not a jet has to be inserted in the + * list of protojets. If it has, set its sm_variable and + * insert it to the list of protojets. + * \param jet jet to insert + */ + bool insert(CSphjet &jet); + + /** + * given a 4-momentum and its associated pT, return the + * variable tht has to be used for SM + * \param v 4 momentum of the protojet + * \param E_tilde E_tilde of the protojet + */ + double get_sm_var2(CSphmomentum &v, double &E_tilde); + + /// compute Etilde for a given jet + void compute_Etilde(CSphjet &j); + + // jet information + /// list of jet candidates + std::auto_ptr > candidates; + + /// minimal E + double E_min; + + /** + * do we have or not to use the energy-weighted splitting + * (see description for set_E_weighted_splitting) + * This will be false by default + */ + bool use_E_weighted_splitting; + +#ifdef ALLOW_MERGE_IDENTICAL_PROTOCONES + /// checkxor for the candidates (to avoid having twice the same contents) + std::set cand_refs; +#endif +}; + +} + + +#endif diff --git a/JETAN/fastjet/siscone/spherical/vicinity.h b/JETAN/fastjet/siscone/spherical/vicinity.h new file mode 100644 index 00000000000..7446e7abf4c --- /dev/null +++ b/JETAN/fastjet/siscone/spherical/vicinity.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: vicinity.h // +// Description: header file for particle vicinity (Cvicinity class) // +// This file is part of the SISCone project. // +// WARNING: this is not the main SISCone trunk but // +// an adaptation to spherical coordinates // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 255 $// +// $Date:: 2008-07-12 17:40:35 +0200 (Sat, 12 Jul 2008) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPH_VICINITY_H__ +#define __SPH_VICINITY_H__ + +#include +#include +#include +#include "momentum.h" +#include +#ifdef USE_QUADTREE_FOR_STABILITY_TEST +#include +#endif + +namespace siscone_spherical{ + + +/** + * \class CSphvicinity_elm + * \brief element in the vicinity of a parent. + * + * class used to manage one points in the vicinity + * of a parent point. + */ +class CSphvicinity_elm{ + public: + /// pointer to the second borderline particle + CSphmomentum *v; + + /// variable to tell if the particle is inside or outside the cone + siscone::Cvicinity_inclusion *is_inside; + + // centre variables + CSph3vector centre; ///< direction of the centre + double angle; ///< angle with parent + bool side; ///< true if angle on the positive side, false otherwise + double cocircular_range; ///< amount by which the angle can be varied while + ///< maintaining this point within co-circularity margin + + /// list of elements co-circular with this one + /// NB: empty list uses less mem than vector + std::list cocircular; +}; + +/// ordering pointers to CSphvicinity_elm +bool ve_less(CSphvicinity_elm *ve1, CSphvicinity_elm *ve2); + + +/** + * \class CSphvicinity + * \brief list of element in the vicinity of a parent. + * + * class used to manage the points which are in the vicinity + * of a parent point. + */ +class CSphvicinity{ + public: + /// default constructor + CSphvicinity(); + + /// constructor with initialisation (see set_particle_list) + CSphvicinity(std::vector &_particle_list); + + /// default destructor + ~CSphvicinity(); + + /** + * set the particle_list + * \param _particle_list list of particles (type CSphmomentum) + */ + void set_particle_list(std::vector &_particle_list); + + /** + * build the vicinity list from the list of points. + * \param _parent reference particle + * \param _VR vicinity radius + */ + void build(CSphmomentum *_parent, double _VR); + + // cone kinematical information + CSphmomentum *parent; ///< parent vector + double VR; ///< radius of the vicinity + double VR2; ///< squared radius of the vicinity + double cosVR; ///< cosine of the radius of the vicinity + double R; ///< normal radius + double R2; ///< squared normal radius + double tan2R; ///< squared tangent of the normal radius + double D2_R; ///< euclidian distance (squared) corresp. to the arc R + double inv_R_EPS_COCIRC; ///< R / EPSILON_COCIRCULAR + double inv_R_2EPS_COCIRC; ///< R / (2*EPSILON_COCIRCULAR) + + // particle list information + int n_part; ///< number of particles + std::vector plist; ///< the list of particles + /// the inclusion state of particles + std::vector pincluded; + CSphvicinity_elm *ve_list; ///< list of vicinity elements built from particle list (size=2*n) +#ifdef USE_QUADTREE_FOR_STABILITY_TEST + siscone::Cquadtree *quadtree; ///< quadtree used for final stability tests +#endif + + // vicinity information + std::vector vicinity; ///< list of points in parent's vicinity + unsigned int vicinity_size; ///< number of elements in vicinity + + protected: + /** + * append a particle to the 'vicinity' list after + * having tested it and computed the angular-ordering quantities + * \param v vector to test + */ + void append_to_vicinity(CSphmomentum *v); + + // internal variables + CSph3vector parent_centre; ///< parent centre + CSph3vector angular_dir1; ///< main direction to measure angles + CSph3vector angular_dir2; ///< second direction to measure angles (sign) +}; + +} + +#endif diff --git a/JETAN/fastjet/siscone/split_merge.h b/JETAN/fastjet/siscone/split_merge.h new file mode 100644 index 00000000000..2100a92db39 --- /dev/null +++ b/JETAN/fastjet/siscone/split_merge.h @@ -0,0 +1,401 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: split_merge.h // +// Description: header file for splitting/merging (contains the CJet class) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 268 $// +// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __SPLIT_MERGE_H__ +#define __SPLIT_MERGE_H__ + +#include "defines.h" +#include "geom_2d.h" +#include "momentum.h" +#include +#include +#include +#include +#include + +namespace siscone{ + +/** + * \class Cjet + * real Jet information. + * + * This class contains information for one single jet. + * That is, first, its momentum carrying information + * about its centre and pT, and second, its particle + * contents + */ +class Cjet{ + public: + /// default ctor + Cjet(); + + /// default dtor + ~Cjet(); + + Cmomentum v; ///< jet momentum + double pt_tilde; ///< p-scheme pt + int n; ///< number of particles inside + std::vector contents; ///< particle contents (list of indices) + + /// ordering variable used for ordering and overlap in the + /// split--merge. This variable is automatically set either to + /// pt_tilde, or to mt or to pt, depending on the siscone + /// parameter. Note that the default behaviour is pt_tilde and that + /// other chices may lead to infrared unsafe situations. + /// Note: we use the square of the varible rather than the variable itself + double sm_var2; + + /// covered range in eta-phi + Ceta_phi_range range; + + /// pass at which the jet has been found + /// It starts at 0 (first pass), -1 means infinite rapidity + int pass; +}; + +/// ordering of jets in pt (e.g. used in final jets ordering) +bool jets_pt_less(const Cjet &j1, const Cjet &j2); + + +/// the choices of scale variable that can be used in the split-merge +/// step, both for ordering the protojets and for measuing their +/// overlap; pt, Et and mt=sqrt(pt^2+m^2) are all defined in E-scheme +/// (4-momentum) recombination; pttilde = \sum_{i\in jet} |p_{t,i}| +/// +/// NB: if one changes the order here, one _MUST_ also change the order +/// in the SISCone plugin +enum Esplit_merge_scale { + SM_pt, ///< transverse momentum (E-scheme), IR unsafe + SM_Et, ///< transverse energy (E-scheme), not long. boost inv. + ///< original run-II choice [may not be implemented] + SM_mt, ///< transverse mass (E-scheme), IR safe except + ///< in decays of two identical narrow heavy particles + SM_pttilde ///< pt-scheme pt = \sum_{i in jet} |p_{ti}|, should + ///< be IR safe in all cases +}; + +/// return the name of the split-merge scale choice +std::string split_merge_scale_name(Esplit_merge_scale sms); + +/** + * \class Csplit_merge_ptcomparison + * comparison of jets for split--merge ordering + * + * a class that allows us to carry out comparisons of pt of jets, using + * information from exact particle contents where necessary. + */ +class Csplit_merge_ptcomparison{ +public: + /// default ctor + Csplit_merge_ptcomparison() : + particles(0), split_merge_scale(SM_pttilde){}; + + /// return the name corresponding to the SM scale variable + std::string SM_scale_name() const { + return split_merge_scale_name(split_merge_scale);} + + std::vector * particles; ///< pointer to the list of particles + std::vector * pt; ///< pointer to the pt of the particles + + /// comparison between 2 jets + bool operator()(const Cjet &jet1, const Cjet &jet2) const; + + /** + * get the difference between 2 jets, calculated such that rounding + * errors will not affect the result even if the two jets have + * almost the same content (so that the difference is below the + * rounding errors) + * + * \param j1 first jet + * \param j2 second jet + * \param v jet1-jet2 + * \param pt_tilde jet1-jet2 pt_tilde + */ + void get_difference(const Cjet &j1, const Cjet &j2, Cmomentum *v, double *pt_tilde) const; + + /// the following parameter controls the variable we're using for + /// the split-merge process i.e. the variable we use for + /// 1. ordering jet candidates; + /// 2. computing te overlap fraction of two candidates. + /// The default value uses pttile (p-scheme pt). Other alternatives are + /// pt, mt=sqrt(pt^2+m^2)=sqrt(E^2-pz^2) or Et. + /// NOTE: Modifying the default choice can have nasty effects: + /// - using pt leads to some IR unsafety when we have two jets, + /// e.g. back-to-back, with the same pt. In that case, their ordering + /// in pt is random and can be affected by the addition of a + /// soft particle. Hence, we highly recommand to keep this to + /// the default value i.e. to use pt only for the purpose of + /// investigating the IR issue + /// - using Et is safe but do not respect boost invariance + /// - using mt solves the IR unsafety issues with the pt variable + /// for QCD jets but the IR unsafety remains for nack-to-back + /// jets of unstable narrow-width particles (e.g. Higgs). + /// Therefore, keeping the default value is strongly advised. + Esplit_merge_scale split_merge_scale; +}; + + +// iterator types +/// iterator definition for the jet candidates structure +typedef std::multiset::iterator cjet_iterator; + +/// iterator definition for the jet structure +typedef std::vector::iterator jet_iterator; + + + +/** + * \class Csplit_merge + * Class used to split and merge jets. + */ +class Csplit_merge{ + public: + /// default ctor + Csplit_merge(); + + /// default dtor + ~Csplit_merge(); + + + ////////////////////////////// + // initialisation functions // + ////////////////////////////// + + /** + * initialisation function + * \param _particles list of particles + * \param protocones list of protocones (initial jet candidates) + * \param R2 cone radius (squared) + * \param ptmin minimal pT allowed for jets + * \return 0 on success, 1 on error + */ + int init(std::vector &_particles, std::vector *protocones, double R2, double ptmin=0.0); + + /** + * initialisation function for particle list + * \param _particles list of particles + * \return 0 on success, 1 on error + */ + int init_particles(std::vector &_particles); + + /** + * build initial list of left particles + */ + int init_pleft(); + + /** + * use a pt-dependent boundary for splitting + * When called with true, the criterium for splitting two protojets + * will be to compare D1^2/kt1^2 vs. D2^2/kt2^2, the (anti-)kt-weighted + * distance instead of the plain distance D1^2 vs. D2^2. + * This can be set in order to produce more circular hard jets, + * with the same underlying philosophy as for the anti-kt algorithm. + * We thus expect a behaviour closer to the IterativeCone one. + * By default, we use the standard D1^2 vs. D2^2 comparison and this + * function is not called. + */ + inline int set_pt_weighted_splitting(bool _use_pt_weighted_splitting){ + use_pt_weighted_splitting = _use_pt_weighted_splitting; + return 0; + } + + //////////////////////// + // cleaning functions // + //////////////////////// + + /// partial clearance + int partial_clear(); + + /// full clearance + int full_clear(); + + + ///////////////////////////////// + // main parts of the algorithm // + ///////////////////////////////// + + /** + * build the list 'p_uncol_hard' from p_remain by clustering + * collinear particles and removing particles softer than + * stable_cone_soft_pt2_cutoff + * note that thins in only used for stable-cone detection + * so the parent_index field is unnecessary + */ + int merge_collinear_and_remove_soft(); + + /** + * add a list of protocones + * \param protocones list of protocones (initial jet candidates) + * \param R2 cone radius (squared) + * \param ptmin minimal pT allowed for jets + * \return 0 on success, 1 on error + */ + int add_protocones(std::vector *protocones, double R2, double ptmin=0.0); + + /** + * really do the splitting and merging + * At the end, the vector jets is filled with the jets found. + * the 'contents' field of each jets contains the indices + * of the particles included in that jet. + * \param overlap_tshold threshold for splitting/merging transition + * \param ptmin minimal pT allowed for jets + * \return the number of jets is returned + */ + int perform(double overlap_tshold, double ptmin=0.0); + + + ////////////////////////////// + // save and debug functions // + ////////////////////////////// + + /// save final jets + /// \param flux stream to save the jet contentss + int save_contents(FILE *flux); + + /// show jets/candidates status + int show(); + + // particle information + int n; ///< number of particles + std::vector particles; ///< list of particles + std::vector pt; ///< list of particles' pt + int n_left; ///< numer of particles that does not belong to any jet + std::vector p_remain; ///< list of particles remaining to deal with + std::vector p_uncol_hard; ///< list of particles remaining with collinear clustering + int n_pass; ///< index of the run + + /// minimal difference in squared distance between a particle and + /// two overlapping protojets when doing a split (useful when + /// testing approx. collinear safety) + double most_ambiguous_split; + + // jets information + std::vector jets; ///< list of jets + + // working entries + int *indices; ///< maximal size array for indices works + int idx_size; ///< number of elements in indices1 + + /// The following flag indicates that identical protocones + /// are to be merged automatically each time around the split-merge + /// loop and before anything else happens. + /// + /// This flag is only effective if ALLOW_MERGE_IDENTICAL_PROTOCONES + /// is set in 'defines.h' + /// Note that this lead to infrared-unsafety so it is disabled + /// by default + bool merge_identical_protocones; + + /// member used for detailed comparisons of pt's + Csplit_merge_ptcomparison ptcomparison; + + /// stop split--merge when the SM_var of the hardest protojet + /// is below this cut-off. + /// This is not collinear-safe so you should not use this + /// variable unless you really know what you are doing + /// Note that the cut-off is set on the variable squared. + double SM_var2_hardest_cut_off; + + /// pt cutoff for the particles to put in p_uncol_hard + /// this is meant to allow removing soft particles in the + /// stable-cone search. + double stable_cone_soft_pt2_cutoff; + + private: + /** + * get the overlap between 2 jets + * \param j1 first jet + * \param j2 second jet + * \param v returned overlap^2 (determined by the choice of SM variable) + * \return true if overlapping, false if disjoint + */ + bool get_overlap(const Cjet &j1, const Cjet &j2, double *v); + + + /** + * split the two given jets. + * during this procedure, the jets j1 & j2 are replaced + * by 2 new jets. Common particles are associted to the + * closest initial jet. + * \param it_j1 iterator of the first jet in 'candidates' + * \param it_j2 iterator of the second jet in 'candidates' + * \param j1 first jet (Cjet instance) + * \param j2 second jet (Cjet instance) + * \return true on success, false on error + */ + bool split(cjet_iterator &it_j1, cjet_iterator &it_j2); + + /** + * merge the two given jet. + * during this procedure, the jets j1 & j2 are replaced + * by 1 single jets containing both of them. + * \param it_j1 iterator of the first jet in 'candidates' + * \param it_j2 iterator of the second jet in 'candidates' + * \return true on success, false on error + */ + bool merge(cjet_iterator &it_j1, cjet_iterator &it_j2); + + /** + * Check whether or not a jet has to be inserted in the + * list of protojets. If it has, set its sm_variable and + * insert it to the list of protojets. + * \param jet jet to insert + */ + bool insert(Cjet &jet); + + /** + * given a 4-momentum and its associated pT, return the + * variable tht has to be used for SM + * \param v 4 momentum of the protojet + * \param pt_tilde pt_tilde of the protojet + */ + double get_sm_var2(Cmomentum &v, double &pt_tilde); + + // jet information + /// list of jet candidates + std::auto_ptr > candidates; + + /// minimal pt2 + double pt_min2; + + /** + * do we have or not to use the pt-weighted splitting + * (see description for set_pt_weighted_splitting) + * This will be false by default + */ + bool use_pt_weighted_splitting; + +#ifdef ALLOW_MERGE_IDENTICAL_PROTOCONES + /// checkxor for the candidates (to avoid having twice the same contents) + std::set cand_refs; +#endif +}; + +} + + +#endif diff --git a/JETAN/fastjet/siscone/vicinity.h b/JETAN/fastjet/siscone/vicinity.h new file mode 100644 index 00000000000..80ef15af8f5 --- /dev/null +++ b/JETAN/fastjet/siscone/vicinity.h @@ -0,0 +1,156 @@ +// -*- C++ -*- +/////////////////////////////////////////////////////////////////////////////// +// File: vicinity.h // +// Description: header file for particle vicinity (Cvicinity class) // +// This file is part of the SISCone project. // +// For more details, see http://projects.hepforge.org/siscone // +// // +// Copyright (c) 2006 Gavin Salam and Gregory Soyez // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program; if not, write to the Free Software // +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // +// // +// $Revision:: 123 $// +// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007) $// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __VICINITY_H__ +#define __VICINITY_H__ + +#include +#include +#include "momentum.h" +#include "defines.h" +#include "quadtree.h" + +namespace siscone{ + + + +/** + * \class Cvicinity_inclusion + * \brief a class to keep track of inclusion status in cone and in cocircular region + * while using minimal resources + */ +class Cvicinity_inclusion { +public: + /// default ctor + Cvicinity_inclusion() : cone(false), cocirc(false) {} + + bool cone; ///< flag for particle inclusion in the cone + bool cocirc; ///< flag for particle inclusion in the border +}; + + +/** + * \class Cvicinity_elm + * \brief element in the vicinity of a parent. + * + * class used to manage one points in the vicinity + * of a parent point. + */ +class Cvicinity_elm{ + public: + /// pointer to the second borderline particle + Cmomentum *v; + + /// variable to tell if the particle is inside or outside the cone + Cvicinity_inclusion *is_inside; + + // centre variables + double eta; ///< eta coordinate of the center + double phi; ///< phi coordinate of the center + double angle; ///< angle with parent + bool side; ///< true if angle on the positive side, false otherwise + double cocircular_range; ///< amount by which the angle can be varied while + ///< maintaining this point within co-circularity margin + + /// list of elements co-circular with this one + /// NB: empty list uses less mem than vector + std::list cocircular; +}; + +/// ordering pointers to Cvicinity_elm +bool ve_less(Cvicinity_elm *ve1, Cvicinity_elm *ve2); + + +/** + * \class Cvicinity + * \brief list of element in the vicinity of a parent. + * + * class used to manage the points which are in the vicinity + * of a parent point. + */ +class Cvicinity{ + public: + /// default constructor + Cvicinity(); + + /// constructor with initialisation (see set_particle_list) + Cvicinity(std::vector &_particle_list); + + /// default destructor + ~Cvicinity(); + + /** + * set the particle_list + * \param _particle_list list of particles (type Cmomentum) + */ + void set_particle_list(std::vector &_particle_list); + + /** + * build the vicinity list from the list of points. + * \param _parent reference particle + * \param _VR vicinity radius + */ + void build(Cmomentum *_parent, double _VR); + + // cone kinematical information + Cmomentum *parent; ///< parent vector + double VR; ///< radius of the vicinity + double VR2; ///< squared radius of the vicinity + double R; ///< normal radius + double R2; ///< squared normal radius + double inv_R_EPS_COCIRC; ///< R / EPSILON_COCIRCULAR + double inv_R_2EPS_COCIRC; ///< R / (2*EPSILON_COCIRCULAR) + + // particle list information + int n_part; ///< number of particles + std::vector plist; ///< the list of particles + std::vector pincluded; ///< the inclusion state of particles + Cvicinity_elm *ve_list; ///< list of vicinity elements built from particle list (size=2*n) +#ifdef USE_QUADTREE_FOR_STABILITY_TEST + Cquadtree *quadtree; ///< quadtree used for final stability tests +#endif + + // vicinity information + std::vector vicinity; ///< list of points in parent's vicinity + unsigned int vicinity_size; ///< number of elements in vicinity + + protected: + /** + * append a particle to the 'vicinity' list after + * having tested it and computed the angular-ordering quantities + * \param v vector to test + */ + void append_to_vicinity(Cmomentum *v); + + // internal variables + double pcx; ///< parent centre (eta) + double pcy; ///< parent centre (phi) +}; + +} + +#endif -- 2.43.5