Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:29:44

0001 #ifndef MaterialAccountingStep_h
0002 #define MaterialAccountingStep_h
0003 
0004 #include <utility>
0005 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0006 
0007 // struct to keep material accounting informations on a per-step basis
0008 // TODO split segment info (in, out) into separate child class
0009 class MaterialAccountingStep {
0010 public:
0011   MaterialAccountingStep(void) : m_length(0.), m_radiationLengths(0.), m_energyLoss(0.), m_in(), m_out() {}
0012 
0013   MaterialAccountingStep(double position, double radlen, double loss, const GlobalPoint& in, const GlobalPoint& out)
0014       : m_length(position), m_radiationLengths(radlen), m_energyLoss(loss), m_in(in), m_out(out) {}
0015 
0016   void clear(void) {
0017     m_length = 0.;
0018     m_radiationLengths = 0.;
0019     m_energyLoss = 0.;
0020     m_in = GlobalPoint();
0021     m_out = GlobalPoint();
0022   }
0023 
0024 private:
0025   double m_length;
0026   double m_radiationLengths;
0027   double m_energyLoss;
0028   GlobalPoint m_in;
0029   GlobalPoint m_out;
0030 
0031 public:
0032   double length(void) const { return m_length; }
0033 
0034   double radiationLengths(void) const { return m_radiationLengths; }
0035 
0036   double energyLoss(void) const { return m_energyLoss; }
0037 
0038   const GlobalPoint& in(void) const { return m_in; }
0039 
0040   const GlobalPoint& out(void) const { return m_out; }
0041 
0042   /// split the step (0..1) in (0..f) + (f..1) using linear interpolation
0043   std::pair<MaterialAccountingStep, MaterialAccountingStep> split(double fraction) const {
0044     // no check is done to ensure that 0 <= f <= 1 !
0045     GlobalPoint limit(m_in.x() * fraction + m_out.x() * (1. - fraction),
0046                       m_in.y() * fraction + m_out.y() * (1. - fraction),
0047                       m_in.z() * fraction + m_out.z() * (1. - fraction));
0048 
0049     MaterialAccountingStep part1(
0050         fraction * m_length, fraction * m_radiationLengths, fraction * m_energyLoss, m_in, limit);
0051 
0052     MaterialAccountingStep part2(
0053         (1 - fraction) * m_length, (1 - fraction) * m_radiationLengths, (1 - fraction) * m_energyLoss, limit, m_out);
0054     return std::make_pair(part1, part2);
0055   }
0056 
0057   /// add a step
0058   MaterialAccountingStep& operator+=(const MaterialAccountingStep& step) {
0059     m_length += step.m_length;
0060     m_radiationLengths += step.m_radiationLengths;
0061     m_energyLoss += step.m_energyLoss;
0062 
0063     // assume that perp2 is 0 only for uninitialized steps
0064     if ((m_in.perp2() == 0.0) or (step.m_in.perp2() < m_in.perp2()))
0065       m_in = step.m_in;
0066 
0067     if ((m_out.perp2() == 0.0) or (step.m_out.perp2() > m_out.perp2()))
0068       m_out = step.m_out;
0069 
0070     return *this;
0071   }
0072 
0073   /// subtract a step
0074   MaterialAccountingStep& operator-=(const MaterialAccountingStep& step) {
0075     m_length -= step.m_length;
0076     m_radiationLengths -= step.m_radiationLengths;
0077     m_energyLoss -= step.m_energyLoss;
0078 
0079     // can anything more sensible be done for m_in and/or m_out ?
0080     if ((step.m_in.perp2() <= m_in.perp2()) and (step.m_out.perp2() >= m_in.perp2()))
0081       m_in = step.m_out;
0082 
0083     if ((step.m_out.perp2() >= m_out.perp2()) and (step.m_in.perp2() <= m_out.perp2()))
0084       m_out = step.m_in;
0085 
0086     return *this;
0087   }
0088 
0089   /// multiply two steps, usefull to implement (co)variance
0090   MaterialAccountingStep& operator*=(const MaterialAccountingStep& step) {
0091     m_length *= step.m_length;
0092     m_radiationLengths *= step.m_radiationLengths;
0093     m_energyLoss *= step.m_energyLoss;
0094     return *this;
0095   }
0096 
0097   /// multiply by a scalar
0098   MaterialAccountingStep& operator*=(double x) {
0099     m_length *= x;
0100     m_radiationLengths *= x;
0101     m_energyLoss *= x;
0102     return *this;
0103   }
0104 
0105   /// divide by a scalar
0106   MaterialAccountingStep& operator/=(double x) {
0107     m_length /= x;
0108     m_radiationLengths /= x;
0109     m_energyLoss /= x;
0110     return *this;
0111   }
0112 };
0113 
0114 inline MaterialAccountingStep operator+(const MaterialAccountingStep& x, const MaterialAccountingStep& y) {
0115   MaterialAccountingStep step(x);
0116   step += y;
0117   return step;
0118 }
0119 
0120 inline MaterialAccountingStep operator-(const MaterialAccountingStep& x, const MaterialAccountingStep& y) {
0121   MaterialAccountingStep step(x);
0122   step -= y;
0123   return step;
0124 }
0125 
0126 inline MaterialAccountingStep operator*(const MaterialAccountingStep& x, const MaterialAccountingStep& y) {
0127   MaterialAccountingStep step(x);
0128   step *= y;
0129   return step;
0130 }
0131 
0132 inline MaterialAccountingStep operator*(const MaterialAccountingStep& x, double y) {
0133   MaterialAccountingStep step(x);
0134   step *= y;
0135   return step;
0136 }
0137 
0138 inline MaterialAccountingStep operator*(double y, const MaterialAccountingStep& x) {
0139   MaterialAccountingStep step(x);
0140   step *= y;
0141   return step;
0142 }
0143 
0144 inline MaterialAccountingStep operator/(const MaterialAccountingStep& x, double y) {
0145   MaterialAccountingStep step(x);
0146   step /= y;
0147   return step;
0148 }
0149 
0150 #endif  // MaterialAccountingStep_h