#include "CondTools/Ecal/interface/EcalLaserHandler.h"

#include "CondTools/Ecal/interface/EcalPedestalsHandler.h"
#include "FWCore/ParameterSet/interface/ParameterSetfwd.h"

#include <cstring>
#include <iostream>
#include <fstream>

#include "TFile.h"
#include "TTree.h"

const Int_t kChannels = 75848, kEBChannels = 61200, kEEChannels = 14648, kGains = 3;
const Int_t Nbpedxml = 81;  // Number of Gain1 Gain6 files in 2016 (26), 2017 (25), 2018 (30) : L1248 and L1600
const Int_t gainValues[kGains] = {12, 6, 1};

popcon::EcalPedestalsHandler::EcalPedestalsHandler(const edm::ParameterSet& ps)
    : m_name(ps.getUntrackedParameter<std::string>("name", "EcalPedestalsHandler")) {
  edm::LogInfo("EcalPedestals Source handler constructor\n");
  m_firstRun = static_cast<unsigned int>(atoi(ps.getParameter<std::string>("firstRun").c_str()));
  m_lastRun = static_cast<unsigned int>(atoi(ps.getParameter<std::string>("lastRun").c_str()));
  m_sid = ps.getParameter<std::string>("OnlineDBSID");
  m_user = ps.getParameter<std::string>("OnlineDBUser");
  m_pass = ps.getParameter<std::string>("OnlineDBPassword");
  m_locationsource = ps.getParameter<std::string>("LocationSource");
  m_location = ps.getParameter<std::string>("Location");
  m_gentag = ps.getParameter<std::string>("GenTag");
  m_runtag = ps.getParameter<std::string>("RunTag");
  m_filename = ps.getUntrackedParameter<std::string>("filename", "EcalPedestals.txt");
  m_runtype = ps.getUntrackedParameter<int>("RunType", 1);
  m_corrected = ps.getUntrackedParameter<bool>("corrected", false);

  edm::LogInfo("EcalPedestalsHandler") << m_sid << "/"
                                       << "/" << m_location << "/" << m_gentag;
}

popcon::EcalPedestalsHandler::~EcalPedestalsHandler() {}

void popcon::EcalPedestalsHandler::getNewObjects() {
  edm::LogInfo("------- Ecal - > getNewObjects\n");
  if (m_locationsource == "P5") {
    getNewObjectsP5();
  } else if (m_locationsource == "H2") {
    getNewObjectsH2();
  } else if (m_locationsource == "File") {
    readPedestalFile();
  } else if (m_locationsource == "MC") {
    readPedestalMC();
  } else if (m_locationsource == "2017") {
    readPedestal2017();
  } else if (m_locationsource == "Tree") {
    readPedestalTree();
  } else if (m_locationsource == "Timestamp") {
    readPedestalTimestamp();
  } else {
    edm::LogInfo(" unknown location ") << m_locationsource << " give up ";
    exit(-1);
  }
}

bool popcon::EcalPedestalsHandler::checkPedestal(EcalPedestals::Item* item) {
  // true means all is standard and OK
  bool result = true;
  if (item->rms_x12 > 3 || item->rms_x12 <= 0)
    result = false;
  if (item->rms_x6 > 2 || item->rms_x6 <= 0)
    result = false;
  if (item->rms_x1 > 1 || item->rms_x1 <= 0)
    result = false;
  if (item->mean_x12 > 300 || item->mean_x12 <= 100)
    result = false;
  if (item->mean_x1 > 300 || item->mean_x1 <= 100)
    result = false;
  if (item->mean_x6 > 300 || item->mean_x6 <= 100)
    result = false;
  return result;
}

