[chronojump] Leave opened encoder R Processes (capture done)
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Leave opened encoder R Processes (capture done)
- Date: Wed, 22 Apr 2015 17:05:14 +0000 (UTC)
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]