00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "fastjet/Error.hh"
00033 #include "fastjet/PseudoJet.hh"
00034 #include<valarray>
00035 #include<iostream>
00036 #include<sstream>
00037 #include<cmath>
00038
00039 FASTJET_BEGIN_NAMESPACE
00040
00041 using namespace std;
00042
00043
00044
00045
00046 PseudoJet::PseudoJet(const double px, const double py, const double pz, const double E) {
00047
00048 _E = E ;
00049 _px = px;
00050 _py = py;
00051 _pz = pz;
00052
00053 this->_finish_init();
00054 };
00055
00056
00057
00059 void PseudoJet::_finish_init () {
00060 _kt2 = this->px()*this->px() + this->py()*this->py();
00061 if (_kt2 == 0.0) {
00062 _phi = 0.0; }
00063 else {
00064 _phi = atan2(this->py(),this->px());
00065 }
00066 if (_phi < 0.0) {_phi += twopi;}
00067 if (_phi >= twopi) {_phi -= twopi;}
00068 if (this->E() == abs(this->pz()) && _kt2 == 0) {
00069
00070
00071
00072
00073 double MaxRapHere = MaxRap + abs(this->pz());
00074 if (this->pz() >= 0.0) {_rap = MaxRapHere;} else {_rap = -MaxRapHere;}
00075 } else {
00076
00077
00078
00079 double effective_m2 = max(0.0,m2());
00080 double E_plus_pz = _E + abs(_pz);
00081
00082 _rap = 0.5*log((_kt2 + effective_m2)/(E_plus_pz*E_plus_pz));
00083 if (_pz > 0) {_rap = - _rap;}
00084 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 }
00095
00096
00097
00098
00099 valarray<double> PseudoJet::four_mom() const {
00100 valarray<double> mom(4);
00101 mom[0] = _px;
00102 mom[1] = _py;
00103 mom[2] = _pz;
00104 mom[3] = _E ;
00105 return mom;
00106 }
00107
00108
00109
00110
00111 double PseudoJet::operator () (int i) const {
00112 switch(i) {
00113 case X:
00114 return px();
00115 case Y:
00116 return py();
00117 case Z:
00118 return pz();
00119 case T:
00120 return e();
00121 default:
00122 ostringstream err;
00123 err << "PseudoJet subscripting: bad index (" << i << ")";
00124 throw Error(err.str());
00125 }
00126 return 0.;
00127 }
00128
00129
00130
00131 PseudoJet operator+ (const PseudoJet & jet1, const PseudoJet & jet2) {
00132
00133 return PseudoJet(jet1.px()+jet2.px(),
00134 jet1.py()+jet2.py(),
00135 jet1.pz()+jet2.pz(),
00136 jet1.E() +jet2.E() );
00137 }
00138
00139
00140
00141 PseudoJet operator- (const PseudoJet & jet1, const PseudoJet & jet2) {
00142
00143 return PseudoJet(jet1.px()-jet2.px(),
00144 jet1.py()-jet2.py(),
00145 jet1.pz()-jet2.pz(),
00146 jet1.E() -jet2.E() );
00147 }
00148
00149
00150
00151 PseudoJet operator* (double coeff, const PseudoJet & jet) {
00152
00153
00154 PseudoJet coeff_times_jet(jet);
00155 coeff_times_jet *= coeff;
00156 return coeff_times_jet;
00157 }
00158
00159
00160
00161 PseudoJet operator* (const PseudoJet & jet, double coeff) {
00162 return coeff*jet;
00163 }
00164
00165
00166
00167 PseudoJet operator/ (const PseudoJet & jet, double coeff) {
00168 return (1.0/coeff)*jet;
00169 }
00170
00171
00173 void PseudoJet::operator*=(double coeff) {
00174 _px *= coeff;
00175 _py *= coeff;
00176 _pz *= coeff;
00177 _E *= coeff;
00178 _kt2*= coeff*coeff;
00179
00180 }
00181
00182
00184 void PseudoJet::operator/=(double coeff) {
00185 (*this) *= 1.0/coeff;
00186 }
00187
00188
00189
00191 void PseudoJet::operator+=(const PseudoJet & other_jet) {
00192 _px += other_jet._px;
00193 _py += other_jet._py;
00194 _pz += other_jet._pz;
00195 _E += other_jet._E ;
00196 _finish_init();
00197 }
00198
00199
00200
00202 void PseudoJet::operator-=(const PseudoJet & other_jet) {
00203 _px -= other_jet._px;
00204 _py -= other_jet._py;
00205 _pz -= other_jet._pz;
00206 _E -= other_jet._E ;
00207 _finish_init();
00208 }
00209
00210
00211
00212
00213 double PseudoJet::kt_distance(const PseudoJet & other) const {
00214
00215 double distance = min(_kt2, other._kt2);
00216 double dphi = abs(_phi - other._phi);
00217 if (dphi > pi) {dphi = twopi - dphi;}
00218 double drap = _rap - other._rap;
00219 distance = distance * (dphi*dphi + drap*drap);
00220 return distance;
00221 }
00222
00223
00224
00225
00226 double PseudoJet::plain_distance(const PseudoJet & other) const {
00227 double dphi = abs(_phi - other._phi);
00228 if (dphi > pi) {dphi = twopi - dphi;}
00229 double drap = _rap - other._rap;
00230 return (dphi*dphi + drap*drap);
00231 }
00232
00233
00234
00235
00236 void sort_indices(vector<int> & indices,
00237 const vector<double> & values) {
00238 IndexedSortHelper index_sort_helper(&values);
00239 sort(indices.begin(), indices.end(), index_sort_helper);
00240 }
00241
00242
00246 template<class T> vector<T> objects_sorted_by_values(
00247 const vector<T> & objects,
00248 const vector<double> & values) {
00249
00250 assert(objects.size() == values.size());
00251
00252
00253 vector<int> indices(values.size());
00254 for (size_t i = 0; i < indices.size(); i++) {indices[i] = i;}
00255
00256
00257 sort_indices(indices, values);
00258
00259
00260 vector<T> objects_sorted(objects.size());
00261
00262
00263 for (size_t i = 0; i < indices.size(); i++) {
00264 objects_sorted[i] = objects[indices[i]];
00265 }
00266
00267 return objects_sorted;
00268 }
00269
00270
00272 vector<PseudoJet> sorted_by_pt(const vector<PseudoJet> & jets) {
00273 vector<double> minus_kt2(jets.size());
00274 for (size_t i = 0; i < jets.size(); i++) {minus_kt2[i] = -jets[i].kt2();}
00275 return objects_sorted_by_values(jets, minus_kt2);
00276 }
00277
00278
00280 vector<PseudoJet> sorted_by_rapidity(const vector<PseudoJet> & jets) {
00281 vector<double> rapidities(jets.size());
00282 for (size_t i = 0; i < jets.size(); i++) {rapidities[i] = jets[i].rap();}
00283 return objects_sorted_by_values(jets, rapidities);
00284 }
00285
00286
00288 vector<PseudoJet> sorted_by_E(const vector<PseudoJet> & jets) {
00289 vector<double> energies(jets.size());
00290 for (size_t i = 0; i < jets.size(); i++) {energies[i] = -jets[i].E();}
00291 return objects_sorted_by_values(jets, energies);
00292 }
00293
00294
00295 FASTJET_END_NAMESPACE
00296