CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/L1Trigger/DTTraco/src/DTTracoChip.cc

Go to the documentation of this file.
00001 //-------------------------------------------------------------
00002 //
00003 //   Class: DTTracoChip
00004 //
00005 //   Description: Implementation of TRACO
00006 //                trigger algorithm
00007 //
00008 //
00009 //   Author List:
00010 //   SV 4/II/2003
00011 //   Modifications: 
00012 //   22/VI/04 SV : last trigger code update
00013 //   16/I/07  SV : new DTConfig update
00014 //   3/IV/07  SV : setTracoAcceptance moved from card to chip
00015 //   30/10/09 SV : lut parameters from DB are used in code
00016 //   110208 SV   : TRACO hardware bug included
00017 //------------------------------------------------------------
00018 
00019 //-----------------------
00020 // This Class's Header --
00021 //-----------------------
00022 #include "L1Trigger/DTTraco/interface/DTTracoChip.h"
00023 
00024 //-------------------------------
00025 // Collaborating Class Headers --
00026 //-------------------------------
00027 #include "L1Trigger/DTTraco/interface/DTTracoCard.h"
00028 #include "L1Trigger/DTBti/interface/DTBtiTrigData.h"
00029 #include "L1Trigger/DTTraco/interface/DTTracoTrig.h"
00030 #include "L1Trigger/DTTraco/interface/DTTracoTrigData.h"
00031 #include "L1Trigger/DTTriggerServerTheta/interface/DTTSTheta.h"
00032 #include "L1Trigger/DTTraco/interface/DTTracoCand.h"
00033 #include "L1TriggerConfig/DTTPGConfig/interface/BitArray.h"
00034 
00035 //---------------
00036 // C++ Headers --
00037 //---------------
00038 #include <iostream>
00039 #include <cmath>
00040 #include <algorithm>
00041 #include <string>
00042 
00043 //----------------
00044 // Constructors --
00045 //----------------
00046 
00047 DTTracoChip::DTTracoChip(DTTracoCard* card, int n, DTConfigTraco* conf) :
00048                                 _card(card), _config(conf) {
00049 
00050   _geom = _card->geom();
00051 
00052   // n=traco number 1,2,...
00053   if(config()->debug()==4){
00054     std::cout << "DTTracoChip constructor called for TRACO number " << n << std::endl;
00055   }
00056 
00057   // set acceptances from CMSSW geometry
00058   setTracoAcceptances();
00059   
00060   // reserve the appropriate amount of space for vectors
00061   int i=0;
00062   for(i=0;i<DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF;i++) {
00063     _innerCand[i].reserve(DTConfigTraco::NBTITC);
00064     _outerCand[i].reserve(3*DTConfigTraco::NBTITC);
00065     _tracotrig[i].reserve(2);
00066   }
00067  
00068   // the identifier
00069   DTChamberId sid = _geom->statId();
00070   _id = DTTracoId(sid,n);
00071  
00072   // Flags for LTS
00073   _bxlts.zero();
00074   for(int is=0;is<DTConfigTraco::NSTEPL-DTConfigTraco::NSTEPF+1;is++){
00075     _flag[is].zero();
00076   }
00077 
00078   // debugging
00079   if(config()->debug()==4){
00080     std::cout << "CMS position:" << CMSPosition() << std::endl;
00081     std::cout << " psiRad=" << psiRad() << " KRad=" << KRad() << std::endl;
00082   }
00083 
00084   //init traco parameters from traco config file
00085   _krad = config()->KRAD();
00086   _btic=config()->BTIC(); 
00087 
00088   //offset from geometry (x1-x3 FE view): converted from cm to ST units (0.9999 for rounding)
00089   _ibtioff=static_cast<int>(config()->BTIC()/(_geom->cellPitch())*(_geom->phiSLOffset()/0.9999));  
00090 
00091   // 091030 SV lut parameters from DB
00092   // SV 08/12/12 : added flag for computing luts from DB parameters
00093   if( _card->lutFromDBFlag()==1 )
00094   {
00095     //int board = int( (n-1)/4 );
00096     //int traco = int(fmod( double(n-1),4.));
00097     // 110208 SV for TRACO hardware bug included SL_shift
00098     // SL shift
00099     float xBTI1_3       = _geom->localPosition( DTBtiId(DTSuperLayerId(sid.wheel(),sid.station(),sid.sector(),3),1) ).x();
00100     float xBTI1_1       = _geom->localPosition( DTBtiId(DTSuperLayerId(sid.wheel(),sid.station(),sid.sector(),1),1) ).x();
00101     float SL_shift      = xBTI1_3 - xBTI1_1;
00102 
00103     _lutsCCB = new Lut(_card->config_luts(),n,SL_shift);
00104     _luts = 0;
00105   }
00106   else
00107   //this is always the case with new DTConfig SV 15/I/2007
00108   //if( config()->trigSetupGeom()==0 ){
00109   {
00110     _luts = 0;
00111     _lutsCCB = 0;
00112   }
00113 /*
00114   //SV 21/V/03 for testbeam purpose: parameters from hardware setup
00115   if(config()->trigSetupGeom()==1){
00116     //init traco parameters
00117     _dd=config()->DD();
00118     _krad=config()->KRAD();
00119     _btic=config()->BTIC();
00120     _ibtioff=config()->IBTIOFF();
00121 
00122     //const char* testfile = "traco";   //FIXTB 
00123     std::string  testfile = "traco_";
00124     int it = number() - 4 - 1;
00125     if(it<10)
00126       testfile += it+'0';
00127     if(it>9){
00128       testfile += int(float(it)/10.0) + '0';                //add decimal char
00129       testfile += int(fmod(float(it),float(10))) + '0';     //add unit char
00130     }
00131 
00132     //const char* name = testfile;
00133     if(config()->debug()==4)
00134       std::cout << "Loading " << testfile << " luts for traco " << number() << std::endl;
00135     _luts = new DTTracoLUTs(testfile);
00136     _luts->reset();
00137     _luts->load();
00138     if(config()->debug()==4)
00139       _luts->print();
00140   }//end hardware setup
00141 
00142   //TB 2004 setup : luts from minicrate ccb equations
00143   if(config()->trigSetupGeom()==2){
00144     int board = int( (n-1)/4 );
00145     int traco = fmod( double(n-1),4. );
00146     _lutsCCB = new Lut(sid.station(),board,traco);
00147     // 091030 SV this constructur is obsolete now, use setForTestBeam instead
00148   }//end TB2004
00149 */
00150 }
00151 
00152 
00153 DTTracoChip::DTTracoChip(const DTTracoChip& traco) : 
00154   _geom(traco._geom), _id(traco._id), _card(traco._card), _luts(traco._luts) {
00155   int i=0;
00156   for(i=0;i<DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF;i++) {
00157     _innerCand[i].reserve(DTConfigTraco::NBTITC);
00158     std::vector<DTTracoCand>::const_iterator p;
00159     for(p=traco._innerCand[i].begin();p<traco._innerCand[i].end();p++) {
00160       _innerCand[i].push_back(*p);
00161     }
00162     _outerCand[i].reserve(3*DTConfigTraco::NBTITC);
00163     for(p=traco._outerCand[i].begin();p<traco._outerCand[i].end();p++) {
00164       _outerCand[i].push_back(*p);
00165     }
00166     _tracotrig[i].reserve(2);
00167     std::vector<DTTracoTrig*>::const_iterator p1;
00168     for(p1=traco._tracotrig[i].begin();p1<traco._tracotrig[i].end();p1++) {
00169       _tracotrig[i].push_back(*p1);
00170     }
00171   }
00172   _bxlts = traco._bxlts;
00173   for(int is=0;is<DTConfigTraco::NSTEPL-DTConfigTraco::NSTEPF+1;is++){
00174     _flag[is] = traco._flag[is];
00175   }
00176 
00177 }
00178 
00179 
00180 //--------------
00181 // Destructor --
00182 //--------------
00183 DTTracoChip::~DTTracoChip(){
00184   clear();
00185   /*
00186   if(config()->trigSetupGeom()==1){
00187     _luts->reset();
00188     delete _luts;
00189   }
00190 
00191   if(config()->trigSetupGeom()==2)
00192     delete _lutsCCB;
00193   */
00194 
00195   if( _card->lutFromDBFlag()==1 )
00196     delete _lutsCCB;
00197 
00198 }
00199 
00200 //--------------
00201 // Operations --
00202 //--------------
00203 
00204 DTTracoChip&
00205 DTTracoChip::operator=(const DTTracoChip& traco) {
00206   if(this != &traco){
00207     _geom = traco._geom;
00208     _id = traco._id;
00209     _card = traco._card;
00210     int i=0;
00211     for(i=0;i<DTConfigTraco::NSTEPL - DTConfigTraco::NSTEPF;i++) {
00212       _innerCand[i].reserve(DTConfigTraco::NBTITC);
00213       std::vector<DTTracoCand>::const_iterator p;
00214       for(p=traco._innerCand[i].begin();p<traco._innerCand[i].end();p++) {
00215         _innerCand[i].push_back(*p);
00216       }
00217       _outerCand[i].reserve(3*DTConfigTraco::NBTITC);
00218       for(p=traco._outerCand[i].begin();p<traco._outerCand[i].end();p++) {
00219         _outerCand[i].push_back(*p);
00220       }
00221       _tracotrig[i].reserve(2);
00222       std::vector<DTTracoTrig*>::const_iterator p1;
00223       for(p1=traco._tracotrig[i].begin();p1<traco._tracotrig[i].end();p1++) {
00224         _tracotrig[i].push_back(*p1);
00225       }
00226     }
00227     _bxlts = traco._bxlts;
00228     for(int is=0;is<DTConfigTraco::NSTEPL-DTConfigTraco::NSTEPF+1;is++){
00229       _flag[is] = traco._flag[is];
00230     }
00231   }
00232   return *this;
00233 }
00234 
00235 
00236 void
00237 DTTracoChip::clear() {
00238 
00239   std::vector<DTTracoTrig*>::iterator p1;
00240   for(int is=0;is<DTConfigTraco::NSTEPL-DTConfigTraco::NSTEPF+1;is++){
00241     for(p1=_tracotrig[is].begin();p1<_tracotrig[is].end();p1++){
00242       delete (*p1);
00243     }
00244     _tracotrig[is].clear();
00245     _innerCand[is].clear();
00246     _outerCand[is].clear();
00247     _flag[is].zero();
00248   }
00249   _bxlts.zero();
00250 }
00251 
00252 
00253 
00254 void
00255 DTTracoChip::run() {
00256 
00257   // Debugging...
00258   if(config()->debug()>1){
00259     std::cout << "DTTracoChip::run: Processing TRACO " << _id.traco() << std::endl;
00260   }
00261   // End debugging
00262 
00263   int maxtc = static_cast<int>(ceil( float(geom()->nCell(1)) / float(DTConfigTraco::NBTITC) ));
00264 
00265   if( _id.traco()<1 || _id.traco()>maxtc ) {
00266     if(config()->debug()==4)
00267       std::cout << "DTTracoChip::run: wrong TRACO number " << _id.traco() << std::endl;
00268     return;
00269   }
00270 
00271   // Loop on step
00272   for(int is=DTConfigTraco::NSTEPF; is<=DTConfigTraco::NSTEPL;is++) {
00273     if(config()->debug()>1){
00274       std::cout << "\n STEP: " << is << std::endl;
00275       std::cout << " ================" << std::endl;
00276     }
00277 
00278     // skip if no cand. at this step
00279     if(_innerCand[is-DTConfigTraco::NSTEPF].size()<1 &&
00280        _outerCand[is-DTConfigTraco::NSTEPF].size()<1 ) 
00281       continue;
00282 
00283     // Debugging...
00284     if(config()->debug()==4){
00285       std::cout << " --> " << _innerCand[is-DTConfigTraco::NSTEPF].size()+
00286                          _outerCand[is-DTConfigTraco::NSTEPF].size();
00287       std::cout << " candidates " << std::endl;
00288     }
00289     // End debugging
00290 
00291     // Multiple trigger detection between consecutive TRACO's  
00292     setFlag(is);
00293 
00294     //check if there is a H in bx for LVALIDIFH flag
00295     if(config()->LVALIDIFH()){
00296       for(unsigned int e=0; e<_innerCand[is-DTConfigTraco::NSTEPF].size(); e++) {
00297         if(_innerCand[is-DTConfigTraco::NSTEPF][e].BtiTrig()->code()==8){
00298           _flag[is-DTConfigTraco::NSTEPF].set(9);
00299           break;
00300         }
00301       }
00302       for(unsigned int e=0; e<_outerCand[is-DTConfigTraco::NSTEPF].size(); e++) {
00303         if(_outerCand[is-DTConfigTraco::NSTEPF][e].BtiTrig()->code()==8){
00304           _flag[is-DTConfigTraco::NSTEPF].set(9);
00305           break;
00306         }
00307       }
00308     }
00309    
00310     // Loop over first/second tracks
00311     //for(int itk=0; itk < DTConfigTraco::NMAXCAND; itk++){ 
00312     // FIX this hardcoded 2!! 
00313     for(int itk=0; itk < 2; itk++){ 
00314     
00315       // Get the best inner and outer segments 
00316       if(config()->debug()==4)
00317         std::cout << "Inner:" << std::endl;
00318       DTTracoCand* inner = bestCand(itk,_innerCand[is-DTConfigTraco::NSTEPF]);
00319       if(config()->debug()==4)
00320         std::cout << "Outer:" << std::endl;
00321       DTTracoCand* outer = bestCand(itk,_outerCand[is-DTConfigTraco::NSTEPF]);
00322 
00323       //debug
00324       if(config()->debug()>1){
00325         if(inner || outer)
00326            std::cout<<"Best candidates for track " << itk+1 << " are:"<<std::endl;
00327         if(inner){ 
00328           std::cout<<"inner->";
00329           inner->print();
00330         }
00331         if(outer){
00332           std::cout<<"outer->";
00333           outer->print();
00334         }
00335       }
00336 
00337       // Skip to next step if no suitable candidates found
00338       if(inner==0&&outer==0)
00339         break;
00340 
00341       // suppression of LTRIG on BTI close to selected HTRIG
00342       // SV 24/IX/03 : AND suppression of LTRIG close to H in adiacent Traco
00343       // SV 31/III/03 : test : only if htprf is off--> NO, it's worse
00344       // if( config()->prefHtrig(0) && config()->prefHtrig(1) ){
00345         if(inner){
00346           DoAdjBtiLts( inner, _innerCand[is-DTConfigTraco::NSTEPF] );
00347         }
00348         if(outer){
00349           DoAdjBtiLts( outer, _outerCand[is-DTConfigTraco::NSTEPF] );
00350         }
00351       //}
00352 
00353       // set candidates unusable by further steps
00354       if(inner)inner->setUsed(); 
00355       if(outer)outer->setUsed(); 
00356       // Create a new TRACO trigger with preview for TS
00357       DTTracoTrig* tct = setPV(itk,inner,outer);
00358 
00359       // skip if no TRACO trigger has been created with this trigger
00360       if(!tct) break; // something nasty happened. Go to next step
00361 
00362       // try a correlation between segments
00363       int stored = 0;
00364       if(inner && outer) {
00365         stored = storeCorr(tct,inner,outer,itk);
00366       }
00367 
00368       if (!stored) { 
00369         // No suitable candidate found or no correlation possible
00370         // Fill single trigger
00371         stored = storeUncorr(tct,inner,outer,itk);
00372       }
00373 
00374       // if trigger has been filled store it in TRACO, otherway delete it
00375       if (stored) {
00376         addTrig(is,tct);
00377       } else {
00378         delete tct;
00379         //break;-> II track is computed even if no I track found...
00380       }
00381 
00382     } // end loop on first/second track
00383 
00384     // Inhibit second track at previous bunch crossing
00385     if(config()->debug()==4)
00386       std::cout<<"Checking overlap I-II track..." <<std::endl;
00387     if(_tracotrig[is-DTConfigTraco::NSTEPF].size()>0 && is>DTConfigTraco::NSTEPF
00388       && (_tracotrig[is-DTConfigTraco::NSTEPF])[0]->isFirst() ) {    //I track at bx
00389       if(nTrig(is-1)>0) {                                           //there is a track at bx-1
00390         if( !(trigger(is-1,1)->isFirst())  ||                       //trig 1 is II track
00391              ( nTrig(is-1)==2 && !(trigger(is-1,2)->isFirst()) )) { //trig 2 is II track
00392           raiseOverlap(is);
00393           if(config()->debug()==4){
00394             std::cout << "II track at step " << std::hex << is-1 <<std::dec << "marked rej."<< std::endl;
00395             std::cout << "I track overlap flag at step " << std::hex << is << std::dec << " setted" << std::endl;
00396           }
00397         }
00398       }
00399     }
00400     //debug...
00401     for(int isd=0;isd<=DTConfigTraco::NSTEPL-DTConfigTraco::NSTEPF+1;isd++)
00402       if(config()->debug()==4){
00403         std::cout << "overlap flag step = " << isd+DTConfigTraco::NSTEPF << 
00404            "  " << _flag[isd].element(1) << std::endl;
00405       }
00406     // debugging...
00407     if(config()->debug()>0){    
00408       if(nTrig(is)>0) {
00409         for(int cc=1;cc<=nTrig(is);cc++){
00410           trigger(is,cc)->print();
00411         }
00412       }
00413     }// end debugging
00414   }// end loop on step
00415 }
00416 
00417 
00418 void
00419 DTTracoChip::raiseOverlap(int step){
00420     _flag[step-DTConfigTraco::NSTEPF].set(1);                    //overlap flag raised
00421     _flag[step-DTConfigTraco::NSTEPF-1].set(2);                  //mark II rej.
00422 }
00423 
00424 
00425 void
00426 DTTracoChip::setFlag(int step, int ext) {
00427 
00428   if(ext==0){
00429     //this is the original: flags from card
00430     DTTracoChip* prevTraco = _card->getTRACO(_id.traco()-1);
00431     if(prevTraco!=0){
00432       if(prevTraco->edgeBTI(step,1,2))
00433         _flag[step-DTConfigTraco::NSTEPF].set(3);
00434       if(prevTraco->edgeBTI(step,2,2))
00435         _flag[step-DTConfigTraco::NSTEPF].set(5);
00436     }
00437     DTTracoChip* nextTraco = _card->getTRACO(_id.traco()+1);
00438     if(nextTraco!=0){
00439       if(nextTraco->edgeBTI(step,1,1))
00440         _flag[step-DTConfigTraco::NSTEPF].set(4);
00441       if(nextTraco->edgeBTI(step,2,1))
00442         _flag[step-DTConfigTraco::NSTEPF].set(6);
00443     }
00444   }
00445   else{
00446     //SV III/03: flags from input EXT: only for testing purpose
00447     for(int i=0;i<6;i++){
00448       int ibit = ext >> i;
00449       if(ibit & 0x01)   // bit i+1 -> flag 3,4,5,6 : IL,IR,OL,OR
00450         _flag[step-DTConfigTraco::NSTEPF].set(i+1 + 2);
00451     }
00452   }
00453 
00454   //debug:
00455   if(config()->debug()==4){
00456     std::cout << "Flags set for bx=" << step << std::endl;
00457     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(1)<< "  ";
00458     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(2)<< "  ";
00459     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(3)<< "  ";
00460     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(4)<< "  ";
00461     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(5)<< "  ";
00462     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(6)<< "  ";
00463     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(7)<< "  ";
00464     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(8)<< "  ";
00465     std::cout << _flag[step-DTConfigTraco::NSTEPF].element(9)<< "  "<<std::endl;
00466   } //end debugging
00467 }
00468 
00469 
00470 DTTracoCand*
00471 DTTracoChip::bestCand(int itk, std::vector<DTTracoCand> & tclist) {
00472 
00473   // Return if no candidates
00474   if(tclist.size()<1) return 0;
00475 
00476   // stl function: sort in Ktc ascending or descending order according 
00477   // to user request comparing by default with user-defined <
00478   // NB don't reverse if candidates are two with same K
00479   stable_sort( tclist.begin(),tclist.end() ); //0=K ascending, 1=K descending
00480   if(config()->sortKascend(itk) &&
00481      !(tclist.size()==2 && tclist[0].K()==tclist[1].K()) ) {
00482      reverse( tclist.begin(),tclist.end() );
00483      if(config()->debug()==4)
00484        std::cout << "Reversing order of sorted candidate list..." << std::endl;
00485   }
00486 
00487   /*
00488   if(!config()->sortKascend(itk)){
00489     stable_sort( tclist.begin(),tclist.end(),DTTracoCand::closer );
00490   } else {
00491     stable_sort( tclist.begin(),tclist.end(),DTTracoCand::wider );
00492   }
00493  */
00494 
00495  // debugging...
00496  if(config()->debug()==4){
00497     std::cout << "DTTracoChip::findBest - Looking for track number " << itk+1 << std::endl ;
00498     std::cout << "Sorted std::vector of usable track candidates is:" << std::endl;
00499     int i = 1;
00500     for(std::vector<DTTracoCand>::iterator p=tclist.begin();p<tclist.end();p++){
00501       if((*p).usable()){
00502         std::cout << " DTTracoChip Candidate # " << i++;
00503         (*p).print();
00504       }
00505     }
00506     std::cout << "--------------------------------------------------" << std::endl;
00507   }
00508   // end debugging
00509 
00510   // return the best candidate
00511   int i=0;
00512   DTTracoCand* bestltrig = 0;
00513   std::vector<DTTracoCand>::iterator p;
00514   for ( p = tclist.begin(); p < tclist.end(); ++p ) {
00515     i++;
00516     // candidate must be usable and not suppressed by LTS
00517     if(AdjBtiLTSuppressed(&(*p))) 
00518       if(config()->debug()==4) 
00519         std::cout << "Candidate # " << i << " supp. because next to H in adiacent Tracos" << std::endl;
00520     if ( (*p).usable() && !AdjBtiLTSuppressed(&(*p)) ) {
00521       // check if preference to HTRIG is set and return first trigger
00522       if( !config()->prefHtrig(itk) ) return &(*p);
00523       if( (*p).BtiTrig()->code()==8 ) return &(*p);
00524       if( bestltrig==0 ) bestltrig=&(*p);
00525     }
00526   }
00527   return bestltrig;
00528 
00529 }
00530 
00531 void
00532 DTTracoChip::DoAdjBtiLts(DTTracoCand* candidate, std::vector<DTTracoCand> & tclist) {
00533   // If requested, do suppression of LTRIG on BTI close to selected HTRIG in same traco
00534   //if(!(config()->adjBtiLts()) && candidate->BtiTrig()->code()==8) {
00535   // SV this is done always, not parametrized !! 
00536   if(candidate->BtiTrig()->code()==8) {
00537     std::vector<DTTracoCand>::iterator p;
00538     for(p=tclist.begin();p<tclist.end();p++){
00539       if( (*p).BtiTrig()->code()<8 &&
00540           abs(       (*p).BtiTrig()->btiNumber() -
00541                candidate->BtiTrig()->btiNumber() ) < 2 ) {
00542         (*p).setUsed();
00543         if(config()->debug()==4){
00544           std::cout << "Candidate :";
00545           (*p).print();
00546           std::cout << "Suppressed because adiacent to H trig" <<std::endl;
00547         } // end debug
00548       } // end if
00549     } // end candidate loop 
00550   } // end if H
00551 }
00552 
00553 int
00554 DTTracoChip::AdjBtiLTSuppressed(DTTracoCand* candidate) {
00555   // If requested, do suppression of LTRIG on adjacent BTI -> obsolete!
00556   //if(!(config()->adjBtiLts()) && candidate->BtiTrig()->code()<8) {
00557   //SV: Ltrig always suppressed in hardware if Htrig in adj traco!
00558     if(candidate->BtiTrig()->code()<8) {
00559       if( _flag[candidate->step()-DTConfigTraco::NSTEPF].element(3) &&
00560         candidate->position()==1 )                                   return 1;
00561       if( _flag[candidate->step()-DTConfigTraco::NSTEPF].element(4) &&
00562         candidate->position()==DTConfigTraco::NBTITC )                return 1;
00563       if( _flag[candidate->step()-DTConfigTraco::NSTEPF].element(5) &&
00564         candidate->position()== DTConfigTraco::NBTITC+1)              return 1;
00565       if( _flag[candidate->step()-DTConfigTraco::NSTEPF].element(6) &&
00566         candidate->position()==DTConfigTraco::NBTITC*4 )              return 1;
00567     }
00568   //}
00569   return 0;
00570 }
00571 
00572 DTTracoTrig*
00573 DTTracoChip::setPV(int itk, DTTracoCand* inner, DTTracoCand* outer) {
00574 
00575   // debugging...
00576   if(config()->debug()==4){
00577     std::cout << "DTTracoChip::setPV called for candidates : " << std::endl;
00578     if(inner)inner->print();
00579     if(outer)outer->print();
00580     std::cout << "--------------------------------------------------" << std::endl;
00581   }
00582   //end debugging
00583 
00584   // first or second track. This is tricky:
00585   // itk=0 menas first track  ==> first= true=1
00586   // itk=1 menas second track ==> first=false=0
00587   int first = (itk==0) ? 1 : 0;
00588 
00589   //preview selector: the same as priority selector I !!
00590   // select which of the inner/outer segments should be used
00591 
00592   DTTracoCand* candidate=0;  
00593   if(inner!=0&&outer!=0) {
00594 //    if(config()->prefHtrig(itk)){   
00595 //    ---> BUG! selection is ALWAYS for H trigs
00596 //    ---> fixed by Sara Vanini 25/III/03
00597       if(inner->BtiTrig()->code()==8 && outer->BtiTrig()->code()<8 ){
00598         candidate=inner;
00599       } else if(inner->BtiTrig()->code()<8  && outer->BtiTrig()->code()==8){
00600         candidate=outer;
00601       } else { //for same quality tracks, pref. to in/out selection
00602         if(!config()->prefInner(itk)) {
00603           candidate=inner;
00604         } else {
00605           candidate=outer;
00606         }
00607       }
00608 //    } //end if(config()->prefHtrig...
00609 /*
00610     else {
00611       if(!config()->prefInner(itk)) {
00612         candidate=inner;
00613       } else {
00614         candidate=outer;
00615       }
00616     }
00617 */
00618   } else if(inner==0&&outer!=0) {
00619     candidate=outer;
00620   } else if(inner!=0&&outer==0) {
00621     candidate=inner;
00622   } else {
00623     return 0; // no candidates 
00624   }
00625 
00626   // create new trigger with this candidate
00627   DTTracoTrig* tct = new DTTracoTrig(this, candidate->step());
00628   // store preview for TS
00629   int cod = candidate->BtiTrig()->code();
00630   if(candidate->BtiTrig()->btiSL()==1) cod *= 10;
00631   // k output is 5 bits!!! SV
00632   int K=candidate->K();
00633   if(K>31)
00634     K-=32;
00635   int ioflag = 0;
00636   if(candidate->position()>4)
00637     ioflag = 1;
00638   tct->setPV(first, cod, K, ioflag); // this is already BTI_K-KRAD
00639 
00640   if(config()->debug()==4){
00641     std::cout << "Selected candidate stored for preview is: ";
00642     candidate->print();
00643   }
00644   return tct;
00645 }
00646 
00647 int
00648 DTTracoChip::storeCorr(DTTracoTrig* tctrig, DTTracoCand* inner, DTTracoCand* outer, int tkn) {
00649 
00650   // Bunch crossing
00651   int is = tctrig->step();
00652 
00653   // Debugging...
00654   if(config()->debug()==4){
00655     std::cout << "DTTracoChip::storeCorr called with candidates: " << std::endl;
00656     if(inner)inner->print();
00657     if(outer)outer->print();
00658     std::cout << "--------------------------------------------------" << std::endl;
00659   }
00660   // End debugging
00661 
00662   //old orca shift definition
00663   float shift = 0.;
00664   //if( config()->trigSetupGeom()!=1 )
00665     shift = (int)( _geom->distSL()/_geom->cellH() + 0.5 );
00666   //else
00667     //shift = DD();
00668  
00669   int kcor = 9999;
00670   int xcor = 0;
00671   int icor = 0;
00672 
00673   // Check correlation only if --> this cuts LL follow by H in next 4 bx
00674   // SV 1/IV/04 BUG FIX: this cuts LL preview also, traco outputs preview when LTS cut!!!
00675   //if( !config()->TcBxLts() ||          // BX LTS is not enabled or
00676   //    !_bxlts.element(is) ||           // no HTRIG in next 4 BX or
00677   //    inner->BtiTrig()->code()==8 ||   // inner track is HTRIG  or
00678   //    outer->BtiTrig()->code()==8 ){   // outer track is HTRIG
00679   //otherwise in and out trig are L, and necessary one is suppressed for LTS  
00680 
00681     int xq1 = inner->X();
00682     int xq2 = outer->X();
00683     xcor = (xq2+xq1)/2;
00684     kcor = (xq1-xq2)+512;
00685     int kq1 = int(shift/2.) * (inner->BtiTrig()->K()-BTIC()) + 512;
00686     int kq2 = int(shift/2.) * (outer->BtiTrig()->K()-BTIC()) + 512;
00687     //int kd1 = abs(kcor/16-kq1/16);
00688     //int kd2 = abs(kcor/16-kq2/16);
00689     int kd1 = abs(kcor/16-kq1/16);
00690     int kd2 = abs(kcor/16-kq2/16);
00691   
00692     icor =  kd1<=config()->TcKToll(tkn) && 
00693             kd2<=config()->TcKToll(tkn) && 
00694             xcor>0;
00695  
00696     // Debugging...
00697     if(config()->debug()==4){
00698       std::cout << "*************************************************************";
00699       std::cout << std::endl;
00700       std::cout << " shift = " << shift;
00701       std::cout << " xq1 = " << xq1;
00702       std::cout << " xq2 = " << xq2;
00703       std::cout << " xcor = " << xcor;
00704       std::cout << " kcor = " << kcor;
00705       std::cout << " kq1 = " << kq1;
00706       std::cout << " kq2 = " << kq2;
00707       std::cout << " kd1 = " << kd1;
00708       std::cout << " kd2 = " << kd2;
00709       std::cout << " icor = " << icor;
00710       std::cout << std::endl;
00711       std::cout << "*************************************************************";
00712       std::cout << std::endl;
00713     }// End debugging
00714 
00715   //}//end if TcBxLts....
00716 
00717   if(icor){
00718     // correlation was successfull
00719     // set the preview correlation bit. It isn't reset if outside ang. window
00720     tctrig->setPVCorr(1);
00721     // set K and X
00722     tctrig->setK(kcor - 512);
00723     //std::cout<<"Set K " << kcor << " instead of " << kcor-512 << std::endl;
00724     //tctrig->setK(kcor);
00725     tctrig->setX(xcor);
00726     // set codes
00727     tctrig->setCodeIn( inner->BtiTrig()->code());
00728     tctrig->setCodeOut(outer->BtiTrig()->code());
00729     // set position mask
00730     //tctrig->setPosIn(inner->position());
00731     //tctrig->setPosOut(outer->position());
00732     //SV number of bti instead of position...
00733     tctrig->setPosIn( inner->BtiTrig()->btiNumber() );
00734     tctrig->setPosOut( outer->BtiTrig()->btiNumber() );
00735     //SV store also equation: pattern numbers are 1-32
00736     tctrig->setEqIn( inner->BtiTrig()->eq() + 1 ); 
00737     tctrig->setEqOut( outer->BtiTrig()->eq() + 1 );
00738 
00739     // calculate psi, psi_r and Delta(psi_r)
00740     calculateAngles(tctrig);
00741     // check angular window for LL  --> fixed by SV 27/III/03 --> NO, for all!
00742     //if( (tctrig->qdec()==4) && !insideAngWindow(tctrig)) {
00743     if( !insideAngWindow(tctrig) ) {
00744        // reset codes, K, X and angles
00745         tctrig->resetVar() ;
00746     }     
00747     //SV 1/IV/04 BUG FIX: check LTS after angle cut...
00748     else if( tctrig->qdec()==4   &&          // cut only LL
00749              config()->TcBxLts() ){          // BX LTS is  enabled or
00750         // reset codes, K, X and angles
00751         if(tkn==0 && _bxlts.element(is) )      // I track : there is H -4,+1
00752           tctrig->resetVar() ;
00753         if(tkn==1 && _bxlts.element(is+1) )    // II track : there is H -4,+1 1 bx later
00754           tctrig->resetVar() ;
00755     }
00756     else {
00757       // set links to BTI triggers
00758       tctrig->addDTBtiTrig(inner->BtiTrig());
00759       tctrig->addDTBtiTrig(outer->BtiTrig());
00760     }
00761 
00762     // Debugging...
00763     if(config()->debug()>1){
00764       std::cout << "*************************************************************";
00765       std::cout << std::endl;
00766       std::cout << "               Correlation was successfull:                  ";
00767       std::cout << std::endl;
00768       std::cout << " Code = " << tctrig->code();
00769       std::cout << " K = " << tctrig->K();
00770       std::cout << " X = " << tctrig->X();
00771       std::cout << std::endl;
00772       std::cout << "*************************************************************";
00773       std::cout << std::endl;
00774     }
00775     // End debugging
00776 
00777   } else {
00778 
00779     // Debugging...
00780     if(config()->debug()>1){
00781       std::cout << "*************************************************************";
00782       std::cout << std::endl;
00783       std::cout << "               No correlation possible                       ";
00784       std::cout << std::endl;
00785       std::cout << "*************************************************************";
00786       std::cout << std::endl;
00787     }
00788     // End debugging
00789 
00790   }
00791 
00792   return icor;
00793 }
00794 
00795 int
00796 DTTracoChip::storeUncorr(DTTracoTrig* tctrig, DTTracoCand* inner, DTTracoCand* outer, int tkn) {
00797 
00798   // Bunch crossing
00799   int is = tctrig->step();
00800 
00801   // Debugging...
00802   if(config()->debug()==4){
00803     std::cout << "DTTracoChip::storeUncorr called with candidates: " << std::endl;
00804     if(inner)inner->print();
00805     if(outer)outer->print();
00806     std::cout << "--------------------------------------------------" << std::endl;
00807   }
00808 
00809   // End debugging
00810   // priority selector 
00811   // select which of the inner/outer segments should be used
00812   // allow re-use of other segment according to configuration
00813   DTTracoCand* candidate=0;  
00814   if(inner!=0&&outer!=0) {
00815 //    if(config()->prefHtrig(tkn)){  
00816 // --> BUG: selector I preference is ALWAYS for H trig
00817 // fixed by Sara Vanini - 25/III/03
00818       if(inner->BtiTrig()->code()==8 && outer->BtiTrig()->code()<8 ){
00819         candidate=inner;
00820         //if(config()->TcReuse(1)) outer->setUnused(); // reusable
00821       } else if(inner->BtiTrig()->code()<8  && outer->BtiTrig()->code()==8){
00822         candidate=outer;
00823         //if(config()->TcReuse(0)) inner->setUnused(); // reusable
00824       } else { //for the same quality triggers:
00825         if(!config()->prefInner(tkn)) {
00826           candidate=inner;
00827           //if(config()->TcReuse(1))  outer->setUnused(); // reusable
00828         } else {
00829           candidate=outer;
00830           //if(config()->TcReuse(0))  inner->setUnused(); // reusable
00831         }
00832       }//end else
00833 /*
00834     } else {//no Htrig preference
00835       if(!config()->prefInner(tkn)) {
00836         candidate=inner;
00837         if(config()->TcReuse(1))  outer->setUnused(); // reusable
00838       } else {
00839         candidate=outer;
00840         if(config()->TcReuse(0))  inner->setUnused(); // reusable
00841       }
00842     }
00843 */
00844   } else if(inner==0&&outer!=0) {
00845     candidate=outer;
00846   } else if(inner!=0&&outer==0) {
00847     candidate=inner;
00848   } else {
00849     return 0; // no candidates 
00850   }
00851 
00852   //SV *** FOR TESTBEAM OR TEST BENCH PURPOSE ***
00853   //theta trigger bin present(1) or absent(0)
00854   //int thTr = (_flag[is-DTConfigTraco::NSTEPF].element(7)) ?
00855   //   _flag[is-DTConfigTraco::NSTEPF].element(7):
00856   //   _flag[is-DTConfigTraco::NSTEPF].element(8);
00857 
00858   // priority selector II: accept or discard candidate according to masks:
00859   // ** LOW TRIGGERS
00860   if( candidate->BtiTrig()->code()<8 ) { 
00861     // first check with LVALIDIFH: if 1, accept low if there is a H in traco at bx
00862     if(config()->LVALIDIFH() && _flag[is-DTConfigTraco::NSTEPF].element(9)){ 
00863       if(config()->debug()>1)
00864         std::cout << "Low accepted because LVALIDIFH on...." << std::endl;
00865     }
00866     else {//LVALIDIFH==0 or there isn't H in traco in bx : check theta!
00867       //theta check
00868       if( !config()->singleLenab(tkn) ) {
00869         // LTF: single LTRIG not always en. Check cond.:
00870         if( config()->singleLflag(tkn)==1 ||      //always discarded
00871             ( config()->singleLflag(tkn)==2 && !(_card->TSTh()->nHTrig(is)) ) ||
00872             ( config()->singleLflag(tkn)==0 && !(_card->TSTh()->nTrig(is))  ) ){ 
00873 // SV --> for TESTS version
00874 //        config()->singleLflag(tkn)==0 && thTr==0 ||   //only with theta trig. 
00875 //        config()->singleLflag(tkn)==2 && thTr==0  ){  //only with theta H trig (not hw)
00876         if(config()->debug()>1)
00877           std::cout << "Single low trigger discarded by preview and "
00878                << "priority selector for ltmsk!" <<std::endl;
00879         return 0;}
00880         //       ^-------- trigger is suppressed and will not be stored
00881       }//end theta
00882 
00883     } //end else
00884     //REUSE : mark candidates reusable HERE! SV BUG FIX 6IV04
00885     if(candidate==inner && config()->TcReuse(1) && outer)
00886       outer->setUnused();
00887     if(candidate==outer && config()->TcReuse(0) && inner)
00888       inner->setUnused();
00889 
00890     // LTS suppression
00891     if(config()->TcBxLts()){
00892       if( (tkn==0 && _bxlts.element(is))       // I track : there is H -4,+1
00893                         ||
00894           (tkn==1 && _bxlts.element(is+1)) ){  // II track : there is H -4,+1 1 bx later
00895         tctrig->resetVar() ;
00896         if(config()->debug()>1)
00897           std::cout << "Low trigger suppressed because H in next 4 bx "<<
00898                " and LTS flag on...." << std::endl;
00899         return 1; // trigger is suppressed but preview will be stored
00900       }
00901     }//end lts
00902 
00903 //    } //end else
00904   } //Low trigs
00905 
00906   // Preview Htmsk not implemented: awaiting decision 
00907   // --> implemented in priority selector by SV
00908   else { // HTRIG
00909     //if(config()->singleHflag(tkn)==1 && thTr==0 )  //this is for testing
00910     if( config()->singleHflag(tkn)==1 && !(_card->TSTh()->nTrig(is) ) )
00911       return 0;
00912       // ^-----trigger is suppressed and will not be stored
00913 
00914     //mark candidates reusable HERE! SV BUG FIX 6IV04
00915     if(candidate==inner && config()->TcReuse(1) && outer)
00916       outer->setUnused();
00917     if(candidate==outer && config()->TcReuse(0) && inner)
00918       inner->setUnused();
00919   }
00920 
00921   // set code, position, K and X  
00922   float shift;
00923   //if(config()->trigSetupGeom()!=1 )
00924     shift = (int)( _geom->distSL()/_geom->cellH() + 0.5 );
00925   //else 
00926     //shift = DD();  //SV 19/III/03
00927   int kucor = (int)( 0.5*shift * (candidate->BtiTrig()->K()-BTIC()) );
00928   tctrig->setK(kucor);
00929   tctrig->setX( candidate->X() );
00930   // correlation wasn't successfull
00931   // set the preview correlation bit. 
00932   tctrig->setPVCorr(0);
00933   if(candidate->BtiTrig()->btiSL()==1){    // inner track
00934     tctrig->setCodeIn(candidate->BtiTrig()->code());
00935     tctrig->setCodeOut(0);
00936     //tctrig->setPosIn(candidate->position());
00937     //SV number of bti instead of position...
00938     tctrig->setPosIn(candidate->BtiTrig()->btiNumber() );
00939     tctrig->setPosOut(0);
00940     //SV store also equation
00941     tctrig->setEqIn( candidate->BtiTrig()->eq() + 1 );
00942     tctrig->setEqOut( 0 );
00943   } else {                                               // outer track
00944     tctrig->setCodeIn(0);
00945     tctrig->setCodeOut(candidate->BtiTrig()->code());
00946     tctrig->setPosIn(0);
00947     //SV number of bti instead of position...
00948     tctrig->setPosOut(candidate->BtiTrig()->btiNumber() );
00949     //tctrig->setPosOut(candidate->position());
00950     //SV store also equation
00951     tctrig->setEqIn( 0 );
00952     tctrig->setEqOut( candidate->BtiTrig()->eq() + 1);
00953   }
00954 
00955   // coordinate converter LUT
00956   // calculate psi, psi_r and Delta(psi_r)
00957   calculateAngles(tctrig);
00958   // check angular window only for Low!!  --> fixed SV 27/III/03--> NO, for all!
00959   //if( candidate->BtiTrig()->code() < 8 && !insideAngWindow(tctrig) ){
00960   if( !insideAngWindow(tctrig) ){
00961     // reset codes, K, X and angles
00962     tctrig->resetVar() ;
00963     if(config()->debug()>1)
00964       std::cout << "L rejected because outside angular window!" << std::endl;
00965    } else {
00966     // set links to BTI trigger
00967     tctrig->addDTBtiTrig(candidate->BtiTrig());
00968   }
00969 
00970   // Debugging...
00971   if(config()->debug()>1){
00972     std::cout << "*************************************************************";
00973     std::cout << std::endl;
00974     std::cout << "               Single trigger stored:                        ";
00975     std::cout << std::endl;
00976     std::cout << " Code = " << tctrig->code();
00977     std::cout << " K = " << tctrig->K();
00978     std::cout << " X = " << tctrig->X();
00979     std::cout << std::endl;
00980     std::cout << "*************************************************************";
00981     std::cout << std::endl;
00982   }
00983   // End debugging
00984 
00985   return 1;
00986 
00987 }
00988 
00989 void
00990 DTTracoChip::add_btiT(int step, int pos, const DTBtiTrigData* btitrig) {
00991 
00992   if(pos<1 || pos>4*DTConfigTraco::NBTITC) {
00993     std::cout << "DTTracoChip::add_btiT: wrong position: " << pos;
00994     std::cout << "trigger not added!" << std::endl;
00995     return;
00996   }
00997   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
00998     std::cout << "DTTracoChip::add_btiT: step out of range: " << step;
00999     std::cout << "trigger not added!" << std::endl;
01000     return;
01001   }
01002 
01003   if(!config()->usedBti(pos)) {
01004     if(config()->debug()==4){
01005       std::cout << "DTTracoChip::add_btiT: position: " << pos;
01006       std::cout << "has disconnected bti" << std::endl;
01007     }
01008     return;
01009   }
01010 
01011 
01012   // 091103 SV: acceptances are taken from geometry if useAcceptParam()=false
01013   // otherwise cuts based on LL,LH,CL,CH,RL,RH taken from  configuration are applied in TracoCard::loadTraco 
01014   if(_card->useAcceptParamFlag()==false) {
01015     // check K inside acceptance
01016     if(btitrig->K()<_PSIMIN[pos-1] || btitrig->K()>_PSIMAX[pos-1] ) {
01017       if(config()->debug()>1){
01018         std::cout << "In TRACO num. " << number() << " BTI trig. in pos " << pos << " outside K acceptance (";
01019         std::cout << _PSIMIN[pos-1] << "-->";
01020         std::cout << _PSIMAX[pos-1] << ") - Not added" << std::endl;
01021       }
01022       return;
01023     }
01024   } 
01025 
01026   // Store trigger candidate
01027   if(pos<=DTConfigTraco::NBTITC){
01028     _innerCand[step-DTConfigTraco::NSTEPF].push_back(
01029       DTTracoCand(this,btitrig,pos,step));
01030   } else {
01031     _outerCand[step-DTConfigTraco::NSTEPF].push_back(
01032       DTTracoCand(this,btitrig,pos,step));
01033   }
01034 
01035   // Fill array for BX LTS
01036   if(btitrig->code()==8){
01037     for(int is=step-4;is<step;is++){       // set flag for 4 previous BX
01038       if(is>0&&is<=DTConfigTraco::NSTEPL) _bxlts.set(is);
01039     }
01040     //SV 1/IV/04 BUG FIX
01041     _bxlts.set(step+1);
01042     // Debugging
01043     if(config()->debug()==4)
01044       for(int is=0;is<DTConfigTraco::NSTEPL;is++)
01045        std::cout<<"_bxlts["<<is<<"]="<<_bxlts.element(is)<<std::endl;
01046   }
01047 
01048   // Debugging
01049   if(config()->debug()>1){
01050     std::cout << "BTI Trigger added at step " << step;
01051     std::cout << " to TRACO " << _id.traco() << " at position " << pos << std::endl;
01052     btitrig->print();
01053   } // End debugging
01054 
01055 }
01056 
01057 
01058 void
01059 DTTracoChip::addTrig(int step, DTTracoTrig* tctrig) {
01060   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
01061     std::cout << "DTTracoChip::addTrig: step out of range: " << step;
01062     std::cout << " trigger not added!" << std::endl;
01063     return;
01064   }
01065   _tracotrig[step-DTConfigTraco::NSTEPF].push_back(tctrig);
01066 
01067   // Debugging...
01068 
01069   if(config()->debug()==4){
01070     std::cout << "DTTracoChip::addTrig: adding trigger:"<< std::endl; 
01071     tctrig->print();
01072   }
01073   // End debugging
01074 
01075 }
01076 
01077 int
01078 DTTracoChip::nTrig(int step) const {
01079   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
01080     std::cout << "DTTracoChip::nTrig: step out of range: " << step;
01081     std::cout << " 0 returned!" << std::endl;
01082     return 0;
01083   }
01084   return _tracotrig[step-DTConfigTraco::NSTEPF].size();
01085 }
01086 
01087 DTTracoTrig*
01088 DTTracoChip::trigger(int step, unsigned n) const {
01089   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
01090     std::cout << "DTTracoChip::trigger: step out of range: " << step;
01091     std::cout << " empty pointer returned!" << std::endl;
01092     return 0;
01093   }
01094   if(n<1 || n>_tracotrig[step-DTConfigTraco::NSTEPF].size()) {
01095     std::cout << "DTTracoChip::trigger: requested trigger doesn't exist: " << n;
01096     std::cout << " empty pointer returned!" << std::endl;
01097     return 0;
01098   }
01099   std::vector<DTTracoTrig*>::const_iterator p = 
01100     _tracotrig[step-DTConfigTraco::NSTEPF].begin()+n-1;
01101   return *p;
01102 }
01103 
01104 DTTracoTrigData
01105 DTTracoChip::triggerData(int step, unsigned n) const {
01106   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
01107     std::cout << "DTTracoChip::triggerData: step out of range: " << step;
01108     std::cout << " dummy trigger returned!" << std::endl;
01109     return DTTracoTrigData();
01110   }
01111   if(n<1 || n>_tracotrig[step-DTConfigTraco::NSTEPF].size()) {
01112     std::cout << "DTTracoChip::trigger: requested trigger doesn't exist: " << n;
01113     std::cout << " dummy trigger returned!" << std::endl;
01114     return DTTracoTrigData();
01115   }
01116   std::vector<DTTracoTrig*>::const_iterator p = 
01117     _tracotrig[step-DTConfigTraco::NSTEPF].begin()+n-1;
01118   return (*p)->data();
01119 }
01120 
01121 float
01122 DTTracoChip::psiRad(int sl) const {
01123 /*
01124   // Radial angle of correlator center in mrad in CMS frame
01125   LocalPoint p = localPosition();
01126   float x = p.x();
01127   float y = p.y();
01128   float z = p.z();
01129   if        (sl==1) {
01130     z -= 0.5 * _geom->distSL();
01131   } else if (sl==3) {
01132     z += 0.5 * _geom->distSL();
01133   }
01134   float fpsir = _geom->stat()->toGlobal(LocalPoint(x,y,z)).phi()-
01135                 _geom->phiCh();
01136   if(fpsir<-M_PI)fpsir+=M_PI*2;
01137   if(fpsir>M_PI)fpsir-=M_PI*2;
01138   return fpsir*1000;
01139 */
01140   return 0.0;
01141 }
01142 
01143 int
01144 DTTracoChip::KRad() const {
01145   // K parameter of the radial angle of correlator center
01146   //float distp2 = (int)(2*_geom->cellH()*config()->ST()/_geom->cellPitch());
01147   //return -(int)(tan(psiRad(sl)/1000)*distp2); // sign is reverted!!!
01148   //return _krad;
01149   
01150   //SV V/03: for harware bug in traco....
01151   int KRad=0;
01152   return KRad;
01153    
01154 }
01155 
01156 int
01157 DTTracoChip::useSecondTrack(int step) const {
01158   // return 1 if II track use is allow
01159   // return 0 if II track has been rejected
01160   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
01161     std::cout << "DTTracoChip::useSecondTrack: step out of range: " << step;
01162     std::cout << " 0 returned!" << std::endl;
01163     return 0;
01164   }
01165   return !(_flag[step-DTConfigTraco::NSTEPF].element(2));
01166 }
01167 
01168 int
01169 DTTracoChip::edgeBTI(int step, int io, int lr) const {
01170   if(step<DTConfigTraco::NSTEPF||step>DTConfigTraco::NSTEPL){
01171     std::cout << "DTTracoChip::edgeBTI: step out of range: " << step;
01172     std::cout << " 0 returned!" << std::endl;
01173     return 0;
01174   }
01175   //
01176   // inner supl ==> io=1; outer supl ==> io=2      |21   |     |   22|
01177   // right edge ==> rl=1;  left edge ==> rl=2            |11 12|
01178   //
01179   std::vector<DTTracoCand>::const_iterator p;
01180   if(io==1){
01181     if(_innerCand[step-DTConfigTraco::NSTEPF].size()>0) {
01182       // SV 24/IX/03 fix: only HTRIG accepted
01183       for(p=_innerCand[step-DTConfigTraco::NSTEPF].begin();
01184           p<_innerCand[step-DTConfigTraco::NSTEPF].end(); p++){
01185         if(lr==1 && (*p).position()==1 && (*p).BtiTrig()->code()==8 ) 
01186           return  1; 
01187         if(lr==2 && (*p).position()==DTConfigTraco::NBTITC && (*p).BtiTrig()->code()==8 )
01188           return  1; 
01189       }
01190     }
01191   } else {
01192     if(_outerCand[step-DTConfigTraco::NSTEPF].size()>0) {
01193       for(p=_outerCand[step-DTConfigTraco::NSTEPF].begin();
01194           p<_outerCand[step-DTConfigTraco::NSTEPF].end(); p++){
01195         //SV: is the following correct???FIX if using _card to set _flag
01196         //if(lr==1 && (*p).position()==DTConfigTraco::NBTITC+1)return 1; //or pos=8??
01197         //if(lr==2 && (*p).position()==DTConfigTraco::NBTITC*4)return 1; //or pos=13?? 
01198         //SV 24/IX/03 fix 
01199         if(lr==1 && (*p).position()==DTConfigTraco::NBTITC*3+1 && (*p).BtiTrig()->code()==8 )
01200           return  1; 
01201         if(lr==2 && (*p).position()==DTConfigTraco::NBTITC*2   && (*p).BtiTrig()->code()==8 )
01202           return  1;  
01203       }
01204     }
01205   }
01206   return  0;
01207 }
01208 
01209 void 
01210 DTTracoChip::calculateAngles(DTTracoTrig* tct) {
01211 
01212   int ipsi=0;
01213   int iphir=0;
01214   int idpsir=0; 
01215 /* obsolete  
01216   //TB 2004 luts formula from minicrate CCB
01217   if( config()->trigSetupGeom()==2 ){
01218     ipsi = _lutsCCB->get_k( (tct->K()+511) );
01219 
01220     int flag = 0;
01221     int qual=tct->data().qdec();
01222     if(qual==3 || qual==1)                //case 0:outer
01223       flag=0;
01224     if(qual==2 || qual==0)                //case 1:inner
01225       flag=1;
01226     if(qual==6 || qual==5 || qual==4)     //case 2:correlated
01227       flag=2;
01228 
01229     iphir = _lutsCCB->get_x( (tct->X()+512*flag) );
01230 
01231     idpsir = ipsi - iphir/8;
01232   }
01233 
01234  //TB 2003 luts data format
01235  if( config()->trigSetupGeom()==1 ){
01236     //compute bending angles of traco output with lookup tables
01237     //SV TB2003: first trigger board isn't connected;
01238     ipsi = _luts->getPsi(tct->K());  
01239     int flag = 0;
01240     int qual=tct->data().qdec();
01241     if(qual==3 || qual==1)                //case 0:outer
01242       flag=0;  
01243     if(qual==2 || qual==0)                //case 1:inner
01244       flag=1;  
01245     if(qual==6 || qual==5 || qual==4)     //case 2:correlated
01246       flag=2;  
01247     iphir = _luts->getPhiRad( tct->X(), flag);
01248     idpsir = _luts->getBendAng( tct->X(), tct->K(), flag);
01249   }
01250  */
01251 
01252   // 091030 SV angles computed from DB lut parameters
01253   if( _card->lutFromDBFlag()==1 )
01254   {
01255     ipsi = _lutsCCB->get_k( (tct->K()+512) );
01256 
01257     int flag = 0;
01258     int qual=tct->data().qdec();
01259     if(qual==3 || qual==1)                //case 0:outer
01260       flag=0;
01261     if(qual==2 || qual==0)                //case 1:inner
01262       flag=1;
01263     if(qual==6 || qual==5 || qual==4)     //case 2:correlated
01264       flag=2;
01265 
01266     iphir = _lutsCCB->get_x( (tct->X()+512*flag) );
01267 
01268     idpsir = ipsi - iphir/8;
01269   }
01270   else
01271   // compute angles from CMSSW geometry 
01272   //if( config()->trigSetupGeom()==0 )
01273   {
01274     DTTracoTrigData td = tct->data();
01275     // psi
01276     //  float fpsi = atan( (float)(tct->K()) * _geom->cellPitch() / 
01277     //               (_geom->distSL() * config()->ST()) );
01278     float fpsi = atan( _card->localDirection(&td).x() /   // e.g. x>0 and
01279                      _card->localDirection(&td).z() );    //      z<0 => fpsi<0
01280 
01281     // Change sign in case of wheel<0 or wheel==0 and station == 1,4,5,8,9,12
01282     int mywh = tct->ChamberId().wheel();
01283     if (mywh<0   ||
01284         (mywh==0 && (tct->ChamberId().sector()%4)<2))
01285       fpsi = -fpsi;
01286     
01287     fpsi*=DTConfigTraco::RESOLPSI;
01288     if(fpsi<=0)
01289       fpsi-=1.0;
01290     ipsi = (int)fpsi;
01291     // if outside range set to lower edge
01292     if( ipsi>= DTConfigTraco::RESOLPSI || ipsi< -DTConfigTraco::RESOLPSI ) 
01293       ipsi=-DTConfigTraco::RESOLPSI;
01294 
01295 
01296     // psi_r
01297     float fpsir = _card->CMSPosition(&td).phi()-_geom->phiCh();
01298 
01299     if(fpsir<-M_PI)
01300       fpsir+=M_PI*2;
01301     if(fpsir>M_PI)
01302       fpsir-=M_PI*2;
01303     fpsir*=DTConfigTraco::RESOLPSIR;
01304     if(fpsir<=0)
01305       fpsir-=1.0;
01306     iphir = (int)fpsir;
01307     // if outside range set to lower edge
01308     if( iphir>= DTConfigTraco::RESOLPSIR/2 || iphir <-DTConfigTraco::RESOLPSIR/2 ) 
01309       iphir=-DTConfigTraco::RESOLPSIR/2;
01310 
01311     // Delta(psi_r)
01312     int dpsir = (iphir*DTConfigTraco::RESOLPSI) / DTConfigTraco::RESOLPSIR;
01313     idpsir = ipsi-dpsir;
01314     // if outside range set to lower edge
01315     if(idpsir>= DTConfigTraco::RESOLPSI || idpsir <-DTConfigTraco::RESOLPSI ) 
01316       idpsir=-DTConfigTraco::RESOLPSI;
01317   }
01318   
01319   tct->setAngles(ipsi,iphir,idpsir);
01320 
01321   // debugging
01322   if(config()->debug()==4){
01323     std::cout << "DTTracoChip::calculateAngles :" << std::endl;
01324     tct->print();
01325     std::cout << std::dec << "K = " << tct->K() << " X = " << tct->X(); 
01326     std::cout << " ipsi = " << ipsi << " iphir = " << iphir;
01327     std::cout << " idpsir = " << idpsir << std::endl;
01328     if( _card->lutFromDBFlag()==1 )
01329       std::cout << "Angles are calculated from LUT parameters from DB!" << std::endl; 
01330   }// end debugging
01331 
01332 }
01333 
01334 int
01335 DTTracoChip::insideAngWindow(DTTracoTrig* tctrig) const {
01336   // check angular window for every station type
01337   // return 1 for accept, 0 for reject
01338   // abs value of bending angle is 9 bits
01339 
01340   BitArray<10> bendAng;
01341   bendAng.assign(0,10,tctrig->DeltaPsiR());
01342   //bendAng.print();
01343   if(bendAng.element(9))  //negativo!
01344     bendAng.twoComplement(); 
01345   int bendAngINT = bendAng.read(0,9);
01346   //std::cout<<"abs bend angle int ="<< bendAngINT <<std::endl;
01347 
01348   if( config()->BendingAngleCut()!= -1 && 
01349      bendAngINT > 2*(config()->BendingAngleCut())) {
01350     int absBendAng = tctrig->DeltaPsiR() & 0x1FF;
01351     if(config()->debug()==4)
01352       std::cout << "Attention: abs(bendAng)=" << absBendAng << " > " 
01353            << 2*config()->BendingAngleCut() <<"!! reject trigger"<<std::endl;
01354     return 0;
01355   }
01356   return 1;
01357 }
01358 
01359  
01360 void 
01361 DTTracoChip::setTracoAcceptances()
01362 {  
01363   // Set K acceptances of DTTracoChip MT ports: Ktraco = Xinner - Xouter 
01364   float h = _geom->cellH();
01365   float pitch = _geom->cellPitch();
01366   float distsl = _geom->distSL();
01367   float K0 = config()->BTIC();
01368   float shiftSL = _geom->phiSLOffset() / pitch * K0;
01369 
01370   // mt  ports from orca geometry: this is always the case with new DTConfig
01371   //if(config_traco(tracoid)->trigSetupGeom() != 1){
01372   {
01373     // Master Plane
01374     int i = 0;
01375     for(i=0;i<DTConfig::NBTITC;i++){
01376       float Xin_min     =  (i + DTConfig::NBTITC) * K0 + shiftSL;
01377       float Xin_max     =  Xin_min + K0;
01378       float Xout_min    =  0;
01379       float Xout_max    =  3 * DTConfig::NBTITC * K0;
01380       _PSIMAX[i]  =  int( 2.*h/distsl * (Xin_max - Xout_min) + K0 + 1.01 );
01381       _PSIMIN[i]  =  int( 2.*h/distsl * (Xin_min - Xout_max) + K0 );
01382     }
01383 
01384     // Slave Plane
01385     for(i=0;i<3*DTConfig::NBTITC;i++){
01386       float Xin_min     =  (DTConfig::NBTITC) * K0 + shiftSL;
01387       float Xin_max     =  2. * DTConfig::NBTITC * K0 + shiftSL;
01388       float Xout_min    =  i * K0;
01389       float Xout_max    =  Xout_min + K0;
01390       _PSIMAX[DTConfig::NBTITC+i]  =  int( 2.*h/distsl * (Xin_max - Xout_min) + K0 + 1.01 );
01391       _PSIMIN[DTConfig::NBTITC+i]  =  int( 2.*h/distsl * (Xin_min - Xout_max) + K0 );
01392     }
01393   }
01394 
01395 
01396   // debugging
01397   if(config()->debug()==4){
01398     //if(wheel()==2&&station()==3&&sector()==1){ // only 1 chamber
01399       std::cout << "Acceptance of mt ports for offset (cell unit) " 
01400            << _geom->phiSLOffset() / pitch << std::endl;
01401       for(int i=0;i<4*DTConfig::NBTITC;i++){
01402         std::cout << "Port " << i+1 << " : ";
01403         std::cout << _PSIMIN[i] << " --> " << _PSIMAX[i] << std::endl;
01404       }
01405     //}
01406   }// end debugging
01407 
01408 }
01409 
01410 
01411