public void ConstructAsymmetryShotNoiseTOF() { for (int i = 0; i < points.Count; i++) { EDMPoint point = (EDMPoint)points[i]; Shot shot = point.Shot; TOF bottomScaled = (TOF)shot.TOFs[detectors.IndexOf("bottomProbeScaled")]; TOF top = (TOF)shot.TOFs[detectors.IndexOf("topProbeNoBackground")]; // Multiply TOFs by their calibrations bottomScaled *= bottomScaled.Calibration; top *= top.Calibration; // Need the total signal TOF for later calculations TOF total = bottomScaled + top; // Get background counts double topLaserBackground = (double)point.SinglePointData["TopDetectorBackground"] * bottomScaled.Calibration; double bottomLaserBackground = (double)point.SinglePointData["BottomDetectorBackground"] * top.Calibration; // Calculate the shot noise variance in the asymmetry detector TOF asymmetryVariance = bottomScaled * bottomScaled * top * 4.0 + bottomScaled * top * top * 4.0 + top * top * bottomLaserBackground * 8.0 + bottomScaled * bottomScaled * topLaserBackground * 8.0; asymmetryVariance /= total * total * total * total; shot.TOFs.Add(asymmetryVariance); } detectors.Add("asymmetryShotNoiseVariance"); }
//slight variant which can be useful for debugging public static Shot GetFakeShot(int gateStart, int gateLength, int clockPeriod, double intensity, int numberOfDetectors, double scanParameter) { Random rng = new Random(); // generate some fake data double[] detectorOnData = new double[gateLength]; double newRand = rng.NextDouble(); double centre = gateLength / 2 + 10 * scanParameter; for (int i = 0; i < gateLength; i++) { detectorOnData[i] = (5 * rng.NextDouble()) + 5 * intensity * Math.Exp(-Math.Pow((i - centre), 2) / (0.9 * gateLength)); } TOF tofOn = new TOF(); tofOn.Data = detectorOnData; tofOn.GateStartTime = gateStart; tofOn.ClockPeriod = clockPeriod; tofOn.Calibration = 1; Shot sOn = new Shot(); for (int j = 0; j < numberOfDetectors; j++) { sOn.TOFs.Add(tofOn); } return(sOn); }
public void GotPoint(int point, EDMPoint p) { // store the leakage measurements ready for the graph update northLeakages[leakageIndex] = (double)p.SinglePointData["NorthCurrent"]; southLeakages[leakageIndex] = (double)p.SinglePointData["SouthCurrent"]; leakageIndex++; if ((point % UPDATE_EVERY) == 0) { Shot data = p.Shot; mainWindow.TankLevel = point; TOF tof = (TOF)data.TOFs[0]; mainWindow.PlotTOF(0, tof.Data, tof.GateStartTime, tof.ClockPeriod); tof = (TOF)data.TOFs[1]; mainWindow.PlotTOF(1, tof.Data, tof.GateStartTime, tof.ClockPeriod); tof = (TOF)data.TOFs[2]; mainWindow.PlotTOF(2, tof.Data, tof.GateStartTime, tof.ClockPeriod); tof = (TOF)data.TOFs[5]; mainWindow.PlotTOF(3, tof.Data, tof.GateStartTime, tof.ClockPeriod); // update the leakage graphs mainWindow.AppendLeakageMeasurement(new double[] { northLeakages[0] }, new double[] { southLeakages[0] }); leakageIndex = 0; } }
public void Add(TOF t) { if (!initialised) { // the first TOF to be added defines the parameters gateStartTime = t.GateStartTime; clockPeriod = t.ClockPeriod; calibration = t.Calibration; stats = new RunningStatistics[t.Length]; for (int i = 0; i < Length; i++) { stats[i] = new RunningStatistics(); } initialised = true; } // add the TOF data - very minimal error checking: just check the lengths if (t.Length == Length) { for (int i = 0; i < Length; i++) { stats[i].Push(t.Data[i]); } } else { throw new TOFAccumulatorException(); } }
public TOF GetAverageTOF(int index) { TOF temp = new TOF(); for (int i = 0 ; i < points.Count ; i++) temp += (TOF)((EDMPoint)points[i]).Shot.TOFs[index]; return temp /(points.Count); }
public void NewScanLoaded() { window.ClearAll(); Scan averageScan = Controller.GetController().DataStore.AverageScan; if (averageScan.Points.Count == 0) { return; } startSpectrumGate = averageScan.MinimumScanParameter; endSpectrumGate = averageScan.MaximumScanParameter; TOF tof = ((TOF)((Shot)((ScanPoint)averageScan.Points[0]).OnShots[0]).TOFs[0]); startTOFGate = tof.GateStartTime; endTOFGate = tof.GateStartTime + tof.ClockPeriod * tof.Length; UpdateTOFAveragePlots(); UpdatePMTAveragePlots(); window.SpectrumGate = new PlotParameters(startSpectrumGate, endSpectrumGate /*, averageScan.Points.Count*/); window.TOFGate = new PlotParameters(startTOFGate, endTOFGate); if (spectrumFitMode == FitMode.Average) { FitAndPlotSpectrum(averageScan); } if (tofFitMode == FitMode.Average) { FitAverageTOF(); } }
// NOTE: this function is rendered somewhat obsolete by the BlockTOFDemodulator. // This function takes a list of switches, defining an analysis channel, and gives the // average TOF for that analysis channel's positively contributing TOFs and the same for // the negative contributors. Note that this definition may or may not line up with how // the analysis channels are defined (they may differ by a sign, which might depend on // the number of switches in the channel). public TOF[] GetSwitchTOFs(string[] switches, int index) { TOF[] tofs = new TOF[2]; // calculate the state of the channel for each point in the block int numSwitches = switches.Length; int waveformLength = config.GetModulationByName(switches[0]).Waveform.Length; List<bool[]> switchBits = new List<bool[]>(); foreach (string s in switches) switchBits.Add(config.GetModulationByName(s).Waveform.Bits); List<bool> channelStates = new List<bool>(); for (int point = 0; point < waveformLength; point++) { bool channelState = false; for (int i = 0; i < numSwitches; i++) { channelState = channelState ^ switchBits[i][point]; } channelStates.Add(channelState); } // build the "on" and "off" average TOFs TOF tOn = new TOF(); TOF tOff = new TOF(); for (int i = 0; i < waveformLength; i++) { if (channelStates[i]) tOn += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); else tOff += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); } tOn /= (waveformLength / 2); tOff /= (waveformLength / 2); tofs[0] = tOn; tofs[1] = tOff; return tofs; }
private TOF[] GetTOFDetectorData(Block b, string detector) { int detectorIndex = b.detectors.IndexOf(detector); TOF[] tofList = new TOF[b.Points.Count]; for (int i = 0; i < b.Points.Count; i++) { tofList[i] = (TOF)((EDMPoint)b.Points[i]).Shot.TOFs[detectorIndex]; } return(tofList); }
public TOF GetAverageTOF(int index) { TOF temp = new TOF(); for (int i = 0; i < points.Count; i++) { temp += (TOF)((EDMPoint)points[i]).Shot.TOFs[index]; } return(temp / (points.Count)); }
// this function subtracts the background off a TOF signal // the background is taken as the mean of a background array of points public void SubtractBackgroundFromProbeDetectorTOFs() { for (int i = 0; i < points.Count; i++) { EDMPoint point = (EDMPoint)points[i]; Shot shot = point.Shot; TOF t = (TOF)shot.TOFs[0]; double bg = t.GatedMeanAndUncertainty(2800, 2900)[0]; TOF bgSubtracted = t - bg; // if value if negative, set to zero for (int j = 0; j < bgSubtracted.Length; j++) { if (bgSubtracted.Data[j] < 0) { bgSubtracted.Data[j] = 0.0; } } bgSubtracted.Calibration = t.Calibration; shot.TOFs.Add(bgSubtracted); point.SinglePointData.Add("BottomDetectorBackground", bg); } // give these data a name detectors.Add("bottomProbeNoBackground"); for (int i = 0; i < points.Count; i++) { EDMPoint point = (EDMPoint)points[i]; Shot shot = point.Shot; TOF t = (TOF)shot.TOFs[1]; double bg = t.GatedMeanAndUncertainty(3200, 3300)[0]; TOF bgSubtracted = t - bg; // if value if negative, set to zero for (int j = 0; j < bgSubtracted.Length; j++) { if (bgSubtracted.Data[j] < 0) { bgSubtracted.Data[j] = 0.0; } } bgSubtracted.Calibration = t.Calibration; shot.TOFs.Add(bgSubtracted); point.SinglePointData.Add("TopDetectorBackground", bg); } // give these data a name detectors.Add("topProbeNoBackground"); }
// this function adds a new set of detector data to the block, constructed // by calculating the asymmetry of the top and bottom detectors (which must // be scaled first) public void ConstructAsymmetryTOF() { for (int i = 0; i < points.Count; i++) { Shot shot = ((EDMPoint)points[i]).Shot; int bottomScaledIndex = detectors.IndexOf("bottomProbeScaled"); int topIndex = detectors.IndexOf("topProbeNoBackground"); TOF asymmetry = ((TOF)shot.TOFs[bottomScaledIndex] - (TOF)shot.TOFs[topIndex]) / ((TOF)shot.TOFs[bottomScaledIndex] + (TOF)shot.TOFs[topIndex]); asymmetry.Calibration = 1; shot.TOFs.Add(asymmetry); } // give these data a name detectors.Add("asymmetry"); }
// this function adds a new set of detector data to the block, constructed // by normalising the PMT data to the norm data. The normalisation is done // by dividing the PMT tofs through by the integrated norm data. The integration // is done according to the provided GatedDetectorExtractSpec. //public void Normalise(GatedDetectorExtractSpec normGate) //{ // GatedDetectorData normData = GatedDetectorData.ExtractFromBlock(this, normGate); // double averageNorm = 0; // foreach (double val in normData.PointValues) averageNorm += val; // averageNorm /= normData.PointValues.Count; // for (int i = 0; i < points.Count; i++) // { // Shot shot = ((EDMPoint)points[i]).Shot; // TOF normedTOF = ((TOF)shot.TOFs[0]) / (normData.PointValues[i] * (1 / averageNorm)); // shot.TOFs.Add(normedTOF); // } // // give these data a name // detectors.Add("topNormed"); //} //// this function adds a new set of detector data to the block, constructed //// by calculating the asymmetry of the top and bottom detectors The integration //// is done according to the provided GatedDetectorExtractSpec. //public void Normalise(GatedDetectorExtractSpec normGate) //{ // GatedDetectorData normData = GatedDetectorData.ExtractFromBlock(this, normGate); // for (int i = 0; i < points.Count; i++) // { // Shot shot = ((EDMPoint)points[i]).Shot; // TOF normedTOF = ((TOF)shot.TOFs[0]) / (normData.PointValues[i] ); // shot.TOFs.Add(normedTOF); // } // // give these data a name // detectors.Add("topNormed"); //} // this function takes some of the single point data and adds it to the block shots as TOFs // with one data point in them. This allows us to use the same code to break all of the data // into channels. public void TOFuliseSinglePointData(string[] channelsToTOFulise) { foreach (string spv in channelsToTOFulise) { for (int i = 0; i < points.Count; i++) { EDMPoint point = (EDMPoint)points[i]; Shot shot = point.Shot; TOF spvTOF = new TOF((double)point.SinglePointData[spv]); shot.TOFs.Add(spvTOF); } // give these data a name detectors.Add(spv); } }
// This method is called by the GUI thread once the form has // loaded and the UI is ready. internal void UIInitialise() { // put the version number in the title bar to avoid confusion! Version version = Assembly.GetEntryAssembly().GetName().Version; mainWindow.Text += " " + version.ToString(); // This will load the shared code assembly so that we can get its // version number and display that as well. TOF t = new TOF(); Version sharedCodeVersion = Assembly.GetAssembly(t.GetType()).GetName().Version; mainWindow.Text += " (" + sharedCodeVersion.ToString() + ")"; // start the status monitor statusMonitorTimer = new System.Threading.Timer(new TimerCallback(UpdateStatusMonitor), null, 500, 500); }
// this function scales up the bottom detector to match the top public void CreateScaledBottomProbe() { for (int i = 0; i < points.Count; i++) { Shot shot = ((EDMPoint)points[i]).Shot; int bottomIndex = detectors.IndexOf("bottomProbeNoBackground"); int topIndex = detectors.IndexOf("topProbeNoBackground"); TOF bottomTOF = (TOF)shot.TOFs[bottomIndex]; TOF topTOF = (TOF)shot.TOFs[topIndex]; TOF bottomScaled = TOF.ScaleTOFInTimeToMatchAnotherTOF(bottomTOF, topTOF, kDetectorDistanceRatio); bottomScaled.Calibration = bottomTOF.Calibration; shot.TOFs.Add(bottomScaled); } // give these data a name detectors.Add("bottomProbeScaled"); }
// NOTE: this function is rendered somewhat obsolete by the BlockTOFDemodulator. // This function takes a list of switches, defining an analysis channel, and gives the // average TOF for that analysis channel's positively contributing TOFs and the same for // the negative contributors. Note that this definition may or may not line up with how // the analysis channels are defined (they may differ by a sign, which might depend on // the number of switches in the channel). public TOF[] GetSwitchTOFs(string[] switches, int index) { TOF[] tofs = new TOF[2]; // calculate the state of the channel for each point in the block int numSwitches = switches.Length; int waveformLength = config.GetModulationByName(switches[0]).Waveform.Length; List <bool[]> switchBits = new List <bool[]>(); foreach (string s in switches) { switchBits.Add(config.GetModulationByName(s).Waveform.Bits); } List <bool> channelStates = new List <bool>(); for (int point = 0; point < waveformLength; point++) { bool channelState = false; for (int i = 0; i < numSwitches; i++) { channelState = channelState ^ switchBits[i][point]; } channelStates.Add(channelState); } // build the "on" and "off" average TOFs TOF tOn = new TOF(); TOF tOff = new TOF(); for (int i = 0; i < waveformLength; i++) { if (channelStates[i]) { tOn += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); } else { tOff += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); } } tOn /= (waveformLength / 2); tOff /= (waveformLength / 2); tofs[0] = tOn; tofs[1] = tOff; return(tofs); }
private void UpdateTOFAveragePlots() { Scan averageScan = Controller.GetController().DataStore.AverageScan; if (averageScan.Points.Count == 0) { return; } TOF tof = (TOF)((ArrayList)averageScan.GetGatedAverageOnShot(startSpectrumGate, endSpectrumGate).TOFs)[0]; window.PlotAverageOnTOF(tof); Profile p = Controller.GetController().ProfileManager.CurrentProfile; if (p != null && (bool)p.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { window.PlotAverageOffTOF( (TOF)averageScan.GetGatedAverageOffShot(startSpectrumGate, endSpectrumGate).TOFs[0]); } }
// this function adds a new set of detector data to the block, constructed // by normalising the PMT data to the norm data. The normalisation is done // by dividing the PMT tofs through by the integrated norm data. The integration // is done according to the provided GatedDetectorExtractSpec. public void Normalise(GatedDetectorExtractSpec normGate) { GatedDetectorData normData = GatedDetectorData.ExtractFromBlock(this, normGate); double averageNorm = 0; foreach (double val in normData.PointValues) { averageNorm += val; } averageNorm /= normData.PointValues.Count; for (int i = 0; i < points.Count; i++) { Shot shot = ((EDMPoint)points[i]).Shot; TOF normedTOF = ((TOF)shot.TOFs[0]) / (normData.PointValues[i] * (1 / averageNorm)); shot.TOFs.Add(normedTOF); } // give these data a name detectors.Add("topNormed"); }
// TOF-ulise all the single point detectors public void TOFuliseSinglePointData() { EDMPoint point = (EDMPoint)points[0]; string[] pointDetectors = new string[point.SinglePointData.Keys.Count]; point.SinglePointData.Keys.CopyTo(pointDetectors, 0); foreach (string spv in pointDetectors) { if (spv != "dummy") // the hashtable has "dummy" as the default entry, but we don't want it { for (int i = 0; i < points.Count; i++) { EDMPoint pt = (EDMPoint)points[i]; Shot shot = pt.Shot; TOF spvTOF = new TOF((double)pt.SinglePointData[spv]); shot.TOFs.Add(spvTOF); } // give these data a name detectors.Add(spv); } } }
private double[] FitSpectrum(Scan s) { double[] xDat = s.ScanParameterArray; double scanStart = xDat[0]; double scanEnd = xDat[xDat.Length - 1]; TOF avTof = (TOF)s.GetGatedAverageOnShot(scanStart, scanEnd).TOFs[0]; double gateStart = avTof.GateStartTime; double gateEnd = avTof.GateStartTime + avTof.Length * avTof.ClockPeriod; double[] yDat = s.GetTOFOnIntegralArray(0, gateStart, gateEnd); fitter.Fit(xDat, yDat, fitter.SuggestParameters(xDat, yDat, scanStart, scanEnd)); string report = fitter.ParameterReport; string[] tokens = report.Split(' '); double[] fitresult = new double[4]; for (int i = 0; i < fitresult.Length; i++) { fitresult[i] = Convert.ToDouble(tokens[2 * i + 1]); } return(fitresult); }
public void HandleDataPoint(DataEventArgs e) { Profile currentProfile = Controller.GetController().ProfileManager.CurrentProfile; // update the TOF graphs if (currentProfile.GUIConfig.average) { if (shotCounter % currentProfile.GUIConfig.updateTOFsEvery == 0) { if (avOnTof != null) { window.PlotOnTOF(avOnTof / onAverages); } avOnTof = (TOF)e.point.AverageOnShot.TOFs[0]; onAverages = 1; if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { if (avOffTof != null) { window.PlotOffTOF(avOffTof / offAverages); } avOffTof = (TOF)e.point.AverageOffShot.TOFs[0]; offAverages = 1; } } else // do the averaging { if (avOnTof != null) { avOnTof = avOnTof + ((TOF)e.point.AverageOnShot.TOFs[0]); onAverages++; } if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"] && avOffTof != null) { avOffTof = avOffTof + ((TOF)e.point.AverageOffShot.TOFs[0]); offAverages++; } } } else // if not averaging { if (shotCounter % currentProfile.GUIConfig.updateTOFsEvery == 0) { window.PlotOnTOF((TOF)e.point.AverageOnShot.TOFs[0]); if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { window.PlotOffTOF((TOF)e.point.AverageOffShot.TOFs[0]); } } } // update the spectra pointsToPlot.Points.Add(e.point); if (shotCounter % currentProfile.GUIConfig.updateSpectraEvery == 0) { double[] onPoints = pointsToPlot.GetTOFOnIntegralArray(0, startTOFGate, endTOFGate); window.AppendToPMTOn(pointsToPlot.ScanParameterArray, onPoints); if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { double[] offPoints = pointsToPlot.GetTOFOffIntegralArray(0, startTOFGate, endTOFGate); window.AppendToPMTOff(pointsToPlot.ScanParameterArray, offPoints); window.AppendToDifference(pointsToPlot.ScanParameterArray, pointsToPlot.GetDifferenceIntegralArray(0, startTOFGate, endTOFGate)); calculateNewGatedAverages(offPoints[offPoints.Length - 1], onPoints[onPoints.Length - 1]); updateGatedAverageTextBoxes(); } // update the spectrum fit if in shot mode. if (spectrumFitMode == FitMode.Shot) { Scan currentScan = Controller.GetController().DataStore.CurrentScan; if (currentScan.Points.Count > 10) { FitAndPlotSpectrum(currentScan); } } pointsToPlot.Points.Clear(); } shotCounter++; }
public void PlotOnTOF(TOF t) { PlotY(tofGraph, tofOnPlot, t.GateStartTime, t.ClockPeriod, t.Data); }
// this is the method that actually takes the data. It is called by Start() and shouldn't // be called directly public void Acquire() { // lock onto something that the front end can see Monitor.Enter(MonitorLockObject); scanMaster = new ScanMaster.Controller(); phaseLock = new EDMPhaseLock.MainForm(); hardwareController = new EDMHardwareControl.Controller(); // map modulations to physical channels MapChannels(); // map the analog inputs MapAnalogInputs(); Block b = new Block(); b.Config = config; b.SetTimeStamp(); foreach (ScannedAnalogInput channel in inputs.Channels) { b.detectors.Add(channel.Channel.Name); } try { // get things going AcquisitionStarting(); // enter the main loop for (int point = 0; point < (int)config.Settings["numberOfPoints"]; point++) { // set the switch states and impose the appropriate wait times ThrowSwitches(point); // take a point Shot s; EDMPoint p; if (Environs.Debug) { // just stuff a made up shot in //Thread.Sleep(10); s = DataFaker.GetFakeShot(1900, 50, 10, 3, 3); ((TOF)s.TOFs[0]).Calibration = ((ScannedAnalogInput)inputs.Channels[0]).Calibration; p = new EDMPoint(); p.Shot = s; //Thread.Sleep(20); } else { // everything should be ready now so start the analog // input task (it will wait for a trigger) inputTask.Start(); // get the raw data double[,] analogData = inputReader.ReadMultiSample(inputs.GateLength); inputTask.Stop(); // extract the data for each scanned channel and put it in a TOF s = new Shot(); for (int i = 0; i < inputs.Channels.Count; i++) { // extract the raw data double[] rawData = new double[inputs.GateLength]; for (int q = 0; q < inputs.GateLength; q++) { rawData[q] = analogData[i, q]; } ScannedAnalogInput ipt = (ScannedAnalogInput)inputs.Channels[i]; // reduce the data double[] data = ipt.Reduce(rawData); TOF t = new TOF(); t.Calibration = ipt.Calibration; // the 1000000 is because clock period is in microseconds; t.ClockPeriod = 1000000 / ipt.CalculateClockRate(inputs.RawSampleRate); t.GateStartTime = inputs.GateStartTime; // this is a bit confusing. The chop is measured in points, so the gate // has to be adjusted by the number of points times the clock period! if (ipt.ReductionMode == DataReductionMode.Chop) { t.GateStartTime += (ipt.ChopStart * t.ClockPeriod); } t.Data = data; // the 1000000 is because clock period is in microseconds; t.ClockPeriod = 1000000 / ipt.CalculateClockRate(inputs.RawSampleRate); s.TOFs.Add(t); } p = new EDMPoint(); p.Shot = s; } // do the "SinglePointData" (i.e. things that are measured once per point) // We'll save the leakage monitor until right at the end. // keep an eye on what the phase lock is doing p.SinglePointData.Add("PhaseLockFrequency", phaseLock.OutputFrequency); p.SinglePointData.Add("PhaseLockError", phaseLock.PhaseError); // scan the analog inputs double[] spd; // fake some data if we're in debug mode if (Environs.Debug) { spd = new double[7]; spd[0] = 1; spd[1] = 2; spd[2] = 3; spd[3] = 4; spd[4] = 5; spd[5] = 6; spd[6] = 7; } else { singlePointInputTask.Start(); spd = singlePointInputReader.ReadSingleSample(); singlePointInputTask.Stop(); } p.SinglePointData.Add("ProbePD", spd[0]); p.SinglePointData.Add("PumpPD", spd[1]); p.SinglePointData.Add("MiniFlux1", spd[2]); p.SinglePointData.Add("MiniFlux2", spd[3]); p.SinglePointData.Add("MiniFlux3", spd[4]); //p.SinglePointData.Add("CplusV", spd[5]); //p.SinglePointData.Add("CminusV", spd[6]); //hardwareController.UpdateVMonitor(); //p.SinglePointData.Add("CplusV", hardwareController.CPlusMonitorVoltage); //hardwareController.UpdateLaserPhotodiodes(); //p.SinglePointData.Add("ProbePD", hardwareController.ProbePDVoltage); //p.SinglePointData.Add("PumpPD", hardwareController.PumpPDVoltage); //hardwareController.UpdateMiniFluxgates(); //p.SinglePointData.Add("MiniFlux1", hardwareController.MiniFlux1Voltage); //p.SinglePointData.Add("MiniFlux2", hardwareController.MiniFlux2Voltage); //p.SinglePointData.Add("MiniFlux3", hardwareController.MiniFlux3Voltage); hardwareController.ReadIMonitor(); p.SinglePointData.Add("NorthCurrent", hardwareController.NorthCurrent); p.SinglePointData.Add("SouthCurrent", hardwareController.SouthCurrent); //hardwareController.UpdatePiMonitor(); //p.SinglePointData.Add("piMonitor", hardwareController.PiFlipMonVoltage); //p.SinglePointData.Add("CminusV", hardwareController.CMinusMonitorVoltage); // Hopefully the leakage monitors will have finished reading by now. // We join them, read out the data, and then launch another asynchronous // acquisition. [If this is the first shot of the block, the leakage monitor // measurement will have been launched in AcquisitionStarting() ]. //hardwareController.WaitForIMonitorAsync(); //p.SinglePointData.Add("NorthCurrent", hardwareController.NorthCurrent); //p.SinglePointData.Add("SouthCurrent", hardwareController.SouthCurrent); //hardwareController.UpdateIMonitorAsync(); // randomise the Ramsey phase // TODO: check whether the .NET rng is good enough // TODO: reference where this number comes from //double d = 2.3814 * (new Random().NextDouble()); //hardwareController.SetScramblerVoltage(d); b.Points.Add(p); // update the front end Controller.GetController().GotPoint(point, p); if (CheckIfStopping()) { // release hardware AcquisitionStopping(); // signal anybody waiting on the lock that we're done Monitor.Pulse(MonitorLockObject); Monitor.Exit(MonitorLockObject); return; } } } catch (Exception e) { // try and stop the experiment gracefully try { AcquisitionStopping(); } catch (Exception) {} // about the best that can be done at this stage Monitor.Pulse(MonitorLockObject); Monitor.Exit(MonitorLockObject); throw e; } AcquisitionStopping(); // hand the new block back to the controller Controller.GetController().AcquisitionFinished(b); // signal anybody waiting on the lock that we're done Monitor.Pulse(MonitorLockObject); Monitor.Exit(MonitorLockObject); }
public void AcquireAndStepTarget() { // lock onto something that the front end can see Monitor.Enter(MonitorLockObject); scanMaster = new ScanMaster.Controller(); phaseLock = new EDMPhaseLock.MainForm(); hardwareController = new EDMHardwareControl.Controller(); // map modulations to physical channels MapChannels(); // map the analog inputs MapAnalogInputs(); Block b = new Block(); b.Config = config; b.SetTimeStamp(); foreach (ScannedAnalogInput channel in inputs.Channels) { b.detectors.Add(channel.Channel.Name); } try { // get things going AcquisitionStarting(); int point = 0; // enter the main loop for (point = 0; point < (int)config.Settings["maximumNumberOfTimesToStepTarget"]; point++) { // take a point Shot s; EDMPoint p; if (Environs.Debug) { // just stuff a made up shot in //Thread.Sleep(10); s = DataFaker.GetFakeShot(1900, 50, 10, 3, 3); ((TOF)s.TOFs[0]).Calibration = ((ScannedAnalogInput)inputs.Channels[0]).Calibration; p = new EDMPoint(); p.Shot = s; //Thread.Sleep(20); } else { // everything should be ready now so start the analog // input task (it will wait for a trigger) inputTask.Start(); // get the raw data double[,] analogData = inputReader.ReadMultiSample(inputs.GateLength); inputTask.Stop(); // extract the data for each scanned channel and put it in a TOF s = new Shot(); for (int i = 0; i < inputs.Channels.Count; i++) { // extract the raw data double[] rawData = new double[inputs.GateLength]; for (int q = 0; q < inputs.GateLength; q++) { rawData[q] = analogData[i, q]; } ScannedAnalogInput ipt = (ScannedAnalogInput)inputs.Channels[i]; // reduce the data double[] data = ipt.Reduce(rawData); TOF t = new TOF(); t.Calibration = ipt.Calibration; // the 1000000 is because clock period is in microseconds; t.ClockPeriod = 1000000 / ipt.CalculateClockRate(inputs.RawSampleRate); t.GateStartTime = inputs.GateStartTime; // this is a bit confusing. The chop is measured in points, so the gate // has to be adjusted by the number of points times the clock period! if (ipt.ReductionMode == DataReductionMode.Chop) { t.GateStartTime += (ipt.ChopStart * t.ClockPeriod); } t.Data = data; // the 1000000 is because clock period is in microseconds; t.ClockPeriod = 1000000 / ipt.CalculateClockRate(inputs.RawSampleRate); s.TOFs.Add(t); } p = new EDMPoint(); p.Shot = s; } // do the "SinglePointData" (i.e. things that are measured once per point) // We'll save the leakage monitor until right at the end. // keep an eye on what the phase lock is doing p.SinglePointData.Add("PhaseLockFrequency", phaseLock.OutputFrequency); p.SinglePointData.Add("PhaseLockError", phaseLock.PhaseError); // scan the analog inputs double[] spd; // fake some data if we're in debug mode if (Environs.Debug) { spd = new double[7]; spd[0] = 1; spd[1] = 2; spd[2] = 3; spd[3] = 4; spd[4] = 5; spd[5] = 6; spd[6] = 7; } else { singlePointInputTask.Start(); spd = singlePointInputReader.ReadSingleSample(); singlePointInputTask.Stop(); } p.SinglePointData.Add("ProbePD", spd[0]); p.SinglePointData.Add("PumpPD", spd[1]); p.SinglePointData.Add("MiniFlux1", spd[2]); p.SinglePointData.Add("MiniFlux2", spd[3]); p.SinglePointData.Add("MiniFlux3", spd[4]); //p.SinglePointData.Add("CplusV", spd[5]); //p.SinglePointData.Add("CminusV", spd[6]); //hardwareController.UpdateVMonitor(); //p.SinglePointData.Add("CplusV", hardwareController.CPlusMonitorVoltage); //hardwareController.UpdateLaserPhotodiodes(); //p.SinglePointData.Add("ProbePD", hardwareController.ProbePDVoltage); //p.SinglePointData.Add("PumpPD", hardwareController.PumpPDVoltage); //hardwareController.UpdateMiniFluxgates(); //p.SinglePointData.Add("MiniFlux1", hardwareController.MiniFlux1Voltage); //p.SinglePointData.Add("MiniFlux2", hardwareController.MiniFlux2Voltage); //p.SinglePointData.Add("MiniFlux3", hardwareController.MiniFlux3Voltage); hardwareController.ReadIMonitor(); p.SinglePointData.Add("NorthCurrent", hardwareController.NorthCurrent); p.SinglePointData.Add("SouthCurrent", hardwareController.SouthCurrent); b.Points.Add(p); // update the front end Controller.GetController().GotPoint(point, p); // Integrate the first toff and stop the sequence if the signal is sufficiently high TOF detectorATOF = new TOF(); detectorATOF = (TOF)s.TOFs[0]; double sig = detectorATOF.Integrate((double)config.Settings["targetStepperGateStartTime"], (double)config.Settings["targetStepperGateEndTime"]); if (sig > (double)config.Settings["minimumSignalToRun"]) { Controller.GetController().TargetHealthy = true; Stop(); point = (int)config.Settings["maximumNumberOfTimesToStepTarget"] + 1; } else { Controller.GetController().TargetHealthy = false; hardwareController.StepTarget(2); } //if (CheckIfStopping()) //{ // release hardware // AcquisitionStopping(); // signal anybody waiting on the lock that we're done // Monitor.Pulse(MonitorLockObject); // Monitor.Exit(MonitorLockObject); // point = (int)config.Settings["maximumNumberOfTimesToStepTarget"]; // return; //} } AcquisitionStopping(); // hand the new block back to the controller Controller.GetController().IntelligentAcquisitionFinished(); // signal anybody waiting on the lock that we're done Monitor.Pulse(MonitorLockObject); Monitor.Exit(MonitorLockObject); } catch (Exception e) { // try and stop the experiment gracefully try { AcquisitionStopping(); } catch (Exception) { } // about the best that can be done at this stage Monitor.Pulse(MonitorLockObject); Monitor.Exit(MonitorLockObject); throw e; } }
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 TOFChannelSet TOFDemodulateBlock(Block b, int detectorIndex, bool allChannels) { // *** demodulate channels *** // ** build the list of modulations ** List <string> modNames = new List <string>(); List <Waveform> modWaveforms = new List <Waveform>(); foreach (AnalogModulation mod in b.Config.AnalogModulations) { modNames.Add(mod.Name); modWaveforms.Add(mod.Waveform); } foreach (DigitalModulation mod in b.Config.DigitalModulations) { modNames.Add(mod.Name); modWaveforms.Add(mod.Waveform); } foreach (TimingModulation mod in b.Config.TimingModulations) { modNames.Add(mod.Name); modWaveforms.Add(mod.Waveform); } // ** work out the switch state for each point ** int blockLength = modWaveforms[0].Length; List <bool[]> wfBits = new List <bool[]>(); foreach (Waveform wf in modWaveforms) { wfBits.Add(wf.Bits); } List <uint> switchStates = new List <uint>(blockLength); for (int i = 0; i < blockLength; i++) { uint switchState = 0; for (int j = 0; j < wfBits.Count; j++) { if (wfBits[j][i]) { switchState += (uint)Math.Pow(2, j); } } switchStates.Add(switchState); } // pre-calculate the state signs for each analysis channel // the first index selects the analysis channel, the second the switchState int numStates = (int)Math.Pow(2, modWaveforms.Count); bool[,] stateSigns = new bool[numStates, numStates]; // make a BlockDemodulator just to use its stateSign code // They should probably share a base class. BlockDemodulator bd = new BlockDemodulator(); for (uint i = 0; i < numStates; i++) { for (uint j = 0; j < numStates; j++) { stateSigns[i, j] = (bd.stateSign(j, i) == 1); } } TOFChannelSet tcs = new TOFChannelSet(); // By setting all channels to false only a limited number of channels are analysed, // namely those required to extract the edm (and the correction term). This speeds // up the execution enormously when the BlockTOFDemodulator is used by the // BlockDemodulator for calculating the non-linear channel combinations. //int[] channelsToAnalyse; List <int> channelsToAnalyse; if (allChannels) { //channelsToAnalyse = new int[numStates]; channelsToAnalyse = new List <int>(); //for (int i = 0; i < numStates; i++) channelsToAnalyse[i] = i; for (int i = 0; i < numStates; i++) { channelsToAnalyse.Add(i); } } else { // just the essential channels - this code is a little awkward because, like // so many bits of the analysis code, it was added long after the original // code was written, and goes against some assumptions that were made back then! int bIndex = modNames.IndexOf("B"); int dbIndex = modNames.IndexOf("DB"); int eIndex = modNames.IndexOf("E"); int rf1fIndex = modNames.IndexOf("RF1F"); int rf2fIndex = modNames.IndexOf("RF2F"); int rf1aIndex = modNames.IndexOf("RF1A"); int rf2aIndex = modNames.IndexOf("RF2A"); int lf1Index = modNames.IndexOf("LF1"); int lf2Index = modNames.IndexOf("LF2"); int bChannel = (1 << bIndex); int dbChannel = (1 << dbIndex); int ebChannel = (1 << eIndex) + (1 << bIndex); int edbChannel = (1 << eIndex) + (1 << dbIndex); int dbrf1fChannel = (1 << dbIndex) + (1 << rf1fIndex); int dbrf2fChannel = (1 << dbIndex) + (1 << rf2fIndex); int brf1fChannel = (1 << bIndex) + (1 << rf1fIndex); int brf2fChannel = (1 << bIndex) + (1 << rf2fIndex); int edbrf1fChannel = (1 << eIndex) + (1 << dbIndex) + (1 << rf1fIndex); int edbrf2fChannel = (1 << eIndex) + (1 << dbIndex) + (1 << rf2fIndex); int ebdbChannel = (1 << eIndex) + (1 << bIndex) + (1 << dbIndex); int rf1fChannel = (1 << rf1fIndex); int rf2fChannel = (1 << rf2fIndex); int erf1fChannel = (1 << eIndex) + (1 << rf1fIndex); int erf2fChannel = (1 << eIndex) + (1 << rf2fIndex); int rf1aChannel = (1 << rf1aIndex); int rf2aChannel = (1 << rf2aIndex); int dbrf1aChannel = (1 << dbIndex) + (1 << rf1aIndex); int dbrf2aChannel = (1 << dbIndex) + (1 << rf2aIndex); int lf1Channel = (1 << lf1Index); int dblf1Channel = (1 << dbIndex) + (1 << lf1Index); channelsToAnalyse = new List <int>() { bChannel, dbChannel, ebChannel, edbChannel, dbrf1fChannel, dbrf2fChannel, brf1fChannel, brf2fChannel, edbrf1fChannel, edbrf2fChannel, ebdbChannel, rf1fChannel, rf2fChannel, erf1fChannel, erf2fChannel, rf1aChannel, rf2aChannel, dbrf1aChannel, dbrf2aChannel, lf1Channel, dblf1Channel, }; if (lf2Index != -1) // Index = -1 if "LF2" not found { int lf2Channel = (1 << lf2Index); channelsToAnalyse.Add(lf2Channel); int dblf2Channel = (1 << dbIndex) + (1 << lf2Index); channelsToAnalyse.Add(dblf2Channel); } //channelsToAnalyse = new int[] { bChannel, dbChannel, ebChannel, edbChannel, dbrf1fChannel, // dbrf2fChannel, brf1fChannel, brf2fChannel, edbrf1fChannel, edbrf2fChannel, ebdbChannel, // rf1fChannel, rf2fChannel, erf1fChannel, erf2fChannel, rf1aChannel, rf2aChannel, dbrf1aChannel, // dbrf2aChannel, lf1Channel, dblf1Channel, lf2Channel, dblf2Channel //}; } foreach (int channel in channelsToAnalyse) { // generate the Channel TOFChannel tc = new TOFChannel(); TOF tOn = new TOF(); TOF tOff = new TOF(); for (int i = 0; i < blockLength; i++) { if (stateSigns[channel, switchStates[i]]) { tOn += ((TOF)((EDMPoint)(b.Points[i])).Shot.TOFs[detectorIndex]); } else { tOff += ((TOF)((EDMPoint)(b.Points[i])).Shot.TOFs[detectorIndex]); } } tOn /= (blockLength / 2); tOff /= (blockLength / 2); tc.On = tOn; tc.Off = tOff; // This "if" is to take care of the case of the "SIG" channel, for which there // is no off TOF. if (tc.Off.Length != 0) { tc.Difference = tc.On - tc.Off; } else { tc.Difference = tc.On; } // add the Channel to the ChannelSet List <string> usedSwitches = new List <string>(); for (int i = 0; i < modNames.Count; i++) { if ((channel & (1 << i)) != 0) { usedSwitches.Add(modNames[i]); } } string[] channelName = usedSwitches.ToArray(); // the SIG channel has a special name if (channel == 0) { channelName = new string[] { "SIG" } } ; tcs.AddChannel(channelName, tc); } // ** add the special channels ** // extract the TOFChannels that we need. TOFChannel c_eb = (TOFChannel)tcs.GetChannel(new string[] { "E", "B" }); TOFChannel c_edb = (TOFChannel)tcs.GetChannel(new string[] { "E", "DB" }); TOFChannel c_dbrf1f = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF1F" }); TOFChannel c_dbrf2f = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF2F" }); TOFChannel c_b = (TOFChannel)tcs.GetChannel(new string[] { "B" }); TOFChannel c_db = (TOFChannel)tcs.GetChannel(new string[] { "DB" }); TOFChannel c_brf1f = (TOFChannel)tcs.GetChannel(new string[] { "B", "RF1F" }); TOFChannel c_brf2f = (TOFChannel)tcs.GetChannel(new string[] { "B", "RF2F" }); TOFChannel c_edbrf1f = (TOFChannel)tcs.GetChannel(new string[] { "E", "DB", "RF1F" }); TOFChannel c_edbrf2f = (TOFChannel)tcs.GetChannel(new string[] { "E", "DB", "RF2F" }); TOFChannel c_ebdb = (TOFChannel)tcs.GetChannel(new string[] { "E", "B", "DB" }); TOFChannel c_rf1f = (TOFChannel)tcs.GetChannel(new string[] { "RF1F" }); TOFChannel c_rf2f = (TOFChannel)tcs.GetChannel(new string[] { "RF2F" }); TOFChannel c_erf1f = (TOFChannel)tcs.GetChannel(new string[] { "E", "RF1F" }); TOFChannel c_erf2f = (TOFChannel)tcs.GetChannel(new string[] { "E", "RF2F" }); TOFChannel c_rf1a = (TOFChannel)tcs.GetChannel(new string[] { "RF1A" }); TOFChannel c_rf2a = (TOFChannel)tcs.GetChannel(new string[] { "RF2A" }); TOFChannel c_dbrf1a = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF1A" }); TOFChannel c_dbrf2a = (TOFChannel)tcs.GetChannel(new string[] { "DB", "RF2A" }); TOFChannel c_lf1 = (TOFChannel)tcs.GetChannel(new string[] { "LF1" }); TOFChannel c_dblf1 = (TOFChannel)tcs.GetChannel(new string[] { "DB", "LF1" }); TOFChannel c_lf2; TOFChannel c_dblf2; if (modNames.IndexOf("LF2") == -1) // Index = -1 if "LF2" not found { TOF tofTemp = new TOF(); TOFChannel tcTemp = new TOFChannel(); // For many blocks there is no LF2 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 LF2 takes on real values. for (int i = 0; i < blockLength; i++) { tofTemp += ((TOF)((EDMPoint)(b.Points[i])).Shot.TOFs[detectorIndex]); } tofTemp /= (blockLength / 2); tcTemp.On = tofTemp; tcTemp.Off = tofTemp; tcTemp.Difference = tofTemp; c_lf2 = tcTemp; c_dblf2 = tcTemp; } else { c_lf2 = (TOFChannel)tcs.GetChannel(new string[] { "LF2" }); c_dblf2 = (TOFChannel)tcs.GetChannel(new string[] { "DB", "LF2" }); } // work out some intermediate terms for the full, corrected edm. The names // refer to the joint power of c_db and c_b in the term. TOFChannel squaredTerms = (((c_db * c_db) - (c_dbrf1f * c_dbrf1f) - (c_dbrf2f * c_dbrf2f)) * c_eb) - (c_b * c_db * c_edb); // this is missing the term /beta c_db c_ebdb at the moment, mainly because // I've no idea what beta should be. TOFChannel linearTerms = (c_b * c_dbrf1f * c_edbrf1f) + (c_b * c_dbrf2f * c_edbrf2f) - (c_db * c_brf1f * c_edbrf1f) - (c_db * c_brf2f * c_edbrf2f); TOFChannel preDenominator = (c_db * c_db * c_db) + (c_dbrf1f * c_edb * c_edbrf1f) + (c_dbrf1f * c_edb * c_edbrf1f) + (c_dbrf2f * c_edb * c_edbrf2f) + (c_dbrf2f * c_edb * c_edbrf2f) - c_db * ( (c_dbrf1f * c_dbrf1f) + (c_dbrf2f * c_dbrf2f) + (c_edb * c_edb) + (c_edbrf1f * c_edbrf1f) + (c_edbrf2f * c_edbrf2f) ); // 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. TOFChannel edmDB = c_eb / c_db; tcs.AddChannel(new string[] { "EDMDB" }, edmDB); // The corrected edm channel. This should be proportional to the edm phase. TOFChannel edmCorrDB = (squaredTerms + linearTerms) / 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. TOFChannel 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. TOFChannel correctionDB_old = (c_edb * c_b) / (c_db * c_db); tcs.AddChannel(new string[] { "CORRDB_OLD" }, correctionDB_old); TOFChannel edmCorrDB_old = edmDB - correctionDB_old; tcs.AddChannel(new string[] { "EDMCORRDB_OLD" }, edmCorrDB_old); // Normalised RFxF channels. TOFChannel rf1fDB = c_rf1f / c_db; tcs.AddChannel(new string[] { "RF1FDB" }, rf1fDB); TOFChannel 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. TOFChannel rf1fDBDB = c_dbrf1f / c_db; tcs.AddChannel(new string[] { "RF1FDBDB" }, rf1fDBDB); TOFChannel rf2fDBDB = c_dbrf2f / c_db; tcs.AddChannel(new string[] { "RF2FDBDB" }, rf2fDBDB); // Normalised RFxAchannels. TOFChannel rf1aDB = c_rf1a / c_db; tcs.AddChannel(new string[] { "RF1ADB" }, rf1aDB); TOFChannel 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. TOFChannel rf1aDBDB = c_dbrf1a / c_db; tcs.AddChannel(new string[] { "RF1ADBDB" }, rf1aDBDB); TOFChannel rf2aDBDB = c_dbrf2a / c_db; tcs.AddChannel(new string[] { "RF2ADBDB" }, rf2aDBDB); // the E.RFxF channels, normalized to DB TOFChannel erf1fDB = c_erf1f / c_db; tcs.AddChannel(new string[] { "ERF1FDB" }, erf1fDB); TOFChannel erf2fDB = c_erf2f / c_db; tcs.AddChannel(new string[] { "ERF2FDB" }, erf2fDB); // the E.RFxF.DB channels, normalized to DB, again dodgy naming convention. TOFChannel erf1fDBDB = c_edbrf1f / c_db; tcs.AddChannel(new string[] { "ERF1FDBDB" }, erf1fDBDB); TOFChannel erf2fDBDB = c_edbrf2f / c_db; tcs.AddChannel(new string[] { "ERF2FDBDB" }, erf2fDBDB); // the LF1 channel, normalized to DB TOFChannel lf1DB = c_lf1 / c_db; tcs.AddChannel(new string[] { "LF1DB" }, lf1DB); TOFChannel lf1DBDB = c_dblf1 / c_db; tcs.AddChannel(new string[] { "LF1DBDB" }, lf1DBDB); // the LF2 channel, normalized to DB TOFChannel lf2DB = c_lf2 / c_db; tcs.AddChannel(new string[] { "LF2DB" }, lf2DB); TOFChannel lf2DBDB = c_dblf2 / c_db; tcs.AddChannel(new string[] { "LF2DBDB" }, lf2DBDB); TOFChannel 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. I'm going to use just the // simplest level of correction for these. TOFChannel brf1fCorrDB = (c_brf1f / c_db) - ((c_b * c_dbrf1f) / (c_db * c_db)); tcs.AddChannel(new string[] { "BRF1FCORRDB" }, brf1fCorrDB); TOFChannel brf2fCorrDB = (c_brf2f / c_db) - ((c_b * c_dbrf2f) / (c_db * c_db)); tcs.AddChannel(new string[] { "BRF2FCORRDB" }, brf2fCorrDB); return(tcs); } }
public void PlotAverageOffTOF(TOF t) { PlotY(tofGraph, tofOffAveragePlot, t.GateStartTime, t.ClockPeriod, t.Data); }
// NOTE: this function is rendered somewhat obsolete by the BlockTOFDemodulator. // This function takes a list of switches, defining an analysis channel, and gives the // average TOF for that analysis channel's positively contributing TOFs and the same for // the negative contributors. Note that this definition may or may not line up with how // the analysis channels are defined (they may differ by a sign, which might depend on // the number of switches in the channel). public TOF[] GetSwitchTOFs(string[] switches, int index, bool normed) { TOF[] tofs = new TOF[2]; // calculate the state of the channel for each point in the block int numSwitches = switches.Length; int waveformLength = config.GetModulationByName(switches[0]).Waveform.Length; List<bool[]> switchBits = new List<bool[]>(); foreach (string s in switches) switchBits.Add(config.GetModulationByName(s).Waveform.Bits); List<bool> channelStates = new List<bool>(); for (int point = 0; point < waveformLength; point++) { bool channelState = false; for (int i = 0; i < numSwitches; i++) { channelState = channelState ^ switchBits[i][point]; } channelStates.Add(channelState); } // build the "on" and "off" average TOFs TOF tOn = new TOF(); TOF tOff = new TOF(); if (!normed) { // if no normalisation is requested then the TOFs are added directly for (int i = 0; i < waveformLength; i++) { if (channelStates[i]) tOn += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); else tOff += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); } } else { // otherwise each point's TOF is normalised to the ratio of that points norm // signal (integrated over the cgate11) to the average norm signal for the block double[] normIntegrals = GetTOFIntegralArray(1, 0, 3000); double normMean = 0; for (int j = 0; j < normIntegrals.Length; j++) normMean += normIntegrals[j]; normMean /= normIntegrals.Length; for (int j = 0; j < normIntegrals.Length; j++) normIntegrals[j] /= normMean; for (int i = 0; i < waveformLength; i++) { if (channelStates[i]) tOn += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]) / normIntegrals[i]; else tOff += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]) / normIntegrals[i]; } } tOn /= (waveformLength / 2); tOff /= (waveformLength / 2); tofs[0] = tOn; tofs[1] = tOff; return tofs; }
// this function takes some of the single point data and adds it to the block shots as TOFs // with one data point in them. This allows us to use the same code to break all of the data // into channels. public void TOFuliseSinglePointData(string[] channelsToTOFulise) { foreach (string spv in channelsToTOFulise) { for (int i = 0; i < points.Count; i++) { EDMPoint point = (EDMPoint)points[i]; Shot shot = point.Shot; TOF spvTOF = new TOF((double)point.SinglePointData[spv]); shot.TOFs.Add(spvTOF); } // give these data a name detectors.Add(spv); } }
/// <summary> /// GenerateTOF /// </summary> public override void GenerateTOF(Wordprocessing.Position pos, string stylesSourceFile, bool addDefaultStyles) { TOF.Generate(pos); Style.CreateTOFStyles(stylesSourceFile, addDefaultStyles); }
// NOTE: this function is rendered somewhat obsolete by the BlockTOFDemodulator. // This function takes a list of switches, defining an analysis channel, and gives the // average TOF for that analysis channel's positively contributing TOFs and the same for // the negative contributors. Note that this definition may or may not line up with how // the analysis channels are defined (they may differ by a sign, which might depend on // the number of switches in the channel). public TOF[] GetSwitchTOFs(string[] switches, int index, bool normed) { TOF[] tofs = new TOF[2]; // calculate the state of the channel for each point in the block int numSwitches = switches.Length; int waveformLength = config.GetModulationByName(switches[0]).Waveform.Length; List <bool[]> switchBits = new List <bool[]>(); foreach (string s in switches) { switchBits.Add(config.GetModulationByName(s).Waveform.Bits); } List <bool> channelStates = new List <bool>(); for (int point = 0; point < waveformLength; point++) { bool channelState = false; for (int i = 0; i < numSwitches; i++) { channelState = channelState ^ switchBits[i][point]; } channelStates.Add(channelState); } // build the "on" and "off" average TOFs TOF tOn = new TOF(); TOF tOff = new TOF(); if (!normed) { // if no normalisation is requested then the TOFs are added directly for (int i = 0; i < waveformLength; i++) { if (channelStates[i]) { tOn += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); } else { tOff += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]); } } } else { // otherwise each point's TOF is normalised to the ratio of that points norm // signal (integrated over the cgate11) to the average norm signal for the block double[] normIntegrals = GetTOFIntegralArray(1, 0, 3000); double normMean = 0; for (int j = 0; j < normIntegrals.Length; j++) { normMean += normIntegrals[j]; } normMean /= normIntegrals.Length; for (int j = 0; j < normIntegrals.Length; j++) { normIntegrals[j] /= normMean; } for (int i = 0; i < waveformLength; i++) { if (channelStates[i]) { tOn += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]) / normIntegrals[i]; } else { tOff += ((TOF)((EDMPoint)Points[i]).Shot.TOFs[index]) / normIntegrals[i]; } } } tOn /= (waveformLength / 2); tOff /= (waveformLength / 2); tofs[0] = tOn; tofs[1] = tOff; return(tofs); }
public void HandleDataPoint(DataEventArgs e) { Profile currentProfile = Controller.GetController().ProfileManager.CurrentProfile; // update the TOF graphs if (currentProfile.GUIConfig.average) { if (shotCounter % currentProfile.GUIConfig.updateTOFsEvery == 0) { if (avOnTof != null) { window.PlotOnTOF(avOnTof / onAverages); } avOnTof = (TOF)e.point.AverageOnShot.TOFs[0]; onAverages = 1; if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { if (avOffTof != null) { window.PlotOffTOF(avOffTof / offAverages); } avOffTof = (TOF)e.point.AverageOffShot.TOFs[0]; offAverages = 1; } } else // do the averaging { if (avOnTof != null) { avOnTof = avOnTof + ((TOF)e.point.AverageOnShot.TOFs[0]); onAverages++; } if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"] && avOffTof != null) { avOffTof = avOffTof + ((TOF)e.point.AverageOffShot.TOFs[0]); offAverages++; } } } else // if not averaging { if (shotCounter % currentProfile.GUIConfig.updateTOFsEvery == 0) { window.PlotOnTOF((TOF)e.point.AverageOnShot.TOFs[0]); if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { window.PlotOffTOF((TOF)e.point.AverageOffShot.TOFs[0]); } } } // update the spectra pointsToPlot.Points.Add(e.point); if (shotCounter % currentProfile.GUIConfig.updateSpectraEvery == 0) { if (pointsToPlot.AnalogChannelCount >= 1) { window.AppendToAnalog1(pointsToPlot.ScanParameterArray, pointsToPlot.GetAnalogArray(0)); } if (pointsToPlot.AnalogChannelCount >= 2) { window.AppendToAnalog2(pointsToPlot.ScanParameterArray, pointsToPlot.GetAnalogArray(1)); } if (sdisplayMode == ScanDisplayMode.Integral) { window.AppendToPMTOn(pointsToPlot.ScanParameterArray, pointsToPlot.GetTOFOnIntegralArray(0, startTOFGate, endTOFGate)); } if (sdisplayMode == ScanDisplayMode.IofAbs) { window.AppendToPMTOn(pointsToPlot.ScanParameterArray, pointsToPlot.GetTOFOnAbsValIntegralArray(0, startTOFGate, endTOFGate)); } if ((bool)currentProfile.AcquisitorConfig.switchPlugin.Settings["switchActive"]) { if (sdisplayMode == ScanDisplayMode.Integral) { window.AppendToPMTOff(pointsToPlot.ScanParameterArray, pointsToPlot.GetTOFOffIntegralArray(0, startTOFGate, endTOFGate)); window.AppendToDifference(pointsToPlot.ScanParameterArray, pointsToPlot.GetDifferenceIntegralArray(0, startTOFGate, endTOFGate)); } if (sdisplayMode == ScanDisplayMode.IofAbs) { window.AppendToPMTOff(pointsToPlot.ScanParameterArray, pointsToPlot.GetTOFOffAbsValIntegralArray(0, startTOFGate, endTOFGate)); window.AppendToDifference(pointsToPlot.ScanParameterArray, pointsToPlot.GetDifferenceAbsValIntegralArray(0, startTOFGate, endTOFGate)); } } // update the spectrum fit if in shot mode. if (spectrumFitMode == FitMode.Shot) { Scan currentScan = Controller.GetController().DataStore.CurrentScan; if (currentScan.Points.Count > 10) { FitAndPlotSpectrum(currentScan); } } pointsToPlot.Points.Clear(); } shotCounter++; }