Print

Print


Commit in lcsim/src/org/lcsim/contrib/SteveMagill on MAIN
TrackShowerClusterDriver.java+434added 1.1


lcsim/src/org/lcsim/contrib/SteveMagill
TrackShowerClusterDriver.java added at 1.1
diff -N TrackShowerClusterDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ TrackShowerClusterDriver.java	23 Apr 2007 20:08:53 -0000	1.1
@@ -0,0 +1,434 @@
+package org.lcsim.contrib.SteveMagill;
+
+//  This driver extrapolates tracks into CAL, associating clusters to the tracks, testing E/p
+//  output : modified hit map and track cal clusters
+
+import java.util.*;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Track;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.util.swim.*;
+import org.lcsim.util.lcio.LCIOConstants;
+import org.lcsim.recon.cluster.util.*;
+import org.lcsim.util.aida.*;
+import org.lcsim.geometry.*;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.BasicHep3Vector;
+import org.lcsim.geometry.subdetector.CylindricalCalorimeter;
+import org.lcsim.recon.ztracking.cheater.*;
+import org.lcsim.mc.fast.tracking.*;
+import hep.aida.*;
+import org.lcsim.spacegeom.*;
+import org.lcsim.geometry.util.CalorimeterIDDecoder;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.base.MCReconstructedParticle;
+
+public class TrackShowerClusterDriver extends Driver
+{
+   ITree tree;
+   IHistogramFactory histogramFactory;
+   IAnalysisFactory analysisFactory = IAnalysisFactory.create();
+   private AIDA aida = AIDA.defaultInstance();
+   private boolean _initialized = false;
+//    The number of layers in the EM Calorimeter Barrel, Endcap
+   private int _numbemlayers;
+   private int _numecemlayers;
+//    The number of layers in the Hadronic Calorimeter Barrel, Endcap
+   private  int _numbhadlayers;
+   private int _numechadlayers;
+//    The EM calorimeter hits, by layer in barrel, endcap
+   private List[] _emBLayerHits;
+   private List[] _emECLayerHits;
+//    The HAD calorimeter hits, by layer in barrel, endcap
+   private List[] _hadBLayerHits;
+   private List[] _hadECLayerHits;
+//    The radii of the barrel calorimeter layers
+   private double[] _emBRadii;
+   private double[] _hadBRadii;
+   private double[] BRadii = new double[100];
+   private double[] ECZs = new double[100];
+//    modified Barrel helix swimmer for org.lcsim test
+//   private Helix[] _emBSwimmers; //EM
+//   private Helix[] _hadBSwimmers; //HAD
+//   Z extent of the central barrel calorimeters.
+   private double _embZ; //EM Barrel Z
+   private double[] _emecZ; //EM Endcap Z
+   private double _hadbZ; //HAD barrel z
+   private double[] _hadecZ; // HAD endcap z
+//   The central magnetic field strength
+   private double[] _fieldStrength;
+   private double _dminE;
+   private double _dminH;
+   private double _dminTrC;
+   private String[] _clusternames;
+//   private String[] _hitmapnames;
+   
+   public TrackShowerClusterDriver()
+   {
+       //  add arguments if needed
+   }
+   
+    protected void process(EventHeader event)
+    {
+        super.process(event);  // executes all added drivers
+        
+        boolean mcfltr = true;
+//        mcfltr = (Boolean)event.get("MCFilt");
+//        System.out.println("MCFilt is " +mcfltr);
+        if (mcfltr)
+        {
+        
+//      Initialize things here
+        if(!_initialized)
+        {
+            // setup specific detector stuff here
+            Detector det = event.getDetector();
+            double[] zero = {0, 0, 0};
+            _fieldStrength = det.getFieldMap().getField(zero);
+//            Hep3Vector h3zero = new BasicHep3Vector(zero);
+//            Hep3Vector field = det.getFieldMap().getField(h3zero);
+//            System.out.println("B Field " +_fieldStrength[2]+ " Tesla");
+            
+            //  Setup layer counts and distances for barrel, endcap
+            CylindricalCalorimeter emb = ((CylindricalCalorimeter) det.getSubdetectors().get("EMBarrel"));
+            _embZ = emb.getZMin();
+            _numbemlayers = emb.getLayering().getLayerCount();
+//            System.out.println("EM Barrel Layers " +_numbemlayers);
+            for (int i=0; i<_numbemlayers; ++i)
+            {
+                BRadii[i]=emb.getLayering().getDistanceToLayerSensorMid(i);
+//                System.out.println("EM Barrel Layer Number " +i+ " EM Barrel Radius " +_emBRadii[i]);
+            }
+            
+            CylindricalCalorimeter emec = ((CylindricalCalorimeter) det.getSubdetectors().get("EMEndcap"));
+            _numecemlayers = emec.getLayering().getLayerCount();
+//            System.out.println("EM EC Layers " +_numecemlayers);
+            for (int i=0; i<_numecemlayers; ++i)
+            {
+                ECZs[i] = emec.getLayering().getDistanceToLayerSensorMid(i);
+//                System.out.println("EM Endcap Layer Number " +i+ " EM Endcap Z " +_emecZ[i]);
+            }
+
+            CylindricalCalorimeter hadb = ((CylindricalCalorimeter) det.getSubdetectors().get("HADBarrel"));       
+            _hadbZ = hadb.getZMin();
+            _numbhadlayers = hadb.getLayering().getLayerCount();
+//            System.out.println("HAD Barrel Layers " +_numbhadlayers);   
+            for (int i=0; i<_numbhadlayers; ++i)
+            {
+                BRadii[i+_numbemlayers]=hadb.getLayering().getDistanceToLayerSensorMid(i);
+//                System.out.println("HAD Barrel Layer Number " +i+ " HAD Barrel Radius " +_hadBRadii[i]);
+            }
+            
+            CylindricalCalorimeter hadec = ((CylindricalCalorimeter) det.getSubdetectors().get("HADEndcap"));       
+            _numechadlayers = hadec.getLayering().getLayerCount();
+//            System.out.println("HAD Endcap Layers " +_numechadlayers); 
+            for (int i=0; i<_numechadlayers; ++i)
+            {
+                ECZs[i+_numecemlayers] = hadec.getLayering().getDistanceToLayerSensorMid(i);
+//                System.out.println("HAD Endcap Layer Number " +i+ " HAD Endcap Z " +_hadecZ[i]);
+            }
+        
+            _initialized = true;
+        }  // end of initialization section
+        
+        //  combine all clusters into a single shower cluster list
+        List<BasicCluster> showclus = new ArrayList<BasicCluster>();       
+        for (int i=0; i<_clusternames.length; i++)
+        {
+            try
+            {
+                List<BasicCluster> clus = event.get(BasicCluster.class,_clusternames[i]);
+                for (BasicCluster cl : clus)
+                {
+                    BasicCluster shclus = new BasicCluster();
+                    if (cl.getSize()>0) 
+                    {
+                        shclus.addCluster(cl);
+                        showclus.add(shclus);
+                    }
+                }
+            }     
+            catch(java.lang.IllegalArgumentException ex)
+            {
+                System.out.println("requested object not found in event " + _clusternames[i]);      
+            }
+        }
+//        System.out.println("Number Shower Clusters before Matching " + showclus.size());
+        
+        //  create a list of track-cal associated clusters for display
+        List<BasicCluster> trkcalclus = new ArrayList<BasicCluster>();
+        // Loop over tracks in event, extrapolate to layers and match hits if mips
+//        List<PerfectTrack> evtracks = event.get(PerfectTrack.class, "PerfectTracks");
+        // Get maps linking IL and mip clusters to tracks
+        Map<PerfectTrack, BasicCluster> trmipmap = (Map<PerfectTrack, BasicCluster>) event.get("TrackMipMap");
+        Map<BasicCluster, Integer> clusilmap = (Map<BasicCluster, Integer>) event.get("MipClusILMap");
+        double TotTrP = 0;
+        for (PerfectTrack itr : trmipmap.keySet())
+        {
+            double TrClE = 0;
+            BasicCluster trclus = new BasicCluster();
+            int niter = 0;
+            //  get track and associated mip cluster
+//            if (trmipmap.isEmpty()) break;
+//            PerfectTrack itr = trmipmap.keySet().iterator().next();
+            BasicCluster trmclus = trmipmap.get(itr);
+            trclus.addCluster(trmclus);
+            TrClE += trmclus.getEnergy();
+            Integer ClIL = clusilmap.get(trmclus);
+//            System.out.println("InteractionLayer for track " + ClIL);
+            double[] trmpos = trmclus.getPosition();
+            Hep3Vector mclpos = new BasicHep3Vector(trmpos);
+            double trpt = Math.sqrt(itr.getPX()*itr.getPX()+itr.getPY()*itr.getPY());
+            double[] trp = itr.getMomentum();
+            Hep3Vector trp3 = new BasicHep3Vector(trp);
+            Hep3Vector tror3 = itr.getOrigin();
+            int trq = itr.getCharge();
+//            System.out.println("Track Charge " + trq + " Track P " + trp3 + " Origin " + tror3);
+            double TrP = Math.sqrt(itr.getPX()*itr.getPX()+itr.getPY()*itr.getPY()+itr.getPZ()*itr.getPZ());
+            TotTrP += TrP;
+            HelixSwimmer tswim = new HelixSwimmer(_fieldStrength[2]);
+            // swim track to cluster position, arguments are momentum, origin, and charge
+            tswim.setTrack(trp3, tror3, trq);
+            double tobrad = tswim.getDistanceToRadius(BRadii[ClIL]);
+            double toecz = tswim.getDistanceToZ(ECZs[ClIL]);
+            double trtheta = 0;
+            double trphi = 0;
+            double ctrth = 0;
+            double ctrph = 0;
+            if (tobrad<toecz) // in barrel
+            {
+                SpacePoint trSP = tswim.getPointAtDistance(tobrad);
+                
+                trtheta += trSP.theta();
+                trphi += trSP.phi();
+                ctrth += Math.atan(trSP.rxy()/trSP.z());
+                if (ctrth<0) ctrth+=Math.PI;
+                ctrph += Math.atan2(trSP.y(),trSP.x());
+                if (ctrph<0) ctrph+=2*Math.PI;
+//                aida.cloud1D("Theta of Track at IL B").fill(trtheta);
+                aida.cloud1D("Theta of Track c at IL B").fill(ctrth); // this is correct value
+                double clr = Math.sqrt(trmpos[0]*trmpos[0]+trmpos[1]*trmpos[1]);
+                double clth = Math.atan(clr/trmpos[2]);
+                if (clth<0) clth+=Math.PI;
+                double clph = Math.atan2(trmpos[1],trmpos[0]);
+                if (clph<0) clph+=2*Math.PI;
+                aida.cloud1D("Theta of mip cluster c at clus B").fill(Math.atan(clr/trmpos[2]));
+                aida.cloud1D("Phi of Track at IL B").fill(trphi);
+                aida.cloud1D("Phi of Track c at IL B").fill(ctrph);
+                aida.cloud1D("Phi of mip cluster c at clus B").fill(Math.atan2(trmpos[1],trmpos[0]));
+                aida.cloud2D("Theta vs Phi of Track at IL B").fill(ctrph,ctrth);
+                aida.cloud2D("Theta vs Phi of mip cluster at IL B").fill(clph,clth);
+            } else  // in endcap
+            {
+                SpacePoint trSP = tswim.getPointAtDistance(toecz);
+                trtheta += trSP.theta();
+                trphi += trSP.phi();
+                ctrth += Math.atan(trSP.rxy()/trSP.z());
+                if (ctrth<0) ctrth+=Math.PI;
+                ctrph += Math.atan2(trSP.y(),trSP.x());
+                if (ctrph<0) ctrph+=2*Math.PI;
+                aida.cloud1D("Theta of Track c at IL EC").fill(ctrth);
+                double clr = Math.sqrt(trmpos[0]*trmpos[0]+trmpos[1]*trmpos[1]);
+                double clth = Math.atan(clr/trmpos[2]);
+                if (clth<0) clth+=Math.PI;
+                double clph = Math.atan2(trmpos[1],trmpos[0]);
+                if (clph<0) clph+=2*Math.PI;
+                aida.cloud1D("Theta of mip cluster c at clus EC").fill(Math.atan(clr/trmpos[2]));
+                aida.cloud1D("Phi of Track at IL EC").fill(trphi);
+                aida.cloud1D("Phi of Track c at IL EC").fill(ctrph);
+                aida.cloud1D("Phi of mip cluster c at clus EC").fill(Math.atan2(trmpos[1],trmpos[0]));
+                aida.cloud2D("Theta vs Phi of Track at IL EC").fill(ctrph,ctrth);
+                aida.cloud2D("Theta vs Phi of mip cluster at IL EC").fill(clph,clth);
+            }
+            aida.cloud2D("TrackMip Theta vs Phi Extrap").fill(trphi,trtheta);
+            // preselection of clusters near this track - first make a list of clusters that
+            // are candidates to be associated with this track
+            List<BasicCluster> candshclus = new ArrayList<BasicCluster>();
+            for (BasicCluster ibcl : showclus)
+            {
+                double[] ccpos = ibcl.getPosition();
+                double ccph = Math.atan2(ccpos[1],ccpos[0]);
+                if (ccph<0) ccph+=2*Math.PI;
+                double ccr = Math.sqrt(ccpos[0]*ccpos[0]+ccpos[1]*ccpos[1]);
+                double ccth = Math.atan(ccr/ccpos[2]);
+                if (ccth<0) ccth+=Math.PI;
+                double dtrccth = Math.abs(ctrth-ccth);
+                double dtrccph = Math.abs(ctrph-ccph);
+                if (dtrccph>Math.PI) dtrccph = 2*Math.PI-dtrccph;
+                double distrcc = Math.sqrt(dtrccth*dtrccth+dtrccph*dtrccph);
+                if (distrcc<1.0)
+                {
+                    for (int i=0; i<ibcl.getCalorimeterHits().size(); i++)
+                    {
+                        aida.cloud1D("Distance Track Cluster in Shower Match hit wt").fill(distrcc);
+                    }
+                    aida.cloud1D("Distance Track Cluster in Shower Match cl wt").fill(distrcc);
+                    // add cluster to cands
+                    candshclus.add(ibcl);
+                }
+            }
+            aida.cloud1D("Number of Cand Clusters added to track").fill(candshclus.size());
+            event.put("CandidateShowerClusters",candshclus);
+            // check all 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.  If E/p jumps from below min 
+            // to greater than 1.5, break up cluster with NN and retry.
+            do {
+                niter++;
+                double showclE = 0;
+                for (Iterator<BasicCluster> shcl = showclus.iterator(); shcl.hasNext();)
+                {
+                    BasicCluster ishcl = shcl.next();
+                    List<CalorimeterHit> clhits = ishcl.getCalorimeterHits();
+                    // double cltheta = Math.abs(ishcl.getITheta());  
+                    // double clphi = Math.abs(ishcl.getIPhi());
+                    int nhmtch = 0;
+                    for (CalorimeterHit iclhit : clhits)
+                    {
+                        // 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;
+                        double dtrhth = Math.abs(ctrth-htth);
+                        double dtrhph = Math.abs(ctrph-htph);
+                        if (dtrhph>Math.PI) dtrhph = 2*Math.PI-dtrhph;
+                        double distrh = Math.sqrt(dtrhth*dtrhth+dtrhph*dtrhph);
+                        if (distrh<niter*0.0075) nhmtch++;
+                    }
+                    double[] clpos = ishcl.getPosition();
+                    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;
+                    aida.cloud1D("Calculated shower cluster phi").fill(cph);
+                    aida.cloud1D("Calculated shower cluster theta").fill(cth);
+                    aida.cloud2D("Theta vs Phi shower cluster").fill(cph,cth);
+                    double dthtrcl = Math.abs(cth-ctrth);
+                    double dphtrcl = Math.abs(cph-ctrph);
+                    if (dphtrcl>Math.PI) dphtrcl = 2*Math.PI-dphtrcl;
+                    aida.cloud1D("Track Shower Cluster dtheta").fill(dthtrcl);
+                    aida.cloud1D("Track Shower Cluster dphi").fill(dphtrcl);
+                    double dist = Math.sqrt(dthtrcl*dthtrcl+dphtrcl*dphtrcl);
+                    aida.cloud1D("Track Shower dist").fill(dist);
+                    aida.cloud1D("Number of hits matched to Track").fill(nhmtch);
+         //           if (dist < niter*0.015)
+                    if (nhmtch>5)
+                    {
+                        trclus.addCluster(ishcl);
+                        aida.cloud2D("Track Shower Match Cluster Theta Phi").fill(cph,cth);
+                        aida.cloud2D("Track Shower Match Track Theta Phi").fill(ctrph,ctrth);
+                        aida.cloud1D("Number of matched hits for matched CLusters").fill(nhmtch);
+                        // try changing theta, phi to average of trackcluster coord if matched
+                        showclE += ishcl.getEnergy();
+                        ctrph = (TrP*ctrph+showclE*cph)/(TrP+showclE);
+                        ctrth = (TrP*ctrth+showclE*cth)/(TrP+showclE);
+                        shcl.remove();
+//                        System.out.println("Cluster matched to track");
+                    }
+                }
+                TrClE += showclE;
+                if (TrClE>0) aida.cloud1D("E over P Track Shower matches").fill(TrClE/TrP);
+                if (niter == 6) break;
+            } while (TrClE/TrP<0.55);
+            if (TrClE>0) aida.cloud1D("Number of iterations for Track").fill(niter);
+            if (TrClE>0) aida.cloud1D("Final E over p Track Shower matches").fill(TrClE/TrP);
+            trkcalclus.add(trclus);
+        }
+        if (trkcalclus.size()>0) event.put("TrackCALClusters",trkcalclus);
+        //  simple check for neutrals - based on min hits in cluster
+        List<BasicCluster> neuclus = new ArrayList<BasicCluster>();
+        for (BasicCluster shc : showclus)
+        {
+            aida.cloud1D("Number of hits in NeuHClusters").fill(shc.getCalorimeterHits().size());
+            if (shc.getCalorimeterHits().size()>20) neuclus.add(shc);
+        }
+        if (neuclus.size()>0) event.put("NeuHClusters",neuclus);
+//        System.out.println("Number Shower Clusters after Matching " + showclus.size());
+        
+        //  make some plots
+        List<ReconstructedParticle> prepars = event.get(ReconstructedParticle.class,"PerfectRecoParticles");
+        double perfpho = 0;
+        double perfneu = 0;
+        double perfchpE = 0;
+        double perfchpP = 0;
+        for (ReconstructedParticle prepar : prepars)
+        {
+            double perfpCh = prepar.getCharge();
+//          ParticleID perfpID = perfrp.getParticleIDUsed();
+            int perfpID = Math.abs(prepar.getParticleIDUsed().getPDG());
+//          System.out.println("Particle ID = " + perfpID);
+            double perfpE = prepar.getEnergy();
+            Hep3Vector perfpP = prepar.getMomentum();
+            double pP = perfpP.magnitude();
+            if (perfpCh == 0)
+            {
+                if (perfpID == 22) 
+                {
+                    perfpho += perfpE;
+                }else
+                {
+                    perfneu += perfpE;
+                }
+            } else
+            {
+                perfchpE += perfpE;
+                perfchpP += pP;
+            }
+        }
+        List<MCReconstructedParticle> mcpars = event.get(MCReconstructedParticle.class,"CheatReconstructedParticles");
+        double trphoE = 0;
+        for (MCReconstructedParticle mcpar : mcpars)
+        {
+            int mcID = Math.abs(mcpar.getParticleIDUsed().getPDG());
+            double mcE = mcpar.getEnergy();
+            if (mcID == 22) trphoE += mcE;
+        }
+        double TotTrClE = 0;
+        for (BasicCluster trccl : trkcalclus)
+        {
+            TotTrClE += trccl.getEnergy();
+        }
+        aida.cloud1D("PFA Charged Hadron ESum").fill(TotTrClE);
+        aida.cloud1D("PFA Total Track PSum").fill(TotTrP);
+        double TotRemainE = 0;
+        for (BasicCluster nc : neuclus)
+        {
+            TotRemainE += nc.getEnergy()*1.3;
+        }
+        aida.cloud1D("Neutral Cluster ESum").fill(TotRemainE);
+        List<BasicCluster> phobcl = event.get(BasicCluster.class,"PhotonBClusters");
+        List<BasicCluster> phoeccl = event.get(BasicCluster.class,"PhotonECClusters");
+        double TotPhoE = 0;
+        for (BasicCluster phob : phobcl)
+        {
+            TotPhoE += phob.getEnergy()*1.015*1.013;
+        }
+        for (BasicCluster phoec : phoeccl)
+        {
+            TotPhoE += phoec.getEnergy()*1.015*1.013;
+        }
+        aida.cloud1D("PFA Photon ESum").fill(TotPhoE);
+        aida.cloud1D("PFA Track P + PhotonE").fill(TotTrP+TotPhoE);
+        double PFAESum = TotTrP+TotPhoE+TotRemainE;
+        aida.cloud1D("PFA TrP + PhoE + RemE").fill(TotTrP+TotPhoE+TotRemainE);
+        aida.cloud1D("Difference Perf Pho PFA Pho").fill(perfpho-TotPhoE);
+        aida.cloud1D("Difference True Pho Perf Pho").fill((trphoE-perfpho)/Math.sqrt(trphoE));
+        aida.cloud2D("TrPho PerfPho vs PerfPho PFAPho").fill(trphoE-perfpho,perfpho-TotPhoE);
+        aida.cloud1D("Difference Perf Neu PFA Neu").fill(perfneu-TotRemainE);
+        aida.cloud1D("Difference Perf PFA PFA").fill(perfpho+perfneu-TotPhoE-TotRemainE);
+        aida.cloud1D("Perf Pho Neu PFA Pho Neu").fill(perfpho+perfneu-TotPhoE-TotRemainE);
+        
+    }  // end of filter loop
+    }
+
+    public void setClusterNames(String[] names)
+    {
+        _clusternames = names;
+    }
+}
+
CVSspam 0.2.8