public ChannelSet <TOFWithError> GetResult() { ChannelSet <TOFWithError> cs = new ChannelSet <TOFWithError>(); foreach (string channel in Channels) { cs.AddChannel(channel, ((TOFAccumulator)GetChannel(channel)).GetResult()); } return(cs); }
static public ChannelSet <T> operator +(ChannelSet <T> cs1, ChannelSet <T> cs2) { var csNew = new ChannelSet <T>(); foreach (string channelName in cs1.Channels) { csNew.AddChannel(channelName, cs1.GetChannel(channelName)); } foreach (string channelName in cs2.Channels) { csNew.AddChannel(channelName, cs2.GetChannel(channelName)); } return(csNew); }
public void Add(ChannelSet <TOFWithError> val) { if (Channels.Count == 0) { foreach (string channel in val.Channels) { AddChannel(channel, new TOFAccumulator()); } Count = 0; } foreach (string channel in val.Channels) { ((TOFAccumulator)GetChannel(channel)).Add((TOFWithError)val.GetChannel(channel)); } Count++; }
private ChannelSet <TOFWithError> AppendChannelSetWithSpecialValues(ChannelSet <TOFWithError> tcs) { ChannelSet <TOFWithError> tcsWithSpecialValues = tcs; // Extract the TOFChannels that we need. TOFWithError c_eb = (TOFWithError)tcs.GetChannel(new string[] { "E", "B" }); TOFWithError c_edb = (TOFWithError)tcs.GetChannel(new string[] { "E", "DB" }); TOFWithError c_bdb = (TOFWithError)tcs.GetChannel(new string[] { "B", "DB" }); TOFWithError c_dbrf1f = (TOFWithError)tcs.GetChannel(new string[] { "DB", "RF1F" }); TOFWithError c_dbrf2f = (TOFWithError)tcs.GetChannel(new string[] { "DB", "RF2F" }); TOFWithError c_e = (TOFWithError)tcs.GetChannel(new string[] { "E" }); TOFWithError c_b = (TOFWithError)tcs.GetChannel(new string[] { "B" }); TOFWithError c_db = (TOFWithError)tcs.GetChannel(new string[] { "DB" }); TOFWithError c_sig = (TOFWithError)tcs.GetChannel(new string[] { "SIG" }); TOFWithError c_brf1f = (TOFWithError)tcs.GetChannel(new string[] { "B", "RF1F" }); TOFWithError c_brf2f = (TOFWithError)tcs.GetChannel(new string[] { "B", "RF2F" }); TOFWithError c_edbrf1f = (TOFWithError)tcs.GetChannel(new string[] { "E", "DB", "RF1F" }); TOFWithError c_edbrf2f = (TOFWithError)tcs.GetChannel(new string[] { "E", "DB", "RF2F" }); TOFWithError c_bdbrf1f = (TOFWithError)tcs.GetChannel(new string[] { "B", "DB", "RF1F" }); TOFWithError c_bdbrf2f = (TOFWithError)tcs.GetChannel(new string[] { "B", "DB", "RF2F" }); TOFWithError c_ebdb = (TOFWithError)tcs.GetChannel(new string[] { "E", "B", "DB" }); TOFWithError c_ebdbrf1f = (TOFWithError)tcs.GetChannel(new string[] { "E", "B", "DB", "RF1F" }); TOFWithError c_ebdbrf2f = (TOFWithError)tcs.GetChannel(new string[] { "E", "B", "DB", "RF2F" }); TOFWithError c_rf1f = (TOFWithError)tcs.GetChannel(new string[] { "RF1F" }); TOFWithError c_rf2f = (TOFWithError)tcs.GetChannel(new string[] { "RF2F" }); TOFWithError c_erf1f = (TOFWithError)tcs.GetChannel(new string[] { "E", "RF1F" }); TOFWithError c_erf2f = (TOFWithError)tcs.GetChannel(new string[] { "E", "RF2F" }); TOFWithError c_rf1a = (TOFWithError)tcs.GetChannel(new string[] { "RF1A" }); TOFWithError c_rf2a = (TOFWithError)tcs.GetChannel(new string[] { "RF2A" }); TOFWithError c_dbrf1a = (TOFWithError)tcs.GetChannel(new string[] { "DB", "RF1A" }); TOFWithError c_dbrf2a = (TOFWithError)tcs.GetChannel(new string[] { "DB", "RF2A" }); // For SOME blocks there is no LF1 channel (and hence switch states). // To get around this problem I will populate the TOFChannel with "SIG" // It will then be obvious in the analysis when LF1 takes on real values. TOFWithError c_lf1; TOFWithError c_dblf1; if (!tcs.Channels.Contains("LF1")) { c_lf1 = c_sig; c_dblf1 = c_sig; } else { c_lf1 = (TOFWithError)tcs.GetChannel(new string[] { "LF1" }); c_dblf1 = (TOFWithError)tcs.GetChannel(new string[] { "DB", "LF1" }); } // Work out the terms for the full, corrected edm. TOFWithError terms = c_eb * c_db - c_edb * c_b + c_bdb * c_e - c_ebdb * c_sig + c_erf1f * c_bdbrf1f + c_erf2f * c_bdbrf2f - c_brf1f * c_edbrf1f - c_brf2f * c_edbrf2f - c_ebdbrf1f * c_rf1f - c_ebdbrf2f * c_rf2f ; TOFWithError preDenominator = c_db * c_db - c_edb * c_edb + c_bdb * c_bdb - c_ebdb * c_ebdb + c_bdbrf1f * c_bdbrf1f + c_bdbrf2f * c_bdbrf2f - c_edbrf1f * c_edbrf1f - c_edbrf2f * c_edbrf2f + c_ebdbrf1f * c_ebdbrf1f + c_ebdbrf2f * c_ebdbrf2f ; // Work out terms for corrected edm (no rf channels) TOFWithError termsNoRf = c_eb * c_db - c_edb * c_b + c_bdb * c_e + c_ebdb * c_sig; TOFWithError preDenominatorNoRf = c_db * c_db - c_edb * c_edb + c_bdb * c_bdb - c_ebdb * c_ebdb; // it's important when working out the non-linear channel // combinations to always keep them dimensionless. If you // don't you'll run into trouble with integral vs. average // signal. TOFWithError edmDB = c_eb / c_db; tcs.AddChannel(new string[] { "EDMDB" }, edmDB); // The corrected edm channel. This should be proportional to the edm phase. TOFWithError edmCorrDB = terms / preDenominator; tcs.AddChannel(new string[] { "EDMCORRDB" }, edmCorrDB); // It's useful to have an estimate of the size of the correction. Here // we return the difference between the corrected edm channel and the // naive guess, edmDB. TOFWithError correctionDB = edmCorrDB - edmDB; tcs.AddChannel(new string[] { "CORRDB" }, correctionDB); // The "old" correction that just corrects for the E-correlated amplitude change. // This is included in the dblocks for debugging purposes. TOFWithError correctionDB_old = (c_edb * c_b) / (c_db * c_db); tcs.AddChannel(new string[] { "CORRDB_OLD" }, correctionDB_old); TOFWithError edmCorrDB_old = edmDB - correctionDB_old; tcs.AddChannel(new string[] { "EDMCORRDB_OLD" }, edmCorrDB_old); // The "no rf" correction that just corrects for the E/B-correlated amplitude change. // This is included in the dblocks for debugging purposes. TOFWithError edmCorrDB_norf = termsNoRf / preDenominatorNoRf; tcs.AddChannel(new string[] { "EDMCORRDB_NORF" }, edmCorrDB_norf); TOFWithError correctionDB_norf = edmCorrDB_norf - edmDB; tcs.AddChannel(new string[] { "CORRDB_NORF" }, correctionDB_norf); // Normalised RFxF channels. TOFWithError rf1fDB = c_rf1f / c_db; tcs.AddChannel(new string[] { "RF1FDB" }, rf1fDB); TOFWithError rf2fDB = c_rf2f / c_db; tcs.AddChannel(new string[] { "RF2FDB" }, rf2fDB); // And RFxF.DB channels, again normalised to DB. The naming of these channels is quite // unfortunate, but it's just tough. TOFWithError rf1fDBDB = c_dbrf1f / c_db; tcs.AddChannel(new string[] { "RF1FDBDB" }, rf1fDBDB); TOFWithError rf2fDBDB = c_dbrf2f / c_db; tcs.AddChannel(new string[] { "RF2FDBDB" }, rf2fDBDB); // Normalised RFxAchannels. TOFWithError rf1aDB = c_rf1a / c_db; tcs.AddChannel(new string[] { "RF1ADB" }, rf1aDB); TOFWithError rf2aDB = c_rf2a / c_db; tcs.AddChannel(new string[] { "RF2ADB" }, rf2aDB); // And RFxA.DB channels, again normalised to DB. The naming of these channels is quite // unfortunate, but it's just tough. TOFWithError rf1aDBDB = c_dbrf1a / c_db; tcs.AddChannel(new string[] { "RF1ADBDB" }, rf1aDBDB); TOFWithError rf2aDBDB = c_dbrf2a / c_db; tcs.AddChannel(new string[] { "RF2ADBDB" }, rf2aDBDB); // the E.RFxF channels, normalized to DB TOFWithError erf1fDB = c_erf1f / c_db; tcs.AddChannel(new string[] { "ERF1FDB" }, erf1fDB); TOFWithError erf2fDB = c_erf2f / c_db; tcs.AddChannel(new string[] { "ERF2FDB" }, erf2fDB); // the E.RFxF.DB channels, normalized to DB, again dodgy naming convention. TOFWithError erf1fDBDB = c_edbrf1f / c_db; tcs.AddChannel(new string[] { "ERF1FDBDB" }, erf1fDBDB); TOFWithError erf2fDBDB = c_edbrf2f / c_db; tcs.AddChannel(new string[] { "ERF2FDBDB" }, erf2fDBDB); // the LF1 channel, normalized to DB TOFWithError lf1DB = c_lf1 / c_db; tcs.AddChannel(new string[] { "LF1DB" }, lf1DB); TOFWithError lf1DBDB = c_dblf1 / c_db; tcs.AddChannel(new string[] { "LF1DBDB" }, lf1DBDB); TOFWithError bDB = c_b / c_db; tcs.AddChannel(new string[] { "BDB" }, bDB); // we also need to extract the rf-step induced phase shifts. These come out in the // B.RFxF channels, but like the edm, need to be corrected. //// Work out the terms //TOFWithError brf1fCorrectionTerms = c_eb * c_db // - c_edb * c_b + c_bdb * c_e - c_ebdb * c_sig // + c_erf1f * c_bdbrf1f + c_erf2f * c_bdbrf2f // - c_brf1f * c_edbrf1f - c_brf2f * c_edbrf2f // - c_ebdbrf1f * c_rf1f - c_ebdbrf2f * c_rf2f // ; //TOFWithError brf1fPreDenominator = c_db * c_db // - c_edb * c_edb + c_bdb * c_bdb - c_ebdb * c_ebdb // + c_bdbrf1f * c_bdbrf1f + c_bdbrf2f * c_bdbrf2f // - c_edbrf1f * c_edbrf1f - c_edbrf2f * c_edbrf2f // + c_ebdbrf1f * c_ebdbrf1f + c_ebdbrf2f * c_ebdbrf2f // ; TOFWithError brf1fCorrDB = (c_brf1f / c_db) - ((c_b * c_dbrf1f) / (c_db * c_db)); tcs.AddChannel(new string[] { "BRF1FCORRDB" }, brf1fCorrDB); TOFWithError brf2fCorrDB = (c_brf2f / c_db) - ((c_b * c_dbrf2f) / (c_db * c_db)); tcs.AddChannel(new string[] { "BRF2FCORRDB" }, brf2fCorrDB); //Some extra channels for various shot noise calculations, these are a bit weird tcs.AddChannel(new string[] { "SIGNL" }, c_sig); tcs.AddChannel(new string[] { "ONEOVERDB" }, 1 / c_db); TOFWithError dbSigNL = c_db / c_sig; tcs.AddChannel(new string[] { "DBSIG" }, dbSigNL); TOFWithError dbdbSigSigNL = dbSigNL * dbSigNL; tcs.AddChannel(new string[] { "DBDBSIGSIG" }, dbdbSigSigNL); TOFWithError SigdbdbNL = c_sig / (c_db * c_db); tcs.AddChannel(new string[] { "SIGDBDB" }, SigdbdbNL); return(tcsWithSpecialValues); }
public DemodulatedBlock DemodulateBlock(Block b, DemodulationConfig demodulationConfig, int[] tofChannelsToAnalyse) { if (!b.detectors.Contains("asymmetry")) { b.AddDetectorsToBlock(); } int blockLength = b.Points.Count; DemodulatedBlock db = new DemodulatedBlock(b.TimeStamp, b.Config, demodulationConfig); Dictionary <string, double[]> pointDetectorData = new Dictionary <string, double[]>(); foreach (string d in demodulationConfig.GatedDetectors) { pointDetectorData.Add(d, GetGatedDetectorData(b, d, demodulationConfig.Gates.GetGate(d))); } foreach (string d in demodulationConfig.PointDetectors) { pointDetectorData.Add(d, GetPointDetectorData(b, d)); } Dictionary <string, TOF[]> tofDetectorData = new Dictionary <string, TOF[]>(); foreach (string d in demodulationConfig.TOFDetectors) { tofDetectorData.Add(d, GetTOFDetectorData(b, d)); } // ----Demodulate channels---- // --Build list of modulations-- List <Modulation> modulations = GetModulations(b); // --Work out switch state for each point-- List <uint> switchStates = GetSwitchStates(modulations); // --Calculate state signs for each analysis channel-- // The first index selects the analysis channel, the second the switchState int numStates = (int)Math.Pow(2, modulations.Count); int[,] stateSigns = GetStateSigns(numStates); // --This is done for each point/gated detector-- foreach (string d in pointDetectorData.Keys) { int detectorIndex = b.detectors.IndexOf(d); // We obtain one Channel Set for each detector ChannelSet <PointWithError> channelSet = new ChannelSet <PointWithError>(); // Detector calibration double calibration = ((TOF)((EDMPoint)b.Points[0]).Shot.TOFs[detectorIndex]).Calibration; // Divide points into bins depending on switch state List <List <double> > statePoints = new List <List <double> >(numStates); for (int i = 0; i < numStates; i++) { statePoints.Add(new List <double>(blockLength / numStates)); } for (int i = 0; i < blockLength; i++) { statePoints[(int)switchStates[i]].Add(pointDetectorData[b.detectors[detectorIndex]][i]); } int subLength = blockLength / numStates; // For each analysis channel, calculate the mean and standard error, then add to ChannelSet for (int channel = 0; channel < numStates; channel++) { RunningStatistics stats = new RunningStatistics(); for (int subIndex = 0; subIndex < subLength; subIndex++) { double onVal = 0.0; double offVal = 0.0; for (int i = 0; i < numStates; i++) { if (stateSigns[channel, i] == 1) { onVal += statePoints[i][subIndex]; } else { offVal += statePoints[i][subIndex]; } } onVal /= numStates; offVal /= numStates; stats.Push(onVal - offVal); } PointWithError pointWithError = new PointWithError() { Value = stats.Mean, Error = stats.StandardErrorOfSampleMean }; // add the channel to the ChannelSet List <string> usedSwitches = new List <string>(); for (int i = 0; i < modulations.Count; i++) { if ((channel & (1 << i)) != 0) { usedSwitches.Add(modulations[i].Name); } } string[] channelName = usedSwitches.ToArray(); // the SIG channel has a special name if (channel == 0) { channelName = new string[] { "SIG" } } ; channelSet.AddChannel(channelName, pointWithError); } // Add the ChannelSet to the demodulated block db.AddDetector(b.detectors[detectorIndex], calibration, channelSet); } // --This is done for each TOF detector-- foreach (string d in tofDetectorData.Keys) { int detectorIndex = b.detectors.IndexOf(d); // We obtain one Channel Set for each detector ChannelSet <TOFWithError> channelSet = new ChannelSet <TOFWithError>(); // Detector calibration double calibration = ((TOF)((EDMPoint)b.Points[0]).Shot.TOFs[detectorIndex]).Calibration; // Divide TOFs into bins depending on switch state List <List <TOF> > statePoints = new List <List <TOF> >(numStates); for (int i = 0; i < numStates; i++) { statePoints.Add(new List <TOF>(blockLength / numStates)); } for (int i = 0; i < blockLength; i++) { statePoints[(int)switchStates[i]].Add(tofDetectorData[b.detectors[detectorIndex]][i]); } int subLength = blockLength / numStates; // For each analysis channel, calculate the mean and standard error, then add to ChannelSet foreach (int channel in tofChannelsToAnalyse) { TOFAccumulator tofAccumulator = new TOFAccumulator(); for (int subIndex = 0; subIndex < subLength; subIndex++) { TOF onTOF = new TOF(); TOF offTOF = new TOF(); for (int i = 0; i < numStates; i++) { if (stateSigns[channel, i] == 1) { onTOF += statePoints[i][subIndex]; } else { offTOF += statePoints[i][subIndex]; } } onTOF /= numStates; offTOF /= numStates; tofAccumulator.Add(onTOF - offTOF); } // add the channel to the ChannelSet List <string> usedSwitches = new List <string>(); for (int i = 0; i < modulations.Count; i++) { if ((channel & (1 << i)) != 0) { usedSwitches.Add(modulations[i].Name); } } string[] channelName = usedSwitches.ToArray(); // the SIG channel has a special name if (channel == 0) { channelName = new string[] { "SIG" } } ; channelSet.AddChannel(channelName, tofAccumulator.GetResult()); } // If the detector is a molecule detector, add the special channels if (MOLECULE_DETECTORS.Contains(d)) { channelSet = AppendChannelSetWithSpecialValues(channelSet); } // Add the ChannelSet to the demodulated block db.AddDetector(d, calibration, channelSet); } return(db); }
public void AddDetector(string detector, double calibration, ChannelSet <TOFWithError> channelSet) { TOFChannelSetDictionary.Add(detector, channelSet); DetectorCalibrations.Add(detector, calibration); }