[chronojump] ForceSensor can export session modelized RFDs (1st code working)



commit 4d9adab7a3db94a3122ff51d2333fa5e8149bc05
Author: Xavier de Blas <xaviblas gmail com>
Date:   Wed Feb 3 13:25:24 2021 +0100

    ForceSensor can export session modelized RFDs (1st code working)

 glade/app1.glade                   |  48 +++++++---
 src/forceSensor.cs                 |  17 ++++
 src/gui/app1/forceSensorAnalyze.cs | 189 ++++++++++++++++++++++++++++++++++++-
 src/utilEncoder.cs                 |   3 +
 4 files changed, 241 insertions(+), 16 deletions(-)
---
diff --git a/glade/app1.glade b/glade/app1.glade
index 94846efd..018bd514 100644
--- a/glade/app1.glade
+++ b/glade/app1.glade
@@ -21049,9 +21049,6 @@ Concentric</property>
                                                             <property name="column_spacing">16</property>
                                                             <property name="row_spacing">2</property>
                                                             <child>
-                                                            <placeholder/>
-                                                            </child>
-                                                            <child>
                                                             <widget class="GtkButton" 
id="button_force_sensor_analyze_load">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">True</property>
@@ -21747,6 +21744,21 @@ Concentric</property>
                                                             <property name="y_options"/>
                                                             </packing>
                                                             </child>
+                                                            <child>
+                                                            <widget class="GtkButton" 
id="button_force_sensor_export_session">
+                                                            <property name="label">Export session</property>
+                                                            <property name="visible">True</property>
+                                                            <property name="can_focus">True</property>
+                                                            <property name="receives_default">True</property>
+                                                            <signal name="clicked" 
handler="on_button_force_sensor_export_session_clicked" swapped="no"/>
+                                                            </widget>
+                                                            <packing>
+                                                            <property name="top_attach">1</property>
+                                                            <property name="bottom_attach">2</property>
+                                                            <property name="x_options"/>
+                                                            <property name="y_options"/>
+                                                            </packing>
+                                                            </child>
                                                           </widget>
                                                           <packing>
                                                             <property name="expand">False</property>
@@ -23610,6 +23622,9 @@ Concentric</property>
                                                             <child>
                                                             <placeholder/>
                                                             </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
@@ -28456,6 +28471,18 @@ Concentric</property>
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">6</property>
                                                             <child>
+                                                            <widget class="GtkLabel" 
id="label_video_encoder_tests_will_be_filmed">
+                                                            <property name="can_focus">False</property>
+                                                            <property name="label" translatable="yes">Tests 
will be filmed</property>
+                                                            </widget>
+                                                            <packing>
+                                                            <property name="expand">False</property>
+                                                            <property name="fill">False</property>
+                                                            <property name="pack_type">end</property>
+                                                            <property name="position">0</property>
+                                                            </packing>
+                                                            </child>
+                                                            <child>
                                                             <widget class="GtkHBox" 
id="hbox_video_encoder_capturing">
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">4</property>
@@ -28492,18 +28519,6 @@ Concentric</property>
                                                             </packing>
                                                             </child>
                                                             <child>
-                                                            <widget class="GtkLabel" 
id="label_video_encoder_tests_will_be_filmed">
-                                                            <property name="can_focus">False</property>
-                                                            <property name="label" translatable="yes">Tests 
will be filmed</property>
-                                                            </widget>
-                                                            <packing>
-                                                            <property name="expand">False</property>
-                                                            <property name="fill">False</property>
-                                                            <property name="pack_type">end</property>
-                                                            <property name="position">0</property>
-                                                            </packing>
-                                                            </child>
-                                                            <child>
                                                             <widget class="GtkHBox" 
id="hbox_video_encoder_no_capturing">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
@@ -36780,6 +36795,9 @@ then click this button.</property>
                                                             <child>
                                                             <placeholder/>
                                                             </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
diff --git a/src/forceSensor.cs b/src/forceSensor.cs
index bd442cdd..515e32c3 100644
--- a/src/forceSensor.cs
+++ b/src/forceSensor.cs
@@ -306,6 +306,10 @@ public class ForceSensor
                get { return uniqueID; }
                set { uniqueID = value; }
        }
+       public int PersonID
+       {
+               get { return personID; }
+       }
        public int ExerciseID
        {
                get { return exerciseID; }
@@ -1263,6 +1267,19 @@ public class ForceSensorRFD
                return function.ToString() + ";" + type.ToString() + ";" + num1.ToString() + ";" + 
num2.ToString();
        }
 
