[chronojump] bye bye RDotNet 1
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] bye bye RDotNet 1
- Date: Thu, 15 Jan 2015 01:26:35 +0000 (UTC)
commit f126d41655fd0ccc13f87f91b74f7975692d999c
Author: Xavier de Blas <xaviblas gmail com>
Date: Thu Jan 15 02:26:00 2015 +0100
bye bye RDotNet 1
src/constants.cs | 5 +-
src/gui/encoder.cs | 193 ++++++++++++++++++++++++++++++++++++++++++----------
src/utilEncoder.cs | 119 ++++++++++++++++++++++++++++++--
3 files changed, 272 insertions(+), 45 deletions(-)
---
diff --git a/src/constants.cs b/src/constants.cs
index 8de6184..8407ccf 100644
--- a/src/constants.cs
+++ b/src/constants.cs
@@ -695,8 +695,9 @@ public class Constants
* chronojump / encoder / sessionID / graphs
*/
- public static string EncoderScriptCaptureLinux = "pyserial_pyper.py";
- public static string EncoderScriptCaptureWindows = "pyserial_pyper_windows.exe";
+ //public static string EncoderScriptCapturePythonLinux = "pyserial_pyper.py";
+ //public static string EncoderScriptCapturePythonWindows = "pyserial_pyper_windows.exe";
+ public static string EncoderScriptCaptureNoRDotNet = "capture.R";
public static string EncoderScriptCallGraph = "call_graph.R";
public static string EncoderScriptGraph = "graph.R";
public static string EncoderScriptInertiaMomentum = "inertia-momentum.R";
diff --git a/src/gui/encoder.cs b/src/gui/encoder.cs
index e886f2f..95e7b49 100644
--- a/src/gui/encoder.cs
+++ b/src/gui/encoder.cs
@@ -15,7 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Copyright (C) 2004-2014 Xavier de Blas <xaviblas gmail com>
+ * Copyright (C) 2004-2015 Xavier de Blas <xaviblas gmail com>
*/
using System;
@@ -29,6 +29,7 @@ using System.Threading;
using Mono.Unix;
using System.Linq;
using RDotNet;
+using System.Diagnostics; //for detect OS and for Process
public partial class ChronoJumpWindow
@@ -272,6 +273,7 @@ public partial class ChronoJumpWindow
Constants.Status RInitialized;
+ bool useRDotNet = false; //on 1.5.0 no more RDotNet use
private void encoderInitializeStuff() {
encoder_pulsebar_capture.Fraction = 1;
@@ -1951,6 +1953,7 @@ public partial class ChronoJumpWindow
}
REngine rengine;
+ static Process processCaptureNoRDotNet;
private bool runEncoderCaptureCsharp(string title, int time, string outputData1, string port)
@@ -1965,7 +1968,8 @@ public partial class ChronoJumpWindow
LogB.Information("sp created");
sp.Open();
LogB.Information("sp opened");
-
+
+
encoderCaptureCountdown = time;
//int recordingTime = es.Ep.Time * 1000;
int recordingTime = time * 1000;
@@ -2131,13 +2135,44 @@ public partial class ChronoJumpWindow
if(startFrame < 0)
startFrame = 0;
+ bool previousWasUp = ! Util.IntToBool(directionNow); //if we
go now UP, then record previous DOWN phase
EncoderCaptureCurve ecc = new EncoderCaptureCurve(
- ! Util.IntToBool(directionNow), //if we go
now UP, then record previous DOWN phase
+ previousWasUp,
startFrame,
(i - directionChangeCount + lastNonZero)/2
//endFrame
//to find endFrame, first substract
directionChangePeriod from i
//then find the middle point between that and
lastNonZero
);
+
+
+ if(! useRDotNet) {
+ //on 1.4.9 secundary thread was capturing
+ //while main thread was calculing with RDotNet and
updating GUI
+ //
+ //on 1.5.0 secundary thread is capturing and sending
data to R process
+ //while main thread is reading data coming from R and
updating GUI
+ //
+ // send the curve
+ string eccon = findEccon(true);
+ LogB.Debug("curve stuff" + ecc.startFrame + ":" +
ecc.endFrame + ":" + encoderReaded.Length);
+ if(ecc.endFrame - ecc.startFrame > 0 ) {
+ 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++;
+ }
+ if( ( eccon == "c" && previousWasUp ) ||
eccon != "c" ) {
+
UtilEncoder.RunEncoderCaptureNoRDotNetSendCurve(
+
processCaptureNoRDotNet,
+ curve);
+ ecca.curvesDone ++;
+ ecca.curvesAccepted ++;
+ }
+ // end of send the curve
+ }
+ }
+
ecca.ecc.Add(ecc);
@@ -2145,6 +2180,7 @@ public partial class ChronoJumpWindow
directionChangeCount = 0;
directionCompleted = directionNow;
+
}
}
@@ -2176,7 +2212,7 @@ public partial class ChronoJumpWindow
writer.Close();
((IDisposable)writer).Dispose();
LogB.Debug("runEncoderCaptureCsharp ended");
-
+
return true;
}
@@ -4367,22 +4403,27 @@ public partial class ChronoJumpWindow
LogB.Information("encoderThreadStart begins");
if( runEncoderCaptureCsharpCheckPort(chronopicWin.GetEncoderPort()) ) {
if(action == encoderActions.CAPTURE) {
- if(RInitialized == Constants.Status.UNSTARTED)
- rengine =
UtilEncoder.RunEncoderCaptureCsharpInitializeR(rengine, out RInitialized);
-
- /*
- * if error means a problem with RDotNet, not necessarily a problem
with R
- * we can contnue but without realtime data
- *
- if(RInitialized == Constants.Status.ERROR) {
- new DialogMessage(Constants.MessageTypes.WARNING,
- Catalog.GetString("Sorry. Error doing
graph.") +
- "\n" + Catalog.GetString("Maybe R or EMD are
not installed.") +
- "\n\nhttp://www.r-project.org/");
- return;
- }
- */
+
+ if(useRDotNet) {
+ if(RInitialized == Constants.Status.UNSTARTED)
+ rengine =
UtilEncoder.RunEncoderCaptureCsharpInitializeR(rengine, out RInitialized);
+
+ /*
+ * if error means a problem with RDotNet, not necessarily a
problem with R
+ * we can contnue but without realtime data
+ *
+ if(RInitialized == Constants.Status.ERROR) {
+ new DialogMessage(Constants.MessageTypes.WARNING,
+ Catalog.GetString("Sorry. Error doing graph.") +
+ "\n" + Catalog.GetString("Maybe R or EMD are not
installed.") +
+ "\n\nhttp://www.r-project.org/");
+ return;
+ }
+ */
+ } else
+ processCaptureNoRDotNet =
UtilEncoder.RunEncoderCaptureNoRDotNetInitialize();
}
+
prepareEncoderGraphs();
eccaCreated = false;
@@ -4401,11 +4442,15 @@ public partial class ChronoJumpWindow
massDisplacedEncoder = UtilEncoder.GetMassByEncoderConfiguration(
encoderConfigurationCurrent,
findMass(Constants.MassType.BODY),
findMass(Constants.MassType.EXTRA),
getExercisePercentBodyWeightFromCombo() );
+
+
}
if(action == encoderActions.CAPTURE) {
captureCurvesBarsData = new ArrayList();
updatingEncoderCaptureGraphRCalc = false;
+
+ curvesSentToR = 0;
encoderThread = new Thread(new ThreadStart(encoderDoCaptureCsharp));
GLib.Idle.Add (new GLib.IdleHandler
(pulseGTKEncoderCaptureAndCurves));
}
@@ -4534,33 +4579,109 @@ public partial class ChronoJumpWindow
pen_selected_encoder_capture.SetLineAttributes (2, Gdk.LineStyle.Solid, Gdk.CapStyle.NotLast,
Gdk.JoinStyle.Miter);
}
+
+ /*
+ * 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(
+ processCaptureNoRDotNet,
+ curve);
+
+ ecca.curvesAccepted ++;
+
+ }
+ ecca.curvesDone ++;
+ }
+ */
+
+ int curvesSentToR;
+ private void readingCurveFromR()
+ {
+ if(! eccaCreated)
+ return;
+
+ if(ecca.curvesAccepted > curvesSentToR) {
+ LogB.Information("ReadingCurveFromR");
+
+ string str = processCaptureNoRDotNet.StandardOutput.ReadLine();
+ if(str != null && str != "" && str != "\n")
+ Console.WriteLine(str);
+
+ curvesSentToR ++;
+ }
+ }
+
private bool pulseGTKEncoderCaptureAndCurves ()
{
if(! encoderThread.IsAlive || encoderProcessCancel) {
LogB.ThreadEnding();
finishPulsebar(encoderActions.CURVES);
+
+ if(! useRDotNet)
+ UtilEncoder.RunEncoderCaptureNoRDotNetSendEnd(processCaptureNoRDotNet);
LogB.ThreadEnded();
return false;
}
- if(capturingCsharp == encoderCaptureProcess.CAPTURING) {
+ if(capturingCsharp == encoderCaptureProcess.CAPTURING)
+ {
updatePulsebar(encoderActions.CAPTURE); //activity on pulsebar
-
- //calculations with RDotNet are not available yet on inertial
- if(encoderConfigurationCurrent.has_inertia) {
- UtilGtk.ErasePaint(encoder_capture_curves_bars_drawingarea,
encoder_capture_curves_bars_pixmap);
- layout_encoder_capture_curves_bars.SetMarkup("Realtime inertial
calculations\nnot available in this version");
- int textWidth = 1;
- int textHeight = 1;
- int graphWidth=encoder_capture_curves_bars_drawingarea.Allocation.Width;
- layout_encoder_capture_curves_bars.GetPixelSize(out textWidth, out
textHeight);
- encoder_capture_curves_bars_pixmap.DrawLayout (pen_black_encoder_capture,
- Convert.ToInt32( (graphWidth/2) - textWidth/2), 0, //x, y
- layout_encoder_capture_curves_bars);
-
- updateEncoderCaptureGraph(true, false, false); //graphSignal, not calcCurves,
not plotCurvesBars
- } else
- updateEncoderCaptureGraph(true, true, true); //graphSignal, calcCurves,
plotCurvesBars
+
+ if(useRDotNet) {
+ //calculations with RDotNet are not available yet on inertial
+ if(encoderConfigurationCurrent.has_inertia) {
+ UtilGtk.ErasePaint(encoder_capture_curves_bars_drawingarea,
encoder_capture_curves_bars_pixmap);
+ layout_encoder_capture_curves_bars.SetMarkup("Realtime inertial
calculations\nnot available in this version");
+ int textWidth = 1;
+ int textHeight = 1;
+ int
graphWidth=encoder_capture_curves_bars_drawingarea.Allocation.Width;
+ layout_encoder_capture_curves_bars.GetPixelSize(out textWidth, out
textHeight);
+ encoder_capture_curves_bars_pixmap.DrawLayout
(pen_black_encoder_capture,
+ Convert.ToInt32( (graphWidth/2) - textWidth/2), 0,
//x, y
+ layout_encoder_capture_curves_bars);
+
+ updateEncoderCaptureGraph(true, false, false); //graphSignal, not
calcCurves, not plotCurvesBars
+ } else
+ updateEncoderCaptureGraph(true, true, true); //graphSignal,
calcCurves, plotCurvesBars
+ } else {
+ //capturingSendCurveToR(); //unused, done while capturing
+ readingCurveFromR();
+
+ updateEncoderCaptureGraph(true, false, false); //graphSignal, no calcCurves,
no plotCurvesBars
+ }
LogB.Debug(" Cap:" + encoderThread.ThreadState.ToString());
} else if(capturingCsharp == encoderCaptureProcess.STOPPING) {
diff --git a/src/utilEncoder.cs b/src/utilEncoder.cs
index b74aaf1..b4bc615 100644
--- a/src/utilEncoder.cs
+++ b/src/utilEncoder.cs
@@ -22,7 +22,7 @@ using System;
//using System.Data;
using System.Text; //StringBuilder
using System.Collections; //ArrayList
-using System.Diagnostics; //for detect OS
+using System.Diagnostics; //for detect OS and for Process
using System.IO; //for detect OS
using System.Linq; //RDotNet
@@ -165,14 +165,20 @@ public class UtilEncoder
return false;
}
-
- private static string getEncoderScriptCapture() {
+
+ /*
+ private static string getEncoderScriptCapturePython() {
if(UtilAll.IsWindows())
return System.IO.Path.Combine(Util.GetPrefixDir(),
- "bin" + Path.DirectorySeparatorChar + "encoder",
Constants.EncoderScriptCaptureWindows);
+ "bin" + Path.DirectorySeparatorChar + "encoder",
Constants.EncoderScriptCapturePythonWindows);
else
return System.IO.Path.Combine(
- Util.GetDataDir(), "encoder", Constants.EncoderScriptCaptureLinux);
+ Util.GetDataDir(), "encoder",
Constants.EncoderScriptCapturePythonLinux);
+ }
+ */
+ private static string getEncoderScriptCaptureNoRdotNet() {
+ return System.IO.Path.Combine(
+ Util.GetDataDir(), "encoder", Constants.EncoderScriptCaptureNoRDotNet);
}
@@ -239,14 +245,14 @@ public class UtilEncoder
//on linux we execute python and call to the py file
//also on windows we need the full path to find R
if (UtilAll.IsWindows()) {
- pBin=getEncoderScriptCapture();
+ pBin=getEncoderScriptCapturePython();
pinfo.Arguments = title + " " + es.OutputData1 + " " + es.Ep.ToString1() + " " + port
+ " " + changeSpaceToSpaceMark(
System.IO.Path.Combine(Util.GetPrefixDir(), "bin" +
Path.DirectorySeparatorChar + "R.exe"));
}
else {
pBin="python";
- pinfo.Arguments = getEncoderScriptCapture() + " " + title + " " +
+ pinfo.Arguments = getEncoderScriptCapturePython() + " " + title + " " +
es.OutputData1 + " " + es.Ep.ToString1() + " " + port;
}
@@ -466,6 +472,105 @@ public class UtilEncoder
}
*/
+ //Process pCaptureNoRDotNet;
+ public static Process RunEncoderCaptureNoRDotNetInitialize()
+ {
+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 optionsFile = Path.GetTempPath() + "Roptions.txt";
+ TextWriter writer = File.CreateText(optionsFile);
+ //writer.Write("some options for the capture, like end at n seconds or maybe not needed
because we can send the Q from the software");
+ writer.Write(GetEncoderScriptUtilR() + "\n" +
+ UtilEncoder.GetEncoderCaptureNoRDotNetStart() + "\n" + //curve sent to R
+ UtilEncoder.GetEncoderCaptureNoRDotNetProcessed() + "\n" + //curve
processed from R (maybe discardedwith some text file)
+ UtilEncoder.GetEncoderCaptureNoRDotNetEnded() //signal that
processing ended (maybe not needed)
+ writer.Flush();
+ writer.Close();
+ ((IDisposable)writer).Dispose();
+ */
+
+ /*
+ if (UtilAll.IsWindows()) {
+ //On win32 R understands backlash as an escape character and
+ //a file path uses Unix-like path separator '/'
+ optionsFile = optionsFile.Replace("\\","/");
+ }
+ */
+ //on Windows we need the \"str\" to call without problems in path with spaces
+ //pinfo.Arguments = "\"" + "passToR.R" + "\" " + optionsFile;
+ pinfo.Arguments = "\"" +
"/home/xavier/informatica/progs_meus/chronojump/chronojump/no-rdotnet/passToR.R" + "\"";
+
+ LogB.Information("Arguments:", pinfo.Arguments);
+ //LogB.Information("--- 1 --- " + optionsFile.ToString() + " ---");
+ //LogB.Information("--- 2 --- " + scriptOptions + " ---");
+ LogB.Information("--- 3 --- " + pinfo.Arguments.ToString() + " ---");
+
+// string outputFileCheck = UtilEncoder.UtilEncoder.GetEncoderCaptureNoRDotNetEnded();
+
+ pinfo.FileName=pBin;
+
+ pinfo.CreateNoWindow = true;
+ pinfo.UseShellExecute = false;
+ pinfo.RedirectStandardInput = true;
+ pinfo.RedirectStandardError = true;
+ pinfo.RedirectStandardOutput = true;
+
+/*
+ //delete output file check(s)
+ LogB.Information("Deleting... " + outputFileCheck);
+ if (File.Exists(outputFileCheck))
+ File.Delete(outputFileCheck);
+ */
+
+
+LogB.Debug("C");
+ Process pCaptureNoRDotNet = new Process();
+ pCaptureNoRDotNet.StartInfo = pinfo;
+ pCaptureNoRDotNet.Start();
+
+LogB.Debug("D");
+// LogB.Information(p.StandardOutput.ReadToEnd());
+// LogB.Warning(p.StandardError.ReadToEnd());
+
+// p.WaitForExit();
+
+// while ( ! ( File.Exists(outputFileCheck) || CancelRScript ) );
+
+ return pCaptureNoRDotNet;
+ }
+
+ public static void RunEncoderCaptureNoRDotNetSendCurve(Process p, double [] d)
+ {
+ LogB.Debug("writing line 1");
+ string curveSend = string.Join(" ", Array.ConvertAll(d, x => x.ToString()));
+
+ //TODO convert comma to point in this doubles
+
+ LogB.Debug("curveSend",curveSend);
+ p.StandardInput.WriteLine(curveSend);
+ }
+ public static void RunEncoderCaptureNoRDotNetSendEnd(Process p)
+ {
+ LogB.Debug("sending end line");
+ p.StandardInput.WriteLine("Q");
+ p.WaitForExit();
+ }
+
/*
* 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]