scilens 0.3.13__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.
@@ -1,8 +1,9 @@
1
- _A='(Valide seulement si la première ligne est les en-têtes)'
1
+ _B='(Valide seulement si la première ligne est les en-têtes)'
2
+ _A=None
2
3
  from pydantic import BaseModel,Field,model_validator
3
4
  from enum import Enum
4
5
  class ReaderCurveParserNameConfig(str,Enum):COL_X='col_x';COLS_COUPLE='cols_couple'
5
- class ReaderCurveParserColXConfig(BaseModel):x:int|str|list[str]=Field(default=1,description="Si `integer`, index de la colonne pour l'axe x (index `1` pour la première colonne)."+"Si `String`, nom de la colonne pour l'axe x. Si la colonne n'existe pas, il n'y aura pas de parsing."+_A+"Si `List[String] (utiles dans un contexte multi dataset), noms de la colonne pour l'axe x, noms des colonnes pour l'axe x , si plusieurs colonnes correspondent, la première trouvée sera utilisée. Si aucune colonne ne correspond, il n'y aura pas de parsing."+_A)
6
+ class ReaderCurveParserColXConfig(BaseModel):x:int|str|list[str]=Field(default=1,description="Si `integer`, index de la colonne pour l'axe x (index `1` pour la première colonne)."+"Si `String`, nom de la colonne pour l'axe x. Si la colonne n'existe pas, il n'y aura pas de parsing."+_B+"Si `List[String] (utiles dans un contexte multi dataset), noms de la colonne pour l'axe x, noms des colonnes pour l'axe x , si plusieurs colonnes correspondent, la première trouvée sera utilisée. Si aucune colonne ne correspond, il n'y aura pas de parsing."+_B)
6
7
  class ReaderCurveParserColsCoupleConfig(BaseModel):x_index:int=Field(description='NOT IMPLEMENTED - Index Col x');y_index:int=Field(description='NOT IMPLEMENTED - Index Col y')
7
8
  class ReaderColsCurveParserConfig(BaseModel):
8
9
  name:ReaderCurveParserNameConfig=Field(description='Le type de `paramètres` dépend de cette valeur');parameters:ReaderCurveParserColXConfig|ReaderCurveParserColsCoupleConfig=Field(description='Paramètres du parser de courbes')
@@ -13,4 +14,6 @@ class ReaderColsCurveParserConfig(BaseModel):
13
14
  if isinstance(A.parameters,dict):
14
15
  if A.name==ReaderCurveParserNameConfig.COL_X:A.parameters=ReaderCurveParserColXConfig(**A.parameters)
15
16
  elif A.name==ReaderCurveParserNameConfig.COLS_COUPLE:A.parameters=ReaderCurveParserColsCoupleConfig(**A.parameters)
16
- return A
17
+ return A
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_curve import ReaderColsCurveParserConfig
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)');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)')
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_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.");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`.")
@@ -7,24 +7,43 @@ import logging
7
7
  from dataclasses import dataclass,field
8
8
  from scilens.components.compare_models import CompareGroup
9
9
  from scilens.components.compare_floats import CompareFloats
10
- from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
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
@@ -1,10 +1,11 @@
1
+ _B=True
1
2
  _A=None
2
3
  import logging,csv,re
3
4
  from scilens.readers.reader_interface import ReaderInterface
4
- 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
5
6
  from scilens.readers.mat_dataset import MatDataset,from_iterator as mat_from_iterator,compare as mat_compare,get_data
6
7
  from scilens.config.models.reader_format_csv import ReaderCsvConfig,ReaderCsvMatrixConfig
7
- from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
8
+ from scilens.config.models.reader_format_cols import ReaderCurveParserNameConfig
8
9
  from scilens.components.compare_models import CompareGroup
9
10
  from scilens.components.compare_floats import CompareFloats
10
11
  def is_num(x):
@@ -12,47 +13,77 @@ def is_num(x):
12
13
  except ValueError:return
13
14
  def csv_row_detect_header(first_row):
14
15
  A=first_row
15
- if all(not A.isdigit()for A in A):return True,A
16
+ if all(not A.isdigit()for A in A):return _B,A
16
17
  else:return False,[f"Column {A}"for(A,B)in enumerate(A)]
