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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
#include <memory>
#include <fstream>
#include <iostream>

#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/ParameterSet/interface/FileInPath.h"
#include "DataFormats/DetId/interface/DetId.h"
#include "DataFormats/EcalDetId/interface/ESDetId.h"
#include "DataFormats/EcalDigi/interface/ESDataFrame.h"
#include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
#include "CondFormats/DataRecord/interface/ESGainRcd.h"
#include "DQMServices/Core/interface/DQMStore.h"
#include "DQM/EcalPreshowerMonitorModule/interface/ESTimingTask.h"

#include "TMath.h"
#include "TGraph.h"

using namespace cms;
using namespace edm;
using namespace std;

// fit function
double fitf(double* x, double* par) {
  double wc = par[2];
  double n = par[3];  // n-1 (in fact)
  double v1 = pow(wc / n * (x[0] - par[1]), n);
  double v2 = TMath::Exp(n - wc * (x[0] - par[1]));
  double v = par[0] * v1 * v2;

  if (x[0] < par[1])
    v = 0;

  return v;
}

ESTimingTask::ESTimingTask(const edm::ParameterSet& ps) {
  digilabel_ = consumes<ESDigiCollection>(ps.getParameter<InputTag>("DigiLabel"));
  prefixME_ = ps.getUntrackedParameter<string>("prefixME", "EcalPreshower");
  esgainToken_ = esConsumes();
  eCount_ = 0;

  fit_ = new TF1("fitShape", fitf, -200, 200, 4);
  fit_->SetParameters(50, 10, 0, 0);

  //Histogram init
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      hTiming_[i][j] = nullptr;

  htESP_ = new TH1F("htESP", "Timing ES+", 81, -20.5, 20.5);
  htESM_ = new TH1F("htESM", "Timing ES-", 81, -20.5, 20.5);
}

void ESTimingTask::bookHistograms(DQMStore::IBooker& iBooker, Run const&, EventSetup const&) {
  iBooker.setCurrentFolder(prefixME_ + "/ESTimingTask");

  //Booking Histograms
  //Notice: Change ESRenderPlugin under DQM/RenderPlugins/src if you change this histogram name.
  char histo[200];
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j) {
      int iz = (i == 0) ? 1 : -1;
      sprintf(histo, "ES Timing Z %d P %d", iz, j + 1);
      hTiming_[i][j] = iBooker.book1D(histo, histo, 81, -20.5, 20.5);
      hTiming_[i][j]->setAxisTitle("ES Timing (ns)", 1);
    }

  sprintf(histo, "ES 2D Timing");
  h2DTiming_ = iBooker.book2D(histo, histo, 81, -20.5, 20.5, 81, -20.5, 20.5);
  h2DTiming_->setAxisTitle("ES- Timing (ns)", 1);
  h2DTiming_->setAxisTitle("ES+ Timing (ns)", 2);
}

ESTimingTask::~ESTimingTask() {
  delete fit_;
  delete htESP_;
  delete htESM_;
}

void ESTimingTask::analyze(const edm::Event& e, const edm::EventSetup& iSetup) {
  set(iSetup);

  runNum_ = e.id().run();
  eCount_++;

  htESP_->Reset();
  htESM_->Reset();

  //Digis
  int zside, plane, ix, iy, is;
  double adc[3];
  //  double para[10];
  //double tx[3] = {-5., 20., 45.};
  Handle<ESDigiCollection> digis;
  if (e.getByToken(digilabel_, digis)) {
    for (ESDigiCollection::const_iterator digiItr = digis->begin(); digiItr != digis->end(); ++digiItr) {
      ESDataFrame dataframe = (*digiItr);
      ESDetId id = dataframe.id();

      zside = id.zside();
      plane = id.plane();
      ix = id.six();
      iy = id.siy();
      is = id.strip();

      //if (zside==1 && plane==1 && ix==15 && iy==6) continue;
      if (zside == 1 && plane == 1 && ix == 7 && iy == 28)
        continue;
      if (zside == 1 && plane == 1 && ix == 24 && iy == 9 && is == 21)
        continue;
      if (zside == -1 && plane == 2 && ix == 35 && iy == 17 && is == 23)
        continue;

      int i = (zside == 1) ? 0 : 1;
      int j = plane - 1;

      for (int k = 0; k < dataframe.size(); ++k)
        adc[k] = dataframe.sample(k).adc();

      double status = 0;
      if (adc[1] < 200)
        status = 1;
      if (fabs(adc[0]) > 10)
        status = 1;
      if (adc[1] < 0 || adc[2] < 0)
        status = 1;
      if (adc[0] > adc[1] || adc[0] > adc[2])
        status = 1;
      if (adc[2] > adc[1])
        status = 1;

      if (int(status) == 0) {
        double A1 = adc[1];
        double A2 = adc[2];
        double DeltaT = 25.;
        double aaa = (A2 > 0 && A1 > 0) ? log(A2 / A1) / n_ : 20.;  // if A1=0, t0=20
        double bbb = wc_ / n_ * DeltaT;
        double ccc = exp(aaa + bbb);

        double t0 = (2. - ccc) / (1. - ccc) * DeltaT - 5;
        hTiming_[i][j]->Fill(t0);
        //cout<<"t0 : "<<t0<<endl;
        /*
	TGraph *gr = new TGraph(3, tx, adc);
	fit_->SetParameters(50, 10, wc_, n_);
	fit_->FixParameter(2, wc_);
	fit_->FixParameter(3, n_);
	fit_->Print();
	gr->Fit("fitShape", "MQ");
	fit_->GetParameters(para); 
	delete gr;
	//hTiming_[i][j]->Fill(para[1]);
	*/
        //cout<<"ADC : "<<zside<<" "<<plane<<" "<<ix<<" "<<iy<<" "<<is<<" "<<adc[0]<<" "<<adc[1]<<" "<<adc[2]<<" "<<para[1]<<" "<<wc_<<" "<<n_<<endl;

        if (zside == 1)
          htESP_->Fill(t0);
        else if (zside == -1)
          htESM_->Fill(t0);
      }
    }
  } else {
    LogWarning("ESTimingTask") << "DigiCollection not available";
  }

  if (htESP_->GetEntries() > 0 && htESM_->GetEntries() > 0)
    h2DTiming_->Fill(htESM_->GetMean(), htESP_->GetMean());
}

void ESTimingTask::set(const edm::EventSetup& es) {
  const ESGain* gain = &es.getData(esgainToken_);

  int ESGain = (int)gain->getESGain();

  if (ESGain == 1) {  // LG
    wc_ = 0.0837264;
    n_ = 2.016;
  } else {  // HG
    wc_ = 0.07291;
    n_ = 1.798;
  }

  //cout<<"gain : "<<ESGain<<endl;
  //cout<<wc_<<" "<<n_<<endl;
}

//define this as a plug-in
DEFINE_FWK_MODULE(ESTimingTask);