Exemple #1
0
        public void ConnectLMMMInstruments()
        {
            if (!Instruments.Active.HasSocketBasedLM())
            {
                return;
            }
            LMInstrument lmi = (LMInstrument)Instruments.Active.FirstLM();

            // for the LMs
            // Start listening for instruments.
            StartLMDAQServer((LMConnectionInfo)lmi.id.FullConnInfo);   // NEXT: socket reset should occur here for robust restart and recovery
            collog.TraceInformation("Broadcasting to LM instruments. . .");

            // broadcast message to all subnet (configurable, defaulting to 169.254.x.x) addresses. This is the instrument group.
            // look for the number of requested instruments
            DAQControl.LMMMComm.PostLMMMCommand(LMMMLingo.Tokens.broadcast);
            collog.TraceInformation("Sent broadcast. Waiting for LM instruments to connect");

            // wait until enough time has elapsed to be sure live instruments can report back
            Thread.Sleep(lmi.id.FullConnInfo.Wait);  // todo: configure this with a unique wait parameter value
            if (!LMMMComm.LMServer.IsRunning)
            {
                collog.TraceEvent(LogLevels.Error, 0x2A29, "No socket server for LM support running");
            }
        }
Exemple #2
0
        /// <summary>
        /// Checks control state for DAQ continuation, then
        /// If at the end of a cycle
        /// 1) finishes cycle processing (wait for analyzer completion, get results, summarize counts, cycle conditioning steps)
        ///   a) starts the next assay cycle, or
        ///   b) notifies controller of DAQ measurement completion
        /// </summary>
        /// <param name="activeInstr">instrument object associated with the current DAQ state</param>
        /// <param name="sb">status block object indicating end of a cycle</param>
        internal static void HandleEndOfCycleProcessing(LMInstrument activeInstr, Analysis.StreamStatusBlock sb)
        {
            activeInstr.RDT.PlaceStatusTextOnCurrentCycle(sb);

            bool done = true; // assume done for all instruments

            activeInstr.DAQState = DAQInstrState.Online;

            // tbd RR: need to lock this
            // for each networked instrument
            // check ALL instrument for done so we can set the assay.state to done or repeat
            // only look at active instrs in the listbox list.
            for (int j = 0; j < Instruments.Active.Count; j++) // NEXT: revisit this for mixing of the LM and SR behaviors
            {
                if (Instruments.Active[j].DAQState != DAQInstrState.Online)
                {
                    done = false;
                    break;
                }
            }

            if (done) // all are done
            {
                CurState.State = DAQInstrState.Online;
                gControl.netlog.TraceInformation("Assay cycle " + CurState.Measurement.CurrentRepetition + " complete");
                if ((CurState.Measurement.CurrentRepetition < CurState.Measurement.RequestedRepetitions) ||
                    (CurState.Measurement.RequestedRepetitions == 0) && !CurState.IsQuitRequested)
                {
                    // dev note: this could   be spawned in a task because the end processing can be time consuming, delaying the start of next DAQ iteration
                    bool ok = activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement);
                    if (ok)  // start the next cycle
                    {
                        gControl.FireEvent(EventType.ActionInProgress, gControl);
                        gControl.StartLM_SRAssay();
                    }
                    else
                    {
                        gControl.MajorOperationCompleted(); // the overall pend handle used by cmd line
                    }
                }
                else
                {
                    gControl.netlog.TraceInformation("All assay cycles completed");
                    activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement); // do final processing on the last cycle, then do the last cycle closure processing
                    activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement, last: true);
                    gControl.MajorOperationCompleted();                         // the overall pend handle used by cmd line
                }
            }
        }
Exemple #3
0
 public LMInstrument MatchByPort(int Port)
 {
     return((LMInstrument)this.Find(i =>
     {
         if (i is LMInstrument)
         {
             LMInstrument lm = (LMInstrument)i;
             return lm.port == Port;
         }
         else
         {
             return false;
         }
     }
                                    ));
 }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void SL_ClientConnected(object sender, SocketAsyncEventArgs e)
        {
            connections = Interlocked.Increment(ref connections);
            Socket s = e.UserToken as Socket;

            System.Net.IPEndPoint ep = (System.Net.IPEndPoint)s.RemoteEndPoint;

            gControl.netlog.TraceInformation("New Connection : " + s.RemoteEndPoint.ToString());

            LMInstrument lmi = new LMInstrument(e, ep.Port);

            Instruments.All.Add(lmi);
            // dev note: need a parallel entry in the counting parameters map on the enclosing Measurement for each instrument and it;s SR params class instance

            // get the status of the instrument
            DAQControl.ReadInstrStatus(lmi);
        }