////////////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::getNewObjectsP5() {
  std::ostringstream ss;
  ss << "ECAL ";

  unsigned int max_since = 0;
  max_since = static_cast<unsigned int>(tagInfo().lastInterval.since);
  edm::LogInfo("max_since : ") << max_since;
  Ref ped_db = lastPayload();

  // we copy the last valid record to a temporary object peds
  EcalPedestals* peds = new EcalPedestals();
  edm::LogInfo("retrieved last payload ");

  for (int iEta = -EBDetId::MAX_IETA; iEta <= EBDetId::MAX_IETA; ++iEta) {
    if (iEta == 0)
      continue;
    for (int iPhi = EBDetId::MIN_IPHI; iPhi <= EBDetId::MAX_IPHI; ++iPhi) {
      // make an EBDetId since we need EBDetId::rawId() to be used as the key for the pedestals
      if (EBDetId::validDetId(iEta, iPhi)) {
        EBDetId ebdetid(iEta, iPhi, EBDetId::ETAPHIMODE);
        EcalPedestals::const_iterator it = ped_db->find(ebdetid.rawId());
        EcalPedestals::Item aped = (*it);

        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;

        peds->insert(std::make_pair(ebdetid.rawId(), item));
      }
    }
  }

  for (int iX = EEDetId::IX_MIN; iX <= EEDetId::IX_MAX; ++iX) {
    for (int iY = EEDetId::IY_MIN; iY <= EEDetId::IY_MAX; ++iY) {
      // make an EEDetId since we need EEDetId::rawId() to be used as the key for the pedestals
      if (EEDetId::validDetId(iX, iY, 1)) {
        EEDetId eedetidpos(iX, iY, 1);

        EcalPedestals::const_iterator it = ped_db->find(eedetidpos.rawId());
        EcalPedestals::Item aped = (*it);

        //	unsigned int hiee = eedetidpos.hashedIndex();
        //	EcalPedestals::Item aped= ped_db->endcap(hiee);

        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;
        peds->insert(std::make_pair(eedetidpos.rawId(), item));
      }
      if (EEDetId::validDetId(iX, iY, -1)) {
        EEDetId eedetidneg(iX, iY, -1);

        EcalPedestals::const_iterator it = ped_db->find(eedetidneg.rawId());
        EcalPedestals::Item aped = (*it);
        //     unsigned int hiee = eedetidneg.hashedIndex();
        //     EcalPedestals::Item aped= ped_db->endcap(hiee);

        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;
        peds->insert(std::make_pair(eedetidneg.rawId(), item));
      }
    }
  }

  // here we retrieve all the runs after the last from online DB

  edm::LogInfo("Retrieving run list from ONLINE DB ... ");
  econn = new EcalCondDBInterface(m_sid, m_user, m_pass);
  edm::LogInfo("Connection done");

  // these are the online conditions DB classes
  RunList my_runlist;
  RunTag my_runtag;
  LocationDef my_locdef;
  RunTypeDef my_rundef;

  my_locdef.setLocation(m_location);
  //	my_rundef.setRunType("PEDESTAL");  // 2017
  my_rundef.setRunType(m_runtag);
  my_runtag.setLocationDef(my_locdef);
  my_runtag.setRunTypeDef(my_rundef);
  my_runtag.setGeneralTag(m_gentag);

  // here we retrieve the Monitoring run records

  MonVersionDef monverdef;
  monverdef.setMonitoringVersion("test01");

  MonRunTag mon_tag;
  //	mon_tag.setGeneralTag("CMSSW");
  mon_tag.setGeneralTag("CMSSW-offline-private");
  mon_tag.setMonVersionDef(monverdef);
  MonRunList mon_list;
  mon_list.setMonRunTag(mon_tag);
  mon_list.setRunTag(my_runtag);
  //    mon_list=econn->fetchMonRunList(my_runtag, mon_tag);
  unsigned int min_run = 0;
  if (m_firstRun < max_since) {
    min_run = max_since + 1;  // we have to add 1 to the last transferred one
  } else {
    min_run = m_firstRun;
  }

  unsigned int max_run = m_lastRun;
  mon_list = econn->fetchMonRunList(my_runtag, mon_tag, min_run, max_run);

  std::vector<MonRunIOV> mon_run_vec = mon_list.getRuns();
  int mon_runs = mon_run_vec.size();
  edm::LogInfo("number of Mon runs is : ") << mon_runs;

  if (mon_runs > 0) {
    int krmax = std::min(mon_runs, 30);
    for (int kr = 0; kr < krmax; kr++) {
      edm::LogInfo("-kr------:  ") << kr;

      unsigned int irun = static_cast<unsigned int>(mon_run_vec[kr].getRunIOV().getRunNumber());
      edm::LogInfo("retrieve the data for run number: ") << mon_run_vec[kr].getRunIOV().getRunNumber();
      if (mon_run_vec[kr].getSubRunNumber() <= 1) {
        // retrieve the data for a given run
        RunIOV runiov_prime = mon_run_vec[kr].getRunIOV();
        // retrieve the pedestals from OMDS for this run
        std::map<EcalLogicID, MonPedestalsDat> dataset_mon;
        econn->fetchDataSet(&dataset_mon, &mon_run_vec[kr]);
        edm::LogInfo("OMDS record for run ") << irun << " is made of " << dataset_mon.size();
        int nEB = 0, nEE = 0;
        typedef std::map<EcalLogicID, MonPedestalsDat>::const_iterator CImon;
        EcalLogicID ecid_xt;
        MonPedestalsDat rd_ped;

        // this to validate ...
        int nbad = 0;
        for (CImon p = dataset_mon.begin(); p != dataset_mon.end(); p++) {
          ecid_xt = p->first;
          rd_ped = p->second;
          int sm_num = ecid_xt.getID1();
          int xt_num = ecid_xt.getID2();
          int yt_num = ecid_xt.getID3();

          EcalPedestals::Item item;
          item.mean_x1 = rd_ped.getPedMeanG1();
          item.rms_x1 = rd_ped.getPedRMSG1();
          item.mean_x6 = rd_ped.getPedMeanG6();
          item.rms_x6 = rd_ped.getPedRMSG6();
          item.mean_x12 = rd_ped.getPedMeanG12();
          item.rms_x12 = rd_ped.getPedRMSG12();
          /*	
	  if(irun != 280216 && irun != 280218 && irun != 280259 && irun != 280261 && irun != 280392 && irun != 280394
	     && irun != 280762 && irun != 280765 && irun != 280936 && irun != 280939 && irun != 281756 && irun != 281757) {
	  */
          if (ecid_xt.getName() == "EB_crystal_number") {
            nEB++;
          } else {
            nEE++;
          }

          // here we check and count how many bad channels we have

          if (!checkPedestal(&item)) {
            nbad++;
            if (nbad < 10)
              std::cout << "BAD LIST: channel " << sm_num << "/" << xt_num << "/" << yt_num << "ped/rms "
                        << item.mean_x12 << "/" << item.rms_x12 << std::endl;
          }
          /*
	  }
	  else {      // only gain 12 in these runs
	    if(ecid_xt.getName()=="EB_crystal_number") {
	      nEB++;
	      if(item.mean_x12 <= 100 || item.mean_x12 > 300 || item.rms_x12 > 3 || item.rms_x12 <= 0) {
		nbad++;
		nEBbad++;
	      }
	    }
	    else {
	      nEE++;
	      if(item.mean_x12 <= 100 || item.mean_x12 > 300 || item.rms_x12 > 3 || item.rms_x12 <= 0) {
		nbad++;
		nEEbad++;
	      }
	    }
	  }    //    only gain 12 in these runs
	    */
        }  // loop over all channels

        // ok or bad?
        // a bad run is for more than 5% bad channels

        //	      if(nbad<(dataset_mon.size()*0.1)){
        if (nbad < (dataset_mon.size() * 0.05) && (nEB > 10200 || nEE > 2460)) {
          for (CImon p = dataset_mon.begin(); p != dataset_mon.end(); p++) {
            ecid_xt = p->first;
            rd_ped = p->second;
            int sm_num = ecid_xt.getID1();
            int xt_num = ecid_xt.getID2();
            int yt_num = ecid_xt.getID3();

            EcalPedestals::Item item;
            item.mean_x1 = rd_ped.getPedMeanG1();
            item.rms_x1 = rd_ped.getPedRMSG1();
            item.mean_x6 = rd_ped.getPedMeanG6();
            item.rms_x6 = rd_ped.getPedRMSG6();
            item.mean_x12 = rd_ped.getPedMeanG12();
            item.rms_x12 = rd_ped.getPedRMSG12();

            if (ecid_xt.getName() == "EB_crystal_number") {
              // Barrel channel
              EBDetId ebdetid(sm_num, xt_num, EBDetId::SMCRYSTALMODE);

              // individual objects check
              if (item.mean_x1 == -1 || item.rms_x1 == -1 || item.mean_x6 == -1 || item.rms_x6 == -1 ||
                  item.mean_x12 == -1 || item.rms_x12 == -1 || item.mean_x1 == 0 || item.rms_x1 == 0 ||
                  item.mean_x6 == 0 || item.rms_x6 == 0 || item.mean_x12 == 0 || item.rms_x12 == 0) {
                // if one is bad we
                // retrieve the old valid value
                unsigned int hieb = ebdetid.hashedIndex();
                EcalPedestals::Item previous_ped = peds->barrel(hieb);
                if (item.mean_x1 == -1 || item.mean_x1 == 0)
                  item.mean_x1 = previous_ped.mean_x1;
                if (item.rms_x1 == -1 || item.rms_x1 == 0)
                  item.rms_x1 = previous_ped.rms_x1;
                if (item.mean_x6 == -1 || item.mean_x6 == 0)
                  item.mean_x6 = previous_ped.mean_x6;
                if (item.rms_x6 == -1 || item.rms_x6 == 0)
                  item.rms_x6 = previous_ped.rms_x6;
                if (item.mean_x12 == -1 || item.mean_x12 == 0)
                  item.mean_x12 = previous_ped.mean_x12;
                if (item.rms_x12 == -1 || item.rms_x12 == 0)
                  item.rms_x12 = previous_ped.rms_x12;
              }

              // here we change in the peds object only the channels that are available in the online DB
              // otherwise we keep the previous value
              peds->insert(std::make_pair(ebdetid.rawId(), item));
            } else {
              // Endcap channel
              // in this case xt_num is x
              // yt_num is y and sm_num is the side +/- 1
              if (EEDetId::validDetId(xt_num, yt_num, sm_num)) {
                EEDetId eedetid(xt_num, yt_num, sm_num);

                // individual objects check
                if (item.mean_x1 == -1 || item.rms_x1 == -1 || item.mean_x6 == -1 || item.rms_x6 == -1 ||
                    item.mean_x12 == -1 || item.rms_x12 == -1 || item.mean_x1 == 0 || item.rms_x1 == 0 ||
                    item.mean_x6 == 0 || item.rms_x6 == 0 || item.mean_x12 == 0 || item.rms_x12 == 0) {
                  // if one is bad we
                  // retrieve the old valid value
                  unsigned int hiee = eedetid.hashedIndex();
                  EcalPedestals::Item previous_ped = peds->endcap(hiee);
                  if (item.mean_x1 == -1 || item.mean_x1 == 0)
                    item.mean_x1 = previous_ped.mean_x1;
                  if (item.rms_x1 == -1 || item.rms_x1 == 0)
                    item.rms_x1 = previous_ped.rms_x1;
                  if (item.mean_x6 == -1 || item.mean_x6 == 0)
                    item.mean_x6 = previous_ped.mean_x6;
                  if (item.rms_x6 == -1 || item.rms_x6 == 0)
                    item.rms_x6 = previous_ped.rms_x6;
                  if (item.mean_x12 == -1 || item.mean_x12 == 0)
                    item.mean_x12 = previous_ped.mean_x12;
                  if (item.rms_x12 == -1 || item.rms_x12 == 0)
                    item.rms_x12 = previous_ped.rms_x12;
                }
                // here we change in the peds object only the channels that are available in the online DB
                // otherwise we keep the previous value
                peds->insert(std::make_pair(eedetid.rawId(), item));
              }
            }
          }

          edm::LogInfo("Generating popcon record for run ") << irun << "..." << std::flush;
          // now I copy peds in pedtemp and I ship pedtemp to popcon
          // if I use always the same peds I always overwrite
          // so I really have to create new objects for each new run
          // popcon deletes everything for me

          EcalPedestals* pedtemp = new EcalPedestals();
          for (int iEta = -EBDetId::MAX_IETA; iEta <= EBDetId::MAX_IETA; ++iEta) {
            if (iEta == 0)
              continue;
            for (int iPhi = EBDetId::MIN_IPHI; iPhi <= EBDetId::MAX_IPHI; ++iPhi) {
              // make an EBDetId since we need EBDetId::rawId() to be used as the key for the pedestals
              if (EBDetId::validDetId(iEta, iPhi)) {
                EBDetId ebdetid(iEta, iPhi);
                unsigned int hiee = ebdetid.hashedIndex();
                EcalPedestals::Item aped = peds->barrel(hiee);

                // here I copy the last valid value in the peds object
                EcalPedestals::Item item;
                item.mean_x1 = aped.mean_x1;
                item.rms_x1 = aped.rms_x1;
                item.mean_x6 = aped.mean_x6;
                item.rms_x6 = aped.rms_x6;
                item.mean_x12 = aped.mean_x12;
                item.rms_x12 = aped.rms_x12;
                // here I copy the last valid value in the pedtemp object
                pedtemp->insert(std::make_pair(ebdetid.rawId(), item));
                if ((iEta == -1 || iEta == 1) && iPhi == 20) {
                  float x = aped.mean_x12;
                  edm::LogInfo("channel:") << iEta << "/" << iPhi << "/" << hiee << " ped mean 12=" << x;
                }
              }
            }
          }
          // endcaps
          for (int iX = EEDetId::IX_MIN; iX <= EEDetId::IX_MAX; ++iX) {
            for (int iY = EEDetId::IY_MIN; iY <= EEDetId::IY_MAX; ++iY) {
              // make an EEDetId since we need EEDetId::rawId() to be used as the key for the pedestals
              if (EEDetId::validDetId(iX, iY, 1)) {
                EEDetId eedetid(iX, iY, 1);
                unsigned int hiee = eedetid.hashedIndex();
                EcalPedestals::Item aped = peds->endcap(hiee);
                // here I copy the last valid value in the peds object
                EcalPedestals::Item item;
                item.mean_x1 = aped.mean_x1;
                item.rms_x1 = aped.rms_x1;
                item.mean_x6 = aped.mean_x6;
                item.rms_x6 = aped.rms_x6;
                item.mean_x12 = aped.mean_x12;
                item.rms_x12 = aped.rms_x12;
                // here I copy the last valid value in the pedtemp object
                pedtemp->insert(std::make_pair(eedetid.rawId(), item));
              }
              if (EEDetId::validDetId(iX, iY, -1)) {
                EEDetId eedetid(iX, iY, -1);
                unsigned int hiee = eedetid.hashedIndex();
                EcalPedestals::Item aped = peds->endcap(hiee);
                // here I copy the last valid value in the peds object
                EcalPedestals::Item item;
                item.mean_x1 = aped.mean_x1;
                item.rms_x1 = aped.rms_x1;
                item.mean_x6 = aped.mean_x6;
                item.rms_x6 = aped.rms_x6;
                item.mean_x12 = aped.mean_x12;
                item.rms_x12 = aped.rms_x12;
                // here I copy the last valid value in the pedtemp object
                pedtemp->insert(std::make_pair(eedetid.rawId(), item));
              }
            }
          }

          Time_t snc = (Time_t)irun;
          m_to_transfer.push_back(std::make_pair((EcalPedestals*)pedtemp, snc));

          ss << "Run=" << irun << "_WAS_GOOD_" << std::endl;
          m_userTextLog = ss.str() + ";";
        }  // good run : write in DB
        else {
          edm::LogInfo("Run ") << irun << " was BAD !!!! not sent to the DB";
          if (nbad >= (dataset_mon.size() * 0.05))
            edm::LogInfo(" number of bad channels = ") << nbad;
          if (nEB <= 10200)
            edm::LogInfo(" number of EB channels = ") << nEB;
          if (nEE <= 2440)
            edm::LogInfo(" number of EE channels = ") << nEE;
          ss << "Run=" << irun << "_WAS_BAD_" << std::endl;
          m_userTextLog = ss.str() + ";";
        }  //  bad run : do not write in DB
      }    //  SubRunNumber
    }      // loop over runs

    delete econn;
    delete peds;  // this is the only one that popcon does not delete
  }               // runs to analyze ?
  edm::LogInfo("Ecal - > end of getNewObjects -----------\n");
}

