public static Row CreateRow(HVControl.HVStatus h, int i) { Row row = new Row(); row.Add((int)HVVals.Run, i.ToString()); row.Add((int)HVVals.Time, h.time.ToString("s")); row.Add((int)HVVals.HVRead, h.HVread.ToString()); row.Add((int)HVVals.HVSetPt, h.HVsetpt.ToString()); for (int j = (int)HVVals.C1; j <= (int)HVVals.C32; j++) { row.Add(j, h.counts[j - (int)HVVals.C1].ToString()); } return(row); }
public void GenerateReport(AnalysisDefs.HVCalibrationParameters hvc, List <HVControl.HVStatus> HVSteps, DateTime time, String instId) { TabularReport t = new TabularReport(typeof(HVVals), NC.App.Loggers); // default file output type is CSV try { t.CreateOutputFile(NC.App.Opstate.Measurement.AcquireState.lm.Results, instId + " HV " + time.ToString("yyyyMMddHHmmss"), null); t.rows = new Row[HVSteps.Count + 4 + 2]; // header, steps, space, header, current params, space, header, config // first, the column header int cols = System.Enum.GetValues(typeof(HVVals)).Length; int i = 0; // now for each hvcalib row for (i = 0; i < HVSteps.Count; i++) { HVControl.HVStatus h = HVSteps[i]; Row row = CreateRow(h, i); t.rows[i] = row; } // then do the current parameters t.rows[i++] = new Row(); t.rows[i] = new Row(); t.rows[i++].GenFromEnum(typeof(HVCalibVals)); t.rows[i++] = CreateRow(hvc, i); t.rows[i++] = new Row(); // lastly, add the full software version state t.rows[i] = new Row(); t.rows[i++].Add(0, "Software application configuration details"); Row[] temp = AnalysisDefs.SimpleReport.GenSoftwareConfigRows(); Array.Resize(ref t.rows, temp.Length + t.rows.Length + 2); Array.Copy(temp, 0, t.rows, i, temp.Length); t.CreateReport(3); } catch (Exception e) { ctrllog.TraceException(e); } finally { t.CloseOutputFile(); } }
// implement incremental row addition using something like this public void AddRow(HVControl.HVStatus h, int r) { int lc = System.Enum.GetValues(typeof(SimpleHVReport.HVVals)).Length; Row row = SimpleHVReport.CreateRow(h, r); try { #if EXCEL for (int j = 1; j <= lc; j++) { target.Cells[r + 1, j] = row[j - 1]; } #endif } catch (Exception e) { ctrllog.TraceException(e); } }
/// <summary> /// Handle data from the client sockets /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void SL_DataReceived(object sender, SocketAsyncEventArgs e) { Socket s = e.UserToken as Socket; System.Net.IPEndPoint ep = (System.Net.IPEndPoint)s.RemoteEndPoint; packets = Interlocked.Increment(ref packets); // call the specific instrument handler here using the ID. // This routine is needed if there are more than one type of instrument. // match with port it came from, each connection will have a different port. LMInstrument activeInstr = Instruments.Active.MatchByPort(ep.Port); // dev note: this might be slow, could speed up this by switching to a map rather than a list bool verbose = gControl.collog.ShouldTrace(LogLevels.Verbose); if (verbose) { PacketLogSLOW(activeInstr, e); } if (activeInstr.DAQState == DAQInstrState.ReceivingData) { activeInstr.NumProcessedRawDataBuffers++; if (verbose) /* diag buffer tracing */ { string temp = string.Format("{0}: bytes {1}, total bytes {2}, LM {3}", activeInstr.NumProcessedRawDataBuffers, e.BytesTransferred, numTotalBytes, Instruments.Active.IndexOf(activeInstr)); gControl.collog.TraceEvent(LogLevels.Verbose, 686, temp); } try { if (CurState.IsQuitRequested) throw new AnalysisDefs.CancellationRequestedException(); else if ((e.BytesTransferred % 2) == 0) // EVEN messages are data. { // dev note: file writing is controlled via LiveFileWrite (activeInstr.file as NCCFile.NCDFile).Write(e.Buffer, e.Offset, e.BytesTransferred); try { // this method copies the buffer and sends it on to neutron counting var res = activeInstr.RDT.PassBufferToTheCounters(e.Buffer, e.Offset, e.BytesTransferred); if (res != null) //Handle this error condition as if it is a regular ODD-count packet with the end marker { HandleEndOfCycleProcessing(activeInstr, res); } } catch (Exception ex) { HandleFatalGeneralError(activeInstr, ex); } } else // ODD - last data is the status message. { try { LMComm.LMMMLingo.Tokens response = LMMMComm.DataPacketResponseMatch(e.Buffer, e.Offset, e.BytesTransferred); // command parsing here should be as fast as possible because data collection is active and may be hampered by even short delays in this section // it is a status message, the last message of an assay if (response == LMComm.LMMMLingo.Tokens.statusdata) // dev note: must be odd length and end with '......' or '......' (old style) or else start with 'Status\r\n' (new style Nov. 2010) { try // // write the last message to the file.This might be a partial data + last message { (activeInstr.file as NCCFile.NCDFile).Write(e.Buffer, e.Offset, e.BytesTransferred); (activeInstr.file as NCCFile.NCDFile).CloseWriter(); } catch (Exception fex) { if ((activeInstr.file as NCCFile.NCDFile).stream != null) gControl.collog.TraceEvent(LogLevels.Error, 642, "{0}: error on close {1}", (activeInstr.file as NCCFile.NCDFile).stream.Name, fex.Message); } var res = activeInstr.RDT.PassBufferToTheCounters(e.Buffer, e.Offset, e.BytesTransferred); HandleEndOfCycleProcessing(activeInstr, res); } else if (response == LMComm.LMMMLingo.Tokens.tosenddatasize) // this says how many bytes are going to be sent { numTotalBytes = LMMMComm.ResponseToSendDataSize(e.Buffer, e.Offset, e.BytesTransferred); // t gControl.collog.TraceEvent(LogLevels.Verbose, 654, "Expecting " + Convert.ToString(numTotalBytes) + " (to sen)"); } else if (response == LMComm.LMMMLingo.Tokens.unrecognizeddata) // unrecognized command { string temp = LMMMComm.ResponseUnrecoSample(e.Buffer, e.Offset, e.BytesTransferred); gControl.collog.TraceInformation(temp); } else // it might be an odd message with some data tacked on the beginning { if (gControl.collectingFileData) { (activeInstr.file as NCCFile.NCDFile).Write(e.Buffer, e.Offset, e.BytesTransferred); (activeInstr.file as NCCFile.NCDFile).CloseWriter(); } if (response == LMComm.LMMMLingo.Tokens.rates) // somehow got a rates block { RatesStatus p = new RatesStatus(); String received = LMMMComm.NonDataResponse(e.Buffer, e.Offset, e.BytesTransferred); LMMMComm.SplitRatesReadResponse(received, ref p); gControl.collog.TraceInformation("ReceivingData rates {0} on LM {1}:{2}", p.ToString(), Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } CurState.State = DAQInstrState.Online; gControl.collog.TraceInformation("Cycle " + CurState.Measurement.CurrentRepetition + " complete"); if ((CurState.Measurement.CurrentRepetition < CurState.Measurement.RequestedRepetitions) || (CurState.Measurement.RequestedRepetitions == 0)) { bool ok = activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement); if (ok) { gControl.FireEvent(EventType.ActionInProgress, gControl); gControl.StartLM_SRAssay(); } else gControl.MajorOperationCompleted(); // the overall pend handle used by cmd line } else { gControl.collog.TraceInformation("All assay cycles completed, but with data in an odd-sized packet"); bool ok = activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement, last:true); gControl.MajorOperationCompleted(); // the overall pend handle used by cmd line } } } catch (AnalysisDefs.FatalNeutronCountingException fae) // propagated up from the AnalysisHandler { HandleFatalGeneralError(activeInstr, fae); } catch (AnalysisDefs.CancellationRequestedException) // thrown from this method { StopActiveAssayImmediately(); } catch (Exception oddex) { gControl.collog.TraceEvent(LogLevels.Error, 643, "Internal error, stopping active processing, {0}: Odd data length handler: {1}", activeInstr.NumProcessedRawDataBuffers, oddex.Message); HandleFatalGeneralError(activeInstr, oddex); } } } catch (AnalysisDefs.CancellationRequestedException) // thrown from this method { StopActiveAssayImmediately(); } if (verbose) gControl.collog.Flush(); } else if (activeInstr.DAQState == DAQInstrState.Online || activeInstr.DAQState == DAQInstrState.HVCalib) // we are not taking data. { String received = LMMMComm.NonDataResponse(e.Buffer, e.Offset, e.BytesTransferred); if (activeInstr.IsNew()) { string iname = String.Empty; string type = InstrType.LMMM.ToString(); LMMMComm.SplitBroadcastResponse(received, ref type, ref iname, ref activeInstr.id.version); activeInstr.id.DetectorId = iname; activeInstr.id.SetSRType(type); gControl.collog.TraceInformation("The new instrument is " + LMLoggers.LognLM.FlattenChars(received)); gControl.collog.TraceInformation(Instruments.All.Count + " instrument(s) online"); activeInstr.selected = true; // this should only be set if there is no UI CurState.State = DAQInstrState.Online; gControl.FireEvent(EventType.ActionPrep, gControl); } else { // slow parsing in this section is fine because data collection is not occurring LMComm.LMMMLingo.Tokens response = LMMMComm.ResponseMatchPrefix(received); if (response == LMComm.LMMMLingo.Tokens.cstatus) // it is a status readback { LMMMComm.SplitCStatusResponse(received, ref activeInstr.lmstatus); gControl.collog.TraceInformation( "cStatus for LM {0}:{1} is dbg:{2}, leds:{3}, input:{4}, HVset:{5}, HV:{6}, LLD Max:{7}, LLD:{8}, (u1:{9})", Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId, activeInstr.lmstatus.debug, activeInstr.lmstatus.leds, activeInstr.lmstatus.inputPath, activeInstr.lmstatus.setpoint, activeInstr.lmstatus.hv, activeInstr.lmstatus.MaxLLD, activeInstr.lmstatus.LLD, activeInstr.lmstatus.u1); } else if (response == LMComm.LMMMLingo.Tokens.hvread) // it is a hv readback { int hv = 0; LMMMComm.SplitHVReadResponse(received, ref hv); gControl.collog.TraceInformation("HVread {0} volts for LM {1}:{2}", hv, Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else if (response == LMComm.LMMMLingo.Tokens.hvcalib) // it is a hv calibration point { HVControl.HVStatus hvst = new HVControl.HVStatus(); LMMMComm.SplitHVCalibResponse(received, ref hvst); gControl.AppendHVCalibration(hvst); gControl.collog.TraceInformation("HVcalib for LM {0}:{1} is [setpt:{2}, read:{3}, . . .]", Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId, hvst.HVsetpt, hvst.HVread); gControl.StepHVCalibration(); } else if (response == LMComm.LMMMLingo.Tokens.rates) // it is a rates response { RatesStatus p = new RatesStatus(); LMMMComm.SplitRatesReadResponse(received, ref p); gControl.collog.TraceInformation("Rates {0} on LM {1}:{2}", p.ToString(), Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else if (response == LMComm.LMMMLingo.Tokens.power) // it is a power status { PowerStatus p = new PowerStatus(); LMMMComm.SplitPowerReadResponse(received, ref p); gControl.collog.TraceInformation("Power AC {0}, Batt {1}, Batt Level {2} on LM {3}:{4}", p.ACPresent, p.batteryPresent, p.batterylevelPct, Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else if (response == LMComm.LMMMLingo.Tokens.lld) // LLD status { int lld = 0; LMMMComm.SplitLLDReadResponse(received, ref lld); gControl.collog.TraceInformation("LLD {0} on LM {1}:{2}", lld, Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else // RR: this could be binary data if you cancel an assay and linux is sending a buffer. // RR: this is a large amount of data and we don't want it displayed. // tbd RR: figure out how to turn this back on when data is finished dumping. { if (verbose) { PacketLogSLOW(activeInstr, e); } } } if (verbose) gControl.collog.Flush(); } }
/// <summary> /// Handle data from the client sockets /// </summary> /// <param name="sender"></param> /// <param name="e"></param> static void SL_DataReceived(object sender, SocketAsyncEventArgs e) { Socket s = e.UserToken as Socket; System.Net.IPEndPoint ep = (System.Net.IPEndPoint)s.RemoteEndPoint; packets = Interlocked.Increment(ref packets); // call the specific instrument handler here using the ID. // This routine is needed if there are more than one type of instrument. // match with port it came from, each connection will have a different port. LMInstrument activeInstr = Instruments.Active.MatchByPort(ep.Port); // dev note: this might be slow, could speed up this by switching to a map rather than a list bool verbose = gControl.collog.ShouldTrace(LogLevels.Verbose); if (verbose) { PacketLogSLOW(activeInstr, e); } if (activeInstr.DAQState == DAQInstrState.ReceivingData) { activeInstr.NumProcessedRawDataBuffers++; if (verbose) /* diag buffer tracing */ { string temp = string.Format("{0}: bytes {1}, total bytes {2}, LM {3}", activeInstr.NumProcessedRawDataBuffers, e.BytesTransferred, numTotalBytes, Instruments.Active.IndexOf(activeInstr)); gControl.collog.TraceEvent(LogLevels.Verbose, 686, temp); } try { if (CurState.IsQuitRequested) { throw new AnalysisDefs.CancellationRequestedException(); } else if ((e.BytesTransferred % 2) == 0) // EVEN messages are data. { // dev note: file writing is controlled via LiveFileWrite (activeInstr.file as NCCFile.NCDFile).Write(e.Buffer, e.Offset, e.BytesTransferred); try { // this method copies the buffer and sends it on to neutron counting var res = activeInstr.RDT.PassBufferToTheCounters(e.Buffer, e.Offset, e.BytesTransferred); if (res != null) //Handle this error condition as if it is a regular ODD-count packet with the end marker { HandleEndOfCycleProcessing(activeInstr, res); } } catch (Exception ex) { HandleFatalGeneralError(activeInstr, ex); } } else // ODD - last data is the status message. { try { LMComm.LMMMLingo.Tokens response = LMMMComm.DataPacketResponseMatch(e.Buffer, e.Offset, e.BytesTransferred); // command parsing here should be as fast as possible because data collection is active and may be hampered by even short delays in this section // it is a status message, the last message of an assay if (response == LMComm.LMMMLingo.Tokens.statusdata) // dev note: must be odd length and end with '......' or '......' (old style) or else start with 'Status\r\n' (new style Nov. 2010) { try // // write the last message to the file.This might be a partial data + last message { (activeInstr.file as NCCFile.NCDFile).Write(e.Buffer, e.Offset, e.BytesTransferred); (activeInstr.file as NCCFile.NCDFile).CloseWriter(); } catch (Exception fex) { if ((activeInstr.file as NCCFile.NCDFile).stream != null) { gControl.collog.TraceEvent(LogLevels.Error, 642, "{0}: error on close {1}", (activeInstr.file as NCCFile.NCDFile).stream.Name, fex.Message); } } var res = activeInstr.RDT.PassBufferToTheCounters(e.Buffer, e.Offset, e.BytesTransferred); HandleEndOfCycleProcessing(activeInstr, res); } else if (response == LMComm.LMMMLingo.Tokens.tosenddatasize) // this says how many bytes are going to be sent { numTotalBytes = LMMMComm.ResponseToSendDataSize(e.Buffer, e.Offset, e.BytesTransferred); // t gControl.collog.TraceEvent(LogLevels.Verbose, 654, "Expecting " + Convert.ToString(numTotalBytes) + " (to sen)"); } else if (response == LMComm.LMMMLingo.Tokens.unrecognizeddata) // unrecognized command { string temp = LMMMComm.ResponseUnrecoSample(e.Buffer, e.Offset, e.BytesTransferred); gControl.collog.TraceInformation(temp); } else // it might be an odd message with some data tacked on the beginning { if (gControl.collectingFileData) { (activeInstr.file as NCCFile.NCDFile).Write(e.Buffer, e.Offset, e.BytesTransferred); (activeInstr.file as NCCFile.NCDFile).CloseWriter(); } if (response == LMComm.LMMMLingo.Tokens.rates) // somehow got a rates block { RatesStatus p = new RatesStatus(); String received = LMMMComm.NonDataResponse(e.Buffer, e.Offset, e.BytesTransferred); LMMMComm.SplitRatesReadResponse(received, ref p); gControl.collog.TraceInformation("ReceivingData rates {0} on LM {1}:{2}", p.ToString(), Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } CurState.State = DAQInstrState.Online; gControl.collog.TraceInformation("Cycle " + CurState.Measurement.CurrentRepetition + " complete"); if ((CurState.Measurement.CurrentRepetition < CurState.Measurement.RequestedRepetitions) || (CurState.Measurement.RequestedRepetitions == 0)) { bool ok = activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement); if (ok) { gControl.FireEvent(EventType.ActionInProgress, gControl); gControl.StartLM_SRAssay(); } else { gControl.MajorOperationCompleted(); // the overall pend handle used by cmd line } } else { gControl.collog.TraceInformation("All assay cycles completed, but with data in an odd-sized packet"); bool ok = activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement, last: true); gControl.MajorOperationCompleted(); // the overall pend handle used by cmd line } } } catch (AnalysisDefs.FatalNeutronCountingException fae) // propagated up from the AnalysisHandler { HandleFatalGeneralError(activeInstr, fae); } catch (AnalysisDefs.CancellationRequestedException) // thrown from this method { StopActiveAssayImmediately(); } catch (Exception oddex) { gControl.collog.TraceEvent(LogLevels.Error, 643, "Internal error, stopping active processing, {0}: Odd data length handler: {1}", activeInstr.NumProcessedRawDataBuffers, oddex.Message); HandleFatalGeneralError(activeInstr, oddex); } } } catch (AnalysisDefs.CancellationRequestedException) // thrown from this method { StopActiveAssayImmediately(); } if (verbose) { gControl.collog.Flush(); } } else if (activeInstr.DAQState == DAQInstrState.Online || activeInstr.DAQState == DAQInstrState.HVCalib) // we are not taking data. { String received = LMMMComm.NonDataResponse(e.Buffer, e.Offset, e.BytesTransferred); if (activeInstr.IsNew()) { string iname = String.Empty; string type = InstrType.LMMM.ToString(); LMMMComm.SplitBroadcastResponse(received, ref type, ref iname, ref activeInstr.id.version); activeInstr.id.DetectorId = iname; activeInstr.id.SetSRType(type); gControl.collog.TraceInformation("The new instrument is " + LMLoggers.LognLM.FlattenChars(received)); gControl.collog.TraceInformation(Instruments.All.Count + " instrument(s) online"); activeInstr.selected = true; // this should only be set if there is no UI CurState.State = DAQInstrState.Online; gControl.FireEvent(EventType.ActionPrep, gControl); } else { // slow parsing in this section is fine because data collection is not occurring LMComm.LMMMLingo.Tokens response = LMMMComm.ResponseMatchPrefix(received); if (response == LMComm.LMMMLingo.Tokens.cstatus) // it is a status readback { LMMMComm.SplitCStatusResponse(received, ref activeInstr.lmstatus); gControl.collog.TraceInformation( "cStatus for LM {0}:{1} is dbg:{2}, leds:{3}, input:{4}, HVset:{5}, HV:{6}, LLD Max:{7}, LLD:{8}, (u1:{9})", Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId, activeInstr.lmstatus.debug, activeInstr.lmstatus.leds, activeInstr.lmstatus.inputPath, activeInstr.lmstatus.setpoint, activeInstr.lmstatus.hv, activeInstr.lmstatus.MaxLLD, activeInstr.lmstatus.LLD, activeInstr.lmstatus.u1); } else if (response == LMComm.LMMMLingo.Tokens.hvread) // it is a hv readback { int hv = 0; LMMMComm.SplitHVReadResponse(received, ref hv); gControl.collog.TraceInformation("HVread {0} volts for LM {1}:{2}", hv, Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else if (response == LMComm.LMMMLingo.Tokens.hvcalib) // it is a hv calibration point { HVControl.HVStatus hvst = new HVControl.HVStatus(); LMMMComm.SplitHVCalibResponse(received, ref hvst); gControl.AppendHVCalibration(hvst); gControl.collog.TraceInformation("HVcalib for LM {0}:{1} is [setpt:{2}, read:{3}, . . .]", Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId, hvst.HVsetpt, hvst.HVread); gControl.StepHVCalibration(); } else if (response == LMComm.LMMMLingo.Tokens.rates) // it is a rates response { RatesStatus p = new RatesStatus(); LMMMComm.SplitRatesReadResponse(received, ref p); gControl.collog.TraceInformation("Rates {0} on LM {1}:{2}", p.ToString(), Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else if (response == LMComm.LMMMLingo.Tokens.power) // it is a power status { PowerStatus p = new PowerStatus(); LMMMComm.SplitPowerReadResponse(received, ref p); gControl.collog.TraceInformation("Power AC {0}, Batt {1}, Batt Level {2} on LM {3}:{4}", p.ACPresent, p.batteryPresent, p.batterylevelPct, Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else if (response == LMComm.LMMMLingo.Tokens.lld) // LLD status { int lld = 0; LMMMComm.SplitLLDReadResponse(received, ref lld); gControl.collog.TraceInformation("LLD {0} on LM {1}:{2}", lld, Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId); } else // RR: this could be binary data if you cancel an assay and linux is sending a buffer. // RR: this is a large amount of data and we don't want it displayed. // tbd RR: figure out how to turn this back on when data is finished dumping. { if (verbose) { PacketLogSLOW(activeInstr, e); } } } if (verbose) { gControl.collog.Flush(); } } }
public void AppendHVCalibration(HVControl.HVStatus hvst) { ctrlHVCalib.AddStepData(hvst); }