CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2_patch1/src/CalibTracker/SiStripDCS/src/SiStripPsuDetIdMap.cc

Go to the documentation of this file.
00001 #include "CalibTracker/SiStripDCS/interface/SiStripPsuDetIdMap.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include "FWCore/ParameterSet/interface/ParameterSetfwd.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 #include "FWCore/ServiceRegistry/interface/Service.h"
00007 
00008 #include "OnlineDB/SiStripConfigDb/interface/SiStripConfigDb.h"
00009 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00010 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
00011 #include <cstdlib>
00012 #include <iostream>
00013 #include <iomanip>
00014 #include <sstream>
00015 #include <string>
00016 
00017 using namespace sistrip;
00018 
00019 // only one constructor
00020 SiStripPsuDetIdMap::SiStripPsuDetIdMap() { LogTrace("SiStripPsuDetIdMap") << "[SiStripPsuDetIdMap::" << __func__ << "] Constructing ..."; }
00021 // destructor
00022 SiStripPsuDetIdMap::~SiStripPsuDetIdMap() {LogTrace("SiStripPsuDetIdMap") << "[SiStripPsuDetIdMap::" << __func__ << "] Destructing ..."; }
00023 
00024 // Build PSU-DETID map
00025 void SiStripPsuDetIdMap::BuildMap( const std::string & mapFile, const bool debug )
00026 {
00027   BuildMap(mapFile, debug, LVMap, HVMap, HVUnmapped_Map, HVCrosstalking_Map);
00028 }
00029 
00030 void SiStripPsuDetIdMap::BuildMap( const std::string & mapFile, std::vector<std::pair<uint32_t,std::string> > & rawmap) {
00031   //This method is a remnant of the old method, that provided a vector type of map, based on the 
00032   //raw reading of a file, with no processing.
00033   //FIXME:
00034   //This is not currently used, but I think we could slim this down to just a vector with 
00035   //the detIDs since the PSUChannel part of the excludedlist (if it ever is in a file) is never used!
00036   edm::FileInPath file(mapFile.c_str());
00037   ifstream ifs( file.fullPath().c_str() );
00038   string line;
00039   while( getline( ifs, line ) ) {
00040     if( line != "" ) {
00041       // split the line and insert in the map
00042       stringstream ss(line);
00043       string PSUChannel;
00044       uint32_t detId;
00045       ss >> detId;
00046       ss >> PSUChannel;
00047       rawmap.push_back(std::make_pair(detId, PSUChannel) );
00048     }
00049   }
00050 }
00051 
00052 //The following is the currently used method (called from SiStripDetVOffBuilder::buildPSUdetIdMap)
00053 void SiStripPsuDetIdMap::BuildMap( const std::string & mapFile, const bool debug, PsuDetIdMap & LVmap, PsuDetIdMap & HVmap,PsuDetIdMap & HVUnmappedmap,PsuDetIdMap & HVCrosstalkingmap ) //Maybe it would be nicer to return the map instead of using a reference...
00054 {
00055   //This method reads the map from the mapfile indicated in the cfg
00056   //It populates the 4 maps (private data members of the SiStripPSUDetIdMap in question) (all maps are std::map<std::string,uint32_t > ):
00057   //LVMap
00058   //HVMap
00059   //HVUnmapped_Map
00060   //HVCrosstalking_Map
00061   //These maps are accessed, based on the LV/HV case, to extract the detIDs connected to a given PSUChannel... 
00062   //see the getDetIDs method...
00063   edm::FileInPath file(mapFile.c_str());
00064   ifstream ifs( file.fullPath().c_str() );
00065   string line;
00066   while( getline( ifs, line ) ) {
00067     if( line != "" ) {
00068       // split the line and insert in the map
00069       stringstream ss(line);
00070       string PSUChannel;
00071       uint32_t detId;
00072       ss >> detId;
00073       ss >> PSUChannel;
00074       //Old "vector of pairs" map!
00075       //map.push_back( std::make_pair(detId, dpName) );//This "map" is normally the pgMap of the map of which we are executing BuildMap()...
00076       //Using a map to make the look-up easy and avoid lots of lookup loops.
00077       std::string PSU=PSUChannel.substr(0,PSUChannel.size()-10);
00078       std::string Channel=PSUChannel.substr(PSUChannel.size()-10);
00079       LVmap[PSU].push_back(detId); // LVmap uses simply the PSU since there is no channel distinction necessary
00080       if (Channel=="channel000") {
00081         HVUnmappedmap[PSU].push_back(detId); //Populate HV Unmapped map, by PSU listing all detids unmapped in that PSU (not necessarily all will be unmapped)
00082       }
00083       else if (Channel=="channel999") {
00084         HVCrosstalkingmap[PSU].push_back(detId); //Populate HV Crosstalking map, by PSU listing all detids crosstalking in that PSU (usually all will be unmapped)
00085       }
00086       else {
00087         HVmap[PSUChannel].push_back(detId); //HV map for HV mapped channels, populated by PSU channel!
00088       }
00089     }
00090   }
00091   
00092   //Remove duplicates for all 4 maps
00093   for (PsuDetIdMap::iterator psu = LVMap.begin(); psu != LVMap.end(); psu++) {
00094     RemoveDuplicateDetIDs(psu->second);
00095   }
00096   for (PsuDetIdMap::iterator psuchan = HVMap.begin(); psuchan != HVMap.end(); psuchan++) {
00097     RemoveDuplicateDetIDs(psuchan->second);
00098   }
00099   for (PsuDetIdMap::iterator psu = HVUnmapped_Map.begin(); psu != HVUnmapped_Map.end(); psu++) {
00100     RemoveDuplicateDetIDs(psu->second);
00101   }
00102   for (PsuDetIdMap::iterator psu = HVCrosstalking_Map.begin(); psu != HVCrosstalking_Map.end(); psu++) {
00103     RemoveDuplicateDetIDs(psu->second);
00104   }
00105   if (debug) {
00106     //Print out all the 4 maps:
00107     std::cout<<"Dumping the LV map"<<std::endl;
00108     std::cout<<"PSU->detids"<<std::endl;
00109     for (PsuDetIdMap::iterator psu = LVMap.begin(); psu != LVMap.end(); psu++) {
00110       std::cout<<psu->first<<" corresponds to following detids"<<endl;
00111       for (unsigned int i=0; i<psu->second.size(); i++) {
00112         std::cout<<"\t\t"<<psu->second[i]<<std::endl;
00113       }
00114     }
00115     std::cout<<"Dumping the HV map for HV mapped channels"<<std::endl;
00116     std::cout<<"PSUChannel->detids"<<std::endl;
00117     for (PsuDetIdMap::iterator psuchan = HVMap.begin(); psuchan != HVMap.end(); psuchan++) {
00118       std::cout<<psuchan->first<<" corresponds to following detids"<<endl;
00119       for (unsigned int i=0; i<psuchan->second.size(); i++) {
00120         std::cout<<"\t\t"<<psuchan->second[i]<<std::endl;
00121       }
00122     }
00123     std::cout<<"Dumping the HV map for HV UNmapped channels"<<std::endl;
00124     std::cout<<"PSU->detids"<<std::endl;
00125     for (PsuDetIdMap::iterator psu = HVUnmapped_Map.begin(); psu != HVUnmapped_Map.end(); psu++) {
00126       std::cout<<psu->first<<" corresponds to following detids"<<endl;
00127       for (unsigned int i=0; i<psu->second.size(); i++) {
00128         std::cout<<"\t\t"<<psu->second[i]<<std::endl;
00129       }
00130     }
00131     std::cout<<"Dumping the HV map for HV Crosstalking channels"<<std::endl;
00132     std::cout<<"PSU->detids"<<std::endl;
00133     for (PsuDetIdMap::iterator psu = HVCrosstalking_Map.begin(); psu != HVCrosstalking_Map.end(); psu++) {
00134       std::cout<<psu->first<<" corresponds to following detids"<<endl;
00135       for (unsigned int i=0; i<psu->second.size(); i++) {
00136         std::cout<<"\t\t"<<psu->second[i]<<std::endl;
00137       }
00138     }
00139     //Could add here consistency checks against the list of detIDs for Strip or Pixels
00140     //Number of total detIDs LVMapped, HV Mapped, HVunmapped, HV crosstalking... 
00141   }
00142 }
00143 
00144 void SiStripPsuDetIdMap::RemoveDuplicateDetIDs(std::vector<uint32_t> & detids) {
00145   //Function to remove duplicates from a vector of detids
00146   if (!detids.empty()) { //Leave empty vector alone ;)
00147     std::sort(detids.begin(),detids.end());
00148     std::vector<uint32_t>::iterator it = std::unique(detids.begin(),detids.end());
00149     detids.resize( it - detids.begin() );
00150   }
00151 }
00152 
00153 std::vector<uint32_t> SiStripPsuDetIdMap::getLvDetID(std::string PSU) {
00154   //Function that returns a vector with all detids associated with a PSU 
00155   //(no channel information is saved in the map since it is not relevant for LV!)
00156   if (LVMap.find(PSU)!=LVMap.end()) {
00157     return LVMap[PSU];
00158   }
00159   else {
00160     std::vector<uint32_t> detids;
00161     return detids;
00162   }
00163 }
00164 
00165 void SiStripPsuDetIdMap::getHvDetID(std::string PSUChannel, std::vector<uint32_t> & ids, std::vector<uint32_t> & unmapped_ids, std::vector<uint32_t> & crosstalking_ids ) {
00166   //Function that (via reference parameters) populates ids, unmapped_ids, crosstalking_ids vectors of detids associated with a given PSU *HV* channel.
00167   if (HVMap.find(PSUChannel)!=HVMap.end()) {
00168     ids=HVMap[PSUChannel];
00169   }
00170   //Extract the PSU to check the unmapped and crosstalking maps too corresponding to this channel
00171   std::string PSU = PSUChannel.substr(0,PSUChannel.size()-10);
00172   if (HVUnmapped_Map.find(PSU)!=HVUnmapped_Map.end()) {
00173     unmapped_ids=HVUnmapped_Map[PSU];
00174   }
00175   if (HVCrosstalking_Map.find(PSU)!=HVCrosstalking_Map.end()) {
00176     crosstalking_ids=HVCrosstalking_Map[PSU];
00177   }
00178 }
00179 
00180 // This method needs to be updated once HV channel mapping is known
00181 // Currently, channel number is ignored for mapping purposes
00182 // check both PG and CG as the channels should be unique
00183 
00184 void SiStripPsuDetIdMap::getDetID(std::string PSUChannel,const bool debug,std::vector<uint32_t> & detids,std::vector<uint32_t> & unmapped_detids,std::vector<uint32_t> & crosstalking_detids ) {
00185   //This function takes as argument the PSUChannel (i.e. the dpname as it comes from the PVSS query, e.g. cms_trk_dcs_02:CAEN/CMS_TRACKER_SY1527_2/branchController05/easyCrate0/easyBoard12/channel001)
00186   //And it returns 3 vectors:
00187   //1-detids->all the detids positively matching the PSUChannel in question
00188   //2-unmapped_detids->the detids that are matching the PSU in question but that are not HV mapped
00189   //3-crosstalking_detids->the detids that are matching the PSU in question but exhibit the HV channel cross-talking behavior (they are ON as long as ANY of the 2 HV channels of the supply is ON, so they only go OFF when both channels are OFF)
00190   //The second and third vectors are only relevant for the HV case, when unmapped and cross-talking channels need further processing before being turned ON and OFF.
00191   
00192   std::string PSUChannelFromQuery = PSUChannel;
00193 
00194   //Get the channel to see if it is LV or HV, they will be treated differently
00195   std::string ChannelFromQuery=PSUChannelFromQuery.substr(PSUChannelFromQuery.size()-10);
00196   //Get the PSU from Query, to be used for LVMap and for the HVUnmapped and HVCrosstalking maps:
00197   std::string PSUFromQuery=PSUChannelFromQuery.substr(0,PSUChannelFromQuery.size()-10);
00198   if (debug) {
00199     //FIXME:
00200     //Should handle all the couts with MessageLogger!
00201     std::cout << "DPNAME from QUERY: "<<PSUChannelFromQuery<<", Channel: "<<ChannelFromQuery<<"PSU: "<<PSUFromQuery<<std::endl;
00202   }
00203 
00204   //First prepare the strings needed to do the matching of the PSUChannel from the query to the ones in the map
00205 
00206   //Handle the LV case first:
00207   if (ChannelFromQuery=="channel000" or ChannelFromQuery=="channel001") {
00208     //For LV channels we need to look for any detID that is reported either as channel000 (not HV mapped)
00209     //but also as channel002 and channel003 (if they are HV mapped), or as channel999 (if they are in a crosstalking PSU)
00210     //Get the PSU to do a PSU-only matching to get all detIDs connected to the LV channel:
00211     //Now loop over the map!
00212     //for (PsuDetIdMap::iterator iter = pgMap.begin(); iter != pgMap.end(); iter++) {
00213     //  std::string PSUFromMap = iter->second.substr(0,iter->second.size()-10);
00214     //  //Careful if you uncomment this cout: it prints 15148 lines when checking for 1 psu name match! (meant for debugging of course)
00215     //  //std::cout<<"Truncated DPNAME from MAP: "<<PSUFromMap<<std::endl;
00216     //  if (PSUFromQuery == PSUFromMap) {
00217     //    detids.push_back(iter->first); //And fill the detids vector with the all detids matching the PSU from the query!
00218     //  }
00219     //}
00220     //No need to loop over if we use an actual map!
00221     
00222     if (LVMap.find(PSUFromQuery)!=LVMap.end()) {
00223       detids=LVMap[PSUFromQuery];
00224     }
00225   }
00226   //Handle the HV case too:
00227   else if (ChannelFromQuery=="channel002" or ChannelFromQuery=="channel003") {
00228     //For the HV channel we need to look at the actual positive matching detIDs, 
00229     //but also to the unmapped one (channel000) and the crosstalking ones (channel999).
00230     //Assemble the corresponding channel000 (unmapped channels) replacing the last character in PSUChannelFromQuery:
00231     //  std::string ZeroedPSUChannelFromQuery= PSUChannelFromQuery;
00232     //  ZeroedPSUChannelFromQuery.replace(ZeroedPSUChannelFromQuery.size()-1,1,"0");
00233     //  //Same for channel999 for the crosstalking channels:
00234     //  //std::string NineNineNine='999';
00235     //  std::string NinedPSUChannelFromQuery= PSUChannelFromQuery;
00236     //  NinedPSUChannelFromQuery.replace(NinedPSUChannelFromQuery.size()-3,3,"999");
00237     //  //std::string NinedPSUChannelFromQuery= PSUChannelFromQuery.substr(0,PSUChannelFromQuery.size()-3);// + '999';
00238     //  //Now loop over the map!
00239     //  for (PsuDetIdMap::iterator iter = pgMap.begin(); iter != pgMap.end(); iter++) {
00240     //    std::string PSUChannelFromMap = iter->second;
00241     //    //Careful if you uncomment this cout: it prints 15148 lines when checking for 1 psu name match! (meant for debugging of course)
00242     //    //std::cout<<"Truncated DPNAME from MAP: "<<PSUFromMap<<std::endl;
00243     //    if (PSUChannelFromMap==PSUChannelFromQuery)  {
00244     //      detids.push_back(iter->first); //Fill the detids vector with the all detids matching the PSUChannel from the query!
00245     //    }
00246     //    if (PSUChannelFromMap==ZeroedPSUChannelFromQuery) {
00247     //          unmapped_detids.push_back(iter->first); //Fill the unmapped_detids vector with the all detids matching the channel000 for the PSU from the query!
00248     //          if (debug) { //BEWARE: this debug printouts can become very heavy! 1 print out per detID matched!
00249     //            std::cout<<"Matched one of the HV-UNMAPPED channels: "<<ZeroedPSUChannelFromQuery<<std::endl;
00250     //            std::cout<<"Corresponding to detID: "<<iter->first<<std::endl;
00251     //            //for (unsigned int i_nohvmap_detid=0;i_nohvmap_detid < iter->first.size();i_nohvmap_detid++) {
00252     //            //  cout<< iter->first[i_nohvmap_detid] << std::endl;
00253     //          }
00254     //    }
00255     //    if (PSUChannelFromMap==NinedPSUChannelFromQuery) {
00256     //          crosstalking_detids.push_back(iter->first); //Fill the crosstalking_detids vector with the all detids matching the channel999 for the PSU from the query!
00257     //    }
00258     //  }
00259     if (HVMap.find(PSUChannelFromQuery)!=HVMap.end()) {
00260       detids=HVMap[PSUChannelFromQuery];
00261     }
00262     else if (HVUnmapped_Map.find(PSUFromQuery)!=HVUnmapped_Map.end()) {
00263       unmapped_detids=HVUnmapped_Map[PSUFromQuery];
00264     }
00265     else if (HVCrosstalking_Map.find(PSUFromQuery)!=HVCrosstalking_Map.end()) {
00266       crosstalking_detids=HVCrosstalking_Map[PSUFromQuery];
00267     }
00268   }
00269   //  
00270   //  
00271   //  //With the new code above that makes use of the channel00X information in the map
00272   //  //we should no more need to remove duplicates by construction.
00273   //  //The following code was used when there was no channel information in the map, 
00274   //  //to elegantly eliminate duplicates.
00275   //  //We can now use it as a cross-check (still removing duplicates in case they happen, but writing a message out)
00276   //  
00277   //  // remove duplicates
00278   //  
00279   //  //First sort detIDs vector, so that duplicates will be consecutive
00280   //  if (!detids.empty()) {
00281   //    std::sort(detids.begin(),detids.end());
00282   //    //Then use the forward iterator unique from STD that basically removes all consecutive duplicates from the vector
00283   //    //and reports a forward iterator pointing to the new end of the sequence
00284   //    std::vector<uint32_t>::iterator it = std::unique(detids.begin(),detids.end());
00285   //    if (it!=detids.end()) {
00286   //      std::cout<<"ARGH! It seems we found duplicate detIDs in the map corresponding to this PSUChannel: "<<PSUChannelFromQuery<<std::endl;
00287   //      detids.resize( it - detids.begin() );
00288   //    }
00289   //    if (debug) {
00290   //      std::cout<<"Matched the following detIDs to PSU channel from query "<<PSUChannelFromQuery <<":"<<std::endl;
00291   //      for (std::vector<uint32_t>::iterator i_detid=detids.begin();i_detid!=detids.end(); i_detid++) {
00292   //    std::cout<<*i_detid<<std::endl;;
00293   //      }
00294   //    }
00295   //  }
00296   //  //Same for unmapped detIDs:
00297   //  if (!unmapped_detids.empty()) {
00298   //    std::sort(unmapped_detids.begin(),unmapped_detids.end());
00299   //    //Then use the forward iterator unique from STD that basically removes all consecutive duplicates from the vector
00300   //    //and reports a forward iterator pointing to the new end of the sequence
00301   //    std::vector<uint32_t>::iterator it = std::unique(unmapped_detids.begin(),unmapped_detids.end());
00302   //    if (it!=unmapped_detids.end()) {
00303   //      std::cout<<"ARGH! It seems we found duplicate unmapped_detids in the map corresponding to this PSUChannel: "<<PSUChannelFromQuery<<std::endl;
00304   //      unmapped_detids.resize( it - unmapped_detids.begin() );
00305   //    }
00306   //    if (debug) {
00307   //      std::cout<<"Matched the following unmapped_detids to PSU channel from query "<<PSUChannelFromQuery <<":"<<std::endl;
00308   //      for (std::vector<uint32_t>::iterator i_detid=unmapped_detids.begin();i_detid!=unmapped_detids.end(); i_detid++) {
00309   //    std::cout<<*i_detid<<std::endl;;
00310   //      }
00311   //    }
00312   //  }
00313   //  //Finally, same for crosstalking detIDs:
00314   //  if (!crosstalking_detids.empty()) {
00315   //    std::sort(crosstalking_detids.begin(),crosstalking_detids.end());
00316   //    //Then use the forward iterator unique from STD that basically removes all consecutive duplicates from the vector
00317   //    //and reports a forward iterator pointing to the new end of the sequence
00318   //    std::vector<uint32_t>::iterator it = std::unique(crosstalking_detids.begin(),crosstalking_detids.end());
00319   //    if (it!=crosstalking_detids.end()) {
00320   //      std::cout<<"ARGH! It seems we found duplicate crosstalking_detids in the map corresponding to this PSUChannel: "<<PSUChannelFromQuery<<std::endl;
00321   //      crosstalking_detids.resize( it - crosstalking_detids.begin() );
00322   //    }
00323   //    if (debug) {
00324   //      std::cout<<"Matched the following crosstalking_detids to PSU channel from query "<<PSUChannelFromQuery <<":"<<std::endl;
00325   //      for (std::vector<uint32_t>::iterator i_detid=crosstalking_detids.begin();i_detid!=crosstalking_detids.end(); i_detid++) {
00326   //    std::cout<<*i_detid<<std::endl;;
00327   //      }
00328   //    }
00329   //  }
00330   //  
00331   //  //Using reference parameters since we are returning multiple objects.
00332   //  //return detids;
00333 
00334 }
00335 
00336 // returns PSU channel name for a given DETID
00337 std::string SiStripPsuDetIdMap::getPSUName(uint32_t detid) {
00338   std::vector< std::pair<uint32_t, std::string> >::iterator iter;
00339   for (iter = pgMap.begin(); iter != pgMap.end(); iter++) {
00340     if (iter->first && iter->first == detid) {return iter->second;}
00341   }
00342   // if we reach here, then we didn't find the detid in the map
00343   return "UNKNOWN";
00344 }
00345 
00346 std::string SiStripPsuDetIdMap::getPSUName(uint32_t detid, std::string group) {
00347   std::vector< std::pair<uint32_t, std::string> >::iterator iter;
00348   if (group == "PG") {
00349     for (iter = pgMap.begin(); iter != pgMap.end(); iter++) {
00350       if (iter->first && iter->first == detid) {return iter->second;}
00351     }
00352   }
00353   if (group == "CG") {
00354     for (iter = cgMap.begin(); iter != cgMap.end(); iter++) {
00355       if (iter->first && iter->first == detid) {return iter->second;}
00356     }
00357   }
00358   // if we reach here, then we didn't find the detid in the map
00359   return "UNKNOWN";
00360 }
00361 
00362 // returns the PVSS name for a given DETID
00363 std::string SiStripPsuDetIdMap::getDetectorLocation(uint32_t detid) {
00364   for (unsigned int i = 0; i < pgMap.size(); i++) {
00365     if (pgMap[i].first == detid) {return detectorLocations[i];}
00366   }
00367   return "UNKNOWN";
00368 }
00369 
00370 // returns the PVSS name for a given DETID, depending on specified map
00371 std::string SiStripPsuDetIdMap::getDetectorLocation(uint32_t detid, std::string group) {
00372   if (group == "PG") {
00373     for (unsigned int i = 0; i < pgMap.size(); i++) {
00374       if (pgMap[i].first == detid) {return detectorLocations[i];}
00375     }
00376   }
00377   if (group == "CG") {
00378     for (unsigned int i = 0; i < cgMap.size(); i++) {
00379       if (cgMap[i].first == detid) {return controlLocations[i];}
00380     }
00381   }
00382   return "UNKNOWN";
00383 }
00384 
00385 // returns the PVSS name for a given PSU channel
00386 std::string SiStripPsuDetIdMap::getDetectorLocation(std::string PSUChannel) {
00387   for (unsigned int i = 0; i < pgMap.size(); i++) {
00388     if (pgMap[i].second == PSUChannel) {return detectorLocations[i];}
00389   }
00390   for (unsigned int i = 0; i < cgMap.size(); i++) {
00391     if (cgMap[i].second == PSUChannel) {return controlLocations[i];}
00392   }
00393   return "UNKNOWN";
00394 }
00395 
00396 // returns the DCU ID for a given PSU channel
00397 uint32_t SiStripPsuDetIdMap::getDcuId(std::string PSUChannel) {
00398   for (unsigned int i = 0; i < pgMap.size(); i++) {
00399     if (pgMap[i].second == PSUChannel) {return dcuIds[i];}
00400   }
00401   for (unsigned int i = 0; i < cgMap.size(); i++) {
00402     if (cgMap[i].second == PSUChannel) {return cgDcuIds[i];}
00403   }
00404   return 0;
00405 }
00406 
00407 uint32_t SiStripPsuDetIdMap::getDcuId(uint32_t detid) {
00408   for (unsigned int i = 0; i < pgMap.size(); i++) {
00409     if (pgMap[i].first == detid) {return dcuIds[i];}
00410   }
00411   return 0;
00412 }
00413 
00414 // determine if a given PSU channel is HV or not
00415 int SiStripPsuDetIdMap::IsHVChannel(std::string PSUChannel) {
00416   // isHV = 0 means LV, = 1 means HV, = -1 means error
00417   int isHV = 0;
00418   std::string::size_type loc = PSUChannel.find( "channel", 0 );
00419   if (loc != std::string::npos) {
00420     std::string chNumber = PSUChannel.substr(loc+7,3);
00421     if (chNumber == "002" || chNumber == "003") {
00422       isHV = 1;
00423     } else if (chNumber == "000" || chNumber == "001") {
00424       isHV = 0;
00425     } else {
00426       edm::LogWarning("SiStripPsuDetIdMap") << "[SiStripPsuDetIdMap::" << __func__ << "] channel number of unexpected format, setting error flag!";
00427       isHV = -1;
00428     }
00429   } else {
00430     edm::LogWarning("SiStripPsuDetIdMap") << "[SiStripPsuDetIdMap::" << __func__ << "] channel number not located in PSU channel name, setting error flag!";
00431     isHV = -1;
00432   }
00433   return isHV;
00434 }
00435 
00436 void SiStripPsuDetIdMap::clone(DcuPsuVector &input, DcuPsuVector &output) {
00437   output.clear();
00438   for (unsigned int i = 0; i < input.size(); i++) {
00439     output.push_back(new TkDcuPsuMap(*(input[i])));
00440   }
00441 }
00442 
00443 void SiStripPsuDetIdMap::printMap() {
00444   stringstream pg;
00445   pg << "Map of power supplies to DET IDs: " << std::endl
00446      << "-- PSU name --          -- Det Id --" << std::endl;
00447   for (unsigned int p = 0; p < pgMap.size(); p++) {
00448     pg << pgMap[p].first << "         " << pgMap[p].second << std::endl;
00449   }
00450   edm::LogInfo("SiStripPsuDetIdMap") << "[SiStripPsuDetIdMap::" << __func__ << "] " << pg.str();
00451 }
00452 
00453 void SiStripPsuDetIdMap::printControlMap() {
00454   stringstream cg;
00455   cg << "Map of control power supplies to DET IDs: " << std::endl
00456      << "-- PSU name --                -- Det Id --" << std::endl;
00457   for (unsigned int p = 0; p < cgMap.size(); p++) {
00458     cg << cgMap[p].first << "         " << cgMap[p].second << std::endl;
00459   }
00460   edm::LogInfo("SiStripPsuDetIdMap") << "[SiStripPsuDetIdMap::" << __func__ << "] " << cg.str();
00461 }
00462 
00463 std::vector< std::pair<uint32_t, std::string> > SiStripPsuDetIdMap::getDcuPsuMap() {
00464   if (pgMap.size() != 0) { return pgMap; }
00465   std::vector< std::pair<uint32_t, std::string> > emptyVec;
00466   return emptyVec;
00467 }
00468 
00469 void SiStripPsuDetIdMap::checkMapInputValues(SiStripConfigDb::DcuDetIdsV dcuDetIds_, DcuPsuVector dcuPsus_) {
00470   std::cout << "Number of entries in DCU-PSU map:    " << dcuPsus_.size() << std::endl;
00471   std::cout << "Number of entries in DCU-DETID map:  " << dcuDetIds_.size() << std::endl;
00472   std::cout << std::endl;
00473   
00474   std::vector<bool> ddUsed(dcuDetIds_.size(),false);
00475   std::vector<bool> dpUsed(dcuPsus_.size(),false);
00476 
00477   for (unsigned int dp = 0; dp < dcuPsus_.size(); dp++) {
00478     for (unsigned int dd = 0; dd < dcuDetIds_.size(); dd++) {
00479       if (dcuPsus_[dp]->getDcuHardId() == dcuDetIds_[dd].second->getDcuHardId()) {
00480         dpUsed[dp] = true;
00481         ddUsed[dd] = true;
00482       }
00483     }
00484   }
00485   unsigned int numDpUsed = 0, numDpNotUsed = 0;
00486   for (unsigned int dp = 0; dp < dpUsed.size(); dp++) {
00487     if (dpUsed[dp]) { numDpUsed++; }
00488     else { numDpNotUsed++; }
00489   }
00490 
00491   std::cout << "Number of used DCU-PSU entries:   " << numDpUsed << std::endl;
00492   std::cout << "Number of unused DCU-PSU entries: " << numDpNotUsed << std::endl;
00493 
00494   unsigned int numDdUsed = 0, numDdNotUsed = 0;
00495   for (unsigned int dd = 0; dd < ddUsed.size(); dd++) {
00496     if (ddUsed[dd]) { numDdUsed++; }
00497     else { numDdNotUsed++; }
00498   }
00499 
00500   std::cout << "Number of used DCU-DETID entries:   " << numDdUsed << std::endl;
00501   std::cout << "Number of unused DCU-DETID entries: " << numDdNotUsed << std::endl;
00502   std::cout << std::endl;
00503   std::cout << "Size of PSU-DETID map:              " << pgMap.size() << std::endl;
00504   std::cout << "Size of detectorLocations:          " << detectorLocations.size() << std::endl;
00505 }
00506 
00507 //std::vector< std::pair<uint32_t, SiStripConfigDb::DeviceAddress> > SiStripPsuDetIdMap::retrieveDcuDeviceAddresses(std::string partition) {
00508 std::vector< std::pair< std::vector<uint16_t> , std::vector<uint32_t> > > SiStripPsuDetIdMap::retrieveDcuDeviceAddresses(std::string partition) {
00509   // get the DB parameters
00510   SiStripDbParams dbParams_ = db_->dbParams();
00511   SiStripDbParams::SiStripPartitions::const_iterator iter;
00512   
00513   std::vector< std::pair<uint32_t, SiStripConfigDb::DeviceAddress> > resultVec;
00514   
00515   SiStripConfigDb::DeviceDescriptionsV dcuDevices_;
00516   SiStripConfigDb::DeviceType device_ = DCU;
00517   
00518   for (iter = dbParams_.partitions().begin(); iter != dbParams_.partitions().end(); ++iter) {
00519     if ( partition == "" || partition == iter->second.partitionName() ) {
00520       if ( iter->second.partitionName() == SiStripPartition::defaultPartitionName_ ) { continue; }
00521       if (iter->second.dcuVersion().first > 0 && iter->second.fecVersion().first > 0) {
00522         SiStripConfigDb::DeviceDescriptionsRange range = db_->getDeviceDescriptions(device_,iter->second.partitionName());
00523         if (!range.empty()) {
00524           SiStripConfigDb::DeviceDescriptionsV nextVec( range.begin(), range.end() );
00525           for (unsigned int i = 0; i < nextVec.size(); i++) {
00526             dcuDescription * desc = dynamic_cast<dcuDescription *>(nextVec[i]);
00527             resultVec.push_back( std::make_pair( desc->getDcuHardId(), db_->deviceAddress(*(nextVec[i])) ) );
00528           }
00529         }
00530       }
00531     }
00532   }
00533 
00534   std::vector< std::pair< std::vector<uint16_t> , std::vector<uint32_t> > > testVec;
00535   std::vector< std::pair<uint32_t, SiStripConfigDb::DeviceAddress> >::iterator reorg_iter = resultVec.begin();
00536 
00537   for ( ; reorg_iter != resultVec.end(); reorg_iter++) {
00538     std::vector<uint16_t> fecInfo(4,0);
00539     fecInfo[0] = reorg_iter->second.fecCrate_;
00540     fecInfo[1] = reorg_iter->second.fecSlot_;
00541     fecInfo[2] = reorg_iter->second.fecRing_;
00542     fecInfo[3] = reorg_iter->second.ccuAddr_;
00543     std::vector<uint32_t> dcuids;
00544     std::vector< std::pair<uint32_t, SiStripConfigDb::DeviceAddress> >::iterator jter = reorg_iter;
00545     for ( ; jter != resultVec.end(); jter++) {
00546       if (reorg_iter->second.fecCrate_ == jter->second.fecCrate_ &&
00547           reorg_iter->second.fecSlot_ == jter->second.fecSlot_ &&
00548           reorg_iter->second.fecRing_ == jter->second.fecRing_ &&
00549           reorg_iter->second.ccuAddr_ == jter->second.ccuAddr_) {
00550         dcuids.push_back(jter->first);
00551       }
00552     }
00553     // handle duplicates
00554     bool isDup = false;
00555     for (unsigned int i = 0; i < testVec.size(); i++) {
00556       if (fecInfo == testVec[i].first) {
00557         isDup = true;
00558         dcuids.insert(dcuids.end(), (testVec[i].second).begin(), (testVec[i].second).end() );
00559         std::sort(dcuids.begin(),dcuids.end());
00560         std::vector<uint32_t>::iterator it = std::unique(dcuids.begin(),dcuids.end());
00561         dcuids.resize( it - dcuids.begin() );
00562         testVec[i].second = dcuids;
00563       }
00564     }
00565     if (!isDup) {
00566       std::sort(dcuids.begin(),dcuids.end());
00567       std::vector<uint32_t>::iterator it = std::unique(dcuids.begin(),dcuids.end());
00568       dcuids.resize( it - dcuids.begin() );
00569       testVec.push_back(std::make_pair(fecInfo,dcuids));
00570     }
00571   }
00572   //  return resultVec;
00573   return testVec;
00574 }
00575 
00576 std::vector<uint32_t> SiStripPsuDetIdMap::findDcuIdFromDeviceAddress(uint32_t dcuid_) {
00577   std::vector< std::pair< std::vector<uint16_t> , std::vector<uint32_t> > >::iterator iter = dcu_device_addr_vector.begin();
00578   std::vector< std::pair< std::vector<uint16_t> , std::vector<uint32_t> > >::iterator res_iter = dcu_device_addr_vector.end();
00579   std::vector<uint32_t> pgDcu;
00580 
00581   for ( ; iter != dcu_device_addr_vector.end(); iter++) {
00582     std::vector<uint32_t> dcuids = iter->second;
00583     std::vector<uint32_t>::iterator dcu_iter = std::find(dcuids.begin(),dcuids.end(),dcuid_);
00584     bool alreadyFound = false;
00585     if (res_iter != dcu_device_addr_vector.end()) {alreadyFound = true;}
00586     if (dcu_iter != dcuids.end()) {
00587       res_iter = iter;
00588       if (!alreadyFound) {
00589         for (unsigned int i = 0; i < dcuids.size(); i++) {
00590           if (dcuids[i] != dcuid_) {pgDcu.push_back(dcuids[i]);}
00591         }
00592       } else {
00593         std::cout << "Oh oh ... we have a duplicate :-(" << std::endl;
00594       }
00595     }
00596   }
00597   return pgDcu;
00598 }
00599 
00600