////////////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::getNewObjectsH2() {
  unsigned int max_since = 0;
  max_since = static_cast<unsigned int>(tagInfo().lastInterval.since);
  edm::LogInfo("max_since : ") << max_since;
  Ref ped_db = lastPayload();

  edm::LogInfo("retrieved last payload ");

  // we copy the last valid record to a temporary object peds
  EcalPedestals* peds = new EcalPedestals();

  // get from offline DB the last valid pedestal set ped_db
  //	edm::ESHandle<EcalPedestals> pedestals;
  //	esetup.get<EcalPedestalsRcd>().get(pedestals);

  // only positive endcap side and
  // x from 86 to 95
  // y from 46 to 55
  int ixmin = 86;
  int ixmax = 95;
  int iymin = 46;
  int iymax = 55;
  for (int iX = ixmin; iX <= ixmax; ++iX) {
    for (int iY = iymin; iY <= iymax; ++iY) {
      if (EEDetId::validDetId(iX, iY, 1)) {
        EEDetId eedetidpos(iX, iY, 1);
        unsigned int hiee = eedetidpos.hashedIndex();
        EcalPedestals::Item aped = ped_db->endcap(hiee);

        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;
        peds->insert(std::make_pair(eedetidpos.rawId(), item));
        if (iX == ixmin && iY == iymin)
          std::cout << "ped12 " << item.mean_x12 << std::endl;
      }
    }
  }

  edm::LogInfo("We just retrieved the last valid record from DB ");

  // here we retrieve all the runs after the last from online DB

  edm::LogInfo("Retrieving run list from ONLINE DB ... ");

  edm::LogInfo("Making connection...") << std::flush;
  econn = new EcalCondDBInterface(m_sid, m_user, m_pass);
  edm::LogInfo("Done.");

  if (!econn) {
    edm::LogInfo(" connection parameters ") << m_sid;
    throw cms::Exception("OMDS not available");
  }

  // these are the online conditions DB classes
  RunList my_runlist;
  RunTag my_runtag;
  LocationDef my_locdef;
  RunTypeDef my_rundef;

  my_locdef.setLocation("H2_07");
  my_rundef.setRunType("PEDESTAL");
  my_runtag.setLocationDef(my_locdef);
  my_runtag.setRunTypeDef(my_rundef);
  my_runtag.setGeneralTag("LOCAL");

  // here we retrieve the Monitoring run records

  MonVersionDef monverdef;
  monverdef.setMonitoringVersion("test01");

  MonRunTag mon_tag;
  mon_tag.setGeneralTag("CMSSW");
  mon_tag.setMonVersionDef(monverdef);
  MonRunList mon_list;
  mon_list.setMonRunTag(mon_tag);
  mon_list.setRunTag(my_runtag);
  //    mon_list=econn->fetchMonRunList(my_runtag, mon_tag);
  unsigned int min_run = max_since + 1;  // we have to add 1 to the last transferred one

  unsigned int max_run = m_lastRun;
  mon_list = econn->fetchMonRunList(my_runtag, mon_tag, min_run, max_run);

  std::vector<MonRunIOV> mon_run_vec = mon_list.getRuns();
  size_t mon_runs = mon_run_vec.size();
  edm::LogInfo("number of Mon runs is : ") << mon_runs;

  if (mon_runs > 0) {
    for (size_t kr = 0; kr < mon_runs; kr++) {
      unsigned int irun = static_cast<unsigned int>(mon_run_vec[kr].getRunIOV().getRunNumber());

      edm::LogInfo("here is first sub run : ") << mon_run_vec[kr].getSubRunNumber();
      edm::LogInfo("here is the run number: ") << mon_run_vec[kr].getRunIOV().getRunNumber();

      edm::LogInfo(" retrieve the data for a given run");

      if (mon_run_vec[kr].getSubRunNumber() <= 1) {
        // retrieve the data for a given run
        RunIOV runiov_prime = mon_run_vec[kr].getRunIOV();

        // retrieve the pedestals from OMDS for this run
        std::map<EcalLogicID, MonPedestalsDat> dataset_mon;
        econn->fetchDataSet(&dataset_mon, &mon_run_vec[kr]);
        std::cout << "OMDS record for run " << irun << " is made of " << dataset_mon.size() << std::endl;
        typedef std::map<EcalLogicID, MonPedestalsDat>::const_iterator CImon;
        EcalLogicID ecid_xt;
        MonPedestalsDat rd_ped;

        //int iEta=0;
        //int iPhi=0;
        int ix = 0;
        int iy = 0;

        for (CImon p = dataset_mon.begin(); p != dataset_mon.end(); p++) {
          ecid_xt = p->first;
          rd_ped = p->second;
          //int sm_num=ecid_xt.getID1();
          int xt_num = ecid_xt.getID2();  // careful here !!! we number the channels from 1 to 1700

          //iEta=(xt_num/20)+1;
          //iPhi=20-(xt_num-(iEta-1)*20);

          ix = 95 - (xt_num - 1) / 20;
          iy = 46 + (xt_num - 1) % 20;

          EcalPedestals::Item item;
          item.mean_x1 = rd_ped.getPedMeanG1();
          item.rms_x1 = rd_ped.getPedRMSG1();
          item.mean_x6 = rd_ped.getPedMeanG6();
          item.rms_x6 = rd_ped.getPedRMSG6();
          item.mean_x12 = rd_ped.getPedMeanG12();
          item.rms_x12 = rd_ped.getPedRMSG12();

          EEDetId eedetidpos(ix, iy, 1);
          // EBDetId ebdetid(iEta,iPhi);

          // here we change in the peds object only the values that are available in the online DB
          // otherwise we keep the old value

          peds->insert(std::make_pair(eedetidpos.rawId(), item));
          if (ix == ixmin && iy == iymin)
            std::cout << "ped12 " << item.mean_x12 << std::endl;
        }

        edm::LogInfo("Generating popcon record for run ") << irun << "..." << std::flush;

        // now I copy peds in pedtemp and I ship pedtemp to popcon
        // if I use always the same peds I always overwrite
        // so I really have to create new objects for each new run
        // popcon deletes everything for me

        EcalPedestals* pedtemp = new EcalPedestals();

        for (int iX = ixmin; iX <= ixmax; ++iX) {
          for (int iY = iymin; iY <= iymax; ++iY) {
            if (EEDetId::validDetId(iX, iY, 1)) {
              EEDetId eedetidpos(iX, iY, 1);
              unsigned int hiee = eedetidpos.hashedIndex();
              EcalPedestals::Item aped = peds->endcap(hiee);

              EcalPedestals::Item item;
              item.mean_x1 = aped.mean_x1;
              item.rms_x1 = aped.rms_x1;
              item.mean_x6 = aped.mean_x6;
              item.rms_x6 = aped.rms_x6;
              item.mean_x12 = aped.mean_x12;
              item.rms_x12 = aped.rms_x12;
              // here I copy the last valid value in the pedtemp object
              pedtemp->insert(std::make_pair(eedetidpos.rawId(), item));
              if (iX == ixmin && iY == iymin)
                std::cout << "ped12 " << item.mean_x12 << std::endl;
            }
          }
        }

        Time_t snc = (Time_t)irun;

        m_to_transfer.push_back(std::make_pair((EcalPedestals*)pedtemp, snc));

        edm::LogInfo("Ecal - > end of getNewObjectsH2 -----------\n");
      }
    }
  }
  delete econn;
  delete peds;  // this is the only one that popcon does not delete
}
//////////////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::readPedestalFile() {
  edm::LogInfo(" reading the input file ") << m_filename;
  std::ifstream fInput;
  fInput.open(m_filename);
  if (!fInput.is_open()) {
    edm::LogInfo("ERROR : cannot open file ") << m_filename;
    exit(1);
  }
  //  string pos, dummyLine;
  int hashedId;
  float EBmean12[kEBChannels], EBrms12[kEBChannels], EBmean6[kEBChannels], EBrms6[kEBChannels], EBmean1[kEBChannels],
      EBrms1[kEBChannels];
  //*****************  barrel
  //  getline(fInput, dummyLine);   // skip first line
  for (int iChannel = 0; iChannel < kEBChannels; iChannel++) {
    fInput >> hashedId >> EBmean12[iChannel] >> EBrms12[iChannel] >> EBmean6[iChannel] >> EBrms6[iChannel] >>
        EBmean1[iChannel] >> EBrms1[iChannel];
    if (hashedId != iChannel + 1) {
      edm::LogInfo("File") << m_filename << " strange hash " << hashedId << " while iChannel " << iChannel;
      exit(-1);
    }
  }

  // ***************** now EE *****************
  float EEmean12[kEEChannels], EErms12[kEEChannels], EEmean6[kEEChannels], EErms6[kEEChannels], EEmean1[kEEChannels],
      EErms1[kEEChannels];
  for (int iChannel = 0; iChannel < kEEChannels; iChannel++) {
    fInput >> hashedId >> EEmean12[iChannel] >> EErms12[iChannel] >> EEmean6[iChannel] >> EErms6[iChannel] >>
        EEmean1[iChannel] >> EErms1[iChannel];
    if (hashedId != iChannel + kEBChannels + 1) {
      edm::LogInfo("File") << m_filename << " strange hash " << hashedId << " while iChannel " << iChannel;
      exit(-1);
    }
  }
  fInput.close();

  EcalPedestals* ped = new EcalPedestals();
  // barrel
  for (int iEta = -EBDetId::MAX_IETA; iEta <= EBDetId::MAX_IETA; ++iEta) {
    if (iEta == 0)
      continue;
    for (int iPhi = EBDetId::MIN_IPHI; iPhi <= EBDetId::MAX_IPHI; ++iPhi) {
      if (EBDetId::validDetId(iEta, iPhi)) {
        EBDetId ebdetid(iEta, iPhi);
        unsigned int hieb = ebdetid.hashedIndex();
        EcalPedestals::Item item;
        item.mean_x1 = EBmean1[hieb];
        item.rms_x1 = EBrms1[hieb];
        item.mean_x6 = EBmean6[hieb];
        item.rms_x6 = EBrms6[hieb];
        item.mean_x12 = EBmean12[hieb];
        item.rms_x12 = EBrms12[hieb];
        ped->insert(std::make_pair(ebdetid.rawId(), item));
      }  // valid EBId
    }    //  loop over phi
  }      //   loop over eta
  // endcaps
  //  std::ofstream fout;
  //  fout.open("Pedestal.check");
  for (int iz = -1; iz < 2; iz = iz + 2) {  // z : -1 and +1
    for (int iX = EEDetId::IX_MIN; iX <= EEDetId::IX_MAX; ++iX) {
      for (int iY = EEDetId::IY_MIN; iY <= EEDetId::IY_MAX; ++iY) {
        if (EEDetId::validDetId(iX, iY, iz)) {
          EEDetId eedetid(iX, iY, iz);
          unsigned int hiee = eedetid.hashedIndex();
          //	  fout << hiee << " mean 12 " << EEmean12[hiee] << std::endl;
          EcalPedestals::Item item;
          item.mean_x1 = EEmean1[hiee];
          item.rms_x1 = EErms1[hiee];
          item.mean_x6 = EEmean6[hiee];
          item.rms_x6 = EErms6[hiee];
          item.mean_x12 = EEmean12[hiee];
          item.rms_x12 = EErms12[hiee];
          ped->insert(std::make_pair(eedetid.rawId(), item));
        }  // val EEId
      }    //  loop over y
    }      //   loop over x
  }        //   loop over z
  //  fout.close();

  unsigned int irun = m_firstRun;
  Time_t snc = (Time_t)irun;
  m_to_transfer.push_back(std::make_pair((EcalPedestals*)ped, snc));

  edm::LogInfo("Ecal - > end of readPedestalFile -----------\n");
}
//////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::readPedestalMC() {
  edm::LogInfo(" reading the input file ") << m_filename;
  std::ifstream fxml;
  fxml.open(m_filename);
  if (!fxml.is_open()) {
    edm::LogInfo("ERROR : cannot open file ") << m_filename;
    exit(1);
  }
  std::ofstream fout;
  fout.open("Pedestal.check");
  //  int hashedId;
  float EBmean12[kEBChannels], EBrms12[kEBChannels], EBmean6[kEBChannels], EBrms6[kEBChannels], EBmean1[kEBChannels],
      EBrms1[kEBChannels];
  //  int ringEB[kEBChannels], ringEE[kEEChannels];
  double RingMean[28][2][3], RingRMS[28][2][3];
  int NbVal[28][2][3];
  for (int ring = 0; ring < 28; ring++) {
    for (int side = 0; side < 2; side++) {
      for (int igain = 0; igain < kGains; igain++) {
        RingMean[ring][side][igain] = 0.;
        RingRMS[ring][side][igain] = 0.;
        NbVal[ring][side][igain] = 0;
      }
    }
  }
  std::string dummyLine, mean12, rms12, bid;
  for (int i = 0; i < 9; i++)
    std::getline(fxml, dummyLine);  // skip first lines
  // Barrel
  for (int iEBChannel = 0; iEBChannel < kEBChannels; iEBChannel++) {
    EBDetId ebdetid = EBDetId::unhashIndex(iEBChannel);
    int ieta = ebdetid.ieta();
    int ring = (abs(ieta) - 1) / 5;
    if (ring < 0 || ring > 16)
      edm::LogInfo("EB channel ") << iEBChannel << " ring " << ring;
    int izz = 0;
    if (ieta > 0)
      izz = 1;
    fxml >> bid;
    std::string stt = bid.substr(10, 15);
    std::istringstream m12(stt);
    m12 >> EBmean12[iEBChannel];
    fxml >> bid;
    stt = bid.substr(9, 15);
    std::istringstream r12(stt);
    r12 >> EBrms12[iEBChannel];
    if (EBrms12[iEBChannel] != 0. && EBrms12[iEBChannel] < 5.) {
      RingMean[ring][izz][0] += EBrms12[iEBChannel];
      RingRMS[ring][izz][0] += EBrms12[iEBChannel] * EBrms12[iEBChannel];
      NbVal[ring][izz][0]++;
    }
    fxml >> bid;
    stt = bid.substr(9, 15);
    std::istringstream m6(stt);
    m6 >> EBmean6[iEBChannel];
    fxml >> bid;
    stt = bid.substr(8, 15);
    std::istringstream r6(stt);
    r6 >> EBrms6[iEBChannel];
    if (EBrms6[iEBChannel] != 0. && EBrms6[iEBChannel] < 5.) {
      RingMean[ring][izz][1] += EBrms6[iEBChannel];
      RingRMS[ring][izz][1] += EBrms6[iEBChannel] * EBrms6[iEBChannel];
      NbVal[ring][izz][1]++;
    }
    fxml >> bid;
    stt = bid.substr(9, 15);
    std::istringstream m1(stt);
    m1 >> EBmean1[iEBChannel];
    fxml >> bid;
    stt = bid.substr(8, 15);
    std::istringstream r1(stt);
    r1 >> EBrms1[iEBChannel];
    if (EBrms1[iEBChannel] != 0. && EBrms1[iEBChannel] < 5.) {
      RingMean[ring][izz][2] += EBrms1[iEBChannel];
      RingRMS[ring][izz][2] += EBrms1[iEBChannel] * EBrms1[iEBChannel];
      NbVal[ring][izz][2]++;
    }
    if (iEBChannel % 10000 == 0)
      fout << " EB channel " << iEBChannel << " " << EBmean12[iEBChannel] << " " << EBrms12[iEBChannel] << " "
           << EBmean6[iEBChannel] << " " << EBrms6[iEBChannel] << " " << EBmean1[iEBChannel] << " "
           << EBrms1[iEBChannel] << std::endl;
    for (int i = 0; i < 3; i++)
      std::getline(fxml, dummyLine);  // skip lines
  }

  // ***************** now EE *****************
  std::ifstream fCrystal;
  fCrystal.open("Crystal");
  if (!fCrystal.is_open()) {
    edm::LogInfo("ERROR : cannot open file Crystal");
    exit(1);
  }
  int ringEE[kEEChannels];
  for (int iChannel = 0; iChannel < kEEChannels; iChannel++) {
    fCrystal >> ringEE[iChannel];
    int ring = abs(ringEE[iChannel]) - 1;
    if (ring < 17 || ring > 27) {
      edm::LogInfo(" EE channel ") << iChannel << " ring " << ringEE[iChannel];
      exit(-1);
    }
  }
  fCrystal.close();

  float EEmean12[kEEChannels], EErms12[kEEChannels], EEmean6[kEEChannels], EErms6[kEEChannels], EEmean1[kEEChannels],
      EErms1[kEEChannels];
  for (int i = 0; i < 6; i++)
    std::getline(fxml, dummyLine);  // skip lines
  for (int iEEChannel = 0; iEEChannel < kEEChannels; iEEChannel++) {
    //    int ich = iEEChannel + kEBChannels;
    fxml >> bid;
    std::string stt = bid.substr(10, 15);
    std::istringstream m12(stt);
    m12 >> EEmean12[iEEChannel];
    int ring = abs(ringEE[iEEChannel]) - 1;
    if (ring < 17 || ring > 27)
      edm::LogInfo("EE channel ") << iEEChannel << " ring " << ring;
    int izz = 1;
    if (iEEChannel < 7324)
      izz = 0;
    fxml >> bid;
    stt = bid.substr(9, 15);
    std::istringstream r12(stt);
    r12 >> EErms12[iEEChannel];
    if (EErms12[iEEChannel] != 0. && EErms12[iEEChannel] < 5.) {
      RingMean[ring][izz][0] += EErms12[iEEChannel];
      RingRMS[ring][izz][0] += EErms12[iEEChannel] * EErms12[iEEChannel];
      NbVal[ring][izz][0]++;
    }
    fxml >> bid;
    stt = bid.substr(9, 15);
    std::istringstream m6(stt);
    m6 >> EEmean6[iEEChannel];
    fxml >> bid;
    stt = bid.substr(8, 15);
    std::istringstream r6(stt);
    r6 >> EErms6[iEEChannel];
    if (EErms6[iEEChannel] != 0. && EErms6[iEEChannel] < 5.) {
      RingMean[ring][izz][1] += EErms6[iEEChannel];
      RingRMS[ring][izz][1] += EErms6[iEEChannel] * EErms6[iEEChannel];
      NbVal[ring][izz][1]++;
    }
    fxml >> bid;
    stt = bid.substr(9, 15);
    std::istringstream m1(stt);
    m1 >> EEmean1[iEEChannel];
    fxml >> bid;
    stt = bid.substr(8, 15);
    std::istringstream r1(stt);
    r1 >> EErms1[iEEChannel];
    if (EErms1[iEEChannel] != 0. && EErms1[iEEChannel] < 5.) {
      RingMean[ring][izz][2] += EErms1[iEEChannel];
      RingRMS[ring][izz][2] += EErms1[iEEChannel] * EErms1[iEEChannel];
      NbVal[ring][izz][2]++;
    }
    if (iEEChannel % 1000 == 0)
      fout << " EE channel " << iEEChannel << " " << EEmean12[iEEChannel] << " " << EErms12[iEEChannel] << " "
           << EEmean6[iEEChannel] << " " << EErms6[iEEChannel] << " " << EEmean1[iEEChannel] << " "
           << EErms1[iEEChannel] << std::endl;
    for (int i = 0; i < 3; i++)
      std::getline(fxml, dummyLine);  // skip lines
  }

  fxml.close();

  for (int gain = 0; gain < kGains; gain++) {
    fout << "\n"
         << "**** Gain ****  " << gainValues[gain] << "\n";
    for (int ring = 0; ring < 28; ring++) {
      for (int side = 0; side < 2; side++) {
        if (NbVal[ring][side][gain] <= 0) {
          edm::LogInfo(" No entry for ring ") << ring;
          exit(-1);
        }
        RingMean[ring][side][gain] /= (double)NbVal[ring][side][gain];
        double x = RingMean[ring][side][gain];
        RingRMS[ring][side][gain] /= (double)NbVal[ring][side][gain];
        double rms = sqrt(RingRMS[ring][side][gain] - x * x);
        RingRMS[ring][side][gain] = rms;
        fout << " ring " << ring + 1 << " mean " << x << " rms " << rms << "    ";
      }  //  loop over sides
      fout << std::endl;
      if (ring == 16)
        fout << "*****  End caps *****     EE-                              EE+" << std::endl;
    }  //  loop over rings
  }    //  loop over gains

  // read also the ring value from Crystal file

  EcalPedestals* ped = new EcalPedestals();
  // barrel
  for (int iEta = -EBDetId::MAX_IETA; iEta <= EBDetId::MAX_IETA; ++iEta) {
    if (iEta == 0)
      continue;
    for (int iPhi = EBDetId::MIN_IPHI; iPhi <= EBDetId::MAX_IPHI; ++iPhi) {
      if (EBDetId::validDetId(iEta, iPhi)) {
        EBDetId ebdetid(iEta, iPhi);
        unsigned int hieb = ebdetid.hashedIndex();
        EcalPedestals::Item item;
        item.mean_x1 = 200.;
        item.mean_x6 = 200.;
        item.mean_x12 = 200.;
        if (m_corrected) {
          int ring = (abs(iEta) - 1) / 5;
          if (ring < 0 || ring > 16)
            edm::LogInfo("EB channel ") << hieb << " ring " << ring;
          int side = 0;
          if (iEta > 0)
            side = 1;
          if (EBrms1[hieb] == 0 || EBrms1[hieb] > RingMean[ring][side][2] + 3 * RingRMS[ring][side][2]) {
            fout << " EB channel " << hieb << " eta " << iEta << " phi " << iPhi << " ring " << ring + 1
                 << " gain 1 rms " << EBrms1[hieb] << " replaced by " << RingMean[ring][side][2] << std::endl;
            item.rms_x1 = RingMean[ring][side][2];
          } else
            item.rms_x1 = EBrms1[hieb];
          if (EBrms6[hieb] == 0 || EBrms6[hieb] > RingMean[ring][side][1] + 3 * RingRMS[ring][side][1]) {
            fout << " EB channel " << hieb << " eta " << iEta << " phi " << iPhi << " ring " << ring + 1
                 << " gain 6 rms " << EBrms6[hieb] << " replaced by " << RingMean[ring][side][1] << std::endl;
            item.rms_x6 = RingMean[ring][side][1];
          } else
            item.rms_x6 = EBrms6[hieb];
          if (EBrms12[hieb] == 0 || EBrms12[hieb] > RingMean[ring][side][0] + 3 * RingRMS[ring][side][0]) {
            fout << " EB channel " << hieb << " eta " << iEta << " phi " << iPhi << " ring " << ring + 1
                 << " gain 12 rms " << EBrms12[hieb] << " replaced by " << RingMean[ring][side][0] << std::endl;
            item.rms_x12 = RingMean[ring][side][0];
          } else
            item.rms_x12 = EBrms12[hieb];
          if (hieb > 4534 && hieb < 4540)
            edm::LogInfo(" Channel ") << hieb << " ring " << ring << " 12 " << EBrms12[hieb] << " mean "
                                      << RingMean[ring][side][0] << " rms " << RingRMS[ring][side][0] << "  6 "
                                      << EBrms6[hieb] << " mean " << RingMean[ring][side][1] << " rms "
                                      << RingRMS[ring][side][1] << "  1 " << EBrms1[hieb] << " mean "
                                      << RingMean[ring][side][2] << " rms " << RingRMS[ring][side][2];
        }  // if corrected
        else {
          item.rms_x1 = EBrms1[hieb];
          item.rms_x6 = EBrms6[hieb];
          item.rms_x12 = EBrms12[hieb];
        }
        if (item.rms_x1 > 4. || item.rms_x6 > 4. || item.rms_x12 > 4.)
          edm::LogInfo(" Channel ") << hieb << " 12 " << item.rms_x12 << " 6 " << item.rms_x6 << " 1 " << item.rms_x1;
        ped->insert(std::make_pair(ebdetid.rawId(), item));
      }  // valid EBId
    }    //  loop over phi
  }      //   loop over eta

  // endcaps
  for (int iz = -1; iz < 2; iz = iz + 2) {  // z : -1 and +1
    for (int iX = EEDetId::IX_MIN; iX <= EEDetId::IX_MAX; ++iX) {
      for (int iY = EEDetId::IY_MIN; iY <= EEDetId::IY_MAX; ++iY) {
        if (EEDetId::validDetId(iX, iY, iz)) {
          EEDetId eedetid(iX, iY, iz);
          unsigned int hiee = eedetid.hashedIndex();
          //	  fout << hiee << " mean 12 " << EEmean12[hiee] << std::endl;
          EcalPedestals::Item item;
          item.mean_x1 = 200.;
          item.mean_x6 = 200.;
          item.mean_x12 = 200.;
          if (m_corrected) {
            int ring = abs(ringEE[hiee]) - 1;
            if (ring < 17 || ring > 27)
              edm::LogInfo("EE channel ") << hiee << " ring " << ring;
            if (EErms1[hiee] == 0 || EErms1[hiee] > RingMean[ring][iz][2] + 3 * RingRMS[ring][iz][2]) {
              fout << " EE channel " << hiee << " x " << iX << " y " << iY << " z " << iz << " ring " << ring + 1
                   << " gain 1 rms " << EErms1[hiee] << " replaced by " << RingMean[ring][iz][2] << std::endl;
              item.rms_x1 = RingMean[ring][iz][2];
            } else
              item.rms_x1 = EErms1[hiee];
            if (EErms6[hiee] == 0 || EErms6[hiee] > RingMean[ring][iz][1] + 3 * RingRMS[ring][iz][1]) {
              fout << " EE channel " << hiee << " x " << iX << " y " << iY << " z " << iz << " ring " << ring + 1
                   << " gain 6 rms " << EErms6[hiee] << " replaced by " << RingMean[ring][iz][1] << std::endl;
              item.rms_x6 = RingMean[ring][iz][1];
            } else
              item.rms_x6 = EErms6[hiee];
            if (EErms12[hiee] == 0 || EErms12[hiee] > RingMean[ring][iz][0] + 3 * RingRMS[ring][iz][0]) {
              fout << " EE channel " << hiee << " x " << iX << " y " << iY << " z " << iz << " ring " << ring + 1
                   << " gain 12 rms " << EErms12[hiee] << " replaced by " << RingMean[ring][iz][0] << std::endl;
              item.rms_x12 = RingMean[ring][iz][0];
            } else
              item.rms_x12 = EErms12[hiee];
          }  // if corrected
          else {
            item.rms_x1 = EErms1[hiee];
            item.rms_x6 = EErms6[hiee];
            item.rms_x12 = EErms12[hiee];
          }
          ped->insert(std::make_pair(eedetid.rawId(), item));
        }  // val EEId
      }    //  loop over y
    }      //   loop over x
  }        //   loop over z
  fout.close();

  unsigned int irun = m_firstRun;
  Time_t snc = (Time_t)irun;
  m_to_transfer.push_back(std::make_pair((EcalPedestals*)ped, snc));

  edm::LogInfo("Ecal - > end of readPedestalMC -----------\n");
}

