scilens 0.3.14__py3-none-any.whl → 0.3.15__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.
@@ -15,4 +15,5 @@ class ReaderColsCurveParserConfig(BaseModel):
15
15
  if A.name==ReaderCurveParserNameConfig.COL_X:A.parameters=ReaderCurveParserColXConfig(**A.parameters)
16
16
  elif A.name==ReaderCurveParserNameConfig.COLS_COUPLE:A.parameters=ReaderCurveParserColsCoupleConfig(**A.parameters)
17
17
  return A
18
- class ReaderColsLinesConfig(BaseModel):start:int|_A=Field(default=_A,description='Ligne de début pour lire le fichier (les en-têtes sont comptées comme une ligne). Si non défini, commence à la première ligne.');end:int|_A=Field(default=_A,description="Ligne de fin pour lire le fichier (les en-têtes sont comptées comme une ligne). Si non défini, lit jusqu'à la dernière ligne.")
18
+ class ReaderColsRowsConfig(BaseModel):ignore_patterns:list[str]|_A=Field(default=_A,description='Liste des patterns de lignes à ignorer. Ex: ["^#", "^//"]. Non applicable si `is_matrix` est vrai.');line_start:int|_A=Field(default=_A,description='Ligne de début pour lire le fichier (les en-têtes sont comptées comme une ligne). Si non défini, commence à la première ligne.');line_end:int|_A=Field(default=_A,description="Ligne de fin pour lire le fichier (les en-têtes sont comptées comme une ligne). Si non défini, lit jusqu'à la dernière ligne.");index_min_value:float|_A=Field(default=_A,description="Valeur minimale de l'index pour les lignes à lire (valeur incluses).");index_max_value:float|_A=Field(default=_A,description="Valeur maximale de l'index pour les lignes à lire (valeur incluses).")
19
+ class ReaderColsConfig(BaseModel):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)');index_col:int|str|_A=Field(default=_A,description='Colonne à utiliser comme index (date/heure, itération, étape, ...) (Utilisé dans différentes règles). Numéro de colonne ou nom de colonne. (Valide seulement si non matrice)');rows:ReaderColsRowsConfig|_A=Field(default=_A,description='Configuration des lignes à lire.');curve_parser:ReaderColsCurveParserConfig|_A=Field(default=_A,description='Parseur de courbe à utiliser.')
@@ -1,6 +1,7 @@
1
1
  _B=False
2
2
  _A=None
3
3
  from pydantic import BaseModel,Field
4
- from scilens.config.models.reader_format_cols import ReaderColsCurveParserConfig,ReaderColsLinesConfig
4
+ from scilens.config.models.reader_format_cols import ReaderColsConfig
5
+ from scilens.config.models.reader_metrics import ReaderColsMetricsConfig
5
6
  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)');ignore_lines_patterns:list[str]|_A=Field(default=_A,description='Liste des patterns de lignes à ignorer. Ex: ["^#", "^//"]. Non applicable si `is_matrix` est vrai.');lines:ReaderColsLinesConfig|_A=Field(default=_A,description='Configuration des lignes à lire.');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)')
7
+ 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.');matrix:ReaderCsvMatrixConfig|_A=Field(default=_A,description='Configuration de la matrice. (Valide seulement si `is_matrix` est vrai)');cols:ReaderColsConfig|_A=Field(default=_A,description='Configuration des colonnes. (Valide seulement si non matrice)');metrics:list['ReaderColsMetricsConfig']|_A=Field(default=_A,description='Liste des métriques à calculer pour les colonnes. (Valide seulement si non matrice)')
@@ -1,4 +1,4 @@
1
1
  _A=None
2
2
  from pydantic import BaseModel,Field
3
- from scilens.config.models.reader_format_cols import ReaderColsCurveParserConfig,ReaderColsLinesConfig
4
- class ReaderTxtFixedColsConfig(BaseModel):ignore_lines_patterns:list[str]|_A=Field(default=_A,description='Liste des patterns de lignes à ignorer. Ex: ["^#", "^//"].');lines:ReaderColsLinesConfig|_A=Field(default=_A,description='Configuration des lignes à lire.');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.')
3
+ from scilens.config.models.reader_format_cols import ReaderColsCurveParserConfig,ReaderColsConfig
4
+ class ReaderTxtFixedColsConfig(BaseModel):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`.');cols:ReaderColsConfig|_A=Field(default=_A,description='Configuration des colonnes. (Valide seulement si non matrice)');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: ['##', '|'].");curve_parser:ReaderColsCurveParserConfig|_A=Field(default=_A,description='Parseur de courbe à utiliser.')
@@ -0,0 +1,3 @@
1
+ _A=None
2
+ from pydantic import BaseModel,Field
3
+ class ReaderColsMetricsConfig(BaseModel):name:str|_A=Field(default=_A,description='Nom de la métrique.');col:int|str|_A=Field(default=_A,description="Index de la colonne pour la métrique (index `1` pour la première colonne). Si `String`, nom de la colonne pour la métrique. Si la colonne n'existe pas, il n'y aura pas de parsing. (Valide seulement si la première ligne est les en-têtes)");aggregation:str=Field(default='sum',description="Méthode d'agrégation pour la métrique. Peut être `mean`, `sum`, `min`, `max`.")
@@ -8,23 +8,42 @@ from dataclasses import dataclass,field
8
8
  from scilens.components.compare_models import CompareGroup
9
9
  from scilens.components.compare_floats import CompareFloats
10
10
  from scilens.config.models.reader_format_cols import ReaderCurveParserNameConfig
11
+ from scilens.config.models.reader_metrics import ReaderColsMetricsConfig
11
12
  @dataclass
12
- class ColsDataset:cols_count:int=0;rows_count:int=0;names:list[str]=field(default_factory=lambda:[]);numeric_col_indexes:list[int]=field(default_factory=lambda:[]);data:list[list[float]]=field(default_factory=lambda:[]);origin_line_nb:list[int]=field(default_factory=lambda:[])
13
+ class ColsDataset:
14
+ cols_count:int=0;rows_count:int=0;names:list[str]=field(default_factory=lambda:[]);numeric_col_indexes:list[int]=field(default_factory=lambda:[]);data:list[list[float]]=field(default_factory=lambda:[]);origin_line_nb:list[int]=field(default_factory=lambda:[])
15
+ def get_curves_col_x(J,col_x):
16
+ I='title';B=col_x;A=J;E={}
17
+ if isinstance(B,int):
18
+ C=B-1
19
+ if C<0 or C>=A.cols_count:raise Exception('curve parser col_x: col_index is out of range.')
20
+ if isinstance(B,str):B=[B]
21
+ if isinstance(B,list):
22
+ G=[A for(A,C)in enumerate(A.names)if C in B]
23
+ if len(G)==0:return _A,E
24
+ C=G[0]
25
+ E[_D]=C;K=[B for(A,B)in enumerate(A.numeric_col_indexes)if A!=C];F=[];H=[]
26
+ for D in K:B=A.data[C];L=A.data[D];M={I:A.names[D],'short_title':A.names[D],'series':[[B[A],L[A]]for A in range(A.rows_count)],_C:D};F+=[M];N={I:A.names[D],'type':'simple','xaxis':A.names[C],'yaxis':A.names[D],_B:[len(F)-1]};H+=[N]
27
+ return{_B:F,_E:H},E
28
+ def compute_metrics(I,config):
29
+ D=I;H={}
30
+ for A in config:
31
+ E=A.col;B=_A
32
+ if isinstance(E,int):B=D.numeric_col_indexes.index(E-1)
33
+ if isinstance(E,str):B=D.names.index(E)
34
+ if B is _A or B<0 or B>=D.cols_count:raise ValueError(f"Metric '{A.name}' has an invalid column: {E}. Skipping.")
35
+ G=A.name
36
+ if not G:G=f"{D.names[B]} {A.aggregation}"
37
+ F=D.data[B];C=_A
38
+ if A.aggregation=='mean':C=sum(F)/len(F)
39
+ elif A.aggregation=='sum':C=sum(F)
40
+ elif A.aggregation=='min':C=min(F)
41
+ elif A.aggregation=='max':C=max(F)
42
+ if C is _A:raise ValueError(f"Metric '{A.name}' has an invalid aggregation: {A.aggregation}.")
43
+ H[G]=C
44
+ return H
13
45
  @dataclass
14
46
  class ColsCurves:type:str;info:dict;curves:dict
15
- def cols_dataset_get_curves_col_x(cols_dataset,col_x):
16
- I='title';B=col_x;A=cols_dataset;E={}
17
- if isinstance(B,int):
18
- C=B-1
19
- if C<0 or C>=A.cols_count:raise Exception('curve parser col_x: col_index is out of range.')
20
- if isinstance(B,str):B=[B]
21
- if isinstance(B,list):
22
- G=[A for(A,C)in enumerate(A.names)if C in B]
23
- if len(G)==0:return _A,E
24
- C=G[0]
25
- E[_D]=C;J=[B for(A,B)in enumerate(A.numeric_col_indexes)if A!=C];F=[];H=[]
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]
27
- return{_B:F,_E:H},E
28
47
  def compare(group,compare_floats,reader_test,reader_ref,cols_curve):
29
48
  O='Errors limit reached';F=reader_ref;D=group;C=cols_curve;A=reader_test;logging.debug(f"compare cols: {D.name}")
30
49
  if len(A.numeric_col_indexes)!=len(F.numeric_col_indexes):D.error=f"Number Float columns indexes are different: {len(A.numeric_col_indexes)} != {len(F.numeric_col_indexes)}";return
@@ -2,7 +2,7 @@ _B=True
2
2
  _A=None
3
3
  import logging,csv,re
4
4
  from scilens.readers.reader_interface import ReaderInterface
5
- from scilens.readers.cols_dataset import ColsDataset,ColsCurves,cols_dataset_get_curves_col_x,compare as cols_compare
5
+ from scilens.readers.cols_dataset import ColsDataset,ColsCurves,compare as cols_compare
6
6
  from scilens.readers.mat_dataset import MatDataset,from_iterator as mat_from_iterator,compare as mat_compare,get_data
7
7
  from scilens.config.models.reader_format_csv import ReaderCsvConfig,ReaderCsvMatrixConfig
8
8
  from scilens.config.models.reader_format_cols import ReaderCurveParserNameConfig
@@ -20,47 +20,70 @@ def csv_detect(path,delimiter,quotechar,encoding):
20
20
  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
21
21
  class ReaderCsv(ReaderInterface):
22
22
  configuration_type_code='csv';category='datalines';extensions=['CSV']
23
+ def _ignore_line(A,line):
24
+ if not line.strip():return _B
25
+ if A.ignore_lines_patterns:
26
+ for B in A.ignore_lines_patterns:
27
+ if bool(re.match(B,line)):return _B
28
+ return False
23
29
  def read(A,reader_options):
24
- B=reader_options;A.reader_options=B;K=B.ignore_lines_patterns;A.raw_lines_number=_A;A.curves=_A;A.report_matrices=_A;D,G,R=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar,encoding=A.encoding);A.has_header=D;A.cols=G;A.numeric_col_indexes=R;L=B.lines.start if B.lines and B.lines.start else _A;M=B.lines.end if B.lines and B.lines.end else _A
25
- with open(A.origin.path,'r',encoding=A.encoding)as S:
26
- N=S.readlines();H=csv.reader(N,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar)
27
- if B.is_matrix:
28
- F=B.matrix or ReaderCsvMatrixConfig();I=mat_from_iterator(x_name=F.x_name,y_name=F.y_name,reader=H,has_header=D,x_value_line=F.x_value_line,has_y=F.has_y)
29
- if F.export_report:A.report_matrices=get_data([I],['csv'])
30
- A.mat_dataset=I;A.raw_lines_number=I.nb_lines+(1 if D else 0)
30
+ C=reader_options;A.reader_options=C;F,I,T=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar,encoding=A.encoding);A.has_header=F;A.cols=I;A.numeric_col_indexes=T;A.index_col_index=_A;A.ignore_lines_patterns=_A;L=_A;M=_A;N=_A;O=_A;B=C.cols
31
+ if B:
32
+ if B.index_col:
33
+ if B.index_col:
34
+ if isinstance(B.index_col,int):
35
+ G=B.index_col-1
36
+ if G not in A.numeric_col_indexes:raise ValueError(f"Index column index {B.index_col} is not a numeric column.")
37
+ A.index_col_index=G
38
+ elif isinstance(B.index_col,str):
39
+ try:A.index_col_index=I.index(B.index_col)
40
+ except ValueError:raise ValueError(f"Index column '{B.index_col}' not found in CSV headers.")
41
+ if B.rows:
42
+ A.ignore_lines_patterns=B.rows.ignore_patterns;L=B.rows.line_start;M=B.rows.line_end
43
+ if B.rows.index_min_value or B.rows.index_max_value:
44
+ if A.index_col_index is _A:raise ValueError('Index column must be defined to use index min/max values.')
45
+ N=B.rows.index_min_value;O=B.rows.index_max_value
46
+ A.raw_lines_number=_A;A.curves=_A;A.report_matrices=_A
47
+ with open(A.origin.path,'r',encoding=A.encoding)as U:
48
+ R=U.readlines();J=csv.reader(R,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar)
49
+ if C.is_matrix:
50
+ H=C.matrix or ReaderCsvMatrixConfig();P=mat_from_iterator(x_name=H.x_name,y_name=H.y_name,reader=J,has_header=F,x_value_line=H.x_value_line,has_y=H.has_y)
51
+ if H.export_report:A.report_matrices=get_data([P],['csv'])
52
+ A.mat_dataset=P;A.raw_lines_number=P.nb_lines+(1 if F else 0)
31
53
  else:
32
- if B.ignore_columns:
33
- if not D:raise Exception('Ignore columns is not supported without header.')
34
- A.numeric_col_indexes=[C for C in A.numeric_col_indexes if A.cols[C]not in B.ignore_columns]
35
- O=len(G);C=ColsDataset(cols_count=O,names=G,numeric_col_indexes=A.numeric_col_indexes,data=[[]for A in range(O)]);E=0
54
+ if C.cols and C.cols.ignore_columns:
55
+ if not F:raise Exception('Ignore columns is not supported without header.')
56
+ A.numeric_col_indexes=[B for B in A.numeric_col_indexes if A.cols[B]not in C.cols.ignore_columns]
57
+ S=len(I);D=ColsDataset(cols_count=S,names=I,numeric_col_indexes=A.numeric_col_indexes,data=[[]for A in range(S)]);E=0
58
+ if F and E==0:next(J);E+=1
36
59
  if L:
37
- for X in range(L-1):
38
- try:next(H);E+=1
39
- except StopIteration:break
60
+ try:
61
+ while _B:
62
+ if L<=E+1:break
63
+ K=next(J);E+=1
64
+ except StopIteration:pass
40
65
  try:
41
66
  while _B:
42
- T=next(H);E+=1
67
+ K=next(J);E+=1
43
68
  if M and E>M:break
44
- if D and E==1:continue
45
- if K:
46
- U=N[E-1].rstrip('\n');P=False
47
- for V in K:
48
- if bool(re.match(V,U)):P=_B;break
49
- if P:continue
50
- for(Q,J)in enumerate(T):
51
- if Q in C.numeric_col_indexes:J=float(J)
52
- C.data[Q].append(J)
53
- C.origin_line_nb.append(E)
69
+ if O is not _A and float(K[A.index_col_index])>O:break
70
+ if A.ignore_lines_patterns and A._ignore_line(R[E-1].rstrip('\n')):continue
71
+ if N is not _A and float(K[A.index_col_index])<N:continue
72
+ for(G,Q)in enumerate(K):
73
+ if G in D.numeric_col_indexes:Q=float(Q)
74
+ D.data[G].append(Q)
75
+ D.origin_line_nb.append(E)
54
76
  except StopIteration:pass
55
- C.rows_count=len(C.origin_line_nb);A.cols_dataset=C;A.raw_lines_number=C.rows_count+(1 if D else 0)
56
- if B.curve_parser:
57
- if B.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
58
- A.curves,W=cols_dataset_get_curves_col_x(C,B.curve_parser.parameters.x)
59
- if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=W,curves=A.curves)
60
- elif B.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
77
+ D.rows_count=len(D.origin_line_nb);A.cols_dataset=D;A.raw_lines_number=D.rows_count+(1 if F else 0);A.metrics=_A
78
+ if C.metrics:A.metrics=D.compute_metrics(C.metrics)
79
+ if C.cols and C.cols.curve_parser:
80
+ if C.cols.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
81
+ A.curves,V=D.get_curves_col_x(C.cols.curve_parser.parameters.x)
82
+ if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=V,curves=A.curves)
83
+ elif C.cols.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
61
84
  else:raise Exception('Curve parser not supported.')
62
85
  def compare(A,compare_floats,param_reader,param_is_ref=_B):
63
86
  H='node';D=param_is_ref;C=param_reader;B=compare_floats;I=A.reader_options
64
87
  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)
65
88
  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)
66
- def class_info(A):return{'cols':A.cols,'raw_lines_number':A.raw_lines_number,'curves':A.curves,'matrices':A.report_matrices}
89
+ def class_info(A):return{'cols':A.cols,'raw_lines_number':A.raw_lines_number,'curves':A.curves,'matrices':A.report_matrices,'metrics':A.metrics}
@@ -4,7 +4,7 @@ from itertools import islice
4
4
  from dataclasses import dataclass
5
5
  from scilens.readers.transform import string_2_float
6
6
  from scilens.readers.reader_interface import ReaderInterface
7
- from scilens.readers.cols_dataset import ColsDataset,ColsCurves,cols_dataset_get_curves_col_x,compare
7
+ from scilens.readers.cols_dataset import ColsDataset,ColsCurves,compare
8
8
  from scilens.config.models import ReaderTxtFixedColsConfig
9
9
  from scilens.config.models.reader_format_cols import ReaderCurveParserNameConfig
10
10
  from scilens.components.compare_floats import CompareFloats
@@ -14,8 +14,8 @@ class ReaderTxtFixedCols(ReaderInterface):
14
14
  configuration_type_code='txt_fixed_cols';category='datalines';extensions=[]
15
15
  def _ignore_line(A,line):
16
16
  if not line.strip():return True
17
- if A.reader_options.ignore_lines_patterns:
18
- for B in A.reader_options.ignore_lines_patterns:
17
+ if A.ignore_lines_patterns:
18
+ for B in A.ignore_lines_patterns:
19
19
  if bool(re.match(B,line)):return True
20
20
  return False
21
21
  def _get_parsed_headers(A,path):
@@ -50,33 +50,36 @@ class ReaderTxtFixedCols(ReaderInterface):
50
50
  if B<len(A):C.append((B,len(A)))
51
51
  return C
52
52
  def _derive_col_indexes(A,header_row=_A):0
53
- def read(B,reader_options):
54
- A=reader_options;B.reader_options=A;E=B._get_parsed_headers(B.origin.path)if A.has_header else _A;I=open(B.origin.path,'r',encoding=B.encoding);C=[]
55
- if A.column_indexes or A.column_widths:
56
- if A.column_indexes and A.column_widths:raise Exception('column_indexes and column_widths are exclusive.')
57
- if A.column_widths:
58
- logging.debug(f"Using column widths: {A.column_widths}");H=0
59
- for J in A.column_widths:C+=[(H,H+J)];H+=J
60
- else:logging.debug(f"Using column indexes: {A.column_indexes}");C=A.column_indexes
61
- else:logging.debug(f"Using auto derived column indexes.");N=B._get_first_data_line(B.origin.path);C=B._discover_col_idx_ralgin_spaces(N)
53
+ def read(A,reader_options):
54
+ B=reader_options;A.reader_options=B;A.ignore_lines_patterns=_A;I=_A;K=_A;E=B.cols
55
+ if E:
56
+ if E.rows:A.ignore_lines_patterns=E.rows.ignore_patterns;I=E.rows.line_start;K=E.rows.line_end
57
+ F=A._get_parsed_headers(A.origin.path)if B.has_header else _A;L=open(A.origin.path,'r',encoding=A.encoding);C=[]
58
+ if B.column_indexes or B.column_widths:
59
+ if B.column_indexes and B.column_widths:raise Exception('column_indexes and column_widths are exclusive.')
60
+ if B.column_widths:
61
+ logging.debug(f"Using column widths: {B.column_widths}");J=0
62
+ for M in B.column_widths:C+=[(J,J+M)];J+=M
63
+ else:logging.debug(f"Using column indexes: {B.column_indexes}");C=B.column_indexes
64
+ else:logging.debug(f"Using auto derived column indexes.");P=A._get_first_data_line(A.origin.path);C=A._discover_col_idx_ralgin_spaces(P)
62
65
  logging.debug(f"Column indexes: {C}")
63
66
  if not C:raise Exception('No column indexes or widths provided, and no headers found to derive column indexes.')
64
- 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)])
65
- if E:D.names=E.data
66
- K=A.lines.start if A.lines and A.lines.start else _A;O=A.lines.end if A.lines and A.lines.end else _A;G=K or 0
67
- for L in islice(I,K,O):
68
- G+=1
69
- if B._ignore_line(L):continue
70
- if E:
71
- if E.ori_line_idx==G-1:continue
72
- for(P,M)in enumerate(C):Q=L[M[0]:M[1]].strip();R=string_2_float(Q);D.data[P].append(R)
73
- D.origin_line_nb.append(G)
74
- D.rows_count=len(D.origin_line_nb);I.close();B.cols_dataset=D;B.raw_lines_number=G;B.curves=_A;B.cols_curve=_A
75
- if A.curve_parser:
76
- if A.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
77
- B.curves,S=cols_dataset_get_curves_col_x(D,A.curve_parser.parameters.x)
78
- if B.curves:B.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=S,curves=B.curves)
79
- elif A.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
67
+ G=len(C);D=ColsDataset(cols_count=G,names=[f"Column {A+1}"for A in range(G)],numeric_col_indexes=[A for A in range(G)],data=[[]for A in range(G)])
68
+ if F:D.names=F.data
69
+ H=I or 0
70
+ for N in islice(L,I,K):
71
+ H+=1
72
+ if A._ignore_line(N):continue
73
+ if F:
74
+ if F.ori_line_idx==H-1:continue
75
+ for(Q,O)in enumerate(C):R=N[O[0]:O[1]].strip();S=string_2_float(R);D.data[Q].append(S)
76
+ D.origin_line_nb.append(H)
77
+ D.rows_count=len(D.origin_line_nb);L.close();A.cols_dataset=D;A.raw_lines_number=H;A.curves=_A;A.cols_curve=_A
78
+ if B.cols and B.cols.curve_parser:
79
+ if B.cols.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
80
+ A.curves,T=D.get_curves_col_x(B.cols.curve_parser.parameters.x)
81
+ if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=T,curves=A.curves)
82
+ elif B.cols.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
80
83
  else:raise Exception('Curve parser not supported.')
81
84
  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)
82
85
  def class_info(A):return{'cols':A.cols_dataset.names,'raw_lines_number':A.raw_lines_number,'curves':A.curves}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scilens
3
- Version: 0.3.14
3
+ Version: 0.3.15
4
4
  Summary: A CesGensLaB framework for data collecting and deep analysis
5
5
  Home-page: https://scilens.dev
6
6
  License: Proprietary
@@ -27,11 +27,12 @@ scilens/config/models/compare_float_thresholds.py,sha256=mHu48-70i3o_qUw6x-1A7Xe
27
27
  scilens/config/models/execute.py,sha256=Hx3DoDJ0fq7bZruqwtPtSKL6PVOF_LpsaDCLrn5klLk,2325
28
28
  scilens/config/models/execute_and_compare.py,sha256=TWL6yXGvQSaaV6nhHqWLvtr3v396APIoDNt0U1TbMro,582
29
29
  scilens/config/models/file_reader.py,sha256=c18vKhVcBX4ufpbnCBJyVyAsQtlxpwx0lGVuf1i8EGA,1176
30
- scilens/config/models/reader_format_cols.py,sha256=FBZYG1uord9XJlYAzYNEVuZgPp7Kz2UE2vkjQ1S3eUw,2259
31
- scilens/config/models/reader_format_csv.py,sha256=XRgPaOzfCKXgt_1ZyyDmdHTKxcz8sOA6ZrHATdlnNps,1821
30
+ scilens/config/models/reader_format_cols.py,sha256=CcvV2SiPM1Pklxm-mG1oVQYixSyjmC5T3WEQfZ0U0ss,3332
31
+ scilens/config/models/reader_format_csv.py,sha256=zxysiAAQitdBjh1mTlzQR0YafmLyIdEm2qarNh98ST8,1590
32
32
  scilens/config/models/reader_format_netcdf.py,sha256=k-AMdm239T6I42R8jzyRlPKKJ8zkRrN8XS8yU6ZkFu0,1256
33
33
  scilens/config/models/reader_format_txt.py,sha256=eHg90gwEI_VpqwqEjMRhwlS8dHcl5G4ow-37HjQq_zY,1168
34
- scilens/config/models/reader_format_txt_fixed_cols.py,sha256=cbwj92QEHUX5xKC2E3PfIdjOAER4AmF_R_RP20gINmg,1246
34
+ scilens/config/models/reader_format_txt_fixed_cols.py,sha256=EmnXcCyvG9J6tTEIgldSD2zZEVotcINM1Yzmtqs9foA,1136
35
+ scilens/config/models/reader_metrics.py,sha256=oWzQPM5EO05QYwJiqeeTX-c4tuoiYBrR_q-meaoGTzA,572
35
36
  scilens/config/models/readers.py,sha256=oWdE4AkckvwN6boln55orq3hUeAt6S9IdQAZkGROR6E,1657
36
37
  scilens/config/models/report.py,sha256=6mzqZMJnS_z5Rs01ISo8L8HRcWvmiQrK0dYqu8a58vM,993
37
38
  scilens/config/models/report_html.py,sha256=OU_df-IwopOILbWgNHImTtZf7Yhj_fsD0lpRQB8-bP8,3728
@@ -48,14 +49,14 @@ scilens/processors/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
48
49
  scilens/processors/models/results.py,sha256=KoWxh13Zgi7PuPql8hkf4VjCis42ZxAuzIgJxBWVaX8,119
49
50
  scilens/processors/processor_interface.py,sha256=jzMp1529JXnMGTJijVy6b_1zmARAMNv70f2lgys7vn4,452
50
51
  scilens/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
- scilens/readers/cols_dataset.py,sha256=yEn2LzetCyoAXzEB490rMKnasGvZK8754wtA0Gw0-Mw,2446
52
+ scilens/readers/cols_dataset.py,sha256=KENQLhlAjktOTPymqokJLp_mBOsMFq8GRy_cs9b3wjU,3151
52
53
  scilens/readers/exceptions.py,sha256=JzmxcjnR5sH-IOWVeCC5A1bSwxv-jCAtIJvDjzx1CTI,32
53
54
  scilens/readers/mat_dataset.py,sha256=Z9TYDWaH2aqdniLNDjlpR6VVNHMSARjh52clhdMyOn4,1496
54
- scilens/readers/reader_csv.py,sha256=12KaY2tEcHfAE7M6ylPMMnW93qF18YwykPk6lE251DA,4180
55
+ scilens/readers/reader_csv.py,sha256=EM674DLK4I2uvE3vKh-soenIhGqrH38r2pAYdxV9Dzo,5272
55
56
  scilens/readers/reader_interface.py,sha256=nnttHL7wt4MOXpi-SBkk8DYxVWscOPG8JFl_z12mIAo,922
56
57
  scilens/readers/reader_manager.py,sha256=DFinxIk3IIIcB6JxybGcv-mXt3jhXgCwUtzR0TqhB2Q,2684
57
58
  scilens/readers/reader_txt.py,sha256=WPsFunEA_idzAKkD3UJQbLnaOzG2U03P3gY4gphuIw0,3868
58
- scilens/readers/reader_txt_fixed_cols.py,sha256=PCgrVLBRhnb2R0cSp4GZongSyJDqfIZiFfwup7nxTfM,4206
59
+ scilens/readers/reader_txt_fixed_cols.py,sha256=G_DFa0d0_OV54vsHZ08Plkn1JPl_OUBz4sxLx9grZG0,4216
59
60
  scilens/readers/transform.py,sha256=kppfgPkXymF0qtquFivuosLVfF66L9bE-wGx-3bMHv8,307
60
61
  scilens/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
62
  scilens/report/assets/logo.svg,sha256=W-1OVqcvdBjf-1AHHcV6WciIUqBoVFUh52Tc3o_jqtA,4519
@@ -105,7 +106,7 @@ scilens/utils/template.py,sha256=9dlXX3nmfzDRUwzPJOkoxk15UXivZ2SW-McdCwokFa4,443
105
106
  scilens/utils/time_tracker.py,sha256=DdVBoMpVLXrX0qZZXyLm4g38EwDVLlRcBqcpNex1mYY,545
106
107
  scilens/utils/vectors.py,sha256=4N2BZSC5n3HgZqPujDGF5NdjVmSL1rOHb_qw4OoABQY,103
107
108
  scilens/utils/web.py,sha256=MAFWpIFOKz7QhqDoFh-Qwstvc76KpcxstSgHFT8FOL4,901
108
- scilens-0.3.14.dist-info/METADATA,sha256=3Wyexc7CQ4LFDhJPNhdMbGA244lCWZhV58_XjfG_m5I,1368
109
- scilens-0.3.14.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
110
- scilens-0.3.14.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
111
- scilens-0.3.14.dist-info/RECORD,,
109
+ scilens-0.3.15.dist-info/METADATA,sha256=1HK7XFb3jdqiHRVMQpzim7YjHGQ6PCS7d6aehDSyQJw,1368
110
+ scilens-0.3.15.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
111
+ scilens-0.3.15.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
112
+ scilens-0.3.15.dist-info/RECORD,,