[chronojump] Leave opened encoder R Processes (capture done)



commit 47646afef019132587123c598b096cf6f1ba0560
Author: Xavier de Blas <xaviblas gmail com>
Date:   Wed Apr 22 19:03:14 2015 +0200

    Leave opened encoder R Processes (capture done)

 encoder/capture.R   |   20 ++++-
 src/encoderRProc.cs |  218 +++++++++++++++++++++++++++++++++++++++++++++++----
 src/gui/encoder.cs  |  177 ++++++------------------------------------
 src/utilEncoder.cs  |   27 ------
 4 files changed, 243 insertions(+), 199 deletions(-)
---
diff --git a/encoder/capture.R b/encoder/capture.R
index df6aa30..9e2e6dd 100644
--- a/encoder/capture.R
+++ b/encoder/capture.R
@@ -130,9 +130,25 @@ doProcess <- function(options)
 
        curveNum = 0
        input <- readLines(f, n = 1L)
-       while(input[1] != "Q") {
-               if(debug)
+       #while(input[1] != "Q") {
+       while(TRUE) {
+               if(debug) {
                        write("doProcess main while", stderr())
+                       write(c("input = ", input), stderr())
+               }
+                       
+               
+               #if should continue with another capture
+               #then read options again
+               if(input[1] == "C") {
+                       write("received a continue signal", stderr())
+                       
+                       options <- getOptionsFromFile(optionsFile, 32)
+                       op <- assignOptions(options)
+
+                       curveNum = 0
+                       input <- readLines(f, n = 1L)
+               }
                
                #Sys.sleep(4) #just to test how Chronojump reacts if process takes too long
                #cat(paste("input is:", input, "\n"))
diff --git a/src/encoderRProc.cs b/src/encoderRProc.cs
index c21f6aa..becbd11 100644
--- a/src/encoderRProc.cs
+++ b/src/encoderRProc.cs
@@ -20,42 +20,98 @@
 
 using System;
 using System.Diagnostics;      //for detect OS and for Process
+using System.IO;               //for detect OS
 
 
 public abstract class EncoderRProc 
 {
-       protected Process p;
-       protected ProcessStartInfo pinfo;
+       protected static Process p;
+       protected static ProcessStartInfo pinfo;
+       protected static bool running;
 
-       protected bool running;
+       protected string optionsFile;   
+       protected EncoderStruct es;
 
-       protected void StartOrContinue() 
+       public void StartOrContinue(EncoderStruct es)
        {
-               if(isRunning())
+               this.es = es;
+
+               //options change at every capture. So do at continueProcess and startProcess
+               writeOptionsFile();
+                       
+               if(isRunning()) {
+                       LogB.Debug("calling continue");
                        continueProcess();
-               else
-                       startProcess();
+               } else {
+                       LogB.Debug("calling start");
+                       bool startedOk = startProcess();
+                       LogB.Debug("StartedOk: " + startedOk.ToString());
+               }
        }
 
        private bool isRunning() 
        {
-               if(p == null)
+               LogB.Debug("calling isRunning()");
+               if(p == null) {
+                       LogB.Debug("p == null");
                        return false;
+               }
 
-               Process [] pids = Process.GetProcessesByName("Rscript");
-
+               /*      
+               LogB.Debug("print processes");  
+               Process [] pids = Process.GetProcesses();
                foreach (Process myPid in pids)
+                       LogB.Information(myPid.ToString());
+               */
+               
+               LogB.Debug(string.Format("last pid id {0}", p.Id));
+
+
+               //if(isRunningThisProcess("Rscript") || isRunningThisProcess("*R*"))
+               if(isRunningThisProcess(p.Id))
+                       return true;
+       
+               return false;
+       }
+
+       private bool isRunningThisProcess(int id)
+       {
+               try {
+                       Process pid = Process.GetProcessById(id);
+                       if(pid == null)
+                               return false;
+               } catch {
+                       return false;
+               }
+
+               return true;
+       }
+
+       /*
+        * don't use this because in linux R script can be called by:
+        * "/usr/lib/R/bin/exec/R"
+        * and it will not be found passing "R" or "*R"
+       private bool isRunningThisProcess(string name)
+       {
+               Process [] pids = Process.GetProcessesByName(name);
+               foreach (Process myPid in pids) {
+                       LogB.Debug(string.Format("pids id: {0}", myPid.Id));
                        if (myPid.Id == Convert.ToInt32(p.Id))
                                return true;
-       
+               }
+               
                return false;
        }
+       */
+               
+       protected virtual void writeOptionsFile()
+       {
+       }
 
        protected virtual bool startProcess() {
                return true;
        }
-       protected virtual bool continueProcess() {
-               return true;
+       protected virtual void continueProcess() {
        }
 }
 
@@ -63,6 +119,134 @@ public class EncoderRProcCapture : EncoderRProc
 {
        public EncoderRProcCapture() {
        }
+       
+       protected override bool startProcess() 
+       {
+               LogB.Debug("A");
+               //ProcessStartInfo pinfo;
+               //If output file is not given, R will try to write in the running folder
+               //in which we may haven't got permissions
+
+               string pBin="";
+               pinfo = new ProcessStartInfo();
+
+               pBin="Rscript";
+               if (UtilAll.IsWindows()) {
+                       //on Windows we need the \"str\" to call without problems in path with spaces
+                       pBin = "\"" + System.IO.Path.Combine(Util.GetPrefixDir(), "bin" + 
Path.DirectorySeparatorChar + "Rscript.exe") + "\"";
+                       LogB.Information("pBin:", pBin);
+               }
+               LogB.Debug("B");
+
+
+               //on Windows we need the \"str\" to call without problems in path with spaces
+               //pinfo.Arguments = "\"" + "passToR.R" + "\" " + optionsFile;
+               pinfo.Arguments = "\"" + UtilEncoder.GetEncoderScriptCallCaptureNoRdotNet() + "\" " + 
optionsFile;
+
+               LogB.Information("Arguments:", pinfo.Arguments);
+               LogB.Information("--- 1 --- " + optionsFile.ToString() + " ---");
+               LogB.Information("--- 2 --- " + pinfo.Arguments.ToString() + " ---");
+
+               pinfo.FileName=pBin;
+
+               pinfo.CreateNoWindow = true;
+               pinfo.UseShellExecute = false;
+               pinfo.RedirectStandardInput = true;
+               pinfo.RedirectStandardError = true;
+               //pinfo.RedirectStandardOutput = true; 
+
+
+
+               LogB.Debug("C");
+               try {
+                       p= new Process();
+                       p.StartInfo = pinfo;
+
+                       p.ErrorDataReceived += new DataReceivedEventHandler(readingCurveFromRerror);
+
+                       p.Start();
+
+                       // Start asynchronous read of the output.
+                       // Caution: This has to be called after Start
+                       //p.BeginOutputReadLine();
+                       p.BeginErrorReadLine();
+
+               
+                       LogB.Debug("D");
+                       
+                       LogB.Debug(string.Format("this pid id : {0}", p.Id));
+               } catch {
+                       Console.WriteLine("catched at runEncoderCaptureNoRDotNetStart");
+                       return false;
+               }
+                       
+               return true;
+       }
+       private void readingCurveFromRerror (object sendingProcess, DataReceivedEventArgs curveFromR)
+       {
+               if (! String.IsNullOrEmpty(curveFromR.Data))
+               {
+                       //use Warning because it's used also to print flow messages
+                       LogB.Warning(curveFromR.Data);
+               }
+       }
+       
+       protected override void continueProcess() 
+       {
+               LogB.Debug("sending continue process");
+               p.StandardInput.WriteLine("C");
+       }
+       
+       //here curve is sent compressed (string. eg: "0*5 1 0 -1*3 2")
+       public void SendCurve(double heightAtStart, string curveCompressed)
+       {
+               LogB.Debug("writing line 1 -->");
+               
+               string curveSend = "ps " + Util.ConvertToPoint(heightAtStart);
+               LogB.Debug("curveSend [heightAtStart]",curveSend);
+               p.StandardInput.WriteLine(curveSend);
+                                                               
+               curveSend = curveCompressed;
+               
+               //TODO convert comma to point in this doubles
+
+               LogB.Debug("curveSend [displacement array]",curveSend);
+               p.StandardInput.WriteLine(curveSend);   //this will send some lines because compressed data 
comes with '\n's
+               p.StandardInput.WriteLine("E");         //this will mean the 'E'nd of the curve. Then data 
can be uncompressed on R
+               
+               LogB.Debug("<-- writen line 1");
+       }       
+       
+       public void SendCaptureEnd() 
+       {
+               /*
+                * don't send end line
+                * process should remain opened
+                *
+               LogB.Debug("sending end line");
+               p.StandardInput.WriteLine("Q");
+               */
+       }
+
+       protected override void writeOptionsFile()
+       {
+               optionsFile = Path.GetTempPath() + "Roptions.txt";
+       
+               string scriptOptions = UtilEncoder.PrepareEncoderGraphOptions(
+                               "none",         //title
+                               es, 
+                               false,  //neuromuscularProfile
+                               false   //translate (graphs)
+                               ).ToString();
+
+               TextWriter writer = File.CreateText(optionsFile);
+               writer.Write(scriptOptions);
+               writer.Flush();
+               writer.Close();
+               ((IDisposable)writer).Dispose();
+       }
+
+
 }
 
 public class EncoderRProcAnalyze : EncoderRProc 
@@ -72,6 +256,9 @@ public class EncoderRProcAnalyze : EncoderRProc
 
        protected override bool startProcess() 
        {
+               /*
+                * WIP
+                *
                try {   
                        p = new Process();
                        p.StartInfo = pinfo;
@@ -86,18 +273,17 @@ public class EncoderRProcAnalyze : EncoderRProc
                }
                        
                running = true;
+               */
                return true;
        }
        
-       protected override bool continueProcess() 
+       protected override void continueProcess() 
        {
                /*
                 * create a file to be file to be readed by the Rscript
                 * or send there STDIN, like:
                 * p.StandardInput.WriteLine();
                 */
-               
-               return true;
        }
 
 }
diff --git a/src/gui/encoder.cs b/src/gui/encoder.cs
index 625ed13..1d1fed7 100644
--- a/src/gui/encoder.cs
+++ b/src/gui/encoder.cs
@@ -245,6 +245,9 @@ public partial class ChronoJumpWindow
        //STOPPING is used to stop the camera. It has to be called only one time
        enum encoderCaptureProcess { CAPTURING, STOPPING, STOPPED } 
        static encoderCaptureProcess capturingCsharp;   
+               
+       EncoderRProcCapture encoderRProcCapture;
+       EncoderRProcAnalyze encoderRProcAnalyze;
 
        /* 
         *
@@ -318,6 +321,10 @@ public partial class ChronoJumpWindow
                //spin_encoder_capture_inertial.Value = Convert.ToDouble(Util.ChangeDecimalSeparator(
                //                      SqlitePreferences.Select("inertialmomentum")));
                
+               //initialize capture and analyze classes                
+               encoderRProcCapture = new EncoderRProcCapture();
+               //encoderRProcAnalyze = new EncoderRProcAnalyze();
+               
                encoderCaptureOptionsWin = EncoderCaptureOptionsWindow.Create(repetitiveConditionsWin);
                encoderCaptureOptionsWin.FakeButtonClose.Clicked += new 
EventHandler(on_encoder_capture_options_closed);
 
@@ -2325,11 +2332,9 @@ public partial class ChronoJumpWindow
                                                                }
 
                                                                if(sendCurve) {
-                                                                       
UtilEncoder.RunEncoderCaptureNoRDotNetSendCurve(
-                                                                                       pCaptureNoRDotNet, 
+                                                                       encoderRProcCapture.SendCurve(
                                                                                        heightAtCurveStart, 
-                                                                                       //curve);             
                  //uncompressed
-                                                                               
UtilEncoder.CompressData(curve, 25)     //compressed
+                                                                                       
UtilEncoder.CompressData(curve, 25)     //compressed
                                                                                        );
 
                                                                        ecca.curvesDone ++;
@@ -4552,150 +4557,9 @@ public partial class ChronoJumpWindow
                                "none", //SpecialData
                                ep);
 
-               runEncoderCaptureNoRDotNetStart(es);
-       }
-       
-       private static Process pCaptureNoRDotNet;
-
-       //this has to here (and not in UtilEncode.cs) in order to be able to call: readingCurveFromR
-       private void runEncoderCaptureNoRDotNetStart(EncoderStruct es)
-       {
-LogB.Debug("A");
-               ProcessStartInfo pinfo;
-               //If output file is not given, R will try to write in the running folder
-               //in which we may haven't got permissions
-       
-               string pBin="";
-               pinfo = new ProcessStartInfo();
-
-               pBin="Rscript";
-               if (UtilAll.IsWindows()) {
-                       //on Windows we need the \"str\" to call without problems in path with spaces
-                       pBin = "\"" + System.IO.Path.Combine(Util.GetPrefixDir(), "bin" + 
Path.DirectorySeparatorChar + "Rscript.exe") + "\"";
-                       LogB.Information("pBin:", pBin);
-               }
-LogB.Debug("B");
-
-
-               string scriptOptions = UtilEncoder.PrepareEncoderGraphOptions(
-                               "none",         //title
-                               es, 
-                               false,  //neuromuscularProfile
-                               false   //translate (graphs)
-                               ).ToString();
-
-
-               string optionsFile = Path.GetTempPath() + "Roptions.txt";
-               TextWriter writer = File.CreateText(optionsFile);
-               writer.Write(scriptOptions);
-               writer.Flush();
-               writer.Close();
-               ((IDisposable)writer).Dispose();
-
-
-       
-               //on Windows we need the \"str\" to call without problems in path with spaces
-               //pinfo.Arguments = "\"" + "passToR.R" + "\" " + optionsFile;
-               pinfo.Arguments = "\"" + UtilEncoder.GetEncoderScriptCallCaptureNoRdotNet() + "\" " + 
optionsFile;
-       
-               LogB.Information("Arguments:", pinfo.Arguments);
-               LogB.Information("--- 1 --- " + optionsFile.ToString() + " ---");
-               LogB.Information("--- 2 --- " + pinfo.Arguments.ToString() + " ---");
-
-               pinfo.FileName=pBin;
-
-               pinfo.CreateNoWindow = true;
-               pinfo.UseShellExecute = false;
-               pinfo.RedirectStandardInput = true;
-               pinfo.RedirectStandardError = true;
-               //pinfo.RedirectStandardOutput = true; 
-
-               
-
-LogB.Debug("C");
-try {
-               pCaptureNoRDotNet = new Process();
-               pCaptureNoRDotNet.StartInfo = pinfo;
-               
-               // output will go here
-               //pCaptureNoRDotNet.OutputDataReceived += new DataReceivedEventHandler(readingCurveFromR);
-               pCaptureNoRDotNet.ErrorDataReceived += new DataReceivedEventHandler(readingCurveFromRerror);
-
-               pCaptureNoRDotNet.Start();
-
-               // Start asynchronous read of the output.
-               // Caution: This has to be called after Start
-               //pCaptureNoRDotNet.BeginOutputReadLine();
-               pCaptureNoRDotNet.BeginErrorReadLine();
-
-LogB.Debug("D");
-} catch {
-       Console.WriteLine("catched at runEncoderCaptureNoRDotNetStart");
-}
-//             LogB.Information(p.StandardOutput.ReadToEnd());
-//             LogB.Warning(p.StandardError.ReadToEnd());
-
-//             p.WaitForExit();
-
-//             while ( ! ( File.Exists(outputFileCheck) || CancelRScript ) );
+               encoderRProcCapture.StartOrContinue(es);
        }
-
-
        
-       /*
-        * unused, done while capturing
-        *
-       private void capturingSendCurveToR() 
-       {
-               if(! eccaCreated)
-                       return;
-
-               //LogB.Information("ecca.ecc.Count", ecca.ecc.Count.ToString());
-               //LogB.Information("ecca.curvesDone", ecca.curvesDone.ToString());
-               if(ecca.ecc.Count <= ecca.curvesDone) 
-                       return;
-                       
-               EncoderCaptureCurve ecc = (EncoderCaptureCurve) ecca.ecc[ecca.curvesDone];
-               string eccon = findEccon(true);
-               
-               if( ( ( eccon == "c" && ecc.up ) || eccon != "c" ) &&
-                               (ecc.endFrame - ecc.startFrame) > 0 ) 
-               {
-                       LogB.Information("Processing at capturingSendCurveToR... ");
-                       
-                       //on excentric-concentric discard if first curve is concentric
-                       if ( (eccon == "ec" || eccon == "ecS") && ecc.up && ecca.curvesAccepted == 0 ) {
-                               ecca.curvesDone ++;
-                               LogB.Warning("Discarded curve. eccentric-concentric and first curve is 
concentric.");
-                               return; 
-                       }
-
-                       double [] curve = new double[ecc.endFrame - ecc.startFrame];
-                       for(int k=0, j=ecc.startFrame; j < ecc.endFrame ; j ++) {
-                               //height += encoderReaded[j];
-                               curve[k]=encoderReaded[j];
-                               k++;
-                       }
-
-                       LogB.Information("Sending... ");
-                       UtilEncoder.RunEncoderCaptureNoRDotNetSendCurve(
-                                       pCaptureNoRDotNet, 
-                                       curve);
-
-                       ecca.curvesAccepted ++;
-               
-               }
-               ecca.curvesDone ++;
-       }
-       */
-
-       /*
-        * History
-        * 1) In the beginning we used RDotNet for C# - R communication. But it was buggy, complex, problems 
with try catch, ...
-        * 2) Then we used stdin,stdout,stderr communication. Worked fine on Linux and Windows but not in Mac
-        * 3) Then we used a capture.txt file created by R with a row for each curve. But reading it on 
windows from C# gives file access problems
-        * 4) Now we try to create one file for each curve and read it here with a try/catch
-        */
 
        private void deleteAllCapturedCurveFiles()
        {
@@ -4716,6 +4580,14 @@ LogB.Debug("D");
                        return(filenameBegins + "-00" + curveNum.ToString());   //eg. "filename-003"
        }
 
+       /*
+        * History
+        * 1) In the beginning we used RDotNet for C# - R communication. But it was buggy, complex, problems 
with try catch, ...
+        * 2) Then we used stdin,stdout,stderr communication. Worked fine on Linux and Windows but not in Mac
+        * 3) Then we used a capture.txt file created by R with a row for each curve. But reading it on 
windows from C# gives file access problems
+        * 4) Now we try to create one file for each curve and read it here with a try/catch
+        */
+
        static bool needToRefreshTreeviewCapture;
        static int encoderCaptureReadedLines;
        //private void readingCurveFromR (object sendingProcess, DataReceivedEventArgs curveFromR)
@@ -4808,14 +4680,6 @@ LogB.Debug("D");
                        needToRefreshTreeviewCapture = true;
                }
        }
