scilens 0.2.1__py3-none-any.whl → 0.3.0__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/compare_2_files.py +18 -14
- scilens/components/compare_errors.py +16 -15
- scilens/components/compare_floats.py +55 -33
- scilens/components/compare_models.py +20 -0
- scilens/components/file_reader.py +1 -0
- scilens/config/models/reader_format_csv.py +2 -1
- scilens/readers/cols_dataset.py +16 -14
- scilens/readers/mat_dataset.py +22 -0
- scilens/readers/reader_csv.py +34 -25
- scilens/readers/reader_txt.py +15 -16
- scilens/readers/reader_txt_fixed_cols.py +1 -1
- scilens/report/templates/compare_13_section_numbers.html +6 -87
- scilens/report/templates/compare_13_section_numbers_table.html +99 -0
- {scilens-0.2.1.dist-info → scilens-0.3.0.dist-info}/METADATA +1 -1
- {scilens-0.2.1.dist-info → scilens-0.3.0.dist-info}/RECORD +17 -16
- scilens/readers/reader_com_txt_lines.py +0 -2
- scilens/readers/reader_csv copy.py +0 -74
- {scilens-0.2.1.dist-info → scilens-0.3.0.dist-info}/WHEEL +0 -0
- {scilens-0.2.1.dist-info → scilens-0.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from scilens.run.task_context import TaskContext
|
|
3
|
+
from scilens.readers.reader_interface import ReaderInterface
|
|
3
4
|
from scilens.components.file_reader import FileReader
|
|
4
|
-
from scilens.components.
|
|
5
|
+
from scilens.components.compare_models import SEVERITY_ERROR
|
|
6
|
+
from scilens.components.compare_errors import CompareErrors
|
|
5
7
|
from scilens.components.compare_floats import CompareFloats
|
|
6
8
|
class Compare2Files:
|
|
7
9
|
def __init__(A,context):A.context=context
|
|
8
10
|
def compare(B,path_test,path_ref):
|
|
9
|
-
|
|
10
|
-
for(
|
|
11
|
-
if not
|
|
12
|
-
|
|
13
|
-
for(
|
|
14
|
-
C=D[
|
|
15
|
-
if not C or not
|
|
16
|
-
A[
|
|
17
|
-
if C.read_error:A[
|
|
18
|
-
|
|
19
|
-
if
|
|
20
|
-
|
|
21
|
-
if
|
|
11
|
+
R='comparison_errors';Q='comparison';N='reader';L='error';K='ref';J='test';F='path';A={J:{},K:{},Q:None,R:None};D={J:{F:path_test},K:{F:path_ref}}
|
|
12
|
+
for(M,G)in D.items():
|
|
13
|
+
if not G.get(F)or not os.path.exists(G[F]):A[L]=f"file {M} does not exist";return A
|
|
14
|
+
S=FileReader(B.context.working_dir,B.context.config.file_reader,B.context.config.readers,config_alternate_path=B.context.origin_working_dir)
|
|
15
|
+
for(M,G)in D.items():D[M][N]=S.read(G[F])
|
|
16
|
+
C=D[J][N];H=D[K][N]
|
|
17
|
+
if not C or not H:A['skipped']=True;return A
|
|
18
|
+
A[J]=C.info();A[K]=H.info()
|
|
19
|
+
if C.read_error:A[L]=C.read_error;return A
|
|
20
|
+
I=CompareErrors(B.context.config.compare.errors_limit,B.context.config.compare.ignore_warnings);T=CompareFloats(I,B.context.config.compare.float_thresholds);C.compare(T,H,param_is_ref=True);E=I.root_group;O={'total_diffs':E.total_diffs}
|
|
21
|
+
if E.info:O.update(E.info)
|
|
22
|
+
A[Q]=O;A[R]=I.get_data()
|
|
23
|
+
if E.error:A[L]=E.error;return A
|
|
24
|
+
C.close();H.close();P=len(I.errors[SEVERITY_ERROR])
|
|
25
|
+
if P>0:U=f"{P} comparison errors";A[L]=U
|
|
22
26
|
return A
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
_B=False
|
|
2
2
|
_A=None
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
class CompareErrFloats(BaseModel):is_relative:bool;value:float;test:float;reference:float
|
|
6
|
-
class CompareErr(BaseModel):err:CompareErrFloats|_A;msg:int;group:int|_A=_A;info:dict|_A=_A
|
|
7
|
-
SEVERITY_ERROR='error'
|
|
8
|
-
SEVERITY_WARNING='warning'
|
|
3
|
+
from dataclasses import asdict
|
|
4
|
+
from.compare_models import SEVERITY_ERROR,SEVERITY_WARNING,COMPARE_GROUP_TYPE,CompareGroup,CompareFloatsErr,CompareErr,Compare2ValuesResults
|
|
9
5
|
class CompareErrors:
|
|
10
|
-
def __init__(A,nb_max,ignore_warnings=_B):A.nb_max=nb_max;A.ignore_warnings=ignore_warnings;A.errors={SEVERITY_ERROR:[],SEVERITY_WARNING:[]};A.count=0;A.limit_reached=_B;A.messages=[];A.
|
|
11
|
-
def add_group(A,name,
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
def __init__(A,nb_max,ignore_warnings=_B):A.nb_max=nb_max;A.ignore_warnings=ignore_warnings;A.errors={SEVERITY_ERROR:[],SEVERITY_WARNING:[]};A.count=0;A.limit_reached=_B;A.root_group=_A;A.messages=[];A._messages_map={};A.groups=[]
|
|
7
|
+
def add_group(A,type,name,parent=_A,data=_A):
|
|
8
|
+
B=parent
|
|
9
|
+
if not A.root_group and B:raise Exception('No root group defined')
|
|
10
|
+
id=len(A.groups);C=CompareGroup(id=id,type=type,name=name,parent=B,data=data)
|
|
11
|
+
if not B:A.root_group=C
|
|
12
|
+
A.groups.append(C);return id,C
|
|
13
|
+
def add(A,group,comp_res,info=_A):
|
|
14
|
+
F=group;C=comp_res;D=C.severity;E=C.message;G=C.comp_err
|
|
14
15
|
if A.ignore_warnings and D==SEVERITY_WARNING:return _B
|
|
15
|
-
A.count+=1;B=A.
|
|
16
|
-
if B is _A:B=len(A.messages);A.messages.append(
|
|
17
|
-
A.errors[D].append(CompareErr(err=
|
|
16
|
+
A.count+=1;B=A._messages_map.get(E)
|
|
17
|
+
if B is _A:B=len(A.messages);A.messages.append(E);A._messages_map[E]=B
|
|
18
|
+
A.errors[D].append(CompareErr(err=G,msg=B,group=F.id,info=info));F.incr(D)
|
|
18
19
|
if A.count>=A.nb_max:A.limit_reached=True;return True
|
|
19
20
|
def get_data(B):
|
|
20
|
-
|
|
21
|
-
for(C,
|
|
21
|
+
D=[{'id':A.id,'type':A.type,'name':A.name,'error':A.error,'total_diffs':A.total_diffs,'total_warnings':A.total_warnings,'total_errors':A.total_errors,'data':A.data,'info':A.info,'parent_id':A.parent.id if A.parent else _A}for A in B.groups];A={'messages':B.messages,'groups':D}
|
|
22
|
+
for(C,E)in B.errors.items():A[C]=[A.model_dump()for A in E];A[C+'_nb']=len(A[C])
|
|
22
23
|
return A
|
|
@@ -1,50 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
_C='amplitude'
|
|
2
|
+
_B=False
|
|
2
3
|
_A=None
|
|
3
|
-
from scilens.components.
|
|
4
|
+
from scilens.components.compare_models import SEVERITY_ERROR,SEVERITY_WARNING,CompareFloatsErr,Compare2ValuesResults
|
|
5
|
+
from scilens.components.compare_errors import CompareErrors
|
|
4
6
|
from scilens.config.models import CompareFloatThresholdsConfig
|
|
5
7
|
try:from scilens_compare import vectors as CheckVectors
|
|
6
8
|
except ModuleNotFoundError:pass
|
|
7
|
-
def vector_get_amplitude(vector):min_val=min(vector);max_val=max(vector);return{'min':min_val,'max':max_val,
|
|
9
|
+
def vector_get_amplitude(vector):min_val=min(vector);max_val=max(vector);return{'min':min_val,'max':max_val,_C:abs(max_val-min_val)}
|
|
8
10
|
class CompareFloats:
|
|
9
11
|
def __init__(self,compare_errors,config):self.compare_errors=compare_errors;self.thresholds=config
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
if
|
|
12
|
+
def compare_2_values(self,test,reference):
|
|
13
|
+
thr=self.thresholds;sign=-1 if test-reference<0 else 1
|
|
14
|
+
if abs(test)>thr.relative_vs_absolute_min and reference!=0:
|
|
15
|
+
err=abs(test-reference)/abs(reference);comp_err=CompareFloatsErr(is_relative=True,value=sign*err,test=test,reference=reference)
|
|
16
|
+
if err<thr.relative_error_max:
|
|
17
|
+
if err>thr.relative_error_min:return Compare2ValuesResults(SEVERITY_WARNING,f"Rel. err. > {thr.relative_error_min} and < {thr.relative_error_max}",comp_err)
|
|
18
|
+
else:return Compare2ValuesResults(SEVERITY_ERROR,f"Rel. err. > {thr.relative_error_max}",comp_err)
|
|
19
|
+
else:
|
|
20
|
+
err=abs(test-reference);comp_err=CompareFloatsErr(is_relative=_B,value=sign*err,test=test,reference=reference)
|
|
21
|
+
if err<thr.absolute_error_max:
|
|
22
|
+
if err>thr.absolute_error_min:return Compare2ValuesResults(SEVERITY_WARNING,f"Abs. err. > {thr.absolute_error_min} and < {thr.absolute_error_max}",comp_err)
|
|
23
|
+
else:return Compare2ValuesResults(SEVERITY_ERROR,f"Abs. err. > {thr.absolute_error_max}",comp_err)
|
|
24
|
+
def compare_vectors(self,test_vector,reference_vector,group_id,info_vector=_A):
|
|
25
|
+
B='ignore';A='RIAE_trapezoid';group=self.compare_errors.groups[group_id]
|
|
26
|
+
if len(test_vector)!=len(reference_vector):raise Exception('Vectors have different lengths')
|
|
27
|
+
diffs_count=0;err_limit_reached=_B;ponderation_method=self.thresholds.vectors.ponderation_method
|
|
28
|
+
if ponderation_method=='RIAE':ponderation_method=A
|
|
29
|
+
amplitude_compare=_A
|
|
30
|
+
if self.thresholds.vectors and ponderation_method=='amplitude_moderation':amplitude=vector_get_amplitude(test_vector)[_C];amplitude_compare=amplitude*self.thresholds.vectors.amplitude_moderation_multiplier;reduction_method=self.thresholds.vectors.reduction_method
|
|
13
31
|
RIAE_force_severity=_A
|
|
14
|
-
if self.thresholds.vectors and
|
|
32
|
+
if self.thresholds.vectors and ponderation_method in[A,'RIAE_midpoint']:
|
|
15
33
|
RIAE_force_severity=self.thresholds.vectors.reduction_method
|
|
16
34
|
if'CheckVectors'not in globals():raise Exception('scilens_compare not found. Please install scilens-compare package with `pip install scilens-compare`.')
|
|
17
|
-
riae_error=CheckVectors.relative_integral_absolute_error_trapezoid(reference_vector,test_vector,range(len(test_vector)))
|
|
18
|
-
if riae_error
|
|
19
|
-
else:0
|
|
35
|
+
riae_error=CheckVectors.relative_integral_absolute_error_trapezoid(reference_vector,test_vector,range(len(test_vector)))if ponderation_method==A else CheckVectors.relative_integral_absolute_error_midpoint(reference_vector,test_vector,range(len(test_vector)))
|
|
36
|
+
if riae_error>self.thresholds.vectors.riae_threshold:ee=CompareFloatsErr(is_relative=_B,value=riae_error);res_compare=Compare2ValuesResults(SEVERITY_ERROR,f"RIAE ({ponderation_method}) > {self.thresholds.vectors.riae_threshold}",ee);err_limit_reached=self.compare_errors.add(group,res_compare)
|
|
20
37
|
nb=len(test_vector)
|
|
21
38
|
for idx in range(nb):
|
|
22
39
|
diff=test_vector[idx]-reference_vector[idx]
|
|
23
40
|
if diff==0:continue
|
|
24
|
-
else:diffs_count+=1
|
|
41
|
+
else:diffs_count+=1;group.incr('diff')
|
|
25
42
|
if err_limit_reached:continue
|
|
26
|
-
if RIAE_force_severity==
|
|
43
|
+
if RIAE_force_severity==B:continue
|
|
27
44
|
if amplitude_compare is not _A and abs(diff)<amplitude_compare:
|
|
28
|
-
if reduction_method==
|
|
29
|
-
elif reduction_method=='soften':
|
|
45
|
+
if reduction_method==B:continue
|
|
46
|
+
elif reduction_method=='soften':
|
|
47
|
+
res_compare=self.compare_2_values(test_vector[idx],reference_vector[idx])
|
|
48
|
+
if res_compare:res_compare.severity=SEVERITY_WARNING
|
|
30
49
|
else:
|
|
31
|
-
|
|
32
|
-
if RIAE_force_severity:severity=SEVERITY_WARNING
|
|
33
|
-
if
|
|
34
|
-
|
|
50
|
+
res_compare=self.compare_2_values(test_vector[idx],reference_vector[idx])
|
|
51
|
+
if res_compare and RIAE_force_severity:res_compare.severity=SEVERITY_WARNING
|
|
52
|
+
if res_compare:
|
|
53
|
+
info={'index':idx}
|
|
35
54
|
if info_vector:info['info']=info_vector[idx]
|
|
36
|
-
err_limit_reached=self.compare_errors.add(
|
|
37
|
-
return err_limit_reached,diffs_count
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
if
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
err_limit_reached=self.compare_errors.add(group,res_compare,info=info)
|
|
56
|
+
return err_limit_reached,diffs_count
|
|
57
|
+
def compare_matrices(self,test_mat,ref_mat,group_id,x_vector=_A,y_vector=_A):
|
|
58
|
+
group=self.compare_errors.groups[group_id];info={};diffs_count=0;err_limit_reached=_B;test_nb_lines=len(test_mat);test_nb_columns=len(test_mat[0])if test_nb_lines>0 else 0;ref_nb_lines=len(ref_mat);ref_nb_columns=len(ref_mat[0])if ref_nb_lines>0 else 0
|
|
59
|
+
if test_nb_lines!=ref_nb_lines or test_nb_columns!=ref_nb_columns:raise Exception('Matrices have different dimensions')
|
|
60
|
+
for i in range(test_nb_lines):
|
|
61
|
+
for j in range(test_nb_columns):
|
|
62
|
+
diff=test_mat[i][j]-ref_mat[i][j]
|
|
63
|
+
if diff==0:continue
|
|
64
|
+
else:diffs_count+=1
|
|
65
|
+
if err_limit_reached:continue
|
|
66
|
+
res_compare=self.compare_2_values(test_mat[i][j],ref_mat[i][j])
|
|
67
|
+
if res_compare:
|
|
68
|
+
info={'i':i+1,'j':j+1}
|
|
69
|
+
if x_vector:info['x']=x_vector[j]
|
|
70
|
+
if y_vector:info['y']=y_vector[i]
|
|
71
|
+
err_limit_reached=self.compare_errors.add(group,res_compare,info=info)
|
|
72
|
+
return err_limit_reached,diffs_count
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
_A=None
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Literal,Optional
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
SEVERITY_ERROR='error'
|
|
6
|
+
SEVERITY_WARNING='warning'
|
|
7
|
+
@dataclass
|
|
8
|
+
class CompareFloatsErr:is_relative:bool;value:float;test:float|_A=_A;reference:float|_A=_A
|
|
9
|
+
@dataclass
|
|
10
|
+
class Compare2ValuesResults:severity:str;message:str;comp_err:CompareFloatsErr|_A=_A
|
|
11
|
+
class CompareErr(BaseModel):err:CompareFloatsErr|_A;msg:int;group:int|_A=_A;info:dict|_A=_A
|
|
12
|
+
COMPARE_GROUP_TYPE=Literal['node','lines','vectors',' matrix']
|
|
13
|
+
@dataclass
|
|
14
|
+
class CompareGroup:
|
|
15
|
+
id:int;type:COMPARE_GROUP_TYPE;name:str;parent:Optional['CompareGroup']=_A;error:str|_A=_A;total_diffs:int=0;total_warnings:int=0;total_errors:int=0;data:dict|_A=_A;info:dict|_A=_A
|
|
16
|
+
def incr(A,type):
|
|
17
|
+
if type==SEVERITY_ERROR:A.total_errors+=1
|
|
18
|
+
elif type==SEVERITY_WARNING:A.total_warnings+=1
|
|
19
|
+
elif type=='diff':A.total_diffs+=1
|
|
20
|
+
if A.parent is not _A:A.parent.incr(type)
|
|
@@ -3,6 +3,7 @@ import logging,importlib,os
|
|
|
3
3
|
from scilens.config.models import FileReaderConfig
|
|
4
4
|
from scilens.config.models.readers import ReadersConfig
|
|
5
5
|
from scilens.readers.reader_manager import ReaderManager
|
|
6
|
+
from scilens.readers.reader_interface import ReaderInterface
|
|
6
7
|
from scilens.readers.exceptions import NoReaderFound
|
|
7
8
|
class FileReader:
|
|
8
9
|
def __init__(A,absolute_working_dir,config,readers_config,config_alternate_path=_A):A.path=absolute_working_dir;A.config_alternate_path=config_alternate_path;A.reader_mgmr=ReaderManager();A.config=config;A.readers_config=readers_config
|
|
@@ -1,4 +1,5 @@
|
|
|
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
|
|
4
|
+
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=False,description='Indique si la première colonne est ma colonne des valeurs y.')
|
|
5
|
+
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=False,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)')
|
scilens/readers/cols_dataset.py
CHANGED
|
@@ -3,7 +3,9 @@ _D='x_index'
|
|
|
3
3
|
_C='csv_col_index'
|
|
4
4
|
_B='curves'
|
|
5
5
|
_A=None
|
|
6
|
+
import logging
|
|
6
7
|
from dataclasses import dataclass,field
|
|
8
|
+
from scilens.components.compare_models import CompareGroup
|
|
7
9
|
from scilens.components.compare_floats import CompareFloats
|
|
8
10
|
from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
|
|
9
11
|
@dataclass
|
|
@@ -23,23 +25,23 @@ def cols_dataset_get_curves_col_x(cols_dataset,col_x):
|
|
|
23
25
|
E[_D]=C;J=[B for(A,B)in enumerate(A.numeric_col_indexes)if A!=C];F=[];H=[]
|
|
24
26
|
for D in J:B=A.data[C];K=A.data[D];L={I:A.names[D],'short_title':A.names[D],'series':[[B[A],K[A]]for A in range(A.rows_count)],_C:D};F+=[L];M={I:A.names[D],'type':'simple','xaxis':A.names[C],'yaxis':A.names[D],_B:[len(F)-1]};H+=[M]
|
|
25
27
|
return{_B:F,_E:H},E
|
|
26
|
-
def compare(compare_floats,reader_test,reader_ref,cols_curve):
|
|
27
|
-
|
|
28
|
-
if len(A.numeric_col_indexes)!=len(
|
|
29
|
-
|
|
30
|
-
if C and C.type==ReaderCurveParserNameConfig.COL_X:
|
|
31
|
-
|
|
28
|
+
def compare(group,compare_floats,reader_test,reader_ref,cols_curve):
|
|
29
|
+
L=compare_floats;K='Errors limit reached';G=reader_ref;E=group;C=cols_curve;A=reader_test;logging.debug(f"compare cols: {E.name}")
|
|
30
|
+
if len(A.numeric_col_indexes)!=len(G.numeric_col_indexes):E.error=f"Number Float columns indexes are different: {len(A.numeric_col_indexes)} != {len(G.numeric_col_indexes)}";return
|
|
31
|
+
D=[''for A in range(A.cols_count)];M=_A;H=_A
|
|
32
|
+
if C and C.type==ReaderCurveParserNameConfig.COL_X:N=C.info[_D];M=A.data[N];H=A.names[N]
|
|
33
|
+
I=False
|
|
32
34
|
for B in range(A.cols_count):
|
|
33
35
|
if B not in A.numeric_col_indexes:continue
|
|
34
|
-
if
|
|
35
|
-
|
|
36
|
-
if
|
|
37
|
-
if
|
|
36
|
+
if I:D[B]=K;continue
|
|
37
|
+
Q=A.data[B];R=G.data[B];U,F=L.compare_errors.add_group('vectors',A.names[B],parent=E,data={'info_prefix':H}if H else _A);logging.debug(f"compare cols: {F.name}");S,V=L.compare_vectors(Q,R,group_id=F.id,info_vector=M)
|
|
38
|
+
if S:I=True;D[B]=K;continue
|
|
39
|
+
if F.total_errors>0:D[B]=f"{F.total_errors} comparison errors"
|
|
38
40
|
if C:
|
|
39
41
|
for O in C.curves[_E]:
|
|
40
42
|
P=0
|
|
41
|
-
for
|
|
42
|
-
|
|
43
|
-
if D[
|
|
43
|
+
for T in O[_B]:
|
|
44
|
+
J=C.curves[_B][T]
|
|
45
|
+
if D[J[_C]]:J['comparison_error']=D[J[_C]];P+=1
|
|
44
46
|
O['comparison']={'curves_nb_with_error':P}
|
|
45
|
-
|
|
47
|
+
E.error=K if I else _A;E.info={'cols_has_error':D}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
_A=None
|
|
2
|
+
import csv
|
|
3
|
+
from collections.abc import Iterator
|
|
4
|
+
from dataclasses import dataclass,field
|
|
5
|
+
from scilens.components.compare_models import CompareGroup
|
|
6
|
+
from scilens.components.compare_floats import CompareFloats
|
|
7
|
+
@dataclass
|
|
8
|
+
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
|
|
9
|
+
def from_reader(reader,x_value_line=_A,has_header=False,has_y=False):
|
|
10
|
+
E=has_y;D=x_value_line;B=reader;H=_A;I=[]if E else _A;A=[];F=0
|
|
11
|
+
if D:
|
|
12
|
+
J=1 if E else 0
|
|
13
|
+
for M in range(0,D):
|
|
14
|
+
K=next(B);F+=1
|
|
15
|
+
if F==D:H=[float(A)for A in K[J:]]
|
|
16
|
+
if F==0 and has_header:next(B)
|
|
17
|
+
if E:
|
|
18
|
+
for C in B:L=float(C[0]);G=[float(A)for A in C[1:]];I.append(L);A.append(G)
|
|
19
|
+
else:
|
|
20
|
+
for C in B:G=[float(A)for A in C];A.append(G)
|
|
21
|
+
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)
|
|
22
|
+
def compare(parent_group,compare_floats,test,ref,group_name=''):C=compare_floats;B=parent_group;A=test;F,D=C.compare_errors.add_group('matrix',group_name,parent=B);E,G=C.compare_matrices(A.data,ref.data,D.id,x_vector=A.x_values,y_vector=A.y_values);B.error='Errors limit reached'if E else _A
|
scilens/readers/reader_csv.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
_A=None
|
|
1
2
|
import logging,csv
|
|
2
3
|
from scilens.readers.reader_interface import ReaderInterface
|
|
3
|
-
from scilens.readers.cols_dataset import ColsDataset,ColsCurves,cols_dataset_get_curves_col_x,compare
|
|
4
|
-
from scilens.
|
|
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,from_reader as mat_from_reader,compare as mat_compare
|
|
6
|
+
from scilens.config.models.reader_format_csv import ReaderCsvConfig,ReaderCsvMatrixConfig
|
|
5
7
|
from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
|
|
8
|
+
from scilens.components.compare_models import CompareGroup
|
|
6
9
|
from scilens.components.compare_floats import CompareFloats
|
|
7
10
|
def is_num(x):
|
|
8
11
|
try:return float(x)
|
|
@@ -11,30 +14,36 @@ def csv_row_detect_header(first_row):
|
|
|
11
14
|
A=first_row
|
|
12
15
|
if all(not A.isdigit()for A in A):return True,A
|
|
13
16
|
else:return False,[f"Column {A}"for(A,B)in enumerate(A)]
|
|
14
|
-
def csv_row_detect_cols_num(row):return[A for(A,B)in enumerate(row)if is_num(B)!=
|
|
15
|
-
def csv_detect(path,delimiter,quotechar):
|
|
16
|
-
with open(path,'r')as B:A=csv.reader(B,delimiter=delimiter,quotechar=quotechar);C=next(A);D,E=csv_row_detect_header(C);F=next(A);G=csv_row_detect_cols_num(F);return D,E,G
|
|
17
|
+
def csv_row_detect_cols_num(row):return[A for(A,B)in enumerate(row)if is_num(B)!=_A]
|
|
18
|
+
def csv_detect(path,delimiter,quotechar,encoding):
|
|
19
|
+
with open(path,'r',encoding=encoding)as B:A=csv.reader(B,delimiter=delimiter,quotechar=quotechar);C=next(A);D,E=csv_row_detect_header(C);F=next(A);G=csv_row_detect_cols_num(F);return D,E,G
|
|
17
20
|
class ReaderCsv(ReaderInterface):
|
|
18
21
|
configuration_type_code='csv';category='datalines';extensions=['CSV']
|
|
19
22
|
def read(A,reader_options):
|
|
20
|
-
|
|
21
|
-
if
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
F
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
B=reader_options;A.reader_options=B;A.raw_lines_number=_A;A.curves=_A;D,E,M=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar,encoding=A.encoding);A.has_header=D;A.cols=E;A.numeric_col_indexes=M;H=open(A.origin.path,'r',encoding=A.encoding);I=csv.reader(H,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar)
|
|
24
|
+
if B.is_matrix:J=B.matrix or ReaderCsvMatrixConfig();N=mat_from_reader(I,has_header=D,x_value_line=J.x_value_line,has_y=J.has_y);A.mat_dataset=N
|
|
25
|
+
else:
|
|
26
|
+
if B.ignore_columns:
|
|
27
|
+
if not D:raise Exception('Ignore columns is not supported without header.')
|
|
28
|
+
A.numeric_col_indexes=[C for C in A.numeric_col_indexes if A.cols[C]not in B.ignore_columns]
|
|
29
|
+
K=len(E);C=ColsDataset(cols_count=K,names=E,numeric_col_indexes=A.numeric_col_indexes,data=[[]for A in range(K)]);F=0
|
|
30
|
+
for O in I:
|
|
31
|
+
F+=1
|
|
32
|
+
if D and F==1:continue
|
|
33
|
+
for(L,G)in enumerate(O):
|
|
34
|
+
if L in C.numeric_col_indexes:G=float(G)
|
|
35
|
+
C.data[L].append(G)
|
|
36
|
+
C.origin_line_nb.append(F)
|
|
37
|
+
C.rows_count=len(C.origin_line_nb);A.cols_dataset=C;A.raw_lines_number=C.rows_count+(1 if D else 0)
|
|
38
|
+
if B.curve_parser:
|
|
39
|
+
if B.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
|
|
40
|
+
A.curves,P=cols_dataset_get_curves_col_x(C,B.curve_parser.parameters.x)
|
|
41
|
+
if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=P,curves=A.curves)
|
|
42
|
+
elif B.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
|
|
43
|
+
else:raise Exception('Curve parser not supported.')
|
|
44
|
+
H.close()
|
|
45
|
+
def compare(A,compare_floats,param_reader,param_is_ref=True):
|
|
46
|
+
H='node';D=param_is_ref;C=param_reader;B=compare_floats;I=A.reader_options
|
|
47
|
+
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)
|
|
48
|
+
else:E=A.cols_dataset if D else C.cols_dataset;F=A.cols_dataset if not D else C.cols_dataset;K=A.cols_curve if hasattr(A,'cols_curve')else _A;J,G=B.compare_errors.add_group(H,'csv cols');cols_compare(G,B,E,F,K)
|
|
40
49
|
def class_info(A):return{'cols':A.cols,'raw_lines_number':A.raw_lines_number,'curves':A.curves}
|
scilens/readers/reader_txt.py
CHANGED
|
@@ -7,7 +7,7 @@ _A=None
|
|
|
7
7
|
from scilens.readers.reader_interface import ReaderInterface
|
|
8
8
|
from scilens.readers.transform import string_2_floats
|
|
9
9
|
from scilens.config.models import ReaderTxtConfig
|
|
10
|
-
from scilens.components.
|
|
10
|
+
from scilens.components.compare_models import SEVERITY_ERROR,Compare2ValuesResults
|
|
11
11
|
from scilens.components.compare_floats import CompareFloats
|
|
12
12
|
class ReaderTxt(ReaderInterface):
|
|
13
13
|
configuration_type_code='txt';category='datalines';extensions=['TXT']
|
|
@@ -42,23 +42,22 @@ class ReaderTxt(ReaderInterface):
|
|
|
42
42
|
C,S=A.find_patterns_lines_nb(B.error_rule_patterns);A.read_data['error_rule_patterns']={'found':C,'data':S}
|
|
43
43
|
if C:A.read_error='String error pattern found'
|
|
44
44
|
def compare(I,compare_floats,param_reader,param_is_ref=_D):
|
|
45
|
-
K=param_is_ref;J=param_reader;
|
|
46
|
-
if
|
|
47
|
-
|
|
48
|
-
for
|
|
49
|
-
F=
|
|
50
|
-
if len(H)!=len(
|
|
51
|
-
if not
|
|
45
|
+
U='diff';K=param_is_ref;J=param_reader;A=compare_floats;V,L=A.compare_errors.add_group('node','txt');V,B=A.compare_errors.add_group(_E,_E,parent=L);C=I if K else J;D=I if not K else J;E=_C
|
|
46
|
+
if C.floats_lines_number!=D.floats_lines_number:L.error=f"Nb number lines 1: {C.floats_lines_number} 2: {D.floats_lines_number} different"
|
|
47
|
+
M=C.floats_lines;W=D.floats_lines
|
|
48
|
+
for N in range(len(M)):
|
|
49
|
+
F=M[N];G=W[N];H=F[_F];O=G[_F];P={'line_nb_1':F[_B],'line_nb_2':G[_B],'line_1':C.get_raw_lines(F[_B]),'line_2':D.get_raw_lines(G[_B])}
|
|
50
|
+
if len(H)!=len(O):
|
|
51
|
+
if not E:B.incr(U);E=A.compare_errors.add(B,Compare2ValuesResults(SEVERITY_ERROR,'Not same numbers number in the lines'),info=P)
|
|
52
52
|
continue
|
|
53
|
-
for
|
|
54
|
-
|
|
55
|
-
if
|
|
53
|
+
for Q in range(len(H)):
|
|
54
|
+
R=H[Q];S=O[Q];X=R-S
|
|
55
|
+
if X==0:continue
|
|
56
56
|
else:
|
|
57
|
-
|
|
58
|
-
if not
|
|
59
|
-
|
|
60
|
-
if
|
|
61
|
-
return _A,{'type':_E,'total_diffs':E}
|
|
57
|
+
B.incr(U)
|
|
58
|
+
if not E:
|
|
59
|
+
T=A.compare_2_values(R,S)
|
|
60
|
+
if T:E=A.compare_errors.add(B,T,info=P)
|
|
62
61
|
def find_patterns_lines_nb(D,patterns):
|
|
63
62
|
A=patterns;B=_C;map={A:[]for A in A}
|
|
64
63
|
for(E,F)in enumerate(D.raw_lines):
|
|
@@ -34,5 +34,5 @@ class ReaderTxtFixedCols(ReaderInterface):
|
|
|
34
34
|
if B.curves:B.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=T,curves=B.curves)
|
|
35
35
|
elif A.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
|
|
36
36
|
else:raise Exception('Curve parser not supported.')
|
|
37
|
-
def compare(A,compare_floats,param_reader,param_is_ref=True):
|
|
37
|
+
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
38
|
def class_info(A):return{'cols':A.cols_dataset.names,'raw_lines_number':A.raw_lines_number,'curves':A.curves}
|
|
@@ -1,93 +1,12 @@
|
|
|
1
1
|
{% if file.comparison_errors %}
|
|
2
|
-
{%
|
|
3
|
-
{% set c_type = file.comparison.type %}
|
|
4
|
-
<table>
|
|
5
|
-
<tr>
|
|
6
|
-
<th class="p-2" colspan="6">Error</th>
|
|
7
|
-
<th class="p-2" colspan="99">Source</th>
|
|
8
|
-
</tr>
|
|
9
|
-
<tr>
|
|
10
|
-
<th class="p-2" rowspan="2">Severity</th>
|
|
11
|
-
<th class="p-2" rowspan="2">Message</th>
|
|
12
|
-
<th class="p-2" colspan="2">Value</th>
|
|
13
|
-
<th class="p-2" rowspan="2">Error</th>
|
|
14
|
-
<th class="p-2" rowspan="2">Visu</th>
|
|
2
|
+
{% for group in file.comparison_errors.groups if group.type != 'node' %}
|
|
15
3
|
|
|
16
|
-
|
|
17
|
-
<th class="p-2" colspan="2">Line Number</th>
|
|
18
|
-
<th class="p-2" colspan="2">Line(s)</th>
|
|
19
|
-
{% endif %}
|
|
4
|
+
{% if group.total_warnings or group.total_errors %}
|
|
20
5
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<th class="p-2" rowspan="2">Index</th>
|
|
24
|
-
<th class="p-2" rowspan="2">Info</th>
|
|
25
|
-
{% endif %}
|
|
6
|
+
<h4>{{ group.name }}</h4>
|
|
7
|
+
{% include 'compare_13_section_numbers_table.html' with context %}
|
|
26
8
|
|
|
27
|
-
|
|
28
|
-
<tr>
|
|
29
|
-
<th class="p-2 test-bg-50">Test</th>
|
|
30
|
-
<th class="p-2 refe-bg-50">Ref.</th>
|
|
31
|
-
|
|
32
|
-
{% if c_type == "lines" %}
|
|
33
|
-
<th class="p-2 test-bg-50">Test</th>
|
|
34
|
-
<th class="p-2 refe-bg-50">Ref.</th>
|
|
35
|
-
<th class="p-2 test-bg-50">Test</th>
|
|
36
|
-
<th class="p-2 refe-bg-50">Ref.</th>
|
|
37
|
-
{% endif %}
|
|
38
|
-
|
|
39
|
-
</tr>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{% for error_type in [{"data_key": "error", "class": "ERROR"}, {"data_key": "warning", "class": "WARNING"}] %}
|
|
43
|
-
{% for item in errs[error_type.data_key] %}
|
|
44
|
-
<tr>
|
|
45
|
-
|
|
46
|
-
<td class="{{error_type.class}}">{{error_type.class}}</td>
|
|
47
|
-
<td>{{ errs.messages[item.msg] }}</td>
|
|
48
|
-
|
|
49
|
-
<!-- COMPARISON -->
|
|
50
|
-
|
|
51
|
-
<td class="number test-bg-20">{{ item.err.test }}</td>
|
|
52
|
-
<td class="number refe-bg-20">{{ item.err.reference }}</td>
|
|
53
|
-
<td class="number">
|
|
54
|
-
{% if item.err.is_relative %}
|
|
55
|
-
{{ '%0.2f' % (item.err.value*100)|float}}%
|
|
56
|
-
{% else %}
|
|
57
|
-
{{ item.err.value }}
|
|
58
|
-
{% endif %}
|
|
59
|
-
</td>
|
|
60
|
-
<td>
|
|
61
|
-
{% if item.err.test and item.err.reference %}
|
|
62
|
-
<div style="width:200px;height:20px">
|
|
63
|
-
<div class="test-bg-80" style="width:{{100*(item.err.test|abs)/([(item.err.test|abs), (item.err.reference|abs)]|max)}}%;height:10px"></div>
|
|
64
|
-
<div class="refe-bg-80" style="width:{{100*(item.err.reference|abs)/([(item.err.test|abs), (item.err.reference|abs)]|max)}}%; height:10px"></div>
|
|
65
|
-
</div>
|
|
66
|
-
{% endif %}
|
|
67
|
-
</td>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
{% if c_type == "vectors" %}
|
|
71
|
-
{% set group = errs.groups[item.group] %}
|
|
72
|
-
<td>{{ group.name }}</td>
|
|
73
|
-
<td>{{ item.info.index }}</td>
|
|
74
|
-
<td>
|
|
75
|
-
{% if group.data %}
|
|
76
|
-
{{ group.data.info_prefix + ": " + item.info.info|string }}
|
|
77
|
-
{% endif %}
|
|
78
|
-
</td>
|
|
79
|
-
{% endif %}
|
|
80
|
-
|
|
81
|
-
{% if c_type == "lines" %}
|
|
82
|
-
<td class="test-bg-20 number">{{ item.info.line_nb_1 }}</td>
|
|
83
|
-
<td class="refe-bg-20 number">{{ item.info.line_nb_2 }}</td>
|
|
84
|
-
<td class="test-bg-20"><pre>{{ item.info.line_1 }}</pre></td>
|
|
85
|
-
<td class="refe-bg-20"><pre>{{ item.info.line_2 }}</pre></td>
|
|
86
|
-
{% endif %}
|
|
9
|
+
{% endif %}
|
|
87
10
|
|
|
88
|
-
|
|
89
|
-
{% endfor %}
|
|
90
|
-
{% endfor %}
|
|
91
|
-
|
|
92
|
-
</table>
|
|
11
|
+
{% endfor %}
|
|
93
12
|
{% endif %}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{% set comp_errs = file.comparison_errors %}
|
|
2
|
+
<table>
|
|
3
|
+
<!-- HEADERS -->
|
|
4
|
+
<tr>
|
|
5
|
+
<th class="p-2" colspan="6">Error</th>
|
|
6
|
+
<th class="p-2" colspan="99">Source</th>
|
|
7
|
+
</tr>
|
|
8
|
+
<tr>
|
|
9
|
+
<th class="p-2" rowspan="2">Severity</th>
|
|
10
|
+
<th class="p-2" rowspan="2">Message</th>
|
|
11
|
+
<th class="p-2" colspan="2">Value</th>
|
|
12
|
+
<th class="p-2" rowspan="2">Error</th>
|
|
13
|
+
<th class="p-2" rowspan="2">Visu</th>
|
|
14
|
+
{% if group.type == "lines" %}
|
|
15
|
+
<th class="p-2" colspan="2">Line Number</th>
|
|
16
|
+
<th class="p-2" colspan="2">Line(s)</th>
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% if group.type == "vectors" %}
|
|
19
|
+
<th class="p-2" rowspan="2">Column</th>
|
|
20
|
+
<th class="p-2" rowspan="2">Index</th>
|
|
21
|
+
<th class="p-2" rowspan="2">Info</th>
|
|
22
|
+
{% endif %}
|
|
23
|
+
{% if group.type == "matrix" %}
|
|
24
|
+
<th class="p-2" rowspan="2">i</th>
|
|
25
|
+
<th class="p-2" rowspan="2">j</th>
|
|
26
|
+
<th class="p-2" rowspan="2">x</th>
|
|
27
|
+
<th class="p-2" rowspan="2">y</th>
|
|
28
|
+
{% endif %}
|
|
29
|
+
</tr>
|
|
30
|
+
<tr>
|
|
31
|
+
<th class="p-2 test-bg-50">Test</th>
|
|
32
|
+
<th class="p-2 refe-bg-50">Ref.</th>
|
|
33
|
+
{% if group.type == "lines" %}
|
|
34
|
+
<th class="p-2 test-bg-50">Test</th>
|
|
35
|
+
<th class="p-2 refe-bg-50">Ref.</th>
|
|
36
|
+
<th class="p-2 test-bg-50">Test</th>
|
|
37
|
+
<th class="p-2 refe-bg-50">Ref.</th>
|
|
38
|
+
{% endif %}
|
|
39
|
+
</tr>
|
|
40
|
+
<!-- BODY -->
|
|
41
|
+
{% for error_type in [{"data_key": "error", "class": "ERROR"}, {"data_key": "warning", "class": "WARNING"}] %}
|
|
42
|
+
{% for item in comp_errs[error_type.data_key] if item.group == group.id %}
|
|
43
|
+
<tr>
|
|
44
|
+
|
|
45
|
+
<td class="{{error_type.class}}">{{error_type.class}}</td>
|
|
46
|
+
<td>{{ comp_errs.messages[item.msg] }}</td>
|
|
47
|
+
|
|
48
|
+
<!-- COMPARISON -->
|
|
49
|
+
|
|
50
|
+
<td class="number test-bg-20">{{ item.err.test }}</td>
|
|
51
|
+
<td class="number refe-bg-20">{{ item.err.reference }}</td>
|
|
52
|
+
<td class="number">
|
|
53
|
+
{% if item.err.is_relative %}
|
|
54
|
+
{{ '%0.2f' % (item.err.value*100)|float}}%
|
|
55
|
+
{% else %}
|
|
56
|
+
{{ item.err.value }}
|
|
57
|
+
{% endif %}
|
|
58
|
+
</td>
|
|
59
|
+
<td>
|
|
60
|
+
{% if item.err.test and item.err.reference %}
|
|
61
|
+
<div style="width:200px;height:20px">
|
|
62
|
+
<div class="test-bg-80" style="width:{{100*(item.err.test|abs)/([(item.err.test|abs), (item.err.reference|abs)]|max)}}%;height:10px"></div>
|
|
63
|
+
<div class="refe-bg-80" style="width:{{100*(item.err.reference|abs)/([(item.err.test|abs), (item.err.reference|abs)]|max)}}%; height:10px"></div>
|
|
64
|
+
</div>
|
|
65
|
+
{% endif %}
|
|
66
|
+
</td>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
{% if group.type == "vectors" %}
|
|
70
|
+
{% set group = comp_errs.groups[item.group] %}
|
|
71
|
+
<td>{{ group.name }}</td>
|
|
72
|
+
<td>{{ item.info.index }}</td>
|
|
73
|
+
<td>
|
|
74
|
+
{% if group.data %}
|
|
75
|
+
{{ group.data.info_prefix + ": " + item.info.info|string }}
|
|
76
|
+
{% endif %}
|
|
77
|
+
</td>
|
|
78
|
+
{% endif %}
|
|
79
|
+
|
|
80
|
+
{% if group.type == "lines" %}
|
|
81
|
+
<td class="test-bg-20 number">{{ item.info.line_nb_1 }}</td>
|
|
82
|
+
<td class="refe-bg-20 number">{{ item.info.line_nb_2 }}</td>
|
|
83
|
+
<td class="test-bg-20"><pre>{{ item.info.line_1 }}</pre></td>
|
|
84
|
+
<td class="refe-bg-20"><pre>{{ item.info.line_2 }}</pre></td>
|
|
85
|
+
{% endif %}
|
|
86
|
+
|
|
87
|
+
{% if group.type == "matrix" %}
|
|
88
|
+
<td class="number">{{ item.info.i }}</td>
|
|
89
|
+
<td class="number">{{ item.info.j }}</td>
|
|
90
|
+
<td class="number">{{ item.info.x }}</td>
|
|
91
|
+
<td class="number">{{ item.info.y }}</td>
|
|
92
|
+
{% endif %}
|
|
93
|
+
|
|
94
|
+
</tr>
|
|
95
|
+
{% endfor %}
|
|
96
|
+
{% endfor %}
|
|
97
|
+
|
|
98
|
+
</table>
|
|
99
|
+
|
|
@@ -8,12 +8,13 @@ scilens/cli/info.py,sha256=xE7q9epjrCQRL6Agi3nhKsG6Mr3B8HSUFMti-epMoXA,1929
|
|
|
8
8
|
scilens/cli/main.py,sha256=LljcS0s2E35y4YZpV01GhMhMK9HyRRHYmxc_q_kSurI,6004
|
|
9
9
|
scilens/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
scilens/components/analyse_folder.py,sha256=yqc-dscKaHLZJCYeXGak2v0c3F2aeX0E11AFPfya6r0,208
|
|
11
|
-
scilens/components/compare_2_files.py,sha256=
|
|
12
|
-
scilens/components/compare_errors.py,sha256=
|
|
13
|
-
scilens/components/compare_floats.py,sha256=
|
|
11
|
+
scilens/components/compare_2_files.py,sha256=U4xumE28ijFbnrTPH8FgRyR_b5f04jOjaCmegJvCvSE,1483
|
|
12
|
+
scilens/components/compare_errors.py,sha256=Kw_zpVmA3Fb7yVDXog2poLaTsV_K81eLqv-z-b73Nlw,1495
|
|
13
|
+
scilens/components/compare_floats.py,sha256=GF4kKvkSKqCLLrx-BnmGi7yWTEBkYZjlCim7B9NBWxc,5028
|
|
14
14
|
scilens/components/compare_folders.py,sha256=LZ1AuYxLVHMNbtXWXQrdms4vZgOQthvDy-8NFD_EFjc,2617
|
|
15
|
+
scilens/components/compare_models.py,sha256=SCPd747h_nd4ewZsqLB6CFr27v6q99NELJb-gpkdj0o,918
|
|
15
16
|
scilens/components/executor.py,sha256=8ZZq9wwoiMr7ys9LXv1pEg5Zc06QatT9PGIigMsDAB8,3620
|
|
16
|
-
scilens/components/file_reader.py,sha256=
|
|
17
|
+
scilens/components/file_reader.py,sha256=7SbKCqb4Co_pqAKX3wweYhqAcVkU7BDlT903sLd76Kc,1407
|
|
17
18
|
scilens/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
19
|
scilens/config/cli_run_options.py,sha256=Ls7yK5QDUPFbk73nbjGuPvuRbBRYw4Miag5ISpu3prg,281
|
|
19
20
|
scilens/config/env_var.py,sha256=NqNBoIfngJEXaGEm7jGqre5pmkJ9eUjiWzbDrTVfi2c,292
|
|
@@ -26,7 +27,7 @@ scilens/config/models/execute.py,sha256=pFY-gZuBvLbcjTEcoNhPPO7FMFmKa6_TU5IXyKaf
|
|
|
26
27
|
scilens/config/models/execute_and_compare.py,sha256=TWL6yXGvQSaaV6nhHqWLvtr3v396APIoDNt0U1TbMro,582
|
|
27
28
|
scilens/config/models/file_reader.py,sha256=c18vKhVcBX4ufpbnCBJyVyAsQtlxpwx0lGVuf1i8EGA,1176
|
|
28
29
|
scilens/config/models/reader_format_cols_curve.py,sha256=eKLvifq1xuN8sPds9ijfru3vgMZ3Odv5tGfeiK4Sfk4,1860
|
|
29
|
-
scilens/config/models/reader_format_csv.py,sha256=
|
|
30
|
+
scilens/config/models/reader_format_csv.py,sha256=cxvkVbBF5DtrbRCIppjDUC2EIkb-GIe9qou3TGrihxU,1265
|
|
30
31
|
scilens/config/models/reader_format_netcdf.py,sha256=nbfTB3avO0DidbNa1dCZGFZmmQvzTYhpe6mqfAanaOA,1025
|
|
31
32
|
scilens/config/models/reader_format_txt.py,sha256=eHg90gwEI_VpqwqEjMRhwlS8dHcl5G4ow-37HjQq_zY,1168
|
|
32
33
|
scilens/config/models/reader_format_txt_fixed_cols.py,sha256=xHD1_JOoRZow8lSNaDSYFeNckojctkT4C61mbBcjeKg,1079
|
|
@@ -46,15 +47,14 @@ scilens/processors/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
46
47
|
scilens/processors/models/results.py,sha256=KoWxh13Zgi7PuPql8hkf4VjCis42ZxAuzIgJxBWVaX8,119
|
|
47
48
|
scilens/processors/processor_interface.py,sha256=jzMp1529JXnMGTJijVy6b_1zmARAMNv70f2lgys7vn4,452
|
|
48
49
|
scilens/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
-
scilens/readers/cols_dataset.py,sha256=
|
|
50
|
+
scilens/readers/cols_dataset.py,sha256=JIfPBzQZml6VlykbrMcCanR12eEnjY1A-ECgXs8wtZ4,2527
|
|
50
51
|
scilens/readers/exceptions.py,sha256=JzmxcjnR5sH-IOWVeCC5A1bSwxv-jCAtIJvDjzx1CTI,32
|
|
51
|
-
scilens/readers/
|
|
52
|
-
scilens/readers/reader_csv
|
|
53
|
-
scilens/readers/reader_csv.py,sha256=oLbA4wU6rlzL1cIrW-AzWifP-RvmG3yHKWQQqITYQ1U,2732
|
|
52
|
+
scilens/readers/mat_dataset.py,sha256=vUEjAK6nuY7miLJvjSkiHAU64KaNa1VCx7EhGPazp-U,1190
|
|
53
|
+
scilens/readers/reader_csv.py,sha256=aPd2IxFiUXYmH_EpNZkCHV1oMWctZW7YSPwC8q75SIo,3490
|
|
54
54
|
scilens/readers/reader_interface.py,sha256=nnttHL7wt4MOXpi-SBkk8DYxVWscOPG8JFl_z12mIAo,922
|
|
55
55
|
scilens/readers/reader_manager.py,sha256=DFinxIk3IIIcB6JxybGcv-mXt3jhXgCwUtzR0TqhB2Q,2684
|
|
56
|
-
scilens/readers/reader_txt.py,sha256=
|
|
57
|
-
scilens/readers/reader_txt_fixed_cols.py,sha256=
|
|
56
|
+
scilens/readers/reader_txt.py,sha256=WPsFunEA_idzAKkD3UJQbLnaOzG2U03P3gY4gphuIw0,3868
|
|
57
|
+
scilens/readers/reader_txt_fixed_cols.py,sha256=vIA6e38_3nkFeCT835eSyCufCXQNGav8Iy7VgHlT_EE,2314
|
|
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
|
|
@@ -68,7 +68,8 @@ scilens/report/templates/body_99_footer.html,sha256=8cWebeWfZwZ-9bYAMZkZj8rbCWq3
|
|
|
68
68
|
scilens/report/templates/compare_11_summary.html,sha256=4rxBlOxTcn59ztYtqDbi6SRQXlaz30HkVl7dJpzCmZE,3776
|
|
69
69
|
scilens/report/templates/compare_12_sections.html,sha256=HWsfCmfdleyRK6IHJeMEheenOuyA0mLzOZ-0qLcuzJU,5952
|
|
70
70
|
scilens/report/templates/compare_13_section_numbers copy.html,sha256=0PWK_I2kNX3LjPLkkY4eSYIeB7YFkA28nk-PPLDhnaY,1753
|
|
71
|
-
scilens/report/templates/compare_13_section_numbers.html,sha256=
|
|
71
|
+
scilens/report/templates/compare_13_section_numbers.html,sha256=FpIYAVXRiWf2zrJtjy2fWPdit_RNbHP2zQLQYScIrtY,291
|
|
72
|
+
scilens/report/templates/compare_13_section_numbers_table.html,sha256=sJy6ZYtjl80vM1b3oqZSXawZWp7KNIwLI_wCnvBwYPE,3270
|
|
72
73
|
scilens/report/templates/index.html,sha256=mNTu-CAzEJ2rhz81cHAdmT_KcQeOQ3b_FSC73NPEi0U,3670
|
|
73
74
|
scilens/report/templates/js_chartlibs_echarts.js,sha256=6YicVhTNIBmmBpV31XCVN5oBeiD0t29JIosJZRUv01M,907
|
|
74
75
|
scilens/report/templates/js_chartlibs_plotly.js,sha256=uVAOKUB5XE33-r04phR-LlRkFoaHEIXyQ3jXT5r97Rc,1521
|
|
@@ -96,7 +97,7 @@ scilens/utils/template.py,sha256=9dlXX3nmfzDRUwzPJOkoxk15UXivZ2SW-McdCwokFa4,443
|
|
|
96
97
|
scilens/utils/time_tracker.py,sha256=DdVBoMpVLXrX0qZZXyLm4g38EwDVLlRcBqcpNex1mYY,545
|
|
97
98
|
scilens/utils/vectors.py,sha256=4N2BZSC5n3HgZqPujDGF5NdjVmSL1rOHb_qw4OoABQY,103
|
|
98
99
|
scilens/utils/web.py,sha256=E4T8Fra65u9g_BpcFANPk4ORvsYavAeiSgWA3vRca2E,804
|
|
99
|
-
scilens-0.
|
|
100
|
-
scilens-0.
|
|
101
|
-
scilens-0.
|
|
102
|
-
scilens-0.
|
|
100
|
+
scilens-0.3.0.dist-info/METADATA,sha256=zvMTkfew0QXwM9EzvFc4bu1oeo4XZCAo1GonbGZ4LtI,1367
|
|
101
|
+
scilens-0.3.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
102
|
+
scilens-0.3.0.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
|
|
103
|
+
scilens-0.3.0.dist-info/RECORD,,
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
_E='charts'
|
|
2
|
-
_D='x_index'
|
|
3
|
-
_C='csv_col_index'
|
|
4
|
-
_B='curves'
|
|
5
|
-
_A=None
|
|
6
|
-
import logging,csv
|
|
7
|
-
from scilens.readers.reader_interface import ReaderInterface
|
|
8
|
-
from scilens.config.models import ReaderCsvConfig
|
|
9
|
-
from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
|
|
10
|
-
from scilens.components.compare_floats import CompareFloats
|
|
11
|
-
def is_num(x):
|
|
12
|
-
try:return float(x)
|
|
13
|
-
except ValueError:return
|
|
14
|
-
def csv_row_detect_header(first_row):
|
|
15
|
-
A=first_row
|
|
16
|
-
if all(not A.isdigit()for A in A):return True,A
|
|
17
|
-
else:return False,[f"Column {A}"for(A,B)in enumerate(A)]
|
|
18
|
-
def csv_row_detect_cols_num(row):return[A for(A,B)in enumerate(row)if is_num(B)!=_A]
|
|
19
|
-
def csv_detect(path,delimiter,quotechar):
|
|
20
|
-
with open(path,'r')as B:A=csv.reader(B,delimiter=delimiter,quotechar=quotechar);C=next(A);D,E=csv_row_detect_header(C);F=next(A);G=csv_row_detect_cols_num(F);return D,E,G
|
|
21
|
-
class ReaderCsv(ReaderInterface):
|
|
22
|
-
category='datalines';extensions=['CSV']
|
|
23
|
-
def read(A,reader_options):
|
|
24
|
-
B=reader_options;A.reader_options=B;C,G,H=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar);A.has_header=C;A.cols=G;A.numeric_col_indexes=H
|
|
25
|
-
if B.ignore_columns:
|
|
26
|
-
if not C:raise Exception('Ignore columns is not supported without header.')
|
|
27
|
-
A.numeric_col_indexes=[C for C in A.numeric_col_indexes if A.cols[C]not in B.ignore_columns]
|
|
28
|
-
E=open(A.origin.path,'r',encoding=A.encoding);I=csv.reader(E,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar);D=[]
|
|
29
|
-
for J in I:D+=[J]
|
|
30
|
-
if C:D.pop(0)
|
|
31
|
-
E.close();A.data_rows=D;A.raw_lines_number=len(A.data_rows)+(1 if C else 0);A.curves=_A
|
|
32
|
-
if B.curve_parser:
|
|
33
|
-
if B.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
|
|
34
|
-
A.curves,K=A._get_curves_col_x(B.curve_parser.parameters.x)
|
|
35
|
-
if A.curves:A.curves_parser_type=B.curve_parser.name;A.curves_info=K
|
|
36
|
-
elif B.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
|
|
37
|
-
else:raise Exception('Curve parser not supported.')
|
|
38
|
-
A.cols_data=[_A]*len(A.cols)
|
|
39
|
-
for F in A.numeric_col_indexes:A.cols_data[F]=[float(A[F])for A in D]
|
|
40
|
-
def compare(A,compare_floats,param_reader,param_is_ref=True):
|
|
41
|
-
U='error';M=param_is_ref;L=param_reader;K=compare_floats;J='Errors limit reached';C=A if M else L;E=A if not M else L
|
|
42
|
-
if len(C.numeric_col_indexes)!=len(E.numeric_col_indexes):V=f"Number Float columns indexes are different: {len(C.numeric_col_indexes)} != {len(E.numeric_col_indexes)}";return V,_A
|
|
43
|
-
N=0;D=[''for A in C.cols];O=_A;F=_A
|
|
44
|
-
if A.curves and A.curves_parser_type==ReaderCurveParserNameConfig.COL_X:P=A.curves_info[_D];O=C.cols_data[P];F=A.cols[P]
|
|
45
|
-
G=False
|
|
46
|
-
for B in range(len(C.cols_data)):
|
|
47
|
-
if C.cols_data[B]==_A:continue
|
|
48
|
-
logging.debug(f"Comparing {A.cols[B]}")
|
|
49
|
-
if G:D[B]=J;continue
|
|
50
|
-
W=C.cols_data[B];X=E.cols_data[B];Y=K.compare_errors.add_group(A.cols[B],data={'info_prefix':F}if F else _A);Q,R,H=K.compare_vectors(W,X,group_idx=Y,info_vector=O);N+=R;logging.debug(f"limit_reached, diffs_count, counts: {Q}, {R}, {H}")
|
|
51
|
-
if Q:G=True;D[B]=J;continue
|
|
52
|
-
if H[U]>0:D[B]=f"{H[U]} comparison errors"
|
|
53
|
-
if A.curves:
|
|
54
|
-
for S in A.curves[_E]:
|
|
55
|
-
T=0
|
|
56
|
-
for Z in S[_B]:
|
|
57
|
-
I=A.curves[_B][Z]
|
|
58
|
-
if D[I[_C]]:I['comparison_error']=D[I[_C]];T+=1
|
|
59
|
-
S['comparison']={'curves_nb_with_error':T}
|
|
60
|
-
a=J if G else _A;return a,{'type':'vectors','total_diffs':N,'cols_has_error':D}
|
|
61
|
-
def class_info(A):return{'cols':A.cols,'raw_lines_number':A.raw_lines_number,_B:A.curves}
|
|
62
|
-
def _get_curves_col_x(E,col_x):
|
|
63
|
-
J='title';A=col_x;F={};B=E.cols
|
|
64
|
-
if isinstance(A,int):
|
|
65
|
-
C=A-1
|
|
66
|
-
if C<0 or C>=len(B):raise Exception('curve parser col_x: col_index is out of range.')
|
|
67
|
-
if isinstance(A,str):A=[A]
|
|
68
|
-
if isinstance(A,list):
|
|
69
|
-
H=[B for(B,C)in enumerate(B)if C in A]
|
|
70
|
-
if len(H)==0:return _A,F
|
|
71
|
-
C=H[0]
|
|
72
|
-
F[_D]=C;K=[B for(A,B)in enumerate(E.numeric_col_indexes)if A!=C];G=[];I=[]
|
|
73
|
-
for D in K:L={J:B[D],'short_title':B[D],'series':[[float(A[C]),float(A[D])]for A in E.data_rows],_C:D};G+=[L];M={J:B[D],'type':'simple','xaxis':B[C],'yaxis':B[D],_B:[len(G)-1]};I+=[M]
|
|
74
|
-
return{_B:G,_E:I},F
|
|
File without changes
|
|
File without changes
|