CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CondTools/Ecal/src/EcalLaserHandler.cc

Go to the documentation of this file.
00001 #include "CondTools/Ecal/interface/EcalLaserHandler.h"
00002 #include "OnlineDB/EcalCondDB/interface/EcalLogicID.h"
00003 #include "OnlineDB/EcalCondDB/interface/LMFSextuple.h"
00004 #include "FWCore/ParameterSet/interface/ParameterSetfwd.h"
00005 #include "CondCore/DBCommon/interface/Time.h"
00006 #include "DataFormats/Provenance/interface/Timestamp.h"
00007 #include "OnlineDB/EcalCondDB/interface/Tm.h"
00008 
00009 #include<iostream>
00010 #include<iomanip>
00011 #include <sstream>
00012 
00013 popcon::EcalLaserHandler::EcalLaserHandler(const edm::ParameterSet & ps) 
00014   : m_name(ps.getUntrackedParameter<std::string>("name","EcalLaserHandler")) {
00015   
00016   std::cout << "EcalLaser Source handler constructor\n" << std::endl;
00017 
00018   m_sequences = 1;
00019   m_fake = true;
00020 
00021   m_sid= ps.getParameter<std::string>("OnlineDBSID");
00022   m_user= ps.getParameter<std::string>("OnlineDBUser");
00023   m_pass= ps.getParameter<std::string>("OnlineDBPassword");
00024   m_debug=ps.getParameter<bool>("debug");
00025   m_fake=ps.getParameter<bool>("fake");
00026   m_sequences=static_cast<unsigned int>(atoi( ps.getParameter<std::string>("sequences").c_str()));
00027   m_maxtime=ps.getParameter<std::string>("maxtime").c_str();
00028   std::cout << "Starting O2O process on DB: " << m_sid
00029             << " User: "<< m_user << std::endl;
00030   if (m_fake) {
00031     std::cout << "*******************************************" << std::endl;
00032     std::cout << "This is a fake run. No change to offline DB" << std::endl;
00033     std::cout << "*******************************************" << std::endl;
00034   }
00035 }
00036 
00037 popcon::EcalLaserHandler::~EcalLaserHandler()
00038 {
00039   // do nothing
00040 }
00041 
00042 double popcon::EcalLaserHandler::diff(float a, float b) {
00043   return std::abs(b- a)/a;
00044 }
00045 
00046 void popcon::EcalLaserHandler::notifyProblems(const EcalLaserAPDPNRatios::EcalLaserAPDPNpair &old, 
00047                                               const EcalLaserAPDPNRatios::EcalLaserAPDPNpair &current,
00048                                               int hashedIndex, const std::string &reason) {
00049   std::cout << "===== " << reason << " =====" << std::endl;
00050   if (hashedIndex < 0) {
00051     EEDetId ee;
00052     std::cout << "Triplets for " << ee.unhashIndex(-hashedIndex) << " bad: [" << old.p1 << ", "
00053               << old.p2 << ", " << old.p3 << "] ==> [" << current.p1 << ", "
00054               << current.p2 << ", " << current.p3 << "]" << std::endl;
00055   } else {
00056     EBDetId eb;
00057     std::cout << "Triplets for " << eb.unhashIndex(hashedIndex) << " bad: [" << old.p1 << ", "
00058               << old.p2 << ", " << old.p3 << "] ==> [" << current.p1 << ", "
00059               << current.p2 << ", " << current.p3 << "]" << std::endl;
00060   }
00061 } 
00062 
00063 bool popcon::EcalLaserHandler::checkAPDPN(const EcalLaserAPDPNRatios::EcalLaserAPDPNpair &old, 
00064                                           const EcalLaserAPDPNRatios::EcalLaserAPDPNpair &current,
00065                                           int hashedIndex) {
00066   bool ret = true;
00067   if ((current.p1 < 0) || (current.p2 < 0) || (current.p3 < 0)) {
00068     ret = false;
00069     notifyProblems(old, current, hashedIndex, "Negative values");
00070   } else if ((current.p1 > 10) || (current.p2 > 10) || (current.p3 > 10)) {
00071     ret = false;
00072     notifyProblems(old, current, hashedIndex, "Values too large");
00073   } else if (((diff(old.p1, current.p1) > 0.2) && (old.p1 != 0) && (old.p1 != 1)) ||
00074              ((diff(old.p2, current.p2) > 0.2) && (old.p2 != 0) && (old.p1 != 2)) ||
00075              ((diff(old.p3, current.p3) > 0.2) && (old.p3 != 0) && (old.p1 != 3))) {
00076     ret = false;
00077     notifyProblems(old, current, hashedIndex, "Difference w.r.t. previous too large");
00078   }
00079   return ret;
00080 }
00081 
00082 bool popcon::EcalLaserHandler::checkAPDPNs(const EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap &laserMap,
00083                                            const EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap &apdpns_popcon) {
00084   bool ret = true;
00085   for (int hashedIndex = 0; hashedIndex < 61200; hashedIndex++) {
00086     EcalLaserAPDPNRatios::EcalLaserAPDPNpair old = laserMap.barrel(hashedIndex);
00087     EcalLaserAPDPNRatios::EcalLaserAPDPNpair current = apdpns_popcon.barrel(hashedIndex);
00088     ret = checkAPDPN(old, current, hashedIndex);
00089   }
00090   for (int hashedIndex = 0; hashedIndex < 14648; hashedIndex++) {
00091     EcalLaserAPDPNRatios::EcalLaserAPDPNpair old = laserMap.endcap(hashedIndex);
00092     EcalLaserAPDPNRatios::EcalLaserAPDPNpair current = apdpns_popcon.endcap(hashedIndex);
00093     ret = checkAPDPN(old, current, -hashedIndex);
00094   }
00095   return ret;
00096 }
00097 
00098 void popcon::EcalLaserHandler::dumpBarrelPayload(EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap const &laserMap) {
00099   int c = 0;
00100   EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap::const_iterator i = laserMap.barrelItems().begin();
00101   EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap::const_iterator e = laserMap.barrelItems().end();
00102   EBDetId eb;
00103   try {
00104     EcalCondDBInterface *econn = new EcalCondDBInterface( m_sid, m_user, m_pass );
00105     while (i != e) {
00106       if (c % 1000 == 0) {
00107         std::cout << std::setw(5) << c << ": " << eb.unhashIndex(c) << " "   
00108                   << econn->getEcalLogicID("EB_crystal_angle", eb.unhashIndex(c).ieta(), 
00109                                            eb.unhashIndex(c).iphi(), EcalLogicID::NULLID, 
00110                                            "EB_crystal_number").getLogicID() 
00111                   << " " << std::setiosflags(std::ios::fixed) << std::setprecision(9) 
00112                   << i->p1 << " " << i->p2 << " " << i->p3 << std::endl;
00113       }
00114       i++;
00115       c++;
00116     }
00117     delete econn;
00118   }
00119   catch (std::runtime_error &e) {
00120     std::cerr << e.what() << std::endl;
00121     delete econn;
00122     throw cms::Exception("OMDS not available");
00123   }
00124 }
00125 
00126 void popcon::EcalLaserHandler::dumpEndcapPayload(EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap const &laserMap) {
00127   int c = 0;
00128   EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap::const_iterator i = laserMap.endcapItems().begin();
00129   EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap::const_iterator e = laserMap.endcapItems().end();
00130   EEDetId ee;
00131   try {
00132     EcalCondDBInterface *econn = new EcalCondDBInterface( m_sid, m_user, m_pass );
00133     while (i != e) {
00134       if (c % 1000 == 0) {
00135         std::cout << std::setw(5) << c << ": " << ee.unhashIndex(c) << " "   
00136                   << econn->getEcalLogicID("EE_crystal_number", ee.unhashIndex(c).zside(), 
00137                                            ee.unhashIndex(c).ix(), ee.unhashIndex(c).iy(),
00138                                            "EE_crystal_number").getLogicID() 
00139                   << " " << std::setiosflags(std::ios::fixed) << std::setprecision(9) 
00140                   << i->p1 << " " << i->p2 << " " << i->p3 << std::endl;
00141       }
00142       i++;
00143       c++;
00144     }
00145     delete econn;
00146   }
00147   catch (std::runtime_error &e) {
00148     std::cerr << e.what() << std::endl;
00149     delete econn;
00150     throw cms::Exception("OMDS not available");
00151   }
00152 }
00153 
00154 void popcon::EcalLaserHandler::getNewObjects()
00155 {
00156   std::cerr << "------- " << m_name 
00157             << " ---> getNewObjects" << std::endl;
00158   
00159   std::cout << "------- Ecal -> getNewObjects\n";
00160   
00161   
00162   unsigned long long max_since= 1;
00163   Ref payload= lastPayload();
00164   
00165   // here popcon tells us which is the last since of the last object in the 
00166   // offline DB
00167   max_since=tagInfo().lastInterval.first;
00168   //  Tm max_since_tm((max_since >> 32)*1000000);
00169   Tm max_since_tm(max_since);
00170   // get the last object in the orcoff
00171   edm::Timestamp t_min= edm::Timestamp(18446744073709551615ULL);
00172 
00173   const EcalLaserAPDPNRatios::EcalLaserAPDPNRatiosMap& laserRatiosMap = 
00174     payload->getLaserMap(); 
00175   std::cout << "payload->getLaserMap():  OK " << std::endl;
00176   std::cout << "Its size is " << laserRatiosMap.size() << std::endl;
00177   const EcalLaserAPDPNRatios::EcalLaserTimeStampMap& laserTimeMap = 
00178     payload->getTimeMap();
00179   std::cout << "payload->getTimeMap():  OK " << std::endl;
00180   std::cout << "Last Object in Offline DB has SINCE = "  << max_since
00181             << " -> " << max_since_tm.microsTime() 
00182             << " (" << max_since_tm << ")"
00183             << " and  SIZE = " << tagInfo().size
00184             << std::endl;
00185   // loop through light modules and determine the minimum date among the
00186   // available channels
00187   if (m_debug) {
00188     dumpBarrelPayload(laserRatiosMap);
00189     dumpEndcapPayload(laserRatiosMap);
00190   }
00191   for (int i=0; i<92; i++) {
00192     EcalLaserAPDPNRatios::EcalLaserTimeStamp timestamp = laserTimeMap[i];
00193     if( t_min > timestamp.t1) {
00194       t_min=timestamp.t1;
00195     }
00196   }
00197   
00198   std::cout <<"WOW: we just retrieved the last valid record from DB "
00199             << std::endl;
00200   //  std::cout <<"Its tmin is "<< Tm((t_min.value() >> 32)*1000000)
00201   std::cout <<"Its tmin is "<< Tm(t_min.value())
00202             << std::endl;
00203 
00204   // connect to the database 
00205   try {
00206     std::cout << "Making connection..." << std::flush;
00207     econn = new EcalCondDBInterface( m_sid, m_user, m_pass );
00208     std::cout << "Done." << std::endl;
00209   } catch (std::runtime_error &e) {
00210     std::cout << " connection parameters " << m_sid << "/" << m_user;
00211     if (m_debug) {
00212       std::cout << "/" << m_pass <<std::endl;
00213     } else {
00214       std::cout << "/**********" <<std::endl;
00215     }
00216     std::cerr << e.what() << std::endl;
00217     throw cms::Exception("OMDS not available");
00218   } 
00219 
00220   // retrieve the lists of logic_ids, to build the detids
00221   std::vector<EcalLogicID> crystals_EB  = 
00222     econn->getEcalLogicIDSetOrdered( "EB_crystal_angle",
00223                                      -85,85,1,360,
00224                                      EcalLogicID::NULLID,EcalLogicID::NULLID,
00225                                      "EB_crystal_number", 4 );
00226   std::vector<EcalLogicID> crystals_EE  = 
00227     econn->getEcalLogicIDSetOrdered( "EE_crystal_number",
00228                                      -1,1,1,100,
00229                                      1,100,
00230                                      "EE_crystal_number", 4 );
00231   
00232   std::vector<EcalLogicID>::const_iterator ieb = crystals_EB.begin();
00233   std::vector<EcalLogicID>::const_iterator eeb = crystals_EB.end();
00234 
00235   std::cout << "Got list of " << crystals_EB.size() << " crystals in EB" 
00236             << std::endl;
00237   std::cout << "Got list of " << crystals_EE.size() << " crystals in EE" 
00238             << std::endl;
00239   // loop through barrel
00240   int count = 0;
00241   // prepare a map to associate EB logic id's to detids
00242   std::map<int, int> detids;
00243   while (ieb != eeb) {
00244     int iEta = ieb->getID1();
00245     int iPhi = ieb->getID2();
00246     count++;
00247     EBDetId ebdetid(iEta,iPhi);
00248     //    unsigned int hieb = ebdetid.hashedIndex();    
00249     detids[ieb->getLogicID()] = ebdetid;
00250     ieb++;
00251   }
00252   std::cout << "Validated " << count << " logic ID's for EB" << std::endl;
00253   
00254   // do the same for EE
00255   
00256   std::vector<EcalLogicID>::const_iterator iee = crystals_EE.begin();
00257   std::vector<EcalLogicID>::const_iterator eee = crystals_EE.end();
00258 
00259   count = 0;
00260   while (iee != eee) {
00261     int iSide = iee->getID1();
00262     int iX    = iee->getID2();
00263     int iY    = iee->getID3();
00264     EEDetId eedetidpos(iX,iY,iSide);
00265     //    int hi = eedetidpos.hashedIndex();
00266     detids[iee->getLogicID()] = eedetidpos;
00267     count ++;
00268     iee++;
00269   }
00270   std::cout << "Validated " << count << " logic ID's for EE" << std::endl;
00271 
00272   // get association between ecal logic id and LMR
00273   std::map<int, int> logicId2Lmr = econn->getEcalLogicID2LmrMap();
00274 
00275   std::cout << "Retrieving corrections from ONLINE DB ... " << std::endl;
00276 
00277   LMFCorrCoefDat data(econn);
00278   if (m_debug) {
00279     data.debug();
00280   }
00281   // get all data in the database taken after the last available time in ORCOFF
00282   // we associate another map, whose key is the crystal ID and whose value is a
00283   // sextuple (p1, p2, p3, t1, t2, t3)
00284   Tm tmax;
00285   if (m_maxtime[0] == '-') {
00286     // this is a time relative to now
00287     tmax.setToCurrentLocalTime();
00288     tmax -= atoi(m_maxtime.substr(1).c_str())*3600;//
00289   } else {
00290     tmax.setToString(m_maxtime);
00291   }
00292   //  Tm tmin = Tm((t_min.value() >> 32)*1000000);
00293   Tm tmin = Tm(t_min.value());
00294 
00295   if (tmax <= (tmin + 12000)) {
00296     // 3 days buffer
00297     tmax += 86400 * 3;
00298   }
00299 
00300   if (m_debug) {
00301     std::cout << "Tmin: " << tmin << std::endl;
00302     std::cout << "Tmax: " << tmax << std::endl;
00303   }
00304 
00305   std::map<int, std::map<int, LMFSextuple> > d = 
00306     data.getCorrections(tmin, tmax, m_sequences);
00307   // sice must be equal to the number of different SEQ_ID's found
00308   std::cout << "Data organized into " << d.size() << " sequences" << std::endl;
00309   // iterate over sequences
00310   std::map<int, std::map<int, LMFSextuple> >::const_iterator iseq = d.begin();
00311   std::map<int, std::map<int, LMFSextuple> >::const_iterator eseq = d.end();
00312   std::cout << "===== Looping on Sequences" << std::endl;
00313   while (iseq != eseq) {
00314     std::cout << "==== SEQ_ID: " << iseq->first 
00315               << " contains " << iseq->second.size() << " crystals" 
00316               << std::endl << std::flush;
00317     // iterate over crystals, but skip those sequences with wrong number of crystals
00318     if (iseq->second.size() == (61200 + 14648)) {
00319       std::map<int, LMFSextuple>::const_iterator is = iseq->second.begin();
00320       std::map<int, LMFSextuple>::const_iterator es = iseq->second.end();
00321       EcalLaserAPDPNRatios* apdpns_popcon = new EcalLaserAPDPNRatios();         
00322       Time_t t_last = 18446744073709551615ULL;
00323       while (is != es) {
00324         EcalLaserAPDPNRatios::EcalLaserAPDPNpair apdpnpair_temp;
00325         apdpnpair_temp.p1 = is->second.p[0];
00326         apdpnpair_temp.p2 = is->second.p[1];
00327         apdpnpair_temp.p3 = is->second.p[2];
00328         EcalLaserAPDPNRatios::EcalLaserTimeStamp timestamp_temp;
00329         timestamp_temp.t1 = edm::Timestamp(is->second.t[0].microsTime());
00330         timestamp_temp.t2 = edm::Timestamp(is->second.t[1].microsTime());
00331         timestamp_temp.t3 = edm::Timestamp(is->second.t[2].microsTime());
00332         apdpns_popcon->setValue(detids[is->first], apdpnpair_temp);
00333         if (logicId2Lmr.find(is->first) != logicId2Lmr.end()) {
00334           int hashedIndex = logicId2Lmr[is->first] - 1;
00335           if ((hashedIndex >= 0) && (hashedIndex <= 91)) {
00336             apdpns_popcon->setTime( hashedIndex , timestamp_temp);
00337             if (t_last > timestamp_temp.t1.value()) {
00338               t_last = timestamp_temp.t1.value();
00339             }
00340           } else {
00341             std::stringstream ss;
00342             ss << "LOGIC_ID: " << is->first << " LMR: " << hashedIndex + 1
00343                << " Out of range";
00344             throw(std::runtime_error("[EcalLaserHandler::getNewObjects]" +
00345                                      ss.str()));
00346           }
00347         } else {
00348           std::stringstream ss;
00349           ss << "LOGIC_ID: " << is->first << " Cannot determine LMR";
00350           throw(std::runtime_error("[EcalLaserHandler::getNewObjects]" +
00351                                    ss.str()));
00352         }
00353         is++;
00354       }
00355       if (m_fake) {
00356         delete apdpns_popcon;
00357       }
00358       if ((iseq->second.size() > 0) && (!m_fake)) {
00359         m_to_transfer.push_back(std::make_pair(apdpns_popcon, 
00360                                                Tm(t_last).cmsNanoSeconds()));
00361       } 
00362     } else {
00363       // Here we should put a warning
00364     }
00365     iseq++;
00366   }
00367   std::cout << "==== END OF LOOP ON SEQUENCES" << std::endl << std::flush;
00368   delete econn;
00369   std::cout << "Ecal -> end of getNewObjects -----------\n";
00370         
00371         
00372 }