[264] | 1 | /*
|
---|
| 2 | ---- Delphes ----
|
---|
| 3 | A Fast Simulator for general purpose LHC detector
|
---|
| 4 | S. Ovyn ~~~~ severine.ovyn@uclouvain.be
|
---|
| 5 |
|
---|
| 6 | Center for Particle Physics and Phenomenology (CP3)
|
---|
| 7 | Universite Catholique de Louvain (UCL)
|
---|
| 8 | Louvain-la-Neuve, Belgium
|
---|
| 9 | */
|
---|
| 10 |
|
---|
| 11 | /// \file D_CaloUtil.cc
|
---|
| 12 | /// \brief Implementation of D_CaloElement, D_CaloResolution and D_CaloList classes
|
---|
| 13 |
|
---|
| 14 | #include "CaloUtil.h"
|
---|
| 15 | #include <cmath>
|
---|
| 16 | #include <algorithm>
|
---|
| 17 | #include <iostream>
|
---|
| 18 | #include "TRandom.h"
|
---|
| 19 |
|
---|
| 20 | D_CaloElement& D_CaloElement::operator=(const D_CaloElement& calo) {
|
---|
| 21 | if(this == &calo) return *this;
|
---|
| 22 | _name = calo._name;
|
---|
| 23 | _etamin = calo._etamin;
|
---|
| 24 | _etamax = calo._etamax;
|
---|
| 25 | _resol_em = calo._resol_em;
|
---|
| 26 | _resol_had= calo._resol_had;
|
---|
| 27 | return *this;
|
---|
| 28 | }
|
---|
| 29 |
|
---|
| 30 | D_CaloResolution& D_CaloResolution::operator=(const D_CaloResolution& resolution) {
|
---|
| 31 | if(this == &resolution) return *this;
|
---|
| 32 | _c = resolution._c;
|
---|
| 33 | _n = resolution._n;
|
---|
| 34 | _s = resolution._s;
|
---|
| 35 | return *this;
|
---|
| 36 | }
|
---|
| 37 |
|
---|
| 38 | void D_CaloResolution::print() const {
|
---|
| 39 | std::cout << "C: " << _c << " N:" << _n << " S:" << _s << std::endl;
|
---|
| 40 | }
|
---|
| 41 |
|
---|
| 42 | const D_CaloElement& D_CaloList::getElement(const float eta) const {
|
---|
| 43 | for (unsigned int i=0; i<_calorimeters.size(); i++) {
|
---|
| 44 | if(_calorimeters[i].getEtamin() < eta && eta < _calorimeters[i].getEtamax()) return _calorimeters[i];
|
---|
| 45 | }
|
---|
| 46 | // if not found
|
---|
| 47 | return dummyCalo;
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | void D_CaloList::addElement(const D_CaloElement & calo) {
|
---|
| 51 | _sorted = false;
|
---|
| 52 | _calorimeters.push_back(calo);
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | void D_CaloList::sortElements() {
|
---|
| 56 | // here: it sorts the elements with respect to their eta
|
---|
| 57 | sort(_calorimeters.begin(),_calorimeters.end(),ordering());
|
---|
| 58 |
|
---|
| 59 | for (unsigned int i=0; i<_calorimeters.size()-1; i++) {
|
---|
| 60 | if(_calorimeters[i].getEtamax() > _calorimeters[i+1].getEtamin() ) {
|
---|
| 61 | _etamin = UNDEFINED;
|
---|
| 62 | _etamax = UNDEFINED;
|
---|
| 63 | cerr << "** Error: the calorimeter list should never contain overlapping **"<< endl;
|
---|
| 64 | cerr << "** calorimeters. **"<< endl;
|
---|
| 65 | return;
|
---|
| 66 | }
|
---|
| 67 | }
|
---|
| 68 | _etamin = _calorimeters[0].getEtamin();
|
---|
| 69 | _etamax = _calorimeters[_calorimeters.size()-1].getEtamax();
|
---|
| 70 | _sorted = true;
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 | D_CaloList& D_CaloList::operator=(const D_CaloList& list) {
|
---|
| 74 | if(this == &list) return *this;
|
---|
| 75 | _calorimeters = list._calorimeters;
|
---|
| 76 | _etamin = list._etamin;
|
---|
| 77 | _etamax = list._etamax;
|
---|
| 78 | _sorted = list._sorted;
|
---|
| 79 | return *this;
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | void D_CaloList::print() const {
|
---|
| 83 | if(_sorted) cout << "The list has been sorted\n";
|
---|
| 84 | else cout << "The list has not been sorted\n";
|
---|
| 85 |
|
---|
| 86 | for (unsigned int i=0; i<_calorimeters.size(); i++) {
|
---|
| 87 | std::cout << _calorimeters[i].getName() << " " << _calorimeters[i].getEtamin() <<
|
---|
| 88 | " " << _calorimeters[i].getEtamax() << std::endl;
|
---|
| 89 | _calorimeters[i].getElectromagneticResolution().print();
|
---|
| 90 | _calorimeters[i].getHadronicResolution().print();
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 | }
|
---|
| 94 |
|
---|
| 95 |
|
---|
| 96 |
|
---|
| 97 |
|
---|
| 98 |
|
---|
| 99 |
|
---|
| 100 |
|
---|
| 101 |
|
---|
| 102 | D_CaloTower::D_CaloTower(const float iEta, const float iPhi) :
|
---|
| 103 | _eta(iEta), _phi(iPhi), _Eem(UNDEFINED), _Ehad(UNDEFINED), _E(UNDEFINED), _ET(UNDEFINED) {}
|
---|
| 104 |
|
---|
| 105 | D_CaloTower::D_CaloTower(const D_CaloTower& tower) :
|
---|
| 106 | _eta(tower._eta), _phi(tower._phi), _Eem(tower._Eem),
|
---|
| 107 | _Ehad(tower._Ehad), _E(tower._E), _ET(tower._ET) {}
|
---|
| 108 |
|
---|
| 109 | D_CaloTower& D_CaloTower::operator=(const D_CaloTower& tower) {
|
---|
| 110 | if(this==&tower) return *this;
|
---|
| 111 | _eta = tower._eta; _phi = tower._phi;
|
---|
| 112 | _Eem = tower._Eem; _Ehad = tower._Ehad;
|
---|
| 113 | _E = tower._E; _ET = tower._ET;
|
---|
| 114 | return *this;
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 |
|
---|
| 118 | const float D_CaloResolution::Smear(const float energy) const {
|
---|
| 119 | float sE = gRandom->Gaus(energy,
|
---|
| 120 | sqrt( pow(_n,2) +
|
---|
| 121 | pow(_c*energy,2) +
|
---|
| 122 | pow(_s*sqrt(energy),2) ));
|
---|
| 123 | return (sE>0)? sE : 0;
|
---|
| 124 | }
|
---|
| 125 |
|
---|
| 126 | const bool D_CaloTower::operator==(const D_CaloTower& el) const { if (this == &el) return true; return this->_eta==el._eta && this->_phi == el._phi;}
|
---|
| 127 |
|
---|
| 128 | void D_CaloTowerList::addTower(const D_CaloTower& tower) {
|
---|
| 129 | _calotowers.push_back(tower);
|
---|
| 130 | _sorted = false;
|
---|
| 131 | _merged = false;
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | D_CaloTowerList& D_CaloTowerList::operator=(const D_CaloTowerList& list) {
|
---|
| 135 | if(this==&list) return *this;
|
---|
| 136 | _calotowers = list._calotowers;
|
---|
| 137 | _sorted = list._sorted;
|
---|
| 138 | _merged = list._merged;
|
---|
| 139 | return *this;
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | void D_CaloTowerList::sortElements() {
|
---|
| 143 | _sorted = true;
|
---|
| 144 | if(_calotowers.size()==0) return;
|
---|
| 145 | sort(_calotowers.begin(),_calotowers.end(),ordering());
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | void D_CaloTowerList::mergeDuplicates() {
|
---|
| 149 | if(!_sorted) sortElements();
|
---|
| 150 | _merged = true;
|
---|
| 151 | if (_calotowers.size() ==0) { return;}
|
---|
| 152 |
|
---|
| 153 | vector<D_CaloTower> temp;
|
---|
| 154 | temp.push_back(_calotowers[0]);
|
---|
| 155 | for (unsigned int i=1; i<_calotowers.size(); i++) {
|
---|
| 156 |
|
---|
| 157 | if(temp[temp.size()-1] == _calotowers[i]) {
|
---|
| 158 | //i.e. if towers have the same eta/phi
|
---|
| 159 | float em = temp[temp.size()-1].getEem() + _calotowers[i].getEem();
|
---|
| 160 | float had= temp[temp.size()-1].getEhad()+ _calotowers[i].getEhad();
|
---|
| 161 | temp[temp.size()-1].Set_Eem_Ehad_E_ET(em,had);
|
---|
| 162 | }
|
---|
| 163 | else temp.push_back(_calotowers[i]);
|
---|
| 164 |
|
---|
| 165 | }
|
---|
| 166 | _calotowers = temp;
|
---|
| 167 | }
|
---|
| 168 |
|
---|
| 169 | void D_CaloTowerList::print() const {
|
---|
| 170 | for (unsigned int i=0; i<_calotowers.size(); i++) {
|
---|
| 171 | std::cout << _calotowers[i].getEta() << " " <<
|
---|
| 172 | _calotowers[i].getPhi() << " " <<
|
---|
| 173 | _calotowers[i].getEem() << " " <<
|
---|
| 174 | _calotowers[i].getEhad() << std::endl;
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 |
|
---|
| 178 | void D_CaloTowerList::smearTowers(const D_CaloList& list_of_calorimeters) {
|
---|
| 179 | for (unsigned int i=0; i<_calotowers.size(); i++) {
|
---|
| 180 | // first, finds in which calo the tower is, in order to have its resolution em /had
|
---|
| 181 | D_CaloElement currentCalo = list_of_calorimeters.getElement(_calotowers[i].getEta() );
|
---|
| 182 | // then, smears separately the em and had parts
|
---|
| 183 | float sEem = currentCalo.getElectromagneticResolution().Smear( _calotowers[i].getEem() );
|
---|
| 184 | float sEhad = currentCalo.getHadronicResolution().Smear( _calotowers[i].getEhad() );
|
---|
| 185 | // finally, sets the tower smeared energy
|
---|
| 186 | _calotowers[i].Set_Eem_Ehad_E_ET(sEem,sEhad);
|
---|
| 187 | }
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 |
|
---|
| 191 | const bool D_CaloTower::operator>(const D_CaloTower& tocomp) const {
|
---|
| 192 | if(_eta == tocomp._eta) {
|
---|
| 193 | if(_phi > tocomp._phi) return true;
|
---|
| 194 | else return false;
|
---|
| 195 | }
|
---|
| 196 | else if(_eta > tocomp._eta) return true;
|
---|
| 197 | else return false;
|
---|
| 198 | };
|
---|
| 199 |
|
---|
| 200 | const bool D_CaloTower::operator<(const D_CaloTower& tocomp) const {
|
---|
| 201 | if(_eta == tocomp._eta) {
|
---|
| 202 | if(_phi < tocomp._phi) return true;
|
---|
| 203 | else return false;
|
---|
| 204 | }
|
---|
| 205 | else if(_eta < tocomp._eta) return true;
|
---|
| 206 | else return false;
|
---|
| 207 | };
|
---|
| 208 |
|
---|
| 209 | const D_CaloTower& D_CaloTowerList::getElement(const float eta, const float phi) {
|
---|
| 210 | if(!_sorted) sortElements();
|
---|
| 211 | for (unsigned int i=0; i< _calotowers.size(); i++) {
|
---|
| 212 | if(_calotowers[i].getEta() == eta &&
|
---|
| 213 | _calotowers[i].getPhi() == phi )
|
---|
| 214 | return _calotowers[i];
|
---|
| 215 | }
|
---|
| 216 | return dummyTower; // if not found
|
---|
| 217 | }
|
---|