// JetsWithoutJets Package // Questions/Comments? danbert@mit.edu jthaler@mit.edu // // Copyright (c) 2013 // Daniele Bertolini and Jesse Thaler // // $Id$ //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It 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. // // It 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 code. If not, see . //---------------------------------------------------------------------- #include "EventStorage.hh" using namespace std; FASTJET_BEGIN_NAMESPACE namespace jwj { ////// // // ParticleStorage // ////// // find distance in rapidity-azimuth plane between this particle and other double ParticleStorage::deltaRsq(const ParticleStorage & other) const { double deltaRap=rap()-other.rap(); double deltaPhi=abs(phi()-other.phi()); if(deltaPhi > pi) deltaPhi=twopi-deltaPhi; return(deltaRap*deltaRap+deltaPhi*deltaPhi); } ////// // // LocalStorage // ////// // Creates storage array void LocalStorage::establishStorage(const std::vector & myParticles, double Rjet, double ptcut) { // set radius and ptcut _Rjet = Rjet; _ptcut = ptcut; // Dividing up Phase Space to bins of (approximate) size 2R by 2R // Actually makes bins of size bigger than 2R by 2R such that / // we have equal spacing of regions. // (This index scheme need to be synced with getRapIndex/getPhiIndex) _maxRapIndex = (int) floor((_rapmax)/_Rjet);// 2 rapmax / 2 Rjet _rapSpread = 2.0*_rapmax/(floor((_rapmax)/_Rjet)); _maxPhiIndex = (int) floor((M_PI)/_Rjet); // 2 pi / 2 Rjet _phiSpread = 2.0*M_PI/(floor((M_PI)/_Rjet)); // Initializing storage _regionStorage.resize(_maxRapIndex); _aboveCutBool.resize(_maxRapIndex); for (int rapIndex = 0 ; rapIndex < _maxRapIndex ; rapIndex++) { _regionStorage[rapIndex].resize(_maxPhiIndex); _aboveCutBool[rapIndex].resize(_maxPhiIndex); for (int phiIndex = 0; phiIndex < _maxPhiIndex; phiIndex++) { _regionStorage[rapIndex][phiIndex].clear(); } } // looping through particles and assigning to bins for (unsigned int i = 0; i < myParticles.size(); i++) { double rap = myParticles[i].rap(); double phi = myParticles[i].phi(); // find index for particle int lowRap = (int) floor((rap + _rapmax)/_rapSpread); int highRap = (int) ceil((rap + _rapmax)/_rapSpread); int lowPhi = (int) floor(phi/_phiSpread); int highPhi = (int) ceil(phi/_phiSpread); if (highPhi >= _maxPhiIndex) highPhi = highPhi - _maxPhiIndex; // loop around // if out of bounds, set to be in bounds. if (lowRap < 0) lowRap = 0; if (lowRap >= _maxRapIndex) lowRap = _maxRapIndex-1; if (highRap < 0) highRap = 0; if (highRap >= _maxRapIndex) highRap = _maxRapIndex-1; // Fill in storage. For particles at periphery in rapidity, only fill two bins instead of four. If phi overlaps, do the same thing. _regionStorage[lowRap][lowPhi].push_back(i); if (lowPhi != highPhi) _regionStorage[lowRap][highPhi].push_back(i); if (lowRap != highRap) _regionStorage[highRap][lowPhi].push_back(i); if (lowRap != highRap && lowPhi != highPhi) _regionStorage[highRap][highPhi].push_back(i); } // store whether above ptCut values for (int rapIndex = 0; rapIndex < _maxRapIndex; rapIndex++) { for (int phiIndex = 0; phiIndex < _maxPhiIndex; phiIndex++) { _aboveCutBool[rapIndex][phiIndex] = (getSumPt(myParticles,_regionStorage[rapIndex][phiIndex]) >= ptcut); } } } // What is the rapidity index? (Sync with LocalStorage::establishStorage) int LocalStorage::getRapIndex(const ParticleStorage & myParticle) const { double rap = myParticle.rap(); int rapIndex = round((rap + _rapmax)/_rapSpread); if (rapIndex < 0) rapIndex = 0; if (rapIndex >= _maxRapIndex) rapIndex = _maxRapIndex - 1; return rapIndex; } // what is the phi index? (Sync with LocalStorage::establishStorage) int LocalStorage::getPhiIndex(const ParticleStorage & myParticle) const { double phi = myParticle.phi(); int phiIndex = round(phi/_phiSpread); if (phiIndex >= _maxPhiIndex) phiIndex = phiIndex - _maxPhiIndex; return phiIndex; } const vector & LocalStorage::getStorageFor(const ParticleStorage & myParticle) const { return _regionStorage[getRapIndex(myParticle)][getPhiIndex(myParticle)]; } bool LocalStorage::aboveCutFor(const ParticleStorage & myParticle) { return _aboveCutBool[getRapIndex(myParticle)][getPhiIndex(myParticle)]; } double LocalStorage::getSumPt(const std::vector & Particles, const std::vector myIds) const { double myPt = 0; for(unsigned int i=0; i & particles){ _storage.resize(0); _ids.resize(0); for(unsigned int i=0; i* myLocalRegion = &_ids; for (unsigned int i=0; i<_storage.size(); i++){ double pt_in_Rjet,pt_in_Rsub,m_in_Rjet; vector neighbors; _storage[i].set_includeParticle(false); if (_useLocalStorage) { // start from rapidity/phi blocks if (!myLocalStorage.aboveCutFor(_storage[i])) continue; //don't do any further analysis if not above jet pTcut // if using local storage (and the region is above ptcut) then region of interest // where to look for the neighborhood (i.e. Rjet/Rsub circles) of the particle is // given by the local storage (2R_jet by 2R_jet region) else myLocalRegion = &myLocalStorage.getStorageFor(_storage[i]); } // helper function to get all of the relevant information about neighbors _get_local_info(i, myLocalRegion, pt_in_Rjet, pt_in_Rsub, m_in_Rjet,neighbors); // See if there is enough pt in the neighborhood to pass _ptcut if (pt_in_Rjet < _ptcut) continue; assert(_Rsub <= _Rjet); if (pt_in_Rsub/pt_in_Rjet < _fcut) continue; _storage[i].set_includeParticle(true); _storage[i].set_pt_in_Rjet(pt_in_Rjet); _storage[i].set_pt_in_Rsub(pt_in_Rsub); _storage[i].set_m_in_Rjet(m_in_Rjet); // empty information if _storeMass is off _storage[i].set_neighbors(neighbors); // empty information if _storeNeighbors is off _storage[i].set_weight(_storage[i].pt()/pt_in_Rjet); } } // helper function to calculate local info around each particle. // myLocalregion tells where to look, either the whole set of particles or a 2Rx2R // local region if LocalStorage is in use // Note that this function is calculating more information than is strictly necessary // but this is helpful if information has to be reused. void EventStorage::_get_local_info(const unsigned int id, const vector* myLocalRegion, double & pt_in_Rjet, double & pt_in_Rsub, double & m_in_Rjet, std::vector & neighbors) const { double Rjetsq = _Rjet*_Rjet; double Rsubsq = _Rsub*_Rsub; pt_in_Rjet = 0.0; pt_in_Rsub = 0.0; m_in_Rjet = 0.0; neighbors.resize(0); PseudoJet pj_in_Rjet(0.0,0.0,0.0,0.0); for (unsigned int i=0; isize(); i++) { double deltaRsq=_storage[id].deltaRsq(_storage[myLocalRegion->at(i)]); if(deltaRsq <= Rjetsq) { pt_in_Rjet += _storage[myLocalRegion->at(i)].pt(); if (_storeMass) pj_in_Rjet += _storage[myLocalRegion->at(i)].pseudoJet(); if (_storeNeighbors) neighbors.push_back(myLocalRegion->at(i)); if (deltaRsq <= Rsubsq) pt_in_Rsub += _storage[myLocalRegion->at(i)].pt(); } } m_in_Rjet = pj_in_Rjet.m(); } } // namespace jwj FASTJET_END_NAMESPACE