CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CalibCalorimetry/EcalPedestalOffsets/src/EcalPedOffset.cc

Go to the documentation of this file.
00001 //TODO: fix header here?
00013 #include <memory>
00014 #include <iostream>
00015 #include <fstream>
00016 
00017 #include "CalibCalorimetry/EcalPedestalOffsets/interface/EcalPedOffset.h"
00018 
00019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00020 
00021 #include "OnlineDB/EcalCondDB/interface/EcalCondDBInterface.h"
00022 #include "OnlineDB/EcalCondDB/interface/RunTag.h"
00023 #include "OnlineDB/EcalCondDB/interface/RunIOV.h"
00024 #include "OnlineDB/EcalCondDB/interface/MonRunIOV.h"
00025 #include "OnlineDB/EcalCondDB/interface/MonPedestalOffsetsDat.h"
00026 
00027 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
00028 
00029 #include "DataFormats/EcalRawData/interface/EcalDCCHeaderBlock.h"
00030 #include "DataFormats/EcalRawData/interface/EcalRawDataCollections.h"
00031 
00032 #include "FWCore/Framework/interface/ESHandle.h"
00033 #include "Geometry/EcalMapping/interface/EcalElectronicsMapping.h"
00034 #include "Geometry/EcalMapping/interface/EcalMappingRcd.h"
00035 
00036 using namespace cms;
00037 using namespace edm;
00038 
00040 EcalPedOffset::EcalPedOffset (const ParameterSet& paramSet) :
00041   m_barrelDigiCollection (paramSet.getParameter<edm::InputTag> ("EBdigiCollection")),
00042   m_endcapDigiCollection (paramSet.getParameter<edm::InputTag> ("EEdigiCollection")),
00043   m_headerCollection (paramSet.getParameter<edm::InputTag> ("headerCollection")),
00044   m_xmlFile (paramSet.getParameter<std::string> ("xmlFile")),
00045   m_DACmin (paramSet.getUntrackedParameter<int> ("DACmin",0)),
00046   m_DACmax (paramSet.getUntrackedParameter<int> ("DACmax",256)),
00047   m_RMSmax (paramSet.getUntrackedParameter<double> ("RMSmax",2)),
00048   m_bestPed (paramSet.getUntrackedParameter<int> ("bestPed",200)), 
00049   m_dbHostName (paramSet.getUntrackedParameter<std::string> ("dbHostName","0")),
00050   m_dbName (paramSet.getUntrackedParameter<std::string> ("dbName","0")),
00051   m_dbUserName (paramSet.getUntrackedParameter<std::string> ("dbUserName")),
00052   m_dbPassword (paramSet.getUntrackedParameter<std::string> ("dbPassword")),
00053   m_dbHostPort (paramSet.getUntrackedParameter<int> ("dbHostPort",1521)),
00054   m_create_moniov (paramSet.getUntrackedParameter<bool>("createMonIOV", false)),
00055   m_location (paramSet.getUntrackedParameter<std::string>("location", "H4")),
00056   m_run(-1),
00057   m_plotting (paramSet.getParameter<std::string> ("plotting")),
00058   m_maxSlopeAllowed_ (paramSet.getUntrackedParameter<double> ("maxSlopeAllowed",-29)),
00059   m_minSlopeAllowed_ (paramSet.getUntrackedParameter<double> ("minSlopeAllowed",-18)),
00060   m_maxChi2OverNDFAllowed_ (paramSet.getUntrackedParameter<double> ("maxChi2OverNDF",5))
00061 {
00062   edm::LogInfo ("EcalPedOffset") << " reading "
00063     << " m_DACmin: " << m_DACmin
00064     << " m_DACmax: " << m_DACmax
00065     << " m_RMSmax: " << m_RMSmax
00066     << " m_bestPed: " << m_bestPed ;
00067 }
00068 
00069 
00070 // -----------------------------------------------------------------------------
00071 
00072 
00074 EcalPedOffset::~EcalPedOffset ()
00075 {
00076   for (std::map<int,TPedValues*>::iterator mapIt = m_pedValues.begin ();
00077       mapIt != m_pedValues.end ();
00078       ++mapIt)
00079     delete mapIt->second ; 
00080   for (std::map<int,TPedResult*>::iterator mapIt = m_pedResult.begin ();
00081       mapIt != m_pedResult.end ();
00082       ++mapIt)
00083     delete mapIt->second ; 
00084 }
00085 
00086 
00087 // -----------------------------------------------------------------------------
00088 
00089 
00091 void EcalPedOffset::beginRun (Run const &, EventSetup const& eventSetup)
00092 {
00093   LogDebug ("EcalPedOffset") << "entering beginRun..." ;
00094 
00095   edm::ESHandle< EcalElectronicsMapping > handle;
00096   eventSetup.get< EcalMappingRcd >().get(handle);
00097   ecalElectronicsMap_ = handle.product();
00098 
00099 }
00100 
00101 
00102 // -----------------------------------------------------------------------------
00103 
00104 
00106 void EcalPedOffset::analyze (Event const& event, 
00107     EventSetup const& eventSetup) 
00108 {
00109   LogDebug ("EcalPedOffset") << "entering analyze ...";
00110 
00111   // get the headers
00112   // (one header for each supermodule)
00113   edm::Handle<EcalRawDataCollection> DCCHeaders;
00114   event.getByLabel(m_headerCollection, DCCHeaders);
00115 
00116   std::map <int,int> DACvalues;
00117 
00118   if(m_run==-1)
00119     m_run = event.id().run();
00120 
00121   // loop over the headers
00122   for (EcalRawDataCollection::const_iterator headerItr= DCCHeaders->begin();
00123       headerItr != DCCHeaders->end (); 
00124       ++headerItr) 
00125   {
00126     EcalDCCHeaderBlock::EcalDCCEventSettings settings = headerItr->getEventSettings();
00127     int FEDid = 600+headerItr->id();
00128     DACvalues[FEDid] = settings.ped_offset;
00129     LogDebug("EcalPedOffset") << "Found FED: " << FEDid << " in DCC header";
00130   }
00131 
00132   bool barrelDigisFound = true;
00133   bool endcapDigisFound = true;
00134   // get the barrel digis
00135   // (one digi for each crystal)
00136   Handle<EBDigiCollection> barrelDigis;
00137   event.getByLabel(m_barrelDigiCollection, barrelDigis);
00138   if(!barrelDigis.isValid())
00139   {
00140     edm::LogError ("EcalPedOffset") << "Error! can't get the product " 
00141       << m_barrelDigiCollection << "; not reading barrel digis";
00142     barrelDigisFound = false;
00143   }
00144 
00145   if(barrelDigis->size()==0) 
00146   {
00147     edm::LogInfo("EcalPedOffset") << "Size of EBDigiCollection is zero;"
00148       << " not reading barrel digis";
00149     barrelDigisFound = false;
00150   }
00151 
00152   // get the endcap digis
00153   // (one digi for each crystal)
00154   Handle<EEDigiCollection> endcapDigis;
00155   event.getByLabel(m_endcapDigiCollection, endcapDigis);
00156   if(!endcapDigis.isValid())
00157   {
00158     edm::LogError ("EcalPedOffset") << "Error! can't get the product " 
00159       << m_endcapDigiCollection << "; not reading endcap digis";
00160     endcapDigisFound = false;
00161   }
00162 
00163   if(endcapDigis->size()==0) 
00164   {
00165     edm::LogInfo("EcalPedOffset") << "Size of EEDigiCollection is zero;"
00166       << " not reading endcap digis";
00167     endcapDigisFound = false;
00168   }
00169 
00170   
00171   if(barrelDigisFound)
00172     readDACs(barrelDigis, DACvalues);
00173   if(endcapDigisFound)
00174     readDACs(endcapDigis, DACvalues);
00175   if(!barrelDigisFound && !endcapDigisFound)
00176     edm::LogError ("EcalPedOffset") << "No digis found in the event!";
00177   
00178 }
00179 
00180 
00181 // -----------------------------------------------------------------------------
00182 
00183 
00184 void EcalPedOffset::readDACs(edm::Handle<EBDigiCollection> pDigis,
00185                              std::map<int,int> DACvalues)
00186 {
00187 
00188   // loop over the digis
00189   for (EBDigiCollection::const_iterator itdigi = pDigis->begin(); 
00190       itdigi != pDigis->end(); 
00191       ++itdigi)
00192   {
00193     int gainId = ((EBDataFrame)(*itdigi)).sample(0).gainId();
00194     EBDetId detId = EBDetId(itdigi->id());
00195     EcalElectronicsId elecId = ecalElectronicsMap_->getElectronicsId(detId);
00196     int FEDid = 600+elecId.dccId();
00197     int crystalId = detId.ic();
00198 
00199     //TODO: Behavior here
00200     if(DACvalues.find(FEDid)==DACvalues.end())
00201     {
00202       edm::LogError("EcalPedOffset")
00203         << "Error! EB DCCid of digi does not match any DCCid found in DCC headers" << FEDid;
00204     }
00205 
00206     if (!m_pedValues.count(FEDid))
00207     {
00208       LogDebug("EcalPedOffset") << "Inserting new TPedValues object for FED:" << FEDid;
00209       m_pedValues[FEDid] = new TPedValues(m_RMSmax,m_bestPed);
00210     }
00211 
00212     // loop over the samples
00213     for (int iSample = 0; iSample < EcalDataFrame::MAXSAMPLES; ++iSample) 
00214     {
00215       m_pedValues[FEDid]->insert(gainId,
00216           crystalId,
00217           DACvalues[FEDid],
00218           ((EBDataFrame)(*itdigi)).sample(iSample).adc(),
00219           crystalId);
00220     }
00221     
00222   } //end loop over digis
00223 }
00224 
00225 // -----------------------------------------------------------------------------
00226 
00227 
00228 void EcalPedOffset::readDACs(edm::Handle<EEDigiCollection> pDigis,
00229                              std::map<int,int> DACvalues)
00230 {
00231 
00232   // loop over the digis
00233   for (EEDigiCollection::const_iterator itdigi = pDigis->begin(); 
00234       itdigi != pDigis->end(); 
00235       ++itdigi)
00236   {
00237     int gainId = ((EEDataFrame)(*itdigi)).sample(0).gainId();
00238     //int gainId = itdigi->sample(0).gainId();
00239     EEDetId detId = EEDetId(itdigi->id());
00240     EcalElectronicsId elecId = ecalElectronicsMap_->getElectronicsId(detId);
00241     int FEDid = 600+elecId.dccId();
00242     int crystalId = 25*elecId.towerId()+5*elecId.stripId()+elecId.xtalId();
00243     int endcapCrystalId = 100*elecId.towerId()+5*(elecId.stripId()-1)+elecId.xtalId();
00244     
00245     //TODO: Behavior here
00246     if(DACvalues.find(FEDid)==DACvalues.end())
00247     {
00248       edm::LogError("EcalPedOffset")
00249         << "Error! EE DCCid of digi does not match any DCCid found in DCC headers: " << FEDid;
00250     }
00251 
00252     if (!m_pedValues.count(FEDid))
00253     {
00254       LogDebug("EcalPedOffset") << "Inserting new TPedValues object for FED:" << FEDid;
00255       m_pedValues[FEDid] = new TPedValues(m_RMSmax,m_bestPed);
00256     }
00257     
00258     // loop over the samples
00259     for (int iSample = 0; iSample < EcalDataFrame::MAXSAMPLES; ++iSample) 
00260     {
00261       m_pedValues[FEDid]->insert(gainId,
00262           crystalId,
00263           DACvalues[FEDid],
00264           ((EEDataFrame)(*itdigi)).sample(iSample).adc(),
00265           endcapCrystalId);
00266     }
00267     
00268   } //end loop over digis
00269 }
00270 
00271 // -----------------------------------------------------------------------------
00272 
00273 
00275 void EcalPedOffset::endJob () 
00276 {
00277   for (std::map<int,TPedValues*>::const_iterator smPeds = m_pedValues.begin ();
00278       smPeds != m_pedValues.end (); 
00279       ++smPeds)
00280   {
00281     m_pedResult[smPeds->first] = 
00282       new TPedResult ((smPeds->second)->terminate (m_DACmin, m_DACmax));
00283   } 
00284   edm::LogInfo ("EcalPedOffset") << " results map size " 
00285     << m_pedResult.size ();
00286   writeXMLFiles(m_xmlFile);
00287 
00288   if (m_plotting != '0') makePlots ();
00289   if (m_dbHostName != '0') writeDb ();       
00290 }
00291 
00292 
00293 // -----------------------------------------------------------------------------
00294 
00295 
00298 void EcalPedOffset::writeDb () 
00299 {
00300   LogDebug ("EcalPedOffset") << " entering writeDb ..." ;
00301 
00302   // connect to the database
00303   EcalCondDBInterface* DBconnection ;
00304   try
00305   {
00306     LogInfo("EcalPedOffset") << "Opening DB connection with TNS_ADMIN ...";
00307     DBconnection = new EcalCondDBInterface(m_dbName, m_dbUserName, m_dbPassword);
00308   } catch (std::runtime_error &e) {
00309     LogError("EcalPedOffset") << e.what();
00310     if ( m_dbHostName.size() != 0 )
00311     {
00312       try
00313       {
00314         LogInfo("EcalPedOffset") << "Opening DB connection without TNS_ADMIN ...";
00315         DBconnection = new EcalCondDBInterface(m_dbHostName, m_dbName, 
00316             m_dbUserName, m_dbPassword, m_dbHostPort);
00317       } catch (std::runtime_error &e) {
00318         LogError("EcalPedOffset") << e.what();
00319         return;
00320       }
00321     }
00322     else
00323       return;
00324   }
00325 
00326   // define the query for RunIOV to get the right place in the database
00327   RunTag runtag ;  
00328   LocationDef locdef ;
00329   RunTypeDef rundef ;
00330   locdef.setLocation (m_location);
00331 
00332   runtag.setGeneralTag ("PEDESTAL-OFFSET");
00333   rundef.setRunType ("PEDESTAL-OFFSET");
00334   //rundef.setRunType ("TEST");
00335   //runtag.setGeneralTag ("TEST");
00336 
00337   runtag.setLocationDef (locdef);
00338   runtag.setRunTypeDef (rundef);
00339 
00340 
00341   run_t run = m_run ; //FIXME dal config file
00342   //RunIOV runiov = DBconnection->fetchRunIOV (&runtag, run);
00343   RunIOV runiov = DBconnection->fetchRunIOV(m_location, run);
00344   
00345   // MonRunIOV
00346   MonVersionDef monverdef ;  
00347   monverdef.setMonitoringVersion ("test01");
00348   MonRunTag montag ;
00349   montag.setMonVersionDef (monverdef);
00350   montag.setGeneralTag ("CMSSW");
00351 
00352   subrun_t subrun = 1 ; //hardcoded!
00353 
00354   MonRunIOV moniov ;
00355 
00356   try{
00357     runtag = runiov.getRunTag();
00358     moniov = DBconnection->fetchMonRunIOV(&runtag, &montag, run, subrun);
00359   } 
00360   catch (std::runtime_error &e) {
00361     if(m_create_moniov){
00362       //if not already in the DB create a new MonRunIOV
00363       Tm startSubRun;
00364       startSubRun.setToCurrentGMTime();
00365       // setup the MonIOV
00366       moniov.setRunIOV(runiov);
00367       moniov.setSubRunNumber(subrun);
00368       moniov.setSubRunStart(startSubRun);
00369       moniov.setMonRunTag(montag);
00370       LogDebug ("EcalPedOffset") <<" creating a new MonRunIOV" ;
00371     }
00372     else{
00373       edm::LogError ("EcalPedOffset") << " no MonRunIOV existing in the DB" ;
00374       edm::LogError ("EcalPedOffset") << " the result will not be stored into the DB" ;
00375       if ( DBconnection ) {delete DBconnection;}
00376       return;
00377     }
00378   }
00379 
00380   // create the table to be filled and the map to be inserted
00381   EcalLogicID ecid ;
00382   std::map<EcalLogicID, MonPedestalOffsetsDat> DBdataset ;
00383   MonPedestalOffsetsDat DBtable ;
00384 
00385   // fill the table
00386 
00387   // loop over the super-modules
00388   for (std::map<int,TPedResult*>::const_iterator result = m_pedResult.begin ();
00389       result != m_pedResult.end ();
00390       ++result)
00391   {
00392     // loop over the crystals
00393     for (int xtal = 0 ; xtal<1700 ; ++xtal)
00394     {
00395       DBtable.setDACG1 (result->second->m_DACvalue[2][xtal]);
00396       DBtable.setDACG6 (result->second->m_DACvalue[1][xtal]);
00397       DBtable.setDACG12 (result->second->m_DACvalue[0][xtal]);
00398       DBtable.setTaskStatus (1); //FIXME to be set correctly
00399 
00400       // fill the table
00401       if ( DBconnection ) 
00402       {
00403         try 
00404         {
00405           int fedid = result->first;
00406           int eid = m_pedValues[fedid]->getCrystalNumber(xtal);
00407           // If eid is zero, that crystal was not present in digis
00408           if(eid==0)
00409             continue;
00410 
00411           if (fedid >= 601 && fedid <= 609)
00412           {
00413             // Add the FEDid part in for DB
00414             eid = eid+10000*(fedid-600);
00415             ecid = DBconnection->getEcalLogicID("EE_elec_crystal_number", eid);
00416           }
00417           else if (fedid >= 610 && fedid <= 627)
00418           {
00419             ecid = DBconnection->getEcalLogicID("EB_crystal_number", fedid-610+19,
00420                 eid);
00421           } 
00422           else if (fedid >= 628 && fedid <= 645)
00423           {
00424             ecid = DBconnection->getEcalLogicID("EB_crystal_number", fedid-628+1, 
00425                 eid);
00426           }
00427           else if (fedid >= 646 && fedid <= 654)
00428           {
00429             // Add the FEDid part in for DB
00430             eid = eid+10000*(fedid-600);
00431             ecid = DBconnection->getEcalLogicID("EE_elec_crystal_number", eid);
00432           }
00433           else
00434             LogError("EcalPedOffset") << "FEDid is out of range 601-654";
00435 
00436           DBdataset[ecid] = DBtable ;
00437         } catch (std::runtime_error &e) {
00438           edm::LogError ("EcalPedOffset") << e.what();
00439         }
00440       }
00441     } // loop over the crystals
00442   } // loop over the super-modules
00443 
00444   // insert the map of tables in the database
00445   if ( DBconnection ) {
00446     try {
00447       LogDebug ("EcalPedOffset") << "Inserting dataset ... " << std::flush;
00448       if ( DBdataset.size() != 0 ) DBconnection->insertDataSet (&DBdataset, &moniov);
00449       LogDebug ("EcalPedOffset") << "done." ;
00450     } catch (std::runtime_error &e) {
00451       edm::LogError ("EcalPedOffset") << e.what ();
00452     }
00453   }
00454 
00455   if ( DBconnection ) {delete DBconnection;}
00456 }
00457 
00458 
00459 // -----------------------------------------------------------------------------
00460 
00461 
00463 void EcalPedOffset::writeXMLFiles(std::string fileName)
00464 {
00465   // loop over the super-modules
00466   for (std::map<int,TPedResult*>::const_iterator smRes = m_pedResult.begin();
00467       smRes != m_pedResult.end(); 
00468       ++smRes)
00469   {
00470     std::string thisSMFileName = fileName;
00471     // open the output stream
00472     thisSMFileName+="_";
00473     thisSMFileName+=intToString(smRes->first);
00474     thisSMFileName+=".xml";
00475     std::ofstream xml_outfile;
00476     xml_outfile.open(thisSMFileName.c_str());
00477 
00478     // write the header file
00479     xml_outfile<<"<offsets>"<<std::endl;
00480     xml_outfile << "<PEDESTAL_OFFSET_RELEASE VERSION_ID = \"SM1_VER1\"> \n";
00481     xml_outfile << "  <RELEASE_ID>RELEASE_1</RELEASE_ID>\n";
00482     xml_outfile << "  <SUPERMODULE>";
00483     xml_outfile << smRes->first;
00484     xml_outfile << "</SUPERMODULE>\n";
00485     xml_outfile << "  <TIME_STAMP> 070705 </TIME_STAMP>" << std::endl;
00486 
00487     // loop over the crystals
00488     for (int xtal = 0 ; xtal < 1700 ; ++xtal) 
00489     {
00490       int crystalNumber = m_pedValues[smRes->first]->getCrystalNumber(xtal);
00491       if(crystalNumber==0)
00492         continue;
00493       xml_outfile << "  <PEDESTAL_OFFSET>\n";
00494       xml_outfile << "    <HIGH>" << ((smRes->second)->m_DACvalue)[0][xtal] << "</HIGH>\n";
00495       xml_outfile << "    <MED>" << ((smRes->second)->m_DACvalue)[1][xtal] << "</MED>\n";
00496       xml_outfile << "    <LOW>" << ((smRes->second)->m_DACvalue)[2][xtal] << "</LOW>\n";
00497       xml_outfile << "    <CRYSTAL> "<< crystalNumber << " </CRYSTAL>\n";
00498       xml_outfile << "  </PEDESTAL_OFFSET>" << std::endl;            
00499     } 
00500 
00501     // close the open tags  
00502     xml_outfile << " </PEDESTAL_OFFSET_RELEASE>" << std::endl;
00503     xml_outfile << "</offsets>" << std::endl;
00504     xml_outfile.close ();
00505   } // loop over the super-modules
00506 
00507 
00508 }
00509 
00510 
00511 // -----------------------------------------------------------------------------
00512 
00513 
00515 void EcalPedOffset::makePlots () 
00516 {
00517   LogDebug ("EcalPedOffset") << " entering makePlots ..." ;
00518 
00519   edm::LogInfo ("EcalPedOffset") << " map size: " 
00520     << m_pedValues.size();
00521 
00522   // create the ROOT file
00523   m_plotting+=".root";
00524 
00525   TFile * rootFile = new TFile(m_plotting.c_str(),"RECREATE");
00526 
00527   // loop over the supermodules
00528   for (std::map<int,TPedValues*>::const_iterator smPeds = m_pedValues.begin();
00529       smPeds != m_pedValues.end(); 
00530       ++smPeds)
00531   {
00532     // make a folder in the ROOT file
00533     char folderName[120] ;
00534     sprintf (folderName,"FED%02d",smPeds->first);
00535     rootFile->mkdir(folderName);
00536     smPeds->second->makePlots(rootFile,folderName,m_maxSlopeAllowed_,
00537         m_minSlopeAllowed_,m_maxChi2OverNDFAllowed_);
00538   }
00539 
00540   rootFile->Close();
00541   delete rootFile;
00542 
00543   LogDebug ("EcalPedOffset") << " DONE"; 
00544 }
00545 
00546 // -----------------------------------------------------------------------------
00547 
00548 // convert an int to a string
00549 std::string EcalPedOffset::intToString(int num)
00550 {
00551 
00552   // outputs the number into the string stream and then flushes
00553   // the buffer (makes sure the output is put into the stream)
00554   std::ostringstream myStream;
00555   myStream << num << std::flush;
00556   return(myStream.str()); //returns the string form of the stringstream object
00557 }