OSCR

Role of spinal sensorimotor circuits in triphasic muscle command: a simulation approach using goal exploration process.

Code ↔ Paper

5 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 5 matches
  1. [1] § Methods › Brief overview of rGEP ↔ makeGraphs.py, lines 4243–4296 · score 0.70 · behavior space, closest behavior, valid behaviors, behavior domain, inside, chosen
  2. [2] § Results › Analysis of triphasic patterns in the various models › Elaboration of triphasic commands in spinal sensorimotor networks ↔ DialogChoose_in_List.py, lines 448–504 · score 0.67 · Ext PN, ExtAlpha, FlxPN, FlxAlpha, sensory neurons
  3. [3] § Results › Analysis of triphasic patterns in the various models › Elaboration of triphasic commands in spinal sensorimotor networks ↔ DialogChoose_in_List.py, lines 448–504 · score 0.66 · ExtAlpha, ExtPN, FlxPN, FlxAlpha, gamma, sensory
  4. [4] § Methods › Software’s used in simulations ↔ class_animatLabModel.py, lines 1–34 · score 0.52 · python3.8, AnimatLab, synapses, models
  5. [5] § Methods › Musculoskeletal system ↔ makeGraphs.py, lines 4243–4296 · score 0.52 · behavior space, closest behavior, behavior domain, parent, durations, speed

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 4,749 lines · 195 KB · no license · 2 matches

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Mon Feb 19 2018
  4. This script select a file in a chosen directory
  5. @author: Solene Lambert & Daniel Cattaert
  6. When a folder is selected (in the saved directory) - > model_dir
  7. (1) Plot separately Deb, Max, Fin values for each selected chart column
  8. Each plot represents the values for each const parameter and all trials
  9. Thee results are plotted in different colors for different mvt durations
  10. Results for the different angles are on separate sheeet graph
  11. these graphs are saved in the model_dir
  12. (2) Plots of the elbow movementfor each template
  13. Each plot represents the template and all movements obtained with the
  14. different constant values (for example Ia->MN sunapse strength)
  15. these graphs are saved in each folder specific to a movement template
  16. (i.e. angles and mvt duration)
  17. (3) Plot of superimposed movements of same angles and different durations
  18. Possibility to choose the constant values to plot results
  19. Plot relationship between parameters
  20. (1) Builds graphs of chosen parameter values. Each graph represents
  21. the adaptation of the parameter value for each value of the constant
  22. parameter (and for all selected trials). Different mvt durations are
  23. ploted with different lines. The different angles are plotted on different
  24. files.
  25. (2) Draws and saves correlation graphs for each angle_duration condition
  26. (3) Draws and saves a matrix of correlation graphs with color codes
  27. New series of procedures added for metrics of optimization methods.
  28. class GEPGraphsMetrics containing a "grid" method (grid_method) that builts
  29. a grid on behaviour space (40x40) in order to calculate the number of
  30. elements of the grid in which a behavior (at least one) was found.
  31. Then this methods builds the function nbboxes=f(nbRuns) with a step=100
  32. runs (i.e. for 7500 runs we get 75 points).
  33. Builts the corresponding graph (and saves it), with the indication of the
  34. value of span for each run series (numbers on the curve), and the type of
  35. run (reparam, GEPrand, CMAE) with a color code.
  36. 1) "metrics" has been modified to allow re-use of the present df_parremai
  37. and df_bhvremain dataframes. A message box is used to ask the user what to
  38. do either keep these dataframes, or load a new one.
  39. 2)When calling "metrics" the previously present BhvWindow is erased
  40. 3)If the newly selected directory contains only one GepData folder then if
  41. this directory is the same as the one present in memory, the asim file is
  42. not red again
  43. 4) When selecting a single directory in which GEPdata folder contains a
  44. series of runs (GEPdata00.par,GEPdata01.par,... GEPdataii.par) it
  45. is proposed to choose a given run (in a table, select check button case)
  46. 1) windows are now disposed and ordered on right-up screen corner
  47. 2) the bhv_window is erased and recreated each time a new type of analyze
  48. is performed.
  49. 3) a new procedure "makes_bhvpar_windows" was created to recreate the
  50. bhv_window that also actualizes two files used in GEP_GUI procedures:
  51. self.mafen.source_df_bhvremain = df_bhv.iloc[self.df_glob.index]
  52. self.mafen.source_df_parremain = df_par.iloc[self.df_glob.index]
  53. In param_in_blue(self, df_par): all par graphs are built from
  54. listDicGraphs. This dictionary can be modified from makeGEPMetrics.py
  55. to choose the params plotted in each graph
  56. namex = self.listDicGraphs[pargr+1]["abscissa"]
  57. namey = self.listDicGraphs[pargr+1]["ordinate"]
  58. parx = self.xparNameDict[namex[0]]
  59. pary = self.xparNameDict[namey[0]]
  60. In class GUI_Graph:
  61. new methods added:
  62. plot_2D_stability_map(self, df_bhvremain, df_parremain)
  63. Prepares a dataframe in which for each behavior (duration,
  64. amplitude) a mean distance is calculated from the distance to
  65. all behaviors produced by parameters in the vicinyty (dist<0.2)
  66. of this behavior. When several distances are obtained, the mean
  67. value is retained. Then call the do_plot_2D_stability_map()
  68. method to plot the stability map.
  69. do_plot_2D_stability_map(self, df_cues_dist)
  70. plot_densitymap_metrics(self): it asks to choos a folder with GEPdata
  71. and builds the corresponding df_bhvremain and df_parremain dataframes
  72. (if already present in memor, asks if a new folder is to be analysed)
  73. Then calls the new function do_plot_2D_density_map_metrics
  74. do_plot_2D_density_map_metrics(df_bhvremain, behav_col,
  75. pathGEP, GEPdataName,
  76. nbruns, col_scale_range):
  77. Plots and saves a density map that uses the same grid as the grid
  78. used in metrics to evaluate how the GEP explores the behavior
  79. space. THe score in metrics is simply the number of cases in the
  80. grid that contain at least one behavior.
  81. Here, this gid is used to count the number of behaviors in each
  82. case, which gives an idea of the density of the behaviors in the
  83. different regions.
  84. a new general procedure added:
  85. plot_2D_graph_from_array(x, pathGEP, baseName, nameX, nameY, extent)
  86. x is an array of arrays containing values (typically the number of
  87. behaviours in each case of the grid defined by the array of arrays, but
  88. it may be any value that defines a feature of the grid).
  89. pathGEP is the path to save the graphs (.esp and .pdf)
  90. baseName is the name of the graph
  91. nameX and nameY are the X and Y axes legends
  92. extent is an array [x_min, x_max, y_min, y_max] used to define the
  93. ranges of x and y axes.
  94. GEPGraphsMetrics class Contains various methods to build graphs for GEP analysis
  95. - plot and save behavior and parameter maps
  96. - plot and save behavior map
  97. - plot and save behavior map (with chosen number of valid behaviors)
  98. - plot and save density map of GEP behavior domain
  99. - plot and save stability map of GEP behavior domain
  100. - plot and save progression of GEP process with two metric methods
  101. - plot_densitymaps_contour
  102. - plot_save_2D_densitymap_contour
  103. These two methods use contour to draw the density map (continuous way)
  104. Translated in Python 3.8 Jan 2023 (D. Cattaert)
  105. Modified January 27, 2023 (D. Cattaert):
  106. Saving to xls has beenreplaced by saving in csv format.
  107. Modified January 29, 2023 (D. Cattaert):
  108. New methods added in Graph_Setting class :
  109. chartgraph_selected_bhv()
  110. run_selected_bhv()
  111. These methods used selected Bhv to build graph from charts. To do this
  112. the corresponding paramsets are run and results saved in graphs/run-0
  113. or run-1 etc... in incremental manner.
  114. ModifiedFebruary 1, 2023 (D. Cattaert):
  115. Modification of run_selected_bhv() method that use now the saves_seeds()
  116. method of GEP_GUI to complete the new directory.
  117. Modified February 3, 2023 (D. Cattaert):
  118. Modifications of build_newdf() method:
  119. After selectiion of several folders, the index of df_bhvremain and
  120. df_parremain are no more set to range(len(self.df_parremain)) but to
  121. self.lst_valid, the list of valid elements (varmse<1) adapted to take
  122. into account the origin of elements (i.e. the folder of origin)
  123. self.df_bhvremain.index = self.lst_valid
  124. self.df_parremain.index = self.lst_valid
  125. Accordingly, in run_selected_bhv() method, the concatenated pairs numbers
  126. (optSet.pairs) are now directly compatible with seeds_selected
  127. (= list(df_glob.index)). So lst_valid is no more used.
  128. The call to GEP-GUI.py saves_seeds() is made with the param
  129. seedDirCreate=False in order not to create a 0_IDXXX_seeds00 foder.
  130. Modified February 14, 2023 (D. Cattaert):
  131. In the procedure graphfromchart(), "path" replaced by "chart_path"
  132. In the class GUI_Graph, a bug in the method build_newdf() was fixed: when
  133. only one folder (one experiment) was chosen, the variable "tab_bhv" was not
  134. defined. It is now defined if one_expe:
  135. if self.prevListGEPFiles == []:
  136. tab_bhv = readTablo(self.listGEPFolders[0], "GEPdata00bhv.txt")
  137. tab_bhv = np.array(tab_bhv)
  138. Modified February 28, 2023 (D. Cattaert):
  139. in GEPGraphsMetrics class, bug fixed in make_graph_score_evol(method):
  140. "span = int(tabnewspan[idx])" not accepted for a list. Now replaced
  141. by series of tests to define span.
  142. Modified Mars 01, 2023 (D. Cattaert):
  143. graphfromchart() procedure improved. Neuron voltage are no more expressed
  144. in V but in mV.
  145. Modified April 23, 2023 (D. Cattaert):
  146. New method plot_abaque_duration() allows to draw abaques of duration values
  147. in the MaxSpeed vs Amplitude graph. It calls a new prodecure from
  148. optimization: plot_series_curves_maxspeed_ampl_duration()
  149. Modified April 28, 2023 (D. Cattaert):
  150. Method chooseChartFromPar() : bug fixed to take into account the new format
  151. in datastructure. This method builds bhv Plots from the charts of
  152. datastructure the varme of which is <1.
  153. New method analyze_triphasic():
  154. Builds a new df_bhv and df_par from a datastructure
  155. Runs the method chooseChartFromPar() to select charts from the
  156. datastructure
  157. From datastructure, builds a new self.df_chart containint:
  158. chartName, varmse, startangle, ampl, max_speed, dur_mvt2, run_rg
  159. plus three other columns characterizing triphasic pattern:
  160. TwoPicks, FlxTo0BetwPicks, ExtOnePick
  161. Aks if plot is required for each selected chartName (the plot contains
  162. the movement and EMGs (1FlxPotMuscle, 1ExtPotMuscle)
  163. The self.df_chart is saved in csv format.
  164. Modified May 10, 2023 (D. Cattaert):
  165. Bug fixed in chooseChartFromPar() method. The <Max replaced by <=Max
  166. Modified May 16, 2023 (D. cattaert):
  167. Scalses for bhv plots corrected and set to 0-120 for x , and 0-500 for
  168. MaxSpeed
  169. New method: plot_save_density_map_metrics() used when called from
  170. controlScriptGEP.py to build gaphs with autoscale=True
  171. Modified July 29, 2023 (D. Cattaert):
  172. Method saveplot_bhvparam() in GEPGraphMetrics class modified so that
  173. when called from a multipleExpeGraph the complete dataframe is plotted.
  174. Modified September 17, 2023 (D. Cattaert):
  175. Method make_graph_score_evol() Bug fixed to take into account the type of
  176. tabnewspan[idx] when red from datastructure and is ['DicSpanVal.txt'],
  177. Which means that for this series, span values was red from DicSpanVal.txt:
  178. if type(tabnewspan[idx][0]) is str: ...
  179. Modified Ostober 06, 2023 (D. Cattaert):
  180. Method saveplot_bhvparam(): bug fixed for multiple expe graph. Start and
  181. End values missed. Now provided.
  182. Method plot_densitymap_metrics(): same bug fixed
  183. Modified October 10, 2023 (d. Cattaert):
  184. Method analyze_triphasic() improved so that multiple experiments are
  185. allowed. Method build_df_chart() modified accordingly. Nw the df_chart
  186. contains a new column "origine". A number (0 to nbExpe) indicates the
  187. origin folder of the chart name. Method chooseChartFromPar() modified
  188. accordingly. It does not asks anymore for a GEPdata00.par, but gets it
  189. directly from the self.listGEPFolders list elaborated in build_newdf()
  190. method called by make_bhvpardf() method.
  191. Modoified October 10, 2023 (D. Cattaert):
  192. Bug fixed in chooseChartFromPar(). Now the chart directory is obtained from
  193. self.listGEPFolders, and the chart is red in the good GEPChartFiles,
  194. according to the experiment folder in the list self.listGEPFolders.
  195. Modified October 17, 2023 (D. Cattaert):
  196. Method makegr_chart_tcourse() modified to allow two types of graph when the
  197. names extension is ".txt":
  198. either an 'EMG'
  199. or a 'bhvMvt'
  200. Modified February 03, 2024 (D. Cattaert):
  201. In grid_method() method, derecated writing fixed:
  202. state_table = np.zeros(dtype=int, shape=(nbcol, nbrow))
  203. ('dtype=np.int' replaced by 'dtype=int')
  204. Modified April 12, 2024 (D. Cattaert):
  205. makeGraphs.py Bug fixed in the selection of behaviors when data
  206. are from several folders. The behaviors are now selected
  207. using "orig_rg" and "origine". The index of chart_global_df
  208. is now compatible with indexes of df_parremain and
  209. df_bhvremain
  210. Modified April 24, 2024 (D. Cattaert):
  211. Old methods (used for the old format "experiments series")
  212. have been suppressed.
  213. New procedures introduced to Analyze neuron activities and par
  214. vs bhv. Now it is possible to opena previously saved
  215. "df_chart_bhv_neur_param.csv" to make graphs. The new method
  216. ("read_csv_for_df_bhv_neur_par()") relies on a part of the old
  217. "build_newdf()" method to reconstruct the df_parremain and
  218. df_bhvremain dataframes.
  219. To do this, "build_newdf()" has been splitted into four sub methods
  220. Modified May 1st, 2024 (D; Cattaert):
  221. Bug fixed in method "run_selected_bhv". Selected_seeds are obtained from
  222. the index of the dataframe "df_glob". This is OK but the corresponding
  223. parameters were not at those rows, becaus correct rows are indicated in
  224. rgserie column NOT AT INDEX!!! This is why the correct row of each
  225. parameter (in optSet.pairs) is calculated :
  226. rg_pair = int(df_bhvremain.loc[select]["rgserie"])
  227. The script was chaned accordingly:
  228. seeds_selected = list(df_glob.index))
  229. selected_pairs = []
  230. for select in seeds_selected:
  231. print(df_parremain.loc[select][:5])
  232. rg_pair = int(df_bhvremain.loc[select]["rgserie"])
  233. print(optSet.pairs[rg_pair][:5])
  234. selected_pairs.append(optSet.pairs[rg_pair])
  235. Modified May 02, 2024 (D. Cattaert):
  236. Bug in method "run-selected-bhv()' fixed. Now, df-parremain and
  237. df-bhvremain indexes correspond to seeds-selected = df_glob.rgserie
  238. Modified May 15, 2024 (D. Cattaert):
  239. Bug in construct_df_par_bhv_remains() and read_csv_for_df_bhv_neur_par()
  240. methods have been fixedc:
  241. "sum_precedingTab" variable was added to sum preceeding tables in order
  242. to get a correct final index
  243. Modified May 17, 2024 (D. Cattaert):
  244. Suppression of two lines on read_csv_for_df_bhv_neur_par() method:
  245. self.df_bhvremain.loc[:, "orig_rg"] = self.df_bhvremain["rgserie"]
  246. self.df_parremain.loc[:, "orig_rg"] = self.df_parremain["rgserie"]
  247. because self.df_bhvremain and self.df_parremain already got the column
  248. entitled "orgi-rg" (in construct_df_par_bhv_remains() method)
  249. in and self.df_parremain already got the column
  250. In order to allow analysis from a different computer, with path
  251. different from the one used to build the multipleExpeGraph-x folders, the
  252. method "construct_df_par_bhv_remains()" has been modified so that it works
  253. with relative folder addresses established from self.ensembleRunDir
  254. annimatsimdir is rebuilt to make it compatible with the computer paths
  255. Modified June 05, 2024 (D. Cattaert):
  256. new_run_dir is now created in chartgraph_selected_bhv() method
  257. This allows the par and bhv csv files of selected behaviors to be saved in
  258. new_run_dir (run-0, run-1 etc.)
  259. Modified July 5, 2024 (D. Cattaert):
  260. create_df_for_bhv_neur_par() method modified to allow second peak detection
  261. at user's demand.
  262. get_peaks_and_troughs() procedure modified accordingly. Asks the user
  263. Which neurone to search for a second peak.
  264. Modified July 15, 2024 (D. Cattaert):
  265. read_csv_for_df_bhv_neur_par() method modified to accept lines containing a
  266. NaN element
  267. buildStpDiscretCol() procedure modified to get a single color scale (<50),
  268. because plotting to legends(plt.legend()) is no more accepted.
  269. Modified July 17, 2024 (D. Cattaert):
  270. Bug fixed in "save (par+bhv) dataframe to csv". The problem came from the
  271. variable "self.new_run_dir" that was not defined in the method
  272. "construct_df_par_bhv_remains" but only in neuron analysis. Therfor, any
  273. call to "save "par+bhv dataframes to csv" directely after running
  274. "make/analyze (par+bhv) dataframe" failed. This is now fixed in the method
  275. "construct_df_par_bhv_remains":
  276. new line added after the folders have been selected:
  277. self.new_run_dir = self.graph_path
  278. Modified December 20, 2024 (D. Cattaert):
  279. Bug fixed in method "build_df_chart()" (self.mydir was not known):
  280. if self.mydir == '':
  281. self.mydir = self.graph_path
  282. df_chart.to_csv(self.mydir + '/charts_infos.csv')
  283. Modified January 25, 2025 (D.Cattaert):
  284. graphfromchart() procedure modified to include in the title the 3 last
  285. parts of the pathway to the chartFile.
  286. Previously, the graph title was:
  287. "GEP_chart00.txt; randParam bestfit:0.5787...;
  288. mse bestfit:0.5787022423750172; coactBestFit:0.0
  289. Now it is:
  290. GEP_chart05.txt; NS33B2NG(sim)/NS33B2NGB_52_..._100/workDir_animatlab
  291. mse:36.1529 coactP:0.0
  292. max_endangleP:18.33 End_1FlxAlpha_P:2.22 End_1ExtAlpha_P:0.00 ...
  293. mvt duration: 1.08
  294. The algorithm used to get mseVal and coactVal from the chart's firts line
  295. have been modified to work with new charts and old charts accordings to
  296. changes made in savechartfile() (in optimization.py).
  297. This procedure is called by makeGraphFromChart() called by various
  298. methods of GUI_graph class.
  299. Modified February 20, 2025 (D. Cattaert):
  300. build_df_chart() modified so that is self.graph_path does not exist; it
  301. is created. This occured when new charts are created from selected
  302. behaviors limits (or all behaviors).The file charts_infos.csv can then be
  303. saved in this new "graphs" directory.
  304. Modified June 24, 2025 ( D. Cattaert):
  305. Bug fixed in "Analyze Neurons_activity/bhv from charts"
  306. Now after creating the dataframe and saving it (self.fname), the dataframe
  307. is recreated by launching read_csv_for_df_bhv_neur_par_from_file(self),
  308. To do this, read_csv_for_df_bhv_neur_par(self) has been splitted into Two
  309. methods: one to chosse the csv file and the other to read it:
  310. def read_csv_for_df_bhv_neur_par(self):
  311. res = (QtWidgets.QFileDialog.
  312. getOpenFileName(self, "Choose bhv_df_csv file to analyse",
  313. self.mydir, "Files (*csv)"))
  314. if type(res) == tuple:
  315. self.fname, __tmp = res
  316. else:
  317. self.fname = res
  318. print(self.fname)
  319. self.read_csv_for_df_bhv_neur_par_from_file()
  320. def read_csv_for_df_bhv_neur_par_from_file(self):
  321. if self.fname is not None:
  322. ...
  323. modified September 04, 2025 (D. Cattaert):
  324. errThr and coactThr values is now red from win.errThr and win.coactThr
  325. All methods and functions have been modified accordingly in optimization.py
  326. The value of win.errThr (that was 1.0 in previous version) is now given in
  327. a method from GUI ("setErrThr()").
  328. The value of win.coactThr (that was 0.01 in previous version) is now given in
  329. a method from GUI ("setErrThr()"). Using this method plus two new buttons,
  330. win.errThr and win.coactThr can be changed in the GUI.
  331. These two values are incorporated in datastructure (conditons' last list')
  332. and saved in GEPdata00.par at each extend and fill.
  333. The graphs use now these two new settings (red from datastructure) and they
  334. can be changed (via a dialog). This dialog can be call from the first
  335. button of the GEPgraphMetric menu. Thes two values are saved in the graphs'
  336. titles
  337. Suppression of nan elements in selected dataframe for single plot (eiher
  338. with a color factor of not)
  339. Modified October 22, 2025 (D. Cattaert):
  340. Method "create_df_for_bhv_neur_par()" modified self.fname (name of of the
  341. self.chart_glob_df), that includes now the length of df_chart.
  342. Method "plot_bhvmap_nbBhvOK" reduces the number of points of the graph plot
  343. Modified May 24 2026 (D. Cattaert):
  344. New predecure ("Analyse perturbation effects on bhv") allows to add
  345. perturbation to the arm during movement. A new stimulus is added in the
  346. FinalModel files (.asim and .aproj) of the original directory.
  347. New subdirectory of "graph" directory is created to store the rusults of
  348. running each perturbed model.The perturbation parameters are givent by the
  349. user. It is also possible to run a limited ârt of the original behavior
  350. domain.Once finished the original FinalModel files are restored.
  351. Modified June 09, 2026 (D. Cattaert):
  352. Perturbation procedurehas been rewrittent to work in parallel mode.
  353. GEP_GUI.py and optimization.py have been modified accordingly.
  354. modified June 10, 2026 (D.Cattaert):
  355. method "saves_newGEPdata()" (from GEP_GUI.py) modified to include a new
  356. parameter in the call (saveGrFromChart=False). This new parametr allows to
  357. choose to build graphs or not in the class "Perturbation_Setting0" in the
  358. method used to run selected behaviors (run_selected_bhv).
  359. Modified June19, 2026 (D. Cattaert):
  360. It is now possible to choose not to save .aproj and/or .asim files.
  361. New dialog boxes have been added for the user to choose what to save.
  362. """
  363. import os
  364. from os import listdir
  365. from os.path import isfile, join
  366. import pickle
  367. import copy
  368. import random
  369. import ctypes # used to create message box
  370. from ctypes import wintypes as w
  371. import matplotlib.pyplot as plt
  372. # import matplotlib.colors as pltcolors
  373. import matplotlib.pylab as pylab
  374. import matplotlib as mpl
  375. # from matplotlib import colors as mcolors
  376. # from matplotlib import cm
  377. import json
  378. from itertools import product
  379. import numpy as np
  380. import pandas as pd
  381. # from openpyxl import Workbook
  382. import seaborn as sns
  383. from scipy.stats import pearsonr
  384. from scipy.stats import linregress
  385. from scipy.signal import find_peaks_cwt
  386. from scipy.signal import find_peaks
  387. from scipy.signal import lfilter
  388. from itertools import groupby
  389. # from mpl_toolkits.mplot3d import axes3d
  390. from mpl_toolkits.mplot3d import Axes3D
  391. from math import log as ln
  392. from math import sqrt as sqrt
  393. from math import isnan
  394. from math import pi
  395. import pyqtgraph as pg
  396. from pyqtgraph.Qt import QtCore
  397. from pyqtgraph.Qt import QtWidgets
  398. # from PyQt5 import QtWidgets
  399. from optimization import showdialog
  400. from optimization import load_datastructure
  401. from optimization import readTabloTxt
  402. from optimization import readTablo
  403. from optimization import chartToDataFrame
  404. from optimization import getInfoComputer
  405. from optimization import SaveIncrementNb
  406. from optimization import saveListToDir
  407. from optimization import calculate_minjerk_duration
  408. from optimization import copyRenameFilewithExt
  409. from optimization import copyFileDir_ext
  410. from optimization import copyFileDir
  411. from optimization import copyFileWithExt
  412. from optimization import copyFile
  413. from optimization import readGravityfromAsim
  414. from optimization import readCoacPenality
  415. from optimization import testVarMsePlot
  416. from optimization import plot_series_curves_maxspeed_ampl_duration
  417. # import mvt_GUI
  418. from DialogChoose_in_List import ChooseInList
  419. from DialogChoose_in_List import GetText
  420. from DialogChoose_in_List import choose_one_element_in_list
  421. from DialogChoose_in_List import choose_elements_in_list
  422. from DialogChoose_in_List import set_values_in_list
  423. from DialogChoose_in_List import Enter_Values
  424. from DialogChoose_in_List import InfoWindow
  425. from optimization import loadParams
  426. from animatlabOptimSetting import OptimizeSimSettings
  427. from FoldersArm import FolderOrg
  428. import class_animatLabModel as AnimatLabModel
  429. import class_projectManager as ProjectManager
  430. from class_animatLabSimulationRunner import AnimatLabSimulationRunner as SimRun
  431. import class_animatLabSimulationRunner as AnimatLabSimRunner
  432. import xml.etree.ElementTree as elementTree
  433. import uuid
  434. """
  435. from matplotlib.backends.qt_compat import is_pyqt5
  436. if is_pyqt5():
  437. from matplotlib.backends.backend_qt5agg import (
  438. FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
  439. else:
  440. from matplotlib.backends.backend_qt4agg import (
  441. FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
  442. """
  443. from matplotlib.backends.backend_qt5agg import (
  444. FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
  445. global verbose
  446. verbose = 2
  447. # ======= Format a new "MessageBox" function to be used in Python 2.7 =======
  448. # The four folling lines are for python2.7 because Python 2's strings are byte
  449. # strings and marshaled as byte strings (char*). Python 3's strings are Unicode
  450. # strings and marshaled as wide strings (wchar_t*). Without defining .argtypes,
  451. # ctypes won't error check and happily pass the wrong type.
  452. user32 = ctypes.WinDLL('user32')
  453. MessageBox = user32.MessageBoxW
  454. MessageBox.argtypes = w.HWND, w.LPCWSTR, w.LPCWSTR, w.UINT
  455. MessageBox.restype = ctypes.c_int
  456. """
  457. # to use "MessageBox just type
  458. # MessageBox(None, u'message', u'title', 0)
  459. # it will return the code of answer
  460. # several options (styles) are possible:
  461. ## Styles:
  462. ## 0 : OK
  463. ## 1 : OK | Cancel
  464. ## 2 : Abort | Retry | Ignore
  465. ## 3 : Yes | No | Cancel
  466. ## 4 : Yes | No
  467. ## 5 : Retry | No
  468. ## 6 : Cancel | Try Again | Continue
  469. """
  470. # -----------------------------------------------------------------------------
  471. def dialogWindow(titre, info, details=""):
  472. rep = showdialog(titre, info, details)
  473. # print(rep)
  474. if rep == 1024:
  475. OK = True
  476. else:
  477. OK = False
  478. return OK
  479. class Form(QtWidgets.QWidget):
  480. def __init__(self, parent=None):
  481. super(Form, self).__init__(parent)
  482. nameLabel = QtWidgets.QLabel("Name:")
  483. self.nameLine = QtWidgets.QLineEdit()
  484. self.submitButton = QtWidgets.QPushButton("&Submit")
  485. self.quitButton = QtWidgets.QPushButton("&Quit")
  486. buttonLayout1 = QtWidgets.QVBoxLayout()
  487. buttonLayout1.addWidget(nameLabel)
  488. buttonLayout1.addWidget(self.nameLine)
  489. buttonLayout1.addWidget(self.submitButton)
  490. buttonLayout1.addWidget(self.quitButton)
  491. self.submitButton.clicked.connect(self.submitContact)
  492. self.quitButton.clicked.connect(self.closeIt)
  493. mainLayout = QtWidgets.QGridLayout()
  494. # mainLayout.addWidget(nameLabel, 0, 0)
  495. mainLayout.addLayout(buttonLayout1, 0, 1)
  496. self.setLayout(mainLayout)
  497. self.setWindowTitle("Hello Qt")
  498. def submitContact(self):
  499. name = self.nameLine.text()
  500. if name == "":
  501. QtWidgets.QMessageBox.information(self, "Empty Field",
  502. "Please enter a name and address.")
  503. return
  504. else:
  505. QtWidgets.QMessageBox.information(self, "Success!",
  506. "Hello %s!" % name)
  507. def closeIt(self):
  508. """
  509. doc string
  510. """
  511. self.close()
  512. def change_key_str_to_int(dic_folder_st):
  513. rep = {}
  514. for key in list(dic_folder_st.keys()):
  515. rep[int(key)] = dic_folder_st[key].replace("\\", "/")
  516. return rep
  517. def lighten_color(color, amount=0.5):
  518. """
  519. Lightens the given color by multiplying (1-luminosity) by the given amount.
  520. Input can be matplotlib color string, hex string, or RGB tuple.
  521. Examples:
  522. >> lighten_color('g', 0.3)
  523. >> lighten_color('#F034A3', 0.6)
  524. >> lighten_color((.3,.55,.1), 0.5)
  525. """
  526. import matplotlib.colors as mc
  527. import colorsys
  528. try:
  529. c = mc.cnames[color]
  530. except Exception as e:
  531. c = color
  532. print(e)
  533. c = colorsys.rgb_to_hls(*mc.to_rgb(c))
  534. return colorsys.hls_to_rgb(c[0], 1 - amount * (1 - c[1]), c[2])
  535. def getListOfFiles(dirName):
  536. '''
  537. For the given path, get the List of all files in the directory tree
  538. '''
  539. # create a list of file and sub directories
  540. # names in the given directory
  541. listOfFile = os.listdir(dirName)
  542. allFiles = list()
  543. # Iterate over all the entries
  544. for entry in listOfFile:
  545. # Create full path
  546. fullPath = os.path.join(dirName, entry)
  547. # If entry is a directory then get the list of files in this directory
  548. if os.path.isdir(fullPath):
  549. allFiles = allFiles + getListOfFiles(fullPath)
  550. else:
  551. allFiles.append(fullPath)
  552. return allFiles
  553. def find_a_file(rootdir=None, fileName=None):
  554. if rootdir is None:
  555. from mainOpt import readAnimatLabDir
  556. animatsimdir = readAnimatLabDir()
  557. rootdir = animatsimdir
  558. if fileName is None:
  559. fileName = "GEPdata00.par"
  560. # Get the list of all files in directory tree at given path
  561. # listOfFiles = getListOfFiles(rootdir)
  562. # Print the files
  563. # for elem in listOfFiles:
  564. # print(elem)
  565. # print ("****************")
  566. # Get the list of all files in directory tree at given path
  567. listOfFiles = list()
  568. listOfDir = list()
  569. for (dirpath, dirnames, filenames) in os.walk(rootdir):
  570. listOfFiles += [os.path.join(dirpath, file) for file in filenames]
  571. listOfDir += [os.path.join(dirpath, file) for file in dirnames]
  572. listOfSearchedFiles = list()
  573. listOfSearchedDir = list()
  574. # Print the files
  575. for elem in listOfFiles:
  576. if elem[-len(fileName):] == fileName:
  577. print(elem)
  578. listOfSearchedFiles.append(elem)
  579. listOfSearchedDir.append(os.path.split(elem)[0])
  580. return listOfSearchedDir
  581. def save_eps_pdf(graph_path, tit, sstit):
  582. nomfic_eps = r'{0}\{1}{2}.eps'.format(graph_path, tit, sstit)
  583. nomfic_pdf = r'{0}\{1}{2}.pdf'.format(graph_path, tit, sstit)
  584. if len(nomfic_eps) > 250:
  585. nomfic_eps = r'{0}\{1}.eps'.format(graph_path, tit)
  586. nomfic_pdf = r'{0}\{1}.pdf'.format(graph_path, tit)
  587. if not os.path.exists(nomfic_eps):
  588. plt.savefig(nomfic_eps, bbox_inches='tight')
  589. plt.savefig(nomfic_pdf, bbox_inches='tight')
  590. else:
  591. root = nomfic_eps[:nomfic_eps.find(".eps")]
  592. print(len(root))
  593. k = 0
  594. while os.path.exists("{0}({1}){2}".format(root, k, ".eps")):
  595. k += 1
  596. nomfic_eps = "{0}({1}){2}".format(root, k, ".eps")
  597. nomfic_pdf = "{0}({1}){2}".format(root, k, ".pdf")
  598. plt.savefig(nomfic_eps, bbox_inches='tight')
  599. plt.savefig(nomfic_pdf, bbox_inches='tight')
  600. print("files saved under {0}".format(nomfic_eps))
  601. """
  602. def create_workbook(path):
  603. workbook = Workbook()
  604. sheet = workbook.active
  605. sheet['A1'] = 'Hello'
  606. sheet['A2'] = 'from'
  607. sheet['A3'] = 'OpenPyXL'
  608. workbook.save(path)
  609. """
  610. def dataframe_to_rows(df, index=False):
  611. rows = []
  612. if index == True:
  613. row = [""]
  614. for col in list(df.columns):
  615. row.append(col)
  616. else:
  617. row = list(df.columns)
  618. rows.append(row)
  619. indexes = list(df.index)
  620. for id_row, row in enumerate(df.index):
  621. # print("row=", id_row, "index=", indexes[id_row])
  622. if index:
  623. rowVals = [indexes[id_row]]
  624. else:
  625. rowVals = []
  626. for idx, col in enumerate(df.columns):
  627. # print("\t {:2.2f}".format(df.loc[row, col]), end=" " )
  628. rowVals.append(df.loc[row, col])
  629. # print()
  630. rows.append(rowVals)
  631. return rows
  632. """
  633. def save_df_to_xls(df, pathGEP, file_name, typ=None):
  634. # Although this procedure has been fixed for Python 3.8, we do not use it
  635. # anymore because dataframe conversion is not straight forward and more
  636. # over importing xlsx file to built a dataframe is not satisfying. We use
  637. # csv file instead.
  638. workbook = Workbook()
  639. sheet = workbook.active
  640. rows = dataframe_to_rows(df, index=False)
  641. for r_idx, row in enumerate(rows, 1):
  642. for c_idx, value in enumerate(row, 1):
  643. sheet.cell(row=r_idx, column=c_idx, value=value)
  644. completeName = os.path.join(pathGEP, file_name + '.xlsx')
  645. workbook.save(completeName)
  646. print('DataFrame is written successfully to Excel Sheet.')
  647. """
  648. def save_df_to_csv(df, pathGEP, file_name, typ=None):
  649. completeName = os.path.join(pathGEP, file_name + '.csv')
  650. df.to_csv(completeName, sep=",")
  651. def calculate_dist_par(df_parremain, par_names, idx, rg, dist):
  652. d2 = 0
  653. for par in par_names:
  654. x = df_parremain[par][idx] - df_parremain[par][rg]
  655. if x > dist:
  656. d = None
  657. return None
  658. d2 += x*x
  659. d = sqrt(d2)
  660. if d < dist:
  661. return d
  662. # print(idx, d)
  663. return d
  664. def find_close_param(df_parremain, par_names, rg, dist):
  665. """
  666. Gets all parameter sets in df_parremain that are close to a given parameter
  667. set (at distance < dist).
  668. Returns the list of ranks of such parameters and list of distances¨2
  669. """
  670. lst_closepar_rg = []
  671. lst_closepar_d = []
  672. for idx in df_parremain.index:
  673. if idx != rg:
  674. """
  675. d2 = 0
  676. for par in par_names:
  677. x = df_parremain[par][idx] - df_parremain[par][rg]
  678. if x > dist:
  679. d2 += x*x
  680. d = sqrt(d2)
  681. """
  682. d = calculate_dist_par(df_parremain, par_names, idx, rg, dist)
  683. if d is not None:
  684. # print idx, d
  685. lst_closepar_rg.append(idx)
  686. lst_closepar_d.append(d)
  687. return lst_closepar_rg, lst_closepar_d
  688. def Calc_disp(df_bhvremain, source_rg, lst_closepar_rg, behav_col):
  689. """
  690. """
  691. behavs_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  692. # =========== normalization of endangle => division by 100 ===========
  693. behav_normalized = copy.deepcopy(behavs_cues)
  694. behav_normalized[df_bhvremain.columns[behav_col][0]] *= 0.01
  695. lst_bhv_dist = []
  696. for idx in lst_closepar_rg:
  697. if idx != source_rg:
  698. bhv_d2 = 0
  699. for bhv in df_bhvremain.columns[behav_col]:
  700. x = behav_normalized[bhv][idx] -\
  701. behav_normalized[bhv][source_rg]
  702. bhv_d2 += x*x
  703. bhv_d = sqrt(bhv_d2)
  704. lst_bhv_dist.append(bhv_d)
  705. return lst_bhv_dist
  706. def getValuesFromText(txt):
  707. t2 = txt
  708. xtab = []
  709. while t2.find('\t') != -1:
  710. t1 = t2[:t2.find('\t')]
  711. t2 = t2[t2.find('\t')+1:]
  712. xtab.append(t1)
  713. t1 = t2[:t2.find('\n')]
  714. xtab.append(t1)
  715. return xtab
  716. def read_dist_list(pathGEP, baseName):
  717. """
  718. Reads a table containing as columns: idx, run, score, nBhvOK, density
  719. This table was saved as a text file in a previous run of grid_method()
  720. """
  721. tabFinal = []
  722. # idx = 0
  723. completeName = os.path.join(pathGEP, baseName + '.txt')
  724. with open(completeName, 'r') as fich:
  725. columns_txt = fich.readline()
  726. columns = getValuesFromText(columns_txt)
  727. while 1:
  728. # while idx < 9:
  729. tab1 = []
  730. tab2 = []
  731. valid_line = True
  732. txt = fich.readline()
  733. if txt == '':
  734. break
  735. else:
  736. tab1 = getValuesFromText(txt)
  737. # print(tab1)
  738. try:
  739. x = int(tab1[0])
  740. except Exception as e:
  741. x = tab1
  742. print(e, "alpha-numeric line", x)
  743. valid_line = False
  744. if valid_line:
  745. for k in range(len(columns)):
  746. try:
  747. if tab1[k].find('.') == -1: # not a float
  748. tab2.append(int(tab1[k]))
  749. else:
  750. tab2.append(float(tab1[k]))
  751. # tab2.append(tab1[k])
  752. except Exception as e:
  753. if len(tab1) < len(columns):
  754. tab2.append(0)
  755. else:
  756. tab2.append(np.NaN)
  757. k = 0
  758. if (verbose > 2):
  759. print(e)
  760. tabFinal.append(tab2)
  761. # idx += 1
  762. tab_dist = tabFinal
  763. fich.close()
  764. df_dist = pd.DataFrame(tab_dist[:],
  765. columns=columns,
  766. index=np.arange(len(tab_dist[:])))
  767. return df_dist
  768. def read_tab_scores(pathGEP, baseName):
  769. tabFinal = []
  770. # idx = 0
  771. completeName = os.path.join(pathGEP, baseName + '.txt')
  772. with open(completeName, 'r') as fich:
  773. columns_txt = fich.readline()
  774. columns = getValuesFromText(columns_txt)
  775. while 1:
  776. # while idx < 9:
  777. tab1 = []
  778. tab2 = []
  779. valid_line = True
  780. txt = fich.readline()
  781. if txt == '':
  782. break
  783. else:
  784. tab1 = getValuesFromText(txt)
  785. # print(tab1)
  786. try:
  787. x = int(tab1[0])
  788. except Exception as e:
  789. x = tab1
  790. print(e, "alpha-numeric line", x)
  791. valid_line = False
  792. if valid_line:
  793. for k in range(len(columns)):
  794. try:
  795. if tab1[k].find('.') == -1: # not a float
  796. tab2.append(int(tab1[k]))
  797. else:
  798. tab2.append(float(tab1[k]))
  799. # tab2.append(tab1[k])
  800. except Exception as e:
  801. if len(tab1) < len(columns):
  802. tab2.append(0)
  803. else:
  804. tab2.append(np.NaN)
  805. k = 0
  806. if (verbose > 2):
  807. print(e)
  808. tabFinal.append(tab2)
  809. # idx += 1
  810. tab_scores = tabFinal
  811. fich.close()
  812. return tab_scores
  813. def get_titre(path, baseName):
  814. titre = "{}/{}".format(path, baseName)
  815. titre = titre.replace("\\", "/")
  816. slashPositions = [pos for pos, char in enumerate(titre) if char == "/"]
  817. end1 = max([x for x in slashPositions[:-1] if x < 100])
  818. tit1 = titre[: end1+1]
  819. if end1 < max(slashPositions):
  820. end2 = max([x for x in slashPositions if x < 160])
  821. tit2 = titre[end1+1:end2+1]
  822. if end2 < max(slashPositions):
  823. end3 = max([x for x in slashPositions if x < 240])
  824. tit3 = titre[end2+1:end3+1]
  825. if end3 < max(slashPositions):
  826. tit4 = titre[end3+1:]
  827. titr = tit1 + "\n" + tit2 + "\n" + tit3 + "\n" + tit4
  828. else:
  829. tit3 = titre[end2+1:]
  830. titr = tit1 + "\n" + tit2 + "\n" + tit3
  831. else:
  832. tit3 = titre[end2+1:]
  833. titr = tit1 + "\n" + tit2 + "\n" + tit3
  834. else:
  835. titr = titre
  836. return titr
  837. def includePerturbationInAsim(pertStart, pertDur, pertForce,
  838. asimFileName, new_run_dir):
  839. """
  840. """
  841. def indent(elem, level=0):
  842. i = "\n" + level * " "
  843. if len(elem):
  844. if not elem.text or not elem.text.strip():
  845. elem.text = i + " "
  846. for child in elem:
  847. indent(child, level + 1)
  848. if not child.tail or not child.tail.strip():
  849. child.tail = i
  850. if level and (not elem.tail or not elem.tail.strip()):
  851. elem.tail = i
  852. pertStartTxt = '%s' % pertStart
  853. pertEnd = pertStart + pertDur
  854. pertEndTxt = '%s' % pertEnd
  855. pertForceTxt = '%s' % pertForce
  856. lookupType = []
  857. lookupID = []
  858. lookupName = []
  859. lookupElement = []
  860. def lookupAppend(el, elType):
  861. lookupType.append(elType)
  862. lookupID.append(el.find("ID").text)
  863. lookupName.append(el.find("Name").text)
  864. lookupElement.append(el)
  865. asimFile = os.path.join(new_run_dir, asimFileName)
  866. tree = elementTree.parse(asimFile)
  867. root = tree.getroot()
  868. path = "Environment/Organisms"
  869. for el in list(root.find("ExternalStimuli")):
  870. if el.find("Type").text == "MotorPosition":
  871. lookupAppend(el, "MotorPosition")
  872. for el in list(root.find("ExternalStimuli")):
  873. if el.find("Type").text == "MotorVelocity":
  874. lookupAppend(el, "MotorVelocity")
  875. for el in list(root.find("ExternalStimuli")):
  876. if el.find("Type").text == "Current":
  877. lookupAppend(el, "ExternalStimuli")
  878. for el in list(root.find("ExternalStimuli")):
  879. if el.find("Type").text == "ForceInput":
  880. lookupAppend(el, "ForceInput")
  881. external = root.find("ExternalStimuli")
  882. stim = elementTree.Element("Stimulus")
  883. def add(tag, text):
  884. e = elementTree.SubElement(stim, tag)
  885. e.text = text
  886. if "perturbation" not in lookupName:
  887. add("ID", str(uuid.uuid4()))
  888. add("Name", "perturbation")
  889. add("AlwaysActive", "False")
  890. add("Enabled", "True")
  891. add("ModuleName", "")
  892. add("Type", "ForceInput")
  893. add("StructureID", "e6b0c0e2-b87c-4391-8637-55925b1b6ca4")
  894. add("BodyID", "49172659-54fc-42dd-8d4c-cb5b5e921576")
  895. add("StartTime", pertStartTxt)
  896. add("EndTime", pertEndTxt)
  897. rel = elementTree.SubElement(stim, "RelativePosition")
  898. rel.set("x", "0")
  899. rel.set("y", "0")
  900. rel.set("z", "0")
  901. add("ForceX", "0")
  902. add("ForceY", "0")
  903. add("ForceZ", pertForceTxt)
  904. for tag in ["TorqueX", "TorqueY", "TorqueZ"]:
  905. add(tag, "0")
  906. children = list(external)
  907. insert_at = next(
  908. (i for i, el in enumerate(children)
  909. if el.find("Type") is not None and el.find("Type").text == "MotorVelocity"),
  910. len(children)
  911. )
  912. external.insert(insert_at, stim)
  913. indent(root)
  914. tree.write(asimFile, encoding="utf-8", xml_declaration=True)
  915. # ================ Modification of the perturbation parameters ============
  916. else:
  917. for stim in external.findall("Stimulus"):
  918. t = stim.find("Type")
  919. if t is not None and t.text == "ForceInput":
  920. stim.find("Name").text = "perturbation"
  921. stim.find("StartTime").text = pertStartTxt
  922. stim.find("EndTime").text = pertEndTxt
  923. stim.find("ForceX").text = "0"
  924. stim.find("ForceY").text = "0"
  925. stim.find("ForceZ").text = pertForceTxt
  926. stim.find("TorqueX").text = "0"
  927. stim.find("TorqueY").text = "0"
  928. stim.find("TorqueZ").text = "0"
  929. break
  930. tree.write(asimFile, encoding="utf-8", xml_declaration=True)
  931. def includePerturbationinAproj(pertStart, pertDur, pertForce,
  932. aprojFileName, new_run_dir):
  933. def indent(elem, level=0):
  934. i = "\n" + level * " "
  935. if len(elem):
  936. if not elem.text or not elem.text.strip():
  937. elem.text = i + " "
  938. for child in elem:
  939. indent(child, level + 1)
  940. if not child.tail or not child.tail.strip():
  941. child.tail = i
  942. if level and (not elem.tail or not elem.tail.strip()):
  943. elem.tail = i
  944. pertStartTxt = '%s' % pertStart
  945. pertEnd = pertStart + pertDur
  946. pertEndTxt = '%s' % pertEnd
  947. pertForceTxt = '%s' % pertForce
  948. aprojlookupType = []
  949. aprojlookupID = []
  950. aprojlookupName = []
  951. aprojlookupElement = []
  952. def aprojlookupAppend(el, elType):
  953. aprojlookupType.append(elType)
  954. aprojlookupID.append(el.find("ID").text)
  955. aprojlookupName.append(el.find("Name").text)
  956. aprojlookupElement.append(el)
  957. aprojFile = os.path.join(new_run_dir, aprojFileName)
  958. aprojtree = elementTree.parse(aprojFile)
  959. aprojroot = aprojtree.getroot()
  960. print("\nREADING .aproj elements...")
  961. # print "Stimuli"
  962. path = "Simulation/Stimuli"
  963. for el in list(aprojroot.find(path)):
  964. # print el.find("Name").text,
  965. aprojlookupAppend(el, "Stimulus")
  966. stimuli = aprojroot.find("Simulation/Stimuli")
  967. stim = elementTree.Element("Stimulus")
  968. def add_text(tag, text):
  969. e = elementTree.SubElement(stim, tag)
  970. e.text = text
  971. return e
  972. def add_attrib(tag, attrs):
  973. return elementTree.SubElement(stim, tag, attrs)
  974. if "perturbation" not in aprojlookupName:
  975. add_text("AssemblyFile", "AnimatGUI.dll")
  976. add_text("ClassName", "AnimatGUI.DataObjects.ExternalStimuli.Force")
  977. add_text("Name", "perturbation")
  978. add_text("ID", str(uuid.uuid4()))
  979. add_attrib("StartTime", {"Value": pertStartTxt, "Scale": "None", "Actual": pertStartTxt})
  980. add_attrib("EndTime", {"Value": pertEndTxt, "Scale": "None", "Actual": pertEndTxt})
  981. add_attrib("StepInterval", {"Value": "0", "Scale": "milli", "Actual": "0"})
  982. add_text("AlwaysActive", "False")
  983. add_text("Enabled", "True")
  984. add_text("ValueType", "Constant")
  985. add_text("Equation", "0")
  986. add_text("StructureID", "e6b0c0e2-b87c-4391-8637-55925b1b6ca4")
  987. add_text("PartID", "49172659-54fc-42dd-8d4c-cb5b5e921576")
  988. add_attrib("PositionX", {"Value": "0", "Scale": "None", "Actual": "0"})
  989. add_attrib("PositionY", {"Value": "0", "Scale": "None", "Actual": "0"})
  990. add_attrib("PositionZ", {"Value": "0", "Scale": "None", "Actual": "0"})
  991. add_attrib("ForceX", {"Value": "0", "Scale": "None", "Actual": "0"})
  992. add_attrib("ForceY", {"Value": "0", "Scale": "None", "Actual": "0"})
  993. add_attrib("ForceZ", {"Value": pertForceTxt, "Scale": "None", "Actual": pertForceTxt})
  994. add_attrib("TorqueX", {"Value": "0", "Scale": "None", "Actual": "0"})
  995. add_attrib("TorqueY", {"Value": "0", "Scale": "None", "Actual": "0"})
  996. add_attrib("TorqueZ", {"Value": "0", "Scale": "None", "Actual": "0"})
  997. children = list(stimuli)
  998. insert_at = next(
  999. (i for i, el in enumerate(children)
  1000. if el.find("ClassName") is not None and el.find("ClassName").text == "AnimatGUI.DataObjects.ExternalStimuli.MotorVelocity"),
  1001. len(children)
  1002. )
  1003. stimuli.insert(insert_at, stim)
  1004. indent(aprojroot)
  1005. aprojtree.write(aprojFile, encoding="utf-8", xml_declaration=True)
  1006. else:
  1007. for stim in stimuli.findall("Stimulus"):
  1008. cls = stim.find("ClassName")
  1009. if cls is not None and cls.text == "AnimatGUI.DataObjects.ExternalStimuli.Force":
  1010. stim.find("Name").text = "perturbation"
  1011. stim.find("StartTime").set("Value", pertStartTxt)
  1012. stim.find("StartTime").set("Actual", pertStartTxt)
  1013. stim.find("EndTime").set("Value", pertEndTxt)
  1014. stim.find("EndTime").set("Actual", pertEndTxt)
  1015. stim.find("ForceX").set("Value", "0")
  1016. stim.find("ForceX").set("Actual", "0")
  1017. stim.find("ForceY").set("Value", "0")
  1018. stim.find("ForceY").set("Actual", "0")
  1019. stim.find("ForceZ").set("Value", pertForceTxt)
  1020. stim.find("ForceZ").set("Actual", pertForceTxt)
  1021. break
  1022. aprojtree.write(aprojFile, encoding="utf-8", xml_declaration=True)
  1023. def plot_2D_graph_from_array(x, graph_path, baseName,
  1024. nameX, nameY, extent, col_scale_range):
  1025. """
  1026. plot_2D_graph_from_array(x, graph_path, baseName, nameX, nameY, extent)
  1027. x is an array of arrays containing values (typically the number of
  1028. behaviours in each case of the grid defined by the array of arrays, but
  1029. it may be any value that defines a feature of the grid).
  1030. => graph_path is the path to save the graphs (.esp and .pdf)
  1031. => baseName is the name of the graph
  1032. => nameX and nameY are the X and Y axes legends
  1033. => extent is an array [x_min, x_max, y_min, y_max] used to define the
  1034. ranges of x and y axes.
  1035. """
  1036. path = os.path.split(graph_path)[0]
  1037. titre = get_titre(path, baseName)
  1038. # nameX = df_cues_dist.columns[0]
  1039. # nameY = df_cues_dist.columns[1]
  1040. w = 10
  1041. h = 9
  1042. d = 80
  1043. vmin = col_scale_range[0]
  1044. vmax = col_scale_range[1]
  1045. plt.figure(figsize=(w, h), dpi=d)
  1046. color_map = plt.imshow(x, origin='lower',
  1047. extent=extent,
  1048. aspect='auto',
  1049. vmin=vmin, vmax=vmax)
  1050. # color_map = plt.imshow(x, origin='lower')
  1051. # color_map = plt.imshow(x)
  1052. color_map.set_cmap("nipy_spectral")
  1053. # plt.colorbar()
  1054. cbar = plt.colorbar()
  1055. cbar.ax.tick_params(labelsize=18)
  1056. plt.xlabel(nameX, fontsize=18)
  1057. plt.ylabel(nameY, fontsize=18)
  1058. plt.xticks(fontsize=18)
  1059. plt.yticks(fontsize=18)
  1060. plt.suptitle(titre, fontsize=12, y=0.97)
  1061. plt.savefig(os.path.join(graph_path, baseName + '.pdf'))
  1062. plt.savefig(os.path.join(graph_path, baseName + '.eps'))
  1063. plt.show()
  1064. def do_plot_2D_density_map_metrics(df_bhvremain, behav_col, bhv_names,
  1065. graph_path, GEPdataName, nbruns,
  1066. min_x=0, max_x=120,
  1067. min_y=0, max_y=5,
  1068. autoscale=True):
  1069. """
  1070. from df_bhvremain, builds a table 40x40 of number of bhvs contained in each
  1071. frame case.
  1072. """
  1073. nbcol = 40
  1074. nbrow = 40
  1075. """
  1076. min_x = 0
  1077. max_x = 120
  1078. min_y = 0
  1079. max_y = 1.4
  1080. """
  1081. intervalx = (max_x - min_x)/nbcol
  1082. intervaly = round((max_y - min_y)*1000/nbrow)/1000
  1083. extent = [min_x, max_x, min_y, max_y]
  1084. # ================= find rank ond nbruns in orig_rg ===================
  1085. end_rank = df_bhvremain[df_bhvremain["orig_rg"] >= nbruns-1].index[0]
  1086. behav_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  1087. df_cues = copy.deepcopy(behav_cues)
  1088. df_cues_sel = df_cues.loc[:][:end_rank]
  1089. tab_nb_bhv = []
  1090. x_name = bhv_names[behav_col[0]]
  1091. y_name = bhv_names[behav_col[1]]
  1092. for i in range(nbrow):
  1093. yi = i*intervaly + min_y
  1094. ys = (i+1)*intervaly + min_y
  1095. row_df = df_cues_sel.loc[(df_cues_sel[y_name] >= yi) &
  1096. (df_cues_sel[y_name] < ys)]
  1097. nb_bhv_row = []
  1098. for j in range(nbcol):
  1099. xi = j*intervalx + min_x
  1100. xs = (j+1)*intervalx + min_x
  1101. temp_col_df = row_df.loc[(row_df[x_name] >= xi) &
  1102. (row_df[x_name] < xs)]
  1103. # print yi, ys, xi, xs, temp_col_df
  1104. nb_bhv_row.append(len(temp_col_df[x_name]))
  1105. # print nb_bhv_row
  1106. tab_nb_bhv.append(nb_bhv_row)
  1107. tab_nb_bhv = np.array(tab_nb_bhv)
  1108. nameX = df_cues.columns[0]
  1109. nameY = df_cues.columns[1]
  1110. # nb_runs = len(df_cues_sel)
  1111. color_min = 0
  1112. color_max = tab_nb_bhv.max() + 1
  1113. if not autoscale:
  1114. # --------------------------------------------------------------------
  1115. listChoix = ['colorScale_range']
  1116. listDicColScalRange = [{'colorScale_range': ["inf", "sup"]}]
  1117. listDic_Color_range = [{"inf": color_min, "sup": color_max}]
  1118. factorLimits_keys = ["inf", "sup"]
  1119. titleText = "set limits for factor"
  1120. rep = ChooseInList.listTransmit(parent=None,
  1121. graphNo=0,
  1122. listChoix=listChoix,
  1123. items=factorLimits_keys,
  1124. listDicItems=listDicColScalRange,
  1125. onePerCol=[0],
  1126. colNames=["colorScale_range", 'value'],
  1127. dicValues=listDic_Color_range[0],
  1128. typ="val",
  1129. titleText=titleText)
  1130. listDicColScalRange = rep[0]
  1131. if len(rep[1]) > 0: # No values entered, ESC button was used
  1132. color_min = float(rep[1]['inf'])
  1133. color_max = float(rep[1]['sup'])
  1134. # --------------------------------------------------------------------
  1135. col_scale_range = (color_min, color_max)
  1136. if behav_col[1] == 8:
  1137. ordTyp = "duration"
  1138. elif behav_col[1] == 6:
  1139. ordTyp = "maxSpeed"
  1140. baseName = "{}_{}_{}_{}{}".format(GEPdataName, ordTyp, "densityMap",
  1141. nbruns, "_runs")
  1142. plot_2D_graph_from_array(tab_nb_bhv, graph_path, baseName,
  1143. nameX, nameY, extent, col_scale_range)
  1144. def build_stability_dataframe(df_bhvremain, df_parremain, graph_path,
  1145. GEPdataName, behav_col, par_names,
  1146. search_dist):
  1147. """
  1148. Prepares a dataframe in which, for each behavior (duration,
  1149. amplitude) a mean distance is calculated from
  1150. all behaviors produced by parameters in the vicinyty (dist<search_dist)
  1151. of the parameters of this behavior. When several distances are
  1152. obtained, the mean value is retained.
  1153. """
  1154. if behav_col[1] == 8:
  1155. ordTyp = "duration"
  1156. elif behav_col[1] == 6:
  1157. ordTyp = "maxSpeed"
  1158. baseName = "{}_{}_{}{}".format(GEPdataName[:], ordTyp, "List_stab",
  1159. search_dist)
  1160. completeName = os.path.join(graph_path, baseName + '.txt')
  1161. if not os.path.exists(completeName):
  1162. df_dist = []
  1163. lst_dist = []
  1164. print("please wait... building unstability map")
  1165. for source_rg in df_bhvremain.index:
  1166. res = find_close_param(df_parremain, par_names,
  1167. source_rg, search_dist)
  1168. lst_closepar_rg = res[0]
  1169. # lst_closepar_d = res[1]
  1170. bhv_dist = Calc_disp(df_bhvremain, source_rg,
  1171. lst_closepar_rg, behav_col)
  1172. mean_dist = np.array(bhv_dist).mean()
  1173. # print source_rg, mean_dist
  1174. if source_rg % 10 == 0:
  1175. print("*", end=" ")
  1176. lst_dist.append(mean_dist)
  1177. """"
  1178. df_dist.append(pd.DataFrame({'rg': lst_closepar_rg,
  1179. 'par_d': lst_closepar_d,
  1180. 'bhv_d': bhv_dist},
  1181. index = range(len(lst_closepar_rg))))
  1182. """
  1183. print()
  1184. # ================= saves lst_dist ====================
  1185. # baseName = "{}{}{}_{}".format(GEPdataName[:], ordTyp, "_List_stab",
  1186. # search_dist)
  1187. # completeName = os.path.join(graph_path, baseName + '.txt')
  1188. with open(completeName, 'w') as fich:
  1189. s = "index\tmeandist\n"
  1190. fich.write(s)
  1191. for idx, dist in enumerate(lst_dist):
  1192. s = "{}\t{:2.3f}\n".format(idx, dist)
  1193. fich.write(s)
  1194. fich.close()
  1195. # ================= reads lst_dist ====================
  1196. df_dist = read_dist_list(graph_path, baseName)
  1197. print(df_dist)
  1198. behavs_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  1199. df_cues_dist = copy.deepcopy(behavs_cues)
  1200. df_cues_dist['dist_bhv'] = df_dist["meandist"]
  1201. df_cues_dist['rg'] = df_cues_dist.index
  1202. else:
  1203. # ================= reads lst_dist ====================
  1204. df_dist = read_dist_list(graph_path, baseName)
  1205. print(df_dist)
  1206. behavs_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  1207. df_cues_dist = copy.deepcopy(behavs_cues)
  1208. df_cues_dist['dist_bhv'] = df_dist["meandist"]
  1209. df_cues_dist['rg'] = df_cues_dist.index
  1210. return df_cues_dist
  1211. def do_plot_2D_stability_map(MyWin, df_cues_dist, search_dist, graph_path,
  1212. GEPdataName):
  1213. """
  1214. plots the stability map
  1215. """
  1216. nbcol = 40
  1217. nbrow = 40
  1218. """
  1219. min_x = 0
  1220. max_x = 120
  1221. min_y = 0.2
  1222. max_y = 1.4
  1223. """
  1224. behav_col = MyWin.behav_col
  1225. bhv_names = MyWin.bhv_names
  1226. name_x = bhv_names[behav_col[0]]
  1227. name_y = bhv_names[behav_col[1]]
  1228. max_x_bhv = df_cues_dist[name_x].max()
  1229. max_y_bhv = df_cues_dist[name_y].max()
  1230. max_x = float(int(max_x_bhv*10)+1)/10
  1231. max_y = float(int(max_y_bhv*10)+1)/10
  1232. min_x = 0
  1233. min_y = 0
  1234. intervalx = (max_x - min_x)/nbcol
  1235. intervaly = round((max_y - min_y)*1000/nbrow)/1000
  1236. tab_nb_bhv = []
  1237. map_bhv = []
  1238. tab_dist_bhv = []
  1239. name_x = MyWin.bhv_names[MyWin.behav_col[0]]
  1240. name_y = MyWin.bhv_names[MyWin.behav_col[1]]
  1241. for i in range(nbrow):
  1242. yi = i*intervaly + min_y
  1243. ys = (i+1)*intervaly + min_y
  1244. row_df = df_cues_dist.loc[(df_cues_dist[name_y] >= yi) &
  1245. (df_cues_dist[name_y] < ys)]
  1246. map_bhv_row = []
  1247. nb_bhv_row = []
  1248. dist_bhv_row = []
  1249. for j in range(nbcol):
  1250. xi = j*intervalx + min_x
  1251. xs = (j+1)*intervalx + min_x
  1252. temp_col_df = row_df.loc[(row_df[name_x] >= xi) &
  1253. (row_df[name_x] < xs)]
  1254. # print yi, ys, xi, xs, temp_col_df
  1255. map_bhv_row.append([yi, ys, xi, xs,
  1256. len(temp_col_df[name_x])])
  1257. nb_bhv_row.append(len(temp_col_df[name_x]))
  1258. try:
  1259. # we cannot use mean() because this will give NaN in
  1260. # temp_col_df["dist_bhv"].mean()
  1261. # ===== elimination of cases without distance (NaN) ======
  1262. tmp_df = copy.deepcopy(temp_col_df["dist_bhv"])
  1263. tmp_ser = pd.Series(tmp_df)
  1264. nan_elems = tmp_ser.isnull()
  1265. remove_nan = tmp_ser[~nan_elems]
  1266. tmpdist = np.array(remove_nan)
  1267. if len(tmpdist) > 0:
  1268. dist_bhv_row.append(tmpdist.mean())
  1269. else:
  1270. dist_bhv_row.append(np.NaN)
  1271. except Exception as e:
  1272. if (verbose > 2):
  1273. print(e)
  1274. # if in the process a case is empty (NaN) -> a negative value
  1275. # is given: -0.01 is small enough for the case to appear in black
  1276. # but not too larg to modify the color scale
  1277. stab_bhv_row = [-0.01 if isnan(x) else x for x in dist_bhv_row]
  1278. # print nb_bhv_row
  1279. tab_nb_bhv.append(nb_bhv_row)
  1280. map_bhv.append(map_bhv_row)
  1281. tab_dist_bhv.append(stab_bhv_row)
  1282. tab_nb_bhv = np.array(tab_nb_bhv)
  1283. map_bhv = np.array(map_bhv)
  1284. tab_dist_bhv = np.array(tab_dist_bhv)
  1285. extent = [min_x, max_x, min_y, max_y]
  1286. nameX = df_cues_dist.columns[0]
  1287. nameY = df_cues_dist.columns[1]
  1288. nb_runs = len(df_cues_dist)
  1289. if behav_col[1] == 8:
  1290. ordTyp = "duration"
  1291. elif behav_col[1] == 6:
  1292. ordTyp = "maxSpeed"
  1293. col_scale_range = (-0.01, tab_nb_bhv.max())
  1294. baseName = "{}_{}_{}_{}".format(GEPdataName, ordTyp, nb_runs, "densityMap")
  1295. plot_2D_graph_from_array(tab_nb_bhv, graph_path, baseName,
  1296. nameX, nameY, extent, col_scale_range)
  1297. baseName = "{}_{}_{}_{}_{}".format(GEPdataName, ordTyp, nb_runs,
  1298. "stabilityMap", search_dist)
  1299. col_scale_range = (-0.01, tab_dist_bhv.max())
  1300. plot_2D_graph_from_array(tab_dist_bhv, graph_path, baseName,
  1301. nameX, nameY, extent, col_scale_range)
  1302. def makeDensityMap_contour(rel_behavs_cues, step=0.05,
  1303. xmin=None, xmax=None, ymin=None, ymax=None):
  1304. """
  1305. builds a matrix containing the number of elements in each unit surface
  1306. (squarre step x step) covering the X and the Y range of behavs_cues
  1307. """
  1308. # xmin = None
  1309. df = copy.deepcopy(rel_behavs_cues)
  1310. if xmin is None:
  1311. xmin = min(df[df.columns[0]]) - step
  1312. xmax = max(df[df.columns[0]])
  1313. ymin = min(df[df.columns[1]]) - step
  1314. ymax = max(df[df.columns[1]])
  1315. else:
  1316. xmin = xmin - step
  1317. ymin = ymin - step
  1318. xmin_gr = int(xmin/step) * step
  1319. xmax_gr = (int(xmax/step) + 1) * step
  1320. print(xmin, xmax)
  1321. ymin_gr = int(ymin/step) * step
  1322. ymax_gr = (int(ymax/step) + 1) * step
  1323. print(ymin, ymax)
  1324. listx = np.linspace(xmin_gr, xmax_gr, int((xmax_gr-xmin_gr)/step)+1)
  1325. listy = np.linspace(ymin_gr, ymax_gr, int((ymax_gr-ymin_gr)/step)+2)
  1326. density_map = []
  1327. # xmin = min(df[df.columns[0]])
  1328. # xmax = max(df[df.columns[0]])
  1329. # print xmin, xmax
  1330. # ymin = min(df[df.columns[1]])
  1331. # ymax = max(df[df.columns[1]])
  1332. # print ymin, ymax
  1333. for yval in listy:
  1334. res = []
  1335. for xval in listx:
  1336. # print x*step, y*step
  1337. tmp_df = copy.deepcopy(df)
  1338. onTheSpotx1 = (tmp_df[tmp_df.columns[0]] > xval)
  1339. tmp_df = tmp_df[onTheSpotx1]
  1340. onTheSpotx2 = (tmp_df[tmp_df.columns[0]] < xval+step)
  1341. tmp_df = tmp_df[onTheSpotx2]
  1342. onTheSpoty1 = (tmp_df[tmp_df.columns[1]] > yval)
  1343. tmp_df = tmp_df[onTheSpoty1]
  1344. onTheSpoty2 = (tmp_df[tmp_df.columns[1]] < yval+step)
  1345. tmp_df = tmp_df[onTheSpoty2]
  1346. # print len(tmp_df)
  1347. res.append(len(tmp_df))
  1348. density_map.append(res)
  1349. return density_map, listx, listy
  1350. def plot_3D_density_map_contour(df_bhvremain, behav_col, step=0.02,
  1351. incline=60, rot=-90,
  1352. xmin=None, xmax=None, ymin=None, ymax=None):
  1353. """
  1354. Plots a 3D-Graph using the density_map and the listx, listy to build
  1355. a X, Y grid
  1356. """
  1357. behavs_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  1358. rel_behavs_cues = behavs_cues/[MyWin.scale_x, MyWin.scale_y]
  1359. res = makeDensityMap_contour(rel_behavs_cues, step=step,
  1360. xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
  1361. (density_map, listx, listy) = res
  1362. nameX = rel_behavs_cues.columns[0]
  1363. nameY = rel_behavs_cues.columns[1]
  1364. X, Y = np.meshgrid(listx, listy)
  1365. Z = np.array(density_map)
  1366. fig = plt.figure(figsize=(7, 7), dpi=100)
  1367. ax = plt.axes(projection='3d')
  1368. ax.contour3D(X, Y, Z, 50, cmap='cool')
  1369. # ax.contour3D(X, Y, Z, 50, cmap='binary')
  1370. # ax.contour3D(X, Y, Z, 50, cmap='viridis')
  1371. ax.set_xlabel(nameX)
  1372. ax.set_ylabel(nameY)
  1373. ax.set_zlabel("Nb evts")
  1374. ax.view_init(incline, rot)
  1375. fig.show()
  1376. def plot_2D_density_map_contour(MyWin, df_bhvremain, behav_col, graph_path,
  1377. strGEPdataName, nbruns=None,
  1378. step=0.02, aimbhv=[],
  1379. xmin=0, xmax=1.2, ymin=0, ymax=1.5,
  1380. saveDM=False):
  1381. """
  1382. Plots a 2D-Graph using the density_map (contour) and the listx, listy to
  1383. build a X, Y grid. Density_map, listx and listy are obtained from the
  1384. function makeDensityMap_contour()
  1385. """
  1386. behav_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  1387. if nbruns is None:
  1388. nbruns = df_bhvremain["orig_rg"].max()
  1389. # ================= find rank ond nbruns in orig_rg ===================
  1390. end_rank = df_bhvremain[df_bhvremain["orig_rg"] >= nbruns].index[0]
  1391. df_cues = copy.deepcopy(behav_cues)
  1392. df_cues_sel = df_cues.loc[:][:end_rank]
  1393. rel_behavs_cues = df_cues_sel/[MyWin.scale_x, MyWin.scale_y]
  1394. res = makeDensityMap_contour(rel_behavs_cues, step=step,
  1395. xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
  1396. (density_map, listx, listy) = res
  1397. nameX = rel_behavs_cues.columns[0]
  1398. nameY = rel_behavs_cues.columns[1]
  1399. if behav_col[1] == 8: # if ordonate is duration...
  1400. labelnameX = nameX + "(x 0.01)"
  1401. labelnameY = nameY
  1402. elif behav_col[1] == 6:
  1403. labelnameX = nameX + "(x 0.01)"
  1404. labelnameY = nameY + "(x 0.01)"
  1405. X, Y = np.meshgrid(listx, listy)
  1406. Z = np.array(density_map)
  1407. Z[Z == 1] = 4 # replace all 1 by 4
  1408. Z[Z == 2] = 4 # replace all 1 by 4
  1409. Z[Z == 3] = 4 # replace all 1 by 4
  1410. nbniv = int(np.amax(Z))
  1411. plt.figure(figsize=(10, 9), dpi=80)
  1412. plt.contourf(X, Y, Z, nbniv, cmap='nipy_spectral', vmin=0, vmax=130)
  1413. cbar = plt.colorbar()
  1414. cbar.ax.tick_params(labelsize=18)
  1415. plt.xlabel(labelnameX, fontsize=18)
  1416. plt.ylabel(labelnameY, fontsize=18)
  1417. plt.xticks(fontsize=18)
  1418. plt.yticks(fontsize=18)
  1419. for point in aimbhv:
  1420. x = point[0]-MyWin.scale_x*step/2
  1421. y = point[1]-MyWin.scale_y*step/2
  1422. relx, rely = x/MyWin.scale_x, y/MyWin.scale_y
  1423. plt.plot(relx, rely, '-p', color='gray',
  1424. markersize=5, linewidth=4,
  1425. markerfacecolor='white',
  1426. markeredgecolor='gray',
  1427. markeredgewidth=2)
  1428. if saveDM:
  1429. path = os.path.split(graph_path)[0]
  1430. strGEPdataName = os.path.splitext(strGEPdataName)[0]
  1431. if behav_col[1] == 8:
  1432. ordTyp = "duration"
  1433. elif behav_col[1] == 6:
  1434. ordTyp = "maxSpeed"
  1435. baseName = "{}_{}_{}{}{}{}".format(strGEPdataName, ordTyp,
  1436. len(df_cues_sel),
  1437. "bhv_DensityContour_",
  1438. nbruns, "runs")
  1439. titre = get_titre(path, baseName)
  1440. plt.suptitle(titre, fontsize=12, y=0.97)
  1441. plt.savefig(os.path.join(graph_path, baseName + '.pdf'))
  1442. plt.savefig(os.path.join(graph_path, baseName + '.eps'))
  1443. plt.show()
  1444. def read_metric_table(graph_path, baseName):
  1445. """
  1446. Reads a table containing as columns: idx, run, score, nBhvOK, density
  1447. This table was saved as a text file in a previous run of grid_method()
  1448. """
  1449. tabFinal = []
  1450. # idx = 0
  1451. completeName = os.path.join(graph_path, baseName + '.txt')
  1452. with open(completeName, 'r') as fich:
  1453. columns_txt = fich.readline()
  1454. colums = getValuesFromText(columns_txt)
  1455. while 1:
  1456. # while idx < 11:
  1457. tab1 = []
  1458. tab2 = []
  1459. valid_line = True
  1460. txt = fich.readline()
  1461. if txt == '':
  1462. break
  1463. else:
  1464. tab1 = getValuesFromText(txt)
  1465. # print(tab1)
  1466. try:
  1467. x = int(tab1[0])
  1468. except Exception as e:
  1469. x = tab1
  1470. print(e, "alpha-numeric line", x)
  1471. valid_line = False
  1472. if valid_line:
  1473. for k in range(len(colums)):
  1474. try:
  1475. if tab1[k].find('.') == -1: # not a float
  1476. tab2.append(int(tab1[k]))
  1477. else:
  1478. tab2.append(float(tab1[k]))
  1479. # tab2.append(tab1[k])
  1480. except Exception as e:
  1481. if len(tab1) < len(colums):
  1482. tab2.append(0)
  1483. else:
  1484. tab2.append(1)
  1485. k = 0
  1486. if (verbose > 2):
  1487. print(e)
  1488. tabFinal.append(tab2)
  1489. # idx += 1
  1490. tab_scores = tabFinal
  1491. fich.close()
  1492. df_score = pd.DataFrame(tab_scores[:],
  1493. columns=colums,
  1494. index=np.arange(len(tab_scores[:])))
  1495. return df_score
  1496. def FitCourseToDataFrame(completeName):
  1497. """
  1498. Reads a text file (FitCourse.txt). The first line is measured param
  1499. names. There may be several successive sessions (CMAeData-00,
  1500. CMAeData-01...). They are grouped in a single dataframe. Returns the
  1501. nparray of data, the dataframe and the list of parameter names.
  1502. """
  1503. tabFinal = []
  1504. tabnewstart = []
  1505. # idx = 0
  1506. # prevline = ""
  1507. # prevtrial = 0
  1508. with open(completeName, 'r') as fich:
  1509. params = fich.readline()
  1510. params = params[:-2] + "\tsaved\n"
  1511. tabparams = getValuesFromText(params)
  1512. while 1:
  1513. # while idx < 11:
  1514. tab1 = []
  1515. tab2 = []
  1516. valid_line = True
  1517. txt = fich.readline()
  1518. if txt == '':
  1519. break
  1520. else:
  1521. tab1 = getValuesFromText(txt)
  1522. # print(tab1)
  1523. if tab1[0] == "1":
  1524. # tabnewstart.append(int(prevtrial))
  1525. # print(prevline)
  1526. tabnewstart.append(len(tabFinal)+1)
  1527. else:
  1528. try:
  1529. x = float(tab1[0])
  1530. except Exception as e:
  1531. x = tab1
  1532. print(e, "alpha-numeric line", x)
  1533. valid_line = False
  1534. if valid_line:
  1535. for k in range(len(tabparams)):
  1536. try:
  1537. tab2.append(float(tab1[k]))
  1538. # tab2.append(tab1[k])
  1539. except Exception as e:
  1540. if len(tab1) < len(tabparams):
  1541. tab2.append(0)
  1542. else:
  1543. tab2.append(1)
  1544. k = 0
  1545. if (verbose > 2):
  1546. print(e)
  1547. nptab2 = np.array(tab2)
  1548. tabFinal.append(nptab2)
  1549. # idx += 1
  1550. print(tabnewstart)
  1551. tabFinal = np.array(tabFinal)
  1552. # tabFinal = np.transpose(tabFinal)
  1553. dataframe = pd.DataFrame(tabFinal, columns=tabparams)
  1554. dataframe.index = np.arange(1, len(dataframe)+1, 1)
  1555. return (tabFinal, dataframe, tabparams, tabnewstart)
  1556. def plotdataframe(dataframe, par, Deb, Fin, tabnewstart,
  1557. unitx="xaxis", unity="yaxis", color="b", ylim=(-5, 50)):
  1558. plt.legend(fontsize=30)
  1559. if Fin-Deb < 20:
  1560. dataframe[Deb:Fin][par].plot(color=color, marker="o")
  1561. else:
  1562. dataframe[Deb:Fin][par].plot(color=color, ylim=ylim)
  1563. for idx, newstart in enumerate(tabnewstart):
  1564. if newstart in range(Deb, Fin):
  1565. plt.axvline(tabnewstart[idx])
  1566. plt.xlabel(unitx, fontsize=20)
  1567. plt.ylabel(unity, fontsize=20)
  1568. plt.legend(loc=0, fontsize=18)
  1569. plt.xticks(fontsize=18)
  1570. plt.yticks(fontsize=18)
  1571. # plt.rcParams.update({'font.size': 28})
  1572. def plotdf_improve(dataframe, par, Deb, Fin, tabnewstart,
  1573. unitx="xaxis", unity="yaxis", color="b", ylim=(-5, 50)):
  1574. """
  1575. Plots one parameter (par) against time from Deb to Fin. Each time a new
  1576. start is present in tabnewstart, a vertical line is traced.
  1577. """
  1578. if (par == "eval") or (par == "mse"):
  1579. par2 = "bestfit"
  1580. if par == "coactpenality":
  1581. par2 = "bestcoact"
  1582. new_df = copy.deepcopy(dataframe)
  1583. # ====== creates one new column =================
  1584. lst_bestfit = []
  1585. lst_bestcoact = []
  1586. # bestfit = new_df["eval"][1]
  1587. bestfit = new_df[par][1]
  1588. bestcoact = new_df["coactpenality"][1]
  1589. for idx in range(1, len(new_df)):
  1590. lst_bestfit.append(bestfit)
  1591. lst_bestcoact.append(bestcoact)
  1592. if idx in tabnewstart:
  1593. bestfit = new_df["eval"][idx]
  1594. bestcoact = new_df["coactpenality"][idx]
  1595. """
  1596. # if idx in range(len(new_df)-10, len(new_df)):
  1597. if idx in range(1169, 1200):
  1598. print idx, new_df["eval"][idx], "=>", bestfit,
  1599. print " \t", new_df["coactpenality"][idx], "=>", bestcoact
  1600. """
  1601. if new_df["eval"][idx+1] < bestfit:
  1602. bestfit = new_df["eval"][idx+1]
  1603. if new_df["coactpenality"][idx+1] < bestcoact:
  1604. bestcoact = new_df["coactpenality"][idx+1]
  1605. lst_bestfit.append(bestfit)
  1606. lst_bestcoact.append(bestcoact)
  1607. new_df.loc[:, 'bestfit'] = lst_bestfit
  1608. new_df.loc[:, 'bestcoact'] = lst_bestcoact
  1609. """
  1610. saved_OK = dataframe['saved'] == 1
  1611. df = dataframe[saved_OK]
  1612. if len(df) > 0:
  1613. print df
  1614. """
  1615. ylimMax = new_df[Deb:Fin][par2].max()*1.2
  1616. ylimMin = -ylimMax/20
  1617. ylim=(ylimMin, ylimMax)
  1618. # plt.legend(fontsize=30)
  1619. if Fin-Deb < 20:
  1620. new_df[Deb:Fin][par2].plot(color=color, marker="o")
  1621. else:
  1622. new_df[Deb:Fin][par2].plot(color=color, ylim=ylim)
  1623. for idx, newstart in enumerate(tabnewstart):
  1624. # if newstart in range(Deb, Fin):
  1625. if newstart in range(new_df.index[Deb], new_df.index[Fin-1]):
  1626. plt.axvline(tabnewstart[idx])
  1627. plt.xlabel(unitx, fontsize=20)
  1628. plt.ylabel(unity, fontsize=20)
  1629. # plt.legend(loc=0, fontsize=18)
  1630. plt.xticks(fontsize=18)
  1631. plt.yticks(fontsize=18)
  1632. # plt.rcParams.update({'font.size': 28})
  1633. def adaptScale(max_valY):
  1634. y = max_valY * 10000
  1635. while (y > 10):
  1636. y = y/10
  1637. # BarreY = int(round((max_valY / y)))
  1638. BarreY = max_valY / y
  1639. if y < 1.1:
  1640. scaleYMax = 1.1 * BarreY
  1641. elif y < 1.2:
  1642. scaleYMax = 1.2 * BarreY
  1643. elif y < 1.5:
  1644. scaleYMax = 1.5 * BarreY
  1645. elif y < 2:
  1646. scaleYMax = 2 * BarreY
  1647. elif y < 5:
  1648. scaleYMax = int(y + 1) * BarreY
  1649. else:
  1650. scaleYMax = int(y + 1) * BarreY
  1651. return scaleYMax
  1652. def graphfromFitCourse(path, FitCourseFileName):
  1653. """
  1654. Uses the path to FitCourse to built a plot of the corresponding
  1655. dataframe
  1656. """
  1657. completeName = os.path.join(path, FitCourseFileName)
  1658. baseName = os.path.splitext(FitCourseFileName)[0]
  1659. (tabFinal, dataframe,
  1660. tabparams, tabnewstart) = FitCourseToDataFrame(completeName)
  1661. df = copy.deepcopy(dataframe)
  1662. plt.figure(figsize=(20, 20), dpi=50)
  1663. plt.subplot(331)
  1664. Deb = 0
  1665. Fin = len(df)
  1666. par = "mse"
  1667. max_valY = df[Deb:Fin][par].max()
  1668. min_valY = df[Deb:Fin][par][Fin]
  1669. ylimMax = adaptScale(max_valY)
  1670. if (max_valY - min_valY) < (0.5 * ylimMax):
  1671. ylimMax *= 2
  1672. ylimMin = -ylimMax/20
  1673. plotdataframe(df, "mse", Deb, Fin, tabnewstart,
  1674. unitx="Trial", unity=par, color="b",
  1675. ylim=(ylimMin, ylimMax))
  1676. plt.subplot(332)
  1677. Deb = int(len(df)/2)
  1678. Fin = len(df)
  1679. max_valY = df[Deb:Fin][par].max()
  1680. ylimMax = adaptScale(max_valY)
  1681. if (max_valY - min_valY) < (0.5 * ylimMax):
  1682. ylimMax *= 2
  1683. ylimMin = -ylimMax/20
  1684. plotdataframe(df, "mse", Deb, Fin, tabnewstart,
  1685. unitx="Trial", unity=par, color="b",
  1686. ylim=(ylimMin, ylimMax))
  1687. plt.subplot(333)
  1688. Deb = int(len(df)*3/4)
  1689. Fin = len(df)
  1690. max_valY = df[Deb:Fin][par].max()
  1691. ylimMax = adaptScale(max_valY)
  1692. # if (max_valY - min_valY) < (0.5 * ylimMax):
  1693. # ylimMax *= 2
  1694. ylimMin = -ylimMax/20
  1695. plotdataframe(df, "mse", Deb, Fin, tabnewstart,
  1696. unitx="Trial", unity=par, color="b",
  1697. ylim=(ylimMin, ylimMax))
  1698. plt.subplot(334)
  1699. Deb = 0
  1700. Fin = len(df)
  1701. par = "coactpenality"
  1702. plotdataframe(df, "coactpenality", Deb, Fin, tabnewstart,
  1703. unitx="Trial", unity=par, color="orange")
  1704. plt.subplot(335)
  1705. Deb = int(len(df)/2)
  1706. Fin = len(df)
  1707. plotdataframe(df, "coactpenality", Deb, Fin, tabnewstart,
  1708. unitx="Trial", unity=par, color="orange")
  1709. plt.subplot(336)
  1710. Deb = int(len(df)*3/4)
  1711. Fin = len(df)
  1712. plotdataframe(df, "coactpenality", Deb, Fin, tabnewstart,
  1713. unitx="Trial", unity=par, color="orange")
  1714. plt.subplot(337)
  1715. Deb = 0
  1716. Fin = len(df)
  1717. par = "mse"
  1718. max_valY = df[Deb:Fin][par][Deb + 1]
  1719. min_valY = df[Deb:Fin][par][Fin]
  1720. ylimMax = adaptScale(max_valY)
  1721. if (max_valY - min_valY) < (0.5 * ylimMax):
  1722. ylimMax *= 2
  1723. ylimMin = -ylimMax/20
  1724. plotdf_improve(df, "mse", Deb, Fin, tabnewstart,
  1725. unitx="Trial", unity=par, color="b",
  1726. ylim=(ylimMin, ylimMax))
  1727. plt.subplot(338)
  1728. Deb = int(len(df)/2)
  1729. Fin = len(df)
  1730. max_valY = df[Deb:Fin][par][Deb + 1]
  1731. ylimMax = adaptScale(max_valY)
  1732. if (max_valY - min_valY) < (0.5 * ylimMax):
  1733. ylimMax *= 2
  1734. ylimMin = -ylimMax/20
  1735. plotdf_improve(df, "mse", Deb, Fin, tabnewstart,
  1736. unitx="Trial", unity=par, color="b",
  1737. ylim=(ylimMin, ylimMax))
  1738. plt.subplot(339)
  1739. Deb = int(len(df)*3/4)
  1740. Fin = len(df)
  1741. max_valY = df[Deb:Fin][par][Deb + 1]
  1742. ylimMax = adaptScale(max_valY)
  1743. # if (max_valY - min_valY) < (0.5 * ylimMax):
  1744. # ylimMax *= 2
  1745. ylimMin = -ylimMax/20
  1746. plotdf_improve(df, "mse", Deb, Fin, tabnewstart,
  1747. unitx="Trial", unity=par, color="b",
  1748. ylim=(ylimMin, ylimMax))
  1749. plt.gcf().subplots_adjust(left=0.09, right=0.95, top=0.9, bottom=0.1,
  1750. wspace=0.2, hspace=0.25)
  1751. bestfit = df["mse"].min()
  1752. bestfitline = df.index[df['mse'] == bestfit].values
  1753. if len(bestfitline) > 1:
  1754. bestfitlineVal = bestfitline[0]
  1755. else:
  1756. bestfitlineVal = bestfitline
  1757. titre = get_titre(path, FitCourseFileName)
  1758. # titre = completeName
  1759. titre = titre + "\n" + "bestfit= %3.3f at line %3d" % (bestfit,
  1760. bestfitlineVal)
  1761. plt.suptitle(titre, fontsize=20)
  1762. plt.savefig(os.path.join(path, baseName + '.pdf'))
  1763. plt.savefig(os.path.join(path, baseName + '.eps'))
  1764. plt.show()
  1765. def select_chartcol(optSet, colnames):
  1766. list_elem = colnames
  1767. typ = "chart_col"
  1768. print("Select sensory neurons to plot (validate the selection window)")
  1769. selected = optSet.sensColChartNames
  1770. text = "select sensory neurons to plot"
  1771. list_sensory_neur = choose_elements_in_list(list_elem, typ, selected, text)
  1772. print("Select alpha MNs to plot (validate the selection window)")
  1773. selected = optSet.mnColChartNames
  1774. text = "select alpha MNs to plot"
  1775. list_alpha_neur = choose_elements_in_list(list_elem, typ, selected, text)
  1776. print("Select gamma MNs to plot (check and validate selection window)")
  1777. selected = []
  1778. text = "select gamma MN to plot"
  1779. list_gamma_neur = choose_elements_in_list(list_elem, typ, selected, text)
  1780. return list_sensory_neur, list_alpha_neur, list_gamma_neur
  1781. def graph_chart_elements(optSet, chart_path, chartName,
  1782. lstChartColNam=["1FlxPotMuscle", "1ExtPotMuscle"],
  1783. y_label="EMG (mV)",
  1784. title="_EMG_Mvt"):
  1785. """
  1786. Uses the path, chartname to built a plot of a dataframe of chart data.
  1787. """
  1788. # EMGsNames = ['1FlxPotMuscle', '1ExtPotMuscle']
  1789. colnames = optSet.chartColNames
  1790. # completeName = os.path.join(chart_path, chartName)
  1791. completeName = chart_path + "/" + chartName
  1792. baseName = os.path.splitext(chartName)[0]
  1793. my_palette = sns.color_palette("tab10")
  1794. # Tdf[:0.6]
  1795. (L, df, titre, tabparams) = chartToDataFrame(completeName,
  1796. colnames=colnames)
  1797. df.index = df.Time
  1798. df[:0.6]
  1799. plt.figure(figsize=(20, 8), dpi=50)
  1800. plt.subplot(121)
  1801. plt.rc('xtick', labelsize=14) # fontsize of the x tick labels
  1802. plt.rc('ytick', labelsize=14) # fontsize of the x tick labels
  1803. for col in range(len(lstChartColNam)):
  1804. print()
  1805. df_EMG = df[:][lstChartColNam[col]] * 1000
  1806. df_EMG.loc[4:7].plot(color=my_palette[col])
  1807. unitx = "Time (s)"
  1808. # unity = "EMG (mV)"
  1809. unity = y_label
  1810. plt.xlabel(unitx, fontsize=18)
  1811. plt.ylabel(unity, fontsize=18)
  1812. plt.legend(fontsize=12)
  1813. plt.subplot(122)
  1814. df.loc[4:7]["Elbow"].plot(color="c")
  1815. unitx = "Time (s)"
  1816. unity = "Elbow Mvt (degres)"
  1817. plt.xlabel(unitx, fontsize=18)
  1818. plt.ylabel(unity, fontsize=18)
  1819. plt.legend(fontsize=12)
  1820. plt.suptitle(titre, fontsize=20)
  1821. plt.savefig(os.path.join(chart_path, baseName + title + '.pdf'))
  1822. #plt.savefig(os.path.join(chart_path, baseName + title + '.eps'))
  1823. plt.show()
  1824. def graph_triphasic(optSet, chart_path, chartName, EMGsNames):
  1825. """
  1826. Uses the path, chartname to built a plot of a dataframe of chart data.
  1827. """
  1828. # EMGsNames = ['1FlxPotMuscle', '1ExtPotMuscle']
  1829. colnames = optSet.chartColNames
  1830. # completeName = os.path.join(chart_path, chartName)
  1831. completeName = chart_path + "/" + chartName
  1832. baseName = os.path.splitext(chartName)[0]
  1833. my_palette = sns.color_palette("tab10")
  1834. # Tdf[:0.6]
  1835. (L, df, titre, tabparams) = chartToDataFrame(completeName,
  1836. colnames=colnames)
  1837. df.index = df.Time
  1838. df[:0.6]
  1839. plt.figure(figsize=(20, 8), dpi=50)
  1840. plt.subplot(121)
  1841. plt.rc('xtick', labelsize=14) # fontsize of the x tick labels
  1842. plt.rc('ytick', labelsize=14) # fontsize of the x tick labels
  1843. for col in range(2):
  1844. df_EMG = df[:][EMGsNames[col]] * 1000
  1845. df_EMG[4:7].plot(color=my_palette[col])
  1846. unitx = "Time (s)"
  1847. unity = "EMG (mV)"
  1848. plt.xlabel(unitx, fontsize=18)
  1849. plt.ylabel(unity, fontsize=18)
  1850. plt.legend(fontsize=12)
  1851. plt.subplot(122)
  1852. df[4:7]["Elbow"].plot(color="c")
  1853. unitx = "Time (s)"
  1854. unity = "Elbow Mvt (degres)"
  1855. plt.xlabel(unitx, fontsize=18)
  1856. plt.ylabel(unity, fontsize=18)
  1857. plt.legend(fontsize=12)
  1858. plt.suptitle(titre, fontsize=20)
  1859. plt.savefig(os.path.join(chart_path, baseName + '_EMG_Mvt.pdf'))
  1860. plt.savefig(os.path.join(chart_path, baseName + '_EMG_Mvt.eps'))
  1861. plt.show()
  1862. def graphfromchart(optSet, chart_path, chartName, templateFileName,
  1863. comment=""):
  1864. """
  1865. Uses the path, chartname and corresponding mvt template to
  1866. built a plot of a dataframe of chart data.
  1867. """
  1868. colnames = optSet.chartColNames
  1869. completeName = os.path.join(chart_path, chartName)
  1870. baseName = os.path.splitext(chartName)[0]
  1871. rootname = os.path.split(chart_path)[0]
  1872. result_path = rootname + "/ResultFiles"
  1873. expename2 = os.path.split(rootname)[1]
  1874. split2 = os.path.split(rootname)[0]
  1875. expename1 = os.path.split(split2)[1]
  1876. split1 = os.path.split(split2)[0]
  1877. expename0 = os.path.split(split1)[1]
  1878. experoot = expename0 + "/" + expename1 + "/" + expename2
  1879. chart_plot_pickle_name = result_path + "/chart_plot.pkl"
  1880. if os.path.exists(chart_plot_pickle_name):
  1881. with open(chart_plot_pickle_name, 'rb') as f1:
  1882. optSet.chart_column_to_plot = pickle.load(f1)
  1883. list_sensory_neur = optSet.chart_column_to_plot[0]
  1884. list_alpha_neur = optSet.chart_column_to_plot[1]
  1885. list_gamma_neur = optSet.chart_column_to_plot[2]
  1886. else:
  1887. rep = select_chartcol(optSet, colnames)
  1888. list_sensory_neur, list_alpha_neur, list_gamma_neur = rep
  1889. if rep is not None:
  1890. optSet.chart_column_to_plot = list(rep)
  1891. with open(chart_plot_pickle_name, 'wb') as f1:
  1892. pickle.dump(list(rep), f1)
  1893. T = np.loadtxt(templateFileName)
  1894. Tdf = pd.DataFrame(T)
  1895. Tdf.index = Tdf[1]
  1896. my_palette = sns.color_palette("tab10")
  1897. # Tdf[:0.6]
  1898. (L, df, tit, tabparams) = chartToDataFrame(completeName,
  1899. colnames=colnames)
  1900. split_tit = tit.split(";")
  1901. if split_tit[2][:5] == " mse:":
  1902. msetxt = split_tit[2].split(":")[1]
  1903. mseVal = float(msetxt)
  1904. coacttxt = split_tit[3].split(":")[1].split("\n")[0]
  1905. coactVal = float(coacttxt)
  1906. elif split_tit[2][:5] == ' best':
  1907. msetxt = split_tit[2].split(":")[1]
  1908. mseVal = float(msetxt)
  1909. coactVal = None
  1910. else:
  1911. msetxt = split_tit[1].split(":")[1]
  1912. mseVal = float(msetxt)
  1913. coacttxt = split_tit[3].split(":")[1]
  1914. coactVal = float(coacttxt)
  1915. titre = chartName + "; " + experoot
  1916. if coactVal is None:
  1917. titre += "\n mse:{:.4f}".format(mseVal)
  1918. else:
  1919. titre += "\n mse:{:.4f} coactP:{:.4}".format(mseVal, coactVal)
  1920. dfsrtTime = df.Time[0]
  1921. # dfendTime = df.Time[len(df)-1]
  1922. dfendTime = 9.99
  1923. df.index = df.Time
  1924. df[:0.6]
  1925. # add two columns to df : TemplateTime and Template
  1926. df.loc[:, 'TemplateTime'] = Tdf[dfsrtTime:dfendTime][1]
  1927. df.loc[:, 'Template'] = Tdf[dfsrtTime:dfendTime][2]
  1928. if verbose > 3:
  1929. print("15 first rows...")
  1930. print(df[dfsrtTime:dfsrtTime+0.15])
  1931. print("15 last rows")
  1932. print(df[dfendTime-0.15:dfendTime])
  1933. plt.figure(figsize=(20, 15), dpi=50)
  1934. plt.subplot(321)
  1935. muscle = ["Triceps1", "Biceps1"]
  1936. plt.rc('xtick', labelsize=14) # fontsize of the x tick labels
  1937. plt.rc('ytick', labelsize=14) # fontsize of the x tick labels
  1938. for col in range(2):
  1939. df[:dfendTime][muscle[col]].plot(color=my_palette[col])
  1940. unitx = "Time (s)"
  1941. unity = "Force (N)"
  1942. plt.xlabel(unitx, fontsize=18)
  1943. plt.ylabel(unity, fontsize=18)
  1944. plt.legend(fontsize=12)
  1945. list_alpha_neur.sort()
  1946. plt.subplot(322)
  1947. for col, mn in enumerate(list_alpha_neur):
  1948. df_mn = df[:dfendTime][mn] * 1000
  1949. df_mn.plot(color=my_palette[col])
  1950. # df[:]["1ExtAlpha"].plot(color="b")
  1951. # df[:]['1FlxAlpha'].plot(color="r")
  1952. unitx = "Time (s)"
  1953. unity = "Membrane potentoial (mV)"
  1954. plt.xlabel(unitx, fontsize=18)
  1955. plt.ylabel(unity, fontsize=18)
  1956. plt.legend(fontsize=12)
  1957. list_sensory_neur.sort()
  1958. plt.subplot(323)
  1959. for col, sens in enumerate(list_sensory_neur):
  1960. df_sens = df[:dfendTime][sens] * 1000
  1961. df_sens.plot(color=my_palette[col])
  1962. # df[:]["1ExtIa"].plot(color="b")
  1963. # df[:]["1FlxIa"].plot(color="r")
  1964. unitx = "Time (s)"
  1965. unity = "Membrane potentoial (mV)"
  1966. plt.xlabel(unitx, fontsize=18)
  1967. plt.ylabel(unity, fontsize=18)
  1968. plt.legend(fontsize=12)
  1969. list_gamma_neur.sort()
  1970. plt.subplot(324)
  1971. for col, gamma in enumerate(list_gamma_neur):
  1972. df_gamma = df[:dfendTime][gamma] *1000
  1973. df_gamma.plot(color=my_palette[col])
  1974. # df[:]["1ExtGamma"].plot(color="b")
  1975. # df[:]["1FlxGamma"].plot(color="r")
  1976. unitx = "Time (s)"
  1977. unity = "Membrane potentoial (mV)"
  1978. plt.xlabel(unitx, fontsize=18)
  1979. plt.ylabel(unity, fontsize=18)
  1980. plt.legend(fontsize=12)
  1981. plt.subplot(325)
  1982. df[:dfendTime]["Elbow"].plot(color="c")
  1983. df[:dfendTime]["Template"].plot(color="grey")
  1984. unitx = "Time (s)"
  1985. unity = "Elbow Mvt (degres)"
  1986. plt.xlabel(unitx, fontsize=18)
  1987. plt.ylabel(unity, fontsize=18)
  1988. plt.legend(fontsize=12)
  1989. plt.subplot(326)
  1990. df[4.5:6]["Elbow"].plot(color="c")
  1991. df[4.5:6]["Template"].plot(color="grey")
  1992. unitx = "Time (s)"
  1993. unity = "Elbow Mvt (degres)"
  1994. plt.xlabel(unitx, fontsize=18)
  1995. plt.ylabel(unity, fontsize=18)
  1996. plt.legend(fontsize=12)
  1997. plt.gcf().subplots_adjust(left=0.09, right=0.95, top=0.9, bottom=0.1,
  1998. wspace=0.2, hspace=0.25)
  1999. if comment != "":
  2000. titre += "\n " + comment
  2001. plt.suptitle(titre, fontsize=20)
  2002. completename = os.path.join(chart_path, baseName + '_bhvMvt.pdf')
  2003. if os.path.isfile(completename):
  2004. os.remove(completename)
  2005. plt.savefig(os.path.join(chart_path, baseName + '_bhvMvt.pdf'))
  2006. completename = os.path.join(chart_path, baseName + '_bhvMvt.eps')
  2007. if os.path.isfile(completename):
  2008. os.remove(completename)
  2009. plt.savefig(os.path.join(chart_path, baseName + '_bhvMvt.eps'))
  2010. plt.show()
  2011. def choose_title_col(df):
  2012. """
  2013. """
  2014. lst_col_name = list(df.columns)
  2015. listDic_columns = [{'title': lst_col_name[0]}]
  2016. listChoix = list(listDic_columns[0].keys())
  2017. titleText = "select a column for titles"
  2018. rep = ChooseInList.listTransmit(parent=None,
  2019. graphNo=0,
  2020. listChoix=listChoix,
  2021. items=lst_col_name,
  2022. listDicItems=listDic_columns,
  2023. onePerCol=[1],
  2024. colNames=["title"],
  2025. typ="chk",
  2026. titleText=titleText)
  2027. # Create a series from dic_params_order
  2028. listDic_columns = rep[0]
  2029. title_col = listDic_columns[0]['title'][0]
  2030. return title_col
  2031. def choose_lines(lst_ligns):
  2032. """
  2033. """
  2034. lst_items = [str(title) for title in lst_ligns]
  2035. listDic_limits = [{'first': lst_items[0], 'last': lst_items[1]}]
  2036. """
  2037. listChoix = []
  2038. for key in listDic_limits[0].keys():
  2039. listChoix.append(key)
  2040. """
  2041. listChoix = ["first", "last"]
  2042. titleText = "select start and end of rows for radar"
  2043. rep = ChooseInList.listTransmit(parent=None,
  2044. graphNo=0,
  2045. listChoix=listChoix,
  2046. items=lst_items,
  2047. listDicItems=listDic_limits,
  2048. onePerCol=[1, 1],
  2049. colNames=listChoix,
  2050. typ="chk",
  2051. titleText=titleText)
  2052. # Create a series from dic_params_order
  2053. listDic_limits = rep[0]
  2054. first = listDic_limits[0]['first'][0]
  2055. last = listDic_limits[0]['last'][0]
  2056. return (first, last)
  2057. def reorder_df(df, prev_column_order=None):
  2058. """
  2059. """
  2060. if prev_column_order is None:
  2061. col_name = list(df.columns)
  2062. listChoix = ['params']
  2063. listDic_params = [{'params': col_name}]
  2064. params_order = list(zip(col_name, list(range(1, len(col_name)+1, 1))))
  2065. dic_params_order = dict(params_order)
  2066. listDic_params_order = [dic_params_order]
  2067. titleText = "set order of parameters"
  2068. rep = ChooseInList.listTransmit(parent=None,
  2069. graphNo=0,
  2070. listChoix=listChoix,
  2071. items=col_name,
  2072. listDicItems=listDic_params,
  2073. onePerCol=[0],
  2074. colNames=["order"],
  2075. dicValues=listDic_params_order[0],
  2076. typ="val",
  2077. titleText=titleText)
  2078. # Create a series from dic_params_order
  2079. listDic_params = rep[0]
  2080. dic_params_order = rep[1]
  2081. for par in list(dic_params_order.keys()):
  2082. val = dic_params_order[par]
  2083. if int(float(val)) < 10:
  2084. val = "0" + val
  2085. dic_params_order[par] = int(float(val))
  2086. else:
  2087. dic_params_order[par] = int(float(val))
  2088. # print "rep[1]", rep[1]
  2089. s = pd.Series(dic_params_order, name='order')
  2090. s.index.name = 'par_names'
  2091. s = s.reset_index()
  2092. # Create a dataframe from dic_params_order series
  2093. ordered_df = pd.DataFrame(s)
  2094. ordered_df = ordered_df.sort_values(by='order')
  2095. ordered_df.to_pickle(MyWin.graph_path + "/order_param.pkl")
  2096. # get the ordered paramNames
  2097. ordered_names = list(ordered_df["par_names"])
  2098. else:
  2099. ordered_names = prev_column_order
  2100. # Re-order the original df folloing the new column order
  2101. df_new = df.reindex(columns=ordered_names)
  2102. return df_new
  2103. def prepare_spider(df_radar, row, title, overdraw, color, ylim=(-0.2, 1)):
  2104. """
  2105. Procedure used to prepare a radar graph (set position in sheet, polar axes,
  2106. names around the radar)
  2107. """
  2108. (ymin, ymax) = ylim
  2109. # number of variable
  2110. categories = list(df_radar)[0:]
  2111. N = len(categories)
  2112. red_categories = [cat[:cat.find(".")] for cat in categories]
  2113. null_categories = ["" for cat in categories]
  2114. # prepares ticks and labels
  2115. # nbstep = (ymax - ymin) * 10
  2116. # ticks = np.arange(ymin, ymax+float(ymax-ymin)/nbstep,
  2117. # float(ymax-ymin)/nbstep)
  2118. # strticks = ["{:2.2f}".format(tick) for tick in ticks]
  2119. # calculate the angle of each axis in the plot
  2120. # pi = np.pi
  2121. angles = [n / float(N) * 2 * pi for n in range(N)]
  2122. angles += angles[:1]
  2123. # Initialise the spider plot
  2124. if not overdraw:
  2125. ax = plt.subplot(3, 2, row+1, polar=True, )
  2126. plt.subplots_adjust(wspace=0.9, hspace=None)
  2127. labelsize = 9
  2128. offset = (1.08)
  2129. letterscale = 0.036
  2130. else:
  2131. ax = plt.subplot(2, 1, 1, polar=True, )
  2132. plt.gcf().subplots_adjust(left=0.2, bottom=0.2,
  2133. right=0.7, top=0.9,
  2134. wspace=0, hspace=0.2)
  2135. labelsize = 13
  2136. offset = (1.09)
  2137. letterscale = 0.020
  2138. # In order the first axis to be on top:
  2139. ax.set_theta_offset(pi / 2)
  2140. ax.set_theta_direction(-1)
  2141. # Draw one axe per variable + add labels labels yet
  2142. # plt.xticks(angles[:-1], red_categories, color='grey', size=12)
  2143. plt.xticks(angles[:-1], null_categories, color='grey', size=12)
  2144. # Draw ylabels
  2145. ax.set_rlabel_position(0)
  2146. # plt.yticks(ticks, strticks, color="grey", size=10)
  2147. plt.ylim(ymin, ymax)
  2148. # add oriented xlabels
  2149. theta = np.arange(pi/2, -2*pi + pi/2, -2*pi/N)
  2150. rotations = np.rad2deg(theta)
  2151. for x, rotation, label in zip(angles[:-1], rotations, red_categories):
  2152. # offset = (1.1)
  2153. h = offset + (len(label)/2.) * letterscale
  2154. lab = ax.text(x, h, label,
  2155. transform=ax.get_xaxis_transform(),
  2156. ha='center', va='center', fontsize=labelsize)
  2157. lab.set_rotation(rotation)
  2158. # Add a title
  2159. plt.title(title, size=16, color=color, y=1.4)
  2160. return ax, angles
  2161. def add_spider_values(df_radar, row, color, title, filled, ax, angles):
  2162. # get the values to plot
  2163. values = df_radar.loc[row].values.flatten().tolist()
  2164. values += values[:1]
  2165. ax.plot(angles, values, color=color, linewidth=2, linestyle='solid',
  2166. label=title)
  2167. if filled:
  2168. ax.fill(angles, values, color=color, alpha=0.3)
  2169. return ax
  2170. def makeRadarFromExcelPar_csv(df_radar, lst_title, sup_title, sub_title,
  2171. graph_path, name, ylim):
  2172. """
  2173. Builds the global graph of a series of radars (from df_radar), with a
  2174. global name (sup_title), a sub-title, and the path and name of the figure
  2175. to be saved.
  2176. """
  2177. lst_df_rad = []
  2178. # builts a new index for df_radar
  2179. df_radar.index = np.arange(len(df_radar))
  2180. nb_rad = len(df_radar)
  2181. if len(df_radar.index) < 7:
  2182. lst_df_rad.append(df_radar)
  2183. else:
  2184. k = 0
  2185. last_rad = (k+1) * 6
  2186. while last_rad < nb_rad:
  2187. lst_df_rad.append(df_radar[k*6:last_rad])
  2188. k += 1
  2189. last_rad = (k+1) * 6
  2190. lst_df_rad.append(df_radar[k*6:nb_rad])
  2191. # Create a color palette:
  2192. # my_palette = plt.cm.get_cmap("Set2", len(df_radar.index))
  2193. # my_palette = plt.cm.get_cmap("tab20", len(df_radar.index))
  2194. # my_palette = plt.cm.get_cmap("gist_ncar", len(df_radar.index)+2)
  2195. my_palette = mpl.colormaps["gist_ncar"](len(df_radar.index)+2)
  2196. # my_palette = plt.cm.get_cmap("nipy_spectral", len(df_radar.index)+1)
  2197. filled = True
  2198. overdraw = False
  2199. # Loop to plot
  2200. for idx, df_rad in enumerate(lst_df_rad):
  2201. # initialize the figure
  2202. my_dpi = 60
  2203. plt.figure(figsize=(900/my_dpi, 1800/my_dpi), dpi=my_dpi)
  2204. df_rad.index = list(range(len(df_rad)))
  2205. for row in list(df_rad.index):
  2206. rad = row + idx*6
  2207. print(rad)
  2208. color = my_palette(rad)
  2209. title = lst_title[rad]
  2210. # ylim = (0, 1/float(scale_up))
  2211. ax, angles = prepare_spider(df_radar, row, title, overdraw,
  2212. color, ylim)
  2213. add_spider_values(df_radar, row, color, title, filled, ax, angles)
  2214. plt.suptitle(sup_title, fontsize=16)
  2215. plt.figtext(.5, .9, sub_title + str(idx), fontsize=14, ha='center')
  2216. # model_dir = graph_path
  2217. tit = os.path.split(sup_title)[-1]
  2218. sstit = sub_title + str(idx)
  2219. save_eps_pdf(graph_path, tit, sstit)
  2220. # plt.savefig(os.path.join(path, name + sub_title + str(idx) + '.pdf'))
  2221. # plt.savefig(os.path.join(path, name + sub_title + str(idx) + '.eps'))
  2222. plt.show()
  2223. def overdrawRadarFromExcelPar_csv(df_radar, lst_title, sup_title, sub_title,
  2224. graph_path, name, ylim):
  2225. """
  2226. Builds the global graph of overdran selected params (from df_radar), with a
  2227. global name (sup_title), a sub-title, and the path and name of the figure
  2228. to be saved.
  2229. """
  2230. # builts a new index for df_radar
  2231. df_radar.index = np.arange(len(df_radar))
  2232. # Create a color palette:
  2233. # my_palette = plt.cm.get_cmap("Set2", len(df_radar.index))
  2234. # my_palette = plt.cm.get_cmap("tab20", len(df_radar.index))
  2235. my_palette = mpl.colormaps["gist_ncar"](len(df_radar.index)+2)
  2236. # my_palette = plt.cm.get_cmap("nipy_spectral", len(df_radar.index)+1)
  2237. filled = False
  2238. # initialize the figure
  2239. my_dpi = 60
  2240. plt.figure(figsize=(900/my_dpi, 1800/my_dpi), dpi=my_dpi)
  2241. row = 0
  2242. title = ""
  2243. color = "b"
  2244. overdraw = True
  2245. # ax, angles = prepare_spider(df_radar, row, title,
  2246. # overdraw, color, ylim=(-0.2, 1))
  2247. ax, angles = prepare_spider(df_radar, row, title,
  2248. overdraw, color, ylim=ylim)
  2249. for rad in list(df_radar.index):
  2250. print(rad, color)
  2251. color = my_palette(rad)
  2252. title = lst_title[rad]
  2253. ax = add_spider_values(df_radar, rad, color, title, filled, ax, angles)
  2254. # ax.legend(loc='upper right', bbox_to_anchor=(1.9, 1.1))
  2255. # ax.legend(prop=dict(size=18))
  2256. ax.legend(bbox_to_anchor=(1.55, 1.2), prop=dict(size=14))
  2257. plt.suptitle(sup_title, fontsize=16, y=1.02)
  2258. plt.figtext(.5, 0.98, sub_title, fontsize=14, ha='center')
  2259. # model_dir = graph_path
  2260. tit = os.path.split(sup_title)[-1]
  2261. sstit = sub_title + "_overdraw"
  2262. save_eps_pdf(graph_path, tit, sstit)
  2263. # plt.savefig(os.path.join(path, name + sub_title + str(idx) + '.pdf'))
  2264. # plt.savefig(os.path.join(path, name + sub_title + str(idx) + '.eps'))
  2265. plt.show()
  2266. def adaptPaletteTodf(df_glob_sel, factor, step_palette, codeCoul_df_sel):
  2267. """
  2268. From step_palette, creates a set of colors, one for each element in the df.
  2269. """
  2270. colour = [step_palette[i] for i in codeCoul_df_sel['color']]
  2271. if verbose > 2:
  2272. print("... color scale achieved")
  2273. print("len(colour) =", len(colour))
  2274. print("len(df_glob_sel) =", len(df_glob_sel))
  2275. return colour
  2276. def buildStpFilledCol(df, factor):
  2277. """
  2278. Creates a palette of colors one for each element in the df. This is not the
  2279. same as "buildStpDiscretCol()" that get only the colors of levels (missing
  2280. steps in codeCoul_df being removed).
  2281. """
  2282. # ============= creates new "color" & factor df ==============
  2283. codeCoul_df = copy.deepcopy(df[[factor]])
  2284. rg = codeCoul_df.index
  2285. codeCoul_df.loc[:, 'rg'] = rg # index is now in a new column 'rg'
  2286. codeCoul_df.sort_values(factor, axis=0, ascending=True,
  2287. inplace=True, na_position='last')
  2288. sort_factor = np.array(codeCoul_df[factor])
  2289. # ----- creates a quantal progressing array for factor values
  2290. mult = 0.1
  2291. nb_levels = 1
  2292. newsortf = copy.deepcopy(sort_factor)
  2293. newsortf = newsortf * mult
  2294. newsortf = newsortf.astype(int)
  2295. mini = newsortf.min()
  2296. maxi = newsortf.max()
  2297. while nb_levels <= 100:
  2298. mult *= 10
  2299. newsortf = copy.deepcopy(sort_factor)
  2300. # newsortf = (newsortf * 10)
  2301. newsortf = newsortf * mult
  2302. newsortf = newsortf.astype(int)
  2303. mini = newsortf.min()
  2304. maxi = newsortf.max()
  2305. nb_levels = maxi-mini + 1
  2306. if verbose > 2:
  2307. print(nb_levels)
  2308. if nb_levels > 100:
  2309. mult = mult/10
  2310. newsortf = copy.deepcopy(sort_factor)
  2311. # newsortf = (newsortf * 10)
  2312. newsortf = newsortf * mult
  2313. newsortf = newsortf.astype(int)
  2314. mini = newsortf.min()
  2315. maxi = newsortf.max()
  2316. nb_levels = maxi-mini + 1
  2317. if verbose > 2:
  2318. print(nb_levels)
  2319. # ==== creates the color palette associated to nb levels
  2320. step_palette = []
  2321. cmap = plt.get_cmap('gist_rainbow')
  2322. for i in range(nb_levels):
  2323. # print cmap(float(i)/nb_levels, float(10)/10)
  2324. step_palette.append(cmap(float(i)/nb_levels, float(10)/10))
  2325. # ==== crates a list of the colors of each data in factor
  2326. color_sort = []
  2327. for idx, val in enumerate(newsortf):
  2328. color_sort.append(step_palette[val-mini])
  2329. # ------ rescale 'seq_factor' to original scale
  2330. newsortf_scale = newsortf/mult
  2331. # ------ adds the new "quantal progressing factor" column
  2332. seq_factor = "seq_{}".format(factor)
  2333. codeCoul_df.loc[:, seq_factor] = newsortf_scale
  2334. # ------ adds the new "quantal progressing factor" column
  2335. coul = newsortf - newsortf.min()
  2336. coul = coul.astype(int)
  2337. codeCoul_df.loc[:, "color"] = coul
  2338. # ------ re-arrange df according to original rg
  2339. codeCoul_df.sort_values("rg", axis=0, ascending=True,
  2340. inplace=True, na_position='last')
  2341. color = [step_palette[i] for i in codeCoul_df['color']]
  2342. if verbose > 2:
  2343. print("... color scale achieved")
  2344. print("len(color) =", len(color))
  2345. print("len(df) =", len(df))
  2346. return color, codeCoul_df, step_palette
  2347. def buildStpDiscretCol(df_glob, factor):
  2348. """
  2349. Creates a palette of colors corresponding to the number of leves in the
  2350. factor column. This column is first copied and transformed in a series of
  2351. level values. Each level corresponds to a color
  2352. """
  2353. # *********** creates a new rainbow palette n = 20 levels ********
  2354. cmap = plt.get_cmap('gist_rainbow')
  2355. # ============= creates new "color" & factor df ==============
  2356. codeCoul_df = copy.deepcopy(df_glob[[factor]])
  2357. codeCoul_df.dropna(inplace=True)
  2358. rg = codeCoul_df.index
  2359. codeCoul_df.loc[:, 'rg'] = rg # index is now in a new column 'rg'
  2360. codeCoul_df.sort_values(factor, axis=0, ascending=True,
  2361. inplace=True, na_position='last')
  2362. # type(codeCoul_df)
  2363. codeCoul_df.describe()
  2364. sort_factor = codeCoul_df[factor].values
  2365. # sort_factor = codeCoul_df[factor].values.T[0]
  2366. # ----- creates a sequential array for factor values
  2367. mult = 0.1
  2368. nb_levels = 1
  2369. newsortf = copy.deepcopy(sort_factor)
  2370. newsortf = newsortf * mult
  2371. newsortf = newsortf.astype(int)
  2372. mini = newsortf.min()
  2373. maxi = newsortf.max()
  2374. while nb_levels <= 50:
  2375. mult *= 2
  2376. newsortf = copy.deepcopy(sort_factor)
  2377. # newsortf = (newsortf * 10)
  2378. newsortf = newsortf * mult
  2379. newsortf = newsortf.astype(int)
  2380. mini = newsortf.min()
  2381. maxi = newsortf.max()
  2382. nb_levels = maxi-mini + 1
  2383. # print nb_levels
  2384. if nb_levels > 50:
  2385. mult = mult/2
  2386. newsortf = copy.deepcopy(sort_factor)
  2387. # newsortf = (newsortf * 10)
  2388. newsortf = newsortf * mult
  2389. newsortf = newsortf.astype(int)
  2390. mini = newsortf.min()
  2391. maxi = newsortf.max()
  2392. nb_levels = maxi-mini + 1
  2393. # print nb_levels
  2394. print("nb_levels:", nb_levels)
  2395. # ========= build the palettte for factor df ==========
  2396. step_palette = []
  2397. for i in range(nb_levels):
  2398. # print cmap(float(i)/nb_levels, float(10)/10)
  2399. step_palette.append(cmap(float(i)/nb_levels, float(10)/10))
  2400. palette = step_palette
  2401. # the sequential array (newsortf) may contain up to 100 steps
  2402. # So now we limit the superior values of the array
  2403. limsup = mini + len(palette) - 1
  2404. for idx, val in enumerate(newsortf):
  2405. if val > limsup:
  2406. newsortf[idx] = limsup
  2407. mini = newsortf.min()
  2408. maxi = newsortf.max()
  2409. nb_levels = maxi-mini + 1
  2410. # ==== modifies palette for missing levels in 'seq_factor' =====
  2411. step_color = len(palette) // nb_levels
  2412. nbstep_color = 0
  2413. list_colors = [] # list of index of valid colors in palette
  2414. list_colors.append(0) # starts with the first color in palette
  2415. prev_val = newsortf[0] # first value of ordered seq_factor
  2416. for idx, val in enumerate(newsortf):
  2417. if (val - prev_val) < 1: # same value in successive vals
  2418. None
  2419. # print "-",
  2420. else: # increment >= 1
  2421. # print '+{}'.format(val - prev_val),
  2422. nbstep_color = nbstep_color + (val - prev_val)
  2423. list_colors.append(nbstep_color * step_color)
  2424. prev_val = val
  2425. adapt_palette = []
  2426. for col in list_colors:
  2427. adapt_palette.append(palette[col])
  2428. step_pal_misRem = adapt_palette
  2429. # ===============================================================
  2430. # ------ rescale 'seq_factor' to original scale
  2431. newsortf = newsortf/mult
  2432. # ------ adds the new "color" column
  2433. seq_factor = "seq_{}".format(factor)
  2434. codeCoul_df.loc[:, seq_factor] = newsortf
  2435. # ------ reagange df according to original rg
  2436. codeCoul_df.sort_values("rg", axis=0, ascending=True,
  2437. inplace=True, na_position='last')
  2438. print("len(palette) =", len(step_pal_misRem))
  2439. return [step_pal_misRem, codeCoul_df]
  2440. def make_3d_plot_subPlots(df_glob, dataSet, selected_dataSets,
  2441. list_items, faceColItems,
  2442. xlim, ylim, zlim,
  2443. factor, select_3_col, titre, ss_titre, graph_path,
  2444. azim=60, elev=30):
  2445. """
  2446. Draws a 3D scatter plot with a fourth parameter as color scale
  2447. """
  2448. # ======= The following lines are used to debug the plot =======
  2449. """
  2450. self=MyWin
  2451. df_glob = self.df_glob
  2452. factor = self.factor
  2453. select_3_col = self.select_3_col
  2454. ss_titre = self.ss_titre
  2455. titre = "Fig5_3D_Dots_{}__{}__{}".format(select_3_col[0][:13],
  2456. select_3_col[1][:13],
  2457. select_3_col[2][:13])
  2458. dataSet = self.visu_3d.dataSet
  2459. selected_dataSets = self.visu_3d.selected_dataSets
  2460. list_items = self.visu_3d.setnames
  2461. self.graph_settings.choose_factor()
  2462. factor = self.factor
  2463. print("factor =", factor)
  2464. color, codeCoul_df, step_palette = buildStpFilledCol(df_glob, factor)
  2465. # Gets the first set of dots to apply color scale on it
  2466. gl3d_item = self.visu_3d.listgl3dItems[0]
  2467. self.visu_3d.apply_colors(color, gl3d_item)
  2468. azim = self.visu_3d.axis.azim
  2469. elev = self.visu_3d.axis.elev
  2470. xlim = self.visu_3d.axis.get_xlim()
  2471. ylim = self.visu_3d.axis.get_ylim()
  2472. zlim = self.visu_3d.axis.get_zlim()
  2473. model_dir = self.ensembleRunDir
  2474. color, codeCoul_df, step_palette = buildStpFilledCol(df_glob, factor)
  2475. gl3d_item = self.visu_3d.listgl3dItems[0]
  2476. self.visu_3d.apply_colors(color, gl3d_item)
  2477. faceColItems = self.visu_3d.faceColItems
  2478. """
  2479. [step_pal_misRem, codeCoul_df] = buildStpDiscretCol(df_glob, factor)
  2480. seq_factor = "seq_{}".format(factor)
  2481. # seq_factor_col = codeCoul_df[seq_factor]
  2482. classes = list(set(codeCoul_df[seq_factor]))
  2483. classes.sort(reverse=False)
  2484. color_map = dict(list(zip(classes, step_pal_misRem)))
  2485. # colors = seq_factor_col.apply(lambda group: color_map[group])
  2486. # print(colors[0:10])
  2487. # print()
  2488. # =============== Creating plot ==================
  2489. fig = plt.figure(figsize=(8, 8), dpi=100)
  2490. # ax = fig.gca(projection='3d')
  2491. ax = fig.add_axes([0.0, 0.0, 0.8, 0.8], projection='3d')
  2492. ax.view_init(azim=azim, elev=elev)
  2493. ax.set_xlabel(select_3_col[0])
  2494. ax.set_ylabel(select_3_col[1])
  2495. ax.set_zlabel(select_3_col[2])
  2496. ax.set_xlim(xlim)
  2497. ax.set_ylim(ylim)
  2498. ax.set_zlim(zlim)
  2499. subset_txt = ""
  2500. for idx, subset in enumerate(list_items):
  2501. colors = faceColItems[idx]
  2502. # print(colors[0:10])
  2503. if subset in selected_dataSets:
  2504. pos = dataSet[idx]
  2505. (x, y, z) = pos
  2506. ax.scatter(x, y, z, alpha=0.8,
  2507. facecolors=colors,
  2508. edgecolors=colors,
  2509. s=10,
  2510. # label=classes,
  2511. )
  2512. if subset == "main":
  2513. None
  2514. else:
  2515. subset_txt = "{}_{}".format(subset_txt, subset[7:])
  2516. tit = "{}__color={}".format(titre, factor[:13])
  2517. # tit = "{}({})".format(tit, subset_txt[:10])
  2518. orient = "azim({}) elev({})".format(azim, elev)
  2519. titre_2lines = "{}\n{} {}".format(tit, ss_titre, orient)
  2520. titre_3lines = "{}\n{}{}".format(titre_2lines, factor[:13], subset_txt)
  2521. plt.suptitle(titre_3lines, fontsize=14, y=0.90)
  2522. # ================= building legend for color scale ===============
  2523. labels = copy.deepcopy(classes)
  2524. labels.sort(reverse=True)
  2525. nbcolors = len(classes)
  2526. if nbcolors < 50:
  2527. handles = [plt.plot([], [], color=color_map[labels[i]],
  2528. ls="", marker='o',
  2529. markersize=6)[0] for i in range(nbcolors)]
  2530. # In legend order is that of classes (revert order)
  2531. plt.legend(handles, labels, loc=(1.08, 0.00))
  2532. plt.setp(plt.gca().get_legend().get_texts(), fontsize='6')
  2533. else:
  2534. # ------------ 1st set of legend elements ----------------
  2535. labels1 = labels[:nbcolors/2]
  2536. handles1 = [plt.plot([], [], color=color_map[labels[i]],
  2537. ls="", marker='o',
  2538. markersize=6)[0] for i in range(nbcolors/2)]
  2539. # In legend order is that of classes (revert order)
  2540. first_legend = plt.legend(handles1, labels1,
  2541. loc=(1.04, 0.00))
  2542. plt.gca().add_artist(first_legend)
  2543. plt.setp(plt.gca().get_legend().get_texts(), fontsize='6')
  2544. # ------------ 2nd set of legend elements ----------------
  2545. labels2 = labels[nbcolors/2:]
  2546. handles2 = [plt.plot([], [], color=color_map[labels[i]],
  2547. ls="", marker='o',
  2548. markersize=6)[0] for i in range(nbcolors/2,
  2549. nbcolors)]
  2550. # In legend order is that of classes (revert order)
  2551. second_legend = plt.legend(handles2, labels2,
  2552. loc=(1.12, 0.00))
  2553. plt.gca().add_artist(second_legend)
  2554. plt.setp(plt.gca().get_legend().get_texts(), fontsize='6')
  2555. sstit = ss_titre_to_txt(ss_titre)
  2556. sstit = "{}__az({})_el({})".format(sstit, azim, elev)
  2557. ficname = r'{0}\{1}{2}'.format(graph_path, tit, sstit)
  2558. directory = graph_path
  2559. ext = ".pdf"
  2560. complete_name = SaveIncrementNb(directory, ficname, ext)
  2561. file_name = os.path.splitext(complete_name)[0]
  2562. plt.savefig(r'{}.eps'.format(file_name), bbox_inches='tight')
  2563. plt.savefig(r'{}.pdf'.format(file_name), bbox_inches='tight')
  2564. plt.show()
  2565. def saveCSVStructure(self):
  2566. """
  2567. Saves the CSV files sturcture (Angle & Duration, Constants ...)
  2568. """
  2569. structCSVFileName = "CSV_Struct.par"
  2570. complete_structCSVFName = os.path.join(self.graph_path, structCSVFileName)
  2571. csv_structure = [self.graph_path, self.rootdir,
  2572. self.prevListAngles, self.prevListConsts,
  2573. self.prevListTrials, self.prevListColNames,
  2574. self.prevListParams,
  2575. [self.strtTime, self.endTime]]
  2576. f = open(complete_structCSVFName, 'w')
  2577. for idx in range(len(csv_structure)):
  2578. # s = str(idx) + '\t'
  2579. s = ""
  2580. if idx < 2:
  2581. s = csv_structure[idx] + '\n'
  2582. else:
  2583. for idy in range(len(csv_structure[idx])-1):
  2584. tmpval = csv_structure[idx][idy]
  2585. s += "{}".format(tmpval) + '\t'
  2586. s += "{}".format(csv_structure[idx][idy+1]) + '\n'
  2587. # print(s)
  2588. f.write(s)
  2589. f.close()
  2590. print("data saved to:", complete_structCSVFName)
  2591. def getBestParamSet(graph_path, ang, const, trial):
  2592. pathGEP = os.path.join(graph_path, ang, const, trial, "GEPdata")
  2593. fileGEP = os.path.join(pathGEP, "GEPdata00.par")
  2594. datastructure = load_datastructure(fileGEP)
  2595. nbMvtSet = len(datastructure)
  2596. bestChartName = ""
  2597. bestparamset = []
  2598. # print pathGEP,
  2599. if verbose > 2:
  2600. print("NbSets:", nbMvtSet, end=" ")
  2601. if nbMvtSet > 0:
  2602. mvtSet = nbMvtSet - 1
  2603. typ = datastructure[mvtSet][0]
  2604. start = datastructure[mvtSet][1]
  2605. end = datastructure[mvtSet][2]
  2606. # packetsize = datastructure[mvtSet][3]
  2607. if verbose > 2:
  2608. print("{} start={} end={}".format(typ, start, end), end=" ")
  2609. conditions = datastructure[mvtSet][4]
  2610. nbObj = len(conditions)
  2611. chartList = conditions[nbObj-2]
  2612. rangList = conditions[nbObj-1]
  2613. bestChartName = chartList[len(chartList)-1]
  2614. bestParamRg = rangList[len(rangList)-1]
  2615. if verbose > 2:
  2616. print("---> best param set: {}".format(bestParamRg))
  2617. tab = readTablo(pathGEP, "GEPdata00.txt")
  2618. tab = np.array(tab)
  2619. if tab[0][-1] != 0.0:
  2620. # nbparfromtab = len(tab[0]) - 2
  2621. pairs = np.array(tab[:, :])
  2622. else:
  2623. # nbparfromtab = len(tab[0]) - 2 - 1
  2624. pairs = np.array(tab[:, 0:-1])
  2625. bestparamset = pairs[bestParamRg]
  2626. else:
  2627. print("no data to plot")
  2628. return (bestChartName, bestparamset)
  2629. def read_pklfile(self, paramFicName):
  2630. try:
  2631. print()
  2632. print("looking paramOpt file:", paramFicName)
  2633. with open(paramFicName, 'rb') as input:
  2634. self.paramVSCDName = pickle.load(input)
  2635. self.paramVSCDValue = pickle.load(input)
  2636. self.paramVSCDType = pickle.load(input)
  2637. self.paramVSCDCoul = pickle.load(input)
  2638. self.paramMarquezName = pickle.load(input)
  2639. self.paramMarquezValue = pickle.load(input)
  2640. self.paramMarquezType = pickle.load(input)
  2641. self.paramMarquezCoul = pickle.load(input)
  2642. print("nb loaded param :", len(self.paramVSCDName))
  2643. # print "nb nb actual param param:", len(listparNameOpt)
  2644. print("nb expected param:", 42)
  2645. # There are 42 VSCD parameters in this version
  2646. nbloadedpar = len(self.paramVSCDName)
  2647. if nbloadedpar == 42:
  2648. if self.paramVSCDName[16] == 'disabledSynNbs':
  2649. # This is the last version that includes "seriesSynNSParam"
  2650. if verbose > 3:
  2651. print("paramOpt :")
  2652. for idx, val in enumerate(self.paramVSCDName):
  2653. print("{0}:\t{1}".format(val,
  2654. self.paramVSCDValue[idx]))
  2655. elif self.paramVSCDName[16] == 'allsyn':
  2656. # This is not the last version that includes "seriesSynNSParam"
  2657. print("this version does not indicate seriesSynNSParam")
  2658. if verbose > 3:
  2659. print("paramMarquez :")
  2660. for idx, val in enumerate(self.paramMarquezName):
  2661. print("{0}:\t{1}".format(val,
  2662. self.paramMarquezValue[idx]))
  2663. print('=================== Param loaded ====================')
  2664. response = True
  2665. elif nbloadedpar == 41:
  2666. print("paramOpt with only 41 params:")
  2667. pln = ['selectedChart'] + self.paramVSCDName
  2668. self.paramVSCDName = pln
  2669. plv = [0] + self.paramVSCDValue
  2670. paramVSCDValue = plv
  2671. plt = [int] + self.paramVSCDType
  2672. self.paramVSCDType = plt
  2673. plc = ["Magenta"] + self.paramVSCDCoul
  2674. self.paramVSCDCoul = plc
  2675. if verbose > 3:
  2676. print("paramOpt :")
  2677. for idx, val in enumerate(self.paramVSCDName):
  2678. print("{0}:\t{1}".format(val, paramVSCDValue[idx]))
  2679. print("paramMarquez :")
  2680. for idx, val in enumerate(self.paramMarquezName):
  2681. print("{0}:\t{1}".format(val, self.paramMarquezValue[idx]))
  2682. print('=================== Param loaded ====================')
  2683. response = True
  2684. else:
  2685. print("Mismatch between existing and actual parameter files")
  2686. response = False
  2687. except Exception as e:
  2688. if (verbose > 2):
  2689. print(e)
  2690. # print("No parameter file with this name in the directory", end=" ")
  2691. # print("NEEDs to create a new parameter file")
  2692. response = False
  2693. return response
  2694. def getOptSetFromAsim(self, animatsimdir):
  2695. rootdir = os.path.dirname(animatsimdir)
  2696. subdir = os.path.split(animatsimdir)[-1]
  2697. animatLabV2ProgDir, nb_procs = getInfoComputer()
  2698. folders = FolderOrg(animatlab_root=rootdir,
  2699. python27_source_dir=animatLabV2ProgDir,
  2700. subdir=subdir)
  2701. sims = SimRun("Test Sims",
  2702. rootFolder=folders.animatlab_rootFolder,
  2703. commonFiles=folders.animatlab_commonFiles_dir,
  2704. sourceFiles=folders.python27_source_dir,
  2705. simFiles=folders.animatlab_simFiles_dir,
  2706. resultFiles=folders.animatlab_result_dir)
  2707. model = AnimatLabModel.AnimatLabModel(folders.animatlab_commonFiles_dir)
  2708. projMan = ProjectManager.ProjectManager('Test Project')
  2709. # aprojFicName = os.path.split(model.aprojFile)[-1]
  2710. if self.optSet is None:
  2711. optSet = OptimizeSimSettings(folders=folders, model=model,
  2712. projMan=projMan, sims=sims)
  2713. fileName = 'paramOpt.pkl'
  2714. if loadParams(os.path.join(folders.animatlab_result_dir, fileName),
  2715. optSet):
  2716. # optSet was updated from "paramOpt.pkl"
  2717. # we use then optSet to implement the needed variables
  2718. optSet.actualizeparamVSCD()
  2719. optSet.actualizeparamMarquez()
  2720. optSet.ideal_behav = [0, 0]
  2721. else:
  2722. print("paramOpt.pkl MISSING !!, run 'GUI_animatlabOptimization.py'")
  2723. print
  2724. self.stimParName = optSet.stimParName
  2725. self.synParName = optSet.synParName
  2726. self.synNSParName = optSet.synNSParName
  2727. self.synFRParName = optSet.synFRParName
  2728. self.par_names = optSet.xparName
  2729. self.optSet = optSet
  2730. return self.optSet, model
  2731. def get_angle_dur(select_angledur_dir):
  2732. mvt_by_angle = []
  2733. angles = []
  2734. durees = []
  2735. for cond in select_angledur_dir:
  2736. if cond[:cond.find("_")] not in angles:
  2737. angles.append(cond[:cond.find("_")])
  2738. if cond[cond.find("_")+1:] not in durees:
  2739. durees.append(cond[cond.find("_")+1:])
  2740. for ang in angles:
  2741. ang_set = []
  2742. for cond in select_angledur_dir:
  2743. if cond[:cond.find("_")] in ang:
  2744. ang_set.append(cond)
  2745. mvt_by_angle.append(ang_set)
  2746. return (mvt_by_angle, angles, durees)
  2747. def make_graph_var(graph_path, list_VSCDParam, strtTime, endTime,
  2748. prevListConsts, prevListTrials,
  2749. selectLst_const_trial, select_angledur_dir,
  2750. select_var_names_plt):
  2751. """
  2752. Builds graphs of chosen chart names variables for Deb, Max and Fin
  2753. Each graph represents the values of these variables for each constant
  2754. parameter value (for all selected trials). Different mvt durations are
  2755. ploted with different lines. The different angles are plotted on different
  2756. files.
  2757. """
  2758. list_constVal = ['Time']
  2759. for const in prevListConsts:
  2760. lastConstPar = const
  2761. while lastConstPar.find("=") != -1:
  2762. lastConstPar = lastConstPar[lastConstPar.find("=")+1:]
  2763. # print(lastConstPar)
  2764. for idx, trial in enumerate(prevListTrials):
  2765. list_constVal.append("{0}-{1}".format(lastConstPar, idx+1))
  2766. (mvt_by_angle, angles, durees) = get_angle_dur(select_angledur_dir)
  2767. for ang_idx, ang in enumerate(angles):
  2768. dic_VSCDparam = list_VSCDParam[ang_idx]
  2769. # endMvt1 = dic_VSCDparam["endMvt1"]
  2770. endPos1 = dic_VSCDparam["endPos1"]
  2771. endMvt2 = dic_VSCDparam["endMvt2"]
  2772. endPos2 = dic_VSCDparam["endPos2"]
  2773. titre = "fig_var_{0}".format(ang)
  2774. angle_class = mvt_by_angle[ang_idx]
  2775. ysize = len(select_var_names_plt) * 2
  2776. fig, ax = plt.subplots(nrows=len(select_var_names_plt), ncols=3,
  2777. figsize=(7, ysize), dpi=150,
  2778. # subplot_kw={'xticks': [], 'yticks': []},
  2779. sharex='col', sharey='row')
  2780. for idx, var in enumerate(select_var_names_plt):
  2781. for mvt in angle_class:
  2782. output_path = os.path.join(graph_path, mvt, "output")
  2783. df1 = pd.read_csv(r'{0}\{1}.csv'.format(output_path, var),
  2784. delimiter='\t',
  2785. index_col='Time',
  2786. header=1,
  2787. names=list_constVal)
  2788. selectdf1 = df1.loc[:, selectLst_const_trial]
  2789. "Deb_steady part"
  2790. Deb = selectdf1.loc[0.5:endPos1]
  2791. Deb_moy = Deb.mean(axis=0)
  2792. # Deb.describe()
  2793. "Max part"
  2794. MaxVal = selectdf1.max(axis=0)
  2795. "Fin_steady part"
  2796. Fin = selectdf1.loc[endMvt2:endPos2]
  2797. # Fin.describe()
  2798. Fin_moy = Fin.mean(axis=0)
  2799. ax[idx, 0].plot(Deb_moy)
  2800. ax[idx, 0].set_title('Deb_' + var, fontsize=10) # set title
  2801. ax[idx, 1].plot(MaxVal)
  2802. ax[idx, 1].set_title('Max_' + var, fontsize=10)
  2803. ax[idx, 2].plot(Fin_moy)
  2804. ax[idx, 2].set_title("Fin_" + var, fontsize=10)
  2805. if idx == 0:
  2806. # plt.legend(angle_class,
  2807. # bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
  2808. # ncol=1, mode="expand", borderaxespad=0.)
  2809. ax[idx, 2].legend(angle_class,
  2810. bbox_to_anchor=(0.05, 1.2),
  2811. loc=3, borderaxespad=0.)
  2812. if idx == len(select_var_names_plt) - 1:
  2813. ax[idx, 0].tick_params(axis='x', rotation=70)
  2814. ax[idx, 1].tick_params(axis='x', rotation=70)
  2815. ax[idx, 2].tick_params(axis='x', rotation=70)
  2816. plt.suptitle(titre, fontsize=14, y=1-ysize*0.005)
  2817. plt.savefig(r'{0}\fig_var_{1}.eps'.format(graph_path, ang))
  2818. plt.show()
  2819. def make_graph_mvt(graph_path, list_VSCDParam, strtTime, endTime,
  2820. prevListConsts, prevListTrials,
  2821. selectLst_const_trial, select_angledur_dir,
  2822. select_var_names_plt, fname='fig_Elbow.eps'):
  2823. """
  2824. Builds the elbow movement for each angle on a separates files
  2825. (and for all mvt durations).
  2826. """
  2827. list_constVal = ['Time']
  2828. for const in prevListConsts:
  2829. lastConstPar = const
  2830. while lastConstPar.find("=") != -1:
  2831. lastConstPar = lastConstPar[lastConstPar.find("=")+1:]
  2832. # print(lastConstPar)
  2833. for idx, trial in enumerate(prevListTrials):
  2834. list_constVal.append("{0}-{1}".format(lastConstPar, idx+1))
  2835. # movement together
  2836. figmvt, axes = plt.subplots(nrows=len(select_angledur_dir), ncols=2,
  2837. figsize=(7, 14), dpi=150,
  2838. sharex='col',
  2839. sharey='row')
  2840. for idx, angdur in enumerate(select_angledur_dir):
  2841. const = prevListConsts[0]
  2842. trial = prevListTrials[0]
  2843. templateFileName = os.path.join(graph_path, angdur, const, trial,
  2844. "ResultFiles", "template.txt")
  2845. T = np.loadtxt(templateFileName)
  2846. Tdf = pd.DataFrame(T)
  2847. Tdf.index = Tdf[1]
  2848. output_path = os.path.join(graph_path, angdur, "output")
  2849. df_move = pd.read_csv(r'{0}\Elbow.csv'.format(output_path),
  2850. delimiter='\t',
  2851. index_col='Time',
  2852. header=1,
  2853. names=list_constVal)
  2854. select_df_move = df_move.loc[:, selectLst_const_trial]
  2855. # add two columns to df_move : TemplateTime and Template
  2856. select_df_move.loc[:, 'TemplateTime'] = Tdf[strtTime:endTime][1]
  2857. select_df_move.loc[:, 'Template'] = Tdf[strtTime:endTime][2]
  2858. # select_df_move.plot()
  2859. # titre = "{0}".format(angdur)
  2860. for col in selectLst_const_trial:
  2861. data = select_df_move[:][col]
  2862. # data.plot(ax=axes[0])
  2863. axes[idx, 0].plot(data, linewidth=0.2)
  2864. dataT = select_df_move[:]["Template"]
  2865. # dataT.plot(ax=axes[0], color="grey")
  2866. axes[idx, 0].plot(dataT, color="grey")
  2867. unitx = "Time (s)"
  2868. unity = "Elbow Mvt (degres)"
  2869. axes[idx, 0].legend(loc='upper left', fontsize=4)
  2870. axes[idx, 0].set_ylabel(unity, fontsize=10)
  2871. if idx == len(select_angledur_dir) - 1:
  2872. axes[idx, 0].set_xlabel(unitx, fontsize=10)
  2873. for col in selectLst_const_trial:
  2874. data = select_df_move[4.9:6][col]
  2875. # data.plot(ax=axes[1])
  2876. axes[idx, 1].plot(data, linewidth=0.2)
  2877. dataT = select_df_move[4.9:6]["Template"]
  2878. # dataT.plot(ax=axes[1], color="grey")
  2879. axes[idx, 1].plot(dataT, color="grey")
  2880. unitx = "Time (s)"
  2881. unity = "Elbow Mvt (degres)"
  2882. # axes[idx, 1].text(4.25, 35, angdur)
  2883. axes[idx, 1].set_title(angdur)
  2884. axes[idx, 1].legend(loc='upper left', fontsize=4)
  2885. # axes[idx, 1].set_ylabel(unity, fontsize=10)
  2886. if idx == len(select_angledur_dir) - 1:
  2887. axes[idx, 1].set_xlabel(unitx, fontsize=10)
  2888. plt.suptitle("Angles and Durations series", fontsize=14, y=0.91)
  2889. plt.savefig(r'{0}\{1}'.format(graph_path, fname))
  2890. plt.show()
  2891. def make_graph_supmvt(graph_path, list_VSCDParam, strtTime, endTime,
  2892. prevListConsts, prevListTrials,
  2893. selectLst_const_trial, select_angledur_dir,
  2894. select_var_names_plt, fname="fig_Elbow2.eps"):
  2895. """
  2896. Builds superimposed movements of same angles and different durations
  2897. """
  2898. list_constVal = ['Time']
  2899. for const in prevListConsts:
  2900. lastConstPar = const
  2901. while lastConstPar.find("=") != -1:
  2902. lastConstPar = lastConstPar[lastConstPar.find("=")+1:]
  2903. # print(lastConstPar)
  2904. for idx, trial in enumerate(prevListTrials):
  2905. list_constVal.append("{0}-{1}".format(lastConstPar, idx+1))
  2906. (mvt_by_angle, angles, durees) = get_angle_dur(select_angledur_dir)
  2907. # superimposed movements
  2908. nbrows = len(angles)
  2909. fig2mvt, axes2 = plt.subplots(nrows=nbrows, ncols=1,
  2910. figsize=(7, 7*nbrows), dpi=150)
  2911. for ang_idx, ang in enumerate(angles):
  2912. colors = []
  2913. newHandles = []
  2914. newLabels = []
  2915. # dic_VSCDparam = list_VSCDParam[ang_idx]
  2916. # titre = "{0}".format(ang)
  2917. angle_class = mvt_by_angle[ang_idx]
  2918. for mvt_idx, mvt in enumerate(angle_class):
  2919. const = prevListConsts[0]
  2920. trial = prevListTrials[0]
  2921. templateFileName = os.path.join(graph_path, mvt, const, trial,
  2922. "ResultFiles", "template.txt")
  2923. T = np.loadtxt(templateFileName)
  2924. Tdf = pd.DataFrame(T)
  2925. Tdf.index = Tdf[1]
  2926. output_path = os.path.join(graph_path, mvt, "output")
  2927. df_move = pd.read_csv(r'{0}\Elbow.csv'.format(output_path),
  2928. delimiter='\t',
  2929. index_col='Time',
  2930. header=1,
  2931. names=list_constVal)
  2932. select_df_move = df_move.loc[:, selectLst_const_trial]
  2933. # add two columns to df_move : TemplateTime and Template
  2934. select_df_move.loc[:, 'TemplateTime'] = Tdf[strtTime:endTime][1]
  2935. select_df_move.loc[:, 'Template'] = Tdf[strtTime:endTime][2]
  2936. # df_move.plot()
  2937. color = "C{}".format(mvt_idx)
  2938. colors.append(color)
  2939. for col in selectLst_const_trial:
  2940. data = select_df_move[4.9:6][col]
  2941. if nbrows > 1:
  2942. axes2[ang_idx].plot(data, linewidth=0.5,
  2943. color=color, label=mvt)
  2944. else:
  2945. axes2.plot(data, linewidth=0.5, color=color, label=mvt)
  2946. dataT = select_df_move[4.9:6]["Template"]
  2947. unitx = "Time (s)"
  2948. unity = "Elbow Mvt (degres)"
  2949. if nbrows > 1:
  2950. axes2[ang_idx].plot(dataT, color="grey")
  2951. axes2[ang_idx].set_title(ang)
  2952. axes2[ang_idx].legend(angle_class,
  2953. loc='upper left', fontsize=18)
  2954. axes2[ang_idx].set_ylabel(unity, fontsize=10)
  2955. if ang_idx == nbrows - 1:
  2956. axes2[ang_idx].set_xlabel(unitx, fontsize=10)
  2957. # gets the handles and labels of legend for current mvt
  2958. handles, labels = axes2[ang_idx].get_legend_handles_labels()
  2959. else:
  2960. axes2.plot(dataT, color="grey")
  2961. axes2.set_title(ang)
  2962. axes2.legend(angle_class, loc='upper left', fontsize=18)
  2963. axes2.set_ylabel(unity, fontsize=10)
  2964. if ang_idx == nbrows - 1:
  2965. axes2.set_xlabel(unitx, fontsize=10)
  2966. # gets the handles and labels of legend for current mvt
  2967. handles, labels = axes2.get_legend_handles_labels()
  2968. # gets the first handle & label of each constant list
  2969. # and add it in new Handles & newLabels, respectively
  2970. nbConstTrial = len(selectLst_const_trial)
  2971. newHandles.append(handles[mvt_idx*(nbConstTrial)])
  2972. newLabels.append(labels[mvt_idx*(nbConstTrial)])
  2973. # and now adds the "template" in legend handles and labels
  2974. newHandles.append(handles[(mvt_idx+1)*(nbConstTrial)-1])
  2975. newLabels.append(labels[(mvt_idx+1)*(nbConstTrial)-1])
  2976. # at the end of each angle_class, rewrites the legend using newHandles
  2977. # and newLabels
  2978. if nbrows > 1:
  2979. axes2[ang_idx].legend(newHandles, newLabels)
  2980. else:
  2981. axes2.legend(newHandles, newLabels)
  2982. plt.suptitle("Angles and Superimposed Durations", fontsize=14, y=0.94)
  2983. plt.savefig(r'{0}\{1}'.format(graph_path, fname))
  2984. plt.show()
  2985. def make_graph_param(graph_path, select_constVal_dir, select_angledur_dir,
  2986. selectLst_const_trial, prevLstPltParams):
  2987. """
  2988. Builds graphs of chosen parameter values. Each graph represents
  2989. the adaptation of the parameter value for each value of the constant
  2990. parameter (and for all selected trials). Different mvt durations are
  2991. ploted with different lines. The different angles are plotted on different
  2992. files.
  2993. """
  2994. df1 = pd.read_csv(r'{0}\{1}.csv'.format(graph_path, "output_param"),
  2995. delimiter='\t',
  2996. # index_col="param",
  2997. index_col=0,
  2998. # header=2,
  2999. header=[0, 1, 2],
  3000. # names=column_labels,
  3001. )
  3002. parnames = df1.index
  3003. nbcol = 3
  3004. nbrow = int(len(parnames)/nbcol)
  3005. if len(parnames) > nbrow*nbcol:
  3006. nbrow += 1
  3007. ysize = nbrow * 2
  3008. (mvt_by_angle, angles, durees) = get_angle_dur(select_angledur_dir)
  3009. for ang_idx, ang in enumerate(angles):
  3010. titre = "fig_par_{0}".format(ang)
  3011. angle_class = mvt_by_angle[ang_idx]
  3012. dfang = df1[angle_class]
  3013. fig, ax = plt.subplots(nrows=nbrow, ncols=nbcol,
  3014. figsize=(7, ysize), dpi=150,
  3015. # subplot_kw={'xticks': [], 'yticks': []},
  3016. sharex='col', sharey='row')
  3017. lastrow = (len(parnames) - len(parnames) % 3) // 3
  3018. for par_idx, par in enumerate(parnames):
  3019. col = par_idx % 3 # modulo function -> 0 1 2 0 1 2 etc.
  3020. row = (par_idx - col) / 3
  3021. # print row, col
  3022. for dur_idx, dur in enumerate(angle_class):
  3023. dfdur = dfang[dur]
  3024. dfconst = dfdur[select_constVal_dir]
  3025. dfconst.columns = selectLst_const_trial
  3026. ax[row, col].plot(dfconst.loc[par])
  3027. ax[row, col].set_title(par, fontsize=9)
  3028. if row == 0 and col == 2:
  3029. # plt.legend(angle_class,
  3030. # bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
  3031. # ncol=1, mode="expand", borderaxespad=0.)
  3032. ax[0, 2].legend(angle_class,
  3033. bbox_to_anchor=(0.05, 1.2),
  3034. loc=3, borderaxespad=0.)
  3035. if row == lastrow:
  3036. ax[row, col].tick_params(axis='x', rotation=70)
  3037. plt.suptitle(titre, fontsize=14, y=1-ysize*0.005)
  3038. plt.savefig(r'{0}\fig_par_{1}.eps'.format(graph_path, ang))
  3039. plt.show()
  3040. def analyse_const_dir(const):
  3041. list_cstes = []
  3042. fini = False
  3043. while not fini:
  3044. res = const.find("_")
  3045. if res != -1:
  3046. prevconst = const[:const.find("_")]
  3047. # print prevconst
  3048. if prevconst != "const":
  3049. list_cstes.append(prevconst)
  3050. const = const[const.find("_")+1:]
  3051. else:
  3052. # print const
  3053. list_cstes.append(const)
  3054. fini = True
  3055. return list_cstes
  3056. def factor_scatter_matrix(df, factor, graph_name,
  3057. plt_factor=False, palette=None):
  3058. '''
  3059. Create a scatter matrix of the variables in df, with differently colored
  3060. points depending on the value of df[factor].
  3061. inputs:
  3062. df: pandas.DataFrame containing the columns to be plotted, as well
  3063. as factor.
  3064. factor: string or pandas.Series. The column indicating which group
  3065. each row belongs to.
  3066. palette: A list of hex codes, at least as long as the number of groups.
  3067. If omitted, a predefined palette will be used, but it only includes
  3068. 9 groups.
  3069. '''
  3070. from pandas.plotting import scatter_matrix
  3071. from scipy.stats import gaussian_kde
  3072. import seaborn as sns
  3073. if isinstance(factor, str):
  3074. factor_name = factor # save off the name
  3075. factor_col = df.loc[:, factor] # extract column
  3076. if plt_factor is False:
  3077. df = df.drop(factor_name, axis=1) # remove from df, so it
  3078. # doesn't get a row and col in the plot.
  3079. classes = list(set(factor_col))
  3080. classes.sort(reverse=False)
  3081. nbcolors = len(classes)
  3082. if palette is None:
  3083. palette = colors = sns.color_palette()
  3084. """
  3085. palette = ['#e41a1c', '#377eb8', '#4eae4b',
  3086. '#994fa1', '#ff8101', '#fdfc33',
  3087. '#a8572c', '#f482be', '#999999']
  3088. """
  3089. color_map = dict(list(zip(classes, palette)))
  3090. if len(classes) > len(palette):
  3091. message1 = 'Too many groups for the number of colors provided.'
  3092. message2 = ' We only have {} colors in the palette, for {} groups.'
  3093. message = message1 + message2
  3094. raise ValueError(message.format(len(palette), len(classes)))
  3095. plt.rcParams['axes.labelsize'] = 8
  3096. plt.rcParams['ytick.labelsize'] = 6
  3097. colors = factor_col.apply(lambda group: color_map[group])
  3098. axarr = scatter_matrix(df, figsize=(15, 15),
  3099. alpha=1,
  3100. marker='.',
  3101. c=colors,
  3102. diagonal=None)
  3103. for rc in range(len(df.columns)):
  3104. for group in classes:
  3105. try:
  3106. y = df[factor_col == group].iloc[:, rc].values
  3107. gkde = gaussian_kde(y)
  3108. ind = np.linspace(y.min(), y.max(), 1000)
  3109. axarr[rc][rc].plot(ind, gkde.evaluate(ind),
  3110. c=color_map[group])
  3111. # in the color process colors are associated to values in
  3112. # value order (i.e. 1st value 0.01 -> first color)
  3113. except Exception as e:
  3114. None
  3115. if verbose > 2:
  3116. print(e)
  3117. title = "{0} colors by {1}".format(graph_name, factor)
  3118. plt.suptitle(title, fontsize=14, y=0.90)
  3119. labels = copy.deepcopy(classes)
  3120. labels.sort(reverse=True)
  3121. if nbcolors < 50:
  3122. handles = [plt.plot([], [], color=color_map[labels[i]],
  3123. ls="", marker='o',
  3124. markersize=8)[0] for i in range(nbcolors)]
  3125. # In legend the order is that of classes (revert order) so all is OK
  3126. plt.legend(handles, labels, loc=(1.02, 0))
  3127. plt.setp(plt.gca().get_legend().get_texts(), fontsize='10')
  3128. else:
  3129. labels1 = labels[:nbcolors/2]
  3130. handles1 = [plt.plot([], [], color=color_map[labels[i]],
  3131. ls="", marker='o',
  3132. markersize=8)[0] for i in range(nbcolors/2)]
  3133. # In legend the order is that of classes (revert order) so all is OK
  3134. first_legend = plt.legend(handles1, labels1, loc=(1.02, 0))
  3135. plt.gca().add_artist(first_legend)
  3136. plt.setp(plt.gca().get_legend().get_texts(), fontsize='10')
  3137. labels2 = labels[nbcolors/2:]
  3138. handles2 = [plt.plot([], [], color=color_map[labels[i]],
  3139. ls="", marker='o',
  3140. markersize=8)[0] for i in range(nbcolors/2,
  3141. nbcolors)]
  3142. # In legend the order is that of classes (revert order) so all is OK
  3143. second_legend = plt.legend(handles2, labels2, loc=(1.25, 0))
  3144. plt.gca().add_artist(second_legend)
  3145. plt.setp(plt.gca().get_legend().get_texts(), fontsize='10')
  3146. return axarr, color_map
  3147. # ======================================================================
  3148. # functions to plot GEP graphs
  3149. # ======================================================================
  3150. def do_plot_bhv_param(MyWin, df_bhvremain, df_parremain, behav_col, graph_path,
  3151. baseName, listDicGraphs, xparNameDict, xparName,
  3152. max_x_bhv=1.2, max_y_bhv=5):
  3153. nbpargraphs = len(listDicGraphs)
  3154. nbgraphs = nbpargraphs + 1 # the bhvGraph is added on 1st line
  3155. nblines = int(float(nbgraphs+1)/3)
  3156. reste = nbgraphs % 3
  3157. if reste > 0:
  3158. nblines += 1
  3159. if nblines % 5 != 0:
  3160. nbpages = int(nblines / 5) + 1
  3161. # nbLinesLastPage = nblines % 5
  3162. else:
  3163. nbpages = int(nblines / 5)
  3164. # nbLinesLastPage = 5
  3165. # nbLinesPerPage = []
  3166. nbparGr1stPage = min(14, nbpargraphs)
  3167. grlist = [list(range(0, nbparGr1stPage))] # list of pargraphs of 1st page
  3168. rg1stGrNextPage = nbparGr1stPage
  3169. if nbpages > 1:
  3170. for pag in range(1, nbpages-1):
  3171. # nbLinesPerPage.append(5)
  3172. grlist.append(list(range(rg1stGrNextPage, rg1stGrNextPage+14)))
  3173. rg1stGrNextPage = rg1stGrNextPage+14
  3174. # nbLinesPerPage.append(nbLinesLastPage)
  3175. grlist.append(list(range(rg1stGrNextPage, nbpargraphs)))
  3176. for page in range(nbpages):
  3177. plotGrOnPage(MyWin, df_bhvremain, df_parremain, behav_col, graph_path,
  3178. baseName, listDicGraphs, xparNameDict, xparName, page,
  3179. grlist, max_x_bhv=max_x_bhv, max_y_bhv=max_y_bhv)
  3180. def plotGrOnPage(MyWin, df_bhvremain, df_parremain, behav_col, graph_path,
  3181. baseName, listDicGraphs, xparNameDict, xparName, page,
  3182. grlist, max_x_bhv=1.2, max_y_bhv=1.4):
  3183. listcolors = ['blue', 'orange', 'green', 'red', 'purple',
  3184. 'brown', 'pink', 'gray', 'olive', 'cyan']
  3185. fig = plt.figure(figsize=(10, 18), dpi=90)
  3186. # plt.subplots_adjust(bottom=0, left=0.1, top=0.9, right=0.9)
  3187. grid = plt.GridSpec(5, 3, wspace=0.4, hspace=0.3)
  3188. path = os.path.split(graph_path)[0]
  3189. # baseName = strGEPdataName[:] + "/ bhv_par_graphs"
  3190. baseNamePage = baseName + "_p" + str(page+1)
  3191. titre = get_titre(path, baseNamePage)
  3192. # titre = titre + "_p" + str(page+1)
  3193. plt.suptitle(titre, fontsize=12, y=0.95)
  3194. row = -1
  3195. if page == 0:
  3196. # ===================== plots the behavior map =======================
  3197. behavs_cues = df_bhvremain[df_bhvremain.columns[behav_col]]
  3198. rel_behavs_cues = behavs_cues/[MyWin.scale_x, MyWin.scale_y]
  3199. nameX = rel_behavs_cues.columns[0]
  3200. nameY = rel_behavs_cues.columns[1]
  3201. valX = rel_behavs_cues[nameX]
  3202. valY = rel_behavs_cues[nameY]
  3203. # figure, ax = plt.subplots(figsize=(7, 7))
  3204. # figure, ax = plt.subplots()
  3205. # ax3 = fig.add_subplot(337)
  3206. ax3 = fig.add_subplot(grid[0, 0])
  3207. selectedROI = MyWin.mafen.selectedROI
  3208. if selectedROI == []:
  3209. # ===========================================================
  3210. ax3.scatter(valX, valY, marker='o', s=4, c="r")
  3211. # ===========================================================
  3212. else:
  3213. for idxROI, listdata in enumerate(selectedROI):
  3214. valX_s = valX[listdata]
  3215. valY_s = valY[listdata]
  3216. color = listcolors[idxROI]
  3217. # ---------------------------------------------------
  3218. ax3.scatter(valX_s, valY_s, marker='o', s=4, c=color)
  3219. # ---------------------------------------------------
  3220. if behav_col[1] == 8: # if ordonate is duration...
  3221. labelnameX = nameX + " (x 0.01)"
  3222. labelnameY = nameY
  3223. elif behav_col[1] == 6:
  3224. labelnameX = nameX + " (x 0.01)"
  3225. labelnameY = nameY + " (x 0.01)"
  3226. ax3.set_xlabel(labelnameX, fontsize=11)
  3227. ax3.set_ylabel(labelnameY, fontsize=11)
  3228. plt.xticks(fontsize=10)
  3229. plt.yticks(fontsize=10)
  3230. ax3.set_axisbelow(True)
  3231. ax3.set_xlim(0, max_x_bhv)
  3232. ax3.set_ylim(0, max_y_bhv)
  3233. ax3.grid(linestyle='-', linewidth='0.5', color='green')
  3234. row = 0
  3235. # =====================================================================
  3236. # =================== plots the parameter maps =======================
  3237. axpar = []
  3238. # row = 0
  3239. line = 0
  3240. for idx, pargr in enumerate(grlist[page]):
  3241. abscissName = listDicGraphs[pargr]['abscissa'][0]
  3242. ordinateName = listDicGraphs[pargr]['ordinate'][0]
  3243. if abscissName[abscissName.find(".")+1:] == "SynAmp":
  3244. xmin = 0
  3245. xmax = 0.05
  3246. if ordinateName[ordinateName.find(".")+1:] == "SynAmp":
  3247. ymin = 0
  3248. ymax = 0.05
  3249. if abscissName[abscissName.find(".")+1:] == "CurrentOn":
  3250. xmin = 0
  3251. xmax = 1
  3252. if ordinateName[ordinateName.find(".")+1:] == "CurrentOn":
  3253. ymin = 0
  3254. ymax = 1
  3255. row = row + 1
  3256. if row > 2:
  3257. row = 0
  3258. line = line + 1
  3259. # axpar.append(fig.add_subplot(3, nblines+1, 8+pargr))
  3260. axpar.append(fig.add_subplot(grid[line, row]))
  3261. namex = listDicGraphs[pargr]["abscissa"]
  3262. namey = listDicGraphs[pargr]["ordinate"]
  3263. parx = xparNameDict[namex[0]]
  3264. pary = xparNameDict[namey[0]]
  3265. dflist_x = df_parremain[xparName[parx]]
  3266. dflist_y = df_parremain[xparName[pary]]
  3267. if dflist_x.max() > xmax:
  3268. xmax = dflist_x.max()
  3269. if dflist_x.min() < xmin:
  3270. xmin = dflist_x.min()
  3271. """
  3272. if (dflist_y.max() > ymax) or dflist_y.min() < ymin:
  3273. if dflist_y.max() - dflist_y.min() < 2:
  3274. ymax = (dflist_y.max() + dflist_y.min())/2 + 1
  3275. ymin = (dflist_y.max() + dflist_y.min())/2 - 1
  3276. """
  3277. if dflist_y.max() > ymax:
  3278. ymax = dflist_y.max()
  3279. if dflist_y.min() < ymin:
  3280. ymin = dflist_y.min()
  3281. print(namex[0], parx, namey[0], pary)
  3282. selectedROI = MyWin.mafen.selectedROI
  3283. if selectedROI == []:
  3284. # ===========================================================
  3285. axpar[idx].scatter(list(dflist_x), list(dflist_y),
  3286. marker='o', s=4, c="b")
  3287. # ===========================================================
  3288. else:
  3289. for idxROI, listdata in enumerate(selectedROI):
  3290. dflist_x_s = dflist_x[listdata]
  3291. dflist_y_s = dflist_y[listdata]
  3292. color = listcolors[idxROI]
  3293. # ---------------------------------------------------
  3294. axpar[idx].scatter(list(dflist_x_s), list(dflist_y_s),
  3295. marker='o', s=4, c=color)
  3296. # ---------------------------------------------------
  3297. axpar[idx].set_xlabel(namex[0], fontsize=11)
  3298. axpar[idx].set_ylabel(namey[0], fontsize=11)
  3299. plt.xticks(fontsize=10)
  3300. plt.yticks(fontsize=10)
  3301. axpar[idx].set_axisbelow(True)
  3302. """
  3303. xmin = -4
  3304. xmax = 2
  3305. ymin = -3
  3306. ymax = 3
  3307. """
  3308. axpar[idx].set_xlim(xmin, xmax)
  3309. axpar[idx].set_ylim(ymin, ymax)
  3310. axpar[idx].grid(linestyle='-', linewidth='0.5', color='gray')
  3311. # =====================================================================
  3312. plt.savefig(os.path.join(graph_path, baseNamePage + '.pdf'))
  3313. plt.savefig(os.path.join(graph_path, baseNamePage + '.eps'))
  3314. plt.show()
  3315. def ss_titre_to_txt(ss_titre):
  3316. txt = "{}".format(ss_titre)
  3317. txt = txt.replace(" ", "")
  3318. txt = txt.replace("[", "(")
  3319. txt = txt.replace("]", ")")
  3320. txt = txt.replace("_", "")
  3321. return "_{}".format(txt)
  3322. def look_for_peaks(data):
  3323. start = 0
  3324. sequence = []
  3325. for key, group in groupby(data):
  3326. sequence.append((key, start))
  3327. start += sum(1 for _ in group)
  3328. for (b, bi), (m, mi), (a, ai) in zip(sequence, sequence[1:], sequence[2:]):
  3329. if b < m and a < m:
  3330. yield m, mi
  3331. class Ui_Visu3D(object):
  3332. def setupUi(self, Visu3D):
  3333. self.Visu3D = Visu3D
  3334. self.Visu3D.setObjectName("Visu3D")
  3335. self.Visu3D.resize(400, 400)
  3336. btn_color_per_set = QtWidgets.QPushButton('Color Points per set')
  3337. btn_color_per_set.clicked.connect(self.colors_per_set)
  3338. btn_create_subset = QtWidgets.QPushButton('create subset')
  3339. btn_create_subset.clicked.connect(self.restrain_visible_factor)
  3340. btn_choose_subset = QtWidgets.QPushButton('choose subset')
  3341. btn_choose_subset.clicked.connect(self.choose_subset)
  3342. btn_remove_subset = QtWidgets.QPushButton('remove subset')
  3343. btn_remove_subset.clicked.connect(self.remove_subset)
  3344. btn_chge_colorPar = QtWidgets.QPushButton('Change Colored param')
  3345. btn_chge_colorPar.clicked.connect(self.chge_colorPar)
  3346. btn_set_orient = QtWidgets.QPushButton('set orientation')
  3347. btn_set_orient.clicked.connect(self.set_orient)
  3348. btn_clear = QtWidgets.QPushButton('clear graph')
  3349. btn_clear.clicked.connect(self.clearData)
  3350. btn_save = QtWidgets.QPushButton('save graph')
  3351. btn_save.clicked.connect(self.saveGraph)
  3352. btn_quit = QtWidgets.QPushButton('QUIT')
  3353. btn_quit.clicked.connect(self.closeWindows)
  3354. # ==============================================
  3355. # Add QHBoxlayout to place the buttons
  3356. self.buttonHLayout1 = QtWidgets.QHBoxLayout()
  3357. self.buttonHLayout1.setObjectName("ButtonHLayout")
  3358. # self.buttonHLayout1.addWidget(btn_color_per_set)
  3359. self.buttonHLayout1.addWidget(btn_create_subset)
  3360. self.buttonHLayout1.addWidget(btn_choose_subset)
  3361. self.buttonHLayout1.addWidget(btn_remove_subset)
  3362. self.buttonHLayout1.addWidget(btn_chge_colorPar)
  3363. self.buttonHLayout1.addWidget(btn_set_orient)
  3364. self.buttonHLayout1.addWidget(btn_save)
  3365. # self.buttonHLayout1.addWidget(btn_clear)
  3366. self.buttonHLayout1.addWidget(btn_quit)
  3367. self.horizontalLayout = QtWidgets.QHBoxLayout()
  3368. self.horizontalLayout.setObjectName("horizontalLayout")
  3369. self.verticalLayout = QtWidgets.QVBoxLayout()
  3370. self.verticalLayout.setObjectName("verticalLayout")
  3371. # Add widgets to the layout in their proper positions
  3372. # self.verticalLayout.addWidget(self.gl3d)
  3373. self.verticalLayout.addLayout(self.buttonHLayout1)
  3374. self.horizontalLayout.addLayout(self.verticalLayout)
  3375. self.Visu3D.setLayout(self.horizontalLayout)
  3376. # self.centralwidget.setLayout(self.horizontalLayout)
  3377. self.setWindowTitle("Make 3d graph")
  3378. QtCore.QMetaObject.connectSlotsByName(self.Visu3D)
  3379. # TODO ...
  3380. class Visualizer3D(QtWidgets.QDialog, Ui_Visu3D):
  3381. def __init__(self, graph_path, GUI_Gr_obj):
  3382. super(Visualizer3D, self).__init__()
  3383. self.setupUi(self) # le 2eme self est pour l'argument Visualizer3D
  3384. self.graph_path = graph_path
  3385. self.GUI_Gr_obj = GUI_Gr_obj
  3386. self.rootdir = ""
  3387. self.ficname = ""
  3388. self.dataSet = []
  3389. self.listgl3dItems = []
  3390. self.faceColItems = []
  3391. self.setnames = []
  3392. self.listDic_dataSet = [{'data_sets': ["main"]}]
  3393. self.selected_dataSets = ['main']
  3394. plt.ion()
  3395. # self.figure, self.axis = plt.subplots(figsize=(10, 10), dpi=100)
  3396. self.figure = plt.figure(figsize=(10, 10), dpi=100)
  3397. self.canvas = FigureCanvas(self.figure)
  3398. # self.canvas.mpl_connect('pick_event', self.onpick)
  3399. self.verticalLayout.addWidget(self.canvas)
  3400. # self.visu_3d.gridLayout.addWidget(self.canvas)
  3401. self.axis = self.figure.add_subplot(1, 1, 1, projection='3d')
  3402. # self.axis = self.figure.gca(projection='3d')
  3403. # self.figure.set_size_inches(18.5, 10.5)
  3404. self.axis.set_xlabel("xlabel")
  3405. self.axis.set_ylabel("ylabel")
  3406. self.axis.set_zlabel("zlabel")
  3407. self.axis.view_init(60, 30)
  3408. print(" ========== execution in Vizualizer ON ==========")
  3409. # self.show()
  3410. """
  3411. def newData(self):
  3412. pos = np.random.randint(-10, 10, size=(100, 3))
  3413. pos[:, 2] = np.abs(pos[:, 2])
  3414. color = np.zeros((pos.shape[0], 4), dtype=np.float32)
  3415. color[:, 0] = 0.5
  3416. color[:, 1] = 0.2
  3417. color[:, 2] = 0.5
  3418. color[:, 3] = 1
  3419. x = pos[:, 0]
  3420. y = pos[:, 1]
  3421. z = pos[:, 2]
  3422. self.addData(pos=(x, y, z), size=10, pxMode=True, color=color)
  3423. # color = np.roll(color, 1, axis=0)
  3424. def origin_colors(self):
  3425. for idx, gl3d_item in enumerate(self.listgl3dItems):
  3426. color = self.faceColItems[idx]
  3427. gl3d_item._facecolor3d = color
  3428. gl3d_item._edgecolor3d = color
  3429. plt._auto_draw_if_interactive(self.figure, 1)
  3430. """
  3431. """
  3432. def plot_curves(self, indexes):
  3433. for idx, gl3d_item in enumerate(self.listgl3dItems):
  3434. for i in indexes: # might be more than 1 point if ambiguous click
  3435. new_fc = self.fc.copy()
  3436. new_fc[i,:] = (1, 0, 0, 1)
  3437. gl3d_item._facecolor3d = new_fc
  3438. gl3d_item._edgecolor3d = new_fc
  3439. self.figure.canvas.draw_idle()
  3440. def onpick(self, event):
  3441. ind = event.ind
  3442. print ind
  3443. self.plot_curves(list(ind))
  3444. """
  3445. def addData(self, pos=None, names=["xlabel", "ylabel", "zlabel"],
  3446. fourth="fourthlabel", size=10, pxMode=True, color=None,
  3447. setname="", ficname=""):
  3448. factor = fourth
  3449. self.ficname = ficname
  3450. (x, y, z) = pos
  3451. self.axis.set_xlabel(names[0])
  3452. self.axis.set_ylabel(names[1])
  3453. self.axis.set_zlabel(names[2])
  3454. # ======== tests if bvh name (bhv_names[behav_col[i]]) is in names
  3455. # (if so, sets the limits to original (before restraining bhv)
  3456. x_bhvname = self.GUI_Gr_obj.bhv_names[self.GUI_Gr_obj.behav_col[0]]
  3457. y_bhvname = self.GUI_Gr_obj.bhv_names[self.GUI_Gr_obj.behav_col[1]]
  3458. rank_x = list
  3459. rank_y = list
  3460. if x_bhvname in names:
  3461. # print x_bhvname,
  3462. rank_x = [i for i in range(len(names)) if names[i] == x_bhvname]
  3463. # print rank_x
  3464. if rank_x[0] == 0:
  3465. self.axis.set_xlim(self.GUI_Gr_obj.bhv_xmin,
  3466. self.GUI_Gr_obj.bhv_xmax)
  3467. elif rank_x[0] == 1:
  3468. self.axis.set_ylim(self.GUI_Gr_obj.bhv_xmin,
  3469. self.GUI_Gr_obj.bhv_xmax)
  3470. elif rank_x[0] == 2:
  3471. self.axis.set_zlim(self.GUI_Gr_obj.bhv_xmin,
  3472. self.GUI_Gr_obj.bhv_xmax)
  3473. if y_bhvname in names:
  3474. # print(y_bhvname, end=" ")
  3475. rank_y = [i for i in range(len(names)) if names[i] == y_bhvname]
  3476. # print(rank_y)
  3477. if rank_y[0] == 0:
  3478. self.axis.set_xlim(self.GUI_Gr_obj.bhv_ymin,
  3479. self.GUI_Gr_obj.bhv_ymax)
  3480. elif rank_y[0] == 1:
  3481. self.axis.set_ylim(self.GUI_Gr_obj.bhv_ymin,
  3482. self.GUI_Gr_obj.bhv_ymax)
  3483. elif rank_y[0] == 2:
  3484. self.axis.set_zlim(self.GUI_Gr_obj.bhv_ymin,
  3485. self.GUI_Gr_obj.bhv_ymax)
  3486. if color is None:
  3487. print("no color scale")
  3488. gl3d_item = self.axis.scatter(x, y, z, s=size,
  3489. facecolors=["C5"]*len(x),
  3490. edgecolors=["C5"]*len(x),
  3491. picker=True)
  3492. else:
  3493. # print("apllying color scale")
  3494. gl3d_item = self.axis.scatter(x, y, z, s=size,
  3495. facecolors=color,
  3496. edgecolors=color,
  3497. picker=True)
  3498. fc = gl3d_item.get_facecolors()
  3499. self.faceColItems.append(fc)
  3500. self.dataSet.append(pos)
  3501. self.setnames.append(setname)
  3502. self.listgl3dItems.append(gl3d_item)
  3503. plt._auto_draw_if_interactive(self.figure, 1)
  3504. self.setWindowTitle("color={}".format(factor))
  3505. print("new data {} added to 3d_graph".format(gl3d_item))
  3506. return gl3d_item
  3507. def chge_colorPar(self):
  3508. self.GUI_Gr_obj.graph_settings.choose_factor()
  3509. factor = self.GUI_Gr_obj.factor
  3510. print("factor =", factor)
  3511. df_glob = self.GUI_Gr_obj.df_glob
  3512. # print(df_glob)
  3513. color, codeCoul_df, step_palette = buildStpFilledCol(df_glob, factor)
  3514. # Gets the first set of dots to apply color scale on it
  3515. gl3d_item = self.listgl3dItems[0]
  3516. self.apply_colors(color, gl3d_item)
  3517. # =====================================================================
  3518. # TODO Part not Finished...
  3519. fc = gl3d_item.get_facecolors()
  3520. self.faceColItems[0] = fc
  3521. # =====================================================================
  3522. self.setWindowTitle("color={}".format(factor))
  3523. def apply_colors(self, color, gl3d_item):
  3524. # for idx, gl3d_item in enumerate(self.listgl3dItems):
  3525. gl3d_item._facecolor3d = color
  3526. gl3d_item._edgecolor3d = color
  3527. plt._auto_draw_if_interactive(self.figure, 1)
  3528. # print("new_color for gl3d_item")
  3529. # print("len(color) =", len(color))
  3530. def restrain_visible_factor(self):
  3531. factor = self.GUI_Gr_obj.factor
  3532. df_glob = self.GUI_Gr_obj.df_glob
  3533. color, codeCoul_df, step_palette = buildStpFilledCol(df_glob, factor)
  3534. seq_factor = "seq_{}".format(factor)
  3535. # seq_factor_col = copy.deepcopy(codeCoul_df[seq_factor])
  3536. list_sort_seq_factor = np.array(codeCoul_df[seq_factor])
  3537. list_sort_seq_factor.sort()
  3538. if verbose > 2:
  3539. print("seq_factor:", list_sort_seq_factor)
  3540. print("sorted seq_factor:", list_sort_seq_factor)
  3541. step = list_sort_seq_factor[1] - list_sort_seq_factor[0]
  3542. i = 0
  3543. while step == 0:
  3544. step = list_sort_seq_factor[i+1] - list_sort_seq_factor[0]
  3545. i += 1
  3546. # print(step)
  3547. step = step / 100
  3548. # print(step)
  3549. k = 0
  3550. while step < 1:
  3551. step *= 10
  3552. k += 1
  3553. # print(step)
  3554. # print round(step)
  3555. step = round(step) / (10**k)
  3556. # print(step)
  3557. step *= 100
  3558. print("step in color scale: {}".format(step))
  3559. factor_min = min(codeCoul_df[seq_factor])
  3560. factor_max = max(codeCoul_df[seq_factor])
  3561. listChoix = ['factor_limits']
  3562. listDicFactorLimNam = [{'factor_limits': ["inf", "sup"]}]
  3563. listDic_factorLimVal = [{"inf": factor_min, "sup": factor_max}]
  3564. factorLimits_keys = ["inf", "sup"]
  3565. titleText = "set limits for factor"
  3566. rep = ChooseInList.listTransmit(parent=None,
  3567. graphNo=0,
  3568. listChoix=listChoix,
  3569. items=factorLimits_keys,
  3570. listDicItems=listDicFactorLimNam,
  3571. onePerCol=[0],
  3572. colNames=["Factor_limits", 'value'],
  3573. dicValues=listDic_factorLimVal[0],
  3574. typ="val",
  3575. titleText=titleText)
  3576. listDicFactorLimNam = rep[0]
  3577. if len(rep[1]) == 0: # No values entered, ESC button was used
  3578. return
  3579. factLim_names = []
  3580. # print("rep[1]", rep[1])
  3581. for i in range(len(listDicFactorLimNam[0][listChoix[0]])):
  3582. itemName = listDicFactorLimNam[0][listChoix[0]][i]
  3583. factLim_names.append(itemName)
  3584. listDic_factorLimVal[0][itemName] = float(rep[1][itemName])
  3585. # print itemName, rep[1][itemName]
  3586. factor_inf = listDic_factorLimVal[0]['inf']
  3587. factor_sup = listDic_factorLimVal[0]['sup']
  3588. # print('factor_inf={} ; factor_sup={}'.format(factor_inf, factor_sup))
  3589. # get the ranks of factor_inf and factor_sup in codeCoul_df
  3590. idx_inf = codeCoul_df.loc[codeCoul_df[seq_factor] == factor_inf]
  3591. if len(idx_inf) > 0:
  3592. rg_inf = idx_inf.index[0]
  3593. else: # this means that factor_inf does not exist in seq_factor
  3594. while len(idx_inf) < 1: # then lokk for the immediately larger
  3595. if factor_inf - step > factor_min:
  3596. factor_inf -= step
  3597. factor_inf = round(factor_inf/step)*step
  3598. else:
  3599. factor_inf = factor_min
  3600. idx_inf = codeCoul_df.loc[codeCoul_df[seq_factor] ==
  3601. factor_inf]
  3602. if len(idx_inf) > 0:
  3603. rg_inf = idx_inf.index[0]
  3604. # rg = np.searchsorted(list_sort_seq_factor, factor_inf)
  3605. idx_sup = codeCoul_df.loc[codeCoul_df[seq_factor] == factor_sup]
  3606. if len(idx_sup) > 0:
  3607. rg_sup = idx_sup.index[0]
  3608. else: # this means that factor_inf does not exist in seq_factor
  3609. while len(idx_sup) < 1: # then lokk for the immediately larger
  3610. if factor_sup + step < factor_max:
  3611. factor_sup += step
  3612. factor_sup = round(factor_sup/step)*step
  3613. else:
  3614. factor_sup = factor_max
  3615. idx_sup = codeCoul_df.loc[codeCoul_df[seq_factor] ==
  3616. factor_sup]
  3617. if len(idx_sup) > 0:
  3618. print(factor_sup, idx_sup)
  3619. if len(idx_sup) > 0:
  3620. rg_sup = idx_sup.index[0]
  3621. print('factor_inf={} ; factor_sup={}'.format(factor_inf, factor_sup))
  3622. # and gets the corresponding color ranks in "color"
  3623. color_inf = int(codeCoul_df.loc[rg_inf]["color"])
  3624. color_sup = int(codeCoul_df.loc[rg_sup]["color"])
  3625. if verbose > 2:
  3626. print('color_inf={} ; color_sup={}'.format(color_inf, color_sup))
  3627. setname = "factor_{}-{}".format(factor_inf, factor_sup)
  3628. # ========== defines transparent colors for df_glob dots =============
  3629. col_trans = copy.deepcopy(color)
  3630. color_tr = [[col_trans[i][j] for j in range(4)]
  3631. for i in range(len(col_trans))]
  3632. color_t = [tuple([color_tr[i][j] if j < 3 else 0.02 for j in range(4)])
  3633. for i in range(len(col_trans))]
  3634. # and applies it to the main 3D scatter graph
  3635. gl3d_item = self.listgl3dItems[0]
  3636. self.apply_colors(color_t, gl3d_item)
  3637. # prepares a new df for plot data corresponding to selected factor
  3638. df_glob_sel = copy.deepcopy(df_glob)
  3639. factor_OK = df_glob_sel[factor] > factor_inf
  3640. df_glob_sel = df_glob_sel[factor_OK]
  3641. factor_OK = df_glob_sel[factor] < factor_sup
  3642. df_glob_sel = df_glob_sel[factor_OK]
  3643. codeCoul_df_sel = codeCoul_df.loc[df_glob_sel.index][:]
  3644. # colour = step_palette[color_inf]
  3645. # sel_pal = step_palette[color_inf:color_sup]
  3646. colour = adaptPaletteTodf(df_glob_sel, factor,
  3647. step_palette, codeCoul_df_sel)
  3648. x = np.array(df_glob_sel[self.GUI_Gr_obj.select_3_col[0]])
  3649. y = np.array(df_glob_sel[self.GUI_Gr_obj.select_3_col[1]])
  3650. z = np.array(df_glob_sel[self.GUI_Gr_obj.select_3_col[2]])
  3651. self.addData(pos=(x, y, z),
  3652. names=self.GUI_Gr_obj.select_3_col, fourth=factor,
  3653. size=4, pxMode=True, color=colour,
  3654. setname=setname, ficname=self.ficname)
  3655. # nb ficname is not used so far
  3656. self.setWindowTitle("color={} -> restricted to {} - {}".format(factor,
  3657. factor_inf, factor_sup))
  3658. # plt._auto_draw_if_interactive(self.figure, 1)
  3659. def choose_subset(self):
  3660. listChoix = ['data_sets']
  3661. # self.listDic_dataSet = [{'data_sets': ["main"]}]
  3662. titleText = "choose set to plot"
  3663. list_items = self.setnames
  3664. listDic_dataSet = self.listDic_dataSet
  3665. rep = ChooseInList.listTransmit(parent=None,
  3666. graphNo=0,
  3667. listChoix=listChoix,
  3668. items=list_items,
  3669. listDicItems=listDic_dataSet,
  3670. onePerCol=[0],
  3671. colNames=["data sets"],
  3672. typ="chk",
  3673. titleText=titleText)
  3674. self.listDic_dataSet = rep[0]
  3675. self.selected_dataSets = self.listDic_dataSet[0][listChoix[0]]
  3676. unselected_dataSets = []
  3677. for idx, gl3d_item in enumerate(self.listgl3dItems):
  3678. color = self.faceColItems[idx]
  3679. sub_set = list_items[idx]
  3680. if sub_set in self.selected_dataSets:
  3681. gl3d_item._facecolor3d = color
  3682. gl3d_item._edgecolor3d = color
  3683. else:
  3684. unselected_dataSets.append(sub_set)
  3685. gl3d_item._facecolor3d = (0, 0, 0, 0)
  3686. gl3d_item._edgecolor3d = (0, 0, 0, 0)
  3687. plt._auto_draw_if_interactive(self.figure, 1)
  3688. def remove_subset(self):
  3689. listChoix = ['data_sets']
  3690. titleText = "choose set to remove from list"
  3691. list_remove = []
  3692. list_items = self.setnames
  3693. listDic_remSet = [{'data_sets': []}]
  3694. rep = ChooseInList.listTransmit(parent=None,
  3695. graphNo=0,
  3696. listChoix=listChoix,
  3697. items=list_items,
  3698. listDicItems=listDic_remSet,
  3699. onePerCol=[0],
  3700. colNames=["data sets"],
  3701. typ="chk",
  3702. titleText=titleText)
  3703. listDic_remSet = rep[0]
  3704. dataSetsToRemove = listDic_remSet[0][listChoix[0]]
  3705. print("dataSets To Remove:", dataSetsToRemove)
  3706. # for idx, subset in enumerate(list_items):
  3707. for idx, gl3d_item in enumerate(self.listgl3dItems):
  3708. sub_set = list_items[idx]
  3709. if sub_set in dataSetsToRemove:
  3710. list_remove.append(idx)
  3711. if sub_set in self.selected_dataSets:
  3712. gl3d_item._facecolor3d = (0, 0, 0, 0)
  3713. gl3d_item._edgecolor3d = (0, 0, 0, 0)
  3714. plt._auto_draw_if_interactive(self.figure, 1)
  3715. unwanted = set(list_remove)
  3716. faceColItems = self.faceColItems
  3717. listgl3dItems = self.listgl3dItems
  3718. dataSet = self.dataSet
  3719. list_items = [list_items[idx] for idx in range(len(list_items))
  3720. if idx not in unwanted]
  3721. faceColItems = [faceColItems[idx] for idx in range(len(list_items))
  3722. if idx not in unwanted]
  3723. listgl3dItems = [listgl3dItems[idx] for idx in range(len(list_items))
  3724. if idx not in unwanted]
  3725. dataSet = [dataSet[idx] for idx in range(len(list_items))
  3726. if idx not in unwanted]
  3727. self.setnames = list_items
  3728. self.faceColItems = faceColItems
  3729. self.listgl3dItems = listgl3dItems
  3730. self.dataSet = dataSet
  3731. def colors_per_set(self):
  3732. for idx, gl3d_item in enumerate(self.listgl3dItems):
  3733. # -------- One color for all dots --------
  3734. color = [random.uniform(0, 1), random.uniform(0, 1),
  3735. random.uniform(0, 1), 1]
  3736. gl3d_item._facecolor3d = color
  3737. gl3d_item._edgecolor3d = color
  3738. plt._auto_draw_if_interactive(self.figure, 1)
  3739. print("one color per gl3d_item")
  3740. def set_orient(self):
  3741. azim = self.axis.azim
  3742. elev = self.axis.elev
  3743. azim = float("{0:.2f}".format(round(azim, 2)))
  3744. elev = float("{0:.2f}".format(round(elev, 2)))
  3745. print("azim={} elev={}".format(azim, elev))
  3746. listChoix = ['orientation']
  3747. listDicOrientNames = [{'orientation': ["azim", "elev"]}]
  3748. listDic_orient_val = [{"azim": azim, "elev": elev}]
  3749. self.orient_keys = ["azim", "elev"]
  3750. titleText = "set orientation 3D graph"
  3751. rep = ChooseInList.listTransmit(parent=None,
  3752. graphNo=0,
  3753. listChoix=listChoix,
  3754. items=self.orient_keys,
  3755. listDicItems=listDicOrientNames,
  3756. onePerCol=[0],
  3757. colNames=["orientation", 'value'],
  3758. dicValues=listDic_orient_val[0],
  3759. typ="val",
  3760. titleText=titleText)
  3761. listDicOrientNames = rep[0]
  3762. self.orient_names = []
  3763. self.dic_orient_val = rep[1]
  3764. # print "rep[1]", rep[1]
  3765. for i in range(len(listDicOrientNames[0][listChoix[0]])):
  3766. itemName = listDicOrientNames[0][listChoix[0]][i]
  3767. self.orient_names.append(itemName)
  3768. listDic_orient_val[0][itemName] = float(rep[1][itemName])
  3769. # print itemName, rep[1][itemName]
  3770. azim = listDic_orient_val[0]['azim']
  3771. elev = listDic_orient_val[0]['elev']
  3772. print('azim={} ; elev={}'.format(azim, elev))
  3773. self.axis.view_init(azim=azim, elev=elev)
  3774. plt._auto_draw_if_interactive(self.figure, 1)
  3775. def clearData(self):
  3776. for idx, gl3d_item in enumerate(self.listgl3dItems):
  3777. print(gl3d_item)
  3778. gl3d_item.remove()
  3779. self.dataSet = []
  3780. self.listgl3dItems = []
  3781. plt._auto_draw_if_interactive(self.figure, 1)
  3782. print("all gl3d_item supressed")
  3783. def saveGraph(self):
  3784. azim = self.axis.azim
  3785. elev = self.axis.elev
  3786. """
  3787. xlim = self.axis.get_xlim()
  3788. ylim = self.axis.get_ylim()
  3789. zlim = self.axis.get_zlim()
  3790. """
  3791. azim = float("{0:.2f}".format(round(azim, 2)))
  3792. elev = float("{0:.2f}".format(round(elev, 2)))
  3793. print("azim={} elev={}".format(azim, elev))
  3794. self.graph_path = QtWidgets.QFileDialog.\
  3795. getExistingDirectory(self, "folder in which to save figure",
  3796. self.rootdir)
  3797. self.rootdir = os.path.split(self.graph_path)[0]
  3798. print(r'{0}\{1}.pdf'.format(self.graph_path, self.ficname))
  3799. df_glob = self.GUI_Gr_obj.df_glob
  3800. select_3_col = self.GUI_Gr_obj.select_3_col
  3801. factor = self.GUI_Gr_obj.factor
  3802. ss_titre = self.GUI_Gr_obj.ss_titre
  3803. titre = "Fig5_3D_Dots_{}__{}__{}".format(select_3_col[0][:13],
  3804. select_3_col[1][:13],
  3805. select_3_col[2][:13])
  3806. # self.GUI_Gr_obj.make_3d_plot(df_glob, select_3_col,
  3807. # titre, ss_titre, factor,
  3808. # azim=azim, elev=elev)
  3809. """
  3810. dataSet = self.dataSet
  3811. selected_dataSets = self.selected_dataSets
  3812. list_items = self.setnames
  3813. faceColItems = self.faceColItems
  3814. graph_path = self.graph_path
  3815. make_3d_plot_subPlots(df_glob, dataSet, selected_dataSets,
  3816. list_items, faceColItems,
  3817. xlim, ylim, zlim,
  3818. factor, select_3_col, titre, ss_titre,
  3819. graph_path,
  3820. azim=azim, elev=elev)
  3821. """
  3822. self.GUI_Gr_obj.make_3d_plot(df_glob, select_3_col, titre, ss_titre,
  3823. factor, azim=azim, elev=elev)
  3824. def closeWindows(self):
  3825. # self.gl3d.removeItem(self.sp2)
  3826. self.close()
  3827. def closeEvent(self, event):
  3828. """
  3829. code exécuté quand l'interface est fermée
  3830. """
  3831. # ajoute une boite de dialogue pour confirmation de fermeture
  3832. result = QtWidgets.QMessageBox.question(self,
  3833. "Confirm Exit...",
  3834. "Do you want to exit ?",
  3835. (QtWidgets.QMessageBox.Yes |
  3836. QtWidgets.QMessageBox.No))
  3837. if result == QtWidgets.QMessageBox.Yes:
  3838. # permet d'ajouter du code pour fermer proprement
  3839. print(" ========== execution in Vizualizer OFF ==========")
  3840. event.accept()
  3841. else:
  3842. event.ignore()
  3843. class InputDialogWin(QtWidgets.QWidget):
  3844. def __init__(self, parent=None):
  3845. super(InputDialogWin, self).__init__(parent)
  3846. layout = QtWidgets.QFormLayout()
  3847. self.btn2 = QtWidgets.QPushButton("Enter an integer")
  3848. self.btn2.clicked.connect(self.getint)
  3849. self.le2 = QtWidgets.QLineEdit()
  3850. layout.addRow(self.btn2, self.le2)
  3851. self.setLayout(layout)
  3852. def getint(self, dialog_title, question, val):
  3853. num, ok = QtWidgets.QInputDialog.getInt(self, dialog_title, question, val)
  3854. if ok:
  3855. self.le2.setText(str(num))
  3856. return num
  3857. # TODO to be Finished..
  3858. class GEPGraphsMetrics(QtWidgets.QDialog): # top-level widget to hold everything
  3859. """
  3860. class containing various methods to build graphs for GEP analysis
  3861. - plot and save behavior and parameter maps
  3862. - plot and save behavior map
  3863. - plot and save behavior map (with chosen number of valid behaviors)
  3864. - plot and save density map of GEP behavior domain
  3865. - plot and save stability map of GEP behavior domain
  3866. - plot and save progression of GEP process with two metric methods
  3867. Two procedures can be used to estimate the "efficacy" of an
  3868. optimisation process:
  3869. 1) Build an array that covers the behavior space with a given
  3870. step and count the number of behaviours that are present in
  3871. each box.
  3872. Then give the number of boxes with at least one behaviour.
  3873. 2) Generate random targets inb the behaviour space and find for
  3874. each target the closest behaviour. Then calculate the mean of
  3875. distances from targets to closest behaviours.
  3876. """
  3877. def __init__(self, GUI_Gr_obj, parent=None):
  3878. super(GEPGraphsMetrics, self).__init__(parent)
  3879. self.resize(300, 150)
  3880. self.GUI_Gr_obj = GUI_Gr_obj
  3881. # self.scale_x = self.GUI_Gr_obj.scale_x
  3882. # Create some widgets to be placed inside
  3883. self.setErrThr_btn = QtWidgets.QPushButton('set errThr & coactThr')
  3884. self.setErrThr_btn.clicked.connect(self.setErrThr)
  3885. self.saveplotbhv_btn = QtWidgets.QPushButton('saveplot bhv map')
  3886. self.saveplotbhv_btn.clicked.connect(self.saveplot_bhv)
  3887. self.saveplobhvtparam_btn = QtWidgets.QPushButton('saveplot bhvparam maps')
  3888. self.saveplobhvtparam_btn.clicked.connect(self.saveplot_bhvparam)
  3889. self.behavior_map_btn = QtWidgets.QPushButton("&Behavior Map GEP")
  3890. self.behavior_map_btn.clicked.connect(self.plot_bhvmap_nbBhvOK)
  3891. self.MSp_ampl_Abaque_btn = QtWidgets.QPushButton("Abaque MaxSpeed/dur")
  3892. self.MSp_ampl_Abaque_btn.clicked.connect(self.plot_abaque_duration)
  3893. self.plot_density_btn = QtWidgets.QPushButton('plot bhv DensityMapContour')
  3894. self.plot_density_btn.clicked.connect(self.plot_densitymaps_contour)
  3895. self.density_map_btn = QtWidgets.QPushButton("&Density Map GEP")
  3896. self.density_map_btn.clicked.connect(self.plot_densitymap_metrics)
  3897. self.stability_map_btn = QtWidgets.QPushButton("&stability Map GEP")
  3898. self.stability_map_btn.clicked.connect(self.plot_save_2D_stabilitymap)
  3899. self.grid_method_btn = QtWidgets.QPushButton('metrics with grid method')
  3900. self.grid_method_btn.clicked.connect(self.grid_method)
  3901. self.dist_to_rand_goal_btn = QtWidgets.QPushButton('random goal method')
  3902. self.dist_to_rand_goal_btn.clicked.connect(self.rand_goal_method)
  3903. self.btn_quit = QtWidgets.QPushButton('QUIT')
  3904. self.btn_quit.clicked.connect(self.closeIt)
  3905. self.behavs = self.GUI_Gr_obj.optSet.behavs
  3906. self.pairs = self.GUI_Gr_obj.optSet.pairs
  3907. # text = QtWidgets.QLineEdit('enter text')
  3908. self.listw = QtWidgets.QListWidget()
  3909. # self.plot = pg.PlotWidget()
  3910. # self.gl3d = gl.GLViewWidget()
  3911. # Create a grid layout to manage the widgets size and position
  3912. layout = QtWidgets.QGridLayout()
  3913. self.setLayout(layout)
  3914. # layout = QtWidgets..QVBoxLayout()
  3915. # Add widgets to the layout in their proper positions
  3916. layout.addWidget(self.setErrThr_btn, 0, 0)
  3917. layout.addWidget(self.saveplotbhv_btn, 1, 0) # goes 1st row-left
  3918. layout.addWidget(self.saveplobhvtparam_btn, 2, 0) # goes 2nd row-left
  3919. layout.addWidget(self.behavior_map_btn, 3, 0) # goes 3d row-left
  3920. layout.addWidget(self.MSp_ampl_Abaque_btn, 4, 0) # goes 4th row-left
  3921. layout.addWidget(self.plot_density_btn, 5, 0) # goes 5th row-left
  3922. layout.addWidget(self.density_map_btn, 6, 0)
  3923. layout.addWidget(self.stability_map_btn, 7, 0)
  3924. layout.addWidget(self.grid_method_btn, 8, 0)
  3925. layout.addWidget(self.dist_to_rand_goal_btn, 9, 0)
  3926. layout.addWidget(self.btn_quit, 10, 0) # goes in bottom-left
  3927. # layout.addWidget(self.plot, 0, 1, 3, 1) # plot goes on right side,
  3928. # # spanning 3 rows
  3929. self.setWindowTitle("GEP Metrics and Graphs")
  3930. self.to_init()
  3931. def screen_loc(self, xshift=0, yshift=0):
  3932. ag = QtWidgets.QDesktopWidget().availableGeometry()
  3933. # sg = QtWidgets.QDesktopWidget().screenGeometry()
  3934. widget = self.geometry()
  3935. x = ag.width() - widget.width() - xshift
  3936. # y = 2 * ag.height() - sg.height() - widget.height()
  3937. y = ag.height() - widget.height() - yshift
  3938. self.move(x, y)
  3939. def to_init(self):
  3940. """
  3941. doc string
  3942. """
  3943. self.autoscale = False
  3944. self.scale_x = self.GUI_Gr_obj.scale_x
  3945. self.scale_y = self.GUI_Gr_obj.scale_y
  3946. self.behav_col = self.GUI_Gr_obj.behav_col
  3947. self.bhv_names = self.GUI_Gr_obj.bhv_names
  3948. self.errThr = self.GUI_Gr_obj.errThr
  3949. self.coactThr = self.GUI_Gr_obj.coactThr
  3950. def setErrThr(self):
  3951. list_entry_name = ["errThr", "coactThr"]
  3952. list_entry_value = [self.errThr, self.coactThr]
  3953. #list_value_max = [0.2, 5, 5]
  3954. window_name = "Enter errThr and coactThr"
  3955. dicValues = {}
  3956. for idx, nam in enumerate(list_entry_name):
  3957. dicValues[nam] = list_entry_value[idx]
  3958. selected = list(dicValues.keys())
  3959. typ, text = "sel", "typ"
  3960. dicValues = set_values_in_list(dicValues, selected, typ, text)
  3961. self.errThr = float(dicValues["errThr"])
  3962. self.coactThr = float(dicValues["coactThr"])
  3963. self.GUI_Gr_obj.errThr = self.errThr
  3964. self.GUI_Gr_obj.coactThr = self.coactThr
  3965. self.GUI_Gr_obj.mafen.errThr = self.errThr
  3966. self.GUI_Gr_obj.mafen.coactThr = self.coactThr
  3967. self.GUI_Gr_obj.mafen.clearBhv()
  3968. self.GUI_Gr_obj.mafen.plotBhvSet(self.behavs, self.pairs,
  3969. 0, len(self.behavs)-1)
  3970. df_bhvremain = copy.deepcopy(self.GUI_Gr_obj.df_bhvremain)
  3971. # ======== selection of data by coactP level =========
  3972. # print(df_behav)
  3973. coact_OK = df_bhvremain['coactpen'] < self.coactThr
  3974. df_behav = df_bhvremain[coact_OK]
  3975. def saveplot_bhv(self):
  3976. """
  3977. Saves a plot of behavior domain using a method of the class MaFenetre
  3978. """
  3979. df_bhv = self.GUI_Gr_obj.df_bhvremain
  3980. # pathGEP = self.GUI_Gr_obj.listGEPFolders[0]
  3981. # root_path = os.path.split(pathGEP)[0]
  3982. # graph_path = os.path.join(root_path, "graphs")
  3983. # graph_path = root_path + "/graphs"
  3984. graph_path = self.GUI_Gr_obj.graph_path
  3985. if not os.path.exists(graph_path):
  3986. os.makedirs(graph_path)
  3987. behav_col = self.behav_col
  3988. if behav_col[1] == 8:
  3989. ordTyp = "duration"
  3990. elif behav_col[1] == 6:
  3991. ordTyp = "maxSpeed"
  3992. name = "{}_{}".format("GEPdata00", ordTyp)
  3993. behav_col = self.behav_col
  3994. max_x_bhv = df_bhv[df_bhv.columns[behav_col[0]]].max()/self.scale_x
  3995. max_y_bhv = df_bhv[df_bhv.columns[behav_col[1]]].max()/self.scale_y
  3996. self.GUI_Gr_obj.mafen.save_map_behav(df_bhv, graph_path, name,
  3997. max_x=max_x_bhv, max_y=max_y_bhv)
  3998. print("bvh plot saved to: " + graph_path)
  3999. def saveplot_bhvparam(self):
  4000. """
  4001. Plots and saves in pdf and eps format, a series of x-y scatter graphs
  4002. representing the behaviors (from df_bhvremain) and the corresponding
  4003. parameter sets presented by pairs of parameters (from df_parremain).
  4004. It s possible to restraindf_bhvremain and df_parremain to lines that
  4005. are between start and end
  4006. """
  4007. optSet = self.GUI_Gr_obj.optSet
  4008. xparName = optSet.xparName
  4009. graph_path = self.GUI_Gr_obj.graph_path
  4010. graph_name = os.path.split(graph_path)[-1]
  4011. df_bhv = copy.deepcopy(self.GUI_Gr_obj.df_bhvremain)
  4012. df_par = copy.deepcopy(self.GUI_Gr_obj.df_parremain)
  4013. if graph_name[:15] == 'mltpleExpeGraph':
  4014. print("This is a multipleExpeGraph ==> plot totality of _bhv")
  4015. start = 0
  4016. end = df_bhv["rgserie"].max()
  4017. else:
  4018. if self.autoscale is not True:
  4019. self.dialog = InputDialogWin()
  4020. start = 0
  4021. end = len(self.GUI_Gr_obj.df_bhvremain)
  4022. dialog_title = "plot range"
  4023. start = self.dialog.getint(dialog_title, "start row", start)
  4024. end = self.dialog.getint(dialog_title, "end row", end)
  4025. else:
  4026. start = 0
  4027. end = df_bhv["rgserie"].max()
  4028. df_bhv = df_bhv.loc[start:end]
  4029. df_par = df_par.loc[start:end]
  4030. behav_col = self.GUI_Gr_obj.behav_col
  4031. listDicGraphs = self.GUI_Gr_obj.mafen.listDicGraphs
  4032. xparNameDict = self.GUI_Gr_obj.mafen.xparNameDict
  4033. # pathGEP = self.GUI_Gr_obj.listGEPFolders[0]
  4034. # root_path = os.path.split(pathGEP)[0]
  4035. # graph_path = os.path.join(root_path, "graphs")
  4036. # graph_path = root_path + "/graphs"
  4037. graph_path = self.GUI_Gr_obj.graph_path
  4038. if not os.path.exists(graph_path):
  4039. os.makedirs(graph_path)
  4040. strGEPdataName = self.GUI_Gr_obj.prevListGEPFiles[0]
  4041. strGEPdataName = os.path.splitext(strGEPdataName)[0]
  4042. if behav_col[1] == 8:
  4043. ordTyp = "duration"
  4044. max_x_bhv = 1.2
  4045. max_y_bhv = 2.0
  4046. elif behav_col[1] == 6:
  4047. ordTyp = "maxSpeed"
  4048. max_x_bhv = 1.2
  4049. max_y_bhv = 5.0
  4050. baseName = "{}_{}_{}_{}_{}".format(strGEPdataName[:], ordTyp,
  4051. "bhv_par_graphs", start, end)
  4052. """
  4053. max_x_bhv = df_bhv[df_bhv.columns[behav_col[0]]].max()/self.scale_x
  4054. max_y_bhv = df_bhv[df_bhv.columns[behav_col[1]]].max()/self.scale_y
  4055. max_x = float(int(max_x_bhv*10)+1)/10
  4056. max_y = float(int(max_y_bhv*10)+1)/10
  4057. """
  4058. do_plot_bhv_param(self.GUI_Gr_obj, df_bhv, df_par, behav_col,
  4059. graph_path, baseName, listDicGraphs, xparNameDict,
  4060. xparName, max_x_bhv=max_x_bhv, max_y_bhv=max_y_bhv)
  4061. print("bvh & parameter plot saved to: " + graph_path)
  4062. def plot_bhvmap_nbBhvOK(self):
  4063. """
  4064. plots and saves the df_bhvremain dataframe for index < nbBhvOK
  4065. """
  4066. # self.GUI_Gr_obj.close_otherwin()
  4067. """
  4068. df_bhvremain = self.GUI_Gr_obj.df_bhvremain
  4069. ret = 7
  4070. if df_bhvremain is not None:
  4071. msg = "A previous dataframe is present \n Use Same dataframe?"
  4072. ret = MessageBox(None, msg, 'Previous dataframe detected', 3)
  4073. print ret
  4074. if ret == 2:
  4075. print "ESC"
  4076. elif ret == 6:
  4077. print "YES --> Keep the previous dataframe"
  4078. print "df_bhvremain size : {}\n".format(len(df_bhvremain))
  4079. elif ret == 7:
  4080. print "NO: --> Look for another dierctory"
  4081. if ret == 7:
  4082. self.GUI_Gr_obj.make_bhvpardf_bhvparwins()
  4083. """
  4084. optSet = self.GUI_Gr_obj.optSet
  4085. listcolors = ['blue', 'orange', 'green', 'red', 'purple',
  4086. 'brown', 'pink', 'gray', 'olive', 'cyan']
  4087. # self.GUI_Gr_obj.make_bhvpardf_bhvparwins()
  4088. df_bhvremain = self.GUI_Gr_obj.df_bhvremain
  4089. selectedROI = self.GUI_Gr_obj.mafen.selectedROI
  4090. # pathGEP = self.GUI_Gr_obj.listGEPFolders[0]
  4091. # root_path = os.path.split(pathGEP)[0]
  4092. # graph_path = os.path.join(root_path, "graphs")
  4093. # graph_path = root_path + "/graphs"
  4094. graph_path = self.GUI_Gr_obj.graph_path
  4095. if not os.path.exists(graph_path):
  4096. os.makedirs(graph_path)
  4097. strGEPdataName = self.GUI_Gr_obj.prevListGEPFiles[0]
  4098. GEPdataName = os.path.splitext(strGEPdataName)[0]
  4099. df = copy.deepcopy(df_bhvremain)
  4100. # ==============================================================
  4101. coact_OK = df['coactpen'] < self.coactThr
  4102. df = df[coact_OK]
  4103. # ==============================================================
  4104. err_OK = df['varmse'] < self.errThr
  4105. df = df[err_OK]
  4106. # ==============================================================
  4107. list_entry_name = ["nbBhvOKs", "X_min", "X_max", "Y_min", "Y_max"]
  4108. nbBhvOKs = len(df)
  4109. behav_col = self.GUI_Gr_obj.behav_col
  4110. # max_x = df_bhvremain[df_bhvremain.columns[behav_col[0]]].max()/100
  4111. # max_y_bhv = df_bhvremain[df_bhvremain.columns[behav_col[1]]].max()
  4112. list_entry_value = [str(nbBhvOKs), str(0), str(1.2), str(0), str(1.4)]
  4113. list_value_max = [nbBhvOKs, 1.5, 1.5, 5, 5]
  4114. window_name = "Enter nbBhvOK to Plot"
  4115. self.list_bhvmap_value = list_entry_value
  4116. self.get_nbBhvOKs = Enter_Values(self,
  4117. list_entry_name,
  4118. list_entry_value,
  4119. list_value_max,
  4120. window_name)
  4121. self.get_nbBhvOKs.show()
  4122. self.get_nbBhvOKs.exec_() # Stops further processes
  4123. # until executed
  4124. self.list_bhvmap_value = self.list_value
  4125. # QtWidgets.QApplication.processEvents()
  4126. # ==============================================================
  4127. nbBhvOK = int(self.list_bhvmap_value[0])
  4128. x_min = float(self.list_bhvmap_value[1])
  4129. x_max = float(self.list_bhvmap_value[2])
  4130. y_min = float(self.list_bhvmap_value[3])
  4131. y_max = float(self.list_bhvmap_value[4])
  4132. df = df[:nbBhvOK]
  4133. rate = 100
  4134. lstdurMvt2T = []
  4135. behav_col = self.GUI_Gr_obj.behav_col
  4136. if behav_col[1] == 8:
  4137. ordTyp = "duration"
  4138. # ======== add a new column with durMvt2T from template ===========
  4139. for idx in df.index:
  4140. amplitude = df.endangle[idx]
  4141. max_speed = df.max_speed[idx]
  4142. rep = calculate_minjerk_duration(amplitude, max_speed, rate)
  4143. durMvt2T = rep[0]
  4144. lstdurMvt2T.append(durMvt2T)
  4145. df.loc[:, 'durMvt2T'] = lstdurMvt2T
  4146. # =================================================================
  4147. name = "{}_{}_bhvPlot_{}".format(GEPdataName, "durationT", nbBhvOK)
  4148. elif behav_col[1] == 6:
  4149. ordTyp = "maxSpeed"
  4150. name = "{}_{}_bhvPlot_{}".format(GEPdataName, ordTyp, nbBhvOK)
  4151. # name = GEPdataName + "bhvPlot_{}".format(nbBhvOK)
  4152. # path = os.path.split(pathGEP)[0]
  4153. if os.path.split(graph_path)[1] == "graphs":
  4154. path = os.path.split(graph_path)[0]
  4155. else:
  4156. path = graph_path
  4157. # titre = "{}/{}".format(path, name)
  4158. baseName = name
  4159. titre = get_titre(path, baseName) + " errThr: {} coactThr: {}"
  4160. titre = titre.format(self.errThr, self.coactThr)
  4161. if ordTyp == "duration":
  4162. bhv_col = [3, 13]
  4163. else:
  4164. bhv_col = [3, 6]
  4165. # ===========================================================
  4166. # Reduction of the number of points
  4167. # ===========================================================
  4168. x = df[df.columns[bhv_col[0]]].to_numpy()
  4169. y = df[df.columns[bhv_col[1]]].to_numpy()
  4170. points = np.column_stack((x,y))
  4171. nb_cases = 200
  4172. resolution_x = (x.max() - x.min())/ nb_cases
  4173. resolution_y = (y.max() - y.min())/ nb_cases
  4174. resolution = np.array([resolution_x, resolution_y])
  4175. # approximation of each point (several points have the samee coordinates)
  4176. quantized = np.round(points / resolution) * resolution
  4177. # keep only one occurence for each point (doublon suppress)
  4178. _, unique_indices = np.unique(quantized, axis=0, return_index=True)
  4179. df2 = df.iloc[unique_indices].copy()
  4180. a=len(df)
  4181. b=len(df2)
  4182. print(f"reduction from {a} to {b} points")
  4183. behavs_cues = df2[df2.columns[bhv_col]]
  4184. rel_behavs_cues = behavs_cues/[self.scale_x, self.scale_y]
  4185. nameX = rel_behavs_cues.columns[0]
  4186. nameY = rel_behavs_cues.columns[1]
  4187. valX = rel_behavs_cues[nameX]
  4188. valY = rel_behavs_cues[nameY]
  4189. if self.behav_col[1] == 8: # if ordonate is duration...
  4190. labelnameX = nameX + "(x 0.01)"
  4191. labelnameY = nameY
  4192. elif self.behav_col[1] == 6:
  4193. labelnameX = nameX + "(x 0.01)"
  4194. labelnameY = nameY + "(x 0.01)"
  4195. # ===========================================================
  4196. fig = plt.figure(figsize=(10, 10), dpi=90)
  4197. # plt.subplots_adjust(bottom=0, left=0.1, top=0.9, right=0.9)
  4198. grid = plt.GridSpec(1, 1, wspace=0.4, hspace=0.3)
  4199. ax1 = fig.add_subplot(grid[0, 0])
  4200. # selectedROI = []
  4201. if selectedROI == []:
  4202. # ---------------------------------------------------
  4203. ax1.scatter(valX, valY, marker='o', s=4, c="r")
  4204. # ---------------------------------------------------
  4205. else:
  4206. for idxROI, listdata in enumerate(selectedROI):
  4207. dflist_x = rel_behavs_cues[nameX][listdata]
  4208. dflist_y = rel_behavs_cues[nameY][listdata]
  4209. color = listcolors[idxROI]
  4210. # ---------------------------------------------------
  4211. ax1.scatter(dflist_x, dflist_y, marker='o', s=4, c=color)
  4212. # ---------------------------------------------------
  4213. ax1.set_xlabel(labelnameX, fontsize=11)
  4214. ax1.set_ylabel(labelnameY, fontsize=11)
  4215. plt.xticks(fontsize=10)
  4216. plt.yticks(fontsize=10)
  4217. ax1.set_axisbelow(True)
  4218. ax1.set_xlim(x_min, x_max)
  4219. ax1.set_ylim(y_min, y_max)
  4220. ax1.grid(linestyle='-', linewidth='0.5', color='green')
  4221. plt.suptitle(titre, fontsize=12, y=0.95)
  4222. plt.savefig(os.path.join(graph_path, name + "_reduced" + '.pdf'))
  4223. plt.savefig(os.path.join(graph_path, name + "_reduced" + '.eps'))
  4224. plt.show()
  4225. # ===========================================================
  4226. # Plot all points
  4227. # ===========================================================
  4228. behavs_cues = df[df.columns[bhv_col]]
  4229. rel_behavs_cues = behavs_cues/[self.scale_x, self.scale_y]
  4230. nameX = rel_behavs_cues.columns[0]
  4231. nameY = rel_behavs_cues.columns[1]
  4232. valX = rel_behavs_cues[nameX]
  4233. valY = rel_behavs_cues[nameY]
  4234. if self.behav_col[1] == 8: # if ordonate is duration...
  4235. labelnameX = nameX + "(x 0.01)"
  4236. labelnameY = nameY
  4237. elif self.behav_col[1] == 6:
  4238. labelnameX = nameX + "(x 0.01)"
  4239. labelnameY = nameY + "(x 0.01)"
  4240. # ===========================================================
  4241. fig = plt.figure(figsize=(10, 10), dpi=90)
  4242. # plt.subplots_adjust(bottom=0, left=0.1, top=0.9, right=0.9)
  4243. grid = plt.GridSpec(1, 1, wspace=0.4, hspace=0.3)
  4244. ax1 = fig.add_subplot(grid[0, 0])
  4245. # selectedROI = []
  4246. if selectedROI == []:
  4247. # ---------------------------------------------------
  4248. ax1.scatter(valX, valY, marker='o', s=4, c="r")
  4249. # ---------------------------------------------------
  4250. else:
  4251. for idxROI, listdata in enumerate(selectedROI):
  4252. dflist_x = rel_behavs_cues[nameX][listdata]
  4253. dflist_y = rel_behavs_cues[nameY][listdata]
  4254. color = listcolors[idxROI]
  4255. # ---------------------------------------------------
  4256. ax1.scatter(dflist_x, dflist_y, marker='o', s=4, c=color)
  4257. # ---------------------------------------------------
  4258. ax1.set_xlabel(labelnameX, fontsize=11)
  4259. ax1.set_ylabel(labelnameY, fontsize=11)
  4260. plt.xticks(fontsize=10)
  4261. plt.yticks(fontsize=10)
  4262. ax1.set_axisbelow(True)
  4263. ax1.set_xlim(x_min, x_max)
  4264. ax1.set_ylim(y_min, y_max)
  4265. ax1.grid(linestyle='-', linewidth='0.5', color='green')
  4266. plt.suptitle(titre, fontsize=12, y=0.95)
  4267. plt.savefig(os.path.join(graph_path, name + '.pdf'))
  4268. plt.savefig(os.path.join(graph_path, name + '.eps'))
  4269. plt.show()
  4270. # self.mafen.save_map_behav(df, pathGEP, name)
  4271. def plot_abaque_duration(self):
  4272. """
  4273. Plots a series of curves Maxspeed=f(amplitude) for a series of
  4274. duration values
  4275. INPUT: graph_path, graph_name, mindur, maxdur, stepdur
  4276. in which mindur and max dur are the minimum and maximum values of
  4277. duration, and stepdur is the step used to define the varius values
  4278. of duration between mindur and maxdur
  4279. OUTPUT: a plot that will be saved in the graph folder (graph_path)
  4280. under the names : graph_name + '.pdf' and graph_name + '.eps'
  4281. """
  4282. graph_path = self.GUI_Gr_obj.graph_path
  4283. graph_name = "abaques_duration"
  4284. nomfic_eps = graph_path + '/' + graph_name + '.eps'
  4285. nomfic_pdf = graph_path + '/' + graph_name + '.pdf'
  4286. if not os.path.exists(nomfic_eps):
  4287. plt.savefig(nomfic_eps, bbox_inches='tight')
  4288. plt.savefig(nomfic_pdf, bbox_inches='tight')
  4289. else:
  4290. root = nomfic_eps[:nomfic_eps.find(".eps")]
  4291. print(len(root))
  4292. k = 0
  4293. while os.path.exists("{0}({1}){2}".format(root, k, ".eps")):
  4294. k += 1
  4295. nomfic_eps = "{0}({1}){2}".format(root, k, ".eps")
  4296. nomfic_pdf = "{0}({1}){2}".format(root, k, ".pdf")
  4297. graph_name_with_ext = os.path.split(nomfic_eps)[-1]
  4298. graph_name = os.path.splitext(graph_name_with_ext)[0]
  4299. # ==============================================================
  4300. list_entry_name = ["mindur", "maxdur", "stepdur"]
  4301. list_entry_value = [0.2, 5, 0.25]
  4302. #list_value_max = [0.2, 5, 5]
  4303. window_name = "Enter min, max, step for durations"
  4304. dicValues = {}
  4305. for idx, nam in enumerate(list_entry_name):
  4306. dicValues[nam] = list_entry_value[idx]
  4307. selected, typ, text = "sel", "typ", window_name
  4308. dicValues = set_values_in_list(dicValues, selected, typ, text)
  4309. # QtWidgets.QApplication.processEvents()
  4310. # ==============================================================
  4311. mindur = float(dicValues["mindur"])
  4312. maxdur = float(dicValues["maxdur"])
  4313. stepdur = float(dicValues["stepdur"])
  4314. plot_series_curves_maxspeed_ampl_duration(graph_path, graph_name,
  4315. mindur, maxdur, stepdur)
  4316. def plot_densitymap_metrics(self):

makeGraphs.py at commit 04b2210, no license · at the source

Overview

Authors: Daniel Cattaert1, Matthieu Guemann1, Florent Paclet1, Luca Lemarchand1, Bryce Chung2, Pierre-Yves Oudeyer3, Aymar de Rugy1
ORCID iDs: Florent Paclet
  1. Institut de Neurosciences Cognitives et Intégratives d’Aquitaine, UMR 5287, CNRS, Université de Bordeaux, Bordeaux, France
  2. Neuroscience Institute, Georgia State University, Atlanta, GA, United States
  3. Inria Bordeaux Sud-Ouest, Talence, France
Journal: Frontiers in computational neuroscience, volume 20, article 1745836
Dates: received 13 November 2025; accepted 10 February 2026; published online 11 March 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.3389/fncom.2026.1745836 · PMID 41889600 · PMCID PMC13015193 · OpenAlex W7135051484
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: computational modeling (no new data) (modality), none (in silico) (organism), systems (subfield)
Methods: Physiology & signal measures, Statistics
Keywords: goal exploration, motor control, sensorimotor circuits, spinal circuits, triphasic pattern
Topic: Motor Control and Adaptation (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 80 references in the paper

Abstract

During rapid voluntary elbow movement on horizontal plane, a stereotyped triphasic pattern is typically observed in the electromyograms (EMGs) of antagonistic muscles acting at this joint. To explain the origin of such triphasic commands, two types of theories have been proposed. Peripheral theories consider that triphasic commands result from sensorimotor spinal networks, either through a combination of reflexes or through a spinal central pattern generator. Central theories consider that the triphasic command is elaborated in the brain. Although both theories were partially supported by physiological data, there is still no consensus about how exactly triphasic commands are elaborated. Moreover, capacities of simple spinal sensorimotor circuits to elaborate triphasic commands on their own have not been tested yet. In order to test this, we modelled arm musculoskeletal system operating in the absence of gravity, muscle activation dynamics, proprioceptive spindle and Golgi afferent activities and spinal sensorimotor circuits. Step commands were designed to modify the activity of spinal neurons and the strength of their synapses, either to prepare (SET) the network before movement onset, or to launch the movement (GO). Since these step commands do not contain any dynamics, changes in muscle activities responsible for arm movement rest entirely upon interactions between the spinal network and the musculoskeletal system. Critically, we selected step commands using a Goal Exploration Process inspired from baby babbling during development. In this task, the Goal Exploration Process proved very efficient at discovering step commands that enabled spinal circuits to handle a broad spectrum of functional behaviors, displayed in a behavioral space characterized by movement amplitude and maximal speed. All over the behavioral space, specific SET and GO commands elicited natural triphasic commands, thereby substantiating the inherent capacity of the spinal network in generating them.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.

cattaert/rgep

License: none: the authors keep all their rights
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 04b2210fb8ce22193e9a2339340909d294d63bdc, 27 July 2026
Languages: Python (41)
Size: 47 files, 41 scripts
Software Heritage: not archived
Found in: “Data availability statement”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (24 files), scikit-learn (8 files), pandas (7 files), SciPy (6 files), Matplotlib (5 files), seaborn (3 files)
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
42 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 41 scripts, each with its path and the digest of its content;
  • 5 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability statement

Python scripts for GEP and all simulations included in this study can be downloaded from GitHub, with an installation procedure for all software package involved: (https://github.com/Cattaert/rGEP/tree/main).

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 7 authors, 5 keywords, 68 references.

Cite

This paper

Cattaert, D., Guemann, M., Paclet, F., Lemarchand, L., Chung, B., Oudeyer, P.-Y., & de Rugy, A. (2026). Role of spinal sensorimotor circuits in triphasic muscle command: a simulation approach using goal exploration process. Frontiers in computational neuroscience, 20, 1745836. https://doi.org/10.3389/fncom.2026.1745836

BibTeX

@article{cattaert2026role,
author = {Cattaert, Daniel and Guemann, Matthieu and Paclet, Florent and Lemarchand, Luca and Chung, Bryce and Oudeyer, Pierre-Yves and de Rugy, Aymar},
title = {{Role of spinal sensorimotor circuits in triphasic muscle command: a simulation approach using goal exploration process}},
journal = {Frontiers in computational neuroscience},
year = {2026},
month = mar,
volume = {20},
pages = {1745836},
publisher = {Frontiers Media SA},
issn = {1662-5188},
doi = {10.3389/fncom.2026.1745836},
url = {https://doi.org/10.3389/fncom.2026.1745836},
pmid = {41889600},
pmcid = {PMC13015193}
}

RIS

TY - JOUR
AU - Cattaert, Daniel
AU - Guemann, Matthieu
AU - Paclet, Florent
AU - Lemarchand, Luca
AU - Chung, Bryce
AU - Oudeyer, Pierre-Yves
AU - de Rugy, Aymar
TI - Role of spinal sensorimotor circuits in triphasic muscle command: a simulation approach using goal exploration process
T2 - Frontiers in computational neuroscience
J2 - Front Comput Neurosci
PY - 2026
DA - 2026/03/11
VL - 20
SP - 1745836
SN - 1662-5188
PB - Frontiers Media SA
DO - 10.3389/fncom.2026.1745836
UR - https://doi.org/10.3389/fncom.2026.1745836
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fncom.2026.1745836",
"type": "article-journal",
"title": "Role of spinal sensorimotor circuits in triphasic muscle command: a simulation approach using goal exploration process",
"container-title": "Frontiers in computational neuroscience",
"author": [
{
"family": "Cattaert",
"given": "Daniel"
},
{
"family": "Guemann",
"given": "Matthieu"
},
{
"family": "Paclet",
"given": "Florent"
},
{
"family": "Lemarchand",
"given": "Luca"
},
{
"family": "Chung",
"given": "Bryce"
},
{
"family": "Oudeyer",
"given": "Pierre-Yves"
},
{
"family": "de Rugy",
"given": "Aymar"
}
],
"container-title-short": "Front Comput Neurosci",
"volume": "20",
"page": "1745836",
"DOI": "10.3389/fncom.2026.1745836",
"PMID": "41889600",
"PMCID": "PMC13015193",
"ISSN": "1662-5188",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fncom.2026.1745836",
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
11
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1016/j.celrep.2026.117793 [code]
Clustered inputs engage dendritic nonlinearities and calcium signaling to support efficient place-field formation in CA1 pyramidal neurons.
Journal: Cell reports
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico), computational modeling (no new data)
[2] doi:10.1038/s41586-026-10670-w [code]
Zero-shot design of drug-binding proteins via neural iterative selection-expansion.
Journal: Nature
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico), computational modeling (no new data)
[3] doi:10.7554/elife.107423 [code]
A context-free model of savings in motor learning.
Journal: eLife
In common: seaborn, scikit-learn, pandas, 3 other tools, 1 reference
[4] doi:10.1126/sciadv.aeg6797 [code]
Dorsoventral gradient of theta sweeps in the medial entorhinal cortex.
Journal: Science advances
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico), systems
[5] doi:10.1038/s41467-026-76104-3 [code]
Sensorimotor remapping drives task specialization in prefrontal cortex.
Journal: Nature communications
In common: seaborn, scikit-learn, pandas, 3 other tools, computational modeling (no new data), systems
[6] doi:10.1038/s41467-026-72152-x [code]
Centralized brain networks controlling antennal grooming coordination.
Journal: Nature communications
In common: seaborn, scikit-learn, pandas, 3 other tools, computational modeling (no new data), systems
[7] doi:10.1093/nc/niag029 [code]
A data-driven approach to identifying and evaluating connectivity-based neural correlates of conscious visual perception.
Journal: Neuroscience of consciousness
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico)
[8] doi:10.1371/journal.pcbi.1014391 [code]
Multi-stable oscillations in cortical networks with two classes of inhibition.
Journal: PLoS computational biology
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico)
[9] doi:10.3389/fncom.2026.1753444 [code]
NMDA receptor kinetics drive distinct routes to chaotic firing in pyramidal neurons.
Journal: Frontiers in computational neuroscience
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico)
[10] doi:10.1093/bioinformatics/btag328 [code]
eFEL: electrophysiology feature extraction library.
Journal: Bioinformatics (Oxford, England)
In common: seaborn, scikit-learn, pandas, 3 other tools, none (in silico)

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.