Exemple #5
0
        public void ApplyInstrumentSettings()
        {
            foreach (Instrument instrument in Instruments.Active)
            {
                try {
                    instrument.ApplySettings();
                }
                catch (Exception ex) {
                    collog.TraceException(ex);
                }
            }

            // for now, this is for the LMs only
            if (!Instruments.Active.HasConnectedLM())
            {
                return;
            }

            LMInstrument     lm  = (LMInstrument)Instruments.Active.AConnectedLM();
            LMConnectionInfo lmc = (LMConnectionInfo)lm.id.FullConnInfo;

            if (lm.SocketBased()) // it's an LMMM
            {
                // look for any flags requiring conditioning of the instrument prior to assay or HV
                // e.g. input=0, the arg to each is already parsed in the command line processing state
                //if (NC.App.Config.LMMM.isSet(LMFlags.input))
                {
                    DAQControl.LMMMComm.FormatAndSendLMMMCommand(LMMMLingo.Tokens.input, lmc.DeviceConfig.Input);
                }
                //if (NC.App.Config.LMMM.isSet(LMFlags.debug))
                {
                    DAQControl.LMMMComm.FormatAndSendLMMMCommand(LMMMLingo.Tokens.debug, lmc.DeviceConfig.Debug);
                }
                //if (NC.App.Config.LMMM.isSet(LMFlags.leds))
                {
                    DAQControl.LMMMComm.FormatAndSendLMMMCommand(LMMMLingo.Tokens.leds, lmc.DeviceConfig.LEDs);
                }
                //if (NC.App.Config.LMMM.isSet(LMFlags.hv))
                {
                    DAQControl.LMMMComm.FormatAndSendLMMMCommand(LMMMLingo.Tokens.hvset, lmc.DeviceConfig.HV);
                }
            }
            else // its a PTR-32
            {
            }
        }
Exemple #6
0
        static void PacketLogSLOW(LMInstrument activeInstr, SocketAsyncEventArgs e)
        {
            // my little hack by Joe Longo, where I learn by doing
            byte[] bstr1 = new byte[e.BytesTransferred];
            Array.Copy(e.Buffer, e.Offset, bstr1, 0, e.BytesTransferred);
            string tesmp = bytestoASCIIchars(bstr1, e.BytesTransferred, 132);
            string eos   = ((e.BytesTransferred % 2) == 0 ? "EVEN " : "ODD ");
            ulong  buffo = 0;

            if (activeInstr != null)
            {
                if (activeInstr.RDT != null)
                {
                    buffo = activeInstr.NumProcessedRawDataBuffers;
                }
                eos += activeInstr.DAQState.ToString();
            }
            gControl.netlog.TraceEvent(LogLevels.Verbose, 696, "{0}:{1} {2} bytes, state {3}", buffo, packets, e.BytesTransferred, eos);
            gControl.netlog.TraceEvent(LogLevels.Verbose, 697, ">>>" + tesmp);
        }
Exemple #7
0
        // get the LM ranking position (0, 1, 2, etc)
        public int RankPositionInList(LMInstrument inst)
        {
            int idx = 0;

            for (int i = 0; i < this.Count; i++)
            {
                if (this[i] is LMInstrument)
                {
                    if (this[i].Equals(inst))
                    {
                        return(idx);
                    }
                    else
                    {
                        idx++;
                    }
                }
            }
            return(-1);
        }
Exemple #8
0
 void DisconnectFromLMInstruments()
 {
     if (Instruments.Active.HasSocketBasedLM())
     {
         if (_SL == null)
         {
             return;
         }
         // Stop incoming accepts
         _SL.Stop();
         IEnumerator iter = Instruments.Active.GetLMEnumerator();
         // Close all connected instruments
         while (iter.MoveNext())
         {
             LMInstrument lmi = (LMInstrument)iter.Current;
             if (lmi.id.SRType.IsSocketBasedLM())
             {
                 _SL.StopClient(lmi.instrSocketEvent);
             }
         }
     }
 }