+       public string ToExport(bool translated, string sep)
+       {
+               return FunctionPrint(translated) + sep +
+                       TypePrint(translated) + sep +
+                       num1 + sep +
+                       num2;
+       }
+
+       public bool Active
+       {
+               get { return active; }
+       }
+
        public static string Function_RAW_name
        {
                get { return function_RAW_name; }
diff --git a/src/gui/app1/forceSensorAnalyze.cs b/src/gui/app1/forceSensorAnalyze.cs
index 9e230e19..78d8f8ed 100644
--- a/src/gui/app1/forceSensorAnalyze.cs
+++ b/src/gui/app1/forceSensorAnalyze.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) 2018-2020   Xavier de Blas <xaviblas gmail com>
+ * Copyright (C) 2018-2021   Xavier de Blas <xaviblas gmail com>
  */
 
 using System;
@@ -24,6 +24,7 @@ using Gtk;
 using Gdk;
 using Glade;
 using System.Text; //StringBuilder
+using System.Collections; //ArrayList
 using System.Collections.Generic; //List<T>
 using Mono.Unix;
 
@@ -680,6 +681,192 @@ public partial class ChronoJumpWindow
 
        bool force_sensor_ai_drawingareaShown = false;
 
+       //TODO: separate in thread
+       private void on_button_force_sensor_export_session_clicked (object o, EventArgs args)
+       {
+               // 1) Select force sensor files and force sensor exercises
+               List<ForceSensor> fs_l = SqliteForceSensor.Select(false, -1, -1, currentSession.UniqueID);
+               ArrayList personSession_l = 
SqlitePersonSession.SelectCurrentSessionPersons(currentSession.UniqueID, true);
+               ArrayList fsEx_l = SqliteForceSensorExercise.Select (false, -1, false);
+               List<string> exportedRFDs = new List<string>();
+
+               foreach(ForceSensor fs in fs_l)
+               {
+                       //check fs is ok
+                       if(fs == null || ! Util.FileExists(fs.FullURL))
+                               continue;
+
+                       //check fs has data
+                       List<string> contents = Util.ReadFileAsStringList(fs.FullURL);
+                       if(contents.Count < 3)
+                       {
+                               new DialogMessage(Constants.MessageTypes.WARNING, Constants.FileEmptyStr());
+                               return;
+                       }
+
+                       //get the person
+                       string personName = "";
+                       double personWeight = 0;
+                       bool found = false;
+                       foreach(PersonAndPS paps in personSession_l)
+                       {
+                               if(paps.p.UniqueID == fs.PersonID)
+                               {
+                                       personName = paps.p.Name;
+                                       personWeight = paps.ps.Weight;
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if(! found)
+                               continue;
+
+                       //get the exercise
+                       found = false;
+                       ForceSensorExercise fsEx = new ForceSensorExercise();
+                       foreach(ForceSensorExercise fsExTemp in fsEx_l)
+                               if(fsExTemp.UniqueID == fs.ExerciseID)
+                               {
+                                       fsEx = fsExTemp;
+                                       found = true;
+                                       break;
+                               }
+                       if(! found)
+                               continue;
+
+                       double eccMinDispl = fsEx.GetEccOrConMinMaybePreferences(true,
+                                       preferences.forceSensorElasticEccMinDispl,
+                                       preferences.forceSensorNotElasticEccMinForce);
+                       double conMinDispl = fsEx.GetEccOrConMinMaybePreferences(false,
+                                       preferences.forceSensorElasticConMinDispl,
+                                       preferences.forceSensorNotElasticConMinForce);
+
+                       // 3) create fsAI (includes the repetitions
+                       fsAI = new ForceSensorAnalyzeInstant(
+                                       fs.FullURL,
+                                       force_sensor_ai_drawingarea.Allocation.Width,
+                                       force_sensor_ai_drawingarea.Allocation.Height,
+                                       -1, -1,
+                                       fsEx, personWeight,
+                                       fs.CaptureOption, fs.Stiffness,
+                                       eccMinDispl, conMinDispl
+                                       );
+
+                       // 4) call R
+                       int imageWidth = UtilGtk.WidgetWidth(viewport_force_sensor_graph);
+                       int imageHeight = UtilGtk.WidgetHeight(viewport_force_sensor_graph);
+                       if(imageWidth < 300)
+                               imageWidth = 300; //Not crash R with a png height of -1 or "figure margins 
too large"
+                       if(imageHeight < 300)
+                               imageHeight = 300; //Not crash R with a png height of -1 or "figure margins 
too large"
+
+                       int duration = -1;
+                       if(radio_force_duration_seconds.Active)
+                               duration = Convert.ToInt32(spin_force_duration_seconds.Value);
+
+                       //string title = lastForceSensorFile;
+                       string title = personName;
+                       string exercise = fsEx.Name;
+                       if (UtilAll.IsWindows()) {
+                               title = Util.ConvertToUnicode(title);
+                               exercise = Util.ConvertToUnicode(exercise);
+                       }
+                       if (title == null || title == "")
+                               title = "unnamed";
+
+                       //copy file to tmp to be written readed by R
+                       File.Copy(fs.FullURL, UtilEncoder.GetmifCSVFileName(), true); //can be overwritten
+
+                       //delete result file
+                       Util.FileDelete(UtilEncoder.GetmifExportFileName());
+
+                       //TODO: només les concèntriques
+                       foreach(ForceSensorRepetition rep in fsAI.ForceSensorRepetition_l)
+                       {
+                               ForceSensorGraph fsg = new ForceSensorGraph(fs.CaptureOption, rfdList, 
impulse,
+                                               duration, 
Convert.ToInt32(spin_force_rfd_duration_percent.Value),
+                                               title, exercise, fs.DateTimePublic, new TriggerList(),
+                                               rep.sampleStart, rep.sampleEnd, 
preferences.forceSensorStartEndOptimized,
+                                               Util.CSVDecimalColumnIsPoint(UtilEncoder.GetmifCSVFileName(), 
1)                // (*)
+                                               );
+
+                               bool success = fsg.CallR(imageWidth -5, imageHeight -5);
+                       }
+
+                       //TODO: or check cancel when there is a thread, also R should write something blank 
if there is any problem
+                       //also the problem with this code is: if R code fails for any reason (bad data), will 
exit R code and this file will never be created
+                       /*
+                       LogB.Information("Waiting creation of file... ");
+                       while ( ! ( Util.FileReadable(UtilEncoder.GetmifExportFileName())))
+                               ;
+                               */
+
+                       if(File.Exists(UtilEncoder.GetmifExportFileName()))
+                       {
+                               List<string> repRFDs = 
Util.ReadFileAsStringList(UtilEncoder.GetmifExportFileName());
+                               int countRep = 0; //0 will be the header
+                               foreach(string row in repRFDs)
+                               {
+                                       //discard header
+                                       if(countRep == 0)
+                                       {
+                                               countRep ++;
+                                               continue;
+                                       }
+                                       //TODO: respect latin/not latin (decimal character, column separator)
+                                       exportedRFDs.Add(personName + ";" + fs.DateTimePublic + ";" +
+                                                       fsEx.Name + ";" + (countRep++).ToString() + ";" + 
fs.Laterality + ";" +
+                                                       row);
+                               }
+                       }
+               }
+
+               string destination = UtilEncoder.GetmifExportFileName();
+               Util.FileDelete(destination);
+               try {
+                       //this overwrites if needed
+                       TextWriter writer = File.CreateText(destination);
+
+                       string sep = " ";
+                       if (preferences.CSVExportDecimalSeparator == "COMMA")
+                               sep = ";";
+                       else
+                               sep = ",";
+
+                       //write header
+                       string [] headers = { "Person", "date", "Exercise", "Repetition", "Laterality"};
+                       int i = 0;
+                       foreach(ForceSensorRFD rfd in rfdList)
+                       {
+                               if(rfdList[i].Active)
+                                       headers = Util.AddArrayString(headers,
+                                                       string.Format("RFD{0}", i+1) + "_" + 
rfd.ToExport(true, "_"),
+                                                       false);
+                               i ++;
+                       }
+                       ForceSensorImpulse tempImpulse = getImpulseValue ();
+                       if(tempImpulse.Active)
+                               headers = Util.AddArrayString(headers,
+                                               Catalog.GetString("Impulse") + "_" + 
tempImpulse.ToExport(true, "_"),
+                                               false);
+
+                       writer.WriteLine(Util.RemoveNewLine(Util.StringArrayToString(headers, sep), false));
+
+                       //write data
+                       foreach(string str in exportedRFDs)
+                               writer.WriteLine(str);
+
+                       writer.Flush();
+                       writer.Close();
+                       ((IDisposable)writer).Dispose();
+               } catch {
+                       string myString = string.Format(
+                                       Catalog.GetString("Cannot save file {0} "), destination);
+                       new DialogMessage(Constants.MessageTypes.WARNING, myString);
+               }
+
+       }
+
        private void forceSensorDoGraphAI(bool windowResizedAndZoom)
        {
                if(lastForceSensorFullPath == null || lastForceSensorFullPath == "")
diff --git a/src/utilEncoder.cs b/src/utilEncoder.cs
index 2f30dd25..df190554 100644
--- a/src/utilEncoder.cs
+++ b/src/utilEncoder.cs
@@ -263,6 +263,9 @@ public class UtilEncoder
        public static string GetmifTempFileName() {
                return Path.Combine(Path.GetTempPath(), "cj_mif_Graph.png");
        }
+       public static string GetmifExportFileName() {
+               return Path.Combine(Path.GetTempPath(), "cj_mif_export.csv");
+       }
 
        /********** end of r-scripts paths ************/
 


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