public bool?Monitor(params object[] data) { // TODO: move partially up byte backgroundCycles = Config.BackgroundCycles; doBackgroundPremeasure = backgroundCycles != 0; Graph.MeasureGraph g; switch (pState) { case ProgramStates.Ready: if (SomePointsUsed) { //Order is important here!!!! Underlying data update before both matrix formation and measure mode init. g = Graph.MeasureGraph.Instance; g.ResetForMonitor(); //var peaks = g.PreciseData.GetUsed(); //already filtered in ResetForMonitor() var peaks = g.PreciseData; #warning matrix is formed too early // TODO: move matrix formation to manual operator actions // TODO: parallelize matrix formation, flag on completion // TODO: duplicates peaksForMatrix = peaks.GetWithId(); if (peaksForMatrix.Count > 0) { // To comply with other processing order (and saved information) peaksForMatrix.Sort(PreciseEditorData.ComparePreciseEditorDataByPeakValue); matrix = new Matrix(Config.LoadLibrary(peaksForMatrix)); // What do with empty matrix? if (matrix != null) { matrix.Init(); } else { OnLog("Error in peak data format or duplicate substance."); return(null); } } else { matrix = null; } // TODO: feed measure mode with start shift value (really?) short?startShiftValue = 0; { var co = g.CommonOptions; var temp = new MeasureMode.Precise.Monitor(Config.MIN_STEP, Config.MAX_STEP, // TODO: getWithId() peaks, co.befTimeReal, co.iTimeReal, co.eTimeReal, co.ForwardTimeEqualsBeforeTime ? co.befTimeReal : co.fTimeReal, co.bTimeReal, (p, peak) => g.updateGraphDuringPreciseMeasure(p, peak, Counts), g.updateGraphAfterPreciseMeasure, Config.Iterations, Config.TimeLimit, // TODO: move extra data into checker Config.CheckerPeak, Config.CheckerPeak == null ? null : startShiftValue, Config.AllowedShift); temp.SaveResults += (s, e) => { Config.autoSaveMonitorSpectrumFile(LabelNumber); if (LabelNumber.HasValue) { LabelNumber = null; } }; temp.Finalize += (s, e) => Config.finalizeMonitorFile(); // how to unsubscribe? //realizer.MeasureSend += (s, e) => temp.NextMeasure(e.Value); CurrentMeasureMode = temp; } if (doBackgroundPremeasure) { initMeasure(ProgramStates.WaitBackgroundMeasure); background = new FixedSizeQueue <List <long> >(backgroundCycles); // or maybe Enumerator realization: one item, always recounting (accumulate values).. g.GraphDataModified += NewBackgroundMeasureReady; } else { initMeasure(ProgramStates.Measure); g.GraphDataModified += NewMonitorMeasureReady; } return(true); } else { OnLog("No points for monitor mode measure."); return(null); } case ProgramStates.BackgroundMeasureReady: // set background end label LabelNumber = 0; g = Graph.MeasureGraph.Instance; g.GraphDataModified -= NewBackgroundMeasureReady; backgroundResult = background.Aggregate(Summarize); for (int i = 0; i < backgroundResult.Count; ++i) { // TODO: check integral operation behaviour here backgroundResult[i] /= backgroundCycles; } setProgramStateWithoutUndo(ProgramStates.Measure); g.GraphDataModified += NewMonitorMeasureReady; return(false); case ProgramStates.Measure: // set label LabelNumber = (int)data[0]; return(false); default: // wrong state, strange! return(null); } }