-       private void readingCurveFromRerror (object sendingProcess, DataReceivedEventArgs curveFromR)
-       {
-               if (!String.IsNullOrEmpty(curveFromR.Data))
-               {
-                       //use Warning because it's used also to print flow messages
-                       LogB.Warning(curveFromR.Data);
-               }
-       }
                                
        static bool needToCallPrepareEncoderGraphs;
        private bool pulseGTKEncoderCaptureAndCurves ()
@@ -4839,8 +4703,13 @@ LogB.Debug("D");
                                encoderStopVideoRecord();
                        }
 
+                       /*
                        UtilEncoder.RunEncoderCaptureNoRDotNetSendEnd(pCaptureNoRDotNet);
                        pCaptureNoRDotNet.WaitForExit();
+                       */
+                       encoderRProcCapture.SendCaptureEnd();
+                       //maybe here wait for an R ending signal. R process should not end, but will be 
waiting next capture
+
                        
                        LogB.ThreadEnded(); 
                        return false;
diff --git a/src/utilEncoder.cs b/src/utilEncoder.cs
index 3f2788e..d807b1b 100644
--- a/src/utilEncoder.cs
+++ b/src/utilEncoder.cs
@@ -343,33 +343,6 @@ public class UtilEncoder
        }
 
 
-
-       //here curve is sent compressed (string. eg: "0*5 1 0 -1*3 2")
-       public static void RunEncoderCaptureNoRDotNetSendCurve(Process p, double heightAtStart, string 
curveCompressed)
-       {
-               LogB.Debug("writing line 1 -->");
-               
-               string curveSend = "ps " + Util.ConvertToPoint(heightAtStart);
-               LogB.Debug("curveSend [heightAtStart]",curveSend);
-               p.StandardInput.WriteLine(curveSend);
-                                                               
-               curveSend = curveCompressed;
-               
-               //TODO convert comma to point in this doubles
-
-               LogB.Debug("curveSend [displacement array]",curveSend);
-               p.StandardInput.WriteLine(curveSend);   //this will send some lines because compressed data 
comes with '\n's
-               p.StandardInput.WriteLine("E");         //this will mean the 'E'nd of the curve. Then data 
can be uncompressed on R
-               
-               LogB.Debug("<-- writen line 1");
-       }
-       
-       public static void RunEncoderCaptureNoRDotNetSendEnd(Process p)
-       {
-               LogB.Debug("sending end line");
-               p.StandardInput.WriteLine("Q");
-       }
-
        /*
         * this method don't use RDotNet, then has to call call_graph.R, who will call graph.R
         * and has to write a Roptions.txt file


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]