Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:54:23

0001 //-------------------------------------------------
0002 //
0003 //   Class: DTTSPhi.cpp
0004 //
0005 //   Description: Implementation of TS Phi trigger algorithm
0006 //
0007 //
0008 //   Author List:
0009 //   C. Grandi
0010 //   Modifications:
0011 //   jan02 - D.Bonacorsi/S.Marcellini
0012 //           improved algorithm for 2nd track handling in case of pile-up in TSM
0013 //           param: tsmgetcarryflag - value: 1 (default)
0014 //   feb04 - Implementation of sector collector related stuff(S. Marcellini)
0015 //   jan07 - C. Battilana local conf update
0016 //   mar07 - S. Vanini : parameters from DTConfigManager
0017 //
0018 //--------------------------------------------------
0019 
0020 #include "L1TriggerConfig/DTTPGConfig/interface/BitArray.h"
0021 
0022 //-----------------------
0023 // This Class's Header --
0024 //-----------------------
0025 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSPhi.h"
0026 
0027 //-------------------------------
0028 // Collaborating Class Headers --
0029 //-------------------------------
0030 #include "L1Trigger/DTTraco/interface/DTTracoCard.h"
0031 #include "L1Trigger/DTTraco/interface/DTTracoTrigData.h"
0032 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSCand.h"
0033 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSM.h"
0034 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSS.h"
0035 
0036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0037 
0038 //---------------
0039 // C++ Headers --
0040 //---------------
0041 #include <iostream>
0042 
0043 //----------------
0044 // Constructors --
0045 //----------------
0046 DTTSPhi::DTTSPhi(DTTrigGeom *geom, DTTracoCard *tracocard) : DTGeomSupplier(geom), _tracocard(tracocard) {
0047   // reserve the appropriate amount of space for vectors
0048   int i = 0;
0049   for (i = 0; i < DTConfigTSPhi::NSTEPL - DTConfigTSPhi::NSTEPF + 1; i++) {  // SM add + 1
0050     _tss[i].reserve(DTConfigTSPhi::NTSSTSM);
0051     // DBSM-doubleTSM
0052     _tsm[i].reserve(DTConfigTSPhi::NTSMD);
0053   }
0054 
0055   for (int is = 0; is < DTConfigTSPhi::NSTEPL - DTConfigTSPhi::NSTEPF + 1; is++) {
0056     // create DTTSSs
0057     for (int itss = 1; itss <= DTConfigTSPhi::NTSSTSM; itss++) {
0058       DTTSS *tss = new DTTSS(itss);
0059       _tss[is].push_back(tss);
0060     }
0061 
0062     // create DTTSMs     SM double TSM
0063     for (int itsmd = 1; itsmd <= DTConfigTSPhi::NTSMD; itsmd++) {
0064       DTTSM *tsm = new DTTSM(itsmd);
0065       _tsm[is].push_back(tsm);
0066     }
0067   }
0068 }
0069 
0070 //--------------
0071 // Destructor --
0072 //--------------
0073 DTTSPhi::~DTTSPhi() {
0074   std::vector<DTTSS *>::iterator ptss;
0075   std::vector<DTTSM *>::iterator ptsm;
0076   for (int is = 0; is < DTConfigTSPhi::NSTEPL - DTConfigTSPhi::NSTEPF + 1; is++) {
0077     // clear TSSs
0078     for (ptss = _tss[is].begin(); ptss != _tss[is].end(); ptss++) {
0079       delete (*ptss);
0080     }
0081     _tss[is].clear();
0082     // clear TSMs
0083     for (ptsm = _tsm[is].begin(); ptsm != _tsm[is].end(); ptsm++) {
0084       delete (*ptsm);
0085     }
0086     _tsm[is].clear();
0087   }
0088 
0089   localClear();
0090 
0091   // delete _config;
0092 }
0093 
0094 //--------------
0095 // Operations --
0096 //--------------
0097 
0098 void DTTSPhi::localClear() {
0099   for (int is = 0; is < DTConfigTSPhi::NSTEPL - DTConfigTSPhi::NSTEPF + 1; is++) {
0100     // clear buffer
0101     std::vector<DTTSCand *>::iterator p1;
0102     for (p1 = _tctrig[is].begin(); p1 != _tctrig[is].end(); p1++) {
0103       delete (*p1);
0104     }
0105     _tctrig[is].clear();
0106 
0107     std::vector<DTTSS *>::iterator ptss;
0108     for (ptss = _tss[is].begin(); ptss != _tss[is].end(); ptss++) {
0109       (*ptss)->clear();
0110     }
0111     // clear all DTTSM
0112     std::vector<DTTSM *>::iterator ptsm;
0113     for (ptsm = _tsm[is].begin(); ptsm != _tsm[is].end(); ptsm++) {
0114       (*ptsm)->clear();
0115     }
0116   }
0117 }
0118 
0119 void DTTSPhi::setConfig(const DTConfigManager *conf) {
0120   DTChamberId sid = ChamberId();
0121   _config = conf->getDTConfigTSPhi(sid);
0122 
0123   for (int is = 0; is < DTConfigTSPhi::NSTEPL - DTConfigTSPhi::NSTEPF + 1; is++) {
0124     // set TSS config
0125     std::vector<DTTSS *>::iterator ptss;
0126     for (ptss = _tss[is].begin(); ptss != _tss[is].end(); ptss++) {
0127       (*ptss)->setConfig(config());
0128     }
0129     // set TSM config
0130     std::vector<DTTSM *>::iterator ptsm;
0131     for (ptsm = _tsm[is].begin(); ptsm != _tsm[is].end(); ptsm++) {
0132       (*ptsm)->setConfig(config());
0133     }
0134   }
0135 }
0136 
0137 void DTTSPhi::loadTSPhi() {
0138   // clear DTTSSs and DTTSM
0139   localClear();
0140 
0141   if (config()->debug()) {
0142     edm::LogInfo("DTTSPhi") << "loadDTTSPhi called for wheel=" << wheel() << ", station=" << station()
0143                             << ", sector=" << sector();
0144   }
0145 
0146   // loop on all TRACO triggers
0147   std::vector<DTTracoTrigData>::const_iterator p;
0148   std::vector<DTTracoTrigData>::const_iterator pend = _tracocard->end();
0149   for (p = _tracocard->begin(); p != pend; p++) {
0150     if (config()->usedTraco(p->tracoNumber()) /*|| config()->usedTraco(p->tracoNumber())==1*/) {
0151       int step = p->step();
0152       int fs = (p->isFirst()) ? 1 : 2;
0153 
0154       // if first track is found inhibit second track processing in previous BX
0155       if (fs == 1 && step > DTConfigTSPhi::NSTEPF)
0156         ignoreSecondTrack(step - 1, p->tracoNumber());
0157 
0158       // load trigger
0159       addTracoT(step, &(*p), fs);
0160     }
0161   }
0162 }
0163 
0164 void DTTSPhi::addTracoT(int step, const DTTracoTrigData *tracotrig, int ifs) {
0165   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0166     edm::LogWarning("DTTSPhi") << "addTracoT: step out of range: " << step << " trigger not added!";
0167     return;
0168   }
0169   // Check that a preview is present and code is not zero
0170   if (!tracotrig->pvCode() || !tracotrig->code()) {
0171     edm::LogWarning("DTTSPhi") << "addTracoT: preview not present in TRACO trigger or its code=0 "
0172                                << " trigger not added!";
0173     return;
0174   }
0175 
0176   // Get the appropriate TSS
0177   int itss = (tracotrig->tracoNumber() - 1) / DTConfigTSPhi::NTCTSS + 1;
0178   if (itss < 1 || itss > DTConfigTSPhi::NTSSTSM) {
0179     edm::LogWarning("DTTSPhi") << "addTracoT: wrong TRACO number: " << tracotrig->tracoNumber()
0180                                << " trigger not added!";
0181     return;
0182   }
0183 
0184   // TSM status check (if it is the case, reject TRACO triggers related to
0185   // broken TSMData)
0186   if (config()->TsmStatus().element(itss) == 0) {  // TSMD broken
0187     return;
0188   }
0189 
0190   int pos = tracotrig->tracoNumber() - (itss - 1) * DTConfigTSPhi::NTCTSS;
0191   DTTSS *tss = getDTTSS(step, itss);
0192 
0193   // Create a new Trigger Server candidate
0194   DTTSCand *cand = new DTTSCand(tss, tracotrig, ifs, pos);
0195 
0196   // Add it to the buffer and to the TSS
0197   _tctrig[step - DTConfigTSPhi::NSTEPF].push_back(cand);
0198   tss->addDTTSCand(cand);
0199 
0200   // Debugging...
0201   if (config()->debug()) {
0202     edm::LogInfo("DTTSPhi") << "addTracoT at step " << step;
0203     if (ifs == 1) {
0204       edm::LogWarning("DTTSPhi") << " (first track)";
0205     } else {
0206       edm::LogWarning("DTTSPhi") << " (second track)";
0207     }
0208     edm::LogWarning("DTTSPhi") << " from TRACO " << tracotrig->tracoNumber() << " to TSS " << tss->number()
0209                                << ", position=" << pos;
0210     tracotrig->print();
0211   }
0212   // end debugging
0213 }
0214 
0215 void DTTSPhi::runTSPhi() {
0216   DTTSCand *secondPrevBx = nullptr;  // new DTTSCand;
0217 
0218   bool existSecondPrevBx = false;
0219   int itsmd = 1;  // initialize it to 1, default value if not in back up mode
0220   int ntsm[DTConfigTSPhi::NSTEPL + 1 - DTConfigTSPhi::NSTEPF][DTConfigTSPhi::NTSMD];
0221   int i_tsmd;
0222 
0223   for (int is = DTConfigTSPhi::NSTEPF; is < DTConfigTSPhi::NSTEPL + 1; is++) {
0224     // loop on DTTSSs
0225     i_tsmd = 0;
0226     ntsm[is - DTConfigTSPhi::NSTEPF][0] = 0;  // counter to make sector collector run if at least a tsm
0227     ntsm[is - DTConfigTSPhi::NSTEPF][1] = 0;
0228     std::vector<DTTSS *>::iterator p;
0229     for (p = _tss[is - DTConfigTSPhi::NSTEPF].begin(); p < _tss[is - DTConfigTSPhi::NSTEPF].end(); p++) {
0230       if ((*p)->nTracoT(1) > 0) {
0231         // run DTTSS algorithm on non-empty DTTSSs
0232         (*p)->run();
0233         // load DTTSM with output DTTSS tracks
0234         if ((*p)->nTracks() > 0) {
0235           for (int it = 1; it <= (*p)->nTracks(); it++) {
0236             //--- SM double TSM    get the corresponding tsm data
0237             int bkmod = config()->TsmStatus().element(0);
0238             if (bkmod == 0) {                // we are in back-up mode
0239               int my_itss = (*p)->number();  // metodo di DTTSS che ritorna itss
0240               int ntsstsmd = config()->TSSinTSMD(station(), sector());
0241               if (ntsstsmd < 2 || ntsstsmd > DTConfigTSPhi::NTSSTSMD) {
0242                 edm::LogWarning("DTTSPhi") << " addTracoT - wrong TSMD: " << ntsstsmd;
0243               }
0244 
0245               // Get the appropriate TSMD
0246               itsmd = (my_itss - 1) / ntsstsmd + 1;
0247               if (config()->debug()) {
0248                 edm::LogInfo("DTTSPhi") << " addTracoT: itsmd = (my_itss -1 ) / ntsstsmd + 1  ---> my_itss = "
0249                                         << my_itss << "  ntsstsmd = " << ntsstsmd << "  itsmd = " << itsmd;
0250               }
0251             } else if (bkmod == 1) {
0252               itsmd = 1;  // initialize it to 1, default value if not in back up mode
0253             }
0254             if (itsmd > 2)
0255               edm::LogWarning("DTTSPhi") << "****** RunTSPhi wrong  itsmd = " << itsmd;
0256             DTTSM *tsm = getDTTSM(is, itsmd);
0257             tsm->addCand((*p)->getTrack(it));
0258           }
0259         }  // end loop on output DTTSS tracks
0260       }
0261     }  // end loop on DTTSSs
0262 
0263     // at least a DTTSS with signal. Run DTTSM
0264 
0265     std::vector<DTTSM *>::iterator p_tsm;
0266 
0267     for (p_tsm = _tsm[is - DTConfigTSPhi::NSTEPF].begin(); p_tsm < _tsm[is - DTConfigTSPhi::NSTEPF].end(); p_tsm++) {
0268       // Run TSM sorting if at least a first track
0269 
0270       i_tsmd = (*p_tsm)->number() - 1;  // returns itsmd (0 in default, 0 or 1 when bkmode )
0271 
0272       if ((*p_tsm)->nCand(1) > 0) {
0273         int bkmod = config()->TsmStatus().element(0);
0274 
0275         (*p_tsm)->run(bkmod);  // bkmod 1 normal, 0 backup
0276         // Run TSM for current BX in case of 1st Tracks
0277         // Run TSM for previous BX for second tracks, to check whether there is
0278         // a pile up Tells whether a second track at previous BX exists
0279 
0280         if ((*p_tsm)->nTracks() > 0) {
0281           // We have a first track. Store it if code is > 0
0282 
0283           if ((*p_tsm)->getTrack(1)->tracoTr()->code() > 0) {
0284             DTTSCand *first = (*p_tsm)->getTrack(1);
0285             if (config()->TsmGetCarryFlag() == 0) {  //  get 1st tk at current BX and ignore any 2nd tk at
0286                                                      //  previous BX
0287 
0288               _cache.push_back(DTChambPhSegm(ChamberId(), is, (*p_tsm)->getTrack(1)->tracoTr(), 1));
0289               ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX
0290               if (config()->debug())
0291                 edm::LogInfo("DTTSPhi") << "ntsm = " << ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd] << " is = " << is
0292                                         << " i_tsmd = " << i_tsmd;
0293               if ((*p_tsm)->nTracks() > 1) {                         // there is a 2nd tk
0294                 if ((*p_tsm)->getTrack(2)->tracoTr()->code() > 0) {  // check if its code > 0
0295                   ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;
0296                   if (config()->debug())
0297                     edm::LogInfo("DTTSPhi") << "ntsm = " << ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd] << " is = " << is
0298                                             << " i_tsmd = " << i_tsmd;
0299 
0300                   secondPrevBx = (*p_tsm)->getTrack(2);  // assign second tk of previous BX
0301                 }
0302               }
0303             } else if (config()->TsmGetCarryFlag() == 1) {  // compare with 2nd tk in previous BX and get the tk
0304                                                             // with better quality
0305               existSecondPrevBx =
0306                   ((is - 1 - DTConfigTSPhi::NSTEPF >= 0) && (ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] > 1) &&
0307                    (secondPrevBx->tracoTr()->code() > 0));
0308               if ((!existSecondPrevBx) ||
0309                   !((secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) ||
0310                     (secondPrevBx->isCorr() && secondPrevBx->isHtrig() && !secondPrevBx->isInner()) ||
0311                     (!secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner())) ||
0312 
0313                   ((secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) &&
0314                    (first->isCorr() && first->isHtrig() && first->isInner())) ||
0315 
0316                   ((secondPrevBx->isCorr() && secondPrevBx->isHtrig() && !secondPrevBx->isInner()) &&
0317                    ((first->isCorr() && first->isHtrig() && first->isInner()) ||
0318                     (first->isCorr() && first->isHtrig() && !first->isInner()))) ||
0319 
0320                   ((!secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) &&
0321                    !((!first->isCorr() && first->isHtrig() && !first->isInner()) ||
0322                      (!first->isCorr() && !first->isHtrig() && first->isInner()) ||
0323                      (!first->isCorr() && !first->isHtrig() && !first->isInner()) ||
0324                      (first->isCorr() && !first->isHtrig() && !first->isInner()) ||
0325                      (first->isCorr() && !first->isHtrig() && first->isInner())))) {
0326                 // SM sector collector
0327                 ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX. I need to
0328                                                              // know if there is at least a first track from
0329                                                              // TSM to run Sect Coll
0330 
0331                 _cache.push_back(DTChambPhSegm(ChamberId(), is, (*p_tsm)->getTrack(1)->tracoTr(), 1));
0332                 //      (*p_tsm)->getTrack(1)->print();
0333 
0334                 if ((*p_tsm)->nTracks() > 1) {  // there is a 2nd tk
0335                   ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;
0336                   if ((*p_tsm)->getTrack(2)->tracoTr()->code() > 0) {  // check if its code > 0
0337                     secondPrevBx = (*p_tsm)->getTrack(2);              // assign second previous BX
0338                   }
0339                 }
0340               } else {  // if 2nd tk prev BX is better than first present BX skip
0341                         // the event and get 2nd prev BX
0342                 ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at previous BX.
0343                 _cache.push_back(DTChambPhSegm(ChamberId(), is - 1, secondPrevBx->tracoTr(), 2));
0344                 // secondPrevBx->print();
0345               }
0346             }
0347 
0348             else if (config()->TsmGetCarryFlag() == 2) {  // neglect first tk if it is a low uncorrelated
0349                                                           // trigger
0350               existSecondPrevBx =
0351                   ((is - 1 - DTConfigTSPhi::NSTEPF >= 0) && (ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] > 1) &&
0352                    (secondPrevBx->tracoTr()->code() > 0));
0353               if ((!existSecondPrevBx) || first->isHtrig() || first->isCorr()) {
0354                 ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX.
0355                 // SM sector collector: Load DTSectColl with output of DTTSM
0356                 _cache.push_back(DTChambPhSegm(ChamberId(), is, (*p_tsm)->getTrack(1)->tracoTr(), 1));
0357                 //      (*p_tsm)->getTrack(1)->print();
0358 
0359                 if ((*p_tsm)->nTracks() > 1) {  // there is a 2nd tk
0360                   ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;
0361                   if ((*p_tsm)->getTrack(2)->tracoTr()->code() > 0) {  // check if its code > 0
0362                     secondPrevBx = (*p_tsm)->getTrack(2);              // assign second tk of previous BX
0363                   }
0364                 }
0365               } else {
0366                 ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at previous BX.
0367                 _cache.push_back(DTChambPhSegm(ChamberId(), is - 1, secondPrevBx->tracoTr(), 2));
0368                 //      secondPrevBx->print();
0369               }
0370             }
0371           }
0372         }
0373 
0374       } else if (((*p_tsm)->nCand(1) == 0) && (is - 1 - DTConfigTSPhi::NSTEPF >= 0) &&
0375                  ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] >
0376                      0) {  // it means that the last BX with sort 2 was not the
0377                            // previous one
0378         existSecondPrevBx =
0379             ((is - 1 - DTConfigTSPhi::NSTEPF >= 0) && (ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] > 1) &&
0380              (secondPrevBx->tracoTr()->code() > 0));
0381         if (existSecondPrevBx) {
0382           _cache.push_back(DTChambPhSegm(ChamberId(), is - 1, secondPrevBx->tracoTr(), 2));
0383 
0384           //      secondPrevBx->print();
0385         }
0386       }
0387     }
0388     //---
0389 
0390   }  // end loop on step
0391   // debugging...
0392   if (config()->debug()) {
0393     if (!_cache.empty()) {
0394       edm::LogInfo("DTTSPhi") << " Phi segments ";
0395       std::vector<DTChambPhSegm>::const_iterator p;
0396       for (p = _cache.begin(); p < _cache.end(); p++) {
0397         p->print();
0398       }
0399     }
0400   }
0401   //  end debugging
0402 }
0403 
0404 void DTTSPhi::ignoreSecondTrack(int step, int tracon) {
0405   int itsmd = 1;  // initialize it to default
0406 
0407   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0408     edm::LogWarning("DTTSPhi") << "ignoreSecondTrack: step out of range: " << step << " no flag set!";
0409     return;
0410   }
0411   int itss = (tracon - 1) / DTConfigTSPhi::NTCTSS + 1;
0412   if (itss < 1 || itss > DTConfigTSPhi::NTSSTSM) {
0413     edm::LogWarning("DTTSPhi") << "ignoreSecondTrack: wrong TRACO number: " << tracon << " no flag set!";
0414     return;
0415   }
0416   DTTSS *tss = getDTTSS(step, itss);
0417   tss->ignoreSecondTrack();
0418 
0419   int bkmod = config()->TsmStatus().element(0);
0420   if (bkmod == 0) {  // we are in back-up mode
0421 
0422     int ntsstsmd = config()->TSSinTSMD(station(), sector());
0423     // Get the appropriate TSMD
0424     itsmd = (itss - 1) / ntsstsmd + 1;
0425   }
0426 
0427   DTTSM *tsm = getDTTSM(step, itsmd);
0428   tsm->ignoreSecondTrack();
0429 }
0430 
0431 DTTSS *DTTSPhi::getDTTSS(int step, unsigned n) const {
0432   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0433     edm::LogWarning("DTTSPhi") << "getDTTSS: step out of range: " << step << " empty pointer returned!";
0434     return nullptr;
0435   }
0436   if (n < 1 || n > _tss[step - DTConfigTSPhi::NSTEPF].size()) {
0437     edm::LogWarning("DTTSPhi") << "getDTTSS: requested DTTSS not present: " << n << " (at step " << step << ")"
0438                                << " empty pointer returned!";
0439     return nullptr;
0440   }
0441 
0442   std::vector<DTTSS *>::const_iterator p = _tss[step - DTConfigTSPhi::NSTEPF].begin() + n - 1;
0443   return *p;
0444 }
0445 
0446 DTTSM *DTTSPhi::getDTTSM(int step, unsigned n) const {
0447   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0448     edm::LogWarning("DTTSPhi") << "getDTTSM: step out of range: " << step << " empty pointer returned!";
0449     return nullptr;
0450   }
0451   if (n < 1 || n > _tsm[step - DTConfigTSPhi::NSTEPF].size()) {
0452     edm::LogWarning("DTTSPhi") << "getDTTSM: requested DTTSM not present: " << n << " (at step " << step << ")"
0453                                << " empty pointer returned!";
0454     return nullptr;
0455   }
0456   std::vector<DTTSM *>::const_iterator p_tsm = _tsm[step - DTConfigTSPhi::NSTEPF].begin() + n - 1;
0457   return *p_tsm;
0458 }
0459 
0460 int DTTSPhi::nSegm(int step) {
0461   int n = 0;
0462   std::vector<DTChambPhSegm>::const_iterator p;  // p=0;
0463   for (p = begin(); p < end(); p++) {
0464     if (p->step() == step)
0465       n++;
0466   }
0467   return n;
0468 }
0469 
0470 const DTChambPhSegm *DTTSPhi::segment(int step, unsigned n) {
0471   std::vector<DTChambPhSegm>::const_iterator p;  // p=0;
0472   for (p = begin(); p < end(); p++) {
0473     if (p->step() == step && ((n == 1 && p->isFirst()) || (n == 2 && !p->isFirst())))
0474       return &(*p);  // p;
0475   }
0476   return nullptr;
0477 }
0478 
0479 LocalPoint DTTSPhi::localPosition(const DTTrigData *tr) const {
0480   //@@ patch for Sun 4.2 compiler
0481   // sm DTChambPhSegm* trig =
0482   // dynamic_cast<DTChambPhSegm*>(const_cast<DTTrigData*>(tr));
0483   const DTChambPhSegm *trig = dynamic_cast<const DTChambPhSegm *>(tr);
0484   if (!trig) {
0485     edm::LogWarning("DTTSPhi") << "LocalPosition called with wrong argument!";
0486     return LocalPoint(0, 0, 0);
0487   }
0488   return _tracocard->localPosition(trig->tracoTrig());
0489 }
0490 
0491 LocalVector DTTSPhi::localDirection(const DTTrigData *tr) const {
0492   DTChambPhSegm *trig = dynamic_cast<DTChambPhSegm *>(const_cast<DTTrigData *>(tr));
0493   //  const DTChambPhSegm* trig = dynamic_cast<const DTChambPhSegm*>(tr);
0494   if (!trig) {
0495     edm::LogWarning("DTTSPhi") << "LocalDirection called with wrong argument!";
0496     return LocalVector(0, 0, 0);
0497   }
0498   return _tracocard->localDirection(trig->tracoTrig());
0499 }