Author: [log in to unmask]
Date: Sat Jan 31 17:18:52 2015
New Revision: 2019
Log:
1st running pedestal
Added:
java/trunk/users/src/main/java/org/hps/users/baltzell/
java/trunk/users/src/main/java/org/hps/users/baltzell/ECalRunningPedestalDriver.java
java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver_RunPed.java
java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter_RunPed.java
Added: java/trunk/users/src/main/java/org/hps/users/baltzell/ECalRunningPedestalDriver.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/ECalRunningPedestalDriver.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/ECalRunningPedestalDriver.java Sat Jan 31 17:18:52 2015
@@ -0,0 +1,213 @@
+package org.hps.users.baltzell;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannel;
+import org.hps.conditions.ecal.EcalChannelConstants;
+import org.hps.conditions.ecal.EcalConditions;
+import org.hps.recon.ecal.HitExtraData;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+
+/**
+ * Calculate a running pedestal average for every channel from Mode7 FADCs.
+ * @version $Id: ECalRunningPedestalDriver.java,v 0.0 2015/01/31 00:00:00
+ * @author <[log in to unmask]>
+ */
+public class ECalRunningPedestalDriver extends Driver {
+
+ // limit array lengths:
+ private final int limitLookbackEvents = 1000;
+
+ // minimum number of readouts for running averages:
+ // (if not satisfied, use pedestals from database)
+ private int minLookbackEvents = 10;
+
+ // maximum number of readouts for running averages:
+ // (if too many, discard the oldest ones)
+ private int maxLookbackEvents = 100;
+
+ // oldest allowed time for running averages:
+ // (discard older readouts ; negative = no time limit)
+ private long maxLookbackTime = -1; // units = ms
+
+ private static final String rawCollectionName = "EcalReadoutHits";
+ private static final String extraDataRelationsName = "EcalReadoutExtraDataRelations";
+ private static final String runningPedestalsName = "EcalRunningPedestals";
+
+ // FIXME:
+ private final int nChannels = 442;
+
+ // running pedestal averages, one for each channel:
+ private List<Double> runningPedestals = new ArrayList<Double>(nChannels);
+
+ // FIXME:
+ // recent event-by-event pedestals and timestamps:
+ private List<Integer>[] eventPedestals = (ArrayList<Integer>[]) new ArrayList[nChannels];
+ private List<Long>[] eventTimestamps = (ArrayList<Long>[]) new ArrayList[nChannels];
+
+ private EcalConditions ecalConditions = null;
+
+
+
+ public ECalRunningPedestalDriver() {
+ for (int ii = 0; ii < nChannels; ii++) {
+ eventPedestals[ii] = new ArrayList<>();
+ eventTimestamps[ii] = new ArrayList<>();
+ runningPedestals.add(-1.); // would like to initialize with DB pedestals, but they're not available yet
+ }
+ }
+ @Override
+ protected void startOfData() {
+ }
+
+ @Override
+ public void detectorChanged(Detector detector) {
+ ecalConditions = ConditionsManager.defaultInstance()
+ .getCachedConditions(EcalConditions.class,TableConstants.ECAL_CONDITIONS)
+ .getCachedData();
+ }
+ public void setMinLookbackEvents(int nev) {
+ minLookbackEvents = nev;
+ }
+ public void setMaxLookbackEvents(int nev) {
+ maxLookbackEvents = nev;
+ }
+ public void setMaxLookbackTime(int time) {
+ maxLookbackTime = time;
+ }
+
+
+ public double getPedestal(int channel_id) {
+ final int nped = eventPedestals[channel_id - 1].size();
+ if (nped < minLookbackEvents) return getStaticPedestal(channel_id);
+ else return runningPedestals.get(channel_id - 1);
+ }
+
+ public void printPedestals() {
+ for (int ii = 0; ii < nChannels; ii++) {
+ System.out.printf("(%d,%.2f,%.2f) ",ii,runningPedestals.get(ii),getStaticPedestal(ii + 1));
+ }
+ System.out.printf("\n");
+ }
+
+ @Override
+ protected void process(EventHeader event) {
+ if (!event.hasCollection(RawCalorimeterHit.class,rawCollectionName))
+ return;
+ if (!event.hasCollection(LCRelation.class,extraDataRelationsName))
+ return;
+ for (LCRelation rel : event.get(LCRelation.class,extraDataRelationsName)) {
+ RawCalorimeterHit hit = (RawCalorimeterHit) rel.getFrom();
+ GenericObject extraData = (GenericObject) rel.getTo();
+ updatePedestal(event,hit,extraData);
+ }
+
+ // quick fix until I know how to read from DB before 'process':
+ List<Double> peds = new ArrayList<Double>(nChannels);
+ for (int ii=0; ii<nChannels; ii++){
+ peds.add(ii,getPedestal(ii+1));
+ }
+
+ //
+ // don't care right now whether this persists in output slcio,
+ // just that it is accessible during reconstruction (and it is)
+ //
+ // Another option would be to put hits' running pedestals into HitExtraData.Mode7Data
+ // Or create another LCRelation
+ // Either would also remove the need for indexing later.
+ //
+ event.put(runningPedestalsName,peds,Double.class,1,"dog");
+// event.put(runningPedestalsName,runningPedestals,Double.class,1,"dog");
+
+// printPedestals();
+ }
+
+ public void updatePedestal(EventHeader event, RawCalorimeterHit hit, GenericObject mode7data) {
+ final int ii = getChannelID(hit) - 1;
+ if (ii < 0 || ii >= nChannels) {
+ System.err.println(String.format("Event #%d, Invalid id: %d/%d ",
+ event.getEventNumber(),ii + 1,+hit.getCellID()));
+ }
+
+ final long timestamp = event.getTimeStamp();
+ final int min = ((HitExtraData.Mode7Data) mode7data).getAmplLow();
+ final int max = ((HitExtraData.Mode7Data) mode7data).getAmplHigh();
+
+ // ignore if pulse at beginning of window:
+ if (max <= 0) return;
+
+ // If new timestamp is older than previous one, restart pedestals.
+ // This should never happen unless firmware counter cycles back to zero,
+ // in which case it could be dealt with if max timestamp is known.
+ if (eventTimestamps[ii].size() > 0 && eventTimestamps[ii].get(0) > timestamp) {
+ System.err.println(String.format("Event #%d, Old Timestamp: %d < %d",
+ event.getEventNumber(),timestamp,eventTimestamps[ii].get(0)));
+ eventPedestals[ii].clear();
+ eventTimestamps[ii].clear();
+ }
+
+ // add pedestal to the list:
+ eventPedestals[ii].add(min);
+ eventTimestamps[ii].add(timestamp);
+
+ if (eventPedestals[ii].size() > 1) {
+
+ // remove oldest pedestal if we surpassed limit on #events:
+ if (eventPedestals[ii].size() > limitLookbackEvents
+ || (maxLookbackEvents > 0 && eventPedestals[ii].size() > maxLookbackEvents)) {
+ eventPedestals[ii].remove(0);
+ eventTimestamps[ii].remove(0);
+ }
+
+ // remove old pedestals surpassing limit on lookback time:
+ if (maxLookbackTime > 0) {
+ while (eventTimestamps[ii].size() > 0) {
+ if (eventTimestamps[ii].get(0) < timestamp - maxLookbackTime*1e6) {
+ eventTimestamps[ii].remove(0);
+ eventPedestals[ii].remove(0);
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ // Update running pedestal average:
+ if (eventPedestals[ii].size() > 0) {
+ double avg = 0;
+ for (int jj = 0; jj < eventPedestals[ii].size(); jj++) {
+ avg += eventPedestals[ii].get(jj);
+ }
+ runningPedestals.set(ii,avg / eventPedestals[ii].size());
+ } else {
+ runningPedestals.set(ii,getStaticPedestal(ii+1));
+ }
+ }
+
+ public double getPedestal(RawCalorimeterHit hit) {
+ return getPedestal(getChannelID(hit));
+ }
+ private double getStaticPedestal(int channel_id) {
+ EcalChannel cc = ecalConditions.getChannelCollection().findChannel(channel_id);
+ return ecalConditions.getChannelConstants(cc).getCalibration().getPedestal();
+ }
+ private double getStaticPedestal(RawCalorimeterHit hit) {
+ return getStaticPedestal(getChannelID(hit));
+ }
+ public int getChannelID(RawCalorimeterHit hit) {
+ return findChannel(hit.getCellID()).getCalibration().getChannelId();
+ }
+ public EcalChannelConstants findChannel(long cellID) {
+ return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection()
+ .findGeometric(cellID));
+ }
+
+}
Added: java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver_RunPed.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver_RunPed.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver_RunPed.java Sat Jan 31 17:18:52 2015
@@ -0,0 +1,301 @@
+package org.hps.users.baltzell;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalChannelConstants;
+import org.hps.conditions.ecal.EcalConditions;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.lcio.LCIOConstants;
+import org.lcsim.util.Driver;
+
+/**
+ *
+ * @version $Id: HPSEcalRawConverterDriver.java,v 1.2 2012/05/03 00:17:54
+ * phansson Exp $
+ */
+public class EcalRawConverterDriver_RunPed extends Driver {
+
+ // To import database conditions
+ private EcalConditions ecalConditions = null;
+
+ private EcalRawConverter_RunPed converter = null;
+ private String rawCollectionName = "EcalReadoutHits";
+ private final String ecalReadoutName = "EcalHits";
+ private String ecalCollectionName = "EcalCalHits";
+
+ private static final String extraDataRelationsName = "EcalReadoutExtraDataRelations";
+// private static final String extraDataCollectionName = "EcalReadoutExtraData";
+
+ private int integralWindow = 30; //A.C. on 12/14/2014 8:44 after discussion with Nathan.
+ private boolean debug = false;
+ private double threshold = Double.NEGATIVE_INFINITY;
+ private boolean applyBadCrystalMap = true;
+ private boolean dropBadFADC = false;
+ private boolean runBackwards = false;
+ private boolean useTimestamps = false;
+ private boolean useTruthTime = false;
+
+ public EcalRawConverterDriver_RunPed() {
+ converter = new EcalRawConverter_RunPed();
+ }
+
+ public void setUse2014Gain(boolean use2014Gain) {
+ converter.setUse2014Gain(use2014Gain);
+ }
+
+ public void setUseRunningPedestal(boolean useRunningPedestal) {
+ converter.setUseRunningPedestal(useRunningPedestal);
+ }
+ public void setRunBackwards(boolean runBackwards) {
+ this.runBackwards = runBackwards;
+ }
+
+ public void setDropBadFADC(boolean dropBadFADC) {
+ this.dropBadFADC = dropBadFADC;
+ }
+
+ public void setThreshold(double threshold) {
+ this.threshold = threshold;
+ }
+
+ public void setGain(double gain) {
+ converter.setGain(gain);
+ }
+
+ public void setIntegralWindow(int integralWindow) {
+ this.integralWindow = integralWindow;
+ }
+
+ public void setEcalCollectionName(String ecalCollectionName) {
+ this.ecalCollectionName = ecalCollectionName;
+ }
+
+ public void setRawCollectionName(String rawCollectionName) {
+ this.rawCollectionName = rawCollectionName;
+ }
+
+ public void setApplyBadCrystalMap(boolean apply) {
+ this.applyBadCrystalMap = apply;
+ }
+
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ public void setUseTimestamps(boolean useTimestamps) {
+ this.useTimestamps = useTimestamps;
+ }
+
+ public void setUseTruthTime(boolean useTruthTime) {
+ this.useTruthTime = useTruthTime;
+ }
+
+ @Override
+ public void startOfData() {
+ if (ecalCollectionName == null) {
+ throw new RuntimeException("The parameter ecalCollectionName was not set!");
+ }
+ }
+
+ @Override
+ public void detectorChanged(Detector detector) {
+
+ // set the detector for the converter
+ // FIXME: This method doesn't even need the detector object and does not use it.
+ converter.setDetector(detector);
+
+ // ECAL combined conditions object.
+ ecalConditions = ConditionsManager.defaultInstance()
+ .getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();
+ }
+
+ /**
+ * @return false if the channel is a good one, true if it is a bad one
+ * @param CalorimeterHit
+ */
+ public boolean isBadCrystal(CalorimeterHit hit) {
+ // Get the channel data.
+ EcalChannelConstants channelData = findChannel(hit.getCellID());
+
+ return channelData.isBadChannel();
+ }
+
+ /**
+ * @return false if the ADC is a good one, true if it is a bad one
+ * @param CalorimeterHit
+ */
+ public boolean isBadFADC(CalorimeterHit hit) {
+ return (getCrate(hit.getCellID()) == 1 && getSlot(hit.getCellID()) == 3);
+ }
+
+ private static double getTimestamp(int system, EventHeader event) { //FIXME: copied from org.hps.readout.ecal.ReadoutTimestamp
+ if (event.hasCollection(GenericObject.class, "ReadoutTimestamps")) {
+ List<GenericObject> timestamps = event.get(GenericObject.class, "ReadoutTimestamps");
+ for (GenericObject timestamp : timestamps) {
+ if (timestamp.getIntVal(0) == system) {
+ return timestamp.getDoubleVal(0);
+ }
+ }
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public void process(EventHeader event) {
+ final int SYSTEM_TRIGGER = 0;
+ final int SYSTEM_TRACKER = 1;
+ final int SYSTEM_ECAL = 2;
+
+ double timeOffset = 0.0;
+ if (useTimestamps) {
+ double t0ECal = getTimestamp(SYSTEM_ECAL, event);
+ double t0Trig = getTimestamp(SYSTEM_TRIGGER, event);
+ timeOffset += (t0ECal - t0Trig) + 200.0;
+ }
+ if (useTruthTime) {
+ double t0ECal = getTimestamp(SYSTEM_ECAL, event);
+ timeOffset += ((t0ECal + 250.0) % 500.0) - 250.0;
+ }
+
+ int flags = 0;
+ flags += 1 << LCIOConstants.RCHBIT_TIME; //store hit time
+ flags += 1 << LCIOConstants.RCHBIT_LONG; //store hit position; this flag has no effect for RawCalorimeterHits
+
+ if (!runBackwards) {
+ ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>();
+
+ // Get the list of ECal hits.
+ if (event.hasCollection(RawTrackerHit.class, rawCollectionName)) {
+ List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName);
+
+ for (RawTrackerHit hit : hits) {
+ CalorimeterHit newHit = converter.HitDtoA(hit);
+
+ // Get the channel data.
+ EcalChannelConstants channelData = findChannel(newHit.getCellID());
+
+ if (applyBadCrystalMap && channelData.isBadChannel()) {
+ continue;
+ }
+ if (dropBadFADC && isBadFADC(newHit)) {
+ continue;
+ }
+ if (newHit.getRawEnergy() > threshold) {
+ newHits.add(newHit);
+ }
+ }
+ event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
+ }
+ if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { //A.C. this is the case of the RAW pulse hits
+ if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from mode 7 readout
+ List<LCRelation> extraDataRelations = event.get(LCRelation.class, extraDataRelationsName);
+ for (LCRelation rel : extraDataRelations) {
+ RawCalorimeterHit hit = (RawCalorimeterHit) rel.getFrom();
+ if (debug) {
+ System.out.format("old hit energy %d\n", hit.getAmplitude());
+ }
+ GenericObject extraData = (GenericObject) rel.getTo();
+ CalorimeterHit newHit;
+ newHit = converter.HitDtoA(event, hit, extraData, integralWindow, timeOffset);
+ if (newHit.getRawEnergy() > threshold) {
+ if (applyBadCrystalMap && isBadCrystal(newHit)) {
+ continue;
+ }
+ if (dropBadFADC && isBadFADC(newHit)) {
+ continue;
+ }
+ if (debug) {
+ System.out.format("new hit energy %f\n", newHit.getRawEnergy());
+ }
+ newHits.add(newHit);
+ }
+
+ }
+ } else {
+ List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, rawCollectionName);
+ for (RawCalorimeterHit hit : hits) {
+ if (debug) {
+ System.out.format("old hit energy %d\n", hit.getAmplitude());
+ }
+ CalorimeterHit newHit;
+ newHit = converter.HitDtoA(hit, integralWindow, timeOffset);
+ if (newHit.getRawEnergy() > threshold) {
+ if (applyBadCrystalMap && isBadCrystal(newHit)) {
+ continue;
+ }
+ if (dropBadFADC && isBadFADC(newHit)) {
+ continue;
+ }
+ if (debug) {
+ System.out.format("new hit energy %f\n", newHit.getRawEnergy());
+ }
+ newHits.add(newHit);
+ }
+ }
+ }
+ event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
+ }
+ } else {
+ ArrayList<RawCalorimeterHit> newHits = new ArrayList<RawCalorimeterHit>();
+ if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
+ List<CalorimeterHit> hits = event.get(CalorimeterHit.class, ecalCollectionName);
+
+ for (CalorimeterHit hit : hits) {
+ if (debug) {
+ System.out.format("old hit energy %f\n", hit.getRawEnergy());
+ }
+ RawCalorimeterHit newHit = converter.HitAtoD(hit, integralWindow);
+ if (newHit.getAmplitude() > 0) {
+ if (debug) {
+ System.out.format("new hit energy %d\n", newHit.getAmplitude());
+ }
+ newHits.add(newHit);
+ }
+ }
+ event.put(rawCollectionName, newHits, RawCalorimeterHit.class, flags, ecalReadoutName);
+ }
+ }
+ }
+
+ /**
+ * Convert physical ID to gain value.
+ *
+ * @param cellID (long)
+ * @return channel constants (EcalChannelConstants)
+ */
+ private EcalChannelConstants findChannel(long cellID) {
+ return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
+ }
+
+ /**
+ * Return crate number from cellID
+ *
+ * @param cellID (long)
+ * @return Crate number (int)
+ */
+ private int getCrate(long cellID) {
+ // Find the ECAL channel and return the crate number.
+ return ecalConditions.getChannelCollection().findGeometric(cellID).getCrate();
+ }
+
+ /**
+ * Return slot number from cellID
+ *
+ * @param cellID (long)
+ * @return Slot number (int)
+ */
+ private int getSlot(long cellID) {
+ // Find the ECAL channel and return the slot number.
+ return ecalConditions.getChannelCollection().findGeometric(cellID).getSlot();
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter_RunPed.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter_RunPed.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter_RunPed.java Sat Jan 31 17:18:52 2015
@@ -0,0 +1,184 @@
+package org.hps.users.baltzell;
+
+import java.util.List;
+
+import org.hps.conditions.database.TableConstants;
+import org.hps.conditions.ecal.EcalCalibration;
+import org.hps.conditions.ecal.EcalChannelConstants;
+import org.hps.conditions.ecal.EcalConditions;
+import org.hps.recon.ecal.CalorimeterHitUtilities;
+import org.hps.recon.ecal.ECalUtils;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.base.BaseRawCalorimeterHit;
+import org.lcsim.geometry.Detector;
+
+/**
+ * This class is used to convert {@link org.lcsim.event.RawCalorimeterHit}
+ * objects to {@link org.lcsim.event.CalorimeterHit} objects with energy
+ * information. It has methods to convert pedestal subtracted ADC counts to
+ * energy.
+ *
+ * Temporary: NAB January 31, 2015, just for testing running pedestal
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @author Andrea Celentano <[log in to unmask]>
+ */
+public class EcalRawConverter_RunPed {
+
+ private boolean useRunningPedestal = false;
+ private boolean constantGain = false;
+ private double gain;
+ private boolean use2014Gain = true;
+
+ private EcalConditions ecalConditions = null;
+
+ public EcalRawConverter_RunPed() {
+ }
+
+ public void setGain(double gain) {
+ constantGain = true;
+ this.gain = gain;
+ }
+
+ public void setUse2014Gain(boolean use2014Gain) {
+ this.use2014Gain = use2014Gain;
+ }
+
+ public void setUseRunningPedestal(boolean useRunningPedestal) {
+ this.useRunningPedestal=useRunningPedestal;
+ }
+
+ // NAB January 2015
+ // Choose whether to use static pedestal from database or running pedestal:
+ public double getPedestal(EventHeader event, long cellID) {
+ EcalCalibration calib = findChannel(cellID).getCalibration();
+ if (useRunningPedestal) {
+ // works, but remove indexing by using LCRelation or adding to Mode7Data
+ if (event.hasCollection(Double.class,"EcalRunningPedestals")) {
+ List<Double> peds = event.get(Double.class,"EcalRunningPedestals");
+ final int cid = calib.getChannelId()-1;
+ if (cid < 0 || cid>=peds.size()) {
+ // logger, or throw exception, ...
+ System.err.println("EcalRawConverter::getPedestal Bad Channel_id: "+cid);
+ } else {
+ // System.out.println(String.format("%d - %.2f",channel_id-1,peds.get(cid)));
+ return peds.get(cid);
+ }
+ }
+ }
+ // pedestal from database:
+ return calib.getPedestal();
+ }
+
+ public short sumADC(RawTrackerHit hit) {
+ EcalChannelConstants channelData = findChannel(hit.getCellID());
+ double pedestal = channelData.getCalibration().getPedestal();
+ short sum = 0;
+ short samples[] = hit.getADCValues();
+ for (int isample = 0; isample < samples.length; ++isample) {
+ sum += (samples[isample] - pedestal);
+ }
+ return sum;
+ }
+
+ public CalorimeterHit HitDtoA(RawTrackerHit hit) {
+ double time = hit.getTime();
+ long id = hit.getCellID();
+ double rawEnergy = adcToEnergy(sumADC(hit), id);
+ return CalorimeterHitUtilities.create(rawEnergy, time, id);
+ }
+
+ public CalorimeterHit HitDtoA(RawCalorimeterHit hit, int window, double timeOffset) {
+ if (hit.getTimeStamp() % 64 != 0) {
+ System.out.println("unexpected timestamp " + hit.getTimeStamp());
+ }
+ double time = hit.getTimeStamp() / 16.0;
+ long id = hit.getCellID();
+ // Get the channel data.
+ EcalChannelConstants channelData = findChannel(id);
+ double adcSum = hit.getAmplitude() - window * channelData.getCalibration().getPedestal();
+ double rawEnergy = adcToEnergy(adcSum, id);
+ return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id);
+ //return h2;
+ }
+
+ // NAB Januray 2015, mod for running pedestal
+ public CalorimeterHit HitDtoA(EventHeader event,RawCalorimeterHit hit, GenericObject mode7Data, int window, double timeOffset) {
+ double time = hit.getTimeStamp() / 16.0; //timestamps use the full 62.5 ps resolution
+ long id = hit.getCellID();
+// // Get the channel data.
+ EcalChannelConstants channelData = findChannel(id);
+// double adcSum = hit.getAmplitude() - window * channelData.getCalibration().getPedestal();
+// double adcSum = hit.getAmplitude() - window * Mode7Data.getAmplLow(mode7Data); //A.C. is this the proper way to pedestal subtract in mode 7?
+ double adcSum = hit.getAmplitude() - window * getPedestal(event,id);
+ double rawEnergy = adcToEnergy(adcSum, id);
+ return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id);
+
+ //return h2;
+ }
+
+ public RawCalorimeterHit HitAtoD(CalorimeterHit hit, int window) {
+ int time = (int) (Math.round(hit.getTime() / 4.0) * 64.0);
+ long id = hit.getCellID();
+ // Get the channel data.
+ EcalChannelConstants channelData = findChannel(id);
+ int amplitude;
+ if (constantGain) {
+ amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + window * channelData.getCalibration().getPedestal());
+ } else {
+ amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / channelData.getGain().getGain() + window * channelData.getCalibration().getPedestal());
+ }
+ RawCalorimeterHit h = new BaseRawCalorimeterHit(id, amplitude, time);
+ return h;
+ }
+
+ /*
+ * return energy (units of GeV) corresponding to the ADC sum and crystal ID
+ */
+ private double adcToEnergy(double adcSum, long cellID) {
+
+ // Get the channel data.
+ EcalChannelConstants channelData = findChannel(cellID);
+
+ if (use2014Gain) {
+ if (constantGain) {
+ return adcSum * ECalUtils.gainFactor * ECalUtils.ecalReadoutPeriod;
+ } else {
+ return channelData.getGain().getGain() * adcSum * ECalUtils.gainFactor * ECalUtils.ecalReadoutPeriod; // should not be used for the moment (2014/02)
+ }
+ } else {
+ if (constantGain) {
+ return gain * adcSum * ECalUtils.MeV;
+ } else {
+ return channelData.getGain().getGain() * adcSum * ECalUtils.MeV; //gain is defined as MeV/integrated ADC
+ }
+ }
+ }
+
+ /**
+ * Must be set when an object EcalRawConverter is created.
+ *
+ * @param detector (long)
+ */
+ public void setDetector(Detector detector) {
+ // ECAL combined conditions object.
+ ecalConditions = ConditionsManager.defaultInstance()
+ .getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData();
+ }
+
+ /**
+ * Convert physical ID to gain value.
+ *
+ * @param cellID (long)
+ * @return channel constants (EcalChannelConstants)
+ */
+ public EcalChannelConstants findChannel(long cellID) {
+ return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
+ }
+}
|