///////////////////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::readPedestal2017() {
  bool debug = false;
  edm::LogInfo(" reading local Pedestal run (2017 way)! ") << m_filename;

  // First we copy the last valid record to a temporary object peds
  Ref ped_db = lastPayload();
  EcalPedestals* peds = new EcalPedestals();
  edm::LogInfo("retrieved last payload ");

  for (int iEta = -EBDetId::MAX_IETA; iEta <= EBDetId::MAX_IETA; ++iEta) {
    if (iEta == 0)
      continue;
    for (int iPhi = EBDetId::MIN_IPHI; iPhi <= EBDetId::MAX_IPHI; ++iPhi) {
      // make an EBDetId since we need EBDetId::rawId() to be used as the key for the pedestals
      if (EBDetId::validDetId(iEta, iPhi)) {
        EBDetId ebdetid(iEta, iPhi, EBDetId::ETAPHIMODE);
        EcalPedestals::const_iterator it = ped_db->find(ebdetid.rawId());
        EcalPedestals::Item aped = (*it);
        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;
        peds->insert(std::make_pair(ebdetid.rawId(), item));
      }
    }
  }
  for (int iX = EEDetId::IX_MIN; iX <= EEDetId::IX_MAX; ++iX) {
    for (int iY = EEDetId::IY_MIN; iY <= EEDetId::IY_MAX; ++iY) {
      // make an EEDetId since we need EEDetId::rawId() to be used as the key for the pedestals
      if (EEDetId::validDetId(iX, iY, 1)) {
        EEDetId eedetidpos(iX, iY, 1);
        EcalPedestals::const_iterator it = ped_db->find(eedetidpos.rawId());
        EcalPedestals::Item aped = (*it);
        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;
        peds->insert(std::make_pair(eedetidpos.rawId(), item));
      }
      if (EEDetId::validDetId(iX, iY, -1)) {
        EEDetId eedetidneg(iX, iY, -1);
        EcalPedestals::const_iterator it = ped_db->find(eedetidneg.rawId());
        EcalPedestals::Item aped = (*it);
        // here I copy the last valid value in the peds object
        EcalPedestals::Item item;
        item.mean_x1 = aped.mean_x1;
        item.rms_x1 = aped.rms_x1;
        item.mean_x6 = aped.mean_x6;
        item.rms_x6 = aped.rms_x6;
        item.mean_x12 = aped.mean_x12;
        item.rms_x12 = aped.rms_x12;
        peds->insert(std::make_pair(eedetidneg.rawId(), item));
      }
    }
  }

  edm::LogInfo(" reading the input file ") << m_filename;
  std::ifstream fInput;
  fInput.open(m_filename);
  if (!fInput.is_open()) {
    edm::LogInfo("ERROR : cannot open file ") << m_filename;
    exit(1);
  }
  //  string pos, dummyLine;
  int hashedId;
  float EBmean12[kEBChannels], EBrms12[kEBChannels], EBmean6[kEBChannels], EBrms6[kEBChannels], EBmean1[kEBChannels],
      EBrms1[kEBChannels];
  //*****************  barrel
  //  getline(fInput, dummyLine);   // skip first line
  for (int iChannel = 0; iChannel < kEBChannels; iChannel++) {
    fInput >> hashedId >> EBmean12[iChannel] >> EBrms12[iChannel] >> EBmean6[iChannel] >> EBrms6[iChannel] >>
        EBmean1[iChannel] >> EBrms1[iChannel];
    if (hashedId != iChannel + 1) {
      edm::LogInfo("File ") << m_filename << " strange hash " << hashedId << " while iChannel " << iChannel;
      exit(-1);
    }
  }

  // ***************** now EE *****************
  float EEmean12[kEEChannels], EErms12[kEEChannels], EEmean6[kEEChannels], EErms6[kEEChannels], EEmean1[kEEChannels],
      EErms1[kEEChannels];
  for (int iChannel = 0; iChannel < kEEChannels; iChannel++) {
    fInput >> hashedId >> EEmean12[iChannel] >> EErms12[iChannel] >> EEmean6[iChannel] >> EErms6[iChannel] >>
        EEmean1[iChannel] >> EErms1[iChannel];
    if (hashedId != iChannel + kEBChannels + 1) {
      edm::LogInfo("File ") << m_filename << " strange hash " << hashedId << " while iChannel " << iChannel;
      exit(-1);
    }
  }
  fInput.close();

  EcalPedestals* ped = new EcalPedestals();
  // barrel
  for (int iEta = -EBDetId::MAX_IETA; iEta <= EBDetId::MAX_IETA; ++iEta) {
    if (iEta == 0)
      continue;
    for (int iPhi = EBDetId::MIN_IPHI; iPhi <= EBDetId::MAX_IPHI; ++iPhi) {
      if (EBDetId::validDetId(iEta, iPhi)) {
        EBDetId ebdetid(iEta, iPhi);
        unsigned int hieb = ebdetid.hashedIndex();
        EcalPedestals::Item item;
        EcalPedestals::Item previous_ped = peds->barrel(hieb);
        if (debug & (EBmean12[hieb] == -999. || EBrms12[hieb] == -999. || EBmean6[hieb] == -999. ||
                     EBrms6[hieb] == -999. || EBmean1[hieb] == -999. || EBrms1[hieb] == -999.))
          edm::LogInfo(" bad EB channel eta ")
              << iEta << " phi " << iPhi << " " << EBmean12[hieb] << " " << EBrms12[hieb] << " " << EBmean6[hieb] << " "
              << EBrms6[hieb] << " " << EBmean1[hieb] << " " << EBrms1[hieb];
        if (EBmean1[hieb] != -999.)
          item.mean_x1 = EBmean1[hieb];
        else
          item.mean_x1 = previous_ped.mean_x1;
        if (EBrms1[hieb] != -999.)
          item.rms_x1 = EBrms1[hieb];
        else
          item.rms_x1 = previous_ped.rms_x1;
        if (EBmean6[hieb] != -999.)
          item.mean_x6 = EBmean6[hieb];
        else
          item.mean_x6 = previous_ped.mean_x6;
        if (EBrms6[hieb] != -999.)
          item.rms_x6 = EBrms6[hieb];
        else
          item.rms_x6 = previous_ped.rms_x6;
        if (EBmean12[hieb] != -999.)
          item.mean_x12 = EBmean12[hieb];
        else
          item.mean_x12 = previous_ped.mean_x12;
        if (EBrms12[hieb] != -999.)
          item.rms_x12 = EBrms12[hieb];
        else
          item.rms_x12 = previous_ped.rms_x12;
        ped->insert(std::make_pair(ebdetid.rawId(), item));
      }  // valid EBId
    }    //  loop over phi
  }      //   loop over eta
  // endcaps
  //  std::ofstream fout;
  //  fout.open("Pedestal.check");
  for (int iz = -1; iz < 2; iz = iz + 2) {  // z : -1 and +1
    for (int iX = EEDetId::IX_MIN; iX <= EEDetId::IX_MAX; ++iX) {
      for (int iY = EEDetId::IY_MIN; iY <= EEDetId::IY_MAX; ++iY) {
        if (EEDetId::validDetId(iX, iY, iz)) {
          EEDetId eedetid(iX, iY, iz);
          unsigned int hiee = eedetid.hashedIndex();
          //	  fout << hiee << " mean 12 " << EEmean12[hiee] << std::endl;
          EcalPedestals::Item item;
          EcalPedestals::Item previous_ped = peds->endcap(hiee);
          if (debug & (EEmean12[hiee] == -999. || EErms12[hiee] == -999. || EEmean6[hiee] == -999. ||
                       EErms6[hiee] == -999. || EEmean1[hiee] == -999. || EErms1[hiee] == -999.))
            edm::LogInfo(" bad EE channel x ")
                << iX << " y " << iY << " z" << iz << " " << EEmean12[hiee] << " " << EErms12[hiee] << " "
                << EEmean6[hiee] << " " << EErms6[hiee] << " " << EEmean1[hiee] << " " << EErms1[hiee];
          if (EEmean1[hiee] != -999.)
            item.mean_x1 = EEmean1[hiee];
          else
            item.mean_x1 = previous_ped.mean_x1;
          if (EErms1[hiee] != -999.)
            item.rms_x1 = EErms1[hiee];
          else
            item.rms_x1 = previous_ped.rms_x1;
          if (EEmean6[hiee] != -999.)
            item.mean_x6 = EEmean6[hiee];
          else
            item.mean_x6 = previous_ped.mean_x6;
          if (EErms6[hiee] != -999.)
            item.rms_x6 = EErms6[hiee];
          else
            item.rms_x6 = previous_ped.rms_x6;
          if (EEmean12[hiee] != -999.)
            item.mean_x12 = EEmean12[hiee];
          else
            item.mean_x12 = previous_ped.mean_x12;
          if (EErms12[hiee] != -999.)
            item.rms_x12 = EErms12[hiee];
          else
            item.rms_x12 = previous_ped.rms_x12;
          ped->insert(std::make_pair(eedetid.rawId(), item));
        }  // val EEId
      }    //  loop over y
    }      //   loop over x
  }        //   loop over z
  //  fout.close();

  unsigned int irun = m_firstRun;
  Time_t snc = (Time_t)irun;
  m_to_transfer.push_back(std::make_pair((EcalPedestals*)ped, snc));

  edm::LogInfo("Ecal - > end of readPedestal2017 -----------\n");
}
/////////////////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::readPedestalTree() {
  edm::LogInfo(" reading the root file ") << m_filename;
  TFile* hfile = new TFile(m_filename.c_str());

  TTree* treeChan = (TTree*)hfile->Get("PedChan");
  int iChannel = 0, ix = 0, iy = 0, iz = 0;
  treeChan->SetBranchAddress("Channels", &iChannel);
  treeChan->SetBranchAddress("x", &ix);
  treeChan->SetBranchAddress("y", &iy);
  treeChan->SetBranchAddress("z", &iz);
  int neventsChan = (int)treeChan->GetEntries();
  edm::LogInfo("PedChan nb entries ") << neventsChan;
  int ringEB[kEBChannels], sideEB[kEBChannels], ixEE[kEEChannels], iyEE[kEEChannels], izEE[kEEChannels];
  for (int entry = 0; entry < neventsChan; entry++) {
    treeChan->GetEntry(entry);
    if (entry < kEBChannels) {
      ringEB[iChannel] = (abs(ix) - 1) / 5;  // -85...-1, 1...85 give 0...16
      sideEB[iChannel] = 1;
      if (ix < 0)
        sideEB[iChannel] = 0;
      if (entry % 10000 == 0)
        edm::LogInfo(" EB channel ") << iChannel << " eta " << ix << " phi " << iy << " side " << sideEB[iChannel]
                                     << " ring " << ringEB[iChannel];
    } else {
      ixEE[iChannel] = ix;
      iyEE[iChannel] = iy;
      izEE[iChannel] = iz;
      if (entry % 1000 == 0)
        edm::LogInfo(" EE channel ") << iChannel << " x " << ixEE[iChannel] << " y " << iyEE[iChannel] << " z "
                                     << izEE[iChannel];
    }
  }
  //    2016 : 26
  Int_t pedxml[Nbpedxml] = {271948,
                            273634,
                            273931,
                            274705,
                            275403,
                            276108,
                            276510,
                            277169,
                            278123,
                            278183,
                            278246,
                            278389,
                            278499,
                            278693,
                            278858,
                            278888,
                            278931,
                            279728,
                            280129,
                            280263,
                            280941,
                            281753,
                            282631,
                            282833,
                            283199,
                            283766,
                            //    2017 : 25
                            286535,
                            293513,
                            293632,
                            293732,
                            295507,
                            295672,
                            296391,
                            296917,
                            297388,
                            298481,
                            299279,
                            299710,
                            300186,
                            300581,
                            301191,
                            302006,
                            302293,
                            302605,
                            303436,
                            303848,
                            304211,
                            304680,
                            305117,
                            305848,
                            306176,
                            //    2018 : 30
                            313760,
                            315434,
                            315831,
                            316299,
                            316694,
                            316963,
                            317399,
                            317669,
                            318249,
                            318747,
                            319111,
                            319365,
                            319700,
                            320098,
                            320515,
                            320905,
                            321184,
                            321480,
                            321855,
                            322151,
                            322653,
                            323261,
                            323802,
                            324250,
                            324632,
                            325909,
                            326038,
                            326652,
                            326979,
                            327271};

  Int_t run16Index = 0;

  Int_t fed[kChannels], chan[kChannels], id, run, run_type, seq_id, las_id, fill_num, run_num_infill, run_time,
      run_time_stablebeam, nxt, time[54];
  Float_t ped[kChannels], pedrms[kChannels], lumi, bfield;
  TTree* tree = (TTree*)hfile->Get("T");
  tree->Print();
  tree->SetBranchAddress("id", &id);
  tree->SetBranchAddress("run", &run);
  tree->SetBranchAddress("run_type", &run_type);
  tree->SetBranchAddress("seq_id", &seq_id);
  tree->SetBranchAddress("las_id", &las_id);
  tree->SetBranchAddress("fill_num", &fill_num);
  tree->SetBranchAddress("run_num_infill", &run_num_infill);
  tree->SetBranchAddress("run_time", &run_time);
  tree->SetBranchAddress("run_time_stablebeam", &run_time_stablebeam);
  tree->SetBranchAddress("lumi", &lumi);
  tree->SetBranchAddress("bfield", &bfield);
  tree->SetBranchAddress("nxt", &nxt);  // nb of filled Crystals
  tree->SetBranchAddress("time", time);
  tree->SetBranchAddress("fed", fed);
  tree->SetBranchAddress("chan", chan);
  tree->SetBranchAddress("ped", ped);
  tree->SetBranchAddress("pedrms", pedrms);
  int nevents = (int)tree->GetEntries();
  edm::LogInfo(" nb entries ") << nevents;
  std::ofstream fout;
  fout.open("copyTreePedestals.txt");
  if (!fout.is_open()) {
    edm::LogInfo("ERROR : cannot open file copyTreePedestals.txt");
    exit(1);
  }
  Double_t EAmean1[kChannels], EArms1[kChannels], EAmean6[kChannels], EArms6[kChannels], EAmean12[kChannels],
      EArms12[kChannels];
  Int_t RunEntry = 0, EAentry[kChannels];
  for (int ich = 0; ich < kChannels; ich++) {
    EAmean12[ich] = 0;
    EArms12[ich] = 0;
    EAentry[ich] = 0;
  }
  tree->GetEntry(0);
  fout << " first run " << run << " fill " << fill_num << " B field " << bfield << " run type " << run_type
       << " seq_id " << seq_id << " las_id " << las_id << " run_num_infill " << run_num_infill << " lumi " << lumi
       << " nb of Crystals " << nxt << std::endl;
  for (int ich = 0; ich < kChannels; ich++) {
    if (ped[ich] != 0.) {
      if (ich < kEBChannels)
        fout << " channel " << ich << " FED " << fed[ich] << " chan " << chan[ich] << " pedestal " << ped[ich]
             << " RMS " << pedrms[ich] << std::endl;
      else  //   EE
        fout << " channel " << ich << " EE channel " << ich - kEBChannels << " FED " << fed[ich] << " chan "
             << chan[ich] << " pedestal " << ped[ich] << " RMS " << pedrms[ich] << std::endl;
    }
  }

  int run_type_kept = m_runtype;         // 1 collision 2 cosmics 3 circulating 4 test
  int first_run_kept = (int)m_firstRun;  //  m_firstRun is unsigned!
  int last_run_kept = (int)m_lastRun;    //  m_lastRun is unsigned!
  int runold = run;
  int firsttimeFED = -1;
  //  int timeold = -1;
  for (int entry = 0; entry < nevents; entry++) {
    tree->GetEntry(entry);
    if (run < first_run_kept) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time
           << " before first wanted " << m_firstRun << std::endl;
      runold = run;
      continue;
    }
    if (run > last_run_kept) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time
           << " after last wanted " << m_lastRun << std::endl;
      runold = run;
      break;
    }
    if (run_type != run_type_kept) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time << " run type "
           << run_type << std::endl;
      continue;  // use only wanted type runs
    }
    if (nxt != kChannels) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time
           << " ***********  Number of channels " << nxt << std::endl;
      continue;
    }
    if (bfield < 3.79) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time
           << " ***********  bfield = " << bfield << std::endl;
      //      continue;  keep these runs
    }
    if (run_type_kept == 1) {  // for collision runs, keep only sequences after stable beam
      int time_seq = 0;
      for (int ifed = 0; ifed < 54; ifed++) {
        if (time[ifed] < run_time_stablebeam) {
          if (time_seq == 0)
            fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time
                 << "  ***********  sequence before stable beam at " << run_time_stablebeam << " FED " << ifed << " : "
                 << time[ifed];
          else
            fout << " FED " << ifed << " : " << time[ifed];
          time_seq++;
        }
      }
      if (time_seq != 0) {
        fout << " total nb " << time_seq << std::endl;
        continue;
      }
    }  // only collision runs
    //    if(idtime != timeold) {
    //      edm::LogInfo(" entry ")<< entry << " run " << run << " time " << idtime << " run type " << run_type;
    //      timeold = idtime;
    //    }
    if (run == runold) {
      RunEntry++;
      for (int ich = 0; ich < kChannels; ich++) {
        if (ped[ich] < 300 && ped[ich] > 100) {
          EAmean12[ich] += ped[ich];
          EArms12[ich] += pedrms[ich];
          EAentry[ich]++;
        }
      }
    } else {
      // new run. Write the previous one
      //      edm::LogInfo(" entry ")<< entry << " fill " << fill_num << " run " << runold << " nb of events " << RunEntry
      //		<< " time " << run_time << " " << run_time_stablebeam << " " << time[0] << " run type " << run_type;
      if (RunEntry == 0 || (run_type_kept == 2 && RunEntry < 6))
        fout << " skiped run " << runold << " not enough entries : " << RunEntry << std::endl;
      else {
        fout << " entry " << entry - 1 << " run " << runold << " nb of events " << RunEntry;
        firsttimeFED = time[0];
        for (int ifed = 0; ifed < 54; ifed++) {
          fout << " " << time[ifed];
          if (firsttimeFED < time[ifed])
            firsttimeFED = time[ifed];
        }
        fout << std::endl;

        // get gain 1 and 6 results
        bool foundNew = false;
        for (int i = run16Index; i < Nbpedxml; i++) {
          if (runold > pedxml[i]) {
            fout << " found a new gain 1, 6 file " << pedxml[i] << " at index " << i << std::endl;
            run16Index++;
            foundNew = true;
            if (runold < pedxml[i + 1])
              break;
          }
        }
        if (foundNew) {
          int Indexxml = run16Index - 1;
          fout << " opening Pedestals_" << pedxml[Indexxml] << ".xml at index " << Indexxml << std::endl;
          std::ifstream fxml;
          fxml.open(Form("Pedestals_%i.xml", pedxml[Indexxml]));
          if (!fxml.is_open()) {
            edm::LogInfo("ERROR : cannot open file Pedestals_") << pedxml[Indexxml] << ".xml";
            exit(1);
          }
          std::string dummyLine, mean12, rms12, bid;
          for (int i = 0; i < 9; i++)
            std::getline(fxml, dummyLine);  // skip first lines
          // Barrel
          for (int iEBChannel = 0; iEBChannel < kEBChannels; iEBChannel++) {
            fxml >> mean12 >> rms12 >> bid;
            //	  std::string stt = bid.std::substr(10,15);
            //	  istringstream ii(stt);
            //	  ii >> EBmean12[iEBChannel];
            //	  fxml >> bid;
            //	  stt = bid.substr(9,15);
            //	  istringstream r12(stt);
            //	  r12 >> EBrms12[iEBChannel];
            //	  fxml >> bid;
            std::string stt = bid.substr(9, 15);
            std::istringstream m6(stt);
            m6 >> EAmean6[iEBChannel];
            fxml >> bid;
            stt = bid.substr(8, 15);
            std::istringstream r6(stt);
            r6 >> EArms6[iEBChannel];
            fxml >> bid;
            stt = bid.substr(9, 15);
            std::istringstream m1(stt);
            m1 >> EAmean1[iEBChannel];
            fxml >> bid;
            stt = bid.substr(8, 15);
            std::istringstream r1(stt);
            r1 >> EArms1[iEBChannel];
            if (iEBChannel % 10000 == 0)
              fout << " EB channel " << iEBChannel << " " << mean12 << " " << rms12 << " " << EAmean6[iEBChannel] << " "
                   << EArms6[iEBChannel] << " " << EAmean1[iEBChannel] << " " << EArms1[iEBChannel] << std::endl;
            for (int i = 0; i < 3; i++)
              std::getline(fxml, dummyLine);  // skip lines
          }
          for (int i = 0; i < 6; i++)
            std::getline(fxml, dummyLine);  // skip lines
          for (int iEEChannel = 0; iEEChannel < kEEChannels; iEEChannel++) {
            int ich = iEEChannel + kEBChannels;
            fxml >> mean12 >> rms12 >> bid;
            std::string stt = bid.substr(9, 15);
            std::istringstream m6(stt);
            m6 >> EAmean6[ich];
            fxml >> bid;
            stt = bid.substr(8, 15);
            std::istringstream r6(stt);
            r6 >> EArms6[ich];
            fxml >> bid;
            stt = bid.substr(9, 15);
            std::istringstream m1(stt);
            m1 >> EAmean1[ich];
            fxml >> bid;
            stt = bid.substr(8, 15);
            std::istringstream r1(stt);
            r1 >> EArms1[ich];
            if (iEEChannel % 1000 == 0)
              fout << " EE channel " << iEEChannel << " " << mean12 << " " << rms12 << " " << EAmean6[ich] << " "
                   << EArms6[ich] << " " << EAmean1[ich] << " " << EArms1[ich] << std::endl;
            for (int i = 0; i < 3; i++)
              std::getline(fxml, dummyLine);  // skip lines
          }

          fxml.close();
        }
        // end gain 1 and 6 results

        EcalPedestals* pedestal = new EcalPedestals();
        EcalPedestals::Item item;
        for (int ich = 0; ich < kChannels; ich++) {
          if (EAentry[ich] != 0) {
            EAmean12[ich] /= EAentry[ich];
            EArms12[ich] /= EAentry[ich];
          } else {
            EAmean12[ich] = 200.;
            EArms12[ich] = 0.;
          }
          if (ich % 10000 == 0)
            fout << " channel " << ich << " ped " << EAmean12[ich] << " RMS " << EArms12[ich] << std::endl;
          //
          item.mean_x1 = EAmean1[ich];
          item.rms_x1 = EArms1[ich];
          item.mean_x6 = EAmean6[ich];
          item.rms_x6 = EArms6[ich];
          item.mean_x12 = EAmean12[ich];
          item.rms_x12 = EArms12[ich];
          if (ich < kEBChannels) {
            //	EBDetId ebdetid(fed, chan, EBDetId::SMCRYSTALMODE);
            EBDetId ebdetid = EBDetId::unhashIndex(ich);
            pedestal->insert(std::make_pair(ebdetid.rawId(), item));
          } else {
            //	  EEDetId eedetid(iX, iY, iz);
            int iChannel = ich - kEBChannels;
            EEDetId eedetid = EEDetId::unhashIndex(iChannel);
            pedestal->insert(std::make_pair(eedetid.rawId(), item));
          }
        }  // end loop over all channels
        Time_t snc = (Time_t)runold;
        m_to_transfer.push_back(std::make_pair((EcalPedestals*)pedestal, snc));
      }  // skip too short cosmics runs

      runold = run;
      RunEntry = 1;
      for (int ich = 0; ich < kChannels; ich++) {
        if (ped[ich] < 300 && ped[ich] > 100) {
          EAmean12[ich] = ped[ich];
          EArms12[ich] = pedrms[ich];
          EAentry[ich] = 1;
        } else {
          EAmean12[ich] = 0;
          EArms12[ich] = 0;
          EAentry[ich] = 0;
        }
      }
    }  // new run
  }    // end loop over all entries
  // write also the last run
  fout << " last entry fill " << fill_num << " run " << runold << " nb of events " << RunEntry << " time " << run_time
       << " " << run_time_stablebeam << " " << time[0] << " run type " << run_type << std::endl;
  for (int ifed = 0; ifed < 54; ifed++)
    fout << " " << time[ifed];
  fout << std::endl;
  EcalPedestals* pedestal = new EcalPedestals();
  EcalPedestals::Item item;
  for (int ich = 0; ich < kChannels; ich++) {
    if (EAentry[ich] != 0) {
      EAmean12[ich] /= EAentry[ich];
      EArms12[ich] /= EAentry[ich];
    } else {
      EAmean12[ich] = 200.;
      EArms12[ich] = 0.;
    }
    if (ich % 10000 == 0)
      fout << " channel " << ich << " ped " << EAmean12[ich] << " RMS " << EArms12[ich] << std::endl;
    // get gain 1 and 6 results
    // ...
    //
    item.mean_x1 = EAmean1[ich];
    item.rms_x1 = EArms1[ich];
    item.mean_x6 = EAmean6[ich];
    item.rms_x6 = EArms6[ich];
    item.mean_x12 = EAmean12[ich];
    item.rms_x12 = EArms12[ich];
    if (ich < kEBChannels) {
      //	EBDetId ebdetid(fed, chan, EBDetId::SMCRYSTALMODE);
      EBDetId ebdetid = EBDetId::unhashIndex(ich);
      pedestal->insert(std::make_pair(ebdetid.rawId(), item));
    } else {
      //	  EEDetId eedetid(iX, iY, iz);
      int iChannel = ich - kEBChannels;
      EEDetId eedetid = EEDetId::unhashIndex(iChannel);
      pedestal->insert(std::make_pair(eedetid.rawId(), item));
    }
  }  // end loop over all channels
  Time_t snc = (Time_t)runold;
  m_to_transfer.push_back(std::make_pair((EcalPedestals*)pedestal, snc));  // run based IOV
  edm::LogInfo("Ecal - > end of readPedestalTree -----------\n");
}
/////////////////////////////////////////////////////////////////////////////////////////////////

