Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:31:16

0001 //
0002 //
0003 // File: src/Constraint_Intermed.cc
0004 // Purpose: Represent one side of a mass constraint equation.
0005 // Created: Jul, 2000, sss, based on run 1 mass analysis code.
0006 //
0007 // CMSSW File      : src/Constraint_Intermed.cc
0008 // Original Author : Scott Stuart Snyder <snyder@bnl.gov> for D0
0009 // Imported to CMSSW by Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
0010 //
0011 
0012 /**
0013     @file Constraint_Intermed.cc
0014 
0015     @brief Represent one side of a mass constraint
0016     equation.  See the documentation for the header file
0017     Constraint_Intermed.h for details.
0018 
0019     @par Creation date:
0020     July 2000.
0021 
0022     @author
0023     Scott Stuart Snyder <snyder@bnl.gov>.
0024 
0025     @par Modification History:
0026     Apr 2009: Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>:
0027     Imported to CMSSW.<br>
0028     Oct 2009: Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>:
0029     Added Doxygen tags for automatic generation of documentation.
0030 
0031     @par Terms of Usage:
0032     With consent from the original author (Scott Snyder).
0033  */
0034 
0035 #include "TopQuarkAnalysis/TopHitFit/interface/Constraint_Intermed.h"
0036 #include "TopQuarkAnalysis/TopHitFit/interface/Fourvec_Event.h"
0037 #include <iostream>
0038 #include <cmath>
0039 #include <algorithm>
0040 #include <cstdlib>
0041 
0042 using std::find;
0043 using std::ostream;
0044 using std::sqrt;
0045 using std::stable_sort;
0046 using std::string;
0047 using std::swap;
0048 using std::unique_ptr;
0049 using std::vector;
0050 #ifndef __GNUC__
0051 using std::atof;
0052 using std::atoi;
0053 #endif
0054 
0055 namespace hitfit {
0056 
0057   //************************************************************************
0058 
0059   Constraint_Intermed_Constant::Constraint_Intermed_Constant(double constant)
0060       //
0061       // Purpose: Constructor.
0062       //
0063       // Inputs:
0064       //   constant -    The constant in the mass constraint half.
0065       //
0066       : _c2(constant * constant / 2) {}
0067 
0068   Constraint_Intermed_Constant::Constraint_Intermed_Constant(const Constraint_Intermed_Constant& c)
0069       //
0070       // Purpose: Copy constructor.
0071       //
0072       // Inputs:
0073       //   c -           The instance to copy.
0074       //
0075       : _c2(c._c2) {}
0076 
0077   bool Constraint_Intermed_Constant::has_labels(int ilabel, int jlabel) const
0078   //
0079   // Purpose: Return true if this guy references both labels ILABEL and JLABEL.
0080   //
0081   //          This version always returns false.
0082   //
0083   // Inputs:
0084   //   ilabel -      The first label to test.
0085   //   jlabel -      The second label to test.
0086   //
0087   // Returns:
0088   //   True if this guy references both labels ILABEL and JLABEL.
0089   //
0090   {
0091     return false;
0092   }
0093 
0094   double Constraint_Intermed_Constant::sum_mass_terms(const Fourvec_Event& /*ev*/) const
0095   //
0096   // Purpose: Evaluate this half of the mass constraint, using the data in EV.
0097   //          Return m^2/2.
0098   //
0099   // Inputs:
0100   //   ev -          The event for which the constraint should be evaluated.
0101   //
0102   // Returns:
0103   //   m^2/2.
0104   //
0105   {
0106     return _c2;
0107   }
0108 
0109   void Constraint_Intermed_Constant::print(std::ostream& s) const
0110   //
0111   // Purpose: Print out this object.
0112   //
0113   // Inputs:
0114   //   s -           The stream to which we should write.
0115   //
0116   {
0117     s << sqrt(2 * _c2);
0118   }
0119 
0120   unique_ptr<Constraint_Intermed> Constraint_Intermed_Constant::clone() const
0121   //
0122   // Purpose: Copy this object.
0123   //
0124   // Returns:
0125   //   A new copy of this object.
0126   //
0127   {
0128     return unique_ptr<Constraint_Intermed>(new Constraint_Intermed_Constant(*this));
0129   }
0130 
0131   //************************************************************************
0132 
0133   Constraint_Intermed_Labels::Constraint_Intermed_Labels(const std::vector<int>& labels)
0134       //
0135       // Purpose: Constructor.
0136       //
0137       // Inputs:
0138       //   labels -      The labels used by this half-constraint.
0139       //
0140       : _labels(labels) {
0141     // Sort them.
0142     stable_sort(_labels.begin(), _labels.end());
0143   }
0144 
0145   Constraint_Intermed_Labels::Constraint_Intermed_Labels(const Constraint_Intermed_Labels& c)
0146       //
0147       // Purpose: Copy constructor.
0148       //
0149       // Inputs:
0150       //   c -           The instance to copy.
0151       //
0152       : _labels(c._labels) {}
0153 
0154   bool Constraint_Intermed_Labels::has_labels(int ilabel, int jlabel) const
0155   //
0156   // Purpose: Return true if this guy references both labels ILABEL and JLABEL.
0157   //
0158   // Inputs:
0159   //   ilabel -      The first label to test.
0160   //   jlabel -      The second label to test.
0161   //
0162   // Returns:
0163   //   True if this guy references both labels ILABEL and JLABEL.
0164   //
0165   {
0166     if (ilabel > jlabel)
0167       swap(ilabel, jlabel);
0168 
0169     unsigned sz = _labels.size();
0170     unsigned i;
0171     for (i = 0; i < sz; i++) {
0172       if (_labels[i] == ilabel)
0173         break;
0174     }
0175 
0176     if (i == sz)
0177       return false;
0178 
0179     for (; i < sz; i++) {
0180       if (_labels[i] == jlabel)
0181         break;
0182     }
0183 
0184     if (i == sz)
0185       return false;
0186 
0187     return true;
0188   }
0189 
0190   double Constraint_Intermed_Labels::sum_mass_terms(const Fourvec_Event& ev) const
0191   //
0192   // Purpose: Evaluate this half of the mass constraint, using the data in EV.
0193   //          Return m^2/2.
0194   //
0195   // Inputs:
0196   //   ev -          The event for which the constraint should be evaluated.
0197   //
0198   // Returns:
0199   //   m^2/2.
0200   //
0201   {
0202     int nobjs = ev.nobjs();
0203     double sum = 0;
0204     for (int i = 0; i < nobjs; i++) {
0205       const FE_Obj& o = ev.obj(i);
0206       if (has_label(o.label))
0207         sum += o.mass * o.mass / 2;
0208     }
0209 
0210     return sum;
0211   }
0212 
0213   void Constraint_Intermed_Labels::print(std::ostream& s) const
0214   //
0215   // Purpose: Print out this object.
0216   //
0217   // Inputs:
0218   //   s -           The stream to which we should write.
0219   //
0220   {
0221     s << "(";
0222     for (unsigned i = 0; i < _labels.size(); i++) {
0223       if (i > 0)
0224         s << "+";
0225       s << _labels[i];
0226     }
0227     s << ")";
0228   }
0229 
0230   bool Constraint_Intermed_Labels::has_label(int label) const
0231   //
0232   // Purpose: Helper function: Test to see if we use label LABEL.
0233   //
0234   // Inputs:
0235   //   label -       THe label for which to search.
0236   //
0237   // Returns:
0238   //   True if we use label LABEL.
0239   //
0240   {
0241     return find(_labels.begin(), _labels.end(), label) != _labels.end();
0242   }
0243 
0244   unique_ptr<Constraint_Intermed> Constraint_Intermed_Labels::clone() const
0245   //
0246   // Purpose: Copy this object.
0247   //
0248   // Returns:
0249   //   A new copy of this object.
0250   //
0251   {
0252     return unique_ptr<Constraint_Intermed>(new Constraint_Intermed_Labels(*this));
0253   }
0254 
0255   //************************************************************************
0256 
0257   /**
0258    @brief Output stream operator, print the content of this Constraint_Intermed
0259    to an output stream.
0260 
0261    @param s The output stream to write.
0262 
0263    @param ci The instance of <i>Constraint_Intermed</i> to be printed.
0264 
0265    @par Return:
0266    The stream <i>s</i>.
0267  */
0268   std::ostream& operator<<(std::ostream& s, const hitfit::Constraint_Intermed& ci)
0269   //
0270   // Purpose: Print the object to S.
0271   //
0272   // Inputs:
0273   //   s -           The stream to which to write.
0274   //   ci -          The object to write.
0275   //
0276   // Returns:
0277   //   The stream S.
0278   //
0279   {
0280     ci.print(s);
0281     return s;
0282   }
0283 
0284   unique_ptr<Constraint_Intermed> make_constraint_intermed(string s)
0285   //
0286   // Purpose: Parse the string S and return an appropriate
0287   //          Constraint_Intermed instance.
0288   //          Returns null if we can't interpret the string.
0289   //
0290   //          The string should either be a numeric constant like
0291   //
0292   //            80.2
0293   //
0294   //          or a list of integers in parens, like
0295   //
0296   //            (1 4 2)
0297   //
0298   //          Leading spaces are ignored, as is text in a leading < >
0299   //          construction.
0300   //
0301   // Inputs:
0302   //   s -           The string to parse.
0303   //
0304   // Returns:
0305   //   A new Constraint_Intermed instance, or null if we couldn't
0306   //   interpret the string.
0307   //
0308   {
0309     // Skip leading spaces, `=', '< ... >'.
0310     string::size_type i = 0;
0311     while (i < s.size() && s[i] == ' ')
0312       ++i;
0313     if (s[i] == '=')
0314       ++i;
0315     while (i < s.size() && s[i] == ' ')
0316       ++i;
0317     if (i < s.size() && s[i] == '<') {
0318       i = s.find('>', i);
0319       if (i == string::npos)
0320         return unique_ptr<Constraint_Intermed>();
0321       ++i;
0322     }
0323     while (i < s.size() && s[i] == ' ')
0324       ++i;
0325 
0326     // Fail if there's nothing left.
0327     if (i == s.size())
0328       return unique_ptr<Constraint_Intermed>();
0329 
0330     if (s[i] == '(') {
0331       // List of labels.
0332       // Make a Constraint_Intermed_Labels instance.
0333       vector<int> labels;
0334       ++i;
0335       while (i < s.size()) {
0336         while (i < s.size() && s[i] == ' ')
0337           ++i;
0338         if (i < s.size() && s[i] == ')')
0339           break;
0340         if (i < s.size())
0341           labels.push_back(atoi(s.c_str() + i));
0342         while (i < s.size() && s[i] != ' ' && s[i] != ')')
0343           ++i;
0344       }
0345       return unique_ptr<Constraint_Intermed>(new Constraint_Intermed_Labels(labels));
0346     } else {
0347       // Make a Constraint_Intermed_Constant instance.
0348       return unique_ptr<Constraint_Intermed>(new Constraint_Intermed_Constant(atof(s.c_str() + i)));
0349     }
0350   }
0351 
0352 }  // namespace hitfit