Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

SiClustersAlg.cxx

Go to the documentation of this file.
00001 
00002 #include "GaudiKernel/MsgStream.h"
00003 #include "GaudiKernel/AlgFactory.h"
00004 #include "GaudiKernel/IDataProviderSvc.h"
00005 #include "GaudiKernel/SmartDataPtr.h"
00006 #include "GlastSvc/GlastDetSvc/IGlastDetSvc.h"
00007 #include "gui/DisplayControl.h"
00008 #include "GuiSvc/IGuiSvc.h"
00009 #include "gui/GuiMgr.h"
00010 
00011 #include "TkrRecon/SiClustersAlg.h"
00012 //include "TkrRecon/TkrAxis.h"
00013 
00014 #include <algorithm>
00015 
00016 const int bigStripNum = 0x7FFFFF;
00017 
00018 static const AlgFactory<SiClustersAlg>  Factory;
00019 const IAlgFactory& SiClustersAlgFactory = Factory;
00020 
00021 //------------------------------------------------------------------------------
00024 
00025 
00026     
00044 SiClustersAlg::SiClustersAlg(const std::string& name, ISvcLocator* pSvcLocator) :
00045 Algorithm(name, pSvcLocator)  { }
00046 
00047 
00048 StatusCode SiClustersAlg::initialize()
00049 {
00050     MsgStream log(msgSvc(), name());
00051     
00052     //Look for the geometry service
00053     StatusCode sc = service("TkrGeometrySvc", pTkrGeo, true);
00054     if (sc.isFailure()) {
00055         log << MSG::ERROR << "TkrGeometrySvc is required for this algorithm." << endreq;
00056         return sc;
00057     }
00058     //TkrBadStripsSvc is not required for this algorithm
00059     //There are some shenanigans below to ensure that the algorithm runs without it.
00060     sc = service("TkrBadStripsSvc", pBadStrips, false);
00061     if (sc.isFailure()) {
00062         log << MSG::INFO << "algorithm will not filter bad hits." << endreq;   
00063     }
00064     
00065     //Initialize the rest of the data members
00066     m_SiClusters = 0;
00067     m_TkrDigis   = 0; 
00068     
00069     return StatusCode::SUCCESS;
00070 }
00071 
00072 
00073 StatusCode SiClustersAlg::execute()
00074 {
00075     MsgStream log(msgSvc(), name());
00076     
00077     StatusCode sc = retrieve();
00078     // loop over Digis
00079 
00080     TkrDigiCol::const_iterator pTkrDigi = m_TkrDigis->begin();
00081     int nclusters = 0;  // for debugging
00082     int ndigis = m_TkrDigis->size();
00083     
00084     for (int idigi = 0; idigi < ndigis ; idigi++) {
00085         TkrDigi* pDigi = pTkrDigi[idigi];
00086         
00087         int layer  = pDigi->layer();
00088         int view   = pDigi->view();
00089         int tower  = pDigi->tower();
00090         
00091         int nHits  = pDigi->num();
00092 
00093         // the list of bad strips
00094         v_strips* badStrips = 0;
00095         int badStripsSize = 0;
00096         if (pBadStrips) {
00097             badStrips = pBadStrips->getBadStrips(tower, layer, (TkrAxis::axis) view);
00098             if (badStrips) badStripsSize = badStrips->size();
00099             int sizex = badStrips->size();
00100         }
00101 
00102         //Make a local vector big enough to hold everything
00103         int hitsSize = nHits + badStripsSize + 1;
00104         std::vector<int> stripHits(hitsSize);
00105         
00106         int running_index = 0;
00107         // copy and mark the hits good
00108         for (int ihit = 0; ihit < nHits; ihit++,running_index++){
00109             stripHits[running_index] = tagGood(pDigi->hit(ihit));
00110         } 
00111         // copy the bad strips, already marked
00112         if (pBadStrips) {
00113             for (ihit = 0; ihit< badStripsSize; ihit++,running_index++) {
00114                 stripHits[running_index] = (*badStrips)[ihit];
00115             }
00116         }
00117         // add the sentinel -- guaranteed to make a gap, and it's bad
00118         stripHits[running_index] = tagBad(bigStripNum);
00119 
00120         std::sort(stripHits.begin(), stripHits.end()); 
00121         
00122         int lowStrip  = stripHits[0];  // the first strip of the current potential cluster
00123         int highStrip = lowStrip;      // the last strip of the current cluster
00124         int nextStrip = lowStrip;      // the next strip
00125         int nBad = 0;
00126         bool kept;  // for debugging
00127                 
00128         //Loop over the rest of the strips building clusters enroute.
00129         //Keep track of bad strips.
00130         //Loop over all hits, except the sentinel, which is there to provide a gap
00131         
00132         for (ihit = 0; ihit < hitsSize-1; ihit++) {
00133             if(pBadStrips) nBad += pBadStrips->isTaggedBad(nextStrip);
00134             nextStrip = stripHits[ihit+1];
00135             
00136             //If we have a gap, then make a cluster
00137             if (isGapBetween(highStrip, nextStrip)) {
00138                 // there's a gap... see if the current cluster is good...
00139                                 //log << MSG::DEBUG << "Test Cluster: " << lowStrip << " "
00140                                 //                 << highStrip << " " << nBad << endreq;
00141                 if (kept = isGoodCluster(lowStrip, highStrip, nBad)) {
00142                     // it's good... make a new cluster
00143                     SiCluster* cl = new SiCluster(nclusters, view, 
00144                                                 pTkrGeo->numPlanes()-layer-1,
00145                         untag(lowStrip), untag(highStrip), pDigi->ToT(0), tower);
00146                     cl->setPosition(position(cl->plane(),cl->v(),cl->strip(), cl->tower()));
00147                     m_SiClusters->addCluster(cl);
00148                     nclusters++;   
00149                                         //log << MSG::DEBUG << "   good cluster" << endreq;
00150                 } 
00151                 lowStrip = nextStrip;  // start a new cluster with this strip
00152                 nBad = 0;
00153             }
00154             highStrip = nextStrip; // add strip to this cluster
00155         }
00156     }
00157     m_SiClusters->writeOut(log);
00158     
00159     return sc;
00160 }
00161 
00162 
00163 StatusCode SiClustersAlg::finalize()
00164 {       
00165     return StatusCode::SUCCESS;
00166 }
00167 
00168 
00169 //-------------------- private ----------------------
00170 
00171 StatusCode SiClustersAlg::retrieve()
00172 {
00173     StatusCode sc = StatusCode::SUCCESS;
00174     
00175     MsgStream log(msgSvc(), name());
00176     
00179     DataObject* pnode =0;
00180     sc = eventSvc()->retrieveObject("/Event/TkrRecon", pnode);
00181     
00182     if( sc.isFailure() ) {
00183         sc = eventSvc()->registerObject("/Event/TkrRecon",new DataObject);
00184         if( sc.isFailure() ) {
00185             
00186             log << MSG::ERROR << "Could not create TkrRecon directory" << endreq;
00187             return sc;
00188         }
00189     }
00190     
00191     m_SiClusters = new SiClusters(pTkrGeo->numViews(), pTkrGeo->numLayers(), 
00192         pTkrGeo->siStripPitch(), pTkrGeo->towerPitch());
00193     sc = eventSvc()->registerObject("/Event/TkrRecon/SiClusters",m_SiClusters);
00194     
00195     m_TkrDigis  = SmartDataPtr<TkrDigiCol>(eventSvc(),"/Event/TkrRecon/TkrDigis");
00196     
00197     if (m_SiClusters == 0 || m_TkrDigis ==0) sc = StatusCode::FAILURE;
00198     return sc;
00199 }
00200 
00201 
00202 Point SiClustersAlg::position(const int plane, SiCluster::view v, const double strip, const int tower)
00203 {
00204     int iladder = strip / pTkrGeo->ladderNStrips();
00205     double stripInLadder = strip - iladder*pTkrGeo->ladderNStrips();
00206     
00207     tkrDetGeo::axis a = (v==SiCluster::X) ? tkrDetGeo::X : tkrDetGeo::Y;
00208     
00209     // note the differences between layers and planes - ordering!
00210     int layer = pTkrGeo->ilayer(plane);
00211     
00212     tkrDetGeo ladder = pTkrGeo->getSiLadder(layer, a, iladder, tower);
00213     
00214     double Dstrip = (v==SiCluster::X) ? 
00215         ladder.position().x()-ladder.size().x() :
00216         ladder.position().y()-ladder.size().y();
00217     
00218     Dstrip += pTkrGeo->siDeadDistance();
00219     Dstrip += (stripInLadder+0.5)*pTkrGeo->siStripPitch();
00220     
00221     Point P = ladder.position();
00222     double x = (v==SiCluster::X) ? Dstrip : P.x();
00223     double y = (v==SiCluster::Y) ? Dstrip : P.y();
00224     double z = P.z();
00225 
00226     P = Point(x,y,z);
00227     return P;
00228 }
00229 
00230 
00231 bool SiClustersAlg::isGapBetween(const int lowStrip, const int highStrip) 
00232 {
00233     //Get the actual hit strip number from the tagged strips
00234     int lowHit  = untag(lowStrip);
00235     int highHit = untag(highStrip);
00236 
00237     // gap between hits
00238     if (highHit > (lowHit + 1)) { return true; }
00239     
00240     //edge of chip
00241     int nStrips = pTkrGeo->ladderNStrips();
00242     if((lowHit/nStrips) < (highHit/nStrips)) {return true; }
00243     
00244     return false;
00245 }
00246 
00247 
00248 bool SiClustersAlg::isGoodCluster(const int lowStrip, const int highStrip, const int nBad) 
00249 {
00250     //Get the actual hit strip number from the tagged strips
00251     int lowHit  = untag(lowStrip);
00252     int highHit = untag(highStrip);
00253 
00254     // for now, just require at least 1 good hit in the cluster
00255     // later maybe cut on number of strips < some maximum
00256             //if (nBad>0 && highHit-lowHit+1>nBad) {
00257                     //std::cout << "cluster with some bad hits "<<
00258                         //highHit-lowHit+1 << " " << nBad << std::endl;
00259             //}
00260     return ((highHit-lowHit+1)>nBad);
00261 }
00262 
00263 int SiClustersAlg::tagBad(const int strip)
00264 {
00265     if (pBadStrips) return pBadStrips->tagBad(strip);
00266     else return strip;
00267 }
00268 
00269 
00270 int SiClustersAlg::tagGood(const int strip)
00271 {
00272     if (pBadStrips) return pBadStrips->tagGood(strip);
00273     else return strip;
00274 }
00275 
00276 
00277 int SiClustersAlg::untag(const int strip)
00278 {
00279     if (pBadStrips) return pBadStrips->untag(strip);
00280     else return strip;
00281 }
00282 

Generated at Wed Nov 21 12:21:21 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000