Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:58:18

0001 // -*- C++ -*-
0002 // Package:     SiStripObjects
0003 // Class  :     SiStripDetCabling
0004 // Original Author:  dkcira
0005 //         Created:  Wed Mar 22 12:24:33 CET 2006
0006 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
0007 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0008 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/Utilities/interface/typelookup.h"
0011 
0012 #include <iostream>
0013 
0014 //---- default constructor / destructor
0015 SiStripDetCabling::SiStripDetCabling(const TrackerTopology *const topology) : fedCabling_(nullptr), tTopo(topology) {}
0016 SiStripDetCabling::~SiStripDetCabling() {}
0017 
0018 //---- construct detector view (DetCabling) out of readout view (FedCabling)
0019 SiStripDetCabling::SiStripDetCabling(const SiStripFedCabling &fedcabling, const TrackerTopology *const topology)
0020     : fullcabling_(), connected_(), detected_(), undetected_(), fedCabling_(&fedcabling), tTopo(topology) {
0021   // --- CONNECTED = have fedid and i2cAddr
0022   // create fullcabling_, loop over vector of FedChannelConnection, either make
0023   // new element of map, or add to appropriate vector of existing map element
0024   // get feds list (vector) from fedcabling object - these are the active FEDs
0025   auto feds = fedcabling.fedIds();
0026   for (auto ifed = feds.begin(); ifed != feds.end(); ifed++) {  // iterate over active feds, get all their
0027                                                                 // FedChannelConnection-s
0028     SiStripFedCabling::ConnsConstIterRange conns = fedcabling.fedConnections(*ifed);
0029     for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {  // loop over FedChannelConnection objects
0030       addDevices(*iconn,
0031                  fullcabling_);  // leave separate method, in case you will need
0032                                  // to add devices also after constructing
0033       bool have_fed_id = iconn->fedId();
0034       std::vector<int> vector_of_connected_apvs;
0035       if (have_fed_id) {  // these apvpairs are seen from the readout
0036         // there can be at most 6 APVs on one DetId: 0,1,2,3,4,5
0037         int which_apv_pair = iconn->apvPairNumber();  // APVPair (0,1) for 512 strips and (0,1,2)
0038                                                       // for 768 strips
0039 
0040         // patch needed to take into account invalid detids or apvPairs
0041         if (iconn->detId() == 0 || iconn->detId() == sistrip::invalid32_ ||
0042             iconn->apvPairNumber() == sistrip::invalid_ || iconn->nApvPairs() == sistrip::invalid_) {
0043           continue;
0044         }
0045 
0046         if (iconn->i2cAddr(0))
0047           vector_of_connected_apvs.push_back(2 * which_apv_pair + 0);  // first apv of the pair
0048         if (iconn->i2cAddr(1))
0049           vector_of_connected_apvs.push_back(2 * which_apv_pair + 1);  // second apv of the pair
0050       }
0051       if (!vector_of_connected_apvs.empty()) {  // add only is smth. there, obviously
0052         std::map<uint32_t, std::vector<int>> map_of_connected_apvs;
0053         map_of_connected_apvs.insert(std::make_pair(iconn->detId(), vector_of_connected_apvs));
0054         addFromSpecificConnection(connected_, map_of_connected_apvs, &(connectionCount[0]));
0055       }
0056     }
0057   }
0058   // --- DETECTED = do not have fedid but have i2cAddr
0059   SiStripFedCabling::ConnsConstIterRange detected_fed_connections = fedcabling.detectedDevices();
0060   for (std::vector<FedChannelConnection>::const_iterator idtct = detected_fed_connections.begin();
0061        idtct != detected_fed_connections.end();
0062        ++idtct) {
0063     addDevices(*idtct, fullcabling_);
0064     bool have_fed_id = idtct->fedId();
0065     std::vector<int> vector_of_detected_apvs;
0066     if (!have_fed_id) {
0067       int which_apv_pair = idtct->apvPairNumber();  // APVPair (0,1) for 512 strips and (0,1,2)
0068                                                     // for 768 strips
0069       if (idtct->i2cAddr(0))
0070         vector_of_detected_apvs.push_back(2 * which_apv_pair + 0);  // first apv of the pair
0071       if (idtct->i2cAddr(1))
0072         vector_of_detected_apvs.push_back(2 * which_apv_pair + 1);  // second apv of the pair
0073     }
0074     if (!vector_of_detected_apvs.empty()) {  // add only is smth. there, obviously
0075       std::map<uint32_t, std::vector<int>> map_of_detected_apvs;
0076       map_of_detected_apvs.insert(std::make_pair(idtct->detId(), vector_of_detected_apvs));
0077       addFromSpecificConnection(detected_, map_of_detected_apvs, &(connectionCount[1]));
0078     }
0079   }
0080   // --- UNDETECTED = have neither fedid nor i2caddr
0081   SiStripFedCabling::ConnsConstIterRange undetected_fed_connections = fedcabling.undetectedDevices();
0082   for (std::vector<FedChannelConnection>::const_iterator iudtct = undetected_fed_connections.begin();
0083        iudtct != undetected_fed_connections.end();
0084        ++iudtct) {
0085     addDevices(*iudtct, fullcabling_);
0086     bool have_fed_id = iudtct->fedId();
0087     std::vector<int> vector_of_undetected_apvs;
0088     if (!have_fed_id) {
0089       int which_apv_pair = iudtct->apvPairNumber();  // APVPair (0,1) for 512 strips and (0,1,2)
0090                                                      // for 768 strips
0091       if (iudtct->i2cAddr(0))
0092         vector_of_undetected_apvs.push_back(2 * which_apv_pair + 0);  // first apv of the pair
0093       if (iudtct->i2cAddr(1))
0094         vector_of_undetected_apvs.push_back(2 * which_apv_pair + 1);  // second apv of the pair
0095     }
0096     if (!vector_of_undetected_apvs.empty()) {  // add only is smth. there, obviously
0097       std::map<uint32_t, std::vector<int>> map_of_undetected_apvs;
0098       map_of_undetected_apvs.insert(std::make_pair(iudtct->detId(), vector_of_undetected_apvs));
0099       addFromSpecificConnection(undetected_, map_of_undetected_apvs, &(connectionCount[2]));
0100     }
0101   }
0102 }
0103 
0104 //---- add to certain connections
0105 void SiStripDetCabling::addDevices(const FedChannelConnection &conn,
0106                                    std::map<uint32_t, std::vector<const FedChannelConnection *>> &conns) {
0107   if (conn.detId() && conn.detId() != sistrip::invalid32_ &&  // check for valid detid
0108       conn.apvPairNumber() != sistrip::invalid_) {            // check for valid apv pair number
0109     if (conn.fedId() == 0 || conn.fedId() == sistrip::invalid_) {
0110       edm::LogInfo("") << " SiStripDetCabling::addDevices for connection "
0111                           "associated to detid "
0112                        << conn.detId() << " apvPairNumber " << conn.apvPairNumber() << "the fedId is " << conn.fedId();
0113       return;
0114     }
0115     // check cached vector size is sufficient
0116     // if not, resize
0117     if (conn.apvPairNumber() >= conns[conn.detId()].size()) {
0118       conns[conn.detId()].resize(conn.apvPairNumber() + 1);
0119     }
0120     // add latest connection object
0121     conns[conn.detId()][conn.apvPairNumber()] = &conn;
0122   }
0123 }
0124 
0125 //----
0126 void SiStripDetCabling::addDevices(
0127     const FedChannelConnection &conn) {  // by default add to fullcabling_ connections - special case of
0128                                          // above class
0129   addDevices(conn, fullcabling_);        // add to fullcabling_
0130 }
0131 
0132 //---- get vector of connected modules. replaces getActiveDetectorRawIds method
0133 //- avoid use of static
0134 void SiStripDetCabling::addActiveDetectorsRawIds(std::vector<uint32_t> &vector_to_fill_with_detids) const {
0135   for (std::map<uint32_t, std::vector<int>>::const_iterator conn_it = connected_.begin(); conn_it != connected_.end();
0136        ++conn_it) {
0137     vector_to_fill_with_detids.push_back(conn_it->first);
0138   }
0139   // no elements added to vector_to_fill_with_detids is empty connected_
0140 }
0141 
0142 //---- get vector of all modules.
0143 void SiStripDetCabling::addAllDetectorsRawIds(std::vector<uint32_t> &vector_to_fill_with_detids) const {
0144   for (std::map<uint32_t, std::vector<int>>::const_iterator conn_it = connected_.begin(); conn_it != connected_.end();
0145        ++conn_it) {
0146     vector_to_fill_with_detids.push_back(conn_it->first);
0147   }
0148   for (std::map<uint32_t, std::vector<int>>::const_iterator conn_it = detected_.begin(); conn_it != detected_.end();
0149        ++conn_it) {
0150     vector_to_fill_with_detids.push_back(conn_it->first);
0151   }
0152   for (std::map<uint32_t, std::vector<int>>::const_iterator conn_it = undetected_.begin(); conn_it != undetected_.end();
0153        ++conn_it) {
0154     vector_to_fill_with_detids.push_back(conn_it->first);
0155   }
0156   // no elements added to vector_to_fill_with_detids is empty connected_,
0157   // detected_.begin and undetected_.begin
0158 }
0159 
0160 //----
0161 const std::vector<const FedChannelConnection *> &SiStripDetCabling::getConnections(
0162     uint32_t det_id) const {  // return all connections corresponding to one det_id
0163   std::map<uint32_t, std::vector<const FedChannelConnection *>>::const_iterator detcabl_it =
0164       fullcabling_.find(det_id);              // has to be const_iterator because this
0165                                               // function cannot change data members
0166   if (!(detcabl_it == fullcabling_.end())) {  // found detid in fullcabling_
0167     return (detcabl_it->second);
0168   } else {  // DKwarn : is there need for output message here telling det_id does
0169             // not exist?
0170     const static std::vector<const FedChannelConnection *> default_empty_fedchannelconnection;
0171     return default_empty_fedchannelconnection;
0172   }
0173 }
0174 
0175 //----
0176 const FedChannelConnection &SiStripDetCabling::getConnection(uint32_t det_id, unsigned short apv_pair) const {
0177   const std::vector<const FedChannelConnection *> &fcconns = getConnections(det_id);
0178   for (std::vector<const FedChannelConnection *>::const_iterator iconn = fcconns.begin(); iconn != fcconns.end();
0179        ++iconn) {
0180     if (((*iconn) != nullptr) && (((*iconn)->apvPairNumber()) == apv_pair)) {  // check if apvPairNumber() of present
0181       // FedChannelConnection is the same as requested one
0182       return (**iconn);  // if yes, return the FedChannelConnection object
0183     }
0184   }
0185   // if did not match none of the above, return some default value - DKwarn :
0186   // also output message?
0187   const static FedChannelConnection default_empty_fedchannelconnection;
0188   return default_empty_fedchannelconnection;
0189 }
0190 
0191 //----
0192 const unsigned int SiStripDetCabling::getDcuId(uint32_t det_id) const {
0193   const std::vector<const FedChannelConnection *> &fcconns = getConnections(det_id);
0194   if (!fcconns.empty()) {
0195     // patch needed to take into account the possibility that the first
0196     // component of fcconns is invalid
0197     for (size_t i = 0; i < fcconns.size(); ++i)
0198       if (fcconns.at(i) && fcconns.at(i)->detId() != sistrip::invalid32_ && fcconns.at(i)->detId() != 0)
0199         return (fcconns.at(i))->dcuId();  // get dcuId of first element - when
0200                                           // you build check this consistency
0201   }
0202   // default if none of the above is fulfilled
0203   unsigned int default_zero_value = 0;
0204   return default_zero_value;
0205 }
0206 
0207 //---- one can find the nr of apvs from fullcabling_ ->
0208 // std::vector<FedChannelConnection> -> size * 2
0209 const uint16_t SiStripDetCabling::nApvPairs(uint32_t det_id) const {
0210   const std::vector<const FedChannelConnection *> &fcconns = getConnections(det_id);
0211   if (!fcconns.empty()) {
0212     // patch needed to take into account the possibility that the first
0213     // component of fcconns is invalid
0214     for (size_t i = 0; i < fcconns.size(); ++i) {
0215       if ((fcconns.at(i) != nullptr) && (fcconns.at(i)->nApvPairs() != sistrip::invalid_)) {
0216         return fcconns.at(i)->nApvPairs();  // nr of apvpairs for associated module
0217       }
0218     }
0219   }
0220   // else {
0221   //   return 0;
0222   // }
0223   return 0;
0224 }
0225 
0226 //---- map of detector to list of APVs for APVs seen from FECs and FEDs
0227 void SiStripDetCabling::addConnected(std::map<uint32_t, std::vector<int>> &map_to_add_to) const {
0228   addFromSpecificConnection(map_to_add_to, connected_);
0229 }
0230 
0231 //--- map of detector to list of APVs for APVs seen neither from FECS or FEDs
0232 void SiStripDetCabling::addDetected(std::map<uint32_t, std::vector<int>> &map_to_add_to) const {
0233   addFromSpecificConnection(map_to_add_to, detected_);
0234 }
0235 
0236 //---- map of detector to list of APVs for APVs seen neither from FECS or FEDs
0237 void SiStripDetCabling::addUnDetected(std::map<uint32_t, std::vector<int>> &map_to_add_to) const {
0238   addFromSpecificConnection(map_to_add_to, undetected_);
0239 }
0240 
0241 //----  map of detector to list of APVs that are not connected - combination of
0242 // addDetected and addUnDetected
0243 void SiStripDetCabling::addNotConnectedAPVs(std::map<uint32_t, std::vector<int>> &map_to_add_to) const {
0244   addFromSpecificConnection(map_to_add_to, detected_);
0245   addFromSpecificConnection(map_to_add_to, undetected_);
0246 }
0247 
0248 //----
0249 void SiStripDetCabling::addFromSpecificConnection(std::map<uint32_t, std::vector<int>> &map_to_add_to,
0250                                                   const std::map<uint32_t, std::vector<int>> &specific_connection,
0251                                                   std::map<int16_t, uint32_t> *connectionsToFill) const {
0252   for (std::map<uint32_t, std::vector<int>>::const_iterator conn_it = specific_connection.begin();
0253        conn_it != specific_connection.end();
0254        ++conn_it) {
0255     uint32_t new_detid = conn_it->first;
0256     std::vector<int> new_apv_vector = conn_it->second;
0257     std::map<uint32_t, std::vector<int>>::iterator it = map_to_add_to.find(new_detid);
0258     if (it == map_to_add_to.end()) {  // detid does not exist in map, add new entry
0259       std::sort(new_apv_vector.begin(),
0260                 new_apv_vector.end());  // not very efficient sort, time consuming?
0261       map_to_add_to.insert(std::make_pair(new_detid, new_apv_vector));
0262 
0263       // Count the number of detIds per layer. Doing it in this "if" we count
0264       // each detId only once (otherwise it would be counted once per APV pair)
0265       // ATTENTION: consider changing the loop content to avoid this
0266       // This is the expected full number of modules (double sided are counted
0267       // twice because the two sides have different detId). TIB1 : 336, TIB2 :
0268       // 432, TIB3 : 540, TIB4 : 648 TID : each disk has 48+48+40
0269       // (ring1+ring2+ring3) TOB1 : 504, TOB2 : 576, TOB3 : 648, TOB4 : 720,
0270       // TOB5 : 792, TOB6 : 888 TEC1 : Total number of modules = 6400.
0271       if (connectionsToFill) {
0272         (*connectionsToFill)[layerSearch(new_detid)]++;
0273       }
0274 
0275     } else {  // detid exists already, add to its vector - if its not there
0276               // already . . .
0277       std::vector<int> existing_apv_vector = it->second;
0278       for (std::vector<int>::iterator inew = new_apv_vector.begin(); inew != new_apv_vector.end(); ++inew) {
0279         bool there_already = false;
0280         for (std::vector<int>::iterator iold = existing_apv_vector.begin(); iold != existing_apv_vector.end(); ++iold) {
0281           if (*iold == *inew) {
0282             there_already = true;
0283             break;  // leave the loop
0284           }
0285         }
0286         if (!there_already) {
0287           existing_apv_vector.push_back(*inew);
0288           std::sort(existing_apv_vector.begin(),
0289                     existing_apv_vector.end());  // not very efficient sort, time consuming?
0290         } else {
0291           // edm::LogWarning("Logical") << "apv "<<*inew<<" already exists in
0292           // the detector module "<<new_detid;
0293         }
0294       }
0295     }
0296   }
0297 }
0298 
0299 int16_t SiStripDetCabling::layerSearch(const uint32_t detId) const {
0300   const DetId detectorId = DetId(detId);
0301   const int subdet = detectorId.subdetId();
0302   if (subdet == StripSubdetector::TIB) {
0303     return tTopo->layer(detId);
0304   } else if (subdet == StripSubdetector::TID) {
0305     // side: 1 = negative, 2 = positive
0306     return 10 + (tTopo->side(detId) - 1) * 3 + tTopo->layer(detId);
0307   } else if (subdet == StripSubdetector::TOB) {
0308     return 100 + tTopo->layer(detId);
0309   } else if (subdet == StripSubdetector::TEC) {
0310     // side: 1 = negative, 2 = positive
0311     return 1000 + (tTopo->side(detId) - 1) * 9 + tTopo->layer(detId);
0312   }
0313   return 0;
0314 }
0315 
0316 /// Return the number of modules for the specified subDet, layer and
0317 /// connectionType.
0318 uint32_t SiStripDetCabling::detNumber(const std::string &subDet, const uint16_t layer, const int connectionType) const {
0319   uint16_t subDetLayer = layer;
0320   // TIB = 1, TID = 2, TOB = 3, TEC = 4
0321   if (subDet == "TID-")
0322     subDetLayer += 10;
0323   else if (subDet == "TID+")
0324     subDetLayer += 10 + 3;
0325   else if (subDet == "TOB")
0326     subDetLayer += 100;
0327   else if (subDet == "TEC-")
0328     subDetLayer += 1000;
0329   else if (subDet == "TEC+")
0330     subDetLayer += 1000 + 9;
0331   else if (subDet != "TIB") {
0332     LogDebug("SiStripDetCabling") << "Error: Wrong subDet. Please use one of TIB, TID, TOB, TEC." << std::endl;
0333     return 0;
0334   }
0335   auto found = connectionCount[connectionType].find(subDetLayer);
0336   if (found != connectionCount[connectionType].end()) {
0337     return found->second;
0338   }
0339   return 0;
0340 }
0341 
0342 //---- map of all connected, detected, undetected to contiguous Ids - map reset
0343 // first!
0344 void SiStripDetCabling::getAllDetectorsContiguousIds(std::map<uint32_t, unsigned int> &allToContiguous) const {
0345   allToContiguous.clear();  // reset map
0346   std::vector<uint32_t> all;
0347   addAllDetectorsRawIds(all);
0348   std::sort(all.begin(), all.end());  // get all detids and sort them
0349   unsigned int contiguousIndex = 0;
0350   for (std::vector<uint32_t>::const_iterator idet = all.begin(); idet != all.end(); ++idet) {
0351     ++contiguousIndex;
0352     allToContiguous.insert(std::make_pair(*idet, contiguousIndex));
0353   }
0354 }
0355 
0356 //---- map of all connected - map reset first!
0357 void SiStripDetCabling::getActiveDetectorsContiguousIds(std::map<uint32_t, unsigned int> &connectedToContiguous) const {
0358   connectedToContiguous.clear();  // reset map
0359   std::vector<uint32_t> connected;
0360   addAllDetectorsRawIds(connected);
0361   std::sort(connected.begin(),
0362             connected.end());  // get connected detids and sort them (not
0363                                // strictly necessary)
0364   std::map<uint32_t, unsigned int> allToContiguous;
0365   getAllDetectorsContiguousIds(allToContiguous);  // create map of all indices
0366   for (std::vector<uint32_t>::const_iterator idet = connected.begin(); idet != connected.end();
0367        ++idet) {  // select only the indices for active detectors
0368     std::map<uint32_t, unsigned int>::iterator deco = allToContiguous.find(*idet);
0369     if (deco != allToContiguous.end()) {
0370       connectedToContiguous.insert(*deco);
0371     }
0372   }
0373 }
0374 
0375 bool SiStripDetCabling::IsConnected(const uint32_t &det_id) const { return IsInMap(det_id, connected_); }
0376 
0377 bool SiStripDetCabling::IsDetected(const uint32_t &det_id) const { return IsInMap(det_id, detected_); }
0378 bool SiStripDetCabling::IsUndetected(const uint32_t &det_id) const { return IsInMap(det_id, undetected_); }
0379 bool SiStripDetCabling::IsInMap(const uint32_t &det_id, const std::map<uint32_t, std::vector<int>> &map) const {
0380   std::map<uint32_t, std::vector<int>>::const_iterator it = map.find(det_id);
0381   return (it != map.end());
0382 }
0383 
0384 // -----------------------------------------------------------------------------
0385 /** Added missing print method. */
0386 void SiStripDetCabling::print(std::stringstream &ss) const {
0387   uint32_t valid = 0;
0388   uint32_t total = 0;
0389   typedef std::vector<const FedChannelConnection *> Conns;
0390   typedef std::map<uint32_t, Conns> ConnsMap;
0391   ConnsMap::const_iterator ii = fullcabling_.begin();
0392   ConnsMap::const_iterator jj = fullcabling_.end();
0393   ss << "[SiStripDetCabling::" << __func__ << "]"
0394      << " Printing DET cabling for " << fullcabling_.size() << " modules " << std::endl;
0395   for (; ii != jj; ++ii) {
0396     ss << "Printing " << ii->second.size() << " connections for DetId: " << ii->first << std::endl;
0397     Conns::const_iterator iii = ii->second.begin();
0398     Conns::const_iterator jjj = ii->second.end();
0399     for (; iii != jjj; ++iii) {
0400       if ((*iii)->isConnected()) {
0401         valid++;
0402       }
0403       total++;
0404       ss << **iii << std::endl;
0405     }
0406   }
0407   ss << "Number of connected:   " << valid << std::endl << "Number of connections: " << total << std::endl;
0408 }
0409 
0410 void SiStripDetCabling::printSummary(std::stringstream &ss, const TrackerTopology *trackerTopo) const {
0411   for (int connectionType = 0; connectionType < 3; ++connectionType) {
0412     if (connectionType == 0)
0413       ss << "Connected modules:" << std::endl;
0414     else if (connectionType == 1)
0415       ss << "Detected modules:" << std::endl;
0416     else
0417       ss << "Undetected modules:" << std::endl;
0418     ss << "SubDet and layer\t modules" << std::endl;
0419     std::map<int16_t, uint32_t>::const_iterator iter = connectionCount[connectionType].begin();
0420     for (; iter != connectionCount[connectionType].end(); ++iter) {
0421       uint32_t subDetLayer = iter->first;
0422       uint32_t modules = iter->second;
0423       if (int(subDetLayer / 10) == 0) {
0424         ss << "TIB \t layer " << subDetLayer << " \t" << modules << std::endl;
0425       } else if (int(subDetLayer / 100) == 0) {
0426         int layer = subDetLayer % 10;
0427         if (layer <= 3)
0428           ss << "TID- \t disk  " << layer << "\t" << modules << std::endl;
0429         else
0430           ss << "TID+ \t disk  " << layer - 3 << "\t" << modules << std::endl;
0431       } else if (int(subDetLayer / 1000) == 0) {
0432         int layer = subDetLayer % 100;
0433         ss << "TOB \t layer " << layer << " \t" << modules << std::endl;
0434       } else {
0435         int layer = subDetLayer % 100;
0436         if (layer <= 9)
0437           ss << "TEC- \t disk  " << layer << " \t" << modules << std::endl;
0438         else
0439           ss << "TEC+ \t disk  " << layer - 9 << " \t" << modules << std::endl;
0440       }
0441     }
0442   }
0443 }
0444 
0445 void SiStripDetCabling::printDebug(std::stringstream &ss, const TrackerTopology * /*trackerTopo*/) const { print(ss); }