public static Shot operator +(Shot s1, Shot s2) { if (s1.TOFs.Count == s2.TOFs.Count) { Shot temp = new Shot(); for (int i = 0 ; i < s1.TOFs.Count ; i++) { temp.TOFs.Add((TOF)s1.TOFs[i] + (TOF)s2.TOFs[i]); } return temp; } else { if (s1.TOFs.Count == 0) return s2; if (s2.TOFs.Count == 0) return s1; return null; } }
public static Shot GetFakeShot(int gateStart, int gateLength, int clockPeriod, double intensity, int numberOfDetectors) { Random rng = new Random(); // generate some fake data double[] detectorOnData = new double[gateLength]; double newRand = rng.NextDouble(); int centre = gateLength/2; 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; }
// 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(); } hardwareController.UpdateLaserPhotodiodes(); p.SinglePointData.Add("ProbePD", hardwareController.probePDVoltage); p.SinglePointData.Add("PumpPD", hardwareController.probePDVoltage); hardwareController.UpdateMiniFluxgates(); p.SinglePointData.Add("MiniFlux1", hardwareController.miniFlux1Voltage); p.SinglePointData.Add("MiniFlux2", hardwareController.miniFlux2Voltage); p.SinglePointData.Add("MiniFlux3", hardwareController.miniFlux3Voltage); hardwareController.UpdatePiMonitor(); p.SinglePointData.Add("piMonitor", hardwareController.piFlipMonVoltage); hardwareController.ReadIMonitor(); p.SinglePointData.Add("NorthCurrent", hardwareController.NorthCurrent); p.SinglePointData.Add("SouthCurrent", hardwareController.SouthCurrent); // 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 static Shot operator /(Shot s, int n) { Shot temp = new Shot(); foreach (TOF t in s.TOFs) temp.TOFs.Add(t/n); return temp; }