CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/CalibFormats/SiStripObjects/src/SiStripDetCabling.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // Package:     SiStripObjects
00003 // Class  :     SiStripDetCabling
00004 // Original Author:  dkcira
00005 //         Created:  Wed Mar 22 12:24:33 CET 2006
00006 // $Id: SiStripDetCabling.cc,v 1.24 2011/09/16 13:49:22 demattia Exp $
00007 #include "FWCore/Utilities/interface/typelookup.h"
00008 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "DataFormats/SiStripDetId/interface/SiStripSubStructure.h"
00011 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00012 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00013 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00014 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00015 
00016 #include <iostream>
00017 
00018 //---- default constructor / destructor
00019 SiStripDetCabling::SiStripDetCabling() : fedCabling_(0) {}
00020 SiStripDetCabling::~SiStripDetCabling() {}
00021 
00022 //---- construct detector view (DetCabling) out of readout view (FedCabling)
00023 SiStripDetCabling::SiStripDetCabling(const SiStripFedCabling& fedcabling) : fullcabling_(), connected_(), detected_(), undetected_(), fedCabling_(&fedcabling)
00024 {
00025   // --- CONNECTED = have fedid and i2cAddr
00026   // create fullcabling_, loop over vector of FedChannelConnection, either make new element of map, or add to appropriate vector of existing map element
00027   // get feds list (vector) from fedcabling object - these are the active FEDs
00028   const std::vector<uint16_t>& feds = fedcabling.feds();
00029   std::vector<uint16_t>::const_iterator ifed;
00030   for ( ifed = feds.begin(); ifed != feds.end(); ifed++ ) { // iterate over active feds, get all their FedChannelConnection-s
00031     SiStripFedCabling::ConnsConstIterRange conns = fedcabling.fedConnections( *ifed );
00032     std::vector<FedChannelConnection>::const_iterator iconn;
00033     for ( iconn = conns.begin(); iconn != conns.end(); iconn++ ) { // loop over FedChannelConnection objects
00034       addDevices(*iconn, fullcabling_); // leave separate method, in case you will need to add devices also after constructing
00035       bool have_fed_id = iconn->fedId();
00036       std::vector<int> vector_of_connected_apvs;
00037       if(have_fed_id){ // these apvpairs are seen from the readout
00038         // there can be at most 6 APVs on one DetId: 0,1,2,3,4,5
00039         int which_apv_pair = iconn->apvPairNumber(); // APVPair (0,1) for 512 strips and (0,1,2) for 768 strips
00040         
00041         // patch needed to take into account invalid detids or apvPairs
00042         if( iconn->detId()==0 ||  
00043             iconn->detId() == sistrip::invalid32_ ||  
00044             iconn->apvPairNumber() == sistrip::invalid_  ||
00045             iconn->nApvPairs() == sistrip::invalid_ ) {
00046           continue;
00047         }
00048 
00049         if(iconn->i2cAddr(0)) vector_of_connected_apvs.push_back(2*which_apv_pair + 0); // first apv of the pair
00050         if(iconn->i2cAddr(1)) vector_of_connected_apvs.push_back(2*which_apv_pair + 1); // second apv of the pair
00051       }
00052       if(vector_of_connected_apvs.size() != 0){ // add only is smth. there, obviously
00053         std::map<uint32_t, std::vector<int> > map_of_connected_apvs;
00054         map_of_connected_apvs.insert(std::make_pair(iconn->detId(),vector_of_connected_apvs));
00055         addFromSpecificConnection(connected_, map_of_connected_apvs, 0);
00056       }
00057     }
00058   }
00059   // --- DETECTED = do not have fedid but have i2cAddr
00060   SiStripFedCabling::ConnsConstIterRange detected_fed_connections = fedcabling.detectedDevices();
00061   for(std::vector<FedChannelConnection>::const_iterator idtct = detected_fed_connections.begin(); idtct != detected_fed_connections.end(); idtct++){
00062     addDevices(*idtct, fullcabling_);
00063     bool have_fed_id = idtct->fedId();
00064     std::vector<int> vector_of_detected_apvs;
00065     if(! have_fed_id){
00066       int which_apv_pair = idtct->apvPairNumber(); // APVPair (0,1) for 512 strips and (0,1,2) for 768 strips
00067       if(idtct->i2cAddr(0)) vector_of_detected_apvs.push_back(2*which_apv_pair + 0); // first apv of the pair
00068       if(idtct->i2cAddr(1)) vector_of_detected_apvs.push_back(2*which_apv_pair + 1); // second apv of the pair
00069     }
00070     if(vector_of_detected_apvs.size() != 0){ // add only is smth. there, obviously
00071       std::map<uint32_t,std::vector<int> > map_of_detected_apvs;
00072       map_of_detected_apvs.insert(std::make_pair(idtct->detId(),vector_of_detected_apvs));
00073       addFromSpecificConnection(detected_, map_of_detected_apvs, 1);
00074     }
00075   }
00076   // --- UNDETECTED = have neither fedid nor i2caddr
00077   SiStripFedCabling::ConnsConstIterRange undetected_fed_connections = fedcabling.undetectedDevices();
00078   for(std::vector<FedChannelConnection>::const_iterator iudtct = undetected_fed_connections.begin(); iudtct != undetected_fed_connections.end(); iudtct++){
00079     addDevices(*iudtct, fullcabling_);
00080     bool have_fed_id = iudtct->fedId();
00081     std::vector<int> vector_of_undetected_apvs;
00082     if(! have_fed_id){
00083       int which_apv_pair = iudtct->apvPairNumber(); // APVPair (0,1) for 512 strips and (0,1,2) for 768 strips
00084       if(iudtct->i2cAddr(0)) vector_of_undetected_apvs.push_back(2*which_apv_pair + 0); // first apv of the pair
00085       if(iudtct->i2cAddr(1)) vector_of_undetected_apvs.push_back(2*which_apv_pair + 1); // second apv of the pair
00086     }
00087     if(vector_of_undetected_apvs.size() != 0){ // add only is smth. there, obviously
00088       std::map<uint32_t, std::vector<int> > map_of_undetected_apvs;
00089       map_of_undetected_apvs.insert(std::make_pair(iudtct->detId(),vector_of_undetected_apvs));
00090       addFromSpecificConnection(undetected_, map_of_undetected_apvs, 2);
00091     }
00092   }
00093 }
00094 
00095 //---- add to certain connections
00096 void SiStripDetCabling::addDevices( const FedChannelConnection& conn, 
00097                                     std::map< uint32_t, std::vector<const FedChannelConnection *> >& conns ){
00098   if( conn.detId() && conn.detId() != sistrip::invalid32_ &&  // check for valid detid
00099       conn.apvPairNumber() != sistrip::invalid_ ) {           // check for valid apv pair number
00100     if( conn.fedId()==0 || conn.fedId()==sistrip::invalid_ ){
00101       edm::LogInfo("") << " SiStripDetCabling::addDevices for connection associated to detid " << conn.detId() << " apvPairNumber " << conn.apvPairNumber() << "the fedId is " << conn.fedId();
00102       return;
00103     }
00104     // check cached vector size is sufficient
00105     // if not, resize
00106     if( conn.apvPairNumber() >= conns[conn.detId()].size() ) {
00107       conns[conn.detId()].resize( conn.apvPairNumber()+1 );
00108     }
00109     // add latest connection object
00110     conns[conn.detId()][conn.apvPairNumber()] = &conn;
00111   }
00112 }
00113 
00114 //----
00115 void SiStripDetCabling::addDevices(const FedChannelConnection & conn){ // by default add to fullcabling_ connections - special case of above class
00116   addDevices(conn, fullcabling_ ); // add to fullcabling_
00117 }
00118 
00119 //---- get vector of connected modules. replaces getActiveDetectorRawIds method - avoid use of static
00120 void SiStripDetCabling::addActiveDetectorsRawIds(std::vector<uint32_t> & vector_to_fill_with_detids ) const{
00121   for(std::map< uint32_t, std::vector<int> >::const_iterator conn_it = connected_.begin(); conn_it!=connected_.end(); conn_it++){
00122     vector_to_fill_with_detids.push_back(conn_it->first);
00123   }
00124   // no elements added to vector_to_fill_with_detids is empty connected_
00125 }
00126 
00127 //---- get vector of all modules.
00128 void SiStripDetCabling::addAllDetectorsRawIds(std::vector<uint32_t> & vector_to_fill_with_detids ) const{
00129   for(std::map< uint32_t, std::vector<int> >::const_iterator conn_it = connected_.begin(); conn_it!=connected_.end(); conn_it++){
00130     vector_to_fill_with_detids.push_back(conn_it->first);
00131   }
00132   for(std::map< uint32_t, std::vector<int> >::const_iterator conn_it = detected_.begin(); conn_it!=detected_.end(); conn_it++){
00133     vector_to_fill_with_detids.push_back(conn_it->first);
00134   }
00135   for(std::map< uint32_t, std::vector<int> >::const_iterator conn_it = undetected_.begin(); conn_it!=undetected_.end(); conn_it++){
00136     vector_to_fill_with_detids.push_back(conn_it->first);
00137   }
00138   // no elements added to vector_to_fill_with_detids is empty connected_, detected_.begin and undetected_.begin
00139 }
00140 
00141 //----
00142 const std::vector<const FedChannelConnection *>& SiStripDetCabling::getConnections(uint32_t det_id ) const{ // return all connections corresponding to one det_id
00143   std::map< uint32_t, std::vector<const FedChannelConnection *> >::const_iterator detcabl_it = fullcabling_.find(det_id); // has to be const_iterator because this function cannot change data members
00144   if( ! (detcabl_it==fullcabling_.end()) ){  // found detid in fullcabling_
00145     return ( detcabl_it->second );
00146   }else{ // DKwarn : is there need for output message here telling det_id does not exist?
00147     static std::vector<const FedChannelConnection *> default_empty_fedchannelconnection;
00148     return default_empty_fedchannelconnection;
00149   }
00150 }
00151 
00152 //----
00153 const FedChannelConnection& SiStripDetCabling::getConnection( uint32_t det_id, unsigned short apv_pair ) const{
00154   const std::vector<const FedChannelConnection *>& fcconns = getConnections(det_id);
00155   for(std::vector<const FedChannelConnection *>::const_iterator iconn = fcconns.begin(); iconn!=fcconns.end();iconn++){
00156     if ( ((*iconn) != 0) && (((*iconn)->apvPairNumber()) == apv_pair) ) { // check if apvPairNumber() of present FedChannelConnection is the same as requested one
00157       return (**iconn); // if yes, return the FedChannelConnection object
00158     }
00159   }
00160   // if did not match none of the above, return some default value - DKwarn : also output message?
00161   static FedChannelConnection default_empty_fedchannelconnection;
00162   return default_empty_fedchannelconnection;
00163 }
00164 
00165 //----
00166 const unsigned int SiStripDetCabling::getDcuId( uint32_t det_id ) const{
00167   const std::vector<const FedChannelConnection *>& fcconns = getConnections( det_id );
00168   if(fcconns.size()!=0) {
00169     // patch needed to take into account the possibility that the first component of fcconns is invalid
00170     for(size_t i=0;i<fcconns.size();++i)
00171       if (fcconns.at(i)->detId() != sistrip::invalid32_ && fcconns.at(i)->detId() != 0 )
00172         return ( fcconns.at(i) )->dcuId(); // get dcuId of first element - when you build check this consistency
00173   }
00174   // default if none of the above is fulfilled
00175   unsigned int default_zero_value = 0;
00176   return default_zero_value;
00177 }
00178 
00179 //---- one can find the nr of apvs from fullcabling_ -> std::vector<FedChannelConnection> -> size * 2
00180 const uint16_t SiStripDetCabling::nApvPairs(uint32_t det_id) const{
00181   const std::vector<const FedChannelConnection *>& fcconns = getConnections( det_id );
00182   if(fcconns.size()!=0) {
00183     // patch needed to take into account the possibility that the first component of fcconns is invalid
00184     for(size_t i=0;i<fcconns.size();++i) {
00185       if ( (fcconns.at(i) != 0) && (fcconns.at(i)->nApvPairs() != sistrip::invalid_) ) {
00186         return fcconns.at(i)->nApvPairs(); // nr of apvpairs for associated module
00187       }
00188     }
00189   }
00190   // else {
00191   //   return 0;
00192   // }
00193   return 0;
00194 }
00195 
00196 //---- map of detector to list of APVs for APVs seen from FECs and FEDs
00197 void SiStripDetCabling::addConnected ( std::map<uint32_t, std::vector<int> > & map_to_add_to) const{
00198   addFromSpecificConnection(map_to_add_to, connected_);
00199 }
00200 
00201 //--- map of detector to list of APVs for APVs seen neither from FECS or FEDs
00202 void SiStripDetCabling::addDetected( std::map<uint32_t, std::vector<int> > & map_to_add_to) const{
00203   addFromSpecificConnection(map_to_add_to, detected_);
00204 }
00205 
00206 //---- map of detector to list of APVs for APVs seen neither from FECS or FEDs
00207 void SiStripDetCabling::addUnDetected( std::map<uint32_t, std::vector<int> > & map_to_add_to) const{
00208   addFromSpecificConnection(map_to_add_to, undetected_);
00209 }
00210 
00211 //----  map of detector to list of APVs that are not connected - combination of addDetected and addUnDetected
00212 void SiStripDetCabling::addNotConnectedAPVs( std::map<uint32_t, std::vector<int> > & map_to_add_to) const{
00213   addFromSpecificConnection(map_to_add_to, detected_);
00214   addFromSpecificConnection(map_to_add_to, undetected_);
00215 }
00216 
00217 //----
00218 void SiStripDetCabling::addFromSpecificConnection( std::map<uint32_t, std::vector<int> > & map_to_add_to,
00219                                                    const std::map< uint32_t, std::vector<int> > & specific_connection,
00220                                                    const int connectionType ) const {
00221   for(std::map< uint32_t, std::vector<int> >::const_iterator conn_it = specific_connection.begin(); conn_it!=specific_connection.end(); ++conn_it){
00222     uint32_t new_detid = conn_it->first;
00223     std::vector<int> new_apv_vector = conn_it->second;
00224     std::map<uint32_t, std::vector<int> >::iterator it = map_to_add_to.find(new_detid);
00225     if( it == map_to_add_to.end() ){ // detid does not exist in map, add new entry
00226       std::sort(new_apv_vector.begin(),new_apv_vector.end()); // not very efficient sort, time consuming?
00227       map_to_add_to.insert(std::make_pair(new_detid,new_apv_vector));
00228 
00229       // Count the number of detIds per layer. Doing it in this "if" we count each detId only once
00230       // (otherwise it would be counted once per APV pair)
00231       // ATTENTION: consider changing the loop content to avoid this
00232       // This is the expected full number of modules (double sided are counted twice because the two
00233       // sides have different detId).
00234       // TIB1 : 336, TIB2 : 432, TIB3 : 540, TIB4 : 648
00235       // TID : each disk has 48+48+40 (ring1+ring2+ring3)
00236       // TOB1 : 504, TOB2 : 576, TOB3 : 648, TOB4 : 720, TOB5 : 792, TOB6 : 888
00237       // TEC1 : Total number of modules = 6400.
00238       if( connectionType != -1 ) {
00239         connectionCount[connectionType][layerSearch(new_detid)]++;
00240       }
00241     }else{                    // detid exists already, add to its vector - if its not there already . . .
00242       std::vector<int> existing_apv_vector = it->second;
00243       for(std::vector<int>::iterator inew = new_apv_vector.begin(); inew != new_apv_vector.end(); inew++ ){
00244         bool there_already = false;
00245         for(std::vector<int>::iterator iold = existing_apv_vector.begin(); iold != existing_apv_vector.end(); iold++){
00246           if (*iold == *inew){
00247             there_already = true;
00248             break; // leave the loop
00249           }
00250         }
00251         if( ! there_already ){
00252           existing_apv_vector.push_back(*inew);
00253           std::sort(existing_apv_vector.begin(),existing_apv_vector.end()); // not very efficient sort, time consuming?
00254         }else{
00255           //edm::LogWarning("Logical") << "apv "<<*inew<<" already exists in the detector module "<<new_detid;
00256         }
00257       }
00258     }
00259   }
00260 }
00261 
00262 int16_t SiStripDetCabling::layerSearch( const uint32_t detId ) const
00263 {
00264   if(SiStripDetId(detId).subDetector()==SiStripDetId::TIB){
00265     TIBDetId D(detId);
00266     return D.layerNumber();
00267   } else if (SiStripDetId(detId).subDetector()==SiStripDetId::TID){
00268     TIDDetId D(detId);
00269     // side: 1 = negative, 2 = positive
00270     return 10+(D.side() -1)*3 + D.wheel();
00271   } else if (SiStripDetId(detId).subDetector()==SiStripDetId::TOB){
00272     TOBDetId D(detId);
00273     return 100+D.layerNumber();
00274   } else if (SiStripDetId(detId).subDetector()==SiStripDetId::TEC){
00275     TECDetId D(detId);
00276     // side: 1 = negative, 2 = positive
00277     return 1000+(D.side() -1)*9 + D.wheel();
00278   }
00279   return 0;
00280 }
00281 
00283 uint32_t SiStripDetCabling::detNumber(const std::string & subDet, const uint16_t layer, const int connectionType) const {
00284   uint16_t subDetLayer = layer;
00285   // TIB = 1, TID = 2, TOB = 3, TEC = 4
00286   if( subDet == "TID-" ) subDetLayer += 10;
00287   else if( subDet == "TID+" ) subDetLayer += 10 + 3;
00288   else if( subDet == "TOB" ) subDetLayer += 100;
00289   else if( subDet == "TEC-" ) subDetLayer += 1000;
00290   else if( subDet == "TEC+" ) subDetLayer += 1000 + 9;
00291   else if( subDet != "TIB" ) {
00292     LogDebug("SiStripDetCabling") << "Error: Wrong subDet. Please use one of TIB, TID, TOB, TEC." << std::endl;
00293     return 0;
00294   }
00295   return connectionCount[connectionType][subDetLayer];
00296 }
00297 
00298 //---- map of all connected, detected, undetected to contiguous Ids - map reset first!
00299 void SiStripDetCabling::getAllDetectorsContiguousIds(std::map<uint32_t, unsigned int>& allToContiguous) const{
00300   allToContiguous.clear(); // reset map
00301   std::vector<uint32_t> all; addAllDetectorsRawIds(all); std::sort(all.begin(), all.end()); // get all detids and sort them
00302   unsigned int contiguousIndex = 0;
00303   for(std::vector<uint32_t>::const_iterator idet = all.begin(); idet!= all.end(); ++idet){
00304      ++contiguousIndex;
00305      allToContiguous.insert(std::make_pair(*idet,contiguousIndex)); 
00306   }
00307 }
00308 
00309 //---- map of all connected - map reset first!
00310 void SiStripDetCabling::getActiveDetectorsContiguousIds(std::map<uint32_t, unsigned int>& connectedToContiguous) const{
00311   connectedToContiguous.clear(); // reset map
00312   std::vector<uint32_t> connected; addAllDetectorsRawIds(connected); std::sort(connected.begin(), connected.end()); // get connected detids and sort them (not strictly necessary)
00313   std::map<uint32_t, unsigned int> allToContiguous; getAllDetectorsContiguousIds(allToContiguous); // create map of all indices
00314   for(std::vector<uint32_t>::const_iterator idet = connected.begin(); idet!= connected.end(); ++idet){ // select only the indices for active detectors
00315     std::map<uint32_t, unsigned int>::iterator deco = allToContiguous.find(*idet);
00316     if(deco!=allToContiguous.end()){
00317        connectedToContiguous.insert(*deco);
00318     }
00319   }
00320 }
00321 
00322 bool SiStripDetCabling::IsConnected(const uint32_t& det_id) const {
00323   return IsInMap(det_id,connected_);
00324 }
00325 
00326 bool SiStripDetCabling::IsDetected(const uint32_t& det_id) const {
00327   return IsInMap(det_id,detected_);
00328 }
00329 bool SiStripDetCabling::IsUndetected(const uint32_t& det_id) const{
00330   return IsInMap(det_id,undetected_);
00331 }
00332 bool SiStripDetCabling::IsInMap(const uint32_t& det_id, const std::map<uint32_t, std::vector<int> > & map) const{
00333   std::map< uint32_t, std::vector<int> >::const_iterator it=map.find(det_id);
00334   return (it!=map.end());
00335 }
00336 
00337 // -----------------------------------------------------------------------------
00339 void SiStripDetCabling::print( std::stringstream& ss ) const {
00340   uint32_t valid = 0;
00341   uint32_t total = 0;
00342   typedef std::vector<const FedChannelConnection *> Conns;
00343   typedef std::map<uint32_t,Conns> ConnsMap;
00344   ConnsMap::const_iterator ii = fullcabling_.begin();
00345   ConnsMap::const_iterator jj = fullcabling_.end();
00346   ss << "[SiStripDetCabling::" << __func__ << "]"
00347      << " Printing DET cabling for " << fullcabling_.size()
00348      << " modules " << std::endl;
00349   for ( ; ii != jj; ++ii ) {
00350     ss << "Printing " << ii->second.size()
00351        << " connections for DetId: " << ii->first << std::endl;
00352     Conns::const_iterator iii = ii->second.begin();
00353     Conns::const_iterator jjj = ii->second.end();
00354     for ( ; iii != jjj; ++iii ) { 
00355       if ( (*iii)->isConnected() ) { valid++; }
00356       total++;
00357       ss << **iii << std::endl;
00358     }
00359   }
00360   ss << "Number of connected:   " << valid << std::endl
00361      << "Number of connections: " << total << std::endl;
00362 }
00363 
00364 void SiStripDetCabling::printSummary(std::stringstream& ss) const {
00365   for( int connectionType = 0; connectionType < 3; ++connectionType ) {
00366     if( connectionType == 0 ) ss << "Connected modules:" << std::endl;
00367     else if( connectionType == 1 ) ss << "Detected modules:" << std::endl;
00368     else ss << "Undetected modules:" << std::endl;
00369     ss << "SubDet and layer\t modules" << std::endl;
00370     std::map< int16_t, uint32_t >::const_iterator iter = connectionCount[connectionType].begin();
00371     for( ; iter != connectionCount[connectionType].end(); ++iter ) {
00372       uint32_t subDetLayer = iter->first;
00373       uint32_t modules = iter->second;
00374       if( int(subDetLayer/10) == 0 ) {
00375         ss << "TIB \t layer " << subDetLayer << " \t" << modules << std::endl;
00376       }
00377       else if( int(subDetLayer/100) == 0 ) {
00378         int layer = subDetLayer%10;
00379         if( layer <= 3 ) ss << "TID- \t disk  " << layer << "\t" << modules << std::endl;
00380         else ss << "TID+ \t disk  " << layer-3 << "\t" << modules << std::endl;
00381       }
00382       else if( int(subDetLayer/1000) == 0 ) {
00383         int layer = subDetLayer%100;
00384         ss << "TOB \t layer " << layer << " \t" << modules << std::endl;
00385       }
00386       else {
00387         int layer = subDetLayer%100;
00388         if( layer <= 9 ) ss << "TEC- \t disk  " << layer << " \t" << modules << std::endl;
00389         else ss << "TEC+ \t disk  " << layer-9 << " \t" << modules << std::endl;
00390       }
00391     }
00392   }
00393 }
00394 
00395 void SiStripDetCabling::printDebug(std::stringstream& ss) const {
00396   print(ss);
00397 }