void popcon::EcalPedestalsHandler::readPedestalTimestamp() {
  bool debug = false;
  edm::LogInfo(" reading the root file ") << m_filename;
  TFile* hfile = new TFile(m_filename.c_str());

  TTree* treeChan = (TTree*)hfile->Get("PedChan");
  int iChannel = 0, ix = 0, iy = 0, iz = 0;
  treeChan->SetBranchAddress("Channels", &iChannel);
  treeChan->SetBranchAddress("x", &ix);
  treeChan->SetBranchAddress("y", &iy);
  treeChan->SetBranchAddress("z", &iz);
  int neventsChan = (int)treeChan->GetEntries();
  edm::LogInfo("PedChan nb entries ") << neventsChan;
  int ringEB[kEBChannels], sideEB[kEBChannels], ixEE[kEEChannels], iyEE[kEEChannels], izEE[kEEChannels];
  for (int entry = 0; entry < neventsChan; entry++) {
    treeChan->GetEntry(entry);
    if (entry < kEBChannels) {
      ringEB[iChannel] = (abs(ix) - 1) / 5;  // -85...-1, 1...85 give 0...16
      sideEB[iChannel] = 1;
      if (ix < 0)
        sideEB[iChannel] = 0;
      if (debug && entry % 10000 == 0)
        edm::LogInfo(" EB channel ") << iChannel << " eta " << ix << " phi " << iy << " side " << sideEB[iChannel]
                                     << " ring " << ringEB[iChannel];
    } else {
      ixEE[iChannel] = ix;
      iyEE[iChannel] = iy;
      izEE[iChannel] = iz;
      if (debug && entry % 1000 == 0)
        edm::LogInfo(" EE channel ") << iChannel << " x " << ixEE[iChannel] << " y " << iyEE[iChannel] << " z "
                                     << izEE[iChannel];
    }
  }
  //    2016: 26
  Int_t pedxml[Nbpedxml] = {271948,
                            273634,
                            273931,
                            274705,
                            275403,
                            276108,
                            276510,
                            277169,
                            278123,
                            278183,
                            278246,
                            278389,
                            278499,
                            278693,
                            278858,
                            278888,
                            278931,
                            279728,
                            280129,
                            280263,
                            280941,
                            281753,
                            282631,
                            282833,
                            283199,
                            283766,
                            //    2017 : 25
                            286535,
                            293513,
                            293632,
                            293732,
                            295507,
                            295672,
                            296391,
                            296917,
                            297388,
                            298481,
                            299279,
                            299710,
                            300186,
                            300581,
                            301191,
                            302006,
                            302293,
                            302605,
                            303436,
                            303848,
                            304211,
                            304680,
                            305117,
                            305848,
                            306176,
                            //    2018 : 30
                            313760,
                            315434,
                            315831,
                            316299,
                            316694,
                            316963,
                            317399,
                            317669,
                            318249,
                            318747,
                            319111,
                            319365,
                            319700,
                            320098,
                            320515,
                            320905,
                            321184,
                            321480,
                            321855,
                            322151,
                            322653,
                            323261,
                            323802,
                            324250,
                            324632,
                            325909,
                            326038,
                            326652,
                            326979,
                            327271};

  Int_t run16Index = 0;

  Int_t fed[kChannels], chan[kChannels], id, run, run_type, seq_id, las_id, fill_num, run_num_infill, run_time,
      run_time_stablebeam, nxt, time[54];
  Float_t ped[kChannels], pedrms[kChannels], lumi, bfield;
  TTree* tree = (TTree*)hfile->Get("T");
  tree->Print();
  tree->SetBranchAddress("id", &id);
  tree->SetBranchAddress("run", &run);
  tree->SetBranchAddress("run_type", &run_type);
  tree->SetBranchAddress("seq_id", &seq_id);
  tree->SetBranchAddress("las_id", &las_id);
  tree->SetBranchAddress("fill_num", &fill_num);
  tree->SetBranchAddress("run_num_infill", &run_num_infill);
  tree->SetBranchAddress("run_time", &run_time);
  tree->SetBranchAddress("run_time_stablebeam", &run_time_stablebeam);
  tree->SetBranchAddress("lumi", &lumi);
  tree->SetBranchAddress("bfield", &bfield);
  tree->SetBranchAddress("nxt", &nxt);  // nb of filled Crystals
  tree->SetBranchAddress("time", time);
  tree->SetBranchAddress("fed", fed);
  tree->SetBranchAddress("chan", chan);
  tree->SetBranchAddress("ped", ped);
  tree->SetBranchAddress("pedrms", pedrms);
  int nevents = (int)tree->GetEntries();
  edm::LogInfo(" nb entries ") << nevents;
  std::ofstream fout;
  fout.open("copyTimestampPedestals.txt");
  if (!fout.is_open()) {
    edm::LogInfo("ERROR : cannot open file copyTimestampPedestals.txt");
    exit(1);
  }
  Double_t EAmean1[kChannels], EArms1[kChannels], EAmean6[kChannels], EArms6[kChannels], EAmean12[kChannels],
      EArms12[kChannels];
  for (int ich = 0; ich < kChannels; ich++) {
    EAmean12[ich] = 200.;
    EArms12[ich] = 0.;
  }
  tree->GetEntry(0);
  fout << " first run " << run << " fill " << fill_num << " B field " << bfield << " run type " << run_type
       << " seq_id " << seq_id << " las_id " << las_id << " run_num_infill " << run_num_infill << " lumi " << lumi
       << " nb of Crystals " << nxt << std::endl;
  if (debug) {
    for (int ich = 0; ich < kChannels; ich++) {
      if (ped[ich] != 0.) {
        if (ich < kEBChannels)
          fout << " channel " << ich << " FED " << fed[ich] << " chan " << chan[ich] << " pedestal " << ped[ich]
               << " RMS " << pedrms[ich] << std::endl;
        else  //   EE
          fout << " channel " << ich << " EE channel " << ich - kEBChannels << " FED " << fed[ich] << " chan "
               << chan[ich] << " pedestal " << ped[ich] << " RMS " << pedrms[ich] << std::endl;
      }
    }
  }  // debug

  int runold = -1, fillold = -1, firsttimeFEDold = -1;
  int firsttimeFED = -1, firstFillSequence = 0;
  bool firstSeqBeforeStable = false;
  int transfer = 0;
  int first_run_kept = (int)m_firstRun;  //  m_firstRun is unsigned!
  int last_run_kept = (int)m_lastRun;    //  m_lastRun is unsigned!
  for (int entry = 0; entry < nevents; entry++) {
    tree->GetEntry(entry);
    if (nxt != kChannels) {
      //      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " run_time " << run_time
      fout << " entry " << entry << " run " << run << " sequence " << seq_id  // run_time always 0!
           << " ***********  Number of channels " << nxt;
      //      if(seq_id == 0) {    corrected Sep 15 2017
      fout << " rejected" << std::endl;
      continue;
      //      }
      //      else fout << std::endl;
    }
    if (run_type != 1) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id
           << " ***********  run_type ( 1 coll, 2 cosm, 3 circ, 4 test ) = " << run_type << std::endl;
      continue;
    }
    if (las_id != 447) {  //447 = blue laser
      fout << " entry " << entry << " run " << run << " sequence " << seq_id
           << " ***********  laser wave length = " << las_id << std::endl;
      continue;
    }
    //    if(las_id != 527) {  //527 = green laser
    //      fout << " entry " << entry << " run " << run << " sequence " << seq_id
    //    	   << " ***********  laser wave length = " << las_id << std::endl;
    //      continue;
    //    }
    if (bfield < 3.79) {
      fout << " entry " << entry << " run " << run << " sequence " << seq_id << " ***********  bfield = " << bfield
           << std::endl;
      //      continue;  keep these runs
    }
    fout << " entry " << entry << " run " << run;
    if (run_type == 1)
      fout << " fill " << fill_num;
    fout << " sequence " << seq_id;
    if (run_type == 1) {
      fout << " stable " << run_time_stablebeam;
      if (run_time_stablebeam < first_run_kept) {
        fout << " before first wanted " << m_firstRun << std::endl;
        continue;
      }
    }
    firsttimeFED = time[0];
    for (int ifed = 0; ifed < 54; ifed++) {
      if (time[ifed] > firsttimeFEDold && time[ifed] < firsttimeFED)
        firsttimeFED = time[ifed];  // take the first AFTER the previous sequence one!...
    }
    if (firsttimeFED < first_run_kept) {
      fout << " time " << firsttimeFED << " before first wanted " << m_firstRun << std::endl;
      continue;
    }
    if (firsttimeFED > last_run_kept) {
      fout << " entry " << entry << " time " << firsttimeFED << " after last wanted " << m_lastRun << std::endl;
      break;
    }
    fout << " time " << firsttimeFED << std::endl;
    if (firsttimeFED <= firsttimeFEDold) {
      edm::LogInfo(" Problem finding the IOV : old one ") << firsttimeFEDold << " new one " << firsttimeFED;
      for (int ifed = 0; ifed < 54; ifed++)
        edm::LogInfo("Time ") << time[ifed] << " ignore this entry ";
      continue;
    }
    firsttimeFEDold = firsttimeFED;

    //    if(run != runold) firstSeqBeforeStable = false;
    if (fill_num != fillold) {
      firstSeqBeforeStable = false;
      firstFillSequence = 0;
    } else
      firstFillSequence++;
    if (run_type == 1) {
      if (run_time_stablebeam > 0) {
        if (firsttimeFED < run_time_stablebeam) {
          fout << " data taken before stable beam, skip it" << std::endl;
          firstSeqBeforeStable = true;
          runold = run;
          fillold = fill_num;
          continue;
        }
      } else  //  problem with run_time_stablebeam
        fout << " *** entry " << entry << " run_time_stablebeam " << run_time_stablebeam << std::endl;
      if (firstSeqBeforeStable) {  // this is the first fully filled entry after stable beam
        firstSeqBeforeStable = false;
        firsttimeFED = run_time_stablebeam;
        fout << " first full sequence after stable; change the IOV " << firsttimeFED << std::endl;
      }
      if (firstFillSequence == 0) {  // first sequence in this fill
        if (firsttimeFED > run_time_stablebeam) {
          fout << " first full sequence " << firsttimeFED << " after stable " << run_time_stablebeam
               << "; change the IOV " << std::endl;
          firsttimeFED = run_time_stablebeam;
        }
      }
    }  // only collision runs

    for (int ich = 0; ich < kChannels; ich++) {
      if (ped[ich] < 300 && ped[ich] > 100) {
        EAmean12[ich] = ped[ich];
        EArms12[ich] = pedrms[ich];
      }
    }
    // get gain 1 and 6 results
    bool foundNew = false;
    if (run != runold) {
      for (int i = run16Index; i < Nbpedxml; i++) {
        if (run > pedxml[i]) {
          fout << " found a new gain 1, 6 file " << pedxml[i] << " at index " << i << std::endl;
          run16Index++;
          foundNew = true;
          //	  if(runold < pedxml[i + 1]) break;   why runold??
          if (run < pedxml[i + 1])
            break;
        }
      }
      if (foundNew) {
        int Indexxml = run16Index - 1;
        fout << " opening Pedestals_" << pedxml[Indexxml] << ".xml at index " << Indexxml << std::endl;
        std::ifstream fxml;
        fxml.open(Form("Pedestals_%i.xml", pedxml[Indexxml]));
        if (!fxml.is_open()) {
          edm::LogInfo("ERROR : cannot open file Pedestals_") << pedxml[Indexxml] << ".xml";
          exit(1);
        }
        std::string dummyLine, mean12, rms12, bid;
        for (int i = 0; i < 9; i++)
          std::getline(fxml, dummyLine);  // skip first lines
        // Barrel
        for (int iEBChannel = 0; iEBChannel < kEBChannels; iEBChannel++) {
          fxml >> mean12 >> rms12 >> bid;
          std::string stt = bid.substr(9, 15);
          std::istringstream m6(stt);
          m6 >> EAmean6[iEBChannel];
          fxml >> bid;
          stt = bid.substr(8, 15);
          std::istringstream r6(stt);
          r6 >> EArms6[iEBChannel];
          fxml >> bid;
          stt = bid.substr(9, 15);
          std::istringstream m1(stt);
          m1 >> EAmean1[iEBChannel];
          fxml >> bid;
          stt = bid.substr(8, 15);
          std::istringstream r1(stt);
          r1 >> EArms1[iEBChannel];
          if (debug && iEBChannel % 10000 == 0)
            fout << " EB channel " << iEBChannel << " " << mean12 << " " << rms12 << " " << EAmean6[iEBChannel] << " "
                 << EArms6[iEBChannel] << " " << EAmean1[iEBChannel] << " " << EArms1[iEBChannel] << std::endl;
          for (int i = 0; i < 3; i++)
            std::getline(fxml, dummyLine);  // skip lines
        }
        for (int i = 0; i < 6; i++)
          std::getline(fxml, dummyLine);  // skip lines
        for (int iEEChannel = 0; iEEChannel < kEEChannels; iEEChannel++) {
          int ich = iEEChannel + kEBChannels;
          fxml >> mean12 >> rms12 >> bid;
          std::string stt = bid.substr(9, 15);
          std::istringstream m6(stt);
          m6 >> EAmean6[ich];
          fxml >> bid;
          stt = bid.substr(8, 15);
          std::istringstream r6(stt);
          r6 >> EArms6[ich];
          fxml >> bid;
          stt = bid.substr(9, 15);
          std::istringstream m1(stt);
          m1 >> EAmean1[ich];
          fxml >> bid;
          stt = bid.substr(8, 15);
          std::istringstream r1(stt);
          r1 >> EArms1[ich];
          if (debug && iEEChannel % 1000 == 0)
            fout << " EE channel " << iEEChannel << " " << mean12 << " " << rms12 << " " << EAmean6[ich] << " "
                 << EArms6[ich] << " " << EAmean1[ich] << " " << EArms1[ich] << std::endl;
          for (int i = 0; i < 3; i++)
            std::getline(fxml, dummyLine);  // skip lines
        }
        fxml.close();
      }  // found a new gain 1 6 file
    }    // check gain 1 and 6 results only for new runs

    EcalPedestals* pedestal = new EcalPedestals();
    EcalPedestals::Item item;
    for (int ich = 0; ich < kChannels; ich++) {
      if (debug && ich % 10000 == 0)
        fout << " channel " << ich << " ped " << EAmean12[ich] << " RMS " << EArms12[ich] << std::endl;
      //
      item.mean_x1 = EAmean1[ich];
      item.rms_x1 = EArms1[ich];
      item.mean_x6 = EAmean6[ich];
      item.rms_x6 = EArms6[ich];
      item.mean_x12 = EAmean12[ich];
      item.rms_x12 = EArms12[ich];
      if (ich < kEBChannels) {
        //	EBDetId ebdetid(fed, chan, EBDetId::SMCRYSTALMODE);
        EBDetId ebdetid = EBDetId::unhashIndex(ich);
        pedestal->insert(std::make_pair(ebdetid.rawId(), item));
      } else {
        //	  EEDetId eedetid(iX, iY, iz);
        int iChannel = ich - kEBChannels;
        EEDetId eedetid = EEDetId::unhashIndex(iChannel);
        pedestal->insert(std::make_pair(eedetid.rawId(), item));
      }
    }  // end loop over all channels
    uint64_t iov = (uint64_t)firsttimeFED << 32;
    Time_t snc = (Time_t)iov;
    transfer++;
    fout << " entry " << entry << " transfer " << transfer << " iov " << iov << std::endl;
    m_to_transfer.push_back(std::make_pair((EcalPedestals*)pedestal, snc));  // time based IOV
    fout << "  m_to_transfer " << firsttimeFED << std::endl;
    runold = run;
    fillold = fill_num;
  }  // end loop over all entries

  edm::LogInfo("Ecal - > end of readPedestalTimestamp -----------\n");
}
