00001 #include <iostream>
00002 #include <cmath>
00003 #include <cstdlib>
00004
00005 #include "AtlfastAlgs/MuonSpectrometer.h"
00006
00007 namespace Atlfast{
00008
00009
00010
00011 double dEnergyLoss(double eta, double pT){
00012
00013
00014
00015
00016
00017 eta = fabs(eta);
00018 double theta = 2.*atan(exp(-eta));
00019 double sintheta = sin(theta);
00020 double energy = fabs(pT)/sintheta;
00021 double factor = (eta < 1.1) ? 1./sqrt(sintheta) : sqrt(14./11.);
00022 double dEloss = (eta < 1.1) ?
00023 factor*(240. + 0.105*energy/100.)/energy :
00024 factor*(480. + 0.105*energy/100.)/energy;
00025
00026 return dEloss;
00027
00028 }
00029
00030 double dEnergyLoss(const HepLorentzVector& avec){
00031 return dEnergyLoss(avec.pseudoRapidity(),avec.perp());
00032 }
00033
00034
00035
00036
00037
00038 IsCorrectEtaBin::IsCorrectEtaBin(double eta):
00039 m_eta(eta){}
00040 bool IsCorrectEtaBin::operator()(EtaBin& eb){
00041
00042 return ( m_eta >= eb.getEtaMin() && m_eta < eb.getEtaMax() ) ? true : false;
00043 }
00044
00045
00046
00047 IsCorrectPhiBin::IsCorrectPhiBin(double phi):
00048 m_phi(phi){}
00049 bool IsCorrectPhiBin::operator()(PhiBin& pb){
00050
00051 return ( m_phi >= pb.getPhiMin() && m_phi < pb.getPhiMax() ) ? true : false;
00052 }
00053
00054
00055
00056 IsCorrectSector::IsCorrectSector(std::string sectortype):
00057 m_sectortype(sectortype){}
00058 bool IsCorrectSector::operator()(Sector& sec){
00059
00060 return ( m_sectortype == sec.getSectorType() ) ? true : false;
00061 }
00062
00063
00064
00065 IsCorrectMuonSpectrometer::IsCorrectMuonSpectrometer(double pT):
00066 m_pT(pT){}
00067 bool IsCorrectMuonSpectrometer::operator()(MuonSpectrometer& ms){
00068
00069 return ( m_pT >= ms.getPtMin() && m_pT < ms.getPtMax() ) ? true : false;
00070 }
00071
00072
00073
00074
00075 EtaBin::EtaBin(double deltaponp, int etabin):
00076 m_etabin(etabin), m_etamin(0.), m_etamax(0.), m_deltaponp(0.01*deltaponp){}
00077
00078 void EtaBin::setEtaStuff(double etaFirst, double deltaEta){
00079
00080 m_etavalue = deltaEta*double(m_etabin);
00081 m_etamin = m_etabin ? deltaEta*double(m_etabin-0.5) + etaFirst: etaFirst;
00082 m_etamax = deltaEta*double(m_etabin+0.5);
00083
00084 }
00085
00086 void EtaBin::combine(EtaBin& otherEtaBin, double thispt, double nextpt){
00087
00088
00089 m_constterm = 1.;
00090 m_ptterm = 0;
00091
00092 if (m_deltaponp < 1.){
00093
00094 double resthis = m_deltaponp;
00095 double resnext = otherEtaBin.m_deltaponp;
00096 double delossthis = dEnergyLoss(m_etavalue,thispt);
00097 double delossnext = dEnergyLoss(m_etavalue,nextpt);
00098
00099 m_ptterm = ( resnext*resnext - resthis*resthis
00100 - (delossnext*delossnext - delossthis*delossthis ) ) /
00101 (nextpt*nextpt - thispt*thispt);
00102
00103 m_constterm = resthis*resthis - m_ptterm*thispt*thispt - delossthis*delossthis;
00104
00105 }
00106 }
00107
00108 double EtaBin::calculateResolution(const HepLorentzVector& avec){
00109
00110 double resolution = 1.;
00111 if (m_constterm < 1.){
00112 double dEloss = dEnergyLoss(avec);
00113 double pT = avec.perp();
00114 double resolution_squared = m_constterm + m_ptterm*pT*pT + dEloss*dEloss;
00115 if (resolution_squared > 0. && resolution_squared < 1.)
00116 resolution = sqrt(resolution_squared);
00117 }
00118 return resolution;
00119 }
00120
00121 void EtaBin::dump(std::string indent){
00122 indent += " ";
00123 std::cout<<std::endl;
00124 std::cout<<indent<<"\nDump for EtaBin:\n";
00125 std::cout<<indent<<"m_etabin "<<m_etabin<<std::endl;
00126 std::cout<<indent<<"m_etamin "<<m_etamin<<std::endl;
00127 std::cout<<indent<<"m_etamax "<<m_etamax<<std::endl;
00128 std::cout<<indent<<"m_deltaponp "<<m_deltaponp<<std::endl;
00129 std::cout<<indent<<"m_constterm "<<m_constterm<<std::endl;
00130 std::cout<<indent<<"m_ptterm "<<m_ptterm<<std::endl;
00131 }
00132
00133
00134
00135 PhiBin::PhiBin(DOMNode* boundaries, DOMNode* phi):
00136 m_phibin(0), m_phimin(0.), m_phimax(0.){
00137
00138
00139 getFirstValue(phi, "phibinnumber", m_phibin);
00140
00141 std::vector<double> deltaponps;
00142 getAllValues(phi, "deltaponp",deltaponps);
00143 SpectrometerComponentBinInstantiator<EtaBin> instantiator(boundaries);
00144 m_etas = std::for_each(deltaponps.begin(),
00145 deltaponps.end(),
00146 instantiator).objects();
00147
00148 double etafirst;
00149 double etalast;
00150
00151 DOMNode* etaInfoNode = getFirstChildTagByName(boundaries, "etainfo");
00152 getFirstValue(etaInfoNode, "etafirst", etafirst);
00153 getFirstValue(etaInfoNode, "etalast", etalast);
00154
00155 int etaPoints = m_etas.size();
00156 double deltaEta = (etalast-etafirst)/(etaPoints-1);
00157
00158 std::vector<EtaBin>::iterator itr = m_etas.begin();
00159 for(;itr != m_etas.end(); ++itr){
00160 (*itr).setEtaStuff(etafirst,deltaEta);
00161 }
00162
00163 }
00164
00165
00166 PhiBin::~PhiBin(){
00167 m_etas.clear();
00168 }
00169
00170 void PhiBin::setPhiStuff(double sectorPhimin, double sectorPhimax, double deltaPhi, int phipoints){
00171
00172
00173 m_phimin = m_phibin ? deltaPhi*double(m_phibin-0.5) + sectorPhimin : sectorPhimin;
00174 if (m_phimin > M_PI) m_phimin -= (2.*M_PI);
00175
00176 m_phimax = (m_phibin != (phipoints-1)) ? deltaPhi*double(m_phibin+0.5) : sectorPhimax;
00177 if (m_phimax > M_PI) m_phimax -= (2.*M_PI);
00178
00179 }
00180
00181 void PhiBin::combine(PhiBin &otherPhiBin, double thispt, double nextpt){
00182
00183 std::vector<EtaBin>::iterator thisEtaItr = m_etas.begin();
00184 std::vector<EtaBin>::iterator otherEtaItr = otherPhiBin.m_etas.begin();
00185 for(;thisEtaItr != m_etas.end(); ++thisEtaItr, ++otherEtaItr){
00186
00187 (*thisEtaItr).combine(*otherEtaItr, thispt, nextpt);
00188 }
00189
00190 }
00191
00192 double PhiBin::calculateResolution(const HepLorentzVector& avec){
00193
00194 IsCorrectEtaBin iceb(fabs(avec.pseudoRapidity()));
00195 std::vector<EtaBin>::iterator ebitr = find_if(m_etas.begin(),
00196 m_etas.end(),
00197 iceb);
00198 if ( ebitr == m_etas.end() ){
00199
00200 return 1.;
00201 }
00202
00203 return (*ebitr).calculateResolution(avec);
00204
00205 }
00206
00207 void PhiBin::dump(std::string indent){
00208 indent += " ";
00209 std::cout<<indent<<"Dump for PhiBin:\n";
00210 std::cout<<indent<<"m_phibin "<<m_phibin<<std::endl;
00211 std::cout<<indent<<"m_phimin "<<m_phimin<<std::endl;
00212 std::cout<<indent<<"m_phimax "<<m_phimax<<std::endl;
00213 std::cout<<indent<<"Dump of my etas:"<<std::endl;
00214 std::for_each(m_etas.begin(), m_etas.end(), AddToDump(indent));
00215 }
00216
00217
00218
00219 Sector::Sector(DOMNode* boundaries, DOMNode* sector):m_phimin(0.){
00220
00221 m_sectorType = "Unknown";
00222
00223 getFirstValue(sector, "sectortype", m_sectorType);
00224
00225 std::vector<DOMNode*> phis = getAllChildTagsByName(sector, "phibinres");
00226 SpectrometerComponentInstantiator<PhiBin> instantiator(boundaries);
00227 m_phis = std::for_each(phis.begin(),
00228 phis.end(),
00229 instantiator).objects();
00230
00231 DOMNode* phiInfoNode = getFirstChildTagByName(boundaries, "phiinfo");
00232 getFirstValue(phiInfoNode, "phifirst", m_phimin);
00233 getFirstValue(phiInfoNode, "philast", m_phimax);
00234
00235
00236
00237 int phipoints = m_phis.size();
00238 double deltaphi = (m_phimax-m_phimin)/(phipoints-1);
00239
00240
00241 std::vector<PhiBin>::iterator itr = m_phis.begin();
00242 for(;itr != m_phis.end(); ++itr){
00243 (*itr).setPhiStuff(m_phimin, m_phimax, deltaphi, phipoints);
00244 }
00245
00246 }
00247
00248 Sector::~Sector(){
00249 m_phis.clear();
00250 }
00251
00252 void Sector::combine(Sector& otherSec, double thispt, double nextpt){
00253
00254 std::vector<PhiBin>::iterator thisPhiItr = m_phis.begin();
00255 std::vector<PhiBin>::iterator otherPhiItr = otherSec.m_phis.begin();
00256 for(;thisPhiItr != m_phis.end(); ++thisPhiItr, ++otherPhiItr){
00257 (*thisPhiItr).combine(*otherPhiItr, thispt, nextpt);
00258 }
00259 }
00260
00261 double Sector::calculateResolution(const HepLorentzVector& avec){
00262
00263
00264
00265
00266 double localphi = avec.phi();
00267 while (localphi < 0.) localphi += 2.*M_PI;
00268 double global_phi = localphi;
00269 double sectorsize = m_phimax - m_phimin;
00270 while (localphi > sectorsize ) localphi -= sectorsize;
00271 if ( global_phi >= 3.926990815 && global_phi < 4.712388978 )
00272 localphi = sectorsize - localphi;
00273
00274 IsCorrectPhiBin icpb(localphi);
00275 std::vector<PhiBin>::iterator pbitr = find_if(m_phis.begin(),
00276 m_phis.end(),
00277 icpb);
00278 if ( pbitr == m_phis.end() ){
00279
00280 return 1.;
00281 }
00282
00283 return (*pbitr).calculateResolution(avec);
00284
00285 }
00286
00287 void Sector::dump(std::string indent){
00288 indent += " ";
00289 std::cout<<indent<<"Dump for Sector:\n";
00290 std::cout<<indent<<"m_sectorType "<<m_sectorType<<std::endl;
00291 std::cout<<indent<<"m_phimin "<<m_phimin<<std::endl;
00292 std::for_each(m_phis.begin(), m_phis.end(), AddToDump(indent));
00293 }
00294
00295
00296
00297 ProtoSpectrometer::ProtoSpectrometer(DOMNode* boundaries, DOMNode* ptbinres, bool lowestpT, bool highestpT):
00298 m_lowestpT(lowestpT), m_highestpT(highestpT){
00299
00300 getFirstValue(ptbinres, "ptbinnumber", m_ptbin);
00301
00302 DOMNode* node = getFirstChildTagByName(boundaries, "ptpoints");
00303
00304 std::vector<DOMNode*> ptBoundaryNodes =
00305 getAllChildTagsByName(node, "ptpoint");
00306
00307 std::vector<double> ptBoundaries =
00308 for_each(
00309 ptBoundaryNodes.begin(),
00310 ptBoundaryNodes.end(),
00311 GetDoublesFromNodes()
00312 ).doubles();
00313
00314 if(m_ptbin < static_cast<int>(ptBoundaries.size())){
00315 m_ptvalue = ptBoundaries[m_ptbin];
00316 }
00317 std::vector<DOMNode*> sectors = getAllChildTagsByName(ptbinres, "sector");
00318 SpectrometerComponentInstantiator<Sector> instantiator(boundaries);
00319 m_sectors = std::for_each(sectors.begin(),
00320 sectors.end(),
00321 instantiator).objects();
00322 }
00323
00324 ProtoSpectrometer::~ProtoSpectrometer(){
00325 m_sectors.clear();
00326 }
00327
00328 void ProtoSpectrometer::dump(std::string indent){
00329 indent += " ";
00330 std::cout<<indent<<"Dump for Spectrometer:\n";
00331 std::cout<<indent<<"m_bin "<<m_ptbin<<std::endl;
00332 std::cout<<indent<<"m_ptvalue "<<m_ptvalue<<std::endl;
00333 std::cout<<indent<<"Dump of my sectors:"<<std::endl;
00334 std::for_each(m_sectors.begin(), m_sectors.end(), AddToDump(indent));
00335 }
00336
00337 MuonSpectrometer ProtoSpectrometer::combine(ProtoSpectrometer& otherPS){
00338
00339 std::vector<Sector>::iterator thisSecItr = m_sectors.begin();
00340 std::vector<Sector>::iterator otherSecItr = otherPS.m_sectors.begin();
00341
00342 for(; thisSecItr!= m_sectors.end(); ++thisSecItr, ++otherSecItr){
00343 (*thisSecItr).combine(*otherSecItr, m_ptvalue, otherPS.m_ptvalue);
00344 }
00345
00346 double ptlow = m_lowestpT ? 0.0 : m_ptvalue;
00347 double pthigh = otherPS.m_highestpT ? 7000000.0 : otherPS.m_ptvalue;
00348
00349 MuonSpectrometer thisMS(ptlow, pthigh, m_sectors);
00350
00351 return thisMS;
00352
00353 }
00354
00355
00356
00357 MuonSpectrometer::MuonSpectrometer(double ptmin, double ptmax, std::vector<Sector> sectors):
00358 m_ptmin(ptmin), m_ptmax(ptmax), m_sectors(sectors){
00359 }
00360
00361 void MuonSpectrometer::setSectorMap(std::map<int,std::string> sectortypes){
00362 m_sectortypes = sectortypes;
00363 m_sectorsize = 2.*M_PI/m_sectortypes.size();
00364 }
00365
00366 double MuonSpectrometer::calculateResolution(const HepLorentzVector& avec){
00367
00368
00369
00370 double phi = avec.phi();
00371 while (phi < 0.) phi += 2.*M_PI;
00372
00373 int sectorindex = int(phi/m_sectorsize) + 1;
00374
00375
00376 std::string sectortype = m_sectortypes[sectorindex];
00377
00378
00379 IsCorrectSector ics(sectortype);
00380 std::vector<Sector>::iterator secitr = find_if(m_sectors.begin(),
00381 m_sectors.end(),
00382 ics);
00383 if ( secitr == m_sectors.end() ){
00384
00385 return 1.;
00386 }
00387
00388 return (*secitr).calculateResolution(avec);
00389
00390 }
00391
00392 void MuonSpectrometer::dump(std::string indent){
00393 indent += " ";
00394 std::cout<<indent<<"Dump for MuonSpectrometer:\n";
00395 std::cout<<indent<<"m_ptmin "<<m_ptmin<<std::endl;
00396 std::cout<<indent<<"m_ptmax "<<m_ptmax<<std::endl;
00397 std::cout<<indent<<"Dump of my sectors:"<<std::endl;
00398 std::for_each(m_sectors.begin(), m_sectors.end(), AddToDump(indent));
00399 }
00400
00401
00402
00403 MuonResolutionCalculator::MuonResolutionCalculator(const char* filename){
00404
00405 DOMDocument* dom = parseFileForDocument(filename);
00406
00407 if(dom == 0){
00408 std::cout<<"Could not parse " <<filename<<std::endl;
00409 }
00410
00411 DOMElement* docElement = dom->getDocumentElement();
00412
00413 if(docElement == 0){
00414 std::cout<<"Could not get DOMElement from DOMDocument"<<std::endl;
00415 }
00416
00417
00418 XMLCh* s = XMLString::transcode("interpretation");
00419 DOMNodeList* binTags =
00420 docElement->getElementsByTagName(s);
00421 XMLString::release(&s);
00422
00423 DOMNode* boundaries = binTags->item(0);
00424
00425
00426 s = XMLString::transcode("ptbinres");
00427 DOMNodeList* ptbinresTags =
00428 docElement->getElementsByTagName(s);
00429 XMLString::release(&s);
00430
00431
00432
00433 for(XMLSize_t ptr=0; ptr<ptbinresTags->getLength();++ptr){
00434
00435 ProtoSpectrometer thisPS(boundaries,
00436 ptbinresTags->item(ptr),
00437 ptr==0,
00438 ptr==(ptbinresTags->getLength()-1));
00439
00440 m_protoSpectrometers.push_back(thisPS);
00441
00442 }
00443
00444 std::map<int,std::string> sectorMap = makeSectorMap(boundaries);
00445
00446 std::vector<ProtoSpectrometer>::iterator psItr = m_protoSpectrometers.begin();
00447 for (; psItr!=m_protoSpectrometers.end()-1; ++psItr){
00448
00449 MuonSpectrometer newMS = (*psItr).combine(*(psItr+1));
00450 newMS.setSectorMap(sectorMap);
00451 m_muonSpectrometers.push_back(newMS);
00452
00453 }
00454
00455
00456 m_protoSpectrometers.clear();
00457
00458
00459 delete dom;
00460
00461
00462
00463 XMLPlatformUtils::Terminate();
00464
00465 }
00466
00467 std::map<int,std::string> MuonResolutionCalculator::makeSectorMap(DOMNode* boundaries){
00468
00469
00470
00471 DOMNode* node = getFirstChildTagByName(boundaries, "sectortypes");
00472
00473 std::vector<DOMNode*> sectorTypeNodes =
00474 getAllChildTagsByName(node, "sectortype");
00475
00476 AddToMap atm;
00477 std::map<int,std::string> sectorMap = std::for_each(sectorTypeNodes.begin(),
00478 sectorTypeNodes.end(),
00479 atm).getMap();
00480 return sectorMap;
00481
00482 }
00483
00484 double MuonResolutionCalculator::calculateResolution(const HepLorentzVector& avec){
00485
00486
00487 IsCorrectMuonSpectrometer icms(avec.perp());
00488 std::vector<MuonSpectrometer>::iterator msitr = find_if(m_muonSpectrometers.begin(),
00489 m_muonSpectrometers.end(),
00490 icms);
00491 if ( msitr == m_muonSpectrometers.end() ){
00492
00493 return 1.;
00494 }
00495
00496 return (*msitr).calculateResolution(avec);
00497 }
00498
00499 void MuonResolutionCalculator::dump(std::string indent){
00500 indent += " ";
00501 std::cout<<indent<<"\nDump for MuonResolutionCalculator:\n";
00502 std::for_each(m_protoSpectrometers.begin(),
00503 m_protoSpectrometers.end(),
00504 AddToDump(indent));
00505 std::for_each(m_muonSpectrometers.begin(),
00506 m_muonSpectrometers.end(),
00507 AddToDump(indent));
00508
00509 }
00510
00511 }