Print

Print


Author: [log in to unmask]
Date: Mon Nov 23 07:27:09 2015
New Revision: 3977

Log:
puts rf time into event

Added:
    java/trunk/evio/src/main/java/org/hps/evio/RfFitterDriver.java

Added: java/trunk/evio/src/main/java/org/hps/evio/RfFitterDriver.java
 =============================================================================
--- java/trunk/evio/src/main/java/org/hps/evio/RfFitterDriver.java	(added)
+++ java/trunk/evio/src/main/java/org/hps/evio/RfFitterDriver.java	Mon Nov 23 07:27:09 2015
@@ -0,0 +1,164 @@
+package org.hps.evio;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IDataPointSet;
+import hep.aida.IFitFactory;
+import hep.aida.IFitResult;
+import hep.aida.IFitter;
+import hep.aida.IFunction;
+import hep.aida.IFunctionFactory;
+
+import org.hps.recon.ecal.FADCGenericHit;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/*
+ * Extract RF time from waveform and put into lcsim event.
+ */
+public class RfFitterDriver extends Driver {
+
+	static final double NOISE=2.0; // units = FADC
+	static final int CRATE=46;
+	static final int SLOT=13;
+	static final int CHANNELS[]={0,1};
+	static final double NSPERSAMPLE=4;
+		
+
+	// boilerplate:
+    AIDA aida = AIDA.defaultInstance();
+    IAnalysisFactory analysisFactory = aida.analysisFactory();
+    IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null);
+    IFitFactory fitFactory = analysisFactory.createFitFactory();
+    IFitter fitter=fitFactory.createFitter();
+    IDataPointSet fitData=aida.analysisFactory().createDataPointSetFactory(null).create("RF ADC DataPointSet", 2);
+    
+    // the function used to fit the RF pulse:
+    IFunction fitFunction=new RfFitFunction();
+
+    /*
+     * Check the event for an RF pulse, and, if found, fit it to get
+     * RF time and then dump it in the lcsim event.
+     */
+	public void process(EventHeader event) {
+		if (!event.hasCollection(GenericObject.class,"FADCGenericHits")) return;
+		
+		boolean foundRf=false;
+    	double times[]={-9999,-9999};
+    	
+    	for (GenericObject gob : event.get(GenericObject.class,"FADCGenericHits")) {
+			FADCGenericHit hit=(FADCGenericHit)gob;
+    		
+			// ignore hits not from proper RF signals based on crate/slot/channel:
+			if (hit.getCrate()!=CRATE || hit.getSlot()!=SLOT) continue;
+    		for (int ii=0; ii<CHANNELS.length; ii++) {
+				if (hit.getChannel()==CHANNELS[ii]) {
+					
+					// we found a RF readout, fit it:
+					foundRf=true;
+					times[ii] = fitPulse(hit);
+									  				    
+					break;
+				}
+			}
+		}
+		
+    	// if we found an RF readout, dump the fit result in the event:  
+    	if (foundRf) {
+    		List <RfHit> rfHits=new ArrayList<RfHit>();
+    		rfHits.add(new RfHit(times));
+	    	event.put("RFHits", rfHits, RfHit.class, 1);
+		}
+	}
+
+	/*
+	 * Perform the fit to the RF pulse:
+	 */
+	public double fitPulse(FADCGenericHit hit) {
+		fitData.clear();
+		final int adcSamples[]=hit.getData();
+		//stores the number of peaks
+		int iz=0;
+		int peakBin[]={-999,-999};
+		final int threshold = 300;	
+		double fitThresh[]={-999,-999};
+		double pedVal[]={-999,-999};
+		
+		// Look for bins containing the peaks (2-3 peaks)
+		for (int ii=4; ii<adcSamples.length; ii++) {
+			// After 2 peaks, stop looking for more
+			if (iz==2){break;}
+			if ((adcSamples[ii+1]>0) && (adcSamples[ii-1]>0) && (adcSamples[ii]>threshold) && ii>8){
+				if ((adcSamples[ii]>adcSamples[ii+1]) && (adcSamples[ii]>=adcSamples[ii-1]) ){
+					
+					peakBin[iz]=ii;
+					iz++;
+				}
+			}
+		}
+		
+		
+		int jj=0;
+		// Choose peak closest to center of window (second peak, ik=1)
+		final int ik=1;
+		pedVal[ik] = (adcSamples[peakBin[ik]-6]+adcSamples[peakBin[ik]-7]+adcSamples[peakBin[ik]-8]+adcSamples[peakBin[ik]-9])/4.0;
+		fitThresh[ik]= (adcSamples[peakBin[ik]]+pedVal[ik])/3.0;
+	
+		// Initial values: we find/fit 3 points:
+		double itime[] = {-999,-999,-999};
+		double ifadc[] = {-999,-999,-999};
+		
+		// Find the points of the peak bin to peak bin-5 
+		for (int ll=0; ll<5; ll++){	
+			if ((adcSamples[peakBin[ik]-5+ll]) > fitThresh[ik]){
+				// One point is below fit threshold and two points are above	
+				if(jj==0 && (adcSamples[peakBin[ik]-6+ll] > pedVal[ik])){
+					final int zz=fitData.size();	
+					fitData.addPoint();
+					itime[zz] = peakBin[ik]-6+ll;
+					ifadc[zz] = adcSamples[peakBin[ik]-6+ll];
+					fitData.point(zz).coordinate(0).setValue(peakBin[ik]-6+ll);
+					fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-6+ll]);
+					fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
+					fitData.point(zz).coordinate(1).setErrorPlus(NOISE);		
+					jj++;	
+				}
+				final int zz=fitData.size();	
+				fitData.addPoint();
+				itime[zz] = peakBin[ik]-5+ll;
+				ifadc[zz] = adcSamples[peakBin[ik]-5+ll];
+				fitData.point(zz).coordinate(0).setValue(peakBin[ik]-5+ll);
+				fitData.point(zz).coordinate(1).setValue(adcSamples[peakBin[ik]-5+ll]);
+				fitData.point(zz).coordinate(1).setErrorMinus(NOISE);
+				fitData.point(zz).coordinate(1).setErrorPlus(NOISE);
+					
+				jj++;
+				if (jj==3) {break;}					
+			}
+		}
+		
+		double islope = ((double)(ifadc[2]-ifadc[0]))/(itime[2]-itime[0]);
+		double icept = ifadc[1] - islope*itime[1];
+		// Initialize fit parameters:
+		fitFunction.setParameter("intercept",icept);
+		fitFunction.setParameter("slope",islope);
+
+		// this used to be turned on somewhere else on every event, dunno if it still is:
+		//Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
+	
+		IFitResult fitResults = fitter.fit(fitData,fitFunction);
+		
+		// Read the time value at this location on the fit:
+		double halfVal = (adcSamples[peakBin[1]]+pedVal[1])/2.0;	
+	
+		return NSPERSAMPLE*(halfVal-fitResults.fittedParameter("intercept"))/fitResults.fittedParameter("slope");
+			
+	}
+		
+}