CMS 3D CMS Logo

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