Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AlgEventSRList.cxx

Go to the documentation of this file.
00001 
00002 // $Id: AlgEventSRList.cxx,v 1.67 2008/11/05 17:26:55 rodriges Exp $
00003 //
00004 // AlgEventSRList.cxx
00005 //
00006 // AlgEventSRList is a concrete EventSRList Algorithm class.
00007 //
00008 // Author:  R. Lee 2001.03.07
00010 
00011 #include <cassert>
00012 #include <cmath>
00013 #include <map>
00014 
00015 #include "Algorithm/AlgFactory.h"
00016 #include "Algorithm/AlgHandle.h"
00017 #include "Algorithm/AlgConfig.h"
00018 #include "Candidate/CandContext.h"
00019 #include "CandEventSR/AlgEventSRList.h"
00020 #include "RecoBase/CandEvent.h"
00021 #include "RecoBase/CandEventHandle.h"
00022 #include "RecoBase/CandEventList.h"
00023 #include "RecoBase/CandEventListHandle.h"
00024 #include "Conventions/PlaneView.h"
00025 #include "RecoBase/CandClusterHandle.h"
00026 #include "RecoBase/CandCluster.h"
00027 #include "CandShowerSR/CandShowerSR.h"
00028 #include "CandShowerSR/CandShowerSRHandle.h"
00029 #include "CandShowerSR/CandShowerSRListHandle.h"
00030 #include "RecoBase/CandShowerHandle.h"
00031 #include "RecoBase/CandShower.h"
00032 #include "MessageService/MsgService.h"
00033 #include "MinosObjectMap/MomNavigator.h"
00034 #include "Navigation/NavKey.h"
00035 #include "Navigation/NavSet.h"
00036 #include "Plex/PlexPlaneId.h"
00037 #include "RecoBase/CandEventHandle.h"
00038 #include "RecoBase/CandRecoHandle.h"
00039 #include "RecoBase/CandSliceHandle.h"
00040 #include "RecoBase/CandStripHandle.h"
00041 #include "RecoBase/CandShowerHandle.h"
00042 #include "RecoBase/CandTrackHandle.h"
00043 #include "RecoBase/CandClusterListHandle.h"
00044 #include "RecoBase/CandSliceListHandle.h"
00045 #include "RecoBase/CandShowerListHandle.h"
00046 #include "RecoBase/CandTrackListHandle.h"
00047 #include "UgliGeometry/UgliGeomHandle.h"
00048 #include "UgliGeometry/UgliScintPlnHandle.h"
00049 #include "Validity/VldContext.h"
00050 #include  "CandFitTrackSR/CandFitTrackSRHandle.h"
00051 #include "Calibrator/Calibrator.h"
00052 ClassImp(AlgEventSRList)
00053 
00054 #define PITCHINMETRES 0.0594
00055 
00056 //______________________________________________________________________
00057 CVSID("$Id: AlgEventSRList.cxx,v 1.67 2008/11/05 17:26:55 rodriges Exp $");
00058 
00059 //______________________________________________________________________
00060 AlgEventSRList::AlgEventSRList()
00061 {
00062 }
00063 
00064 //______________________________________________________________________
00065 AlgEventSRList::~AlgEventSRList()
00066 {
00067 }
00068 
00069 //______________________________________________________________________
00070 void AlgEventSRList::RunAlg(AlgConfig &ac, CandHandle &ch,
00071                                                         CandContext &cx)
00072 {
00073 
00074   assert(cx.GetDataIn());
00075   if (!(cx.GetDataIn()->InheritsFrom("TObjArray"))) return;
00076 
00077   CandContext cxx(this,cx.GetMom());
00078   AlgFactory &af = AlgFactory::GetInstance();
00079   const char *pEventAlgConfig = 0;
00080   ac.Get("EventAlgConfig",pEventAlgConfig);
00081   AlgHandle ah = af.GetAlgHandle("AlgEventSR",pEventAlgConfig);
00082   // grab all needed algorithm parameters  
00083   Double_t pTrkTrkDtpos2 = ac.GetDouble("TrkTrkDtpos2");
00084   Double_t pTrkTrkDz = ac.GetDouble("TrkTrkDz");
00085   Double_t pTrkTrkDt = ac.GetDouble("TrkTrkDt");
00086   Double_t pShwTrkDtpos2 = ac.GetDouble("ShwTrkDtpos2");
00087   Double_t pShwTrkDz = ac.GetDouble("ShwTrkDz");
00088   Double_t pShwTrkDt = ac.GetDouble("ShwTrkDt");
00089   Double_t pShwShwDtpos2 = ac.GetDouble("ShwShwDtpos2");
00090   Double_t pShwShwDz = ac.GetDouble("ShwShwDz");
00091   Double_t pShwShwDt = ac.GetDouble("ShwShwDt");
00092   Double_t pMaxNewShwLen = ac.GetDouble("MaxNewShwLen");
00093   Double_t pHitAssocDTime0 = ac.GetDouble("HitAssocDTime0");
00094   Double_t pHitAssocDTime1 = ac.GetDouble("HitAssocDTime1");
00095   Double_t pHitAssocMaxDist2 = ac.GetDouble("HitAssocMaxDist2");
00096 
00097 // grab all needed input lists
00098   const CandRecord *candrec = cx.GetCandRecord();
00099   assert(candrec);
00100   const VldContext *vldcptr = candrec->GetVldContext();
00101   assert(vldcptr);
00102   VldContext vldc = *vldcptr;
00103   const CandSliceListHandle *slicelist = 0;
00104   CandShowerListHandle *showerlist = 0;
00105   const CandTrackListHandle *tracklist = 0;
00106   CandClusterListHandle *clusterlist = 0;
00107   const TObjArray *cxin =
00108                         dynamic_cast<const TObjArray *>(cx.GetDataIn());
00109   for (Int_t i=0; i<=cxin->GetLast(); i++) {
00110     TObject *tobj = cxin->At(i);
00111     if (tobj->InheritsFrom("CandSliceListHandle")) {
00112       slicelist = dynamic_cast<CandSliceListHandle*>(tobj);
00113     }
00114     if (tobj->InheritsFrom("CandShowerListHandle")) {
00115       showerlist = dynamic_cast<CandShowerListHandle*>(tobj);
00116     }
00117     if (tobj->InheritsFrom("CandTrackListHandle")) {
00118       tracklist = dynamic_cast<CandTrackListHandle*>(tobj);
00119     }
00120     if (tobj->InheritsFrom("CandClusterListHandle")) {
00121       clusterlist = dynamic_cast<CandClusterListHandle*>(tobj);
00122     }
00123   }
00124   if (!slicelist) {
00125     MSG("EventSR",Msg::kError) << "CandSliceListHandle missing\n";
00126     return;
00127   }
00128 
00129   CandShowerHandleItr * showerItr=0;
00130   // create iterators for track, shower, and cluster lists, keying on slice
00131   if (showerlist && showerlist->GetNDaughters()>0) {
00132     showerItr = new CandShowerHandleItr(showerlist->GetDaughterIterator());
00133     CandShowerHandleKeyFunc *showerKf = showerItr->CreateKeyFunc();
00134     showerKf->SetFun(CandShowerHandle::KeyFromSlice);
00135     showerItr->GetSet()->AdoptSortKeyFunc(showerKf);
00136     showerKf = 0;
00137   }
00138 
00139   CandTrackHandleItr * trackItr = 0;
00140   if (tracklist && tracklist->GetNDaughters()>0) {
00141     trackItr = new CandTrackHandleItr(tracklist->GetDaughterIterator());
00142     CandTrackHandleKeyFunc *trackKf = trackItr->CreateKeyFunc();
00143     trackKf->SetFun(CandTrackHandle::KeyFromSlice);
00144     trackItr->GetSet()->AdoptSortKeyFunc(trackKf);
00145     trackKf = 0;
00146   }
00147 
00148   CandClusterHandleItr * clusterItr = 0;
00149   if (clusterlist && clusterlist->GetNDaughters()>0) {
00150     clusterItr = new CandClusterHandleItr(clusterlist->GetDaughterIterator());
00151     CandClusterHandleKeyFunc *clusterKf = clusterItr->CreateKeyFunc();
00152     clusterKf->SetFun(CandClusterHandle::KeyFromSlice);
00153     clusterItr->GetSet()->AdoptSortKeyFunc(clusterKf);
00154     clusterKf = 0;
00155   }
00156 
00157   Int_t nslice=0;
00158 
00159   // loop over slices
00160   CandSliceHandleItr sliceItr(slicelist->GetDaughterIterator());
00161   while (CandSliceHandle *slice =
00162          dynamic_cast<CandSliceHandle*>(sliceItr())) { //loop over slices
00163   
00164     ++nslice;
00165     MSG("EventSR", Msg::kDebug)
00166       << " ****** Slice " << nslice << " *******"  
00167       << endl;   
00168 
00169     TObjArray recolist;
00170     TObjArray eventlist;
00171    
00172     //construct list of all showers and tracks in this slice
00173     FillRecoList(slice,showerItr,trackItr,recolist);
00174 
00175     // remove tracks in recolist which have few/any isolated hits
00176     RemoveTracksinShowers(ac,&recolist);
00177     
00178     MSG("EventSR",Msg::kVerbose)
00179       << "recolist begin " << recolist.GetLast()+1 << "\n";
00180     // loop over shower+tracklist, and find associations
00181     for (Int_t i=0; i<=recolist.GetLast(); i++) {
00182       //determine whether this entry is shower or track
00183       CandShowerHandle *shower=0;
00184       CandTrackHandle *track=0;
00185       CandRecoHandle *reco=0;
00186       if (recolist.At(i)->InheritsFrom("CandShowerHandle")) {
00187         shower = dynamic_cast<CandShowerHandle*>(recolist.At(i));
00188         reco = shower;
00189         MSG("EventSR",Msg::kVerbose) << "  shower " << reco->GetVtxU()
00190                                      << " " << reco->GetVtxV() << " " 
00191                                      << reco->GetVtxZ() << "\n";
00192       }
00193       if (recolist.At(i)->InheritsFrom("CandTrackHandle")) {
00194         track = dynamic_cast<CandTrackHandle*>(recolist.At(i));
00195         reco = track;
00196         MSG("EventSR",Msg::kVerbose) << "  track  " << reco->GetVtxU()
00197                                      << " " << reco->GetVtxV() << " " 
00198                                      << reco->GetVtxZ() << "\n";
00199       }
00200       
00201       // now loop over events previously created
00202       // and see whether this object should be added
00203       Bool_t merge=false;
00204       TObjArray *prevlist=0;
00205       for (Int_t ievt=0; ievt<=eventlist.GetLast(); ievt++) {
00206         Bool_t thiseventmatches=false;
00207         TObjArray *objectlist = dynamic_cast<TObjArray*>(eventlist.At(ievt));
00208         // loop over objects within this event
00209         for (Int_t ireco=0; !thiseventmatches && ireco<=objectlist->GetLast(); ireco++) {
00210           Bool_t match=false;
00211           if (objectlist->At(ireco)->InheritsFrom("CandShowerHandle")) {
00212             CandShowerHandle *target = dynamic_cast<CandShowerHandle*>
00213               (objectlist->At(ireco));
00214             if(shower) {
00215               match = target->BelongsWithShower(shower,ac,vldcptr,
00216                                                 pShwShwDtpos2,
00217                                                 pShwShwDz,pShwShwDt);
00218             }
00219             if(track) {
00220               match = target->BelongsWithTrack(track,ac,vldcptr,
00221                                                pShwTrkDtpos2,
00222                                                pShwTrkDz,pShwTrkDt);
00223               match = match && MatchOtherTracksInEvent(ac,vldcptr,track,objectlist);
00224             }
00225           }
00226           else if (objectlist->At(ireco)->InheritsFrom("CandTrackHandle")) {
00227             CandTrackHandle *target = dynamic_cast<CandTrackHandle*>
00228               (objectlist->At(ireco));
00229             if(shower) {
00230               match = target->BelongsWithShower(shower,ac,vldcptr,
00231                                                 pShwTrkDtpos2,
00232                                                 pShwTrkDz,pShwTrkDt);         
00233             }
00234             if(track) {
00235               match = target->BelongsWithTrack(track,ac,vldcptr,
00236                                                pTrkTrkDtpos2,
00237                                                pTrkTrkDz,pTrkTrkDt);
00238               match = match && MatchOtherTracksInEvent(ac,vldcptr,track,objectlist);
00239             }
00240           }
00241           if(match){
00242             thiseventmatches = true;
00243             MSG("EventSR",Msg::kVerbose)
00244               << "  adding object to event \n";
00245             AddObjectToEvent(reco,objectlist,prevlist,merge);
00246             if(!merge) prevlist=objectlist;
00247             merge=true;
00248           }
00249         } // end loop over objects in event
00250       } // end loop over event list
00251         // we found no matches for this object, so start a new event
00252       if (!merge) {
00253         Bool_t pass=true;
00254         if (shower) {
00255           MSG("EventSR",Msg::kVerbose)
00256             << "    none found, creating event for shower\n";
00257         }
00258         
00259         if (track) {
00260           MSG("EventSR",Msg::kVerbose)
00261             << "    none found, creating event for track\n";
00262         }
00263         
00264         if(pass){
00265           TObjArray *event = new TObjArray;
00266           event->Add(recolist.At(i));
00267           eventlist.Add(event);
00268         }
00269       }
00270     } // end loop over recolist
00271   
00272     // remove all empty events from event list
00273     for (Int_t i=0; i<=eventlist.GetLast(); i++) {
00274       TObjArray *objectlist = dynamic_cast<TObjArray*>(eventlist.At(i));
00275       if (objectlist->GetLast()<0) {
00276         eventlist.Remove(objectlist);
00277       }
00278     }
00279     eventlist.Compress();
00280     
00281     // merge showers in NC events
00282     MergeShowers(cxx, eventlist,ac,slice,clusterlist,showerlist);
00283     
00284     // now make CandEvents for each event we have found
00285     Bool_t buildEvent=false;
00286     for (Int_t i=0; i<=eventlist.GetLast(); i++) {
00287       TObjArray *objectlist = dynamic_cast<TObjArray*>(eventlist.At(i));
00288       MSG("EventSR",Msg::kVerbose)  << "making event of " 
00289                                     << objectlist->GetLast()+1 
00290                                     << " objects \n";
00291       cxx.SetDataIn(objectlist);
00292       buildEvent=true;
00293       CandEventHandle eventhandle = CandEvent::MakeCandidate(ah,cxx);
00294       MSG("EventSR",Msg::kVerbose) << " # of strips:  " 
00295                                    << eventhandle.GetNDaughters() << "\n";
00296       eventhandle.SetCandSlice(slice);
00297       ch.AddDaughterLink(eventhandle);
00298       delete eventlist.At(i);
00299     }
00300     if (!buildEvent) BuildEventFromUnassoc(ac,ch,cx,slice);
00301   }
00302   
00303   delete trackItr;
00304   delete showerItr;
00305   delete clusterItr;
00306     
00307   MSG("EventSR",Msg::kVerbose) << "starting unassociated hits assignment \n";
00308 
00309   // find unassociated hits, and place them in tobjarray
00310   sliceItr.Reset(); 
00311   TObjArray unassociated;
00312   CandShowerHandleItr * showerItr2=0;
00313   CandTrackHandleItr * trackItr2=0;
00314   CandEventListHandle &eventlist = dynamic_cast<CandEventListHandle &>(ch);
00315   CandEventHandleItr * eventItr2=0;
00316   if (showerlist && showerlist->GetNDaughters()>0) {
00317     showerItr2 = new CandShowerHandleItr(showerlist->GetDaughterIterator());
00318   }
00319   if (tracklist && tracklist->GetNDaughters()>0) { 
00320     trackItr2 = new CandTrackHandleItr(tracklist->GetDaughterIterator());
00321   }
00322   if (eventlist.GetNDaughters()>0) {    
00323     eventItr2 = new CandEventHandleItr(eventlist.GetDaughterIterator());
00324   }
00325   FindUnassociated(ac, sliceItr,eventItr2, unassociated);  
00326   delete trackItr2;
00327   delete showerItr2;
00328   delete eventItr2;
00329 
00330   // reset primary shower assignment for each event (is this needed?)
00331   SetPrimaryShowers(ch,ac);
00332 
00333 // now loop over unnassociated hits, and check for adjacency with all
00334 // showers, and track vertices (in the case that no shower exists).  
00335 // If a match is found in the former case,
00336 // add strip to shower.  In the latter case, create a new shower.
00337  
00338   // this map contains the separation between each event/unassociated hit
00339   vector<map<const CandEventHandle*, Double_t> > dist2map(unassociated.GetLast()+1);
00340   FillDist2Map(ac,unassociated,ch,dist2map);
00341   
00342   vector<Bool_t> alreadyUsed(unassociated.GetLast()+1);
00343   for (Int_t i=0; i<=unassociated.GetLast(); i++) alreadyUsed[i] = false;
00344   
00345   // loop over unnassociated hits, adding them to events.
00346   // After each loop the affected distance map entries are recalculated, 
00347   // and the loop is repeated.  This continues until a loop adds no strips.
00348   Bool_t found=true;
00349   Int_t n_found=0;
00350   while (found) {
00351     // found indicates whether a strip was added to an event in this loop
00352     found=false;
00353     
00354     CandStripHandle *closeststrip= 0;
00355     CandEventHandle *closestevent= 0;
00356     Double_t closestdist2 = 9999999.;
00357     Int_t closesti=-1;
00358     
00359     // loop over unassoc strips
00360     for (Int_t i=0; i<=unassociated.GetLast(); i++) {
00361       if(alreadyUsed[i]) continue;
00362       
00363       CandStripHandle *strip =
00364         dynamic_cast<CandStripHandle*>(unassociated.At(i));
00365       
00366       CandEventHandle *bestevent = 0;
00367       Double_t bestdist2 = 9999999.;
00368       // loop over events, and find event which is closest to strip
00369       // and in time
00370       TIter eventItr(ch.GetDaughterIterator());
00371       while (CandEventHandle *event =
00372              dynamic_cast<CandEventHandle*>(eventItr())) {
00373         Double_t dtime = strip->GetBegTime()-event->GetVtxT();
00374         if (dtime>pHitAssocDTime0 && dtime<pHitAssocDTime1
00375             && (!bestevent || dist2map[i][event]<bestdist2)) {
00376           bestevent = event;
00377           bestdist2 = dist2map[i][event];
00378         }
00379       }          
00380       if (bestevent && (!closeststrip || bestdist2<closestdist2)) {
00381         closeststrip = strip;
00382         closesti=i;
00383         closestdist2 = bestdist2;
00384         closestevent = bestevent;
00385       }
00386     }
00387     MSG("EventSR",Msg::kVerbose)<< "closest strip " << closestdist2
00388                                 << "/"<<pHitAssocMaxDist2<< endl; 
00389     
00390     // if distance to closest event less than maximum allowable add to event   
00391     if(closeststrip && closestevent && closestdist2<pHitAssocMaxDist2){
00392     
00393       MSG("EventSR",Msg::kVerbose) << "closest strip "
00394                                    << closeststrip->GetPlane() << " "
00395                                    << closeststrip->GetTPos()
00396                                    << " " << closestdist2 << "\n"; 
00397 
00398       alreadyUsed[closesti] = true;
00399       found=true;
00400       ++n_found;
00401 
00402       // now either add this strip to existing primary shower, or
00403       // create a new shower at the track vertex if one does not exist
00404       // Get PrimaryShower CandHandle from fShowerList for modification.
00405       CandShowerHandle *shower = 0;
00406       if (CandShowerHandle *primsh = closestevent->GetPrimaryShower()) {
00407         for (Int_t ishower=0; !shower &&
00408                    ishower<closestevent->GetLastShower()+1; ishower++) {
00409            const CandShowerHandle *target =
00410                                        closestevent->GetShower(ishower);
00411            if (primsh->IsCloneOf(*target))     // Tests clone or Cand ==
00412              shower = closestevent->GetShowerWritable(ishower);
00413         }
00414       }
00415       
00416       Float_t minShwPlane=0;
00417       Float_t maxShwPlane=0;
00418       if(shower){
00419         minShwPlane=min(shower->GetVtxPlane(),shower->GetEndPlane());
00420         maxShwPlane=max(shower->GetVtxPlane(),shower->GetEndPlane());
00421       }
00422       Float_t vertexsep = 0;
00423       CandTrackHandle *track = closestevent->GetPrimaryTrack();
00424       if (shower && track) {
00425         vertexsep = abs(shower->GetBegPlane() - track->GetBegPlane());
00426         vertexsep *= PITCHINMETRES;
00427         MSG("EventSR",Msg::kVerbose) << "Found track and primary shower. \n" 
00428                                      << "Vertex separation (limit) = " 
00429                                      << vertexsep << "(" 
00430                                      << pShwTrkDz << ")" << " \n";
00431       }
00432       // if event has shower and either no track, or shower is close
00433       // to track vertex, add this hit to the shower which was
00434       // compared in position to this strip earler.
00435       if (shower && (!track || vertexsep<pShwTrkDz)) {
00436 
00437         // NOTE: CandShowerHandle *shower, used to modify CandShower, is owned
00438         // by fShowerList.
00439         // add new strip to this shower, and the appropriate cluster
00440         if(closeststrip->GetPlane()>minShwPlane-pMaxNewShwLen &&
00441            closeststrip->GetPlane()<maxShwPlane+pMaxNewShwLen ){
00442           
00443           MSG("EventSR",Msg::kVerbose) << "adding strip to shower \n"; 
00444           AddStripToEvent(closestevent,shower,clusterlist,closeststrip);
00445         }
00446       }
00447 
00448       // no shower consistent with track vertex, and this strip
00449       // is close to vertex, so start new shower.    
00450       else if (track) {
00451         CreatePrimaryShower(ac,cxx,closestevent,showerlist,
00452                             clusterlist,closeststrip);
00453       }
00454 
00455       // need to recalculate distances bewteen remaining
00456       // unassoc hits and this modified event, if the added strip
00457       // results in a smaller separation, replace value in dist2map 
00458       ReFillDist2Map(ac,closeststrip,closestevent,unassociated,dist2map);
00459     } // if adding strip to event in form of new shower
00460   } // if found (if an unassoc hit was matched to event in last loop over them
00461 
00462 // because we have added strips to previously constructed showers, their
00463 // runalg method should be run on them again.  In the future, an
00464 // optimization would be to do this only on showers which have been
00465 // touched.
00466   MSG("EventSR",Msg::kVerbose) << "added " << n_found << " of "
00467                                << unassociated.GetLast()+1 
00468                                << " unassociated hits " << endl;
00469 
00470   cxx.SetDataIn(showerlist);  // Pass along persistable CandShowerList
00471   ReConstructShowers(ac,ch,cxx);
00472 
00473 // For each event, we set it's primary shower to that which has the
00474 // highest energy.
00475 
00476   SetPrimaryShowers(ch,ac);
00477 }
00478 
00479 //____________________________________________________________________
00482 void AlgEventSRList::AddStripToEvent(CandEventHandle * closestevent,
00483                                      CandShowerHandle * shower,
00484                                      CandClusterListHandle * clusterlist, 
00485                                      CandStripHandle * closeststrip)
00486 {
00487   closestevent->AddDaughterLink(*closeststrip);
00488   shower->AddDaughterLink(*closeststrip);
00489   Int_t foundcluster=0;
00490   for (Int_t icluster=0; icluster < shower->GetLastCluster()+1 &&
00491          foundcluster==0; icluster++) {
00492     CandClusterHandle *cl = const_cast<CandClusterHandle *>
00493       (shower->GetCluster(icluster));
00494     // add strip to cluster of the same view
00495     if (cl->GetPlaneView()==closeststrip->GetPlaneView()) {
00496       foundcluster=1;
00497       MSG("EventSR",Msg::kVerbose) << "adding strip to cluster "
00498                                    << closeststrip->GetPlane() << endl;
00499       TIter cchItr(clusterlist->GetDaughterIterator());
00500       while (CandClusterHandle *cch = 
00501              dynamic_cast<CandClusterHandle*>(cchItr())) {
00502         if(cch->IsEquivalent(cl)) {
00503           shower->RemoveCluster(cl);
00504           CandClusterHandle * newcl = cch->DupHandle();
00505           newcl->SetCandSlice(cch->GetCandSlice());
00506           newcl->AddDaughterLink(*closeststrip);
00507           clusterlist->RemoveDaughter(cch);
00508           clusterlist->AddDaughterLink(*newcl);
00509           shower->AddCluster(newcl);
00510           delete newcl;
00511           break;
00512         }
00513       }
00514     }
00515   }
00516 }
00517 //__________________________________________________________
00518 
00519 void AlgEventSRList::CreatePrimaryShower(AlgConfig & ac, CandContext & cxx, 
00520                                          CandEventHandle * closestevent,
00521                                          CandShowerListHandle * showerlist,
00522                                          CandClusterListHandle * clusterlist,
00523                                          CandStripHandle * closeststrip)
00524 {
00525   // need to create a shower -- include strips from first plane in each
00526   // view plus this previously unassociated hit to generate a 3D object
00527   
00528   // Get singleton instance of AlgFactory
00529   const char *pEventAlgConfig = 0;
00530   ac.Get("EventAlgConfig",pEventAlgConfig);
00531 
00532   //Double_t shwshwdz = ac.GetDouble("ShwShwDz");
00533   //Double_t minShwEFract = ac.GetDouble("MinShwEFract");
00534   Double_t pMinShwStripPE = ac.GetDouble("MinShwStripPE");
00535   Double_t pMaxNewShwLen = ac.GetDouble("MaxNewShwLen");
00536 
00537   AlgFactory &af = AlgFactory::GetInstance();
00538   
00539   CandTrackHandle *track = closestevent->GetPrimaryTrack();
00540   if (!showerlist) {
00541     MSG("EventSR",Msg::kError) <<"CandShowerListHandle missing\n" << endl;
00542     return;
00543   }
00544   
00545   closestevent->AddDaughterLink(*closeststrip);
00546   
00547   // create arrays of strips for each planeview to create
00548   // shower from
00549   
00550   MSG("EventSR",Msg::kVerbose) <<  "creating shower \n";
00551   TObjArray ustriparray;
00552   TObjArray vstriparray;
00553   Int_t uplane=track->GetBegPlane(PlaneView::kU);
00554   Int_t vplane=track->GetBegPlane(PlaneView::kV);
00555   // seed this shower with strips in most upstream track hits 
00556   // in each view, along with hits above a charge threshold and
00557   // within pMaxNewShwLen of  the track start
00558   TIter stripItr(track->GetDaughterIterator());
00559   while (CandStripHandle *tstrip =
00560          dynamic_cast<CandStripHandle*>(stripItr())) {
00561     if ((tstrip->GetPlane() == uplane) || 
00562         (tstrip->GetPlaneView()==PlaneView::kU &&
00563             tstrip->GetCharge()>pMinShwStripPE && 
00564             abs(tstrip->GetPlane()-uplane)<pMaxNewShwLen)) {
00565       ustriparray.Add(tstrip);
00566     }
00567     if ((tstrip->GetPlane() == vplane) || 
00568         (tstrip->GetPlaneView()==PlaneView::kV &&
00569             tstrip->GetCharge()>pMinShwStripPE && 
00570             abs(tstrip->GetPlane()-vplane)<pMaxNewShwLen)) {
00571       vstriparray.Add(tstrip);
00572     }
00573   }
00574   // add unassoc strip to appropriate array
00575   switch (closeststrip->GetPlaneView()) {
00576   case PlaneView::kU:
00577     ustriparray.Add(closeststrip);
00578     break;
00579   case PlaneView::kV:
00580     vstriparray.Add(closeststrip);
00581     break;
00582   default:
00583     break;
00584   }
00585   // build shower from U/V clusters
00586   if(ustriparray.GetLast()>=0 && vstriparray.GetLast()>=0){
00587     // now construct CandClusters
00588     AlgHandle clusterah = af.GetAlgHandle("AlgClusterSR","default");
00589     
00590     cxx.SetDataIn(&ustriparray);
00591     CandClusterHandle uclusterhandle =
00592       CandCluster::MakeCandidate(clusterah,cxx);
00593     uclusterhandle.SetCandSlice(closestevent->GetCandSlice());
00594     uclusterhandle.IsShowerLike(1);
00595     clusterlist->AddDaughterLink(uclusterhandle);
00596     
00597     cxx.SetDataIn(&vstriparray);
00598     CandClusterHandle vclusterhandle =
00599       CandCluster::MakeCandidate(clusterah,cxx);
00600     vclusterhandle.SetCandSlice(closestevent->GetCandSlice());
00601     vclusterhandle.IsShowerLike(1);
00602     clusterlist->AddDaughterLink(vclusterhandle);
00603     
00604     // build shower from U/V clusters just created
00605     TObjArray newshower;
00606     CandHandle * ucluster =
00607       clusterlist->FindDaughter(&uclusterhandle);
00608     CandHandle * vcluster =
00609       clusterlist->FindDaughter(&vclusterhandle);
00610     
00611     newshower.Add(ucluster);
00612     newshower.Add(vcluster);
00613     
00614     cxx.SetDataIn(&newshower);
00615     AlgHandle showerah = af.GetAlgHandle("AlgShowerSR",pEventAlgConfig);
00616     CandShowerHandle showerhandle =
00617       CandShower::MakeCandidate(showerah,cxx);
00618     showerhandle.SetCandSlice(closestevent->GetCandSlice());
00619     showerlist->AddDaughterLink(showerhandle);
00620     CandHandle *shw = showerlist->FindDaughter(&showerhandle);
00621     CandShowerHandle *shwh = dynamic_cast<CandShowerHandle*>(shw);
00622     
00623     // add this new shower to this event, and make it the
00624     // primary shower
00625     closestevent->AddShower(shwh);    
00626     closestevent->SetPrimaryShower(shwh);
00627   }
00628 }
00629 
00630 //____________________________________________________________________
00631 void AlgEventSRList:: ReFillDist2Map(AlgConfig & ac, CandStripHandle * closeststrip, 
00632                                      CandEventHandle * closestevent,TObjArray & unassociated,  
00633                                      std::vector<std::map<const CandEventHandle*, Double_t> > & dist2map)
00634 {
00635   Double_t pHitAssocZParm = ac.GetDouble("HitAssocZParm");
00636   Double_t pHitAssocPParm = ac.GetDouble("HitAssocPParm");
00637   Double_t pHitAssocTParm = ac.GetDouble("HitAssocTParm");
00638 
00639   for (Int_t i=0; i<=unassociated.GetLast(); i++) {
00640     CandStripHandle *strip =
00641       dynamic_cast<CandStripHandle*>(unassociated.At(i));
00642     if(strip->GetPlaneView()==closeststrip->GetPlaneView()){
00643       Double_t dtime = strip->GetBegTime()-closestevent->GetVtxT();
00644       Double_t dplane =
00645         (Double_t)(strip->GetPlane()-closeststrip->GetPlane());
00646       Double_t dtpos = strip->GetTPos()-closeststrip->GetTPos();
00647       Double_t dist2 = (pHitAssocZParm*dplane*dplane) +
00648         (pHitAssocPParm*dtpos*dtpos) +
00649         (pHitAssocTParm*dtime*dtime);
00650       if (dist2<dist2map[i][closestevent]) {
00651         dist2map[i][closestevent] = dist2;
00652       }
00653     }
00654   } // loop over unassoc hits
00655 }
00656 
00657 //______________________________________________________________________
00661 void AlgEventSRList::ReConstructShowers(AlgConfig &ac, CandHandle &ch, CandContext &cxx)
00662 {
00663 
00664   // Retrieve persistant modifiable CandShowerList
00665   CandShowerListHandle *showerlist = const_cast<CandShowerListHandle*>
00666     (dynamic_cast<const CandShowerListHandle*>(cxx.GetDataIn()));
00667 
00668   // Get singleton instance of AlgFactory
00669   AlgFactory &af = AlgFactory::GetInstance();
00670 
00671   // Get an AlgHandle to AlgShowerSR with default AlgConfig
00672   const char *pEventAlgConfig = 0;
00673   ac.Get("EventAlgConfig",pEventAlgConfig);
00674   
00675   AlgHandle ah = af.GetAlgHandle("AlgShowerSR",pEventAlgConfig);
00676   AlgConfig acshw = ah.GetAlgConfig();
00677 
00678   TIter evItr(ch.GetDaughterIterator());
00679   while (CandEventHandle *ev =
00680          dynamic_cast<CandEventHandle*>(evItr())) {
00681     for (Int_t ishower=0; ishower<ev->GetLastShower()+1; ishower++) {
00682       CandShowerHandle *shower =
00683         dynamic_cast<CandShowerHandle*>(ev->GetShowerWritable(ishower));
00684       if (shower) {
00685         TObjArray newshower;
00686         // fill  array of clusters for this shower
00687         for (Int_t icluster=0; icluster<shower->GetLastCluster()+1;
00688              icluster++) {
00689           const CandClusterHandle *cl = shower->GetCluster(icluster);
00690           if (cl) {
00691             // New handle on heap
00692             CandClusterHandle *cclh = cl->DupHandle();
00693             // Add new heap-based CandHandle to TObjArray
00694             newshower.Add(cclh);
00695           }
00696         }
00697         // re-run algorithm for this shower
00698         if (newshower.GetEntriesFast() > 0) {
00699           cxx.SetDataIn(&newshower);
00700           ah.RunAlg(*shower,cxx);
00701         }
00702         else {
00703           MSG("EventSR", Msg::kError)
00704             << "Attempt to pass empty TObjArray newshower to AlgShowerSR"
00705             << " in CandContext.  AlgShowerSR::RunAlg() call ignored."
00706             << endl;
00707         }
00708 
00709         // Delete heap-based CandHandles in TObjArray
00710         newshower.Delete();
00711       }
00712       else {
00713         MSG("EventSR",Msg::kWarning)
00714           << "Handle is not a CandShowerHandle."
00715           << "  Shower not processed in ReConstructShowers."
00716           << endl;
00717         continue;
00718       }
00719 
00720       // now loop through strips in this shower, and determine whether primary
00721       // track in this event intercepts this strip.  If so, subtract 1 mip
00722       // from shower energy.
00723       
00724       CandTrackHandle *primaryTrack = ev->GetPrimaryTrack();
00725       
00726       // if event has primary track, extrapolate through shower and subtract energy loss to recalibrate 
00727       if (primaryTrack) shower->CalibrateEnergy(primaryTrack,acshw);
00728       
00729       // Update modified showers in persistent modifiable CandShowerList.
00730       // CandHandle could potentially supply a ReplaceDaughter() function.
00731       // Interface of ReplaceDaughter() would be debatable.
00732       if (showerlist) {
00733         TIter shiter(showerlist->GetDaughterIterator());
00734         CandShowerHandle *target;
00735         Bool_t found = kFALSE;
00736         while (!found &&
00737                (target = dynamic_cast<CandShowerHandle*>(shiter()))) {
00738           if (shower->IsCloneOf(*target)) {  // Tests clone or Cand ==
00739             found = kTRUE;
00740             
00741             // Replace target only if shower is a modified version of target
00742             
00743             if (!(shower->IsEqual(target))) {   // CandBase inequality
00744               shower->SetCandSlice(ev->GetCandSlice());
00745               if (!showerlist->RemoveDaughter(target)) {    // Failure
00746                 MSG("EventSR",Msg::kError) << endl
00747                                            << "Failure of ShowerList daughter removal " << endl
00748                                            << "attempted during replacement by modified Shower."
00749                                            << endl << "Will result in double counted Shower."
00750                                            << endl;
00751               }
00752               showerlist->AddDaughterLink(*shower);
00753             }
00754           }
00755         }
00756         
00757         // Add new (unfound) shower to persistent modifiable CandShowerList.
00758         if (!found){
00759           shower->SetCandSlice(ev->GetCandSlice());
00760           showerlist->AddDaughterLink(*shower);
00761         }
00762       }
00763     }
00764   }
00765 }
00766 
00767 //______________________________________________________________________
00770 void AlgEventSRList::SetPrimaryShowers(CandHandle &ch,AlgConfig &ac)
00771 {
00772   
00773   // This method loops over events in the eventlist, finding the largest
00774   // shower and setting that to the primary shower in the event.
00775   
00776   Double_t pShwShwDz = ac.GetDouble("ShwShwDz");
00777   Double_t pMinShwEFract = ac.GetDouble("MinShwEFract");
00778   
00779   TIter evItr(ch.GetDaughterIterator());
00780   while (CandEventHandle *ev =
00781          dynamic_cast<CandEventHandle*>(evItr())) {
00782     ev->SetPrimaryShower(pMinShwEFract,pShwShwDz);
00783   }
00784 }
00785 
00786 //______________________________________________________________________
00789 void AlgEventSRList::BuildEventFromUnassoc(AlgConfig &ac,
00790                                            CandHandle &ch,
00791                                            CandContext &cx, 
00792                                            CandSliceHandle * slice)
00793 {
00794   assert(cx.GetDataIn());
00795   MSG("EventSR",Msg::kDebug) <<" Building Event - no showers or tracks " 
00796                              << endl;
00797   if (!(cx.GetDataIn()->InheritsFrom("TObjArray"))) {
00798     MSG("EventSR",Msg::kDebug)<<" dataIn inherits from TObjArray " << endl;
00799     return;
00800   }
00801   
00802   const CandSliceListHandle *slicelist = 0;
00803   CandShowerListHandle *showerlist = 0;
00804   CandClusterListHandle *clusterlist = 0;  
00805   const TObjArray *cxin = dynamic_cast<const TObjArray *>(cx.GetDataIn());
00806   for (Int_t i=0; i<=cxin->GetLast(); i++) {
00807     TObject *tobj = cxin->At(i);
00808     if (tobj->InheritsFrom("CandSliceListHandle")) {
00809       slicelist = dynamic_cast<CandSliceListHandle*>(tobj);
00810     }
00811     // Retrieve persistant modifiable CandShowerList
00812     if (tobj->InheritsFrom("CandShowerListHandle")) {
00813       showerlist = dynamic_cast<CandShowerListHandle*>(tobj);
00814     }
00815     if (tobj->InheritsFrom("CandClusterListHandle")) {
00816       clusterlist = dynamic_cast<CandClusterListHandle*>(tobj);
00817     }
00818   }
00819   
00820   if (!showerlist || !slicelist) {
00821     MSG("EventSR",Msg::kDebug)<<" no showerlist " << endl;
00822     return;
00823   }
00824   Int_t detectorType = slicelist->GetVldContext()->GetDetector();
00825   
00826   CandContext cxx(this,cx.GetMom());
00827   AlgFactory &af = AlgFactory::GetInstance();
00828   
00829   const char *pEventAlgConfig = 0;
00830   ac.Get("EventAlgConfig",pEventAlgConfig);
00831   AlgHandle ah = af.GetAlgHandle("AlgEventSR",pEventAlgConfig);
00832   
00833   Double_t pHitAssocDPlane = ac.GetInt("HitAssocDPlane");
00834   Double_t pHitAssocDTime0 = ac.GetDouble("HitAssocDTime0");
00835   Double_t pHitAssocDTime1 = ac.GetDouble("HitAssocDTime1");
00836   Double_t pHitAssocMaxDist2 = ac.GetDouble("HitAssocMaxDist2");
00837   Double_t pHitAssocZParm = ac.GetDouble("HitAssocZParm");
00838   Double_t pHitAssocPParm = ac.GetDouble("HitAssocPParm");
00839   Double_t pHitAssocTParm = ac.GetDouble("HitAssocTParm");
00840   Double_t pShwShwDtpos2 = ac.GetDouble("ShwShwDtpos2");
00841   Double_t pShwShwDz = ac.GetDouble("ShwShwDz");
00842   Double_t pShwShwDt = ac.GetDouble("ShwShwDt");
00843   Double_t pMinShwEFract = ac.GetDouble("MinShwEFract");
00844   Double_t pMinUnassocStripPE = ac.GetDouble("MinUnassocStripPE");
00845 
00846   const CandRecord *candrec = cx.GetCandRecord();
00847   assert(candrec);
00848   const VldContext *vldcptr = candrec->GetVldContext();
00849   assert(vldcptr);
00850   VldContext vldc = *vldcptr;
00851   UgliGeomHandle ugh(vldc);
00852 
00853   // Iterate over strips , finding sets which are 'in time', and within
00854   // a given distance of the nearest neighbor in the set, in both views.
00855   // Each of these sets is then used to construct a shower, which becomes
00856   // the primary shower of a new event.  We continue until an iteration
00857   // in which no new event is created.
00858   
00859   // fill array of unique unassociated strips
00860   TObjArray unassociated;
00861   TIter stripItr(slice->GetDaughterIterator());
00862   while (CandStripHandle *strip =
00863          dynamic_cast<CandStripHandle*>(stripItr())) {
00864 
00865     // Ignore strips below the required minimum PE
00866     if (strip->GetCharge(CalDigitType::kPE)<pMinUnassocStripPE) continue;
00867 
00868     Bool_t found=false;
00869     for (Int_t i=0; i<=unassociated.GetLast() && !found; i++) {
00870       CandStripHandle *strip0 =
00871         dynamic_cast<CandStripHandle*>(unassociated.At(i));
00872       if (*strip == *strip0) {
00873         found = true;
00874       }
00875     }
00876     if (!found) {
00877       if(!(detectorType==Detector::kNear && strip->GetPlane()>120)){
00878         unassociated.Add(strip);
00879       }
00880     }
00881   }
00882   
00883     // loop until no new matches are found in the loop over unassoc hits.
00884   Bool_t found=false;
00885   while (unassociated.GetLast()>0 && !found) {
00886     MSG("EventSR",Msg::kDebug)<< " # unassoc " 
00887                               << unassociated.GetLast()+1 << endl; 
00888     Bool_t firstu=true;
00889     Bool_t firstv=true;
00890     TObjArray neweventu;
00891     TObjArray neweventv;
00892     Bool_t addedstrip = true;
00893     Float_t totcharge=0;
00894     while (addedstrip) {
00895       addedstrip=false;      
00896       // loop over unassoc strips.
00897       for (Int_t i=0; i<=unassociated.GetLast(); i++) {
00898         CandStripHandle *strip =
00899           dynamic_cast<CandStripHandle*>(unassociated.At(i));
00900         switch (strip->GetPlaneView()) {
00901         case PlaneView::kU:
00902           // strip is in U plane
00903           // if this is the first strip, add to newevent strip list
00904           if (firstu) {
00905             // if we don't have v strips yet, just add this strip to u list
00906             // seed the event
00907             if (firstv) {
00908               neweventu.Add(strip);
00909               MSG("EventSR",Msg::kDebug)<< " add  first  " << endl;
00910               totcharge +=strip->GetCharge();
00911               addedstrip = true;
00912               firstu=false;
00913             }
00914             // if we already have one or more v strips check that they are
00915             // in time, and  agree in Z position.
00916             else {
00917               Bool_t found2=false;
00918               for (Int_t j=0; j<=neweventv.GetLast() && !found2;
00919                    j++) {
00920                 CandStripHandle *estrip =
00921                   dynamic_cast<CandStripHandle*>(neweventv.At(j));
00922                 Double_t dtime =
00923                   strip->GetBegTime()-estrip->GetBegTime(); 
00924                 MSG("EventSR",Msg::kDebug) << " dtime " << dtime*1e9 
00925                                            << " " <<pHitAssocDTime0*1e9 
00926                                            << "/" << pHitAssocDTime1*1e9 
00927                                            << " plane diff " 
00928                                            <<  abs(strip->GetPlane() - 
00929                                                    estrip->GetPlane()) 
00930                                            << "/" << pHitAssocDPlane << endl;
00931                 if (dtime>pHitAssocDTime0 &&
00932                     dtime<pHitAssocDTime1 &&
00933                     abs(strip->GetPlane()-estrip->GetPlane()) <=
00934                     pHitAssocDPlane) {
00935                   MSG("EventSR",Msg::kDebug)<< " add  " << endl;
00936                   // match is found, add this strip to array
00937                   neweventu.Add(strip);
00938                   totcharge +=strip->GetCharge();
00939                   addedstrip = true;
00940                   firstu=0;
00941                   found2=true;
00942                 } // if match found
00943               }  // for loop over V strips in new event
00944             } // end not first V strip
00945           } // end first U strip
00946           else {  
00947             // if we already have u strips, make sure that the one we
00948             // add is adjaccent, using distance criteria based
00949             // on plane, time, and transverse postion separation
00950             Bool_t found2=false;
00951             for (Int_t j=0; j<=neweventu.GetLast() && !found2; j++) {
00952               CandStripHandle *estrip =
00953                 dynamic_cast<CandStripHandle*>(neweventu.At(j));
00954               Double_t dtime =
00955                 strip->GetBegTime()-estrip->GetBegTime(); 
00956               MSG("EventSR",Msg::kDebug) << " dtime " << dtime*1e9 
00957                                          << " " <<pHitAssocDTime0*1e9 
00958                                          << "/" << pHitAssocDTime1*1e9 
00959                                          << " plane diff " 
00960                                          << abs(strip->GetPlane() - 
00961                                                 estrip->GetPlane())
00962                                          << " dtpos " << (strip->GetTPos() - 
00963                                                           estrip->GetTPos())
00964                                          << endl;
00965               if (dtime>pHitAssocDTime0 &&
00966                   dtime<pHitAssocDTime1) {
00967                 Double_t dplane =
00968                   (Double_t)(strip->GetPlane()-estrip->GetPlane());
00969                 Double_t dtpos = strip->GetTPos()-estrip->GetTPos();
00970                 Double_t dist2 = (pHitAssocZParm*dplane*dplane) +
00971                   (pHitAssocPParm*dtpos*dtpos) +
00972                   (pHitAssocTParm*dtime*dtime);
00973                 // if dist2 2 parameter meets match criteria, add strip to array
00974                 if (dist2<pHitAssocMaxDist2*4) {
00975                   MSG("EventSR",Msg::kDebug)<< " add " << endl;
00976                   neweventu.Add(strip);
00977                   totcharge +=strip->GetCharge();
00978                   addedstrip = true;
00979                   firstu=0;
00980                   found2=true;
00981                 } // if positions match
00982               } // if in time
00983             } // end loop over event u strips
00984           } // end if already have u strip
00985           break;
00986           
00987         case PlaneView::kV:
00988           
00989           // if this is the first strip, add to newevent strip list
00990           if (firstv) {
00991             // strip is in V plane
00992             // if this is the first strip, add to newevent strip list
00993             if (firstu) {
00994               neweventv.Add(strip);
00995               totcharge +=strip->GetCharge();
00996               MSG("EventSR",Msg::kDebug)<< " add  first" << endl;
00997               addedstrip = true;
00998               firstv = 0;
00999             }
01000             else {
01001               // if we already have one or more u strips check that they are
01002               // in time, and require agreement in Z position.
01003               Bool_t found2=false;
01004               for (Int_t j=0; j<=neweventu.GetLast() && !found2;
01005                    j++) {
01006                 CandStripHandle *estrip =
01007                   dynamic_cast<CandStripHandle*>(neweventu.At(j));
01008                 Double_t dtime =
01009                   strip->GetBegTime()-estrip->GetBegTime();
01010                 MSG("EventSR",Msg::kDebug) << " dtime " << dtime*1e9 
01011                                            << " " << pHitAssocDTime0*1e9 
01012                                            << "/" << pHitAssocDTime1*1e9 
01013                                            << " plane diff " 
01014                                            <<  abs(strip->GetPlane() - 
01015                                                    estrip->GetPlane()) 
01016                                            << "/" << pHitAssocDPlane << endl;
01017                 if (dtime>pHitAssocDTime0 &&
01018                     dtime<pHitAssocDTime1 &&
01019                     abs(strip->GetPlane()-estrip->GetPlane()) <=
01020                     pHitAssocDPlane) {
01021                   // if dist2 2 parameter meets match criteria, 
01022                   //add strip to array
01023                   MSG("EventSR",Msg::kDebug)<< " add  " << endl;
01024                   neweventv.Add(strip);
01025                   totcharge +=strip->GetCharge();
01026                   addedstrip = true;
01027                   firstv = false;
01028                   found2 = true;
01029                 }
01030               } // end loop over u strips in event
01031             } // end if already have u strips
01032           } // end if this is the first v strip
01033           else {
01034             // if we already have v strips, make sure that the one we
01035             // add is adjaccent, using same distance criteria base
01036             // on plane, time, and transverse postion separation
01037             Bool_t found2=false;
01038             for (Int_t j=0; j<=neweventv.GetLast() && !found2; j++) {
01039               CandStripHandle *estrip =
01040                 dynamic_cast<CandStripHandle*>(neweventv.At(j));
01041               Double_t dtime = strip->GetBegTime() -
01042                 estrip->GetBegTime();              
01043               MSG("EventSR",Msg::kDebug)<< " dtime " << dtime*1e9 << " " 
01044                                         <<  pHitAssocDTime0*1e9 << "/" 
01045                                         << pHitAssocDTime1*1e9 
01046                                         << " plane diff " 
01047                                         <<  abs(strip->GetPlane() - 
01048                                                 estrip->GetPlane())
01049                                         << " dtpos " << (strip->GetTPos() - 
01050                                                          estrip->GetTPos())
01051                                         << endl;
01052               if (dtime>pHitAssocDTime0 &&
01053                   dtime<pHitAssocDTime1) {
01054                 Double_t dplane =
01055                   (Double_t)(strip->GetPlane()-estrip->GetPlane());
01056                 Double_t dtpos = strip->GetTPos()-estrip->GetTPos();
01057                 Double_t dist2 = (pHitAssocZParm*dplane*dplane) +
01058                   (pHitAssocPParm*dtpos*dtpos) +
01059                   (pHitAssocTParm*dtime*dtime);
01060                 // if dist2 2 parameter meets match criteria, 
01061                 // add strip to array
01062                 if (dist2<pHitAssocMaxDist2*4) {
01063                   MSG("EventSR",Msg::kDebug)<< " add  " << endl;
01064                   neweventv.Add(strip);
01065                   totcharge +=strip->GetCharge();
01066                   addedstrip = true;
01067                   firstv = false;
01068                   found2 = true;
01069                 } // end if add strip
01070               } //end if in time
01071             }  // end loop over v strips
01072           }
01073           break;
01074           
01075         default:
01076           break;
01077         }
01078       }
01079       
01080       // end of loop over hits - remove new 'associations' and compress
01081       for (Int_t i=0; i<=neweventu.GetLast(); i++) {
01082         CandStripHandle *estrip =
01083           dynamic_cast<CandStripHandle*>(neweventu.At(i));
01084         unassociated.Remove(estrip);
01085       }
01086       for (Int_t i=0; i<=neweventv.GetLast(); i++) {
01087         CandStripHandle *estrip =
01088           dynamic_cast<CandStripHandle*>(neweventv.At(i));
01089         unassociated.Remove(estrip);
01090       }
01091       unassociated.Compress();
01092     }
01093     
01094     // if we have hits in both views, build an event from them
01095     // if pulse height>10 pes
01096     MSG("EventSR",Msg::kDebug)<< " considering event formation  u/v: " 
01097                               << !firstu  << "/" << !firstv << " charge " 
01098                               << totcharge << endl;
01099     if (!firstu && !firstv && totcharge>20.0) {      
01100       found=true;
01101       
01102       Bool_t newShowerOverlapsOld=false;
01103       CandHandle *shw = NULL;
01104 
01105       // construct CandClusters
01106       cxx.SetDataIn(&neweventu);
01107       AlgHandle clusterah = af.GetAlgHandle("AlgClusterSR","default");
01108       CandClusterHandle uclusterhandle =
01109         CandCluster::MakeCandidate(clusterah,cxx);
01110       uclusterhandle.SetCandSlice(slice);
01111       uclusterhandle.IsShowerLike(1);
01112       clusterlist->AddDaughterLink(uclusterhandle);
01113       cxx.SetDataIn(&neweventv);
01114       CandClusterHandle vclusterhandle =
01115         CandCluster::MakeCandidate(clusterah,cxx);
01116       vclusterhandle.SetCandSlice(slice);
01117       vclusterhandle.IsShowerLike(1);
01118       clusterlist->AddDaughterLink(vclusterhandle);
01119       CandHandle *ucluster = clusterlist->FindDaughter(&uclusterhandle);
01120       CandHandle *vcluster = clusterlist->FindDaughter(&vclusterhandle);
01121       
01122       //build shower
01123       TObjArray newshower;
01124       newshower.Add(ucluster);
01125       newshower.Add(vcluster);
01126       cxx.SetDataIn(&newshower);
01127       
01128       
01129       AlgHandle showerah = af.GetAlgHandle("AlgShowerSR",pEventAlgConfig);
01130       CandShowerHandle showerhandle =
01131         CandShower::MakeCandidate(showerah,cxx);
01132       showerhandle.SetCandSlice(slice);
01133       showerhandle.SetCandRecord(slicelist->GetCandRecord());
01134       
01135       CandShowerHandleItr showerItr(showerlist->GetDaughterIterator());
01136       while (CandShowerHandle *shower =
01137              dynamic_cast<CandShowerHandle*>(showerItr())){
01138         if(showerhandle.BelongsWithShower(shower,ac,
01139                                           vldcptr,
01140                                           pShwShwDtpos2,
01141                                           pShwShwDz,
01142                                           pShwShwDt)){
01143           newShowerOverlapsOld=true;
01144           MSG("EventSR",Msg::kDebug) 
01145             << " new shower overlaps with previous - don't make new event " 
01146             << endl;
01147           break;
01148         }
01149       }
01150       
01151       if(!newShowerOverlapsOld){
01152         MSG("EventSR",Msg::kDebug)<< " Building Event! " << endl;
01153         showerlist->AddDaughterLink(showerhandle);
01154         shw = showerlist->FindDaughter(&showerhandle);
01155       }
01156       
01157       if(!newShowerOverlapsOld){
01158         // form event from shower
01159         TObjArray recolist;
01160         recolist.Add(shw);
01161         cxx.SetDataIn(&recolist);
01162         AlgHandle eventah = af.GetAlgHandle("AlgEventSR",pEventAlgConfig);
01163         CandEventHandle eventhandle =
01164           CandEvent::MakeCandidate(eventah,cxx);
01165         eventhandle.SetCandSlice(slice);
01166         eventhandle.SetPrimaryShower(pMinShwEFract,pShwShwDz);
01167         ch.AddDaughterLink(eventhandle);
01168       }
01169     }
01170   }
01171 }
01172 
01173 
01174 //_________________________________________________________________________
01177 void AlgEventSRList::RemoveTracksinShowers(AlgConfig &ac, TObjArray * recolist){
01178 
01179 
01180   Double_t pMinTrackIsolation = ac.GetDouble("MinTrackIsolation");
01181   Double_t pMinTrackIsolationDist = ac.GetDouble("MinTrackIsolationDist");
01182 
01183   for (Int_t i = 0; i <= recolist->GetLast(); i++) {
01184     CandTrackHandle *track=0;
01185     Int_t nisolated = 0;
01186     Int_t nisolatedU = 0;
01187     Int_t nisolatedV = 0;
01188     Bool_t isolated = true;
01189     Int_t longestcontig = 0;
01190     Int_t longestcontigU = 0;
01191     Int_t longestcontigV = 0;
01192  
01193     if (recolist->At(i)->InheritsFrom("CandTrackHandle")) {
01194       track = dynamic_cast<CandTrackHandle*>(recolist->At(i));
01195       
01196       // count number of planes in each view in which
01197       // track is outside shower
01198       Int_t firstplane = TMath::Min(track->GetBegPlane(),
01199                                     track->GetEndPlane());
01200       Int_t lastplane = TMath::Max(track->GetBegPlane(),
01201                                    track->GetEndPlane());
01202       Int_t firstuplane = TMath::Min(track->GetBegPlane(PlaneView::kU),
01203                                      track->GetEndPlane(PlaneView::kU));
01204       Int_t firstvplane = TMath::Min(track->GetBegPlane(PlaneView::kV),
01205                                      track->GetEndPlane(PlaneView::kV));
01206       Int_t lastuplane = TMath::Max(track->GetBegPlane(PlaneView::kU),
01207                                   track->GetEndPlane(PlaneView::kU) );
01208       Int_t lastvplane = TMath::Max(track->GetBegPlane(PlaneView::kV),
01209                                   track->GetEndPlane(PlaneView::kV) );      
01210 
01211       MSG("RemoveTracksInShowers",Msg::kDebug) << " track extent " << firstplane << " " << lastplane <<  " " << track->GetNDaughters() << " " << track->GetBegPlane() << " " << track->GetEndPlane() << endl;
01212 
01213       for(Int_t iplane = firstplane;iplane <= lastplane;iplane++){
01214         PlexPlaneId plnid(track->GetVldContext()->GetDetector(),iplane,false);
01215         // require that the plane be within the track 
01216         // extent for this planeview
01217         isolated = true;
01218         if((plnid.GetPlaneView() == PlaneView::kU  && 
01219             iplane >= firstuplane && iplane <= lastuplane) ||
01220            (plnid.GetPlaneView() == PlaneView::kV  && 
01221             iplane >= firstvplane && 
01222             iplane<=lastvplane)){
01223         
01224           for (Int_t j = 0; j<=recolist->GetLast(); j++) {
01225             if(isolated){
01226               if (recolist->At(j)->InheritsFrom("CandShowerHandle")) {
01227                 CandShowerHandle * shower = dynamic_cast<CandShowerHandle*>(recolist->At(j));
01228                 if(iplane >= shower->GetBegPlane() &&
01229                    iplane <= shower->GetEndPlane()){
01230                   // if plane within shower extent, compare track position
01231                   // with shower width. If track outside shower by
01232                   // a distance pMinTrackIsolationDist, or shower width
01233                   // is less than this distance, inc isolated.
01234                   Double_t minPE=2.0;
01235                   Float_t minUshw = shower->GetMinU(iplane,minPE)+0.02;
01236                   Float_t minVshw = shower->GetMinV(iplane,minPE)+0.02;
01237                   Float_t maxUshw = shower->GetMaxU(iplane,minPE)-0.02;
01238                   Float_t maxVshw = shower->GetMaxV(iplane,minPE)-0.02;
01239 
01240                   MSG("RemoveTracksInShowers",Msg::kDebug) << " shower extent Plane: " << iplane << " U " << minUshw << "/" <<  track->GetU(iplane) << "/" << maxUshw << " V  " << minVshw << "/" << track->GetV(iplane) << "/" << maxVshw << endl;
01241                   
01242                   if(plnid.GetPlaneView() == PlaneView::kU && 
01243                      (track->GetU(iplane) >= (minUshw-pMinTrackIsolationDist) && 
01244                       track->GetU(iplane) <= (maxUshw+pMinTrackIsolationDist) &&
01245                       maxUshw-minUshw > (pMinTrackIsolationDist))){
01246                     isolated = false;
01247                   }
01248                   if(plnid.GetPlaneView() == PlaneView::kV &&
01249                      (track->GetV(iplane) >= (minVshw-pMinTrackIsolationDist)&& 
01250                       track->GetV(iplane) <= (maxVshw+pMinTrackIsolationDist)&&
01251                       maxVshw-minVshw > (pMinTrackIsolationDist))){
01252                     isolated = false;
01253                   }
01254                   if(!track->IsTPosValid(iplane))isolated = false;
01255                 }
01256               }      
01257             }
01258           }
01259           if(track->IsTPosValid(iplane)){
01260             nisolated++;
01261             if(plnid.GetPlaneView() == PlaneView::kU){
01262               nisolatedU++;
01263             }
01264             else{
01265               nisolatedV++;
01266             }
01267           }
01268           if(!isolated) {
01269             nisolated=0;  // reset contig. isolation counter
01270             if(plnid.GetPlaneView() == PlaneView::kU){
01271               nisolatedU=0;
01272             }
01273             else{
01274               nisolatedV=0;
01275             }
01276           }
01277           if(nisolated > longestcontig)longestcontig = nisolated;
01278           if(nisolatedU > longestcontigU)longestcontigU = nisolatedU;
01279           if(nisolatedV > longestcontigV)longestcontigV = nisolatedV;
01280            
01281           MSG("RemoveTracksInShowers",Msg::kDebug) << " nisolated, longest " << nisolated << " " << longestcontig << endl;
01282 
01283           // if the number of contiguous isolated track planes is less than threshold
01284           // we remove this track from the event         
01285         }
01286       } 
01287     }
01288     MSG("RemoveTracksInShowers",Msg::kDebug) << " longest contig:" << longestcontig  << " U " << longestcontigU << " V " << longestcontigV<< "/" << pMinTrackIsolation << endl;
01289     if(track && longestcontig < pMinTrackIsolation &&
01290        longestcontigU < pMinTrackIsolation &&
01291        longestcontigV < pMinTrackIsolation){
01292       MSG("RemoveTracksInShowers",Msg::kDebug) << " REMOVING TRACK" << endl;
01293       recolist->RemoveAt(i);     
01294       recolist->Compress();
01295       //If you compress here then decrement i so that you 
01296       //don't miss any tracks in recolist
01297       i-=1;
01298     }
01299   }
01300 }
01301 //_________________________________________________________________________________
01302 // for a given slice, fill an array with all tracks and showers
01303 void AlgEventSRList::FillRecoList(CandSliceHandle *slice, CandShowerHandleItr * showerItr, 
01304                                   CandTrackHandleItr* trackItr, TObjArray & recolist){
01305 
01306   if (showerItr) {
01307     showerItr->Reset();
01308     while (CandShowerHandle *shower =
01309            dynamic_cast<CandShowerHandle*>((*showerItr)())) {
01310       if (shower->GetCandSlice()) {
01311         if (slice->IsCloneOf(*(shower->GetCandSlice()))) {
01312           recolist.Add(shower);
01313         }
01314       }
01315       else {
01316         MSG("EventSR", Msg::kError)
01317           << "Shower doesn't contain a slice.  Not added to recolist."
01318           << endl;
01319       }
01320     }
01321   }
01322   
01323   if (trackItr) {
01324     trackItr->Reset();
01325     while (CandTrackHandle *track =
01326            dynamic_cast<CandTrackHandle*>((*trackItr)())) {
01327       if (track->GetCandSlice()) {
01328         if (slice->IsCloneOf(*track->GetCandSlice())) {
01329           if(track->GetNDaughters()==0 && 
01330              track->InheritsFrom("CandFitTrackHandle") &&  
01331              dynamic_cast<CandFitTrackHandle*>(track)->GetFinderTrack()){
01332             track = dynamic_cast<CandFitTrackHandle*>(track)->GetFinderTrack();    
01333             MSG("EventSR", Msg::kDebug)<< "Finder Track being used " << endl;
01334           }
01335           recolist.Add(track);
01336         }
01337       }
01338       else {
01339         MSG("EventSR", Msg::kError)
01340           << "Track doesn't contain a slice.  Not added to recolist."
01341           << endl;
01342       }
01343     }
01344   }
01345 }
01346 
01347 //_________________________________________________________________________
01348 // compare pre-existing tracks in object list with  new track, 
01349 // and return false if they are inconsistent with being in the
01350 // same event.  Since these tracks are tentatively determined to be
01351 // from the same event, loosen requirements by factor of 3. 
01352 Bool_t AlgEventSRList::MatchOtherTracksInEvent(AlgConfig &ac, const VldContext * vldcptr, 
01353                                                CandTrackHandle * track, TObjArray * objectlist){
01354 
01355   Double_t pTrkTrkDtpos2 = ac.GetDouble("TrkTrkDtpos2")*9;
01356   Double_t pTrkTrkDz = ac.GetDouble("TrkTrkDz")*3;
01357   Double_t pTrkTrkDt = ac.GetDouble("TrkTrkDt");
01358   for (Int_t ireco2=0; ireco2<=objectlist->GetLast();
01359        ireco2++) {
01360     if (objectlist->At(ireco2)->InheritsFrom("CandTrackHandle")) {
01361       CandTrackHandle *othertrack = dynamic_cast<CandTrackHandle*>
01362         (objectlist->At(ireco2));
01363       if( !track->BelongsWithTrack(othertrack, 
01364                                    ac, 
01365                                    vldcptr, 
01366                                    pTrkTrkDtpos2,pTrkTrkDz,pTrkTrkDt))return false;
01367     } 
01368   }
01369   return true;
01370 }
01371 
01372 //_______________________________________________________________
01373 void  AlgEventSRList::AddObjectToEvent(CandRecoHandle * reco, TObjArray *objectlist, 
01374                                        TObjArray * prevlist, Bool_t merge ){
01375   if (!merge) {
01376     // if this is the first match we have found for this object, 
01377     //add object to list
01378     // and point prevlist to this object list
01379     objectlist->Add(reco);
01380     MSG("EventSR",Msg::kVerbose) << "    adding to list\n";
01381   }
01382   else {                  
01383     MSG("EventSR",Msg::kVerbose) << "    combining lists\n";
01384     // this object matches more than one event - merge their member
01385     // objects to list prevlist, and add the new object
01386     for (Int_t ireco2=0; ireco2<=objectlist->GetLast();ireco2++)
01387       prevlist->Add(objectlist->At(ireco2));
01388     prevlist->Add(reco);
01389     objectlist->Clear();
01390   }
01391 }
01392 
01393 //____________________________________________________________
01394 // for events with only showers, merge all showers
01395 
01396 void AlgEventSRList::MergeShowers( CandContext &cxx, TObjArray & eventlist, 
01397                                    AlgConfig &ac,
01398                                    CandSliceHandle * slice,
01399                                    CandClusterListHandle * clusterlist, 
01400                                    CandShowerListHandle * showerlist){
01401   
01402   
01403   const char *pEventAlgConfig = 0;
01404   ac.Get("EventAlgConfig",pEventAlgConfig);
01405 
01406   for (Int_t i=0; i<=eventlist.GetLast(); i++) {
01407     TObjArray *objectlist = dynamic_cast<TObjArray*>(eventlist.At(i));
01408     if(objectlist->GetLast()<=0)break;
01409     Bool_t foundtrack=false;
01410     for (Int_t i=0; i<=objectlist->GetLast(); i++) {
01411       if (!(objectlist->At(i)->InheritsFrom("CandShowerHandle"))) {
01412         foundtrack=true;
01413         break;
01414       }
01415     }
01416     if(foundtrack)break;
01417     MSG("EventSR",Msg::kDebug) << "  merging showers\n";
01418     
01419     // if we are here, we have an event with multiple showers and no tracks, so we merge into single shower.
01420     
01421     // Get singleton instance of AlgFactory
01422     AlgFactory &af = AlgFactory::GetInstance();
01423     
01424     // construct total U/V cluster daughter list
01425     TObjArray ustriparray;
01426     TObjArray vstriparray;
01427     for (Int_t i=0; i<=objectlist->GetLast(); i++) {
01428       CandShowerHandle * shower = dynamic_cast<CandShowerHandle *>(objectlist->At(i));
01429       TIter stripItr(shower->GetDaughterIterator());
01430       while (CandStripHandle *strip =
01431              dynamic_cast<CandStripHandle*>(stripItr())) {
01432         if(strip->GetPlaneView()==PlaneView::kU)ustriparray.Add(strip);
01433         if(strip->GetPlaneView()==PlaneView::kV)vstriparray.Add(strip);
01434       }
01435     }
01436     
01437     // make U cluster
01438     cxx.SetDataIn(&ustriparray);
01439     AlgHandle clusterah = af.GetAlgHandle("AlgClusterSR","default");
01440     CandClusterHandle uclusterhandle =
01441       CandCluster::MakeCandidate(clusterah,cxx);
01442     uclusterhandle.SetCandSlice(slice);
01443     uclusterhandle.IsShowerLike(1);
01444     
01445     // make V cluster
01446     cxx.SetDataIn(&vstriparray);
01447     CandClusterHandle vclusterhandle =
01448       CandCluster::MakeCandidate(clusterah,cxx);
01449     vclusterhandle.SetCandSlice(slice);
01450     vclusterhandle.IsShowerLike(1);
01451     
01452     // add new clusters to cluster list
01453     clusterlist->AddDaughterLink(uclusterhandle);
01454     clusterlist->AddDaughterLink(vclusterhandle);
01455     
01456     // build shower
01457     TObjArray newshower;
01458     CandHandle *ucluster =
01459       clusterlist->FindDaughter(&uclusterhandle);
01460     CandHandle *vcluster =
01461       clusterlist->FindDaughter(&vclusterhandle);
01462     newshower.Add(ucluster);
01463     newshower.Add(vcluster);
01464     cxx.SetDataIn(&newshower);
01465 
01466     AlgHandle showerah = af.GetAlgHandle("AlgShowerSR",pEventAlgConfig);
01467     CandShowerHandle showerhandle =
01468       CandShower::MakeCandidate(showerah,cxx);
01469     showerhandle.SetCandSlice(slice);
01470     showerlist->AddDaughterLink(showerhandle);
01471     // need to clean up shower list
01472     for (Int_t i=0; i<=objectlist->GetLast(); i++) {
01473       CandShowerHandle * shower = dynamic_cast<CandShowerHandle *>(objectlist->At(i));
01474       TIter shiter(showerlist->GetDaughterIterator());
01475       CandShowerHandle *oldshower;
01476       Bool_t found=false;
01477       while (!found &&
01478              (oldshower = dynamic_cast<CandShowerHandle*>(shiter()))) {
01479         if (shower->IsEqual(oldshower)) {
01480           found=true;
01481           showerlist->RemoveDaughter(oldshower);
01482         }
01483       }  
01484     }    
01485     CandShowerHandleItr showerItr(showerlist->GetDaughterIterator());
01486     while (CandShowerHandle *shower =
01487            dynamic_cast<CandShowerHandle*>(showerItr())){
01488       MSG("EventSR",Msg::kDebug) << " new shower " << shower << " " << shower->GetVldContext() << endl;
01489     }
01490     // reset object list to contain new shower
01491     objectlist->Clear();
01492     CandShowerHandle * shower = dynamic_cast<CandShowerHandle *>(showerlist->FindDaughter(&showerhandle));
01493     assert (shower);
01494     objectlist->Add(shower);
01495   }
01496 }
01497 
01498 
01499 //__________________________________________________________________________
01500 // fill TOjArray with strips not in any object daughter list in this snarl
01501 void AlgEventSRList::FindUnassociated(AlgConfig& ac, CandSliceHandleItr & sliceItr, CandEventHandleItr *eventItr, TObjArray & unassociated){
01502   
01503   Double_t pMinUnassocStripPE = ac.GetDouble("MinUnassocStripPE");
01504 
01505   while (CandSliceHandle *slice =
01506          dynamic_cast<CandSliceHandle*>(sliceItr())) {
01507     TIter stripItr(slice->GetDaughterIterator());
01508     while (CandStripHandle *strip =
01509            dynamic_cast<CandStripHandle*>(stripItr())) {
01510 
01511       if (strip->GetCharge(CalDigitType::kPE)<pMinUnassocStripPE) continue;
01512       Bool_t found=false;
01513       // check for duplicates
01514       
01515       for (Int_t i=0; i<=unassociated.GetLast() && !found; i++) {
01516         CandStripHandle *strip0 =
01517           dynamic_cast<CandStripHandle*>(unassociated.At(i));
01518         if (*strip == *strip0) {
01519           found = true;
01520           break;
01521         }
01522       }
01523       // if this strip not already in unnassociated list, then
01524       // loop over objects in this slice, and check against all daughter strips
01525       if (!found) {
01526         if (eventItr) {
01527           eventItr->Reset();
01528           while (CandEventHandle *event =
01529                  dynamic_cast<CandEventHandle*>((*eventItr)())) {
01530             if (event->GetCandSlice()) {
01531               if (slice->IsCloneOf(*(event->GetCandSlice()))) {
01532                 if (event->FindDaughter(strip)) {
01533                   found = true;
01534                   break;
01535                 }
01536               }
01537             }
01538           }
01539         }
01540       }
01541       // this strip is not in any event, add to unassociated list
01542       if (!found) {
01543         unassociated.Add(strip);
01544       }
01545     }
01546   }
01547 }
01548 
01549 //__________________________________________________________________________
01550 // fill TOjArray with strips not in any object daughter list in this snarl
01551 void AlgEventSRList::FindUnassociated(AlgConfig& ac, CandSliceHandleItr & sliceItr, CandShowerHandleItr * showerItr, CandTrackHandleItr* trackItr, TObjArray & unassociated){
01552 
01553   Double_t pMinUnassocStripPE = ac.GetDouble("MinUnassocStripPE");
01554 
01555   while (CandSliceHandle *slice =
01556          dynamic_cast<CandSliceHandle*>(sliceItr())) {
01557     TIter stripItr(slice->GetDaughterIterator());
01558     while (CandStripHandle *strip =
01559            dynamic_cast<CandStripHandle*>(stripItr())) {
01560 
01561       if (strip->GetCharge(CalDigitType::kPE)<pMinUnassocStripPE) continue;
01562       Bool_t found=false;
01563       // check for duplicates
01564       
01565       for (Int_t i=0; i<=unassociated.GetLast() && !found; i++) {
01566         CandStripHandle *strip0 =
01567           dynamic_cast<CandStripHandle*>(unassociated.At(i));
01568         if (*strip == *strip0) {
01569           found = true;
01570           break;
01571         }
01572       }
01573       // if this strip not already in unnassociated list, then
01574       // loop over objects in this slice, and check against all daughter strips
01575       if (!found) {
01576         if (showerItr) {
01577           showerItr->Reset();
01578           while (CandShowerHandle *shower =
01579                  dynamic_cast<CandShowerHandle*>((*showerItr)())) {
01580             if (shower->GetCandSlice()) {
01581               if (slice->IsCloneOf(*(shower->GetCandSlice()))) {
01582                 if (shower->FindDaughter(strip)) {
01583                   found = true;
01584                   break;
01585                 }
01586               }
01587             }
01588           }
01589         }
01590         if (trackItr && !found) {
01591           trackItr->Reset();
01592           while (CandTrackHandle *track =
01593                  dynamic_cast<CandTrackHandle*>((*trackItr)())) {
01594             if (track->GetCandSlice()) {
01595               if (slice->IsCloneOf(*(track->GetCandSlice()))) {
01596                 if (track->FindDaughter(strip)) {
01597                   found = true;
01598                   break;
01599                 }
01600               }
01601             }
01602           }
01603         }
01604       }
01605       // this strip is not in any event, add to unassociated list
01606       if (!found) {
01607         unassociated.Add(strip);
01608       }
01609     }
01610   }
01611 }
01612 
01613 //____________________________________________________________________
01614 
01615 void AlgEventSRList::FillDist2Map(AlgConfig & ac, TObjArray & unassociated,CandHandle & ch,vector<map<const CandEventHandle*, Double_t> > & dist2map){
01616   // grab all needed algorithm parameters  
01617   
01618   Double_t pShwTrkDz = ac.GetDouble("ShwTrkDz");
01619   Double_t pHitAssocDTime0 = ac.GetDouble("HitAssocDTime0");
01620   Double_t pHitAssocDTime1 = ac.GetDouble("HitAssocDTime1");
01621   Double_t pHitAssocZParm = ac.GetDouble("HitAssocZParm");
01622   Double_t pHitAssocPParm = ac.GetDouble("HitAssocPParm");
01623   Double_t pHitAssocTParm = ac.GetDouble("HitAssocTParm");
01624 
01625   // construct the map, first looping over strips
01626   for (Int_t i=0; i<=unassociated.GetLast(); i++) {
01627     CandStripHandle *strip =
01628       dynamic_cast<CandStripHandle*>(unassociated.At(i));
01629     TIter eventItr(ch.GetDaughterIterator());
01630     // inner loop is over events
01631     while (CandEventHandle *event =
01632            dynamic_cast<CandEventHandle*>(eventItr())) {
01633       
01634       // calculate separation in space/time
01635       Double_t dtime = (strip->GetBegTime()-event->GetVtxT());
01636       Double_t bestdist2=-1.;
01637       Double_t bestdplane=-1;
01638       Double_t bestdtpos=-1;
01639       Double_t bestdtime=-1;
01640       dist2map[i][event] = 999999999.;
01641       MSG("EventSR",Msg::kVerbose) << i << " " 
01642         << strip->GetPlane() << " " << strip->GetStrip() << " dtime " << dtime*1e9 << "/" << pHitAssocDTime0*1e9 << "/" << pHitAssocDTime1*1e9 << endl;  
01643       // if there is a rough time match proceed
01644       if (dtime>pHitAssocDTime0 && dtime<pHitAssocDTime1) {
01645 
01646         Float_t vertexsep = 0;
01647         // If  event has both shower
01648         // and track calc separation between the two.  If this 
01649         // separation is greater
01650         // than pSHwTrkDz, we won't bother adding the strip to the
01651         // primary shower, and will instead consider whether
01652         // to create a new shower at track vertex.
01653         if (event->GetPrimaryShower() && event->GetPrimaryTrack())
01654           vertexsep = fabs(event->GetPrimaryShower()->GetVtxZ() -
01655                           event->GetPrimaryTrack()->GetVtxZ());
01656 
01657         // the event has a shower, and either no track, or track and
01658         // shower vertices are in agreement.  In this case, we
01659         // consider adding this strip to this shower, so calc separation.
01660         if (event->GetPrimaryShower() && 
01661                (!event->GetPrimaryTrack() || vertexsep<pShwTrkDz)) {
01662 
01663           // create iterator of shower daughter strips in same view
01664           // as unassoc strip
01665           CandStripHandleItr shwstripItr(
01666                       event->GetPrimaryShower()->GetDaughterIterator());
01667           CandStripHandleKeyFunc *shwstripKf =
01668                                             shwstripItr.CreateKeyFunc();
01669           shwstripKf->SetFun(CandStripHandle::KeyFromView);
01670           shwstripItr.GetSet()->AdoptSortKeyFunc(shwstripKf);
01671           shwstripKf = 0;
01672           shwstripItr.GetSet()->Slice();
01673           shwstripItr.GetSet()->Slice(strip->GetPlaneView(),
01674                                       strip->GetPlaneView());
01675 
01676           // iterate over the daughter list, and find minimum distane
01677           // between daughter and unassoc strip
01678           while (CandStripHandle *shwstrip =
01679                         dynamic_cast<CandStripHandle*>(shwstripItr())) {
01680             Double_t dplane =
01681                      (Double_t)(strip->GetPlane()-shwstrip->GetPlane());
01682             Double_t dtpos = strip->GetTPos()-shwstrip->GetTPos();
01683             Double_t dist2 = (pHitAssocZParm*dplane*dplane) +
01684                              (pHitAssocPParm*dtpos*dtpos) +
01685                              (pHitAssocTParm*dtime*dtime);
01686             if (bestdist2<0. || dist2<bestdist2) {
01687               bestdist2 = dist2;
01688               bestdplane=dplane;
01689               bestdtpos=dtpos;
01690               bestdtime=dtime;
01691             }
01692           }
01693       MSG("EventSR",Msg::kVerbose)
01694             << "primary shower." << " dplane:" << bestdplane <<" dtpos:"
01695                        << bestdtpos <<" dtime:" << bestdtime <<" dist2:"
01696             << bestdist2<< "\n";
01697           dist2map[i][event] = bestdist2;
01698         } // end if event has shower, etc.
01699         // else if criteria above was not satisfied, consider whether
01700         // strip is near track vertex, in which case we start new shower
01701         else if (event->GetPrimaryTrack()) {
01702 
01703           // calc distance to vertex
01704           Double_t dplane =
01705                  (Double_t)(strip->GetPlane()-event->GetPrimaryTrack()->
01706                                                          GetBegPlane());
01707           Double_t dtpos=0;
01708           switch (strip->GetPlaneView()) {
01709           case PlaneView::kU:
01710             dtpos=strip->GetTPos()-event->GetPrimaryTrack()->
01711               GetU(event->GetPrimaryTrack()->GetBegPlane());
01712             break;
01713           case PlaneView::kV:
01714             dtpos=strip->GetTPos()-event->GetPrimaryTrack()->
01715               GetV(event->GetPrimaryTrack()->GetBegPlane());
01716             break;
01717           default:
01718             break;
01719           }
01720           Double_t dist2 = (pHitAssocZParm*dplane*dplane) +
01721             (pHitAssocPParm*dtpos*dtpos) +
01722             (pHitAssocTParm*dtime*dtime);
01723           dist2map[i][event] = dist2;
01724           MSG("EventSR",Msg::kVerbose)
01725             << "primary track. begin:" << " dplane:" << dplane
01726             << " dtpos:" << dtpos <<" dtime:" << dtime <<" dist2:"
01727             << dist2 << "\n";
01728         } // end if primary track
01729       }  // end if time match OK
01730     }  // end loop over events
01731   }  // end loop over unassoc strips
01732 }
01733 
01734 //______________________________________________________________________
01735 void AlgEventSRList::Trace(const char * /* c */) const
01736 {
01737 }

Generated on Mon Feb 15 11:06:17 2010 for loon by  doxygen 1.3.9.1