CheckerType

Comparer

CounterChecker

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
/****************************************************************************
 *
 * This is a part of the TOTEM offline software.
 * Authors: 
 *   Maciej Wróbel (wroblisko@gmail.com)
 *   Jan Kašpar (jan.kaspar@gmail.com)
 *
 ****************************************************************************/

#ifndef EventFilter_CTPPSRawToDigi_CounterChecker
#define EventFilter_CTPPSRawToDigi_CounterChecker

#include <map>
#include <string>
#include <vector>
#include <iostream>

#include "CondFormats/PPSObjects/interface/TotemFramePosition.h"

#include "DataFormats/CTPPSDigi/interface/TotemVFATStatus.h"

/**
 *\brief Class for finding the most popular both EC and BC counter, and filling the conversion
 * status 'wrong EC/BC number' for frames with different value.
 */
class CounterChecker {
public:
  typedef unsigned short word;

  typedef std::map<word, std::vector<TotemFramePosition> > CounterMap;

  enum CheckerType { BCChecker, ECChecker };

  /**
     * \param t: CounterChecker::ECCounter or CounterChecker::BCCounter. On that, depends whether
     * checker will fill wrong EC or BC rogress error.
     * \param name: name
     * \param min: minimal required number of frames to search for the most frequent one
     */
  CounterChecker(CheckerType _type = CounterChecker::BCChecker,
                 const std::string &_name = "",
                 unsigned int _min = 0,
                 double _fraction = 0.,
                 unsigned int _verbosity = 0)
      : type(_type), name(_name), min(_min), fraction(_fraction), verbosity(_verbosity) {}

  /// add new value to map, counter takes value of EC or BC number
  void Fill(word counter, TotemFramePosition fr);

  /// summarizes and fill the status (wrong EC and BC progress error for some frames)
  template <typename T>
  void Analyze(T &status, bool error, std::ostream &es);

private:
  class Comparer {
  public:
    typedef unsigned short word;
    bool operator()(const std::pair<word, std::vector<TotemFramePosition> > &a,
                    const std::pair<word, std::vector<TotemFramePosition> > &b) {
      return a.second.size() < b.second.size();
    }
  };

  /// counter value -> list of frames with this value
  CounterMap relationMap;

  /// EC or BC counter checker
  CheckerType type;

  /// the name of this check, used in error messages
  std::string name;

  /// minimal required number of frames to search for the most frequent one
  unsigned int min;

  /// the most frequent value is accepted only provided its sub-sample size is greater than the
  /// specified fraction of the full sample
  double fraction;

  /// level of verbosity
  unsigned int verbosity;
};

template <typename T>
void CounterChecker::Analyze(T &status, bool error, std::ostream &es) {
  word mostFrequentCounter = 0;
  word mostFrequentSize = 0;
  unsigned int totalFrames = 0;

  // finding the most frequent counter
  for (CounterMap::iterator iter = relationMap.begin(); iter != relationMap.end(); iter++) {
    unsigned int iterSize = iter->second.size();
    totalFrames += iterSize;

    if (iterSize > mostFrequentSize) {
      mostFrequentCounter = iter->first;
      mostFrequentSize = iter->second.size();
    }
  }

  if (totalFrames < min) {
    if (verbosity > 0)
      es << "Too few frames to determine the most frequent " << name << " value.";

    return;
  }

  // if there are too few frames with the most frequent value
  if ((float)mostFrequentSize / (float)totalFrames < fraction) {
    if (verbosity > 0)
      es << "The most frequent " << name << " value is doubtful - variance is too high.";

    return;
  }

  for (CounterMap::iterator iter = relationMap.begin(); iter != relationMap.end(); iter++) {
    if (iter->first != mostFrequentCounter) {
      for (std::vector<TotemFramePosition>::iterator fr = iter->second.begin(); fr != iter->second.end(); fr++) {
        if (error) {
          if (type == ECChecker)
            status[*fr].status.setECProgressError();
          if (type == BCChecker)
            status[*fr].status.setBCProgressError();
        }

        if (verbosity > 0)
          es << "Frame at " << *fr << ": " << name << " number " << iter->first
             << " is different from the most frequent one " << mostFrequentCounter << std::endl;
      }
    }
  }
}

#endif