Print

Print


Commit in lcsim-contrib/src/main/java/org/lcsim/contrib/SteveMagill on MAIN
TrShowerDriver.java+435added 1.1

lcsim-contrib/src/main/java/org/lcsim/contrib/SteveMagill
TrShowerDriver.java added at 1.1
diff -N TrShowerDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ TrShowerDriver.java	14 Feb 2012 19:26:24 -0000	1.1
@@ -0,0 +1,435 @@
+  package org.lcsim.contrib.SteveMagill;
+
+//  Modified from TSCForDriver, this algorithm matches clusters to track extrapolations,
+//  iterating in distance from the extrapolated track, using E/p to limit the size
+//  of the cluster
+//  input : calorimeter clusters
+//  output : clusters associated to tracks
+
+import java.util.*;
+import org.lcsim.event.*;
+import org.lcsim.util.Driver;
+import org.lcsim.recon.cluster.util.*;
+import org.lcsim.util.aida.*;
+import hep.aida.*;
+import org.lcsim.spacegeom.*;
+
+public class TrShowerDriver extends Driver
+{
+   ITree tree;
+   IHistogramFactory histogramFactory;
+   IAnalysisFactory analysisFactory = IAnalysisFactory.create();
+   private AIDA aida = AIDA.defaultInstance();
+   private double _mindist;
+   private int _nloops;
+   private double _mineop;
+   private double _maxeop;
+   private double _hres;
+   private double _mintrp;
+   private String _inclusname;
+   private String _oclname;
+   private String _tmname;
+   private String _tcname;
+   private String _tilname;
+   private String _tispname;
+   private String _tiptname;
+   private String _tfcname;
+   private boolean trshdb = true;
+   
+   public TrShowerDriver(double mindist, int nloops, double hadres, double mintrp)
+   {
+       //  add arguments if needed
+       _mindist = mindist;  // minimum distance between objects to merge (track, clusters) (0.0185)
+       _nloops = nloops;  // number of iterations to merge clusters (until min E/p is met) (5)
+       _hres = hadres;  // stochastic term alpha for hadron showers (0.7 rpc, 0.5 scin)
+       _mintrp = mintrp;  // track momentum which determines minimum E/p value
+       //  note min E/p = 1.0-_hres/sqrt(mintrp)  this value is used for tracks with p<_mintrp
+   }
+   
+    protected void process(EventHeader event)
+    {
+        //  get list of cal clusters
+        List<BasicCluster> inclus = event.get(BasicCluster.class,_inclusname);
+        //  make copy to preserve original list
+        List<BasicCluster> copyclus = new ArrayList<BasicCluster>();
+        for (BasicCluster icl : inclus)
+        {
+            BasicCluster shclus = new BasicCluster();
+            if (icl.getSize()>0)
+            {
+                shclus.addCluster(icl);
+                copyclus.add(shclus);
+            }
+        }
+        //  create lists of track-cal associated clusters for display
+        List<BasicCluster> trkcalclus = new ArrayList<BasicCluster>();
+        List<BasicCluster> trkshoclus = new ArrayList<BasicCluster>();
+        List<BasicCluster> unmcalclus = new ArrayList<BasicCluster>();
+        
+        //  Make a map to link track and final cluster association
+        Map<Track, BasicCluster> trkclusmap = new HashMap<Track, BasicCluster>();
+        //  and a list of the tracks in the map
+        List<Track> trkcaltrack = new ArrayList<Track>();
+        
+        // Get maps linking IL and mip clusters to tracks, tracks linked to SpacePoints
+        Map<Track, BasicCluster> trmipmap = (Map<Track, BasicCluster>) event.get(_tmname);
+        Map<Track, BasicCluster> trcoremap = (Map<Track, BasicCluster>) event.get(_tcname);
+//        Map<BasicCluster, Integer> clusilmap = (Map<BasicCluster, Integer>) event.get("MipClusILMap");
+        Map<Track, SpacePoint> trilmap = (Map<Track, SpacePoint>) event.get(_tilname);
+        Map<Track, BasicCluster> trilspmap = (Map<Track, BasicCluster>) event.get(_tispname);
+        Map<Track, BasicCluster> triptrmap = (Map<Track, BasicCluster>) event.get(_tiptname);
+//        Map<Track, SpacePoint> trh0map = (Map<Track, SpacePoint>) event.get("TrackXH0Map");
+        
+        double TotTrP = 0;  // gets sum of all track momentum in event
+        int ntracks = 0;  // count tracks in event
+        int nmip = 0;
+        int ncore = 0;
+        int nilsp = 0;
+        int niptr = 0;
+        //  loop over all tracks from the mip map
+        for (Track itr : trmipmap.keySet())
+        {
+            boolean abort = false;
+            double TrClE = 0;
+            BasicCluster trclus = new BasicCluster();  // includes mips, cores, and showers
+            BasicCluster trshclus = new BasicCluster();  // just showers
+            int niter = 0;
+            ntracks++;
+
+            //  get some track properties
+            double TrP = Math.sqrt(itr.getPX()*itr.getPX()+itr.getPY()*itr.getPY()+itr.getPZ()*itr.getPZ());
+            TotTrP += TrP;
+            double Trpt = Math.sqrt(itr.getPX()*itr.getPX()+itr.getPY()*itr.getPY());
+            
+            //  define mineop and maxeop based on cal sigma and min track momentum
+            //  used 1.25 for mineop and 2.6 for maxeop originally
+            if (TrP<_mintrp)
+            {
+                _mineop = 1.0-(1.00*_hres/Math.sqrt(_mintrp));
+                _maxeop = 1.0+(2.6*_hres/Math.sqrt(_mintrp));
+                aida.cloud1D("sigma for eop").fill(_hres*Math.sqrt(_mintrp));
+            } else
+            {
+                _mineop = 1.0-(1.00*_hres/Math.sqrt(TrP));
+                _maxeop = 1.0+(2.6*_hres/Math.sqrt(TrP));
+                aida.cloud1D("sigma for eop").fill(_hres*Math.sqrt(TrP));
+            }
+            aida.cloud1D("Min and Max EoP").fill(_mineop);
+            aida.cloud1D("Min and Max EoP").fill(_maxeop);
+            
+            //  get associated mip cluster coordinates, add mip cluster to track cluster, from mip map
+            BasicCluster trmclus = trmipmap.get(itr);
+            trclus.addCluster(trmclus);  // add mip cluster hits to track cluster
+            if (trmclus.getSize()>0) nmip++;
+            double[] trmpos = trmclus.getPosition();
+            double trxym = Math.sqrt(trmpos[0]*trmpos[0]+trmpos[1]*trmpos[1]);
+            double mclth = Math.atan(trxym/trmpos[2]);
+            if (mclth<0) mclth+=Math.PI;
+            double mclph = Math.atan2(trmpos[1],trmpos[0]);
+            if (mclph<0) mclph+=2*Math.PI;
+            double trxyzm = Math.sqrt(trmpos[0]*trmpos[0]+trmpos[1]*trmpos[1]+trmpos[2]*trmpos[2]);
+            TrClE += trmclus.getEnergy();
+
+            //  get associated IL coordinates from IL map
+            SpacePoint trIL = trilmap.get(itr);
+            double trxyzil = trIL.rxyz();  // rxyz of track spacepoint at IL
+            double trtheta = trIL.theta();  // track theta at IL
+            double trphi = trIL.phi();  //  track phi at IL
+            double trilth = Math.atan(trIL.rxy()/trIL.z());
+            if (trilth<0) trilth+=Math.PI;
+            double trilph = Math.atan2(trIL.y(),trIL.x());
+            if (trilph<0) trilph+=2*Math.PI;
+
+            //  add core clusters and get coordinates of core
+            double trcclth = 0.;
+            double trcclph = 0.;
+            if (trcoremap.get(itr) != null)
+            {
+                BasicCluster coreclus = trcoremap.get(itr);
+//                if ((TrClE+coreclus.getEnergy())/TrP > _maxeop) abort = true;
+//                if (abort) continue;
+                trclus.addCluster(coreclus);  //  add no matter what test later
+                if (coreclus.getSize()>0)
+                {
+                    ncore++;
+                    double[] trcpos = coreclus.getPosition();
+                    double trcxym = Math.sqrt(trcpos[0]*trcpos[0]+trcpos[1]*trcpos[1]);
+                    trcclth = Math.atan(trcxym/trcpos[2]);
+                    if (trcclth<0) trcclth+=Math.PI;
+                    trcclph = Math.atan2(trcpos[1],trcpos[0]);
+                    if (trcclph<0) trcclph+=2*Math.PI;
+                    double trcxyzm = Math.sqrt(trcpos[0]*trcpos[0]+trcpos[1]*trcpos[1]+trcpos[2]*trcpos[2]);
+                    TrClE += coreclus.getEnergy();
+                }
+            }
+//            if (abort) continue;  //  go to next track if this is true
+
+            //  add ILSP clusters - don't need coord info for these
+            if (trilspmap.get(itr) != null)
+            {
+                BasicCluster ilspclus = trilspmap.get(itr);
+//                if ((TrClE+ilspclus.getEnergy())/TrP > _maxeop) abort = true;
+//                if (abort) continue;
+                trclus.addCluster(ilspclus);
+                if (ilspclus.getSize()>0)
+                {
+                    nilsp++;
+                    TrClE += ilspclus.getEnergy();
+                }
+            }
+//            if (abort) continue;
+
+            //  add IPTrack clusters - don't need coord info for these
+            if (triptrmap.get(itr) != null)
+            {
+                BasicCluster iptrclus = triptrmap.get(itr);
+//                if ((TrClE+iptrclus.getEnergy())/TrP > _maxeop) abort = true;
+//                if (abort) continue;
+                trclus.addCluster(iptrclus);
+                if (iptrclus.getSize()>0)
+                {
+                    niptr++;
+                    TrClE += iptrclus.getEnergy();
+                }
+            }
+//            if (abort) continue;
+
+            //  some histograms 
+            if (trshdb) 
+            {
+                aida.cloud1D("Theta of mip cluster c").fill(mclth);
+                aida.cloud1D("Theta of Track at IL").fill(trilth);
+                aida.cloud1D("Phi of Track at IL").fill(trilph);
+                aida.cloud1D("Phi of mip cluster c").fill(mclph);
+                aida.cloud2D("Theta vs Phi of Track at IL").fill(trilph,trilth);
+                aida.cloud2D("Theta vs Phi of mip cluster c").fill(mclph,mclth);
+                aida.cloud1D("E over P after adding Mip Core ILSP").fill(TrClE/TrP);
+            }            
+            
+            // check all remaining clusters for matches using spacepoint of extrapolated track and cluster coords
+            // for each cluster, loop over all hits in the cluster, checking if any hits are close to track
+            // if so, remove entire cluster from list according to E/p test.
+            do {
+                niter++;
+                double showclE = 0;  // sum of all cluster match energies
+                for (Iterator<BasicCluster> shcl = copyclus.iterator(); shcl.hasNext();)
+                {
+                    BasicCluster ishcl = shcl.next();
+                    //  first, check cluster rxyz and compare to trIL rxyz, only considering if
+                    //  cluster rxyz>trIL rxyz
+                    double[] clpos = ishcl.getPosition();
+                    double clrxyz = Math.sqrt(clpos[0]*clpos[0]+clpos[1]*clpos[1]+clpos[2]*clpos[2]);
+                    if (TrP>5. && trxyzil>clrxyz) continue;  // if cluster closer than mip endpoint, don't consider
+                    //  if this cluster makes E/p > _maxeop, then no point in considering it for match
+                    if ((TrClE+ishcl.getEnergy())/TrP > _maxeop) continue;
+                    
+                    // first, calculate distance of hits from track, mip, core
+                    List<CalorimeterHit> clhits = ishcl.getCalorimeterHits();
+                    int nhmtch = 0;
+                    int nhits = 0;
+                    for (CalorimeterHit iclhit : clhits)
+                    {
+                        nhits++;
+                        // check distance of hit from track - add up hits to match cluster
+                        double[] htpos = iclhit.getPosition();
+                        double htph = Math.atan2(htpos[1],htpos[0]);
+                        if (htph<0) htph+=2*Math.PI;
+                        double htr = Math.sqrt(htpos[0]*htpos[0]+htpos[1]*htpos[1]);
+                        double htth = Math.atan(htr/htpos[2]);
+                        if (htth<0) htth+=Math.PI;
+
+                        //  now calculate distances from ILSP
+                        double dist = 999.;
+                        double dccth = Math.abs(trilth-htth);
+                        double dccph = Math.abs(trilph-htph);
+                        if (dccph>Math.PI) dccph = 2*Math.PI-dccph;
+                        dist = Math.sqrt(dccth*dccth+dccph*dccph);
+                    
+                        //  if a core cluster was added, also check distances to it
+                        double distcore = 999.;
+                        if (ncore>0)
+                        {
+                            double dcccth = Math.abs(trcclth-htth);
+                            double dcccph = Math.abs(trcclph-htph);
+                            if (dcccph>Math.PI) dcccph = 2*Math.PI-dcccph;
+                            distcore = Math.sqrt(dcccth*dcccth+dcccph*dcccph);
+                        }
+                        //  take smallest distance to test
+                        double distt = 999.;
+                        if (dist<distcore) distt = dist;
+                        if (distcore<dist) distt = distcore;
+                        if (trshdb) aida.cloud1D("Distance of shower hit from track").fill(distt);                        
+                        if (distt<niter*_mindist) 
+                        {
+                            nhmtch++;
+                        }
+                    }
+                    double dnhits = nhits;
+                    double dnhmtch = nhmtch;
+                    double drat = 0.;
+                    if (nhits>0 && nhmtch>0) drat = dnhmtch/dnhits;
+                    
+                    //  now do the same for clusters, not hits
+                    int nclmtch = 0; 
+                    double cph = Math.atan2(clpos[1],clpos[0]);
+                    if (cph<0) cph+=2*Math.PI;
+                    double cshr = Math.sqrt(clpos[0]*clpos[0]+clpos[1]*clpos[1]);
+                    double cth = Math.atan(cshr/clpos[2]);
+                    if (cth<0) cth+=Math.PI;
+                    if (trshdb) aida.cloud1D("Calculated shower cluster phi").fill(cph);
+                    if (trshdb) aida.cloud1D("Calculated shower cluster theta").fill(cth);
+                    if (trshdb) aida.cloud2D("Theta vs Phi shower cluster").fill(cph,cth);
+                    
+                    //  now calculate distances same as for cores
+                    double dist = 999;
+                    double dccth = Math.abs(trilth-cth);
+                    double dccph = Math.abs(trilph-cph);
+                    if (dccph>Math.PI) dccph = 2*Math.PI-dccph;
+                    dist = Math.sqrt(dccth*dccth+dccph*dccph);
+                    
+                    //  if a core cluster was added, also check distance to it
+                    double distcore = 999.;
+                    if (ncore>0)
+                    {
+                        double dcccth = Math.abs(trcclth-cth);
+                        double dcccph = Math.abs(trcclph-cph);
+                        if (dcccph>Math.PI) dcccph = 2*Math.PI-dcccph;
+                        distcore = Math.sqrt(dcccth*dcccth+dcccph*dcccph);
+                    }
+                    //  take smallest distance to test
+                    double distt = 999.;
+                    if (dist<distcore) distt = dist;
+                    if (distcore<dist) distt = distcore;
+                    if (trshdb) aida.cloud1D("Distance of shower cluster from track").fill(distt);
+                    if (distt<niter*_mindist) 
+                    {
+                        nclmtch++;
+                    }
+
+                    if (nclmtch>0 || drat>0.30)  // its a match
+                    {
+                        trclus.addCluster(ishcl);
+                        trshclus.addCluster(ishcl);
+                        if (trshdb) aida.cloud2D("Track Shower Match Cluster Theta Phi").fill(cph,cth);
+                        if (trshdb) aida.cloud1D("Distance of matched shower cluster from track").fill(distt);
+                        if (trshdb) aida.cloud2D("Dist of matched ShCl from Tr vs P").fill(TrP,distt);
+                        showclE += ishcl.getEnergy();
+                        TrClE += ishcl.getEnergy();
+                        shcl.remove();
+//                        System.out.println("Cluster matched to track");
+                    }
+                }  //  loop over all clusters, adding up energy in this road
+                if (trshdb && TrClE>0) aida.cloud1D("E over P Track Shower matches").fill(TrClE/TrP);
+                if (trshdb && TrClE/TrP>_maxeop)
+                {
+                    aida.cloud1D("Number of hits in too large matched shower cluster").fill(trclus.getCalorimeterHits().size());
+                    aida.cloud1D("E over p for too large match").fill(TrClE/TrP);
+                }
+//                if (niter == _nloops) break;
+            } while (TrClE/TrP<_mineop && niter<_nloops);
+            if (TrClE>0) aida.cloud1D("Number of iterations per Track").fill(niter);
+            //  add shower clusters, make map, these numbers have been tuned for single pions
+            //  first look - use 0.86 - 1.16
+            if (TrClE/TrP>0.86 && TrClE/TrP<1.16)
+            {
+                trkcalclus.add(trclus);
+                if (trshclus.getSize()>0) trkshoclus.add(trshclus);
+                trkclusmap.put(itr, trclus);
+                trkcaltrack.add(itr);
+            } else
+            {
+                if (trclus.getSize()>0) unmcalclus.add(trclus);
+            }
+            if (TrClE>0 && trshdb) aida.cloud1D("Final E over p Track Shower matches").fill(TrClE/TrP);
+            if (TrClE>0 && trshdb && nmip==0) aida.cloud1D("Final EoP nomiphits").fill(TrClE/TrP);
+            if (TrClE>0 && trshdb) aida.cloud2D("Final E over p vs p TrShower").fill(TrP,TrClE/TrP);
+            if (TrClE>0 && trshdb) aida.cloud2D("Final E vs p of Track Cal Matches").fill(TrP,TrClE);
+            if (TrClE>TrP && trshdb) aida.cloud1D("Number sigmas E gt p").fill((TrClE-TrP)/(_hres*Math.sqrt(TrP)));
+            if (TrClE==0 && trshdb) aida.cloud1D("Track P for no match").fill(TrP);
+        }
+        if (trkcalclus.size()>0) event.put(_oclname,trkcalclus);
+        if (trkcalclus.size()>0) event.put("TrCalTracks",trkcaltrack);
+        if (trkshoclus.size()>0) event.put("TrackShowerClusters",trkshoclus);
+//        if (trkcalclus.size()>0) event.put(_tfcname,trkclusmap);
+        event.put(_tfcname,trkclusmap);  // write out even if no entries
+        event.put("UnAssocCalClusters",unmcalclus);
+//        List<Double> qqpT = event.get(Double.class, "DJpT");
+        aida.cloud1D("Number of Track Cluster Matches per Event").fill(trkcalclus.size());
+        double ntm = (double) trkcalclus.size();
+        double ntt = (double) ntracks;
+        double tmfrac = 0.;
+        if (ntt>0.) tmfrac = ntm/ntt;
+//        double jpT = 0.;
+//        for (Double qp : qqpT)
+//        {
+//            jpT = qp.doubleValue();
+//        }
+//        if (jpT>0.) aida.cloud2D("Num TrCAL Matches vs pT").fill(jpT, trkcalclus.size());
+//        if (jpT>0. && tmfrac>0.) aida.cloud2D("FracTrCAL Matches vs ET").fill(jpT,tmfrac);
+
+        if (copyclus.size()>0)
+        {
+            event.put("ShowerClustersLeft",copyclus);
+            aida.cloud1D("Number Clusters after TSC match").fill(copyclus.size());
+            int nchit = 0;
+            int nphit = 0;
+            int nnhit = 0;
+            for (BasicCluster shclus : copyclus)
+            {
+                List<CalorimeterHit> calhits = shclus.getCalorimeterHits();
+                for (CalorimeterHit calhit : calhits)
+                {
+                    SimCalorimeterHit mchit = (SimCalorimeterHit) calhit;
+                    double mch = Math.abs(mchit.getMCParticle(0).getCharge());
+                    double hitm = mchit.getMCParticle(0).getMass();
+                    if (shclus.getSize()>5)
+                    {
+                        if (mch>0) nchit++;
+                        if (mch==0 && hitm==0) nphit++;
+                        if (mch==0 && hitm>0) nnhit++;
+                    }
+                }
+            }
+            if (trshdb)
+            {
+                aida.cloud1D("Num ChHits in leftover showclus 5 hits").fill(nchit);
+                aida.cloud1D("Num PhoHits in leftover showclus 5 hits").fill(nphit);
+                aida.cloud1D("Num NHHits in leftover showclus 5 hits").fill(nnhit);
+            }
+        }
+    }
+
+    public void setInputClusterList(String inname)
+    {
+        _inclusname = inname;
+    }
+    public void setOutputClusterList(String outclname)
+    {
+        _oclname = outclname;
+    }
+    public void setTrackMipClusMap(String tmname)
+    {
+        _tmname = tmname;
+    }
+    public void setTrackILPosMap(String tilname)
+    {
+        _tilname = tilname;
+    }
+    public void setTrackCoreClusMap(String tcname)
+    {
+        _tcname = tcname;
+    }
+    public void setTrackILSPClusMap(String tispname)
+    {
+        _tispname = tispname;
+    }
+    public void setTrackIPTrClusMap(String tiptname)
+    {
+        _tiptname = tiptname;
+    }
+    public void setTrackCalClusMap(String tfcname)
+    {
+        _tfcname = tfcname;
+    }
+}
+
CVSspam 0.2.12


Use REPLY-ALL to reply to list

To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1