Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-29 06:08:30

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     ntsm[is - DTConfigTSPhi::NSTEPF][0] = 0;  // counter to make sector collector run if at least a tsm
0226     ntsm[is - DTConfigTSPhi::NSTEPF][1] = 0;
0227     std::vector<DTTSS *>::iterator p;
0228     for (p = _tss[is - DTConfigTSPhi::NSTEPF].begin(); p < _tss[is - DTConfigTSPhi::NSTEPF].end(); p++) {
0229       if ((*p)->nTracoT(1) > 0) {
0230         // run DTTSS algorithm on non-empty DTTSSs
0231         (*p)->run();
0232         // load DTTSM with output DTTSS tracks
0233         if ((*p)->nTracks() > 0) {
0234           for (int it = 1; it <= (*p)->nTracks(); it++) {
0235             //--- SM double TSM    get the corresponding tsm data
0236             int bkmod = config()->TsmStatus().element(0);
0237             if (bkmod == 0) {                // we are in back-up mode
0238               int my_itss = (*p)->number();  // metodo di DTTSS che ritorna itss
0239               int ntsstsmd = config()->TSSinTSMD(station(), sector());
0240               if (ntsstsmd < 2 || ntsstsmd > DTConfigTSPhi::NTSSTSMD) {
0241                 edm::LogWarning("DTTSPhi") << " addTracoT - wrong TSMD: " << ntsstsmd;
0242               }
0243 
0244               // Get the appropriate TSMD
0245               itsmd = (my_itss - 1) / ntsstsmd + 1;
0246               if (config()->debug()) {
0247                 edm::LogInfo("DTTSPhi") << " addTracoT: itsmd = (my_itss -1 ) / ntsstsmd + 1  ---> my_itss = "
0248                                         << my_itss << "  ntsstsmd = " << ntsstsmd << "  itsmd = " << itsmd;
0249               }
0250             } else if (bkmod == 1) {
0251               itsmd = 1;  // initialize it to 1, default value if not in back up mode
0252             }
0253             if (itsmd > 2)
0254               edm::LogWarning("DTTSPhi") << "****** RunTSPhi wrong  itsmd = " << itsmd;
0255             DTTSM *tsm = getDTTSM(is, itsmd);
0256             tsm->addCand((*p)->getTrack(it));
0257           }
0258         }  // end loop on output DTTSS tracks
0259       }
0260     }  // end loop on DTTSSs
0261 
0262     // at least a DTTSS with signal. Run DTTSM
0263 
0264     std::vector<DTTSM *>::iterator p_tsm;
0265 
0266     for (p_tsm = _tsm[is - DTConfigTSPhi::NSTEPF].begin(); p_tsm < _tsm[is - DTConfigTSPhi::NSTEPF].end(); p_tsm++) {
0267       // Run TSM sorting if at least a first track
0268 
0269       i_tsmd = (*p_tsm)->number() - 1;  // returns itsmd (0 in default, 0 or 1 when bkmode )
0270 
0271       if ((*p_tsm)->nCand(1) > 0) {
0272         int bkmod = config()->TsmStatus().element(0);
0273 
0274         (*p_tsm)->run(bkmod);  // bkmod 1 normal, 0 backup
0275         // Run TSM for current BX in case of 1st Tracks
0276         // Run TSM for previous BX for second tracks, to check whether there is
0277         // a pile up Tells whether a second track at previous BX exists
0278 
0279         if ((*p_tsm)->nTracks() > 0) {
0280           // We have a first track. Store it if code is > 0
0281 
0282           if ((*p_tsm)->getTrack(1)->tracoTr()->code() > 0) {
0283             DTTSCand *first = (*p_tsm)->getTrack(1);
0284             if (config()->TsmGetCarryFlag() == 0) {  //  get 1st tk at current BX and ignore any 2nd tk at
0285                                                      //  previous BX
0286 
0287               _cache.push_back(DTChambPhSegm(ChamberId(), is, (*p_tsm)->getTrack(1)->tracoTr(), 1));
0288               ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX
0289               if (config()->debug())
0290                 edm::LogInfo("DTTSPhi") << "ntsm = " << ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd] << " is = " << is
0291                                         << " i_tsmd = " << i_tsmd;
0292               if ((*p_tsm)->nTracks() > 1) {                         // there is a 2nd tk
0293                 if ((*p_tsm)->getTrack(2)->tracoTr()->code() > 0) {  // check if its code > 0
0294                   ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;
0295                   if (config()->debug())
0296                     edm::LogInfo("DTTSPhi") << "ntsm = " << ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd] << " is = " << is
0297                                             << " i_tsmd = " << i_tsmd;
0298 
0299                   secondPrevBx = (*p_tsm)->getTrack(2);  // assign second tk of previous BX
0300                 }
0301               }
0302             } else if (config()->TsmGetCarryFlag() == 1) {  // compare with 2nd tk in previous BX and get the tk
0303                                                             // with better quality
0304               existSecondPrevBx = secondPrevBx && ((is - 1 - DTConfigTSPhi::NSTEPF >= 0) &&
0305                                                    (ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] > 1) &&
0306                                                    (secondPrevBx->tracoTr()->code() > 0));
0307               if ((!existSecondPrevBx) ||
0308                   !((secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) ||
0309                     (secondPrevBx->isCorr() && secondPrevBx->isHtrig() && !secondPrevBx->isInner()) ||
0310                     (!secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner())) ||
0311 
0312                   ((secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) &&
0313                    (first->isCorr() && first->isHtrig() && first->isInner())) ||
0314 
0315                   ((secondPrevBx->isCorr() && secondPrevBx->isHtrig() && !secondPrevBx->isInner()) &&
0316                    ((first->isCorr() && first->isHtrig() && first->isInner()) ||
0317                     (first->isCorr() && first->isHtrig() && !first->isInner()))) ||
0318 
0319                   ((!secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) &&
0320                    !((!first->isCorr() && first->isHtrig() && !first->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                 // SM sector collector
0326                 ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX. I need to
0327                                                              // know if there is at least a first track from
0328                                                              // TSM to run Sect Coll
0329 
0330                 _cache.push_back(DTChambPhSegm(ChamberId(), is, (*p_tsm)->getTrack(1)->tracoTr(), 1));
0331                 //      (*p_tsm)->getTrack(1)->print();
0332 
0333                 if ((*p_tsm)->nTracks() > 1) {  // there is a 2nd tk
0334                   ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;
0335                   if ((*p_tsm)->getTrack(2)->tracoTr()->code() > 0) {  // check if its code > 0
0336                     secondPrevBx = (*p_tsm)->getTrack(2);              // assign second previous BX
0337                   }
0338                 }
0339               } else {  // if 2nd tk prev BX is better than first present BX skip
0340                         // the event and get 2nd prev BX
0341                 ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at previous BX.
0342                 _cache.push_back(DTChambPhSegm(ChamberId(), is - 1, secondPrevBx->tracoTr(), 2));
0343                 // secondPrevBx->print();
0344               }
0345             }
0346 
0347             else if (config()->TsmGetCarryFlag() == 2) {  // neglect first tk if it is a low uncorrelated
0348                                                           // trigger
0349               existSecondPrevBx = secondPrevBx && ((is - 1 - DTConfigTSPhi::NSTEPF >= 0) &&
0350                                                    (ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] > 1) &&
0351                                                    (secondPrevBx->tracoTr()->code() > 0));
0352               if ((!existSecondPrevBx) || first->isHtrig() || first->isCorr()) {
0353                 ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX.
0354                 // SM sector collector: Load DTSectColl with output of DTTSM
0355                 _cache.push_back(DTChambPhSegm(ChamberId(), is, (*p_tsm)->getTrack(1)->tracoTr(), 1));
0356                 //      (*p_tsm)->getTrack(1)->print();
0357 
0358                 if ((*p_tsm)->nTracks() > 1) {  // there is a 2nd tk
0359                   ntsm[is - DTConfigTSPhi::NSTEPF][i_tsmd]++;
0360                   if ((*p_tsm)->getTrack(2)->tracoTr()->code() > 0) {  // check if its code > 0
0361                     secondPrevBx = (*p_tsm)->getTrack(2);              // assign second tk of previous BX
0362                   }
0363                 }
0364               } else {
0365                 ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at previous BX.
0366                 _cache.push_back(DTChambPhSegm(ChamberId(), is - 1, secondPrevBx->tracoTr(), 2));
0367                 //      secondPrevBx->print();
0368               }
0369             }
0370           }
0371         }
0372 
0373       } else if (((*p_tsm)->nCand(1) == 0) && (is - 1 - DTConfigTSPhi::NSTEPF >= 0) &&
0374                  ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] >
0375                      0) {  // it means that the last BX with sort 2 was not the
0376                            // previous one
0377         existSecondPrevBx = secondPrevBx && ((is - 1 - DTConfigTSPhi::NSTEPF >= 0) &&
0378                                              (ntsm[is - 1 - DTConfigTSPhi::NSTEPF][i_tsmd] > 1) &&
0379                                              (secondPrevBx->tracoTr()->code() > 0));
0380         if (existSecondPrevBx) {
0381           _cache.push_back(DTChambPhSegm(ChamberId(), is - 1, secondPrevBx->tracoTr(), 2));
0382 
0383           //      secondPrevBx->print();
0384         }
0385       }
0386     }
0387     //---
0388 
0389   }  // end loop on step
0390   // debugging...
0391   if (config()->debug()) {
0392     if (!_cache.empty()) {
0393       edm::LogInfo("DTTSPhi") << " Phi segments ";
0394       std::vector<DTChambPhSegm>::const_iterator p;
0395       for (p = _cache.begin(); p < _cache.end(); p++) {
0396         p->print();
0397       }
0398     }
0399   }
0400   //  end debugging
0401 }
0402 
0403 void DTTSPhi::ignoreSecondTrack(int step, int tracon) {
0404   int itsmd = 1;  // initialize it to default
0405 
0406   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0407     edm::LogWarning("DTTSPhi") << "ignoreSecondTrack: step out of range: " << step << " no flag set!";
0408     return;
0409   }
0410   int itss = (tracon - 1) / DTConfigTSPhi::NTCTSS + 1;
0411   if (itss < 1 || itss > DTConfigTSPhi::NTSSTSM) {
0412     edm::LogWarning("DTTSPhi") << "ignoreSecondTrack: wrong TRACO number: " << tracon << " no flag set!";
0413     return;
0414   }
0415   DTTSS *tss = getDTTSS(step, itss);
0416   tss->ignoreSecondTrack();
0417 
0418   int bkmod = config()->TsmStatus().element(0);
0419   if (bkmod == 0) {  // we are in back-up mode
0420 
0421     int ntsstsmd = config()->TSSinTSMD(station(), sector());
0422     // Get the appropriate TSMD
0423     itsmd = (itss - 1) / ntsstsmd + 1;
0424   }
0425 
0426   DTTSM *tsm = getDTTSM(step, itsmd);
0427   tsm->ignoreSecondTrack();
0428 }
0429 
0430 DTTSS *DTTSPhi::getDTTSS(int step, unsigned n) const {
0431   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0432     edm::LogWarning("DTTSPhi") << "getDTTSS: step out of range: " << step << " empty pointer returned!";
0433     return nullptr;
0434   }
0435   if (n < 1 || n > _tss[step - DTConfigTSPhi::NSTEPF].size()) {
0436     edm::LogWarning("DTTSPhi") << "getDTTSS: requested DTTSS not present: " << n << " (at step " << step << ")"
0437                                << " empty pointer returned!";
0438     return nullptr;
0439   }
0440 
0441   std::vector<DTTSS *>::const_iterator p = _tss[step - DTConfigTSPhi::NSTEPF].begin() + n - 1;
0442   return *p;
0443 }
0444 
0445 DTTSM *DTTSPhi::getDTTSM(int step, unsigned n) const {
0446   if (step < DTConfigTSPhi::NSTEPF || step > DTConfigTSPhi::NSTEPL) {
0447     edm::LogWarning("DTTSPhi") << "getDTTSM: step out of range: " << step << " empty pointer returned!";
0448     return nullptr;
0449   }
0450   if (n < 1 || n > _tsm[step - DTConfigTSPhi::NSTEPF].size()) {
0451     edm::LogWarning("DTTSPhi") << "getDTTSM: requested DTTSM not present: " << n << " (at step " << step << ")"
0452                                << " empty pointer returned!";
0453     return nullptr;
0454   }
0455   std::vector<DTTSM *>::const_iterator p_tsm = _tsm[step - DTConfigTSPhi::NSTEPF].begin() + n - 1;
0456   return *p_tsm;
0457 }
0458 
0459 int DTTSPhi::nSegm(int step) {
0460   int n = 0;
0461   std::vector<DTChambPhSegm>::const_iterator p;  // p=0;
0462   for (p = begin(); p < end(); p++) {
0463     if (p->step() == step)
0464       n++;
0465   }
0466   return n;
0467 }
0468 
0469 const DTChambPhSegm *DTTSPhi::segment(int step, unsigned n) {
0470   std::vector<DTChambPhSegm>::const_iterator p;  // p=0;
0471   for (p = begin(); p < end(); p++) {
0472     if (p->step() == step && ((n == 1 && p->isFirst()) || (n == 2 && !p->isFirst())))
0473       return &(*p);  // p;
0474   }
0475   return nullptr;
0476 }
0477 
0478 LocalPoint DTTSPhi::localPosition(const DTTrigData *tr) const {
0479   //@@ patch for Sun 4.2 compiler
0480   // sm DTChambPhSegm* trig =
0481   // dynamic_cast<DTChambPhSegm*>(const_cast<DTTrigData*>(tr));
0482   const DTChambPhSegm *trig = dynamic_cast<const DTChambPhSegm *>(tr);
0483   if (!trig) {
0484     edm::LogWarning("DTTSPhi") << "LocalPosition called with wrong argument!";
0485     return LocalPoint(0, 0, 0);
0486   }
0487   return _tracocard->localPosition(trig->tracoTrig());
0488 }
0489 
0490 LocalVector DTTSPhi::localDirection(const DTTrigData *tr) const {
0491   DTChambPhSegm *trig = dynamic_cast<DTChambPhSegm *>(const_cast<DTTrigData *>(tr));
0492   //  const DTChambPhSegm* trig = dynamic_cast<const DTChambPhSegm*>(tr);
0493   if (!trig) {
0494     edm::LogWarning("DTTSPhi") << "LocalDirection called with wrong argument!";
0495     return LocalVector(0, 0, 0);
0496   }
0497   return _tracocard->localDirection(trig->tracoTrig());
0498 }