Exemple #9
0
 /// <summary>
 /// Prepare a detector for live assay/HV by adding it to the active list.
 /// </summary>
 /// <param name="det"></param>
 public static void ActivateDetector(Detector det)
 {
     if (det.Id.SRType.IsSocketBasedLM())
     {
         LMInstrument lm = new LMInstrument(det);
         lm.DAQState = DAQInstrState.Offline; // these are manually initiated as opposed to auto-pickup
         lm.selected = false;                 //must broadcast first to get it selected
         if (!Instruments.All.Contains(lm))
         {
             Instruments.All.Add(lm); // add to global runtime list
         }
     }
     else if (det.Id.SRType.IsUSBBasedLM())
     {
         Ptr32Instrument ptr = new Ptr32Instrument(det);
         ptr.DAQState = DAQInstrState.Offline; // these are manually initiated as opposed to auto-pickup
         if (!Instruments.All.Contains(ptr))
         {
             Instruments.All.Add(ptr); // add to global runtime list
         }
     }
 }
Exemple #10
0
        // still need to test if this works
        //         typing 'stop' at prompt stops the current cycle, but not the overall processing state, this method should now stop the entire process
        // devnote: Could just use a timer-based check of the token, same as for progress polling into the analyzer
        /// <summary>
        /// send the cancel command to each LMMM, set the instrument state Online to prevent data processing of any additional packets
        /// </summary>
        /// <param name="removeCurNCDFile">delete the current NCD files created for the current interval</param>
        private void StopLMCAssay(bool removeCurNCDFile)
        {
            collog.TraceEvent(LogLevels.Info, 0, "Stopping assay...");
            CurState.State = DAQInstrState.Online;

            // stop each instrument in the active list
            foreach (Instrument active in Instruments.Active)
            {
                //This new from USB version incc6, commenting out has no effect on doubles/triples errors hn 9/22/2014
                active.StopAssay();

                // send cancel command to the LMMM instruments
                if (active is LMInstrument && ((LMInstrument)active).SocketBased())
                {
                    LMInstrument lmi = active as LMInstrument;
                    LMMMComm.FormatAndSendLMMMCommand(LMMMLingo.Tokens.cancel, 0, Instruments.Active.RankPositionInList(lmi)); // send to all active, 1 by 1
                    if (collectingFileData && lmi.file != null)
                    {
                        lmi.file.CloseWriter();
                        if (removeCurNCDFile)
                        {
                            lmi.file.Delete();
                        }
                    }
                    active.DAQState = DAQInstrState.Online;
                }
                else if (active is SRInstrument)
                {
                    // tell the SR thread handler to cancel it
                    ctrllog.TraceInformation("Stop SR {0}", active.id.IdentName());
                    SRWrangler.StopThread(active as SRInstrument, true);
                    active.DAQState = DAQInstrState.Offline;
                }
            }

            ctrllog.TraceInformation("Assay cancelled");
            NC.App.Loggers.Flush();
        }
Exemple #11
0
 static public void ReadInstrStatus(LMInstrument lmi)
 {
     DAQControl.LMMMComm.FormatAndSendLMMMCommand(LMMMLingo.Tokens.cstatus, 0, Instruments.Active.RankPositionInList(lmi));
 }
Exemple #12
0
        /// <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.netlog.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.netlog.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.netlog.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.netlog.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.netlog.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.netlog.TraceInformation("ReceivingData rates {0} on LM {1}:{2}", p.ToString(), Instruments.Active.IndexOf(activeInstr), activeInstr.id.DetectorId);
                                }
                                CurState.State = DAQInstrState.Online;
                                gControl.netlog.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.netlog.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.netlog.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.netlog.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.netlog.TraceInformation("The new instrument is " + LMLoggers.LognLM.FlattenChars(received));
                    gControl.netlog.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.netlog.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.netlog.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.netlog.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.netlog.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.netlog.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.netlog.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.netlog.Flush();
                }
            }
        }
Exemple #13
0
 public static bool SocketBased(this LMInstrument lm)
 {
     return(lm.id.SRType.IsSocketBasedLM());
 }