CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_9_patch3/src/L1Trigger/DTTriggerServerPhi/src/DTTSPhi.cc

Go to the documentation of this file.
00001 //-------------------------------------------------
00002 //
00003 //   Class: DTTSPhi.cpp
00004 //
00005 //   Description: Implementation of TS Phi trigger algorithm
00006 //
00007 //
00008 //   Author List:
00009 //   C. Grandi
00010 //   Modifications: 
00011 //   jan02 - D.Bonacorsi/S.Marcellini
00012 //           improved algorithm for 2nd track handling in case of pile-up in TSM
00013 //           param: tsmgetcarryflag - value: 1 (default)
00014 //   feb04 - Implementation of sector collector related stuff(S. Marcellini)
00015 //   jan07 - C. Battilana local conf update
00016 //   mar07 - S. Vanini : parameters from DTConfigManager 
00017 //
00018 //--------------------------------------------------
00019 
00020 #include "L1TriggerConfig/DTTPGConfig/interface/BitArray.h"
00021 
00022 //-----------------------
00023 // This Class's Header --
00024 //-----------------------
00025 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSPhi.h"
00026 
00027 //-------------------------------
00028 // Collaborating Class Headers --
00029 //-------------------------------
00030 #include "L1Trigger/DTTraco/interface/DTTracoCard.h"
00031 #include "L1Trigger/DTTraco/interface/DTTracoTrigData.h"
00032 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSS.h"
00033 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSM.h"
00034 #include "L1Trigger/DTTriggerServerPhi/interface/DTTSCand.h"
00035 
00036 //---------------
00037 // C++ Headers --
00038 //---------------
00039 #include <iostream>
00040 
00041 //----------------
00042 // Constructors --
00043 //----------------
00044 DTTSPhi::DTTSPhi(DTTrigGeom* geom, DTTracoCard* tracocard) : 
00045   DTGeomSupplier(geom), _tracocard(tracocard){
00046 
00047   // reserve the appropriate amount of space for vectors
00048   int i=0;
00049   for(i=0;i<DTConfigTSPhi::NSTEPL - DTConfigTSPhi::NSTEPF + 1 ;i++) {  // SM add + 1
00050     _tss[i].reserve(DTConfigTSPhi::NTSSTSM);
00051     // DBSM-doubleTSM
00052     _tsm[i].reserve(DTConfigTSPhi::NTSMD);
00053   }
00054 
00055   for(int is=0;is<DTConfigTSPhi::NSTEPL-DTConfigTSPhi::NSTEPF+1;is++) {
00056 
00057     // create DTTSSs  
00058     for(int itss=1; itss<=DTConfigTSPhi::NTSSTSM; itss++) {
00059       DTTSS* tss = new DTTSS(itss);
00060       _tss[is].push_back(tss);
00061     }
00062 
00063     // create DTTSMs     SM double TSM  
00064     for(int itsmd=1; itsmd<=DTConfigTSPhi::NTSMD; itsmd++) {
00065       DTTSM* tsm = new DTTSM(itsmd);
00066       _tsm[is].push_back(tsm);
00067     }
00068   }
00069 }
00070 
00071 
00072 //--------------
00073 // Destructor --
00074 //--------------
00075 DTTSPhi::~DTTSPhi(){
00076 
00077   std::vector<DTTSS*>::iterator ptss;
00078   std::vector<DTTSM*>::iterator ptsm;
00079   for(int is=0;is<DTConfigTSPhi::NSTEPL-DTConfigTSPhi::NSTEPF+1;is++){
00080     // clear TSSs
00081     for (ptss = _tss[is].begin(); ptss != _tss[is].end(); ptss++){
00082       delete (*ptss);
00083     }
00084     _tss[is].clear();
00085     // clear TSMs
00086     for (ptsm = _tsm[is].begin(); ptsm != _tsm[is].end(); ptsm++){
00087       delete (*ptsm);
00088     }
00089     _tsm[is].clear();
00090 
00091   }
00092   
00093   localClear();
00094   
00095   //delete _config;
00096 
00097 }
00098 
00099 
00100 //--------------
00101 // Operations --
00102 //--------------
00103 
00104 void
00105 DTTSPhi::localClear() {
00106   for(int is=0;is<DTConfigTSPhi::NSTEPL-DTConfigTSPhi::NSTEPF+1;is++) {
00107     // clear buffer
00108     std::vector<DTTSCand*>::iterator p1;
00109     for(p1 = _tctrig[is].begin(); p1 != _tctrig[is].end(); p1++) {
00110       delete (*p1);
00111     }
00112     _tctrig[is].clear();
00113     
00114     std::vector<DTTSS*>::iterator ptss;
00115     for(ptss = _tss[is].begin(); ptss != _tss[is].end(); ptss++) {
00116       (*ptss)->clear();
00117     }
00118     // clear all DTTSM
00119     std::vector<DTTSM*>::iterator ptsm;
00120     for(ptsm = _tsm[is].begin(); ptsm != _tsm[is].end(); ptsm++) {
00121       (*ptsm)->clear();
00122     }
00123   }
00124 }
00125 
00126 void
00127 DTTSPhi::setConfig (const DTConfigManager *conf){
00128 
00129   DTChamberId sid = ChamberId();
00130   _config = conf->getDTConfigTSPhi(sid);
00131 
00132   for(int is=0;is<DTConfigTSPhi::NSTEPL-DTConfigTSPhi::NSTEPF+1;is++) {
00133 
00134     // set TSS config
00135     std::vector<DTTSS*>::iterator ptss;
00136     for (ptss = _tss[is].begin(); ptss != _tss[is].end(); ptss++){
00137       (*ptss)->setConfig(config());
00138     }
00139     // set TSM config
00140     std::vector<DTTSM*>::iterator ptsm;
00141     for (ptsm = _tsm[is].begin(); ptsm != _tsm[is].end(); ptsm++){
00142       (*ptsm)->setConfig(config());
00143     }
00144 
00145   }
00146 
00147 }
00148 
00149 void
00150 DTTSPhi::loadTSPhi() {
00151 
00152   // clear DTTSSs and DTTSM 
00153   localClear();
00154   
00155   if(config()->debug()){
00156     std::cout << "DTTSPhi::loadDTTSPhi called for wheel=" << wheel() ;
00157     std::cout <<                                ", station=" << station();
00158     std::cout <<                                ", sector="  << sector() << std::endl;
00159   }
00160   
00161   // loop on all TRACO triggers
00162   std::vector<DTTracoTrigData>::const_iterator p;
00163   std::vector<DTTracoTrigData>::const_iterator pend=_tracocard->end();
00164   for(p=_tracocard->begin();p!=pend;p++){
00165 
00166     if(config()->usedTraco(p->tracoNumber()) /*|| config()->usedTraco(p->tracoNumber())==1*/ ) {
00167       int step = p->step();
00168       int fs = (p->isFirst()) ? 1 : 2 ;
00169             
00170       // if first track is found inhibit second track processing in previous BX
00171       if( fs==1 && step>DTConfigTSPhi::NSTEPF)
00172         ignoreSecondTrack(step-1,p->tracoNumber());
00173       
00174       // load trigger
00175       addTracoT( step, &(*p), fs );   
00176     }
00177   }
00178 }
00179 
00180 void
00181 DTTSPhi::addTracoT(int step, const DTTracoTrigData* tracotrig, int ifs) {
00182   if(step<DTConfigTSPhi::NSTEPF||step>DTConfigTSPhi::NSTEPL){
00183     std::cout << "DTTSPhi::addTracoT: step out of range: " << step;
00184     std::cout << " trigger not added!" << std::endl;
00185     return;
00186   }
00187   // Check that a preview is present and code is not zero
00188   if(!tracotrig->pvCode() || !tracotrig->code() ) {
00189     std::cout << "DTTSPhi::addTracoT: preview not present in TRACO trigger or its code=0 ";
00190     std::cout << " trigger not added!" << std::endl;
00191     return;
00192   }
00193   
00194   // Get the appropriate TSS
00195   int itss = (tracotrig->tracoNumber() -1 ) / DTConfigTSPhi::NTCTSS + 1;
00196   if(itss<1 || itss>DTConfigTSPhi::NTSSTSM) {
00197     std::cout << "DTTSPhi::addTracoT: wrong TRACO number: ";
00198     std::cout << tracotrig->tracoNumber();
00199     std::cout << " trigger not added!" << std::endl;
00200     return;
00201   }
00202   
00203   // TSM status check (if it is the case, reject TRACO triggers related to broken TSMData)
00204   if( config()->TsmStatus().element(itss)==0){      // TSMD broken
00205     return;
00206   }
00207 
00208   int pos = tracotrig->tracoNumber() - (itss-1)*DTConfigTSPhi::NTCTSS;
00209   DTTSS* tss = getDTTSS(step,itss);
00210   
00211   // Create a new Trigger Server candidate
00212   DTTSCand* cand = new DTTSCand(tss, tracotrig, ifs, pos);
00213   
00214   // Add it to the buffer and to the TSS  
00215   _tctrig[step-DTConfigTSPhi::NSTEPF].push_back(cand);
00216   tss->addDTTSCand(cand);
00217 
00218   // Debugging...
00219   if(config()->debug()){
00220     std::cout << "DTTSPhi::addTracoT at step " << step;
00221     if(ifs==1) {
00222       std::cout << " (first track)";
00223     } else {
00224       std::cout << " (second track)";
00225     }
00226     std::cout << " from TRACO " << tracotrig->tracoNumber();
00227     std::cout << " to TSS " << tss->number() << ", position=" << pos << std::endl;
00228     tracotrig->print();
00229   }
00230   // end debugging
00231 
00232 }
00233 
00234 void
00235 DTTSPhi::runTSPhi() {
00236 
00237   DTTSCand* secondPrevBx = 0;    // new DTTSCand;
00238 
00239   bool existSecondPrevBx = false;
00240   int itsmd = 1;  // initialize it to 1, default value if not in back up mode
00241   int ntsm[DTConfigTSPhi::NSTEPL+1-DTConfigTSPhi::NSTEPF][DTConfigTSPhi::NTSMD];  
00242   int i_tsmd;
00243   
00244   for(int is=DTConfigTSPhi::NSTEPF;is<DTConfigTSPhi::NSTEPL+1;is++) {
00245     // loop on DTTSSs
00246     int ntss = 0;
00247     i_tsmd = 0;
00248     ntsm[is-DTConfigTSPhi::NSTEPF][0] = 0; // counter to make sector collector run if at least a tsm 
00249     ntsm[is-DTConfigTSPhi::NSTEPF][1] = 0;
00250     std::vector<DTTSS*>::iterator p;
00251     for(p=_tss[is-DTConfigTSPhi::NSTEPF].begin(); 
00252         p<_tss[is-DTConfigTSPhi::NSTEPF].end(); p++) {
00253       if((*p)->nTracoT(1)>0) {
00254         // run DTTSS algorithm on non-empty DTTSSs
00255         (*p)->run();
00256         // load DTTSM with output DTTSS tracks
00257         if((*p)->nTracks()>0){
00258           for(int it=1;it<=(*p)->nTracks();it++){
00259             //--- SM double TSM    get the corresponding tsm data 
00260             int bkmod = config()->TsmStatus().element(0);
00261             if (bkmod==0) {    // we are in back-up mode
00262               int my_itss = (*p)->number();   // metodo di DTTSS che ritorna itss
00263               int ntsstsmd = config()->TSSinTSMD(station(),sector());
00264               if(ntsstsmd<2 || ntsstsmd>DTConfigTSPhi::NTSSTSMD) {                 
00265                 std::cout << " DTTSPhi::addTracoT - wrong TSMD: " << ntsstsmd << std::endl;
00266               }
00267   
00268               // Get the appropriate TSMD
00269               itsmd = (my_itss -1 ) / ntsstsmd + 1;
00270               if(config()->debug()){
00271                 std::cout << " DTTSPhi::addTracoT: itsmd = (my_itss -1 ) / ntsstsmd + 1  ---> my_itss = " <<
00272                   my_itss << "  ntsstsmd = " << ntsstsmd << "  itsmd = " << itsmd << std::endl;}
00273             }
00274             else if(bkmod==1) {
00275               itsmd = 1;  // initialize it to 1, default value if not in back up mode
00276             }
00277             if(itsmd>2) std::cout << "****** >DTTSPhi::RunTSPhi wrong  itsmd = " << itsmd << std::endl; 
00278             DTTSM* tsm = getDTTSM(is,itsmd); 
00279             tsm->addCand((*p)->getTrack(it));
00280           }
00281           ntss++;
00282         } // end loop on output DTTSS tracks
00283       }
00284     } // end loop on DTTSSs
00285     
00286     
00287     // at least a DTTSS with signal. Run DTTSM
00288  
00289     std::vector<DTTSM*>::iterator p_tsm;
00290     
00291     for(p_tsm=_tsm[is-DTConfigTSPhi::NSTEPF].begin(); 
00292         p_tsm<_tsm[is-DTConfigTSPhi::NSTEPF].end(); p_tsm++) {
00293       
00294       // Run TSM sorting if at least a first track 
00295 
00296       i_tsmd = (*p_tsm)->number()-1; // returns itsmd (0 in default, 0 or 1 when bkmode )
00297       
00298       if((*p_tsm)->nCand(1)>0) {  
00299         int bkmod = config()->TsmStatus().element(0);
00300 
00301         (*p_tsm)->run(bkmod);   // bkmod 1 normal, 0 backup
00302         // Run TSM for current BX in case of 1st Tracks
00303         // Run TSM for previous BX for second tracks, to check whether there is a pile up
00304         // Tells whether a second track at previous BX exists
00305         
00306         if((*p_tsm)->nTracks()>0){
00307           // We have a first track. Store it if code is > 0
00308           
00309           if((*p_tsm)->getTrack(1)->tracoTr()->code()>0) {
00310             
00311             DTTSCand* first = (*p_tsm)->getTrack(1);
00312             if( config()->TsmGetCarryFlag()==0 ) {  //  get 1st tk at current BX and ignore any 2nd tk at previous BX
00313               
00314               _cache.push_back(DTChambPhSegm(ChamberId(),is,(*p_tsm)->getTrack(1)->tracoTr(),1));
00315               ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX
00316               if( config()->debug())
00317                 std::cout << "ntsm = " <<  ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd] << " is = " << is << " i_tsmd = " << i_tsmd << std::endl; 
00318               if((*p_tsm)->nTracks()>1)   {  // there is a 2nd tk
00319                 if((*p_tsm)->getTrack(2)->tracoTr()->code()>0) {   // check if its code > 0
00320                   ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd]++;
00321                   if( config()->debug())
00322                     std::cout << "ntsm = " <<  ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd] << " is = " << is << " i_tsmd = " << i_tsmd << std::endl; 
00323                   
00324                   secondPrevBx=(*p_tsm)->getTrack(2) ;   // assign second tk of previous BX
00325                   
00326                 }
00327               }
00328             }
00329             else if( config()->TsmGetCarryFlag()==1 ) {   // compare with 2nd tk in previous BX and get the tk with better quality
00330               existSecondPrevBx = ((is-1-DTConfigTSPhi::NSTEPF>=0) &&  ( ntsm[is-1-DTConfigTSPhi::NSTEPF][i_tsmd]>1) &&   
00331                                    (secondPrevBx->tracoTr()->code()>0));                
00332               if( (!existSecondPrevBx)  || 
00333                   ! (   (secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) ||             
00334                         (secondPrevBx->isCorr() && secondPrevBx->isHtrig() && !secondPrevBx->isInner())  ||           
00335                         (!secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) )           ||
00336                   
00337                   ( (secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) &&
00338                     (first->isCorr() && first->isHtrig() && first->isInner()) ) ||
00339                   
00340                   ( (secondPrevBx->isCorr() && secondPrevBx->isHtrig() && !secondPrevBx->isInner()) &&
00341                     ( (first->isCorr() && first->isHtrig() && first->isInner()) || 
00342                       (first->isCorr() && first->isHtrig() && !first->isInner()) ) ) ||
00343                   
00344                   ( (!secondPrevBx->isCorr() && secondPrevBx->isHtrig() && secondPrevBx->isInner()) && 
00345                     !( (!first->isCorr() && first->isHtrig() && !first->isInner())  || 
00346                        (!first->isCorr() && !first->isHtrig() && first->isInner())  ||
00347                        (!first->isCorr() && !first->isHtrig() && !first->isInner()) ||
00348                        (first->isCorr() && !first->isHtrig() && !first->isInner())  ||
00349                        (first->isCorr() && !first->isHtrig() && first->isInner()) ) )
00350                   ) {
00351                 // SM sector collector
00352                 ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX. I need to know if there is at least a first track from TSM to run Sect Coll
00353                 
00354                 _cache.push_back(DTChambPhSegm(ChamberId(),is,(*p_tsm)->getTrack(1)->tracoTr(),1));
00355                 //              (*p_tsm)->getTrack(1)->print();
00356                 
00357                 if((*p_tsm)->nTracks()>1)   {  // there is a 2nd tk
00358                   ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd]++;               
00359                   if((*p_tsm)->getTrack(2)->tracoTr()->code()>0) {   // check if its code > 0
00360                     secondPrevBx=(*p_tsm)->getTrack(2) ;   // assign second previous BX
00361                   }
00362                 }
00363               }
00364               else   {      // if 2nd tk prev BX is better than first present BX skip the event and get 2nd prev BX 
00365                 ntsm[is-1-DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at previous BX.
00366                 _cache.push_back(DTChambPhSegm(ChamberId(),is-1,secondPrevBx->tracoTr(),2));
00367                 //secondPrevBx->print();
00368               }
00369             }
00370             
00371             else if( config()->TsmGetCarryFlag()==2 ) {  // neglect first tk if it is a low uncorrelated trigger
00372               existSecondPrevBx = ((is-1-DTConfigTSPhi::NSTEPF>=0) && (ntsm[is-1-DTConfigTSPhi::NSTEPF][i_tsmd] >1) && (secondPrevBx->tracoTr()->code()>0));
00373               if( (!existSecondPrevBx) || first->isHtrig() || first->isCorr()) {
00374                 ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at current BX. 
00375                 // SM sector collector: Load DTSectColl with output of DTTSM
00376                 _cache.push_back(DTChambPhSegm(ChamberId(),is,(*p_tsm)->getTrack(1)->tracoTr(),1));
00377                 //              (*p_tsm)->getTrack(1)->print();
00378                 
00379                 if((*p_tsm)->nTracks()>1)   {  // there is a 2nd tk
00380                   ntsm[is-DTConfigTSPhi::NSTEPF][i_tsmd]++;
00381                   if((*p_tsm)->getTrack(2)->tracoTr()->code()>0) {   // check if its code > 0
00382                     secondPrevBx=(*p_tsm)->getTrack(2) ;   // assign second tk of previous BX
00383                   }
00384                 }
00385               }
00386               else {
00387                 ntsm[is-1-DTConfigTSPhi::NSTEPF][i_tsmd]++;  // SM increment ntsm at previous BX. 
00388                 _cache.push_back(DTChambPhSegm(ChamberId(),is-1,secondPrevBx->tracoTr(),2));
00389                 //              secondPrevBx->print(); 
00390               }
00391             }
00392           }
00393         }
00394 
00395 
00396       }      
00397       else if ( ((*p_tsm)->nCand(1) == 0) && (is-1-DTConfigTSPhi::NSTEPF>=0) && ntsm[is-1-DTConfigTSPhi::NSTEPF][i_tsmd] > 0 ) {// it means that the last BX with sort 2 was not the previous one
00398         existSecondPrevBx = ((is-1-DTConfigTSPhi::NSTEPF>=0) && (ntsm[is-1-DTConfigTSPhi::NSTEPF][i_tsmd]>1) && (secondPrevBx->tracoTr()->code()>0));
00399         if(existSecondPrevBx) {
00400           _cache.push_back(DTChambPhSegm(ChamberId(),is-1,secondPrevBx->tracoTr(),2));
00401           
00402           //      secondPrevBx->print();
00403         }
00404       }
00405     } 
00406       //---
00407     
00408   }   // end loop on step  
00409   // debugging...
00410   if(config()->debug()){
00411     if(_cache.size()>0){
00412       std::cout << "====================================================" << std::endl;
00413       std::cout << "                  Phi segments                     " << std::endl;
00414       std::vector<DTChambPhSegm>::const_iterator p;
00415       for(p=_cache.begin();p<_cache.end();p++) {
00416         p->print();
00417         
00418       }
00419       std::cout << "====================================================" << std::endl;
00420     }
00421   }
00422   //  end debugging
00423   
00424   
00425 }
00426 
00427 void
00428 DTTSPhi::ignoreSecondTrack(int step, int tracon) {
00429   
00430   int itsmd = 1; // initialize it to default
00431   
00432   if(step<DTConfigTSPhi::NSTEPF||step>DTConfigTSPhi::NSTEPL){
00433     std::cout << "DTTSPhi::ignoreSecondTrack: step out of range: " << step;
00434     std::cout << " no flag set!" << std::endl;
00435     return;
00436   }
00437   int itss = (tracon-1 ) / DTConfigTSPhi::NTCTSS + 1;
00438   if(itss<1 || itss>DTConfigTSPhi::NTSSTSM) {
00439     std::cout << "DTTSPhi::ignoreSecondTrack: wrong TRACO number: " << tracon;
00440     std::cout << " no flag set!" << std::endl;
00441     return;
00442   }
00443   DTTSS* tss = getDTTSS(step,itss);
00444   tss->ignoreSecondTrack();
00445   
00446   int bkmod = config()->TsmStatus().element(0);
00447   if (bkmod==0) {  // we are in back-up mode
00448     
00449     int ntsstsmd = config()->TSSinTSMD(station(),sector());
00450     // Get the appropriate TSMD
00451     itsmd = (itss -1 ) / ntsstsmd + 1;
00452     
00453   } 
00454   
00455   DTTSM* tsm = getDTTSM(step,itsmd);
00456   tsm->ignoreSecondTrack();
00457 }
00458 
00459 DTTSS*
00460 DTTSPhi::getDTTSS(int step, unsigned n) const {
00461   if(step<DTConfigTSPhi::NSTEPF||step>DTConfigTSPhi::NSTEPL){
00462     std::cout << "DTTSPhi::getDTTSS: step out of range: " << step;
00463     std::cout << " empty pointer returned!" << std::endl;
00464     return 0;
00465   }
00466   if(n<1 || n>_tss[step-DTConfigTSPhi::NSTEPF].size()){
00467     std::cout << "DTTSPhi::getDTTSS: requested DTTSS not present: " << n;
00468     std::cout << " (at step " << step << ")";
00469     std::cout << " empty pointer returned!" << std::endl;
00470     return 0;
00471   }
00472   
00473   std::vector<DTTSS*>::const_iterator p = _tss[step-DTConfigTSPhi::NSTEPF].begin()+n-1;
00474   return *p;
00475   
00476   
00477 }
00478 
00479 
00480 DTTSM*
00481 DTTSPhi::getDTTSM(int step, unsigned n) const {
00482   if(step<DTConfigTSPhi::NSTEPF||step>DTConfigTSPhi::NSTEPL){
00483     std::cout << "DTTSPhi::getDTTSM: step out of range: " << step;
00484     std::cout << " empty pointer returned!" << std::endl;
00485     return 0;
00486   }
00487   if(n<1 || n>_tsm[step-DTConfigTSPhi::NSTEPF].size()){
00488     std::cout << "DTTSPhi::getDTTSM: requested DTTSM not present: " << n;
00489     std::cout << " (at step " << step << ")";
00490     std::cout << " empty pointer returned!" << std::endl;
00491     return 0;
00492   }
00493   std::vector<DTTSM*>::const_iterator p_tsm = _tsm[step-DTConfigTSPhi::NSTEPF].begin()+n-1;
00494   return *p_tsm;
00495 }
00496 
00497 
00498 
00499 int 
00500 DTTSPhi::nSegm(int step) {
00501   int n=0;
00502   std::vector<DTChambPhSegm>::const_iterator p; //p=0;
00503   for(p=begin(); p<end(); p++) {
00504     if(p->step()==step)n++;
00505   }
00506   return n;
00507 }
00508 
00509 const DTChambPhSegm*
00510 DTTSPhi::segment(int step, unsigned n) {
00511   std::vector<DTChambPhSegm>::const_iterator p; //p=0;
00512   for(p=begin();p<end();p++){
00513     if(p->step()==step&&((n==1&&p->isFirst())||(n==2&&!p->isFirst())))
00514       return  &(*p);// p;
00515   }
00516   return 0;
00517 }
00518 
00519 LocalPoint 
00520 DTTSPhi::localPosition(const DTTrigData* tr) const {
00521   //@@ patch for Sun 4.2 compiler
00522   //sm DTChambPhSegm* trig = dynamic_cast<DTChambPhSegm*>(const_cast<DTTrigData*>(tr));
00523     const DTChambPhSegm* trig = dynamic_cast<const DTChambPhSegm*>(tr);
00524   if(!trig) {
00525     std::cout << "DTTSPhi::LocalPosition called with wrong argument!" << std::endl;
00526     return LocalPoint(0,0,0);
00527   }
00528      return _tracocard->localPosition(trig->tracoTrig());
00529 }
00530 
00531 LocalVector 
00532 DTTSPhi::localDirection(const DTTrigData* tr) const  {
00533   DTChambPhSegm* trig = dynamic_cast<DTChambPhSegm*>(const_cast<DTTrigData*>(tr));
00534   //  const DTChambPhSegm* trig = dynamic_cast<const DTChambPhSegm*>(tr);
00535   if(!trig) {
00536     std::cout << "DTTSPhi::LocalDirection called with wrong argument!" << std::endl;
00537     return LocalVector(0,0,0);
00538   }
00539     return _tracocard->localDirection(trig->tracoTrig());
00540 }