Print

Print


Commit in lcsim-contrib/src/main/java/org/lcsim/contrib/twhite on MAIN
MuonAnalysisTest.java+35added 1.1
MuonAnalysis.java+340added 1.1
+375
2 added files
First check in of muon analysis code. Thomas White

lcsim-contrib/src/main/java/org/lcsim/contrib/twhite
MuonAnalysisTest.java added at 1.1
diff -N MuonAnalysisTest.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ MuonAnalysisTest.java	12 Aug 2009 08:52:02 -0000	1.1
@@ -0,0 +1,35 @@
+package main.java.org.lcsim.contrib.twhite;
+/**
+ * @version $Id: MuonAnalysisTest.java,v 1.1 2009/08/12 08:52:02 twhite Exp $
+ * @author T White
+ */
+
+import junit.framework.TestCase;
+
+
+public class MuonAnalysisTest extends TestCase{
+	
+	MuonAnalysis muonanalysis2;
+	
+	 protected void setUp() throws Exception {
+	
+		muonanalysis2 = new MuonAnalysis();
+		
+	 }
+
+	 protected void tearDown() throws Exception {
+	        
+	 }
+	
+	 public void testgettype(){
+		 int returnedtype;
+		 int array[] = {13,13,-13,13,12,9912,-14,9912,-16,9912,2212,211,-321,211,211,211,2112,130,10000000,9999};
+		 for(int i=0;i<array.length;i=i+2){
+			 returnedtype = muonanalysis2.gettype(array[i]);
+		 assertEquals(array[i+1], returnedtype);
+		 }
+		
+	 }
+	 
+
+}

lcsim-contrib/src/main/java/org/lcsim/contrib/twhite
MuonAnalysis.java added at 1.1
diff -N MuonAnalysis.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ MuonAnalysis.java	12 Aug 2009 08:52:02 -0000	1.1
@@ -0,0 +1,340 @@
+package main.java.org.lcsim.contrib.twhite;
+/**
+ * @version $Id: MuonAnalysis.java,v 1.1 2009/08/12 08:52:02 twhite Exp $
+ * @author T White
+ */
+
+import hep.physics.particle.Particle;
+import hep.physics.vec.VecOp;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+import org.lcsim.util.lcio.LCIOWriter;
+
+public class MuonAnalysis extends Driver {
+	
+	//Size of histogram for number of particles in the event MC and RC
+	int numberparthist[] = {150,0,150};
+	//Size of histogram for number of missing particles in the event
+	int numberpartmissinghist[] = {70,-20,50};
+	//Size of histogram for energy of MC particles 
+	int energyhist[] = {500,0,500};
+	//Size of histogram for energy of missing particles
+	int energymissinghist[] = {75,0,75};
+	//Size of cos(angle) histogram
+	int anglehist[] = {200,-1,1};
+
+	String reconname = "ReconstructedParticles"; // Collection name from LCIO file
+	String mcparticlename = "MCParticle"; // Collection name from LCIO file
+
+	private AIDA aida = AIDA.defaultInstance();
+
+	int ievt = 0; // Keeps track of event number
+	
+	int beampipe; //Set to one if muon travels down beampipe 
+
+	int numparticlesmc; //Number of total mc particles
+	int numparticlesrc; //Number of total rc particles
+	
+	Object[] allparticlekeys; //Stores particle ids involved in the event
+	
+	// Hash maps to store the number of each particle type
+	HashMap<Integer, Integer> particlenumbersmc;
+	HashMap<Integer, Integer> particlenumbersrc;
+
+	// Ensures collections are defined as global
+	List<MCParticle> mcparticles;
+	List<ReconstructedParticle> rcparticles;
+	// Lists to store the muons involved in the event
+	List<MCParticle> MCMuons;
+	List<ReconstructedParticle> RCMuons;
+
+	// Ensures writer is public
+	LCIOWriter writer;
+	
+	public MuonAnalysis() {
+		aida = AIDA.defaultInstance();
+		
+		// Opens a new writer
+		try {
+			File output = new File(System.getProperty("user.home"), "output.slcio");
+			writer = new LCIOWriter(output);
+		} catch (IOException x) {
+			throw new RuntimeException("Error writing LCIO file", x);
+		}
+	}
+
+	protected void process(EventHeader event) {
+		
+		// Stores the muons in the event
+		MCMuons = new ArrayList<MCParticle>();
+		RCMuons = new ArrayList<ReconstructedParticle>();
+		// Retrieves the data from the LCIO file
+		mcparticles = event.get(MCParticle.class, mcparticlename);
+		rcparticles = event.get(ReconstructedParticle.class, reconname);
+
+		// Counts the number of particles and fills the HashMaps - also outputs data on MC particles for comparison
+		numparticlesmc = countmc();
+		numparticlesrc = countrc();
+		
+		//Compile list of particles involved in event, either rc or mc
+		//Add any particles that you will be analysis to ensure data is output on EVERY event
+		//Otherwise only events that contain that particle in either the mc or rc particle lists will be used 
+		//This can lead to a problem with analysis the average number of particles created per event
+		Set<Integer> ParticleList = new HashSet<Integer>();
+		ParticleList.addAll(particlenumbersmc.keySet());
+		ParticleList.addAll(particlenumbersrc.keySet());
+		ParticleList.add(130); 
+		ParticleList.add(13); 
+		ParticleList.add(211); 
+		ParticleList.add(9912);
+		ParticleList.add(22);
+		ParticleList.add(11);
+		allparticlekeys = ParticleList.toArray();
+
+		//Fills empty hashmap values with 0 to prevent null pointer error 
+		for(Object id : allparticlekeys){
+			if (particlenumbersmc.get(id.hashCode()) == null) {
+				particlenumbersmc.put(id.hashCode(), 0);
+			}
+			if (particlenumbersrc.get(id.hashCode()) == null) {
+				particlenumbersrc.put(id.hashCode(), 0);
+			}
+		}
+
+		//Outputs number of each particle 
+		for (int i = 0; i < allparticlekeys.length; i++) {
+			aida.histogram1D("MC Data/" + allparticlekeys[i].toString() + "/Numbers",numberparthist[0],numberparthist[1],numberparthist[2]).fill(particlenumbersmc.get(allparticlekeys[i]));
+			aida.histogram1D("RC Data/" + allparticlekeys[i].toString() + "/Numbers",numberparthist[0],numberparthist[1],numberparthist[2]).fill(particlenumbersrc.get(allparticlekeys[i]));
+		}
+		
+		//Output data for all events
+		outputhistograms("Events ( All )");
+		
+		//Output data for events with specific number of muons
+		outputhistograms("Events with " + MCMuons.size() + " muons");
+		
+		//Output cut data - not all muons reconstructed
+		if(RCMuons.size()<MCMuons.size()){
+			outputhistograms("Events (too few muons)");
+	
+//  Output event to LCIO file
+//			try {
+//				writer.write(event);
+//			} catch (IOException x) {
+//				throw new RuntimeException("Error writing LCIO file", x);
+//			}
+			
+		}
+		
+		//Output cut data - excess particles reconstructed
+		if(numparticlesrc>numparticlesmc){
+			outputhistograms("Events (excess particles)");
+		}
+		
+		//Looking for correlations between missing particles and gained particles
+		for(int i=0;i<allparticlekeys.length;i++){
+			for(int j=0; j<i;j++){
+				aida.cloud2D("Missing Particle Correlations/Particle " + allparticlekeys[i].toString() + " vs Particle " + allparticlekeys[j].toString()).fill(particlenumbersmc.get(allparticlekeys[i]) - particlenumbersrc.get(allparticlekeys[i]), particlenumbersmc.get(allparticlekeys[j]) - particlenumbersrc.get(allparticlekeys[j]));
+			}
+		}
+		
+		//Event counter
+		if (ievt % 100 == 0) {
+			System.out.println("Event = " + ievt);
+		}
+		ievt++;
+
+	}
+
+	protected void outputhistograms(String cuttype){
+		//Output data on all involved particles for all events AND split by beampipe
+		for (int i = 0; i < allparticlekeys.length; i++) {
+			aida.histogram1D(cuttype + "/" + allparticlekeys[i].toString() + "/Number Part RC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(particlenumbersrc.get(allparticlekeys[i]));
+			aida.histogram1D(cuttype + "/" + allparticlekeys[i].toString() + "/beampipe = " + beampipe + "/Number Part RC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(particlenumbersrc.get(allparticlekeys[i]));
+			aida.histogram1D(cuttype + "/" + allparticlekeys[i].toString() + "/Number Part MC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(particlenumbersmc.get(allparticlekeys[i]));
+			aida.histogram1D(cuttype + "/" + allparticlekeys[i].toString() + "/beampipe = " + beampipe + "/Number Part MC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(particlenumbersmc.get(allparticlekeys[i]));
+			aida.histogram1D(cuttype + "/" + allparticlekeys[i].toString() + "/Missing Part",numberpartmissinghist[0],numberpartmissinghist[1],numberpartmissinghist[2]).fill(particlenumbersmc.get(allparticlekeys[i]) - particlenumbersrc.get(allparticlekeys[i]));
+			aida.histogram1D(cuttype + "/" + allparticlekeys[i].toString() + "/beampipe = " + beampipe + "/Missing Part",numberpartmissinghist[0],numberpartmissinghist[1],numberpartmissinghist[2]).fill(particlenumbersmc.get(allparticlekeys[i]) - particlenumbersrc.get(allparticlekeys[i]));
+		
+			//Produces data on specific not found particles rather than just the number of particles used up to this point
+			particlehistograms(cuttype,allparticlekeys[i].hashCode());
+		}
+		
+		//Data on all particles not split by type as above
+		aida.histogram1D(cuttype + "/all/beampipe = " + beampipe + "/Number Part RC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(numparticlesrc);
+		aida.histogram1D(cuttype + "/all/beampipe = " + beampipe + "/Number Part MC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(numparticlesmc);
+		aida.histogram1D(cuttype + "/all/beampipe = " + beampipe + "/Missing Part",numberpartmissinghist[0],numberpartmissinghist[1],numberpartmissinghist[2]).fill(numparticlesmc - numparticlesrc);
+		aida.histogram1D(cuttype + "/all/Number Part RC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(numparticlesrc);
+		aida.histogram1D(cuttype + "/all/Number Part MC",numberparthist[0],numberparthist[1],numberparthist[2]).fill(numparticlesmc);
+		aida.histogram1D(cuttype + "/all/Missing Part",numberpartmissinghist[0],numberpartmissinghist[1],numberpartmissinghist[2]).fill(numparticlesmc - numparticlesrc);
+	}
+	
+	protected void particlehistograms(String cuttype, int type) {
+		//Loop over MC particles and output details about particles that are MISSING from the reconstruction
+		for (MCParticle mcparticle : mcparticles) {
+			if ((mcparticle.getGeneratorStatus() == Particle.FINAL_STATE) && (mcparticle.getPDGID() == type)) {
+				//Flag for particle found in reconstruction
+				int found = 0;
+				// Check if particle can be found in corresponding bin
+				for (ReconstructedParticle rcparticle : rcparticles) {
+					if ((gettype(rcparticle.getParticleIDUsed().getPDG()) == gettype(mcparticle.getPDGID())) && (mcparticle.getCharge() == rcparticle.getCharge()) && ((VecOp.dot(mcparticle.getMomentum(), rcparticle.getMomentum()) / (mcparticle.getMomentum().magnitude() * rcparticle.getMomentum().magnitude())) > 0.99) && (Math.abs(rcparticle.getEnergy() - mcparticle.getEnergy()) < 5)) {
+						found = 1;
+					}
+				}
+				// If particle cannot be found plot data on mcparticle that is missing
+				if (found == 0) {
+					//Data split by type AND all
+					aida.histogram1D(cuttype + "/" + type + "/Missing/Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(mcparticle.getMomentum()));
+					aida.histogram1D(cuttype + "/" + type + "/Missing/Energy",energymissinghist[0],energymissinghist[1],energymissinghist[2]).fill(mcparticle.getEnergy());
+					aida.histogram1D(cuttype + "/all/Missing/Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(mcparticle.getMomentum()));
+					aida.histogram1D(cuttype + "/all/Missing/Energy",energymissinghist[0],energymissinghist[1],energymissinghist[2]).fill(mcparticle.getEnergy());
+					if (Math.abs(VecOp.cosTheta(mcparticle.getMomentum())) < 0.99) {
+						//Beampipe data split by type AND all
+						aida.histogram1D(cuttype + "/" + type + "/Missing/Angle Not Beampipe",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(mcparticle.getMomentum()));
+						aida.histogram1D(cuttype + "/" + type + "/Missing/Energy Not Beampipe",energymissinghist[0],energymissinghist[1],energymissinghist[2]).fill(mcparticle.getEnergy());
+						aida.histogram1D(cuttype + "/all/Missing/Angle Not Beampipe",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(mcparticle.getMomentum()));
+						aida.histogram1D(cuttype + "/all/Missing/Energy Not Beampipe",energymissinghist[0],energymissinghist[1],energymissinghist[2]).fill(mcparticle.getEnergy());
+					}
+				}
+			}
+		}
+		//Loops over the RC particles and output details about particles that are CREATED in the reconstruction
+		for (ReconstructedParticle rcparticle : rcparticles) {
+			if ((rcparticle.getParticleIDUsed().getPDG() == type)) {
+				int found = 0;
+				//Search for corresponding particle in corresponding bin
+				for (MCParticle mcparticle : mcparticles) {
+					if ((gettype(rcparticle.getParticleIDUsed().getPDG()) == gettype(mcparticle.getPDGID())) && (mcparticle.getCharge() == rcparticle.getCharge())
+							&& ((VecOp.dot(mcparticle.getMomentum(), rcparticle.getMomentum()) / (mcparticle.getMomentum().magnitude() * rcparticle.getMomentum().magnitude())) > 0.99) && (Math.abs(rcparticle.getEnergy() - mcparticle.getEnergy()) < 5)) {
+						found = 1;
+					}
+				}
+				// If particle cannot be found plot data on mcparticle
+				if (found == 0) {
+					aida.histogram1D(cuttype + "/" + type + "/Created/Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(rcparticle.getMomentum()));
+					aida.histogram1D(cuttype + "/" + type + "/Created/Energy",energyhist[0],energyhist[1],energyhist[2]).fill(rcparticle.getEnergy());
+					aida.histogram1D(cuttype + "/all/Created/Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(rcparticle.getMomentum()));
+					aida.histogram1D(cuttype + "/all/Created/Energy",energyhist[0],energyhist[1],energyhist[2]).fill(rcparticle.getEnergy());
+					//Loops over muons to compare angle to created particles
+					for(MCParticle mcmuon : MCMuons){
+						aida.histogram1D(cuttype + "/" + type + "/Created/Angle to muons",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.dot(mcmuon.getMomentum(),rcparticle.getMomentum())/(mcmuon.getMomentum().magnitude()*rcparticle.getMomentum().magnitude()));
+					}
+					//Loops over clusters associated with created particle and plot number of hits against energy (perhaps need to sum up hits - or check number of clusters is 1)
+					for(Cluster cluster : rcparticle.getClusters()){
+						aida.cloud2D(cuttype + "/" + type + "/Created/Cal Hits vs energy").fill(cluster.getCalorimeterHits().size(),rcparticle.getEnergy());
+						aida.cloud2D(cuttype + "/all/Created/Cal Hits vs energy").fill(cluster.getCalorimeterHits().size(),rcparticle.getEnergy());
+					}
+					//Output same again without the beampipe events
+					if (Math.abs(VecOp.cosTheta(rcparticle.getMomentum())) < 0.99) {
+						aida.histogram1D(cuttype + "/" + type + "/Created/Angle Not Beampipe",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(rcparticle.getMomentum()));
+						aida.histogram1D(cuttype + "/" + type + "/Created/Energy Not Beampipe",energyhist[0],energyhist[1],energyhist[2]).fill(rcparticle.getEnergy());
+						aida.histogram1D(cuttype + "/all/Created/Angle Not Beampipe",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(rcparticle.getMomentum()));
+						aida.histogram1D(cuttype + "/all/Created/Energy Not Beampipe",energyhist[0],energyhist[1],energyhist[2]).fill(rcparticle.getEnergy());
+						for(Cluster cluster : rcparticle.getClusters()){
+							aida.cloud2D(cuttype + "/" + type + "/Created/Cal Hits vs energy Not Beampipe").fill(cluster.getCalorimeterHits().size(),rcparticle.getEnergy());
+						}
+					}
+				}
+			}
+		}
+	}
+
+	protected int gettype(int originaltype) {
+		// Used to change the types of particle to basic types (also removed the sign)
+		int type;
+		switch (Math.abs(originaltype)) {
+		case 12:
+		case 14:
+		case 16:
+			type = 9912; // Neutrinos collected together and called 9912
+			break;
+		case 2112:
+			type = 130; // Neutrons called a K-longs
+			break;
+		case 2212:
+		case 321:
+			type = 211; // Charged particles called pions
+			break;
+		default:
+				type = Math.abs(originaltype);
+			break;
+		}
+		return type;
+	}
+
+	protected int countmc() {
+		// Counts the number of mc particles and adds data to a histogram and particlenumbersmc 
+		beampipe = 0;
+		int i = 0;
+		double energy = 0.0;
+		particlenumbersmc = new HashMap<Integer, Integer>();
+		for (MCParticle mcparticle : mcparticles) {
+			if (mcparticle.getGeneratorStatus() == Particle.FINAL_STATE) {
+				if (particlenumbersmc.get(gettype(mcparticle.getPDGID())) == null) {
+					particlenumbersmc.put(gettype(mcparticle.getPDGID()), 1);
+				} else {
+					particlenumbersmc.put(gettype(mcparticle.getPDGID()), particlenumbersmc.get(gettype(mcparticle.getPDGID())) + 1);
+				}
+				i++;
+				energy+=mcparticle.getEnergy();
+				//Outputs data of MC particles for comparison
+				aida.histogram1D("MC Data/" + gettype(mcparticle.getPDGID()) + "/Energy",energyhist[0],energyhist[1],energyhist[2]).fill(mcparticle.getEnergy());
+				aida.histogram1D("MC Data/" + gettype(mcparticle.getPDGID()) + "/Cos Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(mcparticle.getMomentum()));
+				aida.histogram1D("MC Data/all/Energy",energyhist[0],energyhist[1],energyhist[2]).fill(mcparticle.getEnergy());
+				aida.histogram1D("MC Data/all/Cos Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(mcparticle.getMomentum()));
+				//Add muons to specific list
+				if(gettype(mcparticle.getPDGID())==13){
+					MCMuons.add(mcparticle);
+				}
+				//Set if this is a beampipe event or not
+				if(VecOp.cosTheta(mcparticle.getMomentum())>0.99){
+					beampipe = 1;
+				}
+				}
+		}
+		aida.histogram1D("MC Data/Total Energy",energyhist[0],energyhist[1],energyhist[2]).fill(energy);
+		return i;
+	}
+	
+	protected int countrc() {
+		// Counts the number of rc particles and adds data to a histogram and particlenumbersrc 
+		int i = 0;
+		double energy = 0.0;
+		particlenumbersrc = new HashMap<Integer, Integer>();
+		for (ReconstructedParticle rcparticle : rcparticles) {
+			if (particlenumbersrc.get(gettype(rcparticle.getParticleIDUsed().getPDG())) == null) {
+				particlenumbersrc.put(gettype(rcparticle.getParticleIDUsed().getPDG()), 1);
+			} else {
+				particlenumbersrc.put(gettype(rcparticle.getParticleIDUsed().getPDG()), particlenumbersrc.get(gettype(rcparticle.getParticleIDUsed().getPDG())) + 1);
+			}
+			i++;
+			energy+=rcparticle.getEnergy();
+			//Muons added to specific list for use throughout the program
+			if (rcparticle.getParticleIDUsed().getPDG() == 13) {
+				RCMuons.add(rcparticle);
+			}
+			aida.histogram1D("RC Data/" + gettype(rcparticle.getParticleIDUsed().getPDG()) + "/Energy",energyhist[0],energyhist[1],energyhist[2]).fill(rcparticle.getEnergy());
+			aida.histogram1D("RC Data/" + gettype(rcparticle.getParticleIDUsed().getPDG()) + "/Cos Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(rcparticle.getMomentum()));
+			aida.histogram1D("RC Data/all/Energy",energyhist[0],energyhist[1],energyhist[2]).fill(rcparticle.getEnergy());
+			aida.histogram1D("RC Data/all/Cos Angle",anglehist[0],anglehist[1],anglehist[2]).fill(VecOp.cosTheta(rcparticle.getMomentum()));
+		}
+		aida.histogram1D("RC Data/Total Energy",energyhist[0],energyhist[1],energyhist[2]).fill(energy);
+		return i;
+	}
+
+	protected void endOfData() {
+//  It is possible to output values from the HashMaps used to store the data at the end of a run for more precise data analysis
+//		Object ParticleList2[] = particlenumbersmc.keySet().toArray();
+//		for(int i = 1; i< ParticleList2.length;i++){
+//			System.out.println("Particle ID = " + ParticleList2[i].hashCode() + " number of particles = " + particlenumbersmc.get(ParticleList2[i]));
+//		}
+	}
+}
CVSspam 0.2.8