22 #include "fastjet/tools/Recluster.hh"
23 #include "fastjet/CompositeJetStructure.hh"
24 #include <fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh>
46 FASTJET_BEGIN_NAMESPACE
48 LimitedWarning Recluster::_explicit_ghost_warning;
53 _acquire_recombiner(true), _keep(keep_in), _cambridge_optimisation_enabled(true){}
56 : _acquire_recombiner(true), _keep(keep_in), _cambridge_optimisation_enabled(true){
69 ostr <<
"Recluster with new_jet_def = ";
70 if (_acquire_recombiner){
72 ostr <<
", using a recombiner obtained from the jet being reclustered";
78 ostr <<
" and keeping the hardest inclusive jet";
80 ostr <<
" and joining all inclusive jets into a composite jet";
90 vector<PseudoJet> incljets;
109 vector<PseudoJet> & output_jets)
const{
114 throw Error(
"Recluster can only be applied on jets having constituents");
125 vector<PseudoJet> all_pieces;
126 if ((!_get_all_pieces(input_jet, all_pieces)) || (all_pieces.size()==0)){
127 throw Error(
"Recluster: failed to retrieve all the pieces composing the jet.");
133 if (_acquire_recombiner){
134 _acquire_recombiner_from_pieces(all_pieces, new_jet_def);
152 if (_check_ca(all_pieces, new_jet_def)){
153 _recluster_ca(all_pieces, output_jets, new_jet_def.R());
160 bool include_area_support = input_jet.
has_area();
161 if ((include_area_support) && (!_check_explicit_ghosts(all_pieces))){
162 _explicit_ghost_warning.
warn(
"Recluster: the original cluster sequence is lacking explicit ghosts; area support will no longer be available after re-clustering");
163 include_area_support =
false;
168 _recluster_generic(input_jet, output_jets, new_jet_def, include_area_support);
177 bool ca_optimisation_used)
const{
180 if (incljets.size() > 0) {
190 if (incljets.size()==0)
return join(incljets);
193 *(incljets[0].associated_cluster_sequence()->jet_def().recombiner()));
199 if (ca_optimisation_used){
201 (incljets.size() > 0) &&
202 (! incljets[0].validated_csab()->has_explicit_ghosts())){
217 void Recluster::_recluster_ca(
const vector<PseudoJet> & all_pieces,
218 vector<PseudoJet> & subjets,
224 for (vector<PseudoJet>::const_iterator piece_it = all_pieces.begin();
225 piece_it!=all_pieces.end(); piece_it++){
228 vector<PseudoJet> local_subjets;
230 double dcut = Rfilt / cs->
jet_def().R();
236 local_subjets.push_back(*piece_it);
238 local_subjets = piece_it->exclusive_subjets(dcut*dcut);
241 copy(local_subjets.begin(), local_subjets.end(), back_inserter(subjets));
248 void Recluster::_recluster_generic(
const PseudoJet & jet,
249 vector<PseudoJet> & incljets,
250 const JetDefinition & new_jet_def,
251 bool do_areas)
const{
265 vector<PseudoJet> regular_constituents, ghosts;
271 double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
272 ClusterSequenceActiveAreaExplicitGhosts * csa
273 =
new ClusterSequenceActiveAreaExplicitGhosts(regular_constituents,
277 incljets = csa->inclusive_jets();
287 csa->delete_self_when_unused();
291 ClusterSequence * cs =
new ClusterSequence(jet.constituents(), new_jet_def);
296 cs->delete_self_when_unused();
313 bool Recluster::_get_all_pieces(
const PseudoJet &jet, vector<PseudoJet> &all_pieces)
const{
314 if (jet.has_associated_cluster_sequence()){
315 all_pieces.push_back(jet);
319 if (jet.has_pieces()){
320 const vector<PseudoJet> pieces = jet.pieces();
321 for (vector<PseudoJet>::const_iterator it=pieces.begin(); it!=pieces.end(); it++)
322 if (!_get_all_pieces(*it, all_pieces))
return false;
332 void Recluster::_acquire_recombiner_from_pieces(
const vector<PseudoJet> &all_pieces,
333 JetDefinition &new_jet_def)
const{
335 assert(_acquire_recombiner);
342 const JetDefinition & jd_ref = all_pieces[0].validated_cs()->jet_def();
343 for (
unsigned int i=1; i<all_pieces.size(); i++){
344 if (!all_pieces[i].validated_cs()->jet_def().has_same_recombiner(jd_ref)){
345 throw Error(
"Recluster instance is configured to determine the recombination scheme (or recombiner) from the original jet, but different pieces of the jet were found to have non-equivalent recombiners.");
350 new_jet_def.set_recombiner(jd_ref);
362 bool Recluster::_check_explicit_ghosts(
const vector<PseudoJet> &all_pieces)
const{
363 for (vector<PseudoJet>::const_iterator it=all_pieces.begin(); it!=all_pieces.end(); it++)
364 if (! it->validated_csab()->has_explicit_ghosts())
return false;
383 bool Recluster::_check_ca(
const vector<PseudoJet> &all_pieces,
384 const JetDefinition &new_jet_def)
const{
386 if (!_cambridge_optimisation_enabled)
return false;
394 const ClusterSequence * cs_ref = all_pieces[0].validated_cs();
396 for (
unsigned int i=1; i<all_pieces.size(); i++)
397 if (all_pieces[i].validated_cs() != cs_ref)
return false;
402 if (!cs_ref->jet_def().has_same_recombiner(new_jet_def))
return false;
406 double Rnew2 = new_jet_def.R();
408 for (
unsigned int i=0; i<all_pieces.size()-1; i++){
409 for (
unsigned int j=i+1; j<all_pieces.size(); j++){
410 if (all_pieces[i].squared_distance(all_pieces[j]) < Rnew2)
return false;
417 FASTJET_END_NAMESPACE