scilens 0.3.8__py3-none-any.whl → 0.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scilens/components/executor.py +16 -9
- scilens/config/models/execute.py +1 -1
- scilens/config/models/reader_format_csv.py +2 -2
- scilens/config/models/reader_format_txt_fixed_cols.py +1 -1
- scilens/config/models/readers.py +8 -12
- scilens/config/models/report_html.py +8 -5
- scilens/processors/execute_and_compare.py +2 -2
- scilens/readers/mat_dataset.py +7 -13
- scilens/readers/reader_csv.py +33 -27
- scilens/readers/reader_txt_fixed_cols.py +68 -25
- scilens/report/templates/compare_12_sections.html +1 -1
- scilens/report/templates/index.html +13 -5
- scilens/report/templates/js_chartlibs_plotly.js +1 -1
- scilens/report/templates/js_com_page.js +1 -1
- scilens/report/templates/js_curvemgr.js +0 -1
- scilens/report/templates/uti_matrix.js +22 -9
- scilens/report/templates/uti_spectrograms.js +29 -20
- scilens/report/templates/utils_compare_report_anim.js +4 -1
- scilens/report/templates/utils_compare_report_framesseries.js +5 -2
- {scilens-0.3.8.dist-info → scilens-0.3.9.dist-info}/METADATA +1 -1
- {scilens-0.3.8.dist-info → scilens-0.3.9.dist-info}/RECORD +23 -23
- {scilens-0.3.8.dist-info → scilens-0.3.9.dist-info}/WHEEL +0 -0
- {scilens-0.3.8.dist-info → scilens-0.3.9.dist-info}/entry_points.txt +0 -0
scilens/components/executor.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
_A=None
|
|
1
2
|
import logging,os,shutil,stat,subprocess,platform,tempfile,zipfile
|
|
2
3
|
from scilens.config.models import ExecuteConfig
|
|
3
4
|
from scilens.utils.file import dir_remove,dir_create
|
|
@@ -27,30 +28,36 @@ def find_command(command_path,working_dirs,guess_os_extension=False):
|
|
|
27
28
|
B=os.path.join(E,F)
|
|
28
29
|
if os.path.exists(B):return B
|
|
29
30
|
class Executor:
|
|
30
|
-
def __init__(A,absolute_working_dir,config,alternative_working_dir=
|
|
31
|
-
D=alternative_working_dir;C=absolute_working_dir;B=config;A.config=B;A.working_dir=C;A.dirs=[C]+([D]if D else[]);A.command_path=
|
|
31
|
+
def __init__(A,absolute_working_dir,config,config_file_path=_A,alternative_working_dir=_A):
|
|
32
|
+
D=alternative_working_dir;C=absolute_working_dir;B=config;A.config=B;A.config_file_path=config_file_path;A.working_dir=C;A.dirs=[C]+([D]if D else[]);A.command_path=_A;A.temp_dir=_A
|
|
32
33
|
if not bool(B.exe_url)+bool(B.exe_url)!=1:raise Exception('exe_url and exe_path are mutually exclusive.')
|
|
33
34
|
if not os.path.exists(A.working_dir):logging.info(f"Creating working directory {A.working_dir}");dir_create(A.working_dir)
|
|
34
35
|
def __enter__(A):return A
|
|
35
36
|
def __exit__(A,exc_type,exc_value,traceback):A._cleanup()
|
|
36
37
|
def _cleanup(A):0
|
|
37
38
|
def _pre_operations(A):
|
|
38
|
-
logging.info(f"Execute - Pre Operations")
|
|
39
|
-
|
|
39
|
+
D=A.working_dir;logging.info(f"Execute - Pre Operations")
|
|
40
|
+
if A.config.pre_files_delete:
|
|
41
|
+
logging.info(f"Files deletion")
|
|
42
|
+
for F in os.listdir(D):
|
|
43
|
+
E=os.path.join(D,F)
|
|
44
|
+
if not F.startswith('.')and not os.path.isdir(E)and E!=A.config_file_path:logging.debug(f"Delete file {E}");os.remove(E)
|
|
45
|
+
logging.info(f"Folders deletion")
|
|
46
|
+
for dir in A.config.pre_folder_delete or[]:dir_remove(os.path.join(D,dir))
|
|
40
47
|
logging.info(f"Folders creation")
|
|
41
|
-
for dir in A.config.pre_folder_creation or[]:dir_create(os.path.join(
|
|
48
|
+
for dir in A.config.pre_folder_creation or[]:dir_create(os.path.join(D,dir))
|
|
42
49
|
if A.config.exe_url or A.config.exe_path:
|
|
43
50
|
logging.info(f"Executable file preparation")
|
|
44
51
|
if A.config.exe_url:
|
|
45
|
-
logging.info(f"Download executable {A.config.exe_url}");A.temp_dir=tempfile.mkdtemp();
|
|
52
|
+
logging.info(f"Download executable {A.config.exe_url}");A.temp_dir=tempfile.mkdtemp();H='executable';B=os.path.join(A.temp_dir,H)
|
|
46
53
|
try:Web().download_progress(A.config.exe_url,B,headers=A.config.exe_url_headers,callback100=lambda percentage:logging.info(f"Downloaded {percentage}%"))
|
|
47
|
-
except Exception as
|
|
54
|
+
except Exception as I:raise ValueError(f"Error downloading executable: {I}")
|
|
48
55
|
logging.info(f"Download completed")
|
|
49
56
|
elif A.config.exe_path:B=A.config.exe_path
|
|
50
|
-
if A.config.exe_unzip_and_use:logging.info(f"Unzip archive");
|
|
57
|
+
if A.config.exe_unzip_and_use:logging.info(f"Unzip archive");G=os.path.dirname(B);unzip_file(B,G);B=os.path.join(G,A.config.exe_unzip_and_use);logging.info(f"Unzip completed")
|
|
51
58
|
C=find_command(B,A.dirs,guess_os_extension=A.config.exe_guess_os_extension)
|
|
52
59
|
if not C:raise FileNotFoundError(f"Command not found: {B}")
|
|
53
|
-
logging.info(f"Command path resolved: {C}");logging.info(f"Add executable permissions");
|
|
60
|
+
logging.info(f"Command path resolved: {C}");logging.info(f"Add executable permissions");J=os.stat(C).st_mode;os.chmod(C,J|stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
|
|
54
61
|
elif A.config.exe_command:logging.info(f"Command path: {A.config.exe_command}");C=A.config.exe_command
|
|
55
62
|
A.command_path=C
|
|
56
63
|
def _post_operations(A):logging.info(f"Execute - Post Operations")
|
scilens/config/models/execute.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
_A=None
|
|
2
2
|
from pydantic import BaseModel,Field
|
|
3
|
-
class ExecuteConfig(BaseModel):pre_folder_delete:list[str]|_A=Field(default=_A,description='Liste de répertoire à supprimer avant l\'éxecution. Ex: `["DEBUG", "LOG", "OUT"]`');pre_folder_creation:list[str]|_A=Field(default=_A,description='Liste de répertoire à créeravant l\'éxecution. Ex : `["INI", "DAT"]`');exe_path:str|_A=Field(default=_A,description="Chemin de l'exécutable. Ex : `/absolute/path/executable` or `relative/path/executable`. Dans le cas, d'un chemin relatif, il testera le `working directory` et le `origin working directory` (exclusif avec `exe_url` et `exe_command`).");exe_url:str|_A=Field(default=_A,description="Url de l'exécutable à télécharger avant de l'exécuter. Ex : `https://github.com/org/app/releases/download/v3.31.5/app-2.12.2-linux-x86-64` (exclusif avec `exe_path` et `exe_command`).");exe_command:str|_A=Field(default=_A,description='Commande à exécuter sans résolution de chemin. Ex : `./app-2.12.2-linux-x86-64` ou `python3 app.py` (exclusif avec `exe_path` et `exe_url`).');exe_url_headers:dict[str,str]|_A=Field(default=_A,description='Si `exe_url` les en-têtes à ajouter à la requête de téléchargement de l\'exécutable. Ex : `{"Authorization": "Bearer token"}`');exe_unzip_and_use:str|_A=Field(default=_A,description="Si l'exécutable (`exe_path` ou `exe_url`) est zippé, alors décompresse et utilise le fichier spécifié. Ex : `app-2.12.2-linux-x86-64`");exe_guess_os_extension:bool=Field(default=False,description="Si l'exécutable (`exe_path` ou `exe_url`) n'est pas trouvée, cherche avec des extensions en fonction de l'OS. Ex : `.exe`, `.bat` pour windows");command_suffix:str|_A=Field(default=_A,description='Suffixe à ajouter à la commande. Typiquemnt des secrets. Ex : ` --token DGDFGDFGDH`');working_dir:str|_A=Field(default=_A,description="Chemin relatif du répertoire de travail pour l'éxecution de la commande. Dans le contexte processeur `ExecuteAndCompare` si non défini, récupère respectivement la valeur de `compare.sources.test_folder_relative_path` ou `compare.sources.reference_folder_relative_path`")
|
|
3
|
+
class ExecuteConfig(BaseModel):pre_files_delete:bool=Field(default=False,description="Si `true`, supprime les fichiers avant l'éxecution. (le fichier de configuration et les fichiers . ne seront pas supprimés)");pre_folder_delete:list[str]|_A=Field(default=_A,description='Liste de répertoire à supprimer avant l\'éxecution. Ex: `["DEBUG", "LOG", "OUT"]`');pre_folder_creation:list[str]|_A=Field(default=_A,description='Liste de répertoire à créeravant l\'éxecution. Ex : `["INI", "DAT"]`');exe_path:str|_A=Field(default=_A,description="Chemin de l'exécutable. Ex : `/absolute/path/executable` or `relative/path/executable`. Dans le cas, d'un chemin relatif, il testera le `working directory` et le `origin working directory` (exclusif avec `exe_url` et `exe_command`).");exe_url:str|_A=Field(default=_A,description="Url de l'exécutable à télécharger avant de l'exécuter. Ex : `https://github.com/org/app/releases/download/v3.31.5/app-2.12.2-linux-x86-64` (exclusif avec `exe_path` et `exe_command`).");exe_command:str|_A=Field(default=_A,description='Commande à exécuter sans résolution de chemin. Ex : `./app-2.12.2-linux-x86-64` ou `python3 app.py` (exclusif avec `exe_path` et `exe_url`).');exe_url_headers:dict[str,str]|_A=Field(default=_A,description='Si `exe_url` les en-têtes à ajouter à la requête de téléchargement de l\'exécutable. Ex : `{"Authorization": "Bearer token"}`');exe_unzip_and_use:str|_A=Field(default=_A,description="Si l'exécutable (`exe_path` ou `exe_url`) est zippé, alors décompresse et utilise le fichier spécifié. Ex : `app-2.12.2-linux-x86-64`");exe_guess_os_extension:bool=Field(default=False,description="Si l'exécutable (`exe_path` ou `exe_url`) n'est pas trouvée, cherche avec des extensions en fonction de l'OS. Ex : `.exe`, `.bat` pour windows");command_suffix:str|_A=Field(default=_A,description='Suffixe à ajouter à la commande. Typiquemnt des secrets. Ex : ` --token DGDFGDFGDH`');working_dir:str|_A=Field(default=_A,description="Chemin relatif du répertoire de travail pour l'éxecution de la commande. Dans le contexte processeur `ExecuteAndCompare` si non défini, récupère respectivement la valeur de `compare.sources.test_folder_relative_path` ou `compare.sources.reference_folder_relative_path`")
|
|
@@ -2,5 +2,5 @@ _B=False
|
|
|
2
2
|
_A=None
|
|
3
3
|
from pydantic import BaseModel,Field
|
|
4
4
|
from scilens.config.models.reader_format_cols_curve import ReaderColsCurveParserConfig
|
|
5
|
-
class ReaderCsvMatrixConfig(BaseModel):x_value_line:int|_A=Field(default=_A,description="Indique la ligne des valeurs x si applicable. Peut être la ligne d'en-tête (=1).");has_y:bool=Field(default=_B,description='Indique si la première colonne est la colonne des valeurs y.');
|
|
6
|
-
class ReaderCsvConfig(BaseModel):delimiter:str|_A=Field(default=',',description='Délimiteur de colonnes.');quotechar:str|_A=Field(default='"',description='Délimiteur de texte.');has_header:bool|_A=Field(default=_A,description="Indique si la 1ère ligne est une ligne d'en-tête. Si non spécifié, il y aura une détection automatique.");is_matrix:bool=Field(default=_B,description='Indique si le fichier est une matrice.');ignore_columns:list[str]|_A=Field(default=_A,description='Liste des noms des colonnes à ignorer. (Valide seulement si la première ligne est une ligne en-têtes et non matrice)');curve_parser:ReaderColsCurveParserConfig|_A=Field(default=_A,description='Parseur de courbe à utiliser.');matrix:ReaderCsvMatrixConfig|_A=Field(default=_A,description='Configuration de la matrice. (Valide seulement si `is_matrix` est vrai)')
|
|
5
|
+
class ReaderCsvMatrixConfig(BaseModel):x_value_line:int|_A=Field(default=_A,description="Indique la ligne des valeurs x si applicable. Peut être la ligne d'en-tête (=1).");has_y:bool=Field(default=_B,description='Indique si la première colonne est la colonne des valeurs y.');x_name:str=Field(default='X',description='Nom de la colonne des valeurs x.');y_name:str=Field(default='Y',description='Nom de la colonne des valeurs y.');export_report:bool=Field(default=_B,description='Indique si les matrices doivent être exportées dans les rapports.')
|
|
6
|
+
class ReaderCsvConfig(BaseModel):delimiter:str|_A=Field(default=',',description='Délimiteur de colonnes.');quotechar:str|_A=Field(default='"',description='Délimiteur de texte.');has_header:bool|_A=Field(default=_A,description="Indique si la 1ère ligne est une ligne d'en-tête. Si non spécifié, il y aura une détection automatique.");is_matrix:bool=Field(default=_B,description='Indique si le fichier est une matrice.');ignore_columns:list[str]|_A=Field(default=_A,description='Liste des noms des colonnes à ignorer. (Valide seulement si la première ligne est une ligne en-têtes et non matrice)');curve_parser:ReaderColsCurveParserConfig|_A=Field(default=_A,description='Parseur de courbe à utiliser.');ignore_lines_patterns:list[str]|_A=Field(default=_A,description='Liste des patterns de lignes à ignorer. Ex: ["^#", "^//"]. Non applicable si `is_matrix` est vrai.');matrix:ReaderCsvMatrixConfig|_A=Field(default=_A,description='Configuration de la matrice. (Valide seulement si `is_matrix` est vrai)')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
_A=None
|
|
2
2
|
from pydantic import BaseModel,Field
|
|
3
3
|
from scilens.config.models.reader_format_cols_curve import ReaderColsCurveParserConfig
|
|
4
|
-
class ReaderTxtFixedColsConfig(BaseModel):ignore_lines_patterns:list[str]|_A=Field(default=_A,description='Liste des patterns de lignes à ignorer. Ex: ["^#", "^//"].');has_header:bool=Field(default=False,description="Indique si le dataset contient une ligne d'entête.");
|
|
4
|
+
class ReaderTxtFixedColsConfig(BaseModel):ignore_lines_patterns:list[str]|_A=Field(default=_A,description='Liste des patterns de lignes à ignorer. Ex: ["^#", "^//"].');has_header:bool=Field(default=False,description="Indique si le dataset contient une ligne d'entête.");has_header_line:int|_A=Field(default=_A,description="Numéro de la ligne d'entête. Si None, la première ligne non ignorée est considérée comme l'entête.");has_header_ignore:list[str]|_A=Field(default=_A,description="Chaînes de caractères à ignorer dans la ligne d'entête. eex: ['##', '|'].");column_widths:list[int]|_A=Field(default=_A,description='Liste des largeurs de colonnes. Ex: [9, 13, 12]. Exclusif avec `column_indexes`.');column_indexes:list[tuple[int,int]]|_A=Field(default=_A,description='Liste des index de début et fin de colonnes. Ex: [[0, 8], [9, 12], [13, 28]]. Exclusif avec `column_widths`.');curve_parser:ReaderColsCurveParserConfig|_A=Field(default=_A,description='Parseur de courbe à utiliser.')
|
scilens/config/models/readers.py
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
_B='netcdf'
|
|
2
|
-
_A='txt_fixed_cols'
|
|
3
1
|
from typing import Literal
|
|
4
|
-
from pydantic import BaseModel,Field
|
|
2
|
+
from pydantic import BaseModel,Field
|
|
5
3
|
from scilens.config.models.reader_format_txt import ReaderTxtConfig
|
|
6
4
|
from scilens.config.models.reader_format_csv import ReaderCsvConfig
|
|
7
5
|
from scilens.config.models.reader_format_txt_fixed_cols import ReaderTxtFixedColsConfig
|
|
8
6
|
from scilens.config.models.reader_format_netcdf import ReaderNetcdfConfig
|
|
9
|
-
|
|
10
|
-
class
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return A
|
|
17
|
-
class ReadersConfig(BaseModel):txt:ReaderTxtConfig=Field(default=ReaderTxtConfig(),description='Configuration des readers txt.');csv:ReaderCsvConfig=Field(default=ReaderCsvConfig(),description='Configuration des readers csv.');txt_fixed_cols:ReaderTxtFixedColsConfig=Field(default=ReaderTxtFixedColsConfig(),description='Configuration des readers txt avec colonnes fixes.');netcdf:ReaderNetcdfConfig=Field(default=ReaderNetcdfConfig(),description='Configuration des readers NetCDF.');catalog:dict[str,ReaderConfig]|None=Field(default=None,description="Catalogue de configuration de readers par clé. Ex: `{'csv_comma': {'type': 'csv', 'parameters': {'delimiter': ','}}, 'csv_semicolon': {'type': 'csv', 'parameters': {'delimiter': ';'}}}`")
|
|
7
|
+
class BaseCatalogItem(BaseModel):type:str
|
|
8
|
+
class ReaderTxtConfigItem(BaseCatalogItem):type:Literal['txt'];parameters:ReaderTxtConfig
|
|
9
|
+
class ReaderCsvConfigItem(BaseCatalogItem):type:Literal['csv'];parameters:ReaderCsvConfig
|
|
10
|
+
class ReaderTxtFixedColsConfigItem(BaseCatalogItem):type:Literal['txt_fixed_cols'];parameters:ReaderTxtFixedColsConfig
|
|
11
|
+
class ReaderNetcdfConfigItem(BaseCatalogItem):type:Literal['netcdf'];parameters:ReaderNetcdfConfig
|
|
12
|
+
CATALOG_ITEM_TYPE=ReaderTxtConfigItem|ReaderCsvConfigItem|ReaderTxtFixedColsConfigItem|ReaderNetcdfConfigItem
|
|
13
|
+
class ReadersConfig(BaseModel):txt:ReaderTxtConfig=Field(default=ReaderTxtConfig(),description='Configuration des readers txt.');csv:ReaderCsvConfig=Field(default=ReaderCsvConfig(),description='Configuration des readers csv.');txt_fixed_cols:ReaderTxtFixedColsConfig=Field(default=ReaderTxtFixedColsConfig(),description='Configuration des readers txt avec colonnes fixes.');netcdf:ReaderNetcdfConfig=Field(default=ReaderNetcdfConfig(),description='Configuration des readers NetCDF.');catalog:dict[str,CATALOG_ITEM_TYPE]|None=Field(default=None,description="Catalogue de configuration de readers par clé. Ex: `{'csv_comma': {'type': 'csv', 'parameters': {'delimiter': ','}}, 'csv_semicolon': {'type': 'csv', 'parameters': {'delimiter': ';'}}}`")
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
_D="Paramètre modifiable par l'utilisateur"
|
|
2
|
+
_C=False
|
|
2
3
|
_B=True
|
|
3
4
|
_A=None
|
|
4
5
|
from pydantic import BaseModel,Field
|
|
5
|
-
class ReportParameterPageModeConfig(BaseModel):is_user_preference:bool=Field(default=_B,description=
|
|
6
|
-
class ReportParameterOpenFileInConfig(BaseModel):is_user_preference:bool=Field(default=_B,description=
|
|
7
|
-
class ReportHtmlCurvesConfig(BaseModel):display_on_load:bool=Field(default=
|
|
8
|
-
class
|
|
6
|
+
class ReportParameterPageModeConfig(BaseModel):is_user_preference:bool=Field(default=_B,description=_D);default_value:str=Field(default='onepage',description='`tabs` ou `onepage`')
|
|
7
|
+
class ReportParameterOpenFileInConfig(BaseModel):is_user_preference:bool=Field(default=_B,description=_D);default_value:str=Field(default='browser',description='`browser` ou `vscode`')
|
|
8
|
+
class ReportHtmlCurvesConfig(BaseModel):display_on_load:bool=Field(default=_C,description="Si `true`, affiche tous les graphiques courbes à l'ouverture du rapport.");init_width:int=Field(default=600,description='Largeur initiale des graphiques courbes.');init_height:int=Field(default=400,description='Hauteur initiale des graphiques courbes.');compare_vs_values:bool=Field(default=_B,description='Dans le chart de comparaison, affiche les valeurs de référence et de test.');compare_vs_difference:bool=Field(default=_C,description='Dans le chart de comparaison, affiche la différence entre les valeurs de référence et de test.')
|
|
9
|
+
class ReportHtmlSpectrogramsConfig(BaseModel):test_ref:bool=Field(default=_B,description='Indique si les spectrogrammes de test doivent être affichés.');differences:bool=Field(default=_B,description='Indique si les spectrogrammes de différence doivent être affichés.');init_width:int=Field(default=300,description='Largeur initiale des spectrogrammes.');init_height:int=Field(default=300,description='Hauteur initiale des spectrogrammes.')
|
|
10
|
+
class ReportHtmlMatrixConfig(BaseModel):spectrograms:ReportHtmlSpectrogramsConfig|_A=_A;frameseries:bool=Field(default=_C,description='Indique si les matrices doivent être affichées en mode frameseries.')
|
|
11
|
+
class ReportHtmlConfig(BaseModel):custom_style:str|_A=Field(default=_A,description='CSS personnalisé.');custom_script_head:str|_A=Field(default=_A,description='Script personnalisé dans le `<head>`.');custom_script_body:str|_A=Field(default=_A,description='Script personnalisé en fin de `<body>`.');extra_html_start:str|_A=Field(default=_A,description='HTML personnalisé en début de rapport.');extra_html_summary:str|_A=Field(default=_A,description='HTML personnalisé dans la section `Summary`.');extra_html_end:str|_A=Field(default=_A,description='HTML personnalisé en fin de rapport.');logo_height:int=Field(default=40,description='Hauteur du logo dans le titre.');compare_color_test:str=Field(default='1982c4',description='Couleur pour les données de test.');compare_color_reference:str=Field(default='6a4c93',description='Couleur pour les données de référence.');collapse_if_successful:bool=Field(default=_B,description="N'affiche par défaut les sections de comparaison sans erreur.");parameter_page_mode:ReportParameterPageModeConfig=ReportParameterPageModeConfig();parameter_open_file_in:ReportParameterOpenFileInConfig=ReportParameterOpenFileInConfig();curves:ReportHtmlCurvesConfig=ReportHtmlCurvesConfig();matrix:ReportHtmlMatrixConfig=ReportHtmlMatrixConfig()
|
|
@@ -11,7 +11,7 @@ class ExecuteAndCompare:
|
|
|
11
11
|
if not F.test_only:G.append({I:'reference',J:N,B:F.reference})
|
|
12
12
|
for A in G:
|
|
13
13
|
if not A[B]:C=D
|
|
14
|
-
else:C=ExecuteConfig();C.pre_folder_delete=A[B].pre_folder_delete or D.pre_folder_delete;C.pre_folder_creation=A[B].pre_folder_creation or D.pre_folder_creation;C.exe_path=A[B].exe_path or D.exe_path;C.exe_url=A[B].exe_url or D.exe_url;C.exe_command=A[B].exe_command or D.exe_command;C.exe_url_headers=A[B].exe_url_headers or D.exe_url_headers;C.exe_unzip_and_use=A[B].exe_unzip_and_use or D.exe_unzip_and_use;C.exe_guess_os_extension=A[B].exe_guess_os_extension or D.exe_guess_os_extension;C.command_suffix=A[B].command_suffix or D.command_suffix
|
|
14
|
+
else:C=ExecuteConfig();C.pre_files_delete=A[B].pre_files_delete or D.pre_files_delete;C.pre_folder_delete=A[B].pre_folder_delete or D.pre_folder_delete;C.pre_folder_creation=A[B].pre_folder_creation or D.pre_folder_creation;C.exe_path=A[B].exe_path or D.exe_path;C.exe_url=A[B].exe_url or D.exe_url;C.exe_command=A[B].exe_command or D.exe_command;C.exe_url_headers=A[B].exe_url_headers or D.exe_url_headers;C.exe_unzip_and_use=A[B].exe_unzip_and_use or D.exe_unzip_and_use;C.exe_guess_os_extension=A[B].exe_guess_os_extension or D.exe_guess_os_extension;C.command_suffix=A[B].command_suffix or D.command_suffix
|
|
15
15
|
logging.info(f"Execute {A[I]} Command")
|
|
16
|
-
with Executor(A[J],C,alternative_working_dir=E.context.origin_working_dir)as O:O.process()
|
|
16
|
+
with Executor(A[J],C,E.context.config_file,alternative_working_dir=E.context.origin_working_dir)as O:O.process()
|
|
17
17
|
G=E.compare_folders.compute_list_filenames();logging.info(f"Number files to compare: {len(G)}");K=E.compare_folders.compute_comparison(G);H.warnings=[A[L]for A in K if A.get(L)];H.data=K;return H
|
scilens/readers/mat_dataset.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
_B=False
|
|
2
1
|
_A=None
|
|
3
2
|
import csv
|
|
4
3
|
from collections.abc import Iterator
|
|
@@ -6,8 +5,8 @@ from dataclasses import dataclass,field,asdict
|
|
|
6
5
|
from scilens.components.compare_models import CompareGroup
|
|
7
6
|
from scilens.components.compare_floats import CompareFloats
|
|
8
7
|
@dataclass
|
|
9
|
-
class MatDataset:nb_lines:int=0;nb_columns:int=0;data:list[list[float]]=field(default_factory=lambda:[]);x_values:list[float]|_A=_A;y_values:list[float]|_A=_A
|
|
10
|
-
def
|
|
8
|
+
class MatDataset:x_name:str;y_name:str;nb_lines:int=0;nb_columns:int=0;data:list[list[float]]=field(default_factory=lambda:[]);x_values:list[float]|_A=_A;y_values:list[float]|_A=_A
|
|
9
|
+
def from_iterator(x_name,y_name,reader,x_value_line=_A,has_header=False,has_y=False):
|
|
11
10
|
E=has_y;D=x_value_line;B=reader;H=_A;I=[]if E else _A;A=[];F=0
|
|
12
11
|
if D:
|
|
13
12
|
J=1 if E else 0
|
|
@@ -19,14 +18,9 @@ def from_reader(reader,x_value_line=_A,has_header=_B,has_y=_B):
|
|
|
19
18
|
for C in B:L=float(C[0]);G=[float(A)for A in C[1:]];I.append(L);A.append(G)
|
|
20
19
|
else:
|
|
21
20
|
for C in B:G=[float(A)for A in C];A.append(G)
|
|
22
|
-
return MatDataset(nb_lines=len(A),nb_columns=len(A[0])if len(A)>0 else 0,data=A,x_values=H,y_values=I)
|
|
21
|
+
return MatDataset(x_name=x_name,y_name=y_name,nb_lines=len(A),nb_columns=len(A[0])if len(A)>0 else 0,data=A,x_values=H,y_values=I)
|
|
23
22
|
def compare(parent_group,compare_floats,test,ref,group_name=''):B=parent_group;A=test;D,C,E=compare_floats.add_group_and_compare_matrices(group_name,B,group_data=_A,test_mat=A.data,ref_mat=ref.data,x_vector=A.x_values,y_vector=A.y_values);B.error='Errors limit reached'if C else _A
|
|
24
|
-
def get_data(datasets,names,
|
|
25
|
-
|
|
26
|
-
if len(
|
|
27
|
-
|
|
28
|
-
if display_spectrograms:A['spectrograms']={E:1}
|
|
29
|
-
if display_frameseries:
|
|
30
|
-
A[F]={E:1}
|
|
31
|
-
if D:A[F]['steps']={'name':frameseries_steps_name,'data':D}
|
|
32
|
-
return A
|
|
23
|
+
def get_data(datasets,names,frameseries_steps_data=_A,frameseries_steps_name=_A):
|
|
24
|
+
B=names;A=datasets
|
|
25
|
+
if len(A)!=len(B):raise ValueError('Datasets and names must have the same length')
|
|
26
|
+
C={'datasets':[asdict(A)for A in A],'names':B};return C
|
scilens/readers/reader_csv.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
_A=None
|
|
2
|
-
import logging,csv
|
|
2
|
+
import logging,csv,re
|
|
3
3
|
from scilens.readers.reader_interface import ReaderInterface
|
|
4
4
|
from scilens.readers.cols_dataset import ColsDataset,ColsCurves,cols_dataset_get_curves_col_x,compare as cols_compare
|
|
5
|
-
from scilens.readers.mat_dataset import MatDataset,
|
|
5
|
+
from scilens.readers.mat_dataset import MatDataset,from_iterator as mat_from_iterator,compare as mat_compare,get_data
|
|
6
6
|
from scilens.config.models.reader_format_csv import ReaderCsvConfig,ReaderCsvMatrixConfig
|
|
7
7
|
from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
|
|
8
8
|
from scilens.components.compare_models import CompareGroup
|
|
@@ -20,31 +20,37 @@ def csv_detect(path,delimiter,quotechar,encoding):
|
|
|
20
20
|
class ReaderCsv(ReaderInterface):
|
|
21
21
|
configuration_type_code='csv';category='datalines';extensions=['CSV']
|
|
22
22
|
def read(A,reader_options):
|
|
23
|
-
B=reader_options;A.reader_options=B;A.raw_lines_number=_A;A.curves=_A;A.report_matrices=_A;D,F,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
H
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
23
|
+
B=reader_options;A.reader_options=B;J=B.ignore_lines_patterns;A.raw_lines_number=_A;A.curves=_A;A.report_matrices=_A;D,F,P=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar,encoding=A.encoding);A.has_header=D;A.cols=F;A.numeric_col_indexes=P
|
|
24
|
+
with open(A.origin.path,'r',encoding=A.encoding)as Q:
|
|
25
|
+
K=Q.readlines();L=csv.reader(K,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar)
|
|
26
|
+
if B.is_matrix:
|
|
27
|
+
E=B.matrix or ReaderCsvMatrixConfig();G=mat_from_iterator(x_name=E.x_name,y_name=E.y_name,reader=L,has_header=D,x_value_line=E.x_value_line,has_y=E.has_y)
|
|
28
|
+
if E.export_report:A.report_matrices=get_data([G],['csv'])
|
|
29
|
+
A.mat_dataset=G;A.raw_lines_number=G.nb_lines+(1 if D else 0)
|
|
30
|
+
else:
|
|
31
|
+
if B.ignore_columns:
|
|
32
|
+
if not D:raise Exception('Ignore columns is not supported without header.')
|
|
33
|
+
A.numeric_col_indexes=[C for C in A.numeric_col_indexes if A.cols[C]not in B.ignore_columns]
|
|
34
|
+
M=len(F);C=ColsDataset(cols_count=M,names=F,numeric_col_indexes=A.numeric_col_indexes,data=[[]for A in range(M)]);H=0
|
|
35
|
+
for(R,S)in zip(K,L):
|
|
36
|
+
H+=1
|
|
37
|
+
if D and H==1:continue
|
|
38
|
+
if J:
|
|
39
|
+
N=False
|
|
40
|
+
for T in J:
|
|
41
|
+
if bool(re.match(T,R)):N=True;break
|
|
42
|
+
if N:continue
|
|
43
|
+
for(O,I)in enumerate(S):
|
|
44
|
+
if O in C.numeric_col_indexes:I=float(I)
|
|
45
|
+
C.data[O].append(I)
|
|
46
|
+
C.origin_line_nb.append(H)
|
|
47
|
+
C.rows_count=len(C.origin_line_nb);A.cols_dataset=C;A.raw_lines_number=C.rows_count+(1 if D else 0)
|
|
48
|
+
if B.curve_parser:
|
|
49
|
+
if B.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
|
|
50
|
+
A.curves,U=cols_dataset_get_curves_col_x(C,B.curve_parser.parameters.x)
|
|
51
|
+
if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=U,curves=A.curves)
|
|
52
|
+
elif B.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
|
|
53
|
+
else:raise Exception('Curve parser not supported.')
|
|
48
54
|
def compare(A,compare_floats,param_reader,param_is_ref=True):
|
|
49
55
|
H='node';D=param_is_ref;C=param_reader;B=compare_floats;I=A.reader_options
|
|
50
56
|
if I.is_matrix:E=A.mat_dataset if D else C.mat_dataset;F=A.mat_dataset if not D else C.mat_dataset;J,G=B.compare_errors.add_group(H,'csv matrix');mat_compare(G,B,E,F)
|
|
@@ -1,38 +1,81 @@
|
|
|
1
|
+
_A=None
|
|
1
2
|
import logging,re
|
|
3
|
+
from dataclasses import dataclass
|
|
2
4
|
from scilens.readers.transform import string_2_float
|
|
3
5
|
from scilens.readers.reader_interface import ReaderInterface
|
|
4
6
|
from scilens.readers.cols_dataset import ColsDataset,ColsCurves,cols_dataset_get_curves_col_x,compare
|
|
5
7
|
from scilens.config.models import ReaderTxtFixedColsConfig
|
|
6
8
|
from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
|
|
7
9
|
from scilens.components.compare_floats import CompareFloats
|
|
10
|
+
@dataclass
|
|
11
|
+
class ParsedHeaders:raw:str;cleaned:str;data:list[str];ori_line_idx:int|_A=_A
|
|
8
12
|
class ReaderTxtFixedCols(ReaderInterface):
|
|
9
13
|
configuration_type_code='txt_fixed_cols';category='datalines';extensions=[]
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
def _ignore_line(A,line):
|
|
15
|
+
if not line.strip():return True
|
|
16
|
+
if A.reader_options.ignore_lines_patterns:
|
|
17
|
+
for B in A.reader_options.ignore_lines_patterns:
|
|
18
|
+
if bool(re.match(B,line)):return True
|
|
19
|
+
return False
|
|
20
|
+
def _get_parsed_headers(A,path):
|
|
21
|
+
B=A.reader_options;C=_A
|
|
22
|
+
with open(A.origin.path,'r',encoding=A.encoding)as G:
|
|
23
|
+
D=-1
|
|
24
|
+
if B.has_header_line is not _A:
|
|
25
|
+
for E in G:
|
|
26
|
+
D+=1
|
|
27
|
+
if D+1==B.has_header_line:C=E;break
|
|
28
|
+
else:
|
|
29
|
+
for E in G:
|
|
30
|
+
D+=1
|
|
31
|
+
if not A._ignore_line(E):C=E;break
|
|
32
|
+
if C:
|
|
33
|
+
H=C.strip();F=H
|
|
34
|
+
if B.has_header_ignore:
|
|
35
|
+
for I in B.has_header_ignore:F=F.replace(I,'')
|
|
36
|
+
return ParsedHeaders(raw=H,cleaned=F,data=F.split(),ori_line_idx=D)
|
|
37
|
+
def _get_first_data_line(A,path):
|
|
38
|
+
D=A.reader_options;B=D.has_header
|
|
39
|
+
with open(A.origin.path,'r',encoding=A.encoding)as E:
|
|
40
|
+
for C in E:
|
|
41
|
+
if not A._ignore_line(C):
|
|
42
|
+
if B:B=False;continue
|
|
43
|
+
else:return C
|
|
44
|
+
def _discover_col_idx_ralgin_spaces(G,line):
|
|
45
|
+
A=line;A=A.rstrip();C=[];D=_A;B=0
|
|
46
|
+
for(E,F)in enumerate(A):
|
|
47
|
+
if D is not _A and D!=' 'and F==' ':C.append((B,E));B=E
|
|
48
|
+
D=F
|
|
49
|
+
if B<len(A):C.append((B,len(A)))
|
|
50
|
+
return C
|
|
51
|
+
def _derive_col_indexes(A,header_row=_A):0
|
|
52
|
+
def read(A,reader_options):
|
|
53
|
+
B=reader_options;A.reader_options=B;E=A._get_parsed_headers(A.origin.path)if B.has_header else _A;I=open(A.origin.path,'r',encoding=A.encoding);C=[]
|
|
54
|
+
if B.column_indexes or B.column_widths:
|
|
55
|
+
if B.column_indexes and B.column_widths:raise Exception('column_indexes and column_widths are exclusive.')
|
|
56
|
+
if B.column_widths:
|
|
57
|
+
logging.debug(f"Using column widths: {B.column_widths}");H=0
|
|
58
|
+
for J in B.column_widths:C+=[(H,H+J)];H+=J
|
|
59
|
+
else:logging.debug(f"Using column indexes: {B.column_indexes}");C=B.column_indexes
|
|
60
|
+
else:logging.debug(f"Using auto derived column indexes.");M=A._get_first_data_line(A.origin.path);C=A._discover_col_idx_ralgin_spaces(M)
|
|
61
|
+
logging.debug(f"Column indexes: {C}")
|
|
62
|
+
if not C:raise Exception('No column indexes or widths provided, and no headers found to derive column indexes.')
|
|
63
|
+
F=len(C);D=ColsDataset(cols_count=F,names=[f"Column {A+1}"for A in range(F)],numeric_col_indexes=[A for A in range(F)],data=[[]for A in range(F)])
|
|
64
|
+
if E:D.names=E.data
|
|
65
|
+
G=0
|
|
66
|
+
for K in I:
|
|
13
67
|
G+=1
|
|
14
|
-
if
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
elif A.has_header_repetition and F==D.strip():continue
|
|
26
|
-
if not D.strip():continue
|
|
27
|
-
I=0;N=0
|
|
28
|
-
for O in K:R=D[I:I+O].strip();S=string_2_float(R);C.data[N].append(S);I+=O;N+=1
|
|
29
|
-
C.origin_line_nb.append(G)
|
|
30
|
-
C.rows_count=len(C.origin_line_nb);J.close();B.cols_dataset=C;B.raw_lines_number=G;B.curves=None
|
|
31
|
-
if A.curve_parser:
|
|
32
|
-
if A.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
|
|
33
|
-
B.curves,T=cols_dataset_get_curves_col_x(C,A.curve_parser.parameters.x)
|
|
34
|
-
if B.curves:B.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=T,curves=B.curves)
|
|
35
|
-
elif A.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
|
|
68
|
+
if A._ignore_line(K):continue
|
|
69
|
+
if E:
|
|
70
|
+
if E.ori_line_idx==G-1:continue
|
|
71
|
+
for(N,L)in enumerate(C):O=K[L[0]:L[1]].strip();P=string_2_float(O);D.data[N].append(P)
|
|
72
|
+
D.origin_line_nb.append(G)
|
|
73
|
+
D.rows_count=len(D.origin_line_nb);I.close();A.cols_dataset=D;A.raw_lines_number=G;A.curves=_A;A.cols_curve=_A
|
|
74
|
+
if B.curve_parser:
|
|
75
|
+
if B.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
|
|
76
|
+
A.curves,Q=cols_dataset_get_curves_col_x(D,B.curve_parser.parameters.x)
|
|
77
|
+
if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=Q,curves=A.curves)
|
|
78
|
+
elif B.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
|
|
36
79
|
else:raise Exception('Curve parser not supported.')
|
|
37
80
|
def compare(A,compare_floats,param_reader,param_is_ref=True):D=param_is_ref;C=param_reader;B=compare_floats;E=A.cols_dataset if D else C.cols_dataset;F=A.cols_dataset if not D else C.cols_dataset;G=A.cols_curve;I,H=B.compare_errors.add_group('node','txt cols');return compare(H,B,E,F,G)
|
|
38
81
|
def class_info(A):return{'cols':A.cols_dataset.names,'raw_lines_number':A.raw_lines_number,'curves':A.curves}
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
<!-- MATRICES -->
|
|
138
138
|
{% if file.test.matrices %}
|
|
139
139
|
{% for item in [{"id": "spectrograms", "label": "Spectrograms"}, {"id": "frameseries", "label": "Frameseries"}] %}
|
|
140
|
-
{% if
|
|
140
|
+
{% if meta.config.matrix[item.id] %}
|
|
141
141
|
<h3>{{ item.label }} <action data-command="toogle" data-args="{{ item.id }}_{{ file_index|string }}"></action></h3>
|
|
142
142
|
<div id="{{ item.id }}_{{ file_index }}" ></div>
|
|
143
143
|
{% endif %}
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
{% set ns.statuses = ns.statuses + ['SKIPPED' if file.skipped else ('ERROR' if file.error else ('WARNING' if file.comparison_errors and file.comparison_errors.error_nb > 0 else 'SUCCESS'))] %}
|
|
14
14
|
{% if file.test.matrices %}
|
|
15
15
|
{% set ns.has_matrices = true %}
|
|
16
|
-
{% if
|
|
17
|
-
{% if
|
|
16
|
+
{% if meta.config.matrix.spectrograms %}{% set ns.has_spectrograms = true %}{% endif %}
|
|
17
|
+
{% if meta.config.matrix.frameseries %}{% set ns.has_frameseries = true %}{% endif %}
|
|
18
18
|
{% endif %}
|
|
19
19
|
{% endfor %}
|
|
20
20
|
<html>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
<script>
|
|
29
29
|
|
|
30
|
-
((w_1, undef) => { w_1.None = undef; })(window); // for Python None = undef when templating
|
|
30
|
+
((w_1, undef) => { w_1.None = undef; w_1.True = true; ; w_1.False = false; })(window); // for Python None = undef when templating
|
|
31
31
|
{% include 'js_dom.js' %}
|
|
32
32
|
{% include 'js_palette.js' %}
|
|
33
33
|
|
|
@@ -38,7 +38,15 @@
|
|
|
38
38
|
{% include 'utils_compare_report_anim.js' %}
|
|
39
39
|
{% include 'utils_compare_report_framesseries.js' %}
|
|
40
40
|
|
|
41
|
-
{% if
|
|
41
|
+
{% if meta.config.matrix.spectrograms %}
|
|
42
|
+
{% include 'uti_spectrograms.js' %}
|
|
43
|
+
Spectrograms.config({
|
|
44
|
+
"DISPLAY_TESTREF": {{ meta.config.matrix.spectrograms.test_ref }},
|
|
45
|
+
"DISPLAY_DIFF": {{ meta.config.matrix.spectrograms.differences }},
|
|
46
|
+
"WIDTH": {{ meta.config.matrix.spectrograms.init_width }},
|
|
47
|
+
"HEIGHT": {{ meta.config.matrix.spectrograms.init_height }},
|
|
48
|
+
});
|
|
49
|
+
{% endif %}
|
|
42
50
|
{% if ns.has_matrices %}{% include 'uti_matrix.js' %}{% endif %}
|
|
43
51
|
|
|
44
52
|
</script>
|
|
@@ -127,7 +135,7 @@ function load_file_section(global_var, section_prefix, cls) {
|
|
|
127
135
|
test : [ {% for file in data.files %} {{ file.test.matrices or 'null' }} , {% endfor %} ],
|
|
128
136
|
reference : [ {% for file in data.files %} {{ file.ref.matrices or 'null' }} , {% endfor %} ],
|
|
129
137
|
};
|
|
130
|
-
MatrixMgmt.loadGlobal();
|
|
138
|
+
MatrixMgmt.loadGlobal({{ns.has_spectrograms}}, {{ns.has_frameseries}});
|
|
131
139
|
</script>
|
|
132
140
|
{% endif %}
|
|
133
141
|
{% if meta.config.custom_script_body %}<script>{{ meta.config.custom_script_body }}</script>{% endif %}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
if (item.special) {
|
|
22
22
|
switch (item.special) {
|
|
23
23
|
case 'diff':
|
|
24
|
-
yaxis2 = {title: 'Difference',overlaying: 'y',side: 'right'}
|
|
24
|
+
yaxis2 = {title: 'Difference',overlaying: 'y',side: 'right', color: 'rgba(255, 0, 0, 1)'}
|
|
25
25
|
serie.line.color = 'rgba(255, 0, 0, 0.5)';
|
|
26
26
|
serie.yaxis = 'y2';
|
|
27
27
|
serie.fill = 'tozeroy';
|
|
@@ -21,13 +21,18 @@ function subtractMatrices(A, B) {
|
|
|
21
21
|
row.map((v, j) => v - B[i][j])
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
|
+
function absolueMatrice(A) {
|
|
25
|
+
return A.map(row => row.map(v => Math.abs(v)));
|
|
26
|
+
}
|
|
24
27
|
//
|
|
25
28
|
class Matrix {
|
|
26
|
-
constructor(data, x, y, name, ref) {
|
|
29
|
+
constructor(data, x, y, name, x_name, y_name, ref) {
|
|
27
30
|
this.data = data; // Matrix data array[array[float]]
|
|
28
31
|
this.x = x; // X-axis values array[float]
|
|
29
32
|
this.y = y; // Y-axis values array[float]
|
|
30
33
|
this.name = name; // string
|
|
34
|
+
this.x_name = x_name; // X-axis Name
|
|
35
|
+
this.y_name = y_name; // Y-axis Name
|
|
31
36
|
this.ref = ref; // Reference matrix data (optional) array[array[float]]
|
|
32
37
|
// // Check if the matrix is valid (rectangular)
|
|
33
38
|
// const rowLength = data[0].length;
|
|
@@ -45,31 +50,39 @@ class Matrix {
|
|
|
45
50
|
// ) { throw new Error("Matrices must have the same dimensions."); }
|
|
46
51
|
return new Matrix(subtractMatrices(this.data, other.data), this.x, this.y, name);
|
|
47
52
|
}
|
|
48
|
-
|
|
49
|
-
return subtractMatrices(this.data, this.ref);
|
|
53
|
+
ref_diff_abs_data() {
|
|
54
|
+
return absolueMatrice(subtractMatrices(this.data, this.ref));
|
|
50
55
|
}
|
|
56
|
+
absolueMatrice
|
|
51
57
|
}
|
|
52
58
|
class MatrixGroup {
|
|
53
59
|
constructor(arr, is_spectro, is_frameseries, has_ref) {
|
|
54
60
|
this.arr = arr; // array of Matrix objects
|
|
55
|
-
this.is_spectro = is_spectro;
|
|
56
|
-
this.is_frameseries = is_frameseries;
|
|
57
61
|
this.has_ref = has_ref;
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
const MatrixMgmt = {
|
|
61
65
|
groups: [],
|
|
62
|
-
loadGlobal: function() {
|
|
66
|
+
loadGlobal: function(has_spectrograms, has_frameseries) {
|
|
63
67
|
// load loop GLOBAL_VARS groups
|
|
64
68
|
const g = GLOBAL_VARS.matrices;
|
|
65
69
|
g.test.forEach((data, i) => {
|
|
66
70
|
const group_data = [];
|
|
67
71
|
const ref = g.reference[i];
|
|
68
72
|
data.datasets.forEach((dataset, j) => {
|
|
69
|
-
|
|
73
|
+
console.log(dataset);
|
|
74
|
+
const mat = new Matrix(
|
|
75
|
+
dataset.data,
|
|
76
|
+
dataset.x_values,
|
|
77
|
+
dataset.y_values,
|
|
78
|
+
data.names[j],
|
|
79
|
+
dataset.x_name,
|
|
80
|
+
dataset.y_name,
|
|
81
|
+
ref.datasets[j].data,
|
|
82
|
+
);
|
|
70
83
|
group_data.push(mat);
|
|
71
84
|
});
|
|
72
|
-
const group = new MatrixGroup(group_data,
|
|
85
|
+
const group = new MatrixGroup(group_data, true);
|
|
73
86
|
this.groups.push(group);
|
|
74
87
|
});
|
|
75
88
|
// IMPORTANT
|
|
@@ -78,7 +91,7 @@ const MatrixMgmt = {
|
|
|
78
91
|
// Init
|
|
79
92
|
this.groups.forEach((group, i) => {
|
|
80
93
|
// Init Spectrograms
|
|
81
|
-
if (
|
|
94
|
+
if (has_spectrograms) {
|
|
82
95
|
const spec = new Spectrograms(i, group.arr);
|
|
83
96
|
}
|
|
84
97
|
// Init Frameseries
|
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
//
|
|
5
5
|
function resize22(obj, parent, dir) { // ASSUMPTIONS : obj.size int, "js-plotly-plot"
|
|
6
6
|
// size
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const w = obj.size[0] + (dir * obj.size[0] * 0.1);
|
|
8
|
+
const h = obj.size[0] + (dir * obj.size[0] * 0.1);
|
|
9
|
+
obj.size = [w, h];
|
|
9
10
|
// update widgets
|
|
10
|
-
const update = { width:
|
|
11
|
+
const update = { width: w, height: h };
|
|
11
12
|
const nodes = dom.q(parent, ".js-plotly-plot");
|
|
12
13
|
nodes.forEach((node) => {
|
|
13
|
-
node.style.width =
|
|
14
|
-
node.style.height =
|
|
14
|
+
node.style.width = w + "px";
|
|
15
|
+
node.style.height = h + "px";
|
|
15
16
|
Plotly.relayout(node, update); // update plotly
|
|
16
17
|
});
|
|
17
18
|
}
|
|
@@ -19,15 +20,21 @@ function resize22(obj, parent, dir) { // ASSUMPTIONS : obj.size int, "js-plotly-
|
|
|
19
20
|
//
|
|
20
21
|
//
|
|
21
22
|
const PREFIX = "spectrograms_"; // section prefix
|
|
22
|
-
const DEFAULT_SIZE = 300;
|
|
23
23
|
const COLORSCALE = "Viridis"; // plotly
|
|
24
24
|
const COLORSCALE_DIFF = "RdBu"; // plotly
|
|
25
|
+
const CFG = {
|
|
26
|
+
"DISPLAY_TESTREF": true, // display test reference
|
|
27
|
+
"DISPLAY_DIFF": true, // display diff
|
|
28
|
+
"WIDTH": 300, // default width
|
|
29
|
+
"HEIGHT": 300, // default height
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
//
|
|
26
33
|
class Spectrograms {
|
|
27
34
|
constructor(index, arr_mat) {
|
|
28
|
-
console.log("index data", index);
|
|
35
|
+
//console.log("index data", index);
|
|
29
36
|
// data
|
|
30
|
-
this.size =
|
|
37
|
+
this.size = [CFG.WIDTH, CFG.HEIGHT]; // default size
|
|
31
38
|
this.arr_mat = arr_mat;
|
|
32
39
|
this.elt = dom.get(PREFIX+(1+index));
|
|
33
40
|
// init
|
|
@@ -64,13 +71,14 @@ class Spectrograms {
|
|
|
64
71
|
var_add(idx) {
|
|
65
72
|
const mat = this.arr_mat[idx];
|
|
66
73
|
//
|
|
67
|
-
const style = "width:"+this.size+"px;height:"+this.size+"px;";
|
|
74
|
+
const style = "width:"+this.size[0]+"px;height:"+this.size[1]+"px;";
|
|
68
75
|
const attrs = { class: "m-1 shadow-lg" };
|
|
69
76
|
//
|
|
70
|
-
const templs = [
|
|
77
|
+
const templs = [];
|
|
78
|
+
if (CFG.DISPLAY_TESTREF) templs.push({out:"var", tag:"div", attrs: attrs, style:style});
|
|
71
79
|
if (mat.ref) {
|
|
72
|
-
templs.push({out:"ref", tag:"div", attrs: attrs, style:style});
|
|
73
|
-
templs.push({out:"dif", tag:"div", attrs: attrs, style:style});
|
|
80
|
+
if (CFG.DISPLAY_TESTREF) templs.push({out:"ref", tag:"div", attrs: attrs, style:style});
|
|
81
|
+
if (CFG.DISPLAY_DIFF) templs.push({out:"dif", tag:"div", attrs: attrs, style:style});
|
|
74
82
|
}
|
|
75
83
|
const e = {};
|
|
76
84
|
dom.tree(
|
|
@@ -81,30 +89,31 @@ class Spectrograms {
|
|
|
81
89
|
e
|
|
82
90
|
);
|
|
83
91
|
|
|
84
|
-
this.add_widget(e["var"], mat.data);
|
|
92
|
+
if (CFG.DISPLAY_TESTREF) this.add_widget(e["var"], mat, mat.data);
|
|
85
93
|
if (mat.ref) {
|
|
86
|
-
this.add_widget(e["ref"], mat.ref);
|
|
87
|
-
this.add_widget(e["dif"], mat.
|
|
94
|
+
if (CFG.DISPLAY_TESTREF) this.add_widget(e["ref"], mat, mat.ref, " - Ref.");
|
|
95
|
+
if (CFG.DISPLAY_DIFF) this.add_widget(e["dif"], mat, mat.ref_diff_abs_data(), " - Diff.", COLORSCALE_DIFF);
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
98
|
var_rmv(idx) {
|
|
91
99
|
dom.get(this.var_get_id(idx)).remove();
|
|
92
100
|
}
|
|
93
|
-
add_widget(elt, mat, colorscale=COLORSCALE) {
|
|
101
|
+
add_widget(elt, mat, matdata, suffix="", colorscale=COLORSCALE) {
|
|
94
102
|
const data = [{
|
|
95
|
-
z:
|
|
103
|
+
z: matdata,
|
|
96
104
|
type: 'heatmap',
|
|
97
105
|
colorscale: colorscale,
|
|
98
106
|
}];
|
|
99
107
|
|
|
100
108
|
const layout = {
|
|
101
|
-
|
|
102
|
-
xaxis: { title: 'X' },
|
|
103
|
-
yaxis: { title: 'Y' }
|
|
109
|
+
title: mat.name + suffix,
|
|
110
|
+
xaxis: { title: mat.x_name || 'X' },
|
|
111
|
+
yaxis: { title: mat.y_name || 'Y' },
|
|
104
112
|
};
|
|
105
113
|
|
|
106
114
|
Plotly.newPlot(elt, data, layout);
|
|
107
115
|
}
|
|
108
116
|
}
|
|
117
|
+
Spectrograms.config = function(cfg) {for (k in cfg) {CFG[k] = cfg[k];}};
|
|
109
118
|
w_1.Spectrograms = Spectrograms;
|
|
110
119
|
})(window);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
((w_1, undef) => {
|
|
1
2
|
const Anim = function (elt, options, options_2) {
|
|
2
3
|
const that = this;
|
|
3
4
|
// options
|
|
@@ -70,4 +71,6 @@ update: function () {
|
|
|
70
71
|
};
|
|
71
72
|
Anim.create = function(parent, options, options_2) {
|
|
72
73
|
new Anim(parent, options, options_2)
|
|
73
|
-
}
|
|
74
|
+
}
|
|
75
|
+
w_1.Anim = Anim;
|
|
76
|
+
})(window);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
((w_1, undef) => {
|
|
1
2
|
const Framesseries = function (elt, data, data_ref) {
|
|
2
3
|
const that = this;
|
|
3
4
|
// data
|
|
@@ -21,7 +22,7 @@ const Framesseries = function (elt, data, data_ref) {
|
|
|
21
22
|
// steps
|
|
22
23
|
const steps = []
|
|
23
24
|
data.frames_steps_variable.data.forEach((e,i) => {
|
|
24
|
-
console.log(e)
|
|
25
|
+
// console.log(e)
|
|
25
26
|
steps.push({
|
|
26
27
|
start: e,
|
|
27
28
|
color: palette.get(i),
|
|
@@ -131,7 +132,7 @@ Framesseries.prototype = {
|
|
|
131
132
|
labels.push({label: "Step", val: step, max: steps.length, color: color, val2: val2})
|
|
132
133
|
}
|
|
133
134
|
// labels
|
|
134
|
-
console.log(labels)
|
|
135
|
+
// console.log(labels)
|
|
135
136
|
this.lab.innerHTML = labels.map(x => '<span style="padding:3px 5px;background-color:'+x.color+';"><b> ' + x.label + "</b> " + x.val + "/" + x.max + ( x.val2 ? " (" + x.val2 + ")" : "") +"</span>").join(" - ");
|
|
136
137
|
|
|
137
138
|
|
|
@@ -140,3 +141,5 @@ Framesseries.prototype = {
|
|
|
140
141
|
Framesseries.create = function(parent, options, options_2) {
|
|
141
142
|
new Framesseries(parent, options, options_2)
|
|
142
143
|
}
|
|
144
|
+
w_1.Framesseries = Framesseries;
|
|
145
|
+
})(window);
|
|
@@ -13,7 +13,7 @@ scilens/components/compare_errors.py,sha256=vGb4DWP89HMIeBm0dZU2nt-ksppAs_37xtCH
|
|
|
13
13
|
scilens/components/compare_floats.py,sha256=yYJZ_QpAZUhP1uwNtGshXQLIzKtki9ifCN3hd9AFj2U,5916
|
|
14
14
|
scilens/components/compare_folders.py,sha256=LZ1AuYxLVHMNbtXWXQrdms4vZgOQthvDy-8NFD_EFjc,2617
|
|
15
15
|
scilens/components/compare_models.py,sha256=SCPd747h_nd4ewZsqLB6CFr27v6q99NELJb-gpkdj0o,918
|
|
16
|
-
scilens/components/executor.py,sha256=
|
|
16
|
+
scilens/components/executor.py,sha256=PLeKolzPd4wPX8e6DdfOb0uHGky3DxTcKN9QtB6oe3Q,3712
|
|
17
17
|
scilens/components/file_reader.py,sha256=7SbKCqb4Co_pqAKX3wweYhqAcVkU7BDlT903sLd76Kc,1407
|
|
18
18
|
scilens/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
scilens/config/cli_run_options.py,sha256=Ls7yK5QDUPFbk73nbjGuPvuRbBRYw4Miag5ISpu3prg,281
|
|
@@ -23,17 +23,17 @@ scilens/config/models/__init__.py,sha256=eLCW1OLVINewGFy5GXSrOk8Rab_QsgKAuoErBjp
|
|
|
23
23
|
scilens/config/models/app.py,sha256=JltWRjjqXYkH6rg3OHYhMfkBqHFhZEZdthqES3LxvzY,1453
|
|
24
24
|
scilens/config/models/compare.py,sha256=esRqW3PNVOqkA_mt4_qbS7dVCLulUrZTBUhANQOHoqE,1847
|
|
25
25
|
scilens/config/models/compare_float_thresholds.py,sha256=mHu48-70i3o_qUw6x-1A7XeRwFUNAO6WP6qNPGwAew0,2097
|
|
26
|
-
scilens/config/models/execute.py,sha256=
|
|
26
|
+
scilens/config/models/execute.py,sha256=Hx3DoDJ0fq7bZruqwtPtSKL6PVOF_LpsaDCLrn5klLk,2325
|
|
27
27
|
scilens/config/models/execute_and_compare.py,sha256=TWL6yXGvQSaaV6nhHqWLvtr3v396APIoDNt0U1TbMro,582
|
|
28
28
|
scilens/config/models/file_reader.py,sha256=c18vKhVcBX4ufpbnCBJyVyAsQtlxpwx0lGVuf1i8EGA,1176
|
|
29
29
|
scilens/config/models/reader_format_cols_curve.py,sha256=eKLvifq1xuN8sPds9ijfru3vgMZ3Odv5tGfeiK4Sfk4,1860
|
|
30
|
-
scilens/config/models/reader_format_csv.py,sha256=
|
|
30
|
+
scilens/config/models/reader_format_csv.py,sha256=EQ1nCYsv6Cf4rtK3AUW5LbJakRcutdaNSl4UN634evs,1708
|
|
31
31
|
scilens/config/models/reader_format_netcdf.py,sha256=k-AMdm239T6I42R8jzyRlPKKJ8zkRrN8XS8yU6ZkFu0,1256
|
|
32
32
|
scilens/config/models/reader_format_txt.py,sha256=eHg90gwEI_VpqwqEjMRhwlS8dHcl5G4ow-37HjQq_zY,1168
|
|
33
|
-
scilens/config/models/reader_format_txt_fixed_cols.py,sha256=
|
|
34
|
-
scilens/config/models/readers.py,sha256=
|
|
33
|
+
scilens/config/models/reader_format_txt_fixed_cols.py,sha256=SQ84OW9BLc5mr_TC6gQuYzzHJvrU-sVz223WOtAQMc0,1133
|
|
34
|
+
scilens/config/models/readers.py,sha256=oWdE4AkckvwN6boln55orq3hUeAt6S9IdQAZkGROR6E,1657
|
|
35
35
|
scilens/config/models/report.py,sha256=6mzqZMJnS_z5Rs01ISo8L8HRcWvmiQrK0dYqu8a58vM,993
|
|
36
|
-
scilens/config/models/report_html.py,sha256=
|
|
36
|
+
scilens/config/models/report_html.py,sha256=EqP42x6dupXzHzP4Ar7sP7mmZp1TqpUzgOYV-8FSoOk,3040
|
|
37
37
|
scilens/config/models/report_output.py,sha256=XoqUe-t-y8GRbUR3_bDwwaWf6hif-rZ-5pKDGdCMugw,875
|
|
38
38
|
scilens/helpers/assets.py,sha256=XphDA3-yE1PPKw4XFZhDrlLQjMZfGMlpOBXa8uy_xX0,1552
|
|
39
39
|
scilens/helpers/search_and_index.py,sha256=kXZ7124ra_SGAdKUZ7msy55UOWQ9dCSuPuNoU-NdUyM,1522
|
|
@@ -42,19 +42,19 @@ scilens/helpers/templates/style.css,sha256=2_IndKW2qtGhuoU9T3Sru4NkHR5CXTTs5_nc9
|
|
|
42
42
|
scilens/processors/__init__.py,sha256=x6bmqQVCcdJ7R2oG-_xTVtvl9qRleliEZlZR-Hq9Yc0,105
|
|
43
43
|
scilens/processors/analyse.py,sha256=hG2jALUqtoEwTPiLxDGV9Nbv6TU_SrfzwV_-1RkuiKw,828
|
|
44
44
|
scilens/processors/compare.py,sha256=wCdtDC8nJUeG9dolu2B6rTg4-jW0MYllPbvXFBX64nU,529
|
|
45
|
-
scilens/processors/execute_and_compare.py,sha256
|
|
45
|
+
scilens/processors/execute_and_compare.py,sha256=-JXnZewkza29L3TAsvaAuHTHRNG8biaKMFwpwdeCCbQ,1869
|
|
46
46
|
scilens/processors/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
47
|
scilens/processors/models/results.py,sha256=KoWxh13Zgi7PuPql8hkf4VjCis42ZxAuzIgJxBWVaX8,119
|
|
48
48
|
scilens/processors/processor_interface.py,sha256=jzMp1529JXnMGTJijVy6b_1zmARAMNv70f2lgys7vn4,452
|
|
49
49
|
scilens/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
50
|
scilens/readers/cols_dataset.py,sha256=C4N030_Iqq5KZVpQ0NVjAw4DctALuz_YBb6f6yi35Jk,2452
|
|
51
51
|
scilens/readers/exceptions.py,sha256=JzmxcjnR5sH-IOWVeCC5A1bSwxv-jCAtIJvDjzx1CTI,32
|
|
52
|
-
scilens/readers/mat_dataset.py,sha256=
|
|
53
|
-
scilens/readers/reader_csv.py,sha256=
|
|
52
|
+
scilens/readers/mat_dataset.py,sha256=Z9TYDWaH2aqdniLNDjlpR6VVNHMSARjh52clhdMyOn4,1496
|
|
53
|
+
scilens/readers/reader_csv.py,sha256=MXjGdNHm1i9phhYLeMuNFjCvxuIeZH_KNs6ni3a4nS8,3893
|
|
54
54
|
scilens/readers/reader_interface.py,sha256=nnttHL7wt4MOXpi-SBkk8DYxVWscOPG8JFl_z12mIAo,922
|
|
55
55
|
scilens/readers/reader_manager.py,sha256=DFinxIk3IIIcB6JxybGcv-mXt3jhXgCwUtzR0TqhB2Q,2684
|
|
56
56
|
scilens/readers/reader_txt.py,sha256=WPsFunEA_idzAKkD3UJQbLnaOzG2U03P3gY4gphuIw0,3868
|
|
57
|
-
scilens/readers/reader_txt_fixed_cols.py,sha256=
|
|
57
|
+
scilens/readers/reader_txt_fixed_cols.py,sha256=B7toE3G9KGcgD_p15jzGHOLGIKZ7KMmEQoTt6-4UtHo,4064
|
|
58
58
|
scilens/readers/transform.py,sha256=kppfgPkXymF0qtquFivuosLVfF66L9bE-wGx-3bMHv8,307
|
|
59
59
|
scilens/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
60
|
scilens/report/assets/logo.svg,sha256=W-1OVqcvdBjf-1AHHcV6WciIUqBoVFUh52Tc3o_jqtA,4519
|
|
@@ -67,22 +67,22 @@ scilens/report/templates/body_01_title.html,sha256=LJOWO6ImNPW9cg3tCDlgdllVTwnFG
|
|
|
67
67
|
scilens/report/templates/body_02_tabs.html,sha256=oOFslWcfNsWpCX12GECZDzdR5uAHE54HPP6IYUf7y0U,412
|
|
68
68
|
scilens/report/templates/body_99_footer.html,sha256=8cWebeWfZwZ-9bYAMZkZj8rbCWq3BLIMjKQThWQxoQM,362
|
|
69
69
|
scilens/report/templates/compare_11_summary.html,sha256=qVvFydtAvAYyVOOTqjTN3LUj5Lh_Cl680EYL5SCZkd4,4086
|
|
70
|
-
scilens/report/templates/compare_12_sections.html,sha256=
|
|
70
|
+
scilens/report/templates/compare_12_sections.html,sha256=EYYMqF2HeRXnWRke2vn9O2JCm8oKbx-r1NL7FJvYFDg,6431
|
|
71
71
|
scilens/report/templates/compare_13_section_numbers copy.html,sha256=0PWK_I2kNX3LjPLkkY4eSYIeB7YFkA28nk-PPLDhnaY,1753
|
|
72
72
|
scilens/report/templates/compare_13_section_numbers.html,sha256=9etEMSqwrDyJIn_nMbKEVaDgnFL_hBxSjPR-hU2wgDI,851
|
|
73
73
|
scilens/report/templates/compare_13_section_numbers_table.html,sha256=sJy6ZYtjl80vM1b3oqZSXawZWp7KNIwLI_wCnvBwYPE,3270
|
|
74
|
-
scilens/report/templates/index.html,sha256=
|
|
74
|
+
scilens/report/templates/index.html,sha256=fcC1jrG2nhmCSzXUV6fe14pRlNQ6CAgGRHMHhlx6nNg,5757
|
|
75
75
|
scilens/report/templates/js_chartlibs_echarts.js,sha256=6YicVhTNIBmmBpV31XCVN5oBeiD0t29JIosJZRUv01M,907
|
|
76
|
-
scilens/report/templates/js_chartlibs_plotly.js,sha256=
|
|
77
|
-
scilens/report/templates/js_com_page.js,sha256=
|
|
78
|
-
scilens/report/templates/js_curvemgr.js,sha256=
|
|
76
|
+
scilens/report/templates/js_chartlibs_plotly.js,sha256=3uiQfbd95NMN-3N2NX3c4CC7zFb0JRtH-ZzezDVGeO8,2111
|
|
77
|
+
scilens/report/templates/js_com_page.js,sha256=Q-_Smn77IYIAdlrS1zJtsVIYBOL1t-J1AYYJKji4eL0,6864
|
|
78
|
+
scilens/report/templates/js_curvemgr.js,sha256=gnRLO6HbZOMLIBQKjVhV2PciqXtuNKxpGx4boijV2Qc,12175
|
|
79
79
|
scilens/report/templates/js_dom.js,sha256=XnxgdB0x-Xtt0eQFrwjcFO1cb_KPsTImpJBB6m_y8FI,1229
|
|
80
80
|
scilens/report/templates/js_palette.js,sha256=HeewAmkR67QiqXSanJS3cCgp6IPKomlULUTKt55F6es,218
|
|
81
81
|
scilens/report/templates/style.css,sha256=SOKxdCqoj0yBt2zt3g1RkYx4ZV0_9PhGtO-TDWjmSHE,4217
|
|
82
|
-
scilens/report/templates/uti_matrix.js,sha256=
|
|
83
|
-
scilens/report/templates/uti_spectrograms.js,sha256=
|
|
84
|
-
scilens/report/templates/utils_compare_report_anim.js,sha256=
|
|
85
|
-
scilens/report/templates/utils_compare_report_framesseries.js,sha256=
|
|
82
|
+
scilens/report/templates/uti_matrix.js,sha256=N2fNH_E3Km6H60IOW-BjL0LIKTuJ2eGIHnJV_O354es,2936
|
|
83
|
+
scilens/report/templates/uti_spectrograms.js,sha256=WYnNt5d8aGIeUCXy8q3MWRtpJzr4htMiH-mlxXpBeug,3586
|
|
84
|
+
scilens/report/templates/utils_compare_report_anim.js,sha256=6Yg1nQDrmAQSJzHtsmA0CO2Ng1ddiLIhrbKXSZAB-Ms,2971
|
|
85
|
+
scilens/report/templates/utils_compare_report_framesseries.js,sha256=kg5NDVJYL0dF2cwdunD4WpnckvfGOsxXuO1ttmEV8hw,5766
|
|
86
86
|
scilens/report/vendors/tailwindcss_3_4_15.js,sha256=niHw6Rf0uS2pE5_8h-E18NI24o1urZL5Ac31_n9htKE,407279
|
|
87
87
|
scilens/report/vendors/tailwindcss_min_4.0.0-beta.4.js,sha256=fy2LOvMX7m4b1V9WdtWC0dCPNIYhE2cLkFiD3JNcYhI,177617
|
|
88
88
|
scilens/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -101,7 +101,7 @@ scilens/utils/template.py,sha256=9dlXX3nmfzDRUwzPJOkoxk15UXivZ2SW-McdCwokFa4,443
|
|
|
101
101
|
scilens/utils/time_tracker.py,sha256=DdVBoMpVLXrX0qZZXyLm4g38EwDVLlRcBqcpNex1mYY,545
|
|
102
102
|
scilens/utils/vectors.py,sha256=4N2BZSC5n3HgZqPujDGF5NdjVmSL1rOHb_qw4OoABQY,103
|
|
103
103
|
scilens/utils/web.py,sha256=MAFWpIFOKz7QhqDoFh-Qwstvc76KpcxstSgHFT8FOL4,901
|
|
104
|
-
scilens-0.3.
|
|
105
|
-
scilens-0.3.
|
|
106
|
-
scilens-0.3.
|
|
107
|
-
scilens-0.3.
|
|
104
|
+
scilens-0.3.9.dist-info/METADATA,sha256=ylBI_UDX3OeXxMTpfxODknkBUEFLGyE-_YU88jb6mn8,1367
|
|
105
|
+
scilens-0.3.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
106
|
+
scilens-0.3.9.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
|
|
107
|
+
scilens-0.3.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|