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

/** \file GenericMinL3Algorithm.cc
 *
 *
 * \author R.Ofierzynski, CERN
 */

#include "Calibration/Tools/interface/GenericMinL3Algorithm.h"

GenericMinL3Algorithm::GenericMinL3Algorithm(bool normalise)
    : normaliseFlag(normalise)
// if normalize=true: for all events sum the e25ovTRP. then take the mean value and rescale all TrP
{}

GenericMinL3Algorithm::~GenericMinL3Algorithm() {}

std::vector<float> GenericMinL3Algorithm::iterate(const std::vector<std::vector<float> >& eventMatrix,
                                                  const std::vector<float>& energyVector,
                                                  const int nIter) {
  std::vector<float> solution;
  std::vector<std::vector<float> > myEventMatrix(eventMatrix);
  int Nevents = eventMatrix.size();       // Number of events to calibrate with
  int Nchannels = eventMatrix[0].size();  // Number of channel coefficients
  std::vector<float> theCalibVector(Nchannels, 1.);

  // Iterate the correction
  for (int iter = 1; iter <= nIter; iter++) {
    // make one iteration
    solution = iterate(myEventMatrix, energyVector);

    if (solution.empty())
      return solution;
    // R.O.: or throw an exception, what's the standard CMS way ?

    // re-calibrate eventMatrix with solution
    for (int i = 0; i < Nchannels; i++) {
      for (int ievent = 0; ievent < Nevents; ievent++) {
        myEventMatrix[ievent][i] *= solution[i];
      }
      // save solution into theCalibVector
      theCalibVector[i] *= solution[i];
    }

  }  // end iterate the correction

  return theCalibVector;
}

std::vector<float> GenericMinL3Algorithm::iterate(const std::vector<std::vector<float> >& eventMatrix,
                                                  const std::vector<float>& energyVector) {
  std::vector<float> solution;
  std::vector<float> myEnergyVector(energyVector);

  int Nevents = eventMatrix.size();       // Number of events to calibrate with
  int Nchannels = eventMatrix[0].size();  // Number of channel coefficients

  // Sanity check
  if (Nevents != int(myEnergyVector.size())) {
    std::cout << "GenericMinL3Algorithm::iterate(): Error: bad matrix dimensions. Dropping out." << std::endl;
    return solution;  // empty vector !
  }

  // initialize the solution vector with 1.
  solution.assign(Nchannels, 1.);

  int ievent, i, j;

  // if normalization flag is set, normalize energies
  float sumOverEnergy;
  if (normaliseFlag) {
    float scale = 0.;

    std::cout << "GenericMinL3Algorithm::iterate(): Normalising event data" << std::endl;

    for (i = 0; i < Nevents; i++) {
      sumOverEnergy = 0.;
      for (j = 0; j < Nchannels; j++) {
        sumOverEnergy += eventMatrix[i][j];
      }
      sumOverEnergy /= myEnergyVector[i];
      scale += sumOverEnergy;
    }
    scale /= Nevents;
    std::cout << "  Normalisation = " << scale << std::endl;

    for (i = 0; i < Nevents; i++) {
      myEnergyVector[i] *= scale;
    }
  }  // end normalize energies

  // This is where the real work goes on...
  float sum25, invsum25;
  float w;                                  // weight for event
  std::vector<float> wsum(Nchannels, 0.);   // sum of weights for a crystal
  std::vector<float> Ewsum(Nchannels, 0.);  // sum of products of weight*Etrue/E25

  // Loop over events
  for (ievent = 0; ievent < Nevents; ievent++) {
    // Loop over the 5x5 to find the sum
    sum25 = 0.;

    for (i = 0; i < Nchannels; i++) {
      sum25 += eventMatrix[ievent][i];
    }  //*calibs[i];

    if (sum25 != 0.) {
      invsum25 = 1 / sum25;
      // Loop over the 5x5 again and calculate the weights for each xtal
      for (i = 0; i < Nchannels; i++) {
        w = eventMatrix[ievent][i] * invsum25;  // * calibs[i]
        wsum[i] += w;
        Ewsum[i] += (w * myEnergyVector[ievent] * invsum25);
      }
    } else {
      std::cout << " Debug: dropping null event: " << ievent << std::endl;
    }

  }  // end Loop over events

  // Apply correction factors to all channels not in the margin
  for (i = 0; i < Nchannels; i++) {
    if (wsum[i] != 0.) {
      solution[i] *= Ewsum[i] / wsum[i];
    } else {
      std::cout << "warning - no event data for crystal index " << i << std::endl;
    }
  }

  return solution;
}