Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ]   [ 15.*.* ] 

001 #include <iostream>
002 #include <cmath>
003 #include <cstdlib>
004 
005 #include "AtlfastAlgs/MuonSpectrometer.h"
006 
007 namespace Atlfast{
008 
009   // ============================================
010 
011   double dEnergyLoss(double eta, double pT){
012     
013     // Contribution from energy loss fluctuations
014     // in the colorimeters
015     // Unitless fraction
016     
017     eta = fabs(eta);
018     double theta = 2.*atan(exp(-eta));
019     double sintheta = sin(theta);
020     double energy = fabs(pT)/sintheta;
021     double factor = (eta < 1.1) ? 1./sqrt(sintheta) : sqrt(14./11.);
022     double dEloss = (eta < 1.1) ? 
023       factor*(240. + 0.105*energy/100.)/energy : 
024       factor*(480. + 0.105*energy/100.)/energy;
025 
026     return dEloss;
027 
028   }
029   
030   double dEnergyLoss(const HepLorentzVector& avec){
031     return dEnergyLoss(avec.pseudoRapidity(),avec.perp());
032   }
033   
034   // ============================================
035   // Predicates
036   // ============================================
037   
038   IsCorrectEtaBin::IsCorrectEtaBin(double eta):
039     m_eta(eta){}
040   bool IsCorrectEtaBin::operator()(EtaBin& eb){
041     // returns true if eta value is within this EtaBin
042     return ( m_eta >= eb.getEtaMin() && m_eta < eb.getEtaMax() ) ? true : false;
043   }
044   
045   // ============================================
046   
047   IsCorrectPhiBin::IsCorrectPhiBin(double phi):
048     m_phi(phi){}
049   bool IsCorrectPhiBin::operator()(PhiBin& pb){
050     // returns true if phi value is within this PhiBin
051     return ( m_phi >= pb.getPhiMin() && m_phi < pb.getPhiMax() ) ? true : false;
052   }
053   
054   // ============================================
055   
056   IsCorrectSector::IsCorrectSector(std::string sectortype):
057     m_sectortype(sectortype){}
058   bool IsCorrectSector::operator()(Sector& sec){
059     // returns true if this Sector is of the correct type
060     return ( m_sectortype == sec.getSectorType() ) ? true : false;
061   }
062   
063   // ============================================
064   
065   IsCorrectMuonSpectrometer::IsCorrectMuonSpectrometer(double pT):
066     m_pT(pT){}
067   bool IsCorrectMuonSpectrometer::operator()(MuonSpectrometer& ms){
068     // returns true if pt value is within this MuonSpectrometer
069     return ( m_pT >= ms.getPtMin() && m_pT < ms.getPtMax() ) ? true : false;
070   }
071   
072   
073   // ============================================
074   // ============================================
075   /** @brief Contains resolution term values in a given eta range.
076    *
077    *  For a given muon 4-vector, constant and pT terms are used to
078    *  compute a pT resolution.
079    */
080 
081   
082   EtaBin::EtaBin(double deltaponp, int etabin):
083     m_etabin(etabin), m_etamin(0.), m_etamax(0.), m_deltaponp(0.01*deltaponp){}
084   
085   void EtaBin::setEtaStuff(double etaFirst, double deltaEta){
086     
087     m_etavalue = deltaEta*double(m_etabin);
088     m_etamin = m_etabin ? deltaEta*double(m_etabin-0.5) + etaFirst: etaFirst;
089     m_etamax = deltaEta*double(m_etabin+0.5);
090 
091   }
092   /** Calculates constant and pT terms to be used in resolution calculation */ 
093   void EtaBin::combine(EtaBin& otherEtaBin, double thispt, double nextpt){
094 
095     
096     m_constterm = 1.;
097     m_ptterm = 0;
098 
099     if (m_deltaponp < 1.){
100       
101       double resthis = m_deltaponp;
102       double resnext = otherEtaBin.m_deltaponp;
103       double delossthis = dEnergyLoss(m_etavalue,thispt);
104       double delossnext = dEnergyLoss(m_etavalue,nextpt);
105       
106       m_ptterm = ( resnext*resnext - resthis*resthis
107                    - (delossnext*delossnext - delossthis*delossthis ) ) /
108         (nextpt*nextpt - thispt*thispt);
109       
110       m_constterm = resthis*resthis - m_ptterm*thispt*thispt - delossthis*delossthis;
111       
112     }    
113   }
114   /** Takes muon 4-vector and calculates pT resolution */
115   double EtaBin::calculateResolution(const HepLorentzVector& avec){
116 
117     double resolution = 1.;
118     if (m_constterm < 1.){ // Otherwise return resolution of 1.0
119      double dEloss = dEnergyLoss(avec);
120       double pT = avec.perp();
121       double resolution_squared = m_constterm + m_ptterm*pT*pT + dEloss*dEloss;
122       if (resolution_squared > 0. && resolution_squared < 1.)
123         resolution = sqrt(resolution_squared);
124     }
125     return resolution;
126   }
127  /** Dumps EtaBin properties to standard output */
128   void EtaBin::dump(std::string indent){
129     indent += " ";
130     std::cout<<std::endl;
131     std::cout<<indent<<"\nDump for EtaBin:\n";
132     std::cout<<indent<<"m_etabin "<<m_etabin<<std::endl;
133     std::cout<<indent<<"m_etamin "<<m_etamin<<std::endl;
134     std::cout<<indent<<"m_etamax "<<m_etamax<<std::endl;
135     std::cout<<indent<<"m_deltaponp "<<m_deltaponp<<std::endl;
136     std::cout<<indent<<"m_constterm "<<m_constterm<<std::endl;
137     std::cout<<indent<<"m_ptterm "<<m_ptterm<<std::endl;
138   }
139   
140   // ============================================
141   /** @brief Contains all EtaBins for a given range in phi.
142    *
143    *  Functions called on a PhiBin are delegated to the relevant
144    *  EtaBin.
145    */
146   
147   PhiBin::PhiBin(DOMNode* boundaries, DOMNode* phi):
148     m_phibin(0), m_phimin(0.), m_phimax(0.){
149     
150     // phibin goes from 0 to 90
151     getFirstValue(phi, "phibinnumber", m_phibin);
152     
153     std::vector<double> deltaponps;
154     getAllValues(phi, "deltaponp",deltaponps);
155     SpectrometerComponentBinInstantiator<EtaBin> instantiator(boundaries);
156     m_etas = std::for_each(deltaponps.begin(),
157                            deltaponps.end(),             
158                            instantiator).objects();
159     
160     double etafirst;
161     double etalast;
162     
163     DOMNode* etaInfoNode =  getFirstChildTagByName(boundaries, "etainfo");
164     getFirstValue(etaInfoNode, "etafirst", etafirst);
165     getFirstValue(etaInfoNode, "etalast", etalast);
166     
167     int etaPoints = m_etas.size();
168     double deltaEta = (etalast-etafirst)/(etaPoints-1);
169     
170     std::vector<EtaBin>::iterator itr = m_etas.begin();
171     for(;itr != m_etas.end(); ++itr){
172       (*itr).setEtaStuff(etafirst,deltaEta);
173     }
174     
175   }
176   
177 
178   PhiBin::~PhiBin(){
179     m_etas.clear();
180   }
181    /** Sets phi limits on this bin  */  
182   void PhiBin::setPhiStuff(double sectorPhimin, double sectorPhimax, double deltaPhi, int phipoints){
183 
184     // these are phi values within a sector    
185     m_phimin = m_phibin ? deltaPhi*double(m_phibin-0.5) + sectorPhimin : sectorPhimin;
186     if (m_phimin > M_PI) m_phimin -= (2.*M_PI);
187     
188     m_phimax = (m_phibin != (phipoints-1)) ? deltaPhi*double(m_phibin+0.5) : sectorPhimax;
189     if (m_phimax > M_PI) m_phimax -= (2.*M_PI);
190     
191   }
192   /** Delegates combine method to relevant EtaBin */
193   void PhiBin::combine(PhiBin &otherPhiBin, double thispt, double nextpt){
194     
195     std::vector<EtaBin>::iterator thisEtaItr = m_etas.begin();
196     std::vector<EtaBin>::iterator otherEtaItr = otherPhiBin.m_etas.begin();
197     for(;thisEtaItr != m_etas.end(); ++thisEtaItr, ++otherEtaItr){
198 
199       (*thisEtaItr).combine(*otherEtaItr, thispt, nextpt);
200     }
201     
202   }
203   /** Delegates calculateResolution method to relevant EtaBin */
204   double PhiBin::calculateResolution(const HepLorentzVector& avec){
205     
206     IsCorrectEtaBin iceb(fabs(avec.pseudoRapidity()));
207     std::vector<EtaBin>::iterator ebitr = find_if(m_etas.begin(),
208                                                   m_etas.end(),
209                                                   iceb);
210     if ( ebitr == m_etas.end() ){
211       // Muon outside eta range, returning resolution of 1.0
212       return 1.;
213     }
214     
215     return (*ebitr).calculateResolution(avec);    
216     
217   }
218   /** Dumps PhiBin properties to standard output and calls dump for
219     *  all constituent EtaBins */
220   void PhiBin::dump(std::string indent){
221     indent += "  ";
222     std::cout<<indent<<"Dump for PhiBin:\n";
223     std::cout<<indent<<"m_phibin "<<m_phibin<<std::endl;
224     std::cout<<indent<<"m_phimin "<<m_phimin<<std::endl;
225     std::cout<<indent<<"m_phimax "<<m_phimax<<std::endl;
226     std::cout<<indent<<"Dump of my etas:"<<std::endl;
227     std::for_each(m_etas.begin(), m_etas.end(), AddToDump(indent));
228   }
229 
230   // ============================================
231   // ============================================
232   /** @brief Contains PhiBins for a given spectrometer sector
233    *
234    *  Functions called on a Sector are delegated to the relevant
235    *  PhiBin.
236    */
237 
238   /** Constructor takes xml DOMNodes for detector boundaries and sector index */
239   Sector::Sector(DOMNode* boundaries, DOMNode* sector):m_phimin(0.){
240 
241     m_sectorType = "Unknown";
242     
243     getFirstValue(sector, "sectortype", m_sectorType);
244     
245     std::vector<DOMNode*> phis = getAllChildTagsByName(sector, "phibinres");
246     SpectrometerComponentInstantiator<PhiBin> instantiator(boundaries);
247     m_phis = std::for_each(phis.begin(),
248                            phis.end(),
249                            instantiator).objects();
250     
251     DOMNode* phiInfoNode =  getFirstChildTagByName(boundaries, "phiinfo");
252     getFirstValue(phiInfoNode, "phifirst", m_phimin);
253     getFirstValue(phiInfoNode, "philast", m_phimax);
254     
255     // Calculate phi info once here and give it to the PhiBins
256     
257     int phipoints = m_phis.size();
258     double deltaphi = (m_phimax-m_phimin)/(phipoints-1);
259 
260 
261     std::vector<PhiBin>::iterator itr = m_phis.begin();
262     for(;itr != m_phis.end(); ++itr){
263       (*itr).setPhiStuff(m_phimin, m_phimax, deltaphi, phipoints);
264     }
265     
266   }
267   
268   Sector::~Sector(){
269     m_phis.clear();
270   }
271   /** Delegates combine method to relevant PhiBin */
272   void Sector::combine(Sector& otherSec, double thispt, double nextpt){
273     
274     std::vector<PhiBin>::iterator thisPhiItr = m_phis.begin();
275     std::vector<PhiBin>::iterator otherPhiItr = otherSec.m_phis.begin();
276     for(;thisPhiItr != m_phis.end(); ++thisPhiItr, ++otherPhiItr){
277       (*thisPhiItr).combine(*otherPhiItr, thispt, nextpt);
278     }
279   }
280   
281   /** Delegates calculateResolution method to relevant PhiBin.
282      *  Phi values is translated to local system */
283   double Sector::calculateResolution(const HepLorentzVector& avec){
284 
285     // check for appropriate PhiBin
286     // First calculate the local phi (zeroed at the sector phimin)
287     
288     double localphi = avec.phi();
289     while (localphi < 0.) localphi += 2.*M_PI;
290     double global_phi = localphi;
291     double sectorsize = m_phimax - m_phimin;
292     while (localphi > sectorsize ) localphi -= sectorsize;
293     if ( global_phi >= 3.926990815 && global_phi < 4.712388978 )
294       localphi = sectorsize - localphi;
295     
296     IsCorrectPhiBin icpb(localphi);
297     std::vector<PhiBin>::iterator pbitr = find_if(m_phis.begin(),
298                                                   m_phis.end(),
299                                                   icpb);
300     if ( pbitr == m_phis.end() ){
301       // Could not find correct PhiBin, returning resolution of 1.0
302       return 1.;
303     }
304     
305     return (*pbitr).calculateResolution(avec);    
306     
307   }
308   /** Dumps Sector properties to standard output and calls dump
309     *  for all constituent PhiBins*/
310   void Sector::dump(std::string indent){
311     indent += "  ";
312     std::cout<<indent<<"Dump for Sector:\n";
313     std::cout<<indent<<"m_sectorType "<<m_sectorType<<std::endl;
314     std::cout<<indent<<"m_phimin     "<<m_phimin<<std::endl;
315     std::for_each(m_phis.begin(), m_phis.end(), AddToDump(indent));
316   }
317 
318   // ============================================
319   /** @brief Spectrometer class containing exact resolutions at given pT values
320    *
321    *  These are combined (via the combine method) to produce MuonSpectrometers
322    *  which contain the constant and pT terms necessary to compute a resolution
323    *  at any pT.
324    */
325 
326 
327   /** Constructor takes xml DOMNodes for detector boundaries and pt resolutions and
328    *  indicators for whether this is the lowest pT or highest pT ProtoSpectrometer. */
329   ProtoSpectrometer::ProtoSpectrometer(DOMNode* boundaries, DOMNode* ptbinres, bool lowestpT, bool highestpT):
330     m_lowestpT(lowestpT), m_highestpT(highestpT){
331     
332     getFirstValue(ptbinres, "ptbinnumber", m_ptbin);
333     
334     DOMNode* node = getFirstChildTagByName(boundaries, "ptpoints");
335     
336     std::vector<DOMNode*> ptBoundaryNodes = 
337       getAllChildTagsByName(node, "ptpoint");
338     
339     std::vector<double> ptBoundaries = 
340       for_each(
341                ptBoundaryNodes.begin(),
342                ptBoundaryNodes.end(),
343                GetDoublesFromNodes()
344                ).doubles();
345     
346     if(m_ptbin < static_cast<int>(ptBoundaries.size())){
347       m_ptvalue = ptBoundaries[m_ptbin];
348     }
349     std::vector<DOMNode*> sectors = getAllChildTagsByName(ptbinres, "sector");
350     SpectrometerComponentInstantiator<Sector> instantiator(boundaries);
351     m_sectors = std::for_each(sectors.begin(),
352                               sectors.end(),
353                               instantiator).objects();
354   }
355   
356   ProtoSpectrometer::~ProtoSpectrometer(){
357     m_sectors.clear();
358   }
359 
360   void ProtoSpectrometer::dump(std::string indent){
361     indent += "  ";
362     std::cout<<indent<<"Dump for Spectrometer:\n";
363     std::cout<<indent<<"m_bin "<<m_ptbin<<std::endl;
364     std::cout<<indent<<"m_ptvalue "<<m_ptvalue<<std::endl;
365     std::cout<<indent<<"Dump of my sectors:"<<std::endl;
366     std::for_each(m_sectors.begin(), m_sectors.end(), AddToDump(indent));
367   }
368 
369   MuonSpectrometer ProtoSpectrometer::combine(ProtoSpectrometer& otherPS){
370 
371     std::vector<Sector>::iterator thisSecItr = m_sectors.begin();
372     std::vector<Sector>::iterator otherSecItr = otherPS.m_sectors.begin();
373     
374     for(; thisSecItr!= m_sectors.end(); ++thisSecItr, ++otherSecItr){
375       (*thisSecItr).combine(*otherSecItr, m_ptvalue, otherPS.m_ptvalue);
376     }
377     
378     double ptlow = m_lowestpT ? 0.0 : m_ptvalue;
379     double pthigh = otherPS.m_highestpT ? 7000000.0 : otherPS.m_ptvalue;
380     
381     MuonSpectrometer thisMS(ptlow, pthigh, m_sectors);
382     
383     return thisMS;
384     
385   }
386 
387   // ============================================
388 
389 /** @brief Contains collection of spectrometer Sectors.
390    *
391    *  Functions called on a MuonSpectrometer are delegated to the relevant
392    *  Sector.
393    */
394 
395   /** Constructor takes upper and lower pT values for range covered and
396      *  constituent Sectors */
397   MuonSpectrometer::MuonSpectrometer(double ptmin, double ptmax, std::vector<Sector> sectors):
398     m_ptmin(ptmin), m_ptmax(ptmax), m_sectors(sectors){
399   }
400 
401   void MuonSpectrometer::setSectorMap(std::map<int,std::string> sectortypes){
402     m_sectortypes = sectortypes;
403     m_sectorsize = 2.*M_PI/m_sectortypes.size();
404   }
405   /** Delegates calculateResolution method to relevant Sector */
406   double MuonSpectrometer::calculateResolution(const HepLorentzVector& avec){
407 
408     // Choose sector number based on phi
409     // -pi < HepLorentzVector.phi() < +pi
410     double phi = avec.phi();
411     while (phi < 0.) phi += 2.*M_PI;
412     // Is this compiler-dependent rounding-up? Must check
413     int sectorindex = int(phi/m_sectorsize) + 1;
414 
415     // Translate this to a sector type
416     std::string sectortype = m_sectortypes[sectorindex];
417     
418     // Now find the corresponding sector
419     IsCorrectSector ics(sectortype);
420     std::vector<Sector>::iterator secitr = find_if(m_sectors.begin(),
421                                                     m_sectors.end(),
422                                                     ics);
423     if ( secitr == m_sectors.end() ){
424       // Could not find correct Sector, returning resolution of 1.0
425       return 1.;
426     }
427     
428     return (*secitr).calculateResolution(avec);    
429 
430   }
431   /** Dumps MuonSpectrometer properties to standard output and calls
432      *  dump for all constituent Sectors */
433   void MuonSpectrometer::dump(std::string indent){
434     indent += "  ";
435     std::cout<<indent<<"Dump for MuonSpectrometer:\n";
436     std::cout<<indent<<"m_ptmin "<<m_ptmin<<std::endl;
437     std::cout<<indent<<"m_ptmax "<<m_ptmax<<std::endl;
438     std::cout<<indent<<"Dump of my sectors:"<<std::endl;
439     std::for_each(m_sectors.begin(), m_sectors.end(), AddToDump(indent));
440   }
441 
442   // ============================================
443 
444   /** The constructor takes the two main nodes in the input xml file
445      *  and uses them to instantiate some ProtoSpectrometers. The
446      *  ProtoSpectrometers contain exact resolution values that are
447      *  later used to extract pT and constant terms per eta and phi
448      *  range (represented by EtaBin and PhiBin respectively).
449      *
450      *  The two main nodes in the input xml file are:
451      *
452      *   <interpretation>   Contains information to define the spatial
453      *                      boundaries on components of the muon spectrometer
454      *
455      *   <resolutions>      Contains the resolutions relevant to the
456      *                      components defined in <interpretation>
457      */
458 
459 
460   MuonResolutionCalculator::MuonResolutionCalculator(const char* filename){
461     
462     DOMDocument* dom = parseFileForDocument(filename);
463     
464     if(dom == 0){
465       std::cout<<"Could not parse " <<filename<<std::endl;
466     }
467     
468     DOMElement* docElement = dom->getDocumentElement();
469     
470     if(docElement == 0){
471       std::cout<<"Could not get DOMElement from DOMDocument"<<std::endl;
472     }
473     
474     // get the node containing information for interpreting the resolutions
475     XMLCh* s = XMLString::transcode("interpretation");
476     DOMNodeList* binTags = 
477       docElement->getElementsByTagName(s);
478     XMLString::release(&s);
479 
480     DOMNode* boundaries = binTags->item(0);
481     
482     // get the node needed to build a spectrometer 
483     s = XMLString::transcode("ptbinres");
484     DOMNodeList* ptbinresTags = 
485       docElement->getElementsByTagName(s);
486     XMLString::release(&s);
487 
488     // build the spectrometers
489     
490     for(XMLSize_t ptr=0; ptr<ptbinresTags->getLength();++ptr){
491       
492       ProtoSpectrometer thisPS(boundaries,
493                                ptbinresTags->item(ptr),
494                                ptr==0,
495                                ptr==(ptbinresTags->getLength()-1));
496       
497       m_protoSpectrometers.push_back(thisPS);
498       
499     }
500     
501     std::map<int,std::string> sectorMap = makeSectorMap(boundaries);
502     
503     std::vector<ProtoSpectrometer>::iterator psItr = m_protoSpectrometers.begin();
504     for (; psItr!=m_protoSpectrometers.end()-1; ++psItr){
505       
506       MuonSpectrometer newMS = (*psItr).combine(*(psItr+1));
507       newMS.setSectorMap(sectorMap);
508       m_muonSpectrometers.push_back(newMS);
509       
510     }
511     
512     // Free up memory from the ProtoSpectrometers as they're no longer needed
513     m_protoSpectrometers.clear();
514 
515     // Delete the DOMDocument
516     delete dom;
517 
518     // Clean up xerces-style. This should deallocate all memory used by Xerces
519     // but doesn't seem to work. Nice one.
520     XMLPlatformUtils::Terminate();
521 
522   }
523   
524   std::map<int,std::string> MuonResolutionCalculator::makeSectorMap(DOMNode* boundaries){
525     
526 
527 
528     DOMNode* node = getFirstChildTagByName(boundaries, "sectortypes");
529 
530     std::vector<DOMNode*> sectorTypeNodes =
531       getAllChildTagsByName(node, "sectortype");
532 
533     AddToMap atm;
534     std::map<int,std::string> sectorMap = std::for_each(sectorTypeNodes.begin(),
535                                                         sectorTypeNodes.end(),
536                                                         atm).getMap();
537     return sectorMap;
538     
539   }
540 
541   double MuonResolutionCalculator::calculateResolution(const HepLorentzVector& avec){
542 
543     // check for appropriate MuonSpectrometer
544     IsCorrectMuonSpectrometer icms(avec.perp());
545     std::vector<MuonSpectrometer>::iterator msitr = find_if(m_muonSpectrometers.begin(),
546                                                              m_muonSpectrometers.end(),
547                                                              icms);
548     if ( msitr == m_muonSpectrometers.end() ){
549       // Could not find correct MuonSpectrometer, returning resolution of 1.0
550       return 1.;
551     }
552     
553     return (*msitr).calculateResolution(avec);    
554   }
555 
556   void MuonResolutionCalculator::dump(std::string indent){
557     indent += " ";
558     std::cout<<indent<<"\nDump for MuonResolutionCalculator:\n";
559     std::for_each(m_protoSpectrometers.begin(), 
560                   m_protoSpectrometers.end(), 
561                   AddToDump(indent));
562     std::for_each(m_muonSpectrometers.begin(), 
563                   m_muonSpectrometers.end(), 
564                   AddToDump(indent));
565     
566   }      
567   
568 } // namespace Atlfast
569 

source navigation ] diff markup ] identifier search ] general search ]

Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems
This page was automatically generated by the LXR engine. Valid HTML 4.01!