17
18
  def csv_row_detect_cols_num(row):return[A for(A,B)in enumerate(row)if is_num(B)!=_A]
18
19
  def csv_detect(path,delimiter,quotechar,encoding):
19
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
20
21
  class ReaderCsv(ReaderInterface):
21
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
22
29
  def read(A,reader_options):
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
+ 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)
30
53
  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')
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
59
+ if L:
60
+ try:
61
+ while _B:
62
+ if L<=E+1:break
63
+ K=next(J);E+=1
64
+ except StopIteration:pass
65
+ try:
66
+ while _B:
67
+ K=next(J);E+=1
68
+ if M and E>M:break
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)
76
+ except StopIteration:pass
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')
53
84
  else:raise Exception('Curve parser not supported.')
54
- def compare(A,compare_floats,param_reader,param_is_ref=True):
85
+ def compare(A,compare_floats,param_reader,param_is_ref=_B):
55
86
  H='node';D=param_is_ref;C=param_reader;B=compare_floats;I=A.reader_options
56
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)
57
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)
58
- 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}
@@ -1,11 +1,12 @@
1
1
  _A=None
2
2
  import logging,re
3
+ from itertools import islice
3
4
  from dataclasses import dataclass
4
5
  from scilens.readers.transform import string_2_float
5
6
  from scilens.readers.reader_interface import ReaderInterface
6
- 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
7
8
  from scilens.config.models import ReaderTxtFixedColsConfig
8
- from scilens.config.models.reader_format_cols_curve import ReaderCurveParserNameConfig
9
+ from scilens.config.models.reader_format_cols import ReaderCurveParserNameConfig
9
10
  from scilens.components.compare_floats import CompareFloats
10
11
  @dataclass
11
12
  class ParsedHeaders:raw:str;cleaned:str;data:list[str];ori_line_idx:int|_A=_A
@@ -13,8 +14,8 @@ class ReaderTxtFixedCols(ReaderInterface):
13
14
  configuration_type_code='txt_fixed_cols';category='datalines';extensions=[]
14
15
  def _ignore_line(A,line):
15
16
  if not line.strip():return True
16
- if A.reader_options.ignore_lines_patterns:
17
- for B in A.reader_options.ignore_lines_patterns:
17
+ if A.ignore_lines_patterns:
18
+ for B in A.ignore_lines_patterns:
18
19
  if bool(re.match(B,line)):return True
19
20
  return False
20
21
  def _get_parsed_headers(A,path):
@@ -50,32 +51,35 @@ class ReaderTxtFixedCols(ReaderInterface):
50
51
  return C
51
52
  def _derive_col_indexes(A,header_row=_A):0
52
53
  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
+ 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=[]
54
58
  if B.column_indexes or B.column_widths:
55
59
  if B.column_indexes and B.column_widths:raise Exception('column_indexes and column_widths are exclusive.')
56
60
  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
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
59
63
  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)
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)
61
65
  logging.debug(f"Column indexes: {C}")
62
66
  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:
67
- G+=1
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')
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')
79
83
  else:raise Exception('Curve parser not supported.')
80
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)
81
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.13
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_curve.py,sha256=eKLvifq1xuN8sPds9ijfru3vgMZ3Odv5tGfeiK4Sfk4,1860
31
- scilens/config/models/reader_format_csv.py,sha256=EQ1nCYsv6Cf4rtK3AUW5LbJakRcutdaNSl4UN634evs,1708
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=SQ84OW9BLc5mr_TC6gQuYzzHJvrU-sVz223WOtAQMc0,1133
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=C4N030_Iqq5KZVpQ0NVjAw4DctALuz_YBb6f6yi35Jk,2452
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=MXjGdNHm1i9phhYLeMuNFjCvxuIeZH_KNs6ni3a4nS8,3893
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=B7toE3G9KGcgD_p15jzGHOLGIKZ7KMmEQoTt6-4UtHo,4064
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.13.dist-info/METADATA,sha256=U2VI8vou4zNMseQ0f53-VOO13m5NL4vsJwzqJ_oUEaA,1368
109
- scilens-0.3.13.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
110
- scilens-0.3.13.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
111
- scilens-0.3.13.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,,