scilens 0.4.8__py3-none-any.whl → 0.4.10__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,9 +1,11 @@
1
1
  _A='Configuration utile au processeur `ExecuteAndCompare`.'
2
2
  from pydantic import BaseModel,Field
3
+ from typing import Literal
3
4
  from scilens.config.models.compare import CompareConfig
4
5
  from scilens.config.models.execute import ExecuteConfig
5
6
  from scilens.config.models.execute_and_compare import ExecuteAndCompareConfig
6
7
  from scilens.config.models.file_reader import FileReaderConfig
7
8
  from scilens.config.models.readers import ReadersConfig
8
9
  from scilens.config.models.report import ReportConfig
9
- class AppConfig(BaseModel,extra='forbid'):processor:str=Field(description='Nom du processeur à utiliser. `Compare` ou `ExecuteAndCompare`.');variables:dict[str,str]=Field(default={},description='Variables Utilisateur.');tags:list[str]|None=Field(default=None,description="Utilisé dans un contexte ligne de commande, utilisé en conjonction avec l'option `--discover` pour filtrer les cas à éxécuter.");execute:ExecuteConfig=Field(default=ExecuteConfig(),description=_A);execute_and_compare:ExecuteAndCompareConfig=Field(default=ExecuteAndCompareConfig(),description=_A);file_reader:FileReaderConfig=Field(default=FileReaderConfig(),description='Configuration des readers fichiers.');readers:ReadersConfig=Field(default=ReadersConfig(),description='Configuration des readers.');compare:CompareConfig=Field(default=CompareConfig(),description='Configuration utile aux processeurs `Compare` et `ExecuteAndCompare`');report:ReportConfig=Field(default=ReportConfig(),description='Configuration des Reports.')
10
+ ProcessorType=Literal['Compare','ExecuteAndCompare']
11
+ class AppConfig(BaseModel,extra='forbid'):processor:ProcessorType=Field(description='Nom du processeur à utiliser. `Compare` ou `ExecuteAndCompare`.');variables:dict[str,str]=Field(default={},description='Variables Utilisateur.');tags:list[str]|None=Field(default=None,description="Utilisé dans un contexte ligne de commande, utilisé en conjonction avec l'option `--discover` pour filtrer les cas à éxécuter.");execute:ExecuteConfig=Field(default=ExecuteConfig(),description=_A);execute_and_compare:ExecuteAndCompareConfig=Field(default=ExecuteAndCompareConfig(),description=_A);file_reader:FileReaderConfig=Field(default=FileReaderConfig(),description='Configuration des readers fichiers.');readers:ReadersConfig=Field(default=ReadersConfig(),description='Configuration des readers.');compare:CompareConfig=Field(default=CompareConfig(),description='Configuration utile aux processeurs `Compare` et `ExecuteAndCompare`');report:ReportConfig=Field(default=ReportConfig(),description='Configuration des Reports.')
@@ -34,31 +34,34 @@ class ColsDataset:
34
34
  def compute_metrics(K,config):
35
35
  C=K;L={}
36
36
  for(H,F)in enumerate(config):
37
- I=F.name;B=F.col;J=F.function;D=F.aggregation
38
- if not B and not J:raise ValueError(f"Metric #{H} must have either a column or a function.")
39
- if B and J:raise ValueError(f"Metric #{H} cannot have both a column and a function.")
40
- if B:
41
- E=_A
42
- if isinstance(B,int):E=C.numeric_col_indexes.index(B-1)
43
- if isinstance(B,str):E=C.names.index(B)
44
- if E is _A or E<0 or E>=C.cols_count:raise ValueError(f"Metric #{H} has an invalid column: {B}.")
45
- if not I:I=f"{C.names[E]} {D}"
46
- A=C.data[E]
37
+ I=F.name;A=F.col;J=F.function;E=F.aggregation
38
+ if not A and not J:raise ValueError(f"Metric #{H} must have either a column or a function.")
39
+ if A and J:raise ValueError(f"Metric #{H} cannot have both a column and a function.")
40
+ if A:
41
+ D=_A
42
+ if isinstance(A,int):D=C.numeric_col_indexes.index(A-1)
43
+ if isinstance(A,str):
44
+ D=C.names.index(A)if A in C.names else _A
45
+ if D is _A:continue
46
+ if D is _A or D<0 or D>=C.cols_count:raise ValueError(f"Metric #{H} has an invalid column: {A}.")
47
+ if not I:I=f"{C.names[D]} {E}"
48
+ B=C.data[D]
47
49
  elif J:
48
- A=[0 for A in range(C.rows_count)]
50
+ B=[0 for A in range(C.rows_count)]
49
51
  if J=='euclidean_norm':
50
- if not I:I=f"Euclidean Norm {F.components} {D}"
52
+ if not I:I=f"Euclidean Norm {F.components} {E}"
51
53
  M=K.get_col_indexes(F.components)
54
+ if not M:continue
52
55
  for N in M:
53
- for(O,P)in enumerate(C.data[N]):A[O]+=P**2
54
- A=[math.sqrt(A)for A in A]
56
+ for(O,P)in enumerate(C.data[N]):B[O]+=P**2
57
+ B=[math.sqrt(A)for A in B]
55
58
  else:raise ValueError(f"Metric #{H} has an invalid function: {J}.")
56
59
  G=_A
57
- if D=='mean':G=sum(A)/len(A)
58
- elif D=='sum':G=sum(A)
59
- elif D=='min':G=min(A)
60
- elif D=='max':G=max(A)
61
- if G is _A:raise ValueError(f"Metric #{H} has an invalid aggregation: {D}.")
60
+ if E=='mean':G=sum(B)/len(B)
61
+ elif E=='sum':G=sum(B)
62
+ elif E=='min':G=min(B)
63
+ elif E=='max':G=max(B)
64
+ if G is _A:raise ValueError(f"Metric #{H} has an invalid aggregation: {E}.")
62
65
  L[I]=G
63
66
  return L
64
67
  @dataclass
@@ -27,10 +27,10 @@ class ReaderCsv(ReaderInterface):
27
27
  if bool(re.match(B,line)):return _B
28
28
  return False
29
29
  def read(A,reader_options):
30
- C=reader_options;A.reader_options=C;F,O,V=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar,encoding=A.encoding);A.has_header=F;A.cols=O;A.numeric_col_indexes=V;A.index_col_index=_A;A.ignore_lines_patterns=_A;G=_A;H=_A;I=_A;J=_A;B=C.cols
30
+ C=reader_options;A.reader_options=C;F,L,V=csv_detect(A.origin.path,A.reader_options.delimiter,A.reader_options.quotechar,encoding=A.encoding);A.has_header=F;A.cols=L;A.numeric_col_indexes=V;A.index_col_index=_A;A.ignore_lines_patterns=_A;G=_A;H=_A;I=_A;J=_A;B=C.cols
31
31
  if B:
32
32
  if B.index_col:
33
- if B.index_col:R=get_col_indexes(col_x,D.numeric_col_indexes,D.names);A.index_col_index=R[0]if R else _A
33
+ if B.index_col:R=get_col_indexes(B.index_col,A.numeric_col_indexes,L);A.index_col_index=R[0]if R else _A
34
34
  if B.rows:
35
35
  A.ignore_lines_patterns=B.rows.ignore_patterns;G=B.rows.line_start;H=B.rows.line_end
36
36
  if G and H and H<G:raise ValueError(f"Line end {H} cannot be before line start {G}.")
@@ -40,9 +40,9 @@ class ReaderCsv(ReaderInterface):
40
40
  if I and J and I>J:raise ValueError(f"Index min value {I} cannot be greater than index max value {J}.")
41
41
  A.raw_lines_number=_A;A.curves=_A;A.report_matrices=_A
42
42
  with open(A.origin.path,'r',encoding=A.encoding)as W:
43
- S=W.readlines();L=csv.reader(S,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar)
43
+ S=W.readlines();M=csv.reader(S,delimiter=A.reader_options.delimiter,quotechar=A.reader_options.quotechar)
44
44
  if C.is_matrix:
45
- K=C.matrix or ReaderCsvMatrixConfig();P=mat_from_iterator(x_name=K.x_name,y_name=K.y_name,reader=L,has_header=F,x_value_line=K.x_value_line,has_y=K.has_y)
45
+ K=C.matrix or ReaderCsvMatrixConfig();P=mat_from_iterator(x_name=K.x_name,y_name=K.y_name,reader=M,has_header=F,x_value_line=K.x_value_line,has_y=K.has_y)
46
46
  if K.export_report:A.report_matrices=get_data([P],['csv'])
47
47
  A.mat_dataset=P;A.raw_lines_number=P.nb_lines+(1 if F else 0)
48
48
  else:
@@ -50,22 +50,22 @@ class ReaderCsv(ReaderInterface):
50
50
  if not F:raise Exception('Ignore columns is not supported without header.')
51
51
  if isinstance(C.cols.ignore_columns[0],str):A.numeric_col_indexes=[B for B in A.numeric_col_indexes if A.cols[B]not in C.cols.ignore_columns]
52
52
  if isinstance(C.cols.ignore_columns[0],int):X=[A-1 for A in B.ignore_columns];A.numeric_col_indexes=[A for A in A.numeric_col_indexes if A not in X]
53
- T=len(O);D=ColsDataset(cols_count=T,names=O,numeric_col_indexes=A.numeric_col_indexes,data=[[]for A in range(T)]);E=0
54
- if F and E==0:next(L);E+=1
53
+ T=len(L);D=ColsDataset(cols_count=T,names=L,numeric_col_indexes=A.numeric_col_indexes,data=[[]for A in range(T)]);E=0
54
+ if F and E==0:next(M);E+=1
55
55
  if G:
56
56
  try:
57
57
  while _B:
58
58
  if G<=E+1:break
59
- M=next(L);E+=1
59
+ N=next(M);E+=1
60
60
  except StopIteration:pass
61
61
  try:
62
62
  while _B:
63
- M=next(L);E+=1
63
+ N=next(M);E+=1
64
64
  if H and E>H:break
65
- if J is not _A and float(M[A.index_col_index])>J:break
65
+ if J is not _A and float(N[A.index_col_index])>J:break
66
66
  if A.ignore_lines_patterns and A._ignore_line(S[E-1].rstrip('\n')):continue
67
- if I is not _A and float(M[A.index_col_index])<I:continue
68
- for(U,Q)in enumerate(M):
67
+ if I is not _A and float(N[A.index_col_index])<I:continue
68
+ for(U,Q)in enumerate(N):
69
69
  if U in D.numeric_col_indexes:Q=float(Q)
70
70
  D.data[U].append(Q)
71
71
  D.origin_line_nb.append(E)
@@ -74,11 +74,11 @@ class ReaderCsv(ReaderInterface):
74
74
  if C.metrics:A.metrics=D.compute_metrics(C.metrics)
75
75
  if B and B.curve_parser:
76
76
  if B.curve_parser.name==ReaderCurveParserNameConfig.COL_X:
77
- N=_A
78
- if B.curve_parser.parameters:N=B.curve_parser.parameters.x
79
- elif B.index_col:N=B.index_col
80
- if not N:raise ValueError('Curve parser COL_X requires a parameter x, or index_col to be defined.')
81
- A.curves,Y=D.get_curves_col_x(N)
77
+ O=_A
78
+ if B.curve_parser.parameters:O=B.curve_parser.parameters.x
79
+ elif B.index_col:O=B.index_col
80
+ if not O:raise ValueError('Curve parser COL_X requires a parameter x, or index_col to be defined.')
81
+ A.curves,Y=D.get_curves_col_x(O)
82
82
  if A.curves:A.cols_curve=ColsCurves(type=ReaderCurveParserNameConfig.COL_X,info=Y,curves=A.curves)
83
83
  elif B.curve_parser.name==ReaderCurveParserNameConfig.COLS_COUPLE:raise NotImplementedError('cols_couple not implemented')
84
84
  else:raise Exception('Curve parser not supported.')
@@ -1,27 +1,24 @@
1
1
  import logging,os
2
- from mimetypes import MimeTypes
3
- from scilens.app import pkg_name,pkg_version,pkg_homepage,product_name,powered_by
4
2
  from scilens.config.models import ReportConfig
5
3
  from scilens.report.template import template_render_infolder
6
4
  from scilens.report.assets import get_image_base64,get_image_base64_local,get_logo_image_src
7
- from scilens.utils.time_tracker import TimeTracker
8
5
  class HtmlReport:
9
6
  def __init__(A,config,alt_config_dirs,working_dir=None):A.config=config;A.alt_config_dirs=alt_config_dirs;A.working_dir=working_dir
10
- def process(A,processor,data,task_name):
11
- I='meta';H='date';logging.info(f"Processing html report");J=TimeTracker();B=J.get_data()['start']
7
+ def process(A,data):
8
+ G='meta';logging.info(f"Processing html report")
12
9
  if A.config.logo and A.config.logo_file:raise ValueError('logo and logo_file are exclusive.')
13
- K=A.config.logo;C=None
10
+ H=A.config.logo;B=None
14
11
  if A.config.logo_file:
15
- D=A.config.logo_file
16
- if os.path.isabs(D):
17
- C=D
18
- if not os.path.isfile(E):raise FileNotFoundError(f"Logo file '{A.config.logo_file}' not found.")
12
+ C=A.config.logo_file
13
+ if os.path.isabs(C):
14
+ B=C
15
+ if not os.path.isfile(D):raise FileNotFoundError(f"Logo file '{A.config.logo_file}' not found.")
19
16
  else:
20
- F=list(set([A.working_dir]+A.alt_config_dirs))
21
- for L in F:
22
- E=os.path.join(L,D)
23
- if os.path.isfile(E):C=E;break
24
- if not C:raise FileNotFoundError(f"Logo file '{A.config.logo_file}' not found in {F}.")
25
- M=A.config.title if A.config.title else A.config.title_prefix+' '+task_name;N={'app_name':product_name,'app_version':pkg_version,'app_homepage':pkg_homepage,'app_copyright':f"© {B[H][:4]} {powered_by['name']}. All rights reserved",'app_powered_by':powered_by,'execution_utc_datetime':B['datetime'],'execution_utc_date':B[H],'execution_utc_time':B['time'],'execution_dir':A.working_dir,'title':M,'description':A.config.description,'image':K or get_logo_image_src(C),'config':A.config.html,'config_json':A.config.html.model_dump_json()};G=None
26
- if A.config.debug:G=A.config.model_dump_json(indent=4)
27
- return template_render_infolder('index.html',{I:N,'task':data.get(I),'data':{'files':data.get('processor_results')},'debug':G})
17
+ E=list(set([A.working_dir]+A.alt_config_dirs))
18
+ for I in E:
19
+ D=os.path.join(I,C)
20
+ if os.path.isfile(D):B=D;break
21
+ if not B:raise FileNotFoundError(f"Logo file '{A.config.logo_file}' not found in {E}.")
22
+ F=None
23
+ if A.config.debug:F=A.config.model_dump_json(indent=4)
24
+ return template_render_infolder('index.html',{'image':H or get_logo_image_src(B),'execution_dir':A.working_dir,'config_html':A.config.html,'config_html_json':A.config.html.model_dump_json(),G:data.get(G),'data':{'files':data.get('processor_results')},'debug':F})
scilens/report/report.py CHANGED
@@ -9,22 +9,22 @@ class ReportProcessResults(BaseModel):files_created:list[str]=[]
9
9
  class Report:
10
10
  def __init__(B,working_dir,alt_config_dirs,config,task_name):A=config;B.path=working_dir;B.alt_config_dirs=alt_config_dirs;B.config=A;B.task_name=task_name;B.extensions={'txt':A.output.export_txt,'json':A.output.export_json,'yaml':A.output.export_yaml,_A:A.output.export_html,'py':A.output.export_py,'js':A.output.export_js,'ts':A.output.export_ts,'php':A.output.export_php}
11
11
  def _get_file(A,ext):return os.path.join(A.path,f"{A.config.output.filename}.{ext}")
12
- def process(B,data,processor=None):
13
- I=False;D=data;E=ReportProcessResults();logging.info(f"Processing report");J=B.config;F=B.extensions;logging.info(f"Cleaning reports")
12
+ def process(B,data):
13
+ J='utf-8';I=False;D=data;E=ReportProcessResults();logging.info(f"Processing report");K=B.config;F=B.extensions;logging.info(f"Cleaning reports")
14
14
  for A in F:file_remove(B._get_file(A))
15
15
  G=I
16
- for(A,K)in F.items():
17
- if K:
16
+ for(A,L)in F.items():
17
+ if L:
18
18
  logging.info(f"Creating report {A}");G=True;C=B._get_file(A);H=True
19
19
  if A=='txt':text_write(C,str(D))
20
- elif A=='json':json_write(C,D)
20
+ elif A=='json':json_write(C,D,encoding=J)
21
21
  elif A=='yaml':yaml_write(C,D)
22
22
  elif A=='py':text_write(C,'DATA = '+format(D))
23
23
  elif A in['js','ts']:text_write(C,'export default '+json.dumps(D))
24
24
  elif A=='php':text_write(C,'<?php\nreturn '+dict_to_php_array(D)+';\n')
25
- elif A==_A:text_write(C,HtmlReport(B.config,B.alt_config_dirs,B.path).process(processor,D,B.task_name),encoding='utf-8')
25
+ elif A==_A:text_write(C,HtmlReport(B.config,B.alt_config_dirs,B.path).process(D),encoding=J)
26
26
  else:H=I;logging.error(f"Extension {A} not implemented")
27
27
  if H:E.files_created.append(C)
28
- if J.output.export_html:logging.info(f"Report generated at file://{B._get_file(_A)}")
28
+ if K.output.export_html:logging.info(f"Report generated at file://{B._get_file(_A)}")
29
29
  if not G:logging.warning(f"No report to process")
30
30
  return E
@@ -0,0 +1,4 @@
1
+ import datetime as dt
2
+ from scilens.app import pkg_name,pkg_version,pkg_homepage,product_name,powered_by
3
+ class ReportAppInfo:
4
+ def info(C):A='name';B=dt.datetime.now(dt.timezone.utc).strftime('%Y');return{A:product_name,'version':pkg_version,'homepage':pkg_homepage,'copyright':f"© {B} {powered_by[A]}. All rights reserved",'powered_by':powered_by}
@@ -0,0 +1,4 @@
1
+ from scilens.config.models import ReportConfig
2
+ from scilens.utils.time_tracker import TimeTracker
3
+ class ReportAttributesInfo:
4
+ def info(E,config,task_name):A=config;C=A.title if A.title else A.title_prefix+' '+task_name;D=TimeTracker();B=D.get_data()['start'];return{'title':C,'description':A.description,'execution_utc_date':B['date'],'execution_utc_time':B['time']}
@@ -0,0 +1,9 @@
1
+ class ReportProcessorInfo:
2
+ def info(G,processor,data):
3
+ E='comparison';B=processor;A={'name':B};F=B in['Compare','ExecuteAndCompare'];A['has_multiple_datasets']=len(data)>1
4
+ if F:
5
+ A['is_compare']=True;C=0
6
+ for D in data:
7
+ if D.get(E)and D[E].get('metrics'):C+=1
8
+ A['datasets_metrics']=C
9
+ return A
@@ -1,7 +1,7 @@
1
1
  <!-- TITLE -->
2
2
  <h1>
3
- {% if meta.image %}<img height="{{ meta.config.logo_height }}" src="{{ meta.image }}"/>{% endif %}
4
- {{ meta.title }}
3
+ {% if image %}<img height="{{ config_html.logo_height }}" src="{{ image }}"/>{% endif %}
4
+ {{ meta.report_info.title }}
5
5
  {{ data.name }}
6
6
  </h1>
7
7
  {% if debug %}
@@ -12,8 +12,8 @@
12
12
  <!-- INFO -->
13
13
  <div class="muted">
14
14
  Report generated
15
- on {{ meta.execution_utc_date }} at {{ meta.execution_utc_time }} UTC
16
- by <a href="{{ meta.app_homepage }}" target="_blank">{{ meta.app_name }} v{{ meta.app_version }}</a>
15
+ on {{ meta.report_info.execution_utc_date }} at {{ meta.report_info.execution_utc_time }} UTC
16
+ by <a href="{{ meta.app_info.homepage }}" target="_blank">{{ meta.app_info.name }} v{{ meta.app_info.version }}</a>
17
17
  </div>
18
18
  <!-- DIAGNOSE -->
19
19
  <!-- PARAMETERS -->
@@ -26,21 +26,35 @@
26
26
  <div>Info</div>
27
27
  <table style="border:none;">
28
28
  <tr>
29
+ <td style="vertical-align: top;border:none;">
30
+ <strong>Application</strong>
31
+ <table>
32
+ <tr><th>name</th><td>{{ meta.app_info.name }}</td></tr>
33
+ <tr><th>version</th><td>{{ meta.app_info.version }}</td></tr>
34
+ </table>
35
+ </td>
29
36
  <td style="vertical-align: top;border:none;">
30
37
  <strong>System</strong>
31
38
  <table>
32
- <tr><th>os</th><td>{{ task.system_info.os }}</td></tr>
33
- <tr><th>arch</th><td>{{ task.system_info.arch }}</td></tr>
34
- <tr><th>python</th><td>{{ task.system_info.python }}</td></tr>
35
- <tr><th>python_info</th><td>{{ task.system_info.python_info }}</td></tr>
39
+ <tr><th>os</th><td>{{ meta.system_info.os }}</td></tr>
40
+ <tr><th>arch</th><td>{{ meta.system_info.arch }}</td></tr>
41
+ <tr><th>python</th><td>{{ meta.system_info.python }}</td></tr>
42
+ <tr><th>python_info</th><td>{{ meta.system_info.python_info }}</td></tr>
43
+ </table>
44
+ </td>
45
+ <td style="vertical-align: top;border:none;">
46
+ <strong>Task</strong>
47
+ <table>
48
+ <tr><th>Name</th><td>{{ meta.task_info.name }}</td></tr>
49
+ <tr><th>Start</th><td>{{ meta.task_info.process_time.start.datetime }}</td></tr>
50
+ <tr><th>End</th><td>{{ meta.task_info.process_time.end.datetime }}</td></tr>
51
+ <tr><th>Duration</th><td>{{ meta.task_info.process_time.duration_seconds }}s</td></tr>
36
52
  </table>
37
53
  </td>
38
54
  <td style="vertical-align: top;border:none;">
39
- <strong>Task Process</strong>
55
+ <strong>Processor</strong>
40
56
  <table>
41
- <tr><th>Processor</th><td>{{ task.task_info.processor }}</td></tr>
42
- <tr><th>Start</th><td>{{ task.task_info.process_time.start.datetime }}</td></tr>
43
- <tr><th>End</th><td>{{ task.task_info.process_time.end.datetime }}</td></tr>
57
+ <tr><th>Processor</th><td>{{ meta.processor_info.name }}</td></tr>
44
58
  </table>
45
59
  </td>
46
60
  </tr>
@@ -1,11 +1,11 @@
1
1
  <div class="footer muted">
2
2
  <div class="py-1">
3
- <a href="{{ meta.app_homepage }}" target="_blank">{{ meta.app_name }} - {{ meta.app_version }}</a>
3
+ <a href="{{ meta.app_info.homepage }}" target="_blank">{{ meta.app_info.name }} - {{ meta.app_info.version }}</a>
4
4
  </div>
5
5
  <div class="py-1">
6
- Powered by <a href="{{ meta.app_powered_by.url }}" target="_blank">{{ meta.app_powered_by.name }}</a>
6
+ Powered by <a href="{{ meta.app_info.powered_by.url }}" target="_blank">{{ meta.app_info.powered_by.name }}</a>
7
7
  </div>
8
8
  <div class="py-1">
9
- {{ meta.app_copyright }}
9
+ {{ meta.app_info.copyright }}
10
10
  </div>
11
11
  </div>
@@ -3,15 +3,15 @@
3
3
  <h2>Summary</h2>
4
4
 
5
5
  <!-- DESCRIPTION -->
6
- {% if meta.description %}
6
+ {% if meta.report_info.description %}
7
7
  <!-- <h3>Description</h3> -->
8
8
  <div id="section_summary_description" class="description">
9
- {{ meta.description }}
9
+ {{ meta.report_info.description }}
10
10
  </div>
11
11
  {% endif %}
12
12
 
13
13
  <!-- EXTRA HTML -->
14
- {% if meta.config.extra_html_summary %}{{ meta.config.extra_html_summary }}{% endif %}
14
+ {% if config_html.extra_html_summary %}{{ config_html.extra_html_summary }}{% endif %}
15
15
 
16
16
  <!-- METRICS -->
17
17
  {% include 'compare_11_summary_metrics.html' %}
@@ -37,10 +37,10 @@
37
37
  <td>{{ file.name }}</td>
38
38
  <td class="center">{% if not file.skipped %}<button onclick="actions.see_details({{ loop.index }})">[...]</button>{% endif %}</td>
39
39
  <td class="center test-bg-20">
40
- {% if file.test.origin and file.test.origin.path %}<action data-command="open_file" data-args="{{ file.test.origin.path.replace(meta.execution_dir, "") }}" data-label="[...]"></action>{% endif %}
40
+ {% if file.test.origin and file.test.origin.path %}<action data-command="open_file" data-args="{{ file.test.origin.path.replace(execution_dir, "") }}" data-label="[...]"></action>{% endif %}
41
41
  </td>
42
42
  <td class="center refe-bg-20">
43
- {% if file.ref.origin and file.ref.origin.path %}<action data-command="open_file" data-args="{{ file.ref.origin.path.replace(meta.execution_dir, "") }}" data-label="[...]"></action>{% endif %}
43
+ {% if file.ref.origin and file.ref.origin.path %}<action data-command="open_file" data-args="{{ file.ref.origin.path.replace(execution_dir, "") }}" data-label="[...]"></action>{% endif %}
44
44
  </td>
45
45
  <td class="{{ 'ERROR' if file.error else '' }}">
46
46
  {% if file.error %}<span>{{ file.error }}</span>{% endif %}
@@ -1,9 +1,13 @@
1
- {% for file in data.files %}
2
- {% if file.test.metrics %}
3
- <h3>Metrics <action data-command="toogle" data-args="section_summary_metrics"></action></h3>
4
- <div id="section_summary_metrics">
5
- <div style="display: flex; flex-wrap: wrap;">
6
- <!-- <div class="kpi-container"> -->
1
+ {% if meta.processor_info.datasets_metrics %}
2
+ <h3>Metrics <action data-command="toogle" data-args="section_summary_metrics"></action></h3>
3
+ <div id="section_summary_metrics">
4
+
5
+ {% for file in data.files %}
6
+ {% if file.test.metrics %}
7
+ {% if meta.processor_info.has_multiple_datasets and meta.processor_info.datasets_metrics > 1 %}
8
+ <h4>{{ file.name }}</h4>
9
+ {% endif %}
10
+ <div style="display: flex; flex-wrap: wrap;">
7
11
  {% for metric_k, metric_test in file.test.metrics.items() %}
8
12
  {% set metric_status = file.comparison.metrics[metric_k].status if file.comparison.metrics else None %}
9
13
  {% set metric_err_index = file.comparison.metrics[metric_k].err_index if metric_status else None %}
@@ -16,10 +20,12 @@
16
20
  metric_err
17
21
  ) }}
18
22
  {% endfor %}
19
- </div>
20
- </div>
21
- {% endif %}
22
- {% endfor %}
23
+ </div>
24
+ {% endif %}
25
+ {% endfor %}
26
+
27
+ </div>
28
+ {% endif %}
23
29
 
24
30
 
25
31
 
@@ -13,11 +13,11 @@
13
13
  <span style="font-size:0.9rem;color:#666;">(#{{ file_index }})</span>
14
14
  <!-- actions -->
15
15
  <action data-command="toogle" data-args="file_content_{{ file_index|string }}"></action>
16
- {% if file.test.origin and file.test.origin.path %}<action data-command="open_file" data-args="{{ file.test.origin.path.replace(meta.execution_dir, "") }}" data-label="Open Test"></action>{% endif %}
17
- {% if file.ref.origin and file.ref.origin.path %}<action data-command="open_file" data-args="{{ file.ref.origin.path.replace(meta.execution_dir, "") }}" data-label="Open Ref."></action>{% endif %}
16
+ {% if file.test.origin and file.test.origin.path %}<action data-command="open_file" data-args="{{ file.test.origin.path.replace(execution_dir, "") }}" data-label="Open Test"></action>{% endif %}
17
+ {% if file.ref.origin and file.ref.origin.path %}<action data-command="open_file" data-args="{{ file.ref.origin.path.replace(execution_dir, "") }}" data-label="Open Ref."></action>{% endif %}
18
18
  </h2>
19
19
  <!-- CONTENT -->
20
- <div id="file_content_{{ file_index }}" style="{% if not file.error and meta.config.collapse_if_successful %} display:none;{% endif %}">
20
+ <div id="file_content_{{ file_index }}" style="{% if not file.error and config_html.collapse_if_successful %} display:none;{% endif %}">
21
21
 
22
22
  <!--GENERAL ERROR-->
23
23
  {% if file.error %}
@@ -131,7 +131,7 @@
131
131
  <!-- MATRICES -->
132
132
  {% if file.test.matrices %}
133
133
  {% for item in [{"id": "spectrograms", "label": "Spectrograms"}, {"id": "frameseries", "label": "Frameseries"}] %}
134
- {% if meta.config.matrix[item.id] %}
134
+ {% if config_html.matrix[item.id] %}
135
135
  <h3>{{ item.label }} <action data-command="toogle" data-args="{{ item.id }}_{{ file_index|string }}"></action></h3>
136
136
  <div id="{{ item.id }}_{{ file_index }}" ></div>
137
137
  {% endif %}
@@ -1,5 +1,5 @@
1
- {% set img_test = file.test.origin.path.replace(meta.execution_dir, "") %}
2
- {% set img_ref = file.ref.origin.path.replace(meta.execution_dir, "") %}
1
+ {% set img_test = file.test.origin.path.replace(execution_dir, "") %}
2
+ {% set img_ref = file.ref.origin.path.replace(execution_dir, "") %}
3
3
  {% set img_w = file.test.reader_info.width %}
4
4
  {% set img_h = file.test.reader_info.height %}
5
5
  {% set style = "width: 200px; height: 80px;" %}
@@ -14,14 +14,14 @@
14
14
  {% set ns.statuses = ns.statuses + ['SKIPPED' if file.skipped else ('ERROR' if file.error else ('WARNING' if file.comparison_errors and file.comparison_errors.error_nb > 0 else 'SUCCESS'))] %}
15
15
  {% if file.test.matrices %}
16
16
  {% set ns.has_matrices = true %}
17
- {% if meta.config.matrix.spectrograms %}{% set ns.has_spectrograms = true %}{% endif %}
18
- {% if meta.config.matrix.frameseries %}{% set ns.has_frameseries = true %}{% endif %}
17
+ {% if config_html.matrix.spectrograms %}{% set ns.has_spectrograms = true %}{% endif %}
18
+ {% if config_html.matrix.frameseries %}{% set ns.has_frameseries = true %}{% endif %}
19
19
  {% endif %}
20
20
  {% endfor %}
21
21
  <html>
22
22
  <head>
23
23
  <meta charset="utf-8"/>
24
- <title id="head-title">{{ meta.title }} {{ data.name }}</title>
24
+ <title id="head-title">{{ meta.report_info.title }} {{ data.name }}</title>
25
25
  <!-- <script src="https://cdn.jsdelivr.net/npm/resemblejs@5.0.0/resemble.min.js"></script> -->
26
26
  <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
27
27
  <script src="https://cdn.plot.ly/plotly-2.34.0.min.js" charset="utf-8"></script>
@@ -42,17 +42,17 @@
42
42
  {% include 'utils_compare_report_anim.js' %}
43
43
  {% include 'utils_compare_report_framesseries.js' %}
44
44
 
45
- {% if meta.config.matrix.spectrograms %}
45
+ {% if config_html.matrix.spectrograms %}
46
46
  {% include 'uti_spectrograms.js' %}
47
47
  Spectrograms.config({
48
- "DISPLAY_TESTREF": {{ meta.config.matrix.spectrograms.test_ref }},
49
- "DISPLAY_DIFF": {{ meta.config.matrix.spectrograms.differences }},
50
- "WIDTH": {{ meta.config.matrix.spectrograms.init_width }},
51
- "HEIGHT": {{ meta.config.matrix.spectrograms.init_height }},
52
- "IS_3D": {{ meta.config.matrix.spectrograms.is_3D }},
48
+ "DISPLAY_TESTREF": {{ config_html.matrix.spectrograms.test_ref }},
49
+ "DISPLAY_DIFF": {{ config_html.matrix.spectrograms.differences }},
50
+ "WIDTH": {{ config_html.matrix.spectrograms.init_width }},
51
+ "HEIGHT": {{ config_html.matrix.spectrograms.init_height }},
52
+ "IS_3D": {{ config_html.matrix.spectrograms.is_3D }},
53
53
  });
54
54
  {% endif %}
55
- {% if meta.config.matrix.frameseries %}
55
+ {% if config_html.matrix.frameseries %}
56
56
  {% include 'uti_frameseries.js' %}
57
57
  {% endif %}
58
58
  {% if ns.has_matrices %}{% include 'uti_matrix.js' %}{% endif %}
@@ -107,20 +107,20 @@ function load_file_section(global_var, section_prefix, cls) {
107
107
  user-select: none; /* Standard syntax */
108
108
  }
109
109
  </style>
110
- {% if meta.config.custom_style %}<style type="text/css">{{ meta.config.custom_style }}</style>{% endif %}
111
- {% if meta.config.custom_script_head %}<script>{{ meta.config.custom_script_head }}</script>{% endif %}
110
+ {% if config_html.custom_style %}<style type="text/css">{{ config_html.custom_style }}</style>{% endif %}
111
+ {% if config_html.custom_script_head %}<script>{{ config_html.custom_script_head }}</script>{% endif %}
112
112
  </head>
113
113
  <body>
114
114
  {% include 'body_01_title.html' with context %}
115
- {% if meta.config.extra_html_start %}{{ meta.config.extra_html_start }}{% endif %}
115
+ {% if config_html.extra_html_start %}{{ config_html.extra_html_start }}{% endif %}
116
116
  {% include 'body_02_tabs.html' with context %}
117
117
  {% include 'compare_11_summary.html' with context %}
118
118
  {% include 'compare_12_sections.html' with context %}
119
- {% if meta.config.extra_html_end %}{{ meta.config.extra_html_end }}{% endif %}
119
+ {% if config_html.extra_html_end %}{{ config_html.extra_html_end }}{% endif %}
120
120
  {% include 'body_99_footer.html' with context %}
121
121
  <script type="text/javascript">
122
122
  const GLOBAL_VARS = {};
123
- const GLOBAL_CONFIG = {{ meta.config_json }};
123
+ const GLOBAL_CONFIG = {{ config_html_json }};
124
124
  actions.init_page();
125
125
  if (SLImages) SLImages.init();
126
126
  </script>
@@ -147,6 +147,6 @@ function load_file_section(global_var, section_prefix, cls) {
147
147
  MatrixMgmt.loadGlobal({{ns.has_spectrograms}}, {{ns.has_frameseries}});
148
148
  </script>
149
149
  {% endif %}
150
- {% if meta.config.custom_script_body %}<script>{{ meta.config.custom_script_body }}</script>{% endif %}
150
+ {% if config_html.custom_script_body %}<script>{{ config_html.custom_script_body }}</script>{% endif %}
151
151
  </body>
152
152
  </html>
@@ -10,16 +10,16 @@
10
10
  {
11
11
  id: 'page_mode',
12
12
  label: 'Display Mode',
13
- is_user: {{ 'true' if meta.config.parameter_page_mode.is_user_preference else 'false' }},
13
+ is_user: {{ 'true' if config_html.parameter_page_mode.is_user_preference else 'false' }},
14
14
  values: ['onepage', 'tabs'],
15
15
  action: "actions.render_page()",
16
- default: '{{ meta.config.parameter_page_mode.default_value}}',
16
+ default: '{{ config_html.parameter_page_mode.default_value}}',
17
17
  },{
18
18
  id: 'open_file_in',
19
19
  label: 'Open File in',
20
- is_user: {{ 'true' if meta.config.parameter_open_file_in.is_user_preference else 'false' }},
20
+ is_user: {{ 'true' if config_html.parameter_open_file_in.is_user_preference else 'false' }},
21
21
  values: ['browser', 'vscode'],
22
- default: '{{ meta.config.parameter_open_file_in.default_value}}',
22
+ default: '{{ config_html.parameter_open_file_in.default_value}}',
23
23
  },{
24
24
  id: 'js_lib',
25
25
  label: 'Chart Lib',
@@ -54,12 +54,12 @@ background-color: #fafafa;
54
54
  .ERROR { background-color:#c52a0f20;color:#c52a0f; }
55
55
  .WARNING { background-color:#bcbc0620;color:#bcbc06; }
56
56
  .SUCCESS { background-color:#16840020;color:#168400; }
57
- .test-bg-80 { background-color:#{{ meta.config.compare_color_test }}80; }
58
- .test-bg-50 { background-color:#{{ meta.config.compare_color_test }}50; }
59
- .test-bg-20 { background-color:#{{ meta.config.compare_color_test }}20; }
60
- .refe-bg-80 { background-color:#{{ meta.config.compare_color_reference }}80; }
61
- .refe-bg-50 { background-color:#{{ meta.config.compare_color_reference }}50; }
62
- .refe-bg-20 { background-color:#{{ meta.config.compare_color_reference }}20; }
57
+ .test-bg-80 { background-color:#{{ config_html.compare_color_test }}80; }
58
+ .test-bg-50 { background-color:#{{ config_html.compare_color_test }}50; }
59
+ .test-bg-20 { background-color:#{{ config_html.compare_color_test }}20; }
60
+ .refe-bg-80 { background-color:#{{ config_html.compare_color_reference }}80; }
61
+ .refe-bg-50 { background-color:#{{ config_html.compare_color_reference }}50; }
62
+ .refe-bg-20 { background-color:#{{ config_html.compare_color_reference }}20; }
63
63
  th {
64
64
  background-color:#eee;color:#333;
65
65
  }
scilens/run/run_task.py CHANGED
@@ -8,6 +8,9 @@ from scilens.run.task_context import TaskContext
8
8
  from scilens.processors.models.results import ProcessorResults
9
9
  from scilens.processors import Analyse,Compare,ExecuteAndCompare
10
10
  from scilens.report.report import Report
11
+ from scilens.report.report_app_info import ReportAppInfo
12
+ from scilens.report.report_processor_info import ReportProcessorInfo
13
+ from scilens.report.report_attributes_info import ReportAttributesInfo
11
14
  from scilens.utils.system import info as system_info
12
15
  from scilens.utils.time_tracker import TimeTracker
13
16
  from scilens.utils.template import template_render_string
@@ -35,14 +38,14 @@ class RunTask:
35
38
  def __init__(A,context):A.context=context
36
39
  def _get_processors(A):return{A.__name__:A for A in[Analyse,Compare,ExecuteAndCompare]}
37
40
  def process(A):
38
- logging.info(f"Running task");logging.info(f"Prepare runtime variables");H=runtime_process_vars(A.context.config);logging.info(f"Apply runtime variables to config");runtime_apply_to_config(H,A.context.config,A.context.working_dir);logging.debug(f"on working_dir '{A.context.working_dir}'");logging.debug(f"with origin_working_dir '{A.context.origin_working_dir}'");logging.debug(f"with config {A.context.config.model_dump_json(indent=4)}");C=A.context.config.processor
39
- if not C:raise Exception('Processor not defined in config.')
40
- D=A._get_processors().get(C)
41
- if not D:raise Exception('Processor not found.')
42
- logging.info(f"Processor '{D.__name__}'")
43
- try:F=TimeTracker();G=D(A.context);E=G.process();F.stop();I=F.get_data()
41
+ logging.info(f"Running task");logging.info(f"Prepare runtime variables");H=runtime_process_vars(A.context.config);logging.info(f"Apply runtime variables to config");runtime_apply_to_config(H,A.context.config,A.context.working_dir);logging.debug(f"on working_dir '{A.context.working_dir}'");logging.debug(f"with origin_working_dir '{A.context.origin_working_dir}'");logging.debug(f"with config {A.context.config.model_dump_json(indent=4)}");D=A.context.config.processor
42
+ if not D:raise Exception('Processor not defined in config.')
43
+ E=A._get_processors().get(D)
44
+ if not E:raise Exception('Processor not found.')
45
+ logging.info(f"Processor '{E.__name__}'")
46
+ try:F=TimeTracker();G=E(A.context);C=G.process();F.stop();I=F.get_data()
44
47
  except Exception as B:logging.error(B);return TaskResults(error=str(B))
45
48
  finally:G=None
46
- try:J=Report(A.context.working_dir,[A.context.origin_working_dir],A.context.config.report,A.context.task_name).process({'meta':{'system_info':system_info(),'task_info':{'processor':C,'process_time':I}},'processor_results':E.data},C)
47
- except Exception as B:logging.error(B);return TaskResults(error=str(B),processor_results=E)
48
- return TaskResults(processor_results=E,report_results=J)
49
+ try:J=ReportAttributesInfo().info(A.context.config.report,A.context.task_name);K=ReportAppInfo().info();L=ReportProcessorInfo().info(D,C.data);M=Report(A.context.working_dir,[A.context.origin_working_dir],A.context.config.report,A.context.task_name).process({'meta':{'report_info':J,'app_info':K,'system_info':system_info(),'task_info':{'name':A.context.task_name,'process_time':I},'processor_info':L},'processor_results':C.data})
50
+ except Exception as B:logging.error(B);return TaskResults(error=str(B),processor_results=C)
51
+ return TaskResults(processor_results=C,report_results=M)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scilens
3
- Version: 0.4.8
3
+ Version: 0.4.10
4
4
  Summary: A CesGensLaB framework for data collecting and deep analysis
5
5
  Home-page: https://scilens.dev
6
6
  License: Proprietary
@@ -20,7 +20,7 @@ scilens/config/cli_run_options.py,sha256=Ls7yK5QDUPFbk73nbjGuPvuRbBRYw4Miag5ISpu
20
20
  scilens/config/env_var.py,sha256=NqNBoIfngJEXaGEm7jGqre5pmkJ9eUjiWzbDrTVfi2c,292
21
21
  scilens/config/load.py,sha256=ltcv90GlsMJR2FE2ZL_jDscL7k5aGoHoMatWw61lrTw,1672
22
22
  scilens/config/models/__init__.py,sha256=eLCW1OLVINewGFy5GXSrOk8Rab_QsgKAuoErBjphHRs,673
23
- scilens/config/models/app.py,sha256=T3zCqJKmRw8jwtmAdIogOfmuds1EI6hzhxGix-q5hRA,1468
23
+ scilens/config/models/app.py,sha256=UCC7Be6gOwvxQpM5Wl1HIf2Xb61CmslFzXvj_50eqsQ,1558
24
24
  scilens/config/models/base.py,sha256=k92CR8TA5L8dZJtg28c8albk16AK9-3umdosA7aYsxw,499
25
25
  scilens/config/models/compare.py,sha256=IiH1wJWYVnPnUJ3BiMeGDy8CFHwPOw1nQS2wfk-0p44,2152
26
26
  scilens/config/models/compare_float_thresholds.py,sha256=M8flQmu5B-Lc-RStn-kcQJZum_kZxj591w8myyQQuEY,2127
@@ -49,10 +49,10 @@ scilens/processors/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
49
49
  scilens/processors/models/results.py,sha256=KoWxh13Zgi7PuPql8hkf4VjCis42ZxAuzIgJxBWVaX8,119
50
50
  scilens/processors/processor_interface.py,sha256=jzMp1529JXnMGTJijVy6b_1zmARAMNv70f2lgys7vn4,452
51
51
  scilens/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
- scilens/readers/cols_dataset.py,sha256=l6WXl71n-yTgUUbd2KEMwwXmXdqF54N9edeI3saAO84,3941
52
+ scilens/readers/cols_dataset.py,sha256=r8-torONsaXzYUvKRjguCu_d36MSv1ceWxNoRP2-9xk,4018
53
53
  scilens/readers/exceptions.py,sha256=JzmxcjnR5sH-IOWVeCC5A1bSwxv-jCAtIJvDjzx1CTI,32
54
54
  scilens/readers/mat_dataset.py,sha256=Z9TYDWaH2aqdniLNDjlpR6VVNHMSARjh52clhdMyOn4,1496
55
- scilens/readers/reader_csv.py,sha256=TygAwFFqj8K7d-M2HtD3VzhS8nobPATQ0QmLJOOAye0,5550
55
+ scilens/readers/reader_csv.py,sha256=FKxx26Vzf_h25cFX37DwFXy_-toUGw3481iMbyRa-vg,5550
56
56
  scilens/readers/reader_interface.py,sha256=r1pu9LyweTGXU8YfI3FPZy1Em4stzmJb-6j90j1tPQQ,938
57
57
  scilens/readers/reader_manager.py,sha256=DFinxIk3IIIcB6JxybGcv-mXt3jhXgCwUtzR0TqhB2Q,2684
58
58
  scilens/readers/reader_txt.py,sha256=U3hGIorj-Nv-jq6zYtvbDv2LQBHTgW52PHbV8A5FMA8,4526
@@ -62,33 +62,36 @@ scilens/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  scilens/report/assets/logo.svg,sha256=W-1OVqcvdBjf-1AHHcV6WciIUqBoVFUh52Tc3o_jqtA,4519
63
63
  scilens/report/assets/logo_cglb.svg,sha256=tEpkSr2h-jjQMecqiHef98Mxod4GD5j5nCQaFloTYso,2411
64
64
  scilens/report/assets.py,sha256=CcfGc9NNGnPVinkHZkEyN2S_BGKNIyMFvVdA__-M6-0,532
65
- scilens/report/html_report.py,sha256=ml_paRkzI81irpeWNtEkBOHkK0W7veNU6RbVM6RLM6E,1940
66
- scilens/report/report.py,sha256=E8C4tyMSQd8JbOQU0xC3R0bwPMRc4DS0o3QAq-PvXho,1828
65
+ scilens/report/html_report.py,sha256=lfRUUyNqb2HjdohKXpt1XZW2s6mhwL7mwzbLpVoahzk,1305
66
+ scilens/report/report.py,sha256=tgtpP4gCN0gKUx-6Owtmb18sOFjFCKuk9pWM30jaWS8,1806
67
+ scilens/report/report_app_info.py,sha256=r3umU64EDKilxxQha0SC2dupt33fBen-dKA44McseTU,348
68
+ scilens/report/report_attributes_info.py,sha256=OjPjXpTvQJvu1-iHBhnGcPuaniG56fcZ7wpH4ZZ3L5w,367
69
+ scilens/report/report_processor_info.py,sha256=2A1bGqLYPPIzCHkNlfw--FGoS_HeYRh-oonBlSRmrgs,310
67
70
  scilens/report/template.py,sha256=cPs5gd3uEwb-6JgitGQD_i4IiUxigBTlZLNRS9KVuos,581
68
- scilens/report/templates/body_01_title.html,sha256=LJOWO6ImNPW9cg3tCDlgdllVTwnFGWcb2qvA3yv6wNk,1758
71
+ scilens/report/templates/body_01_title.html,sha256=jjWspY_B2w_QA49Ag9U6-Yrzz4ohl728nytDxyHXlnw,2359
69
72
  scilens/report/templates/body_02_tabs.html,sha256=hooRO_OJPwAQSa6GBsPLca-OnpiHkr3wZ_0NoXGKGR0,465
70
- scilens/report/templates/body_99_footer.html,sha256=8cWebeWfZwZ-9bYAMZkZj8rbCWq3BLIMjKQThWQxoQM,362
71
- scilens/report/templates/compare_11_summary.html,sha256=Goknx4slzt8JX2rq05hf31HTXjkOHUX8u2jYazaUkmc,751
72
- scilens/report/templates/compare_11_summary_datasets.html,sha256=iUhOhZpAc4yLsHqDinx30xQDjLcbXRXU72Ud6n29GBQ,3495
73
+ scilens/report/templates/body_99_footer.html,sha256=KGTKa_DF0dMsX9K4vEbPxy0gY0Kcj0HSEHh0M3sx5TA,392
74
+ scilens/report/templates/compare_11_summary.html,sha256=pT10Id_Rzkk5Z6l1WM3E8JtuD7etuDg8XU5aMwMZ2d8,775
75
+ scilens/report/templates/compare_11_summary_datasets.html,sha256=tP1JmkYjmxyEOx8fX07MrEoE7XKvmgG7kx7-_3h2PL4,3485
73
76
  scilens/report/templates/compare_11_summary_metrics copy.html,sha256=y8hfw8W5GXR7CRDEmlgk_IN100gfF3-67UqvAIMrxPA,623
74
- scilens/report/templates/compare_11_summary_metrics.html,sha256=2qi2ME6VrV68mxnTZq3zS-GEPc5vwhFgswswXEpt_34,966
75
- scilens/report/templates/compare_12_sections.html,sha256=D2_T0GVy2ntRl92ih2ZrRCduHDzuprq5v6i6Ey5MYXA,6311
76
- scilens/report/templates/compare_13_section_images.html,sha256=8z6gwsw6-eCFGb0quEq2WRFfykg-8b1msvTA1vftxS4,945
77
+ scilens/report/templates/compare_11_summary_metrics.html,sha256=1bbRENZYi_HOHFGDLmV_HvLYirSqKBPCJWnVsJVGuFo,1164
78
+ scilens/report/templates/compare_12_sections.html,sha256=X0YP_LgpzdIoM2rqEip9uoR9cng4qQ1ruPTSh4TEQ7Y,6301
79
+ scilens/report/templates/compare_13_section_images.html,sha256=RZ2WGpbuW9eCgmY8szNNVPCTtllm8KczfticBIWxZhA,935
77
80
  scilens/report/templates/compare_13_section_numbers copy.html,sha256=0PWK_I2kNX3LjPLkkY4eSYIeB7YFkA28nk-PPLDhnaY,1753
78
81
  scilens/report/templates/compare_13_section_numbers.html,sha256=9etEMSqwrDyJIn_nMbKEVaDgnFL_hBxSjPR-hU2wgDI,851
79
82
  scilens/report/templates/compare_13_section_numbers_table.html,sha256=pME7vkcPpP2YF0X_jPeD8hEyjA4i-11slfwuQkfUNNI,2927
80
83
  scilens/report/templates/html_macros.html,sha256=jKatNSn4nX_72_wHl0-0dhxZZZBoGDGpOg7E7TMZSGs,1185
81
84
  scilens/report/templates/html_widget_err.html,sha256=sjbtooSh7RGFs8kcct4_tMi_n8FQiaoqRhUjBzHduZM,336
82
- scilens/report/templates/index.html,sha256=lb02RQXDOrigieeFBBJewqRUTw_mwcmVgsibM1eUN_I,6077
85
+ scilens/report/templates/index.html,sha256=02nQg3yqGX69g4W7Zy0EKU_SOrskMd3N4hZhg4uAzu8,6089
83
86
  scilens/report/templates/js_chartlibs_echarts.js,sha256=6YicVhTNIBmmBpV31XCVN5oBeiD0t29JIosJZRUv01M,907
84
87
  scilens/report/templates/js_chartlibs_plotly.js,sha256=MQGpYtBc1gKtu98BcfVOx_W0TktABqanxDjK9YaVqNE,2649
85
- scilens/report/templates/js_com_page.js,sha256=miSPJuzb5hD6sX7b5RYMWoCv9pg2CraHuIfXVFYmUU8,6922
88
+ scilens/report/templates/js_com_page.js,sha256=C4CfGlcv31xVFdfuIje9nMeCD8u_1kaJofNPoJQX2As,6922
86
89
  scilens/report/templates/js_curvemgr.js,sha256=gnRLO6HbZOMLIBQKjVhV2PciqXtuNKxpGx4boijV2Qc,12175
87
90
  scilens/report/templates/js_dom.js,sha256=r5fNSEdeHopMUjSaYtuAIBNRhvSIPoQ9HzAtxvLZcuk,1363
88
91
  scilens/report/templates/js_images.js,sha256=Welcp1ouZdyhE6EyJiiRdPE0VCZjh5dRwgfjMMHmx18,1624
89
92
  scilens/report/templates/js_palette.js,sha256=HeewAmkR67QiqXSanJS3cCgp6IPKomlULUTKt55F6es,218
90
93
  scilens/report/templates/models.js,sha256=MrgnVxPnoimLbR_Eb7Rq3OoNlT89m4PYk6vqt-D7KyY,715
91
- scilens/report/templates/style.css,sha256=_p5wrk-xeIC7-STthrS6OxViYUvJdVE3CKudepCU4Z8,5577
94
+ scilens/report/templates/style.css,sha256=32sC6XVzBpTDtPlzeA4oW6UmZxZ4VKzSn0Dma6VL1Nw,5577
92
95
  scilens/report/templates/uti_frameseries.js,sha256=2edOgmgEfD9F7wYvcB1ZAELnLRq43tcxYMhERnNC5NY,6282
93
96
  scilens/report/templates/uti_matrix.js,sha256=wD9vZ9aMq897XupXDmGYkiUQl8behMAYDjcfDvxGwQ0,3441
94
97
  scilens/report/templates/uti_spectrograms.js,sha256=qE2wdit6Zq8AxShtV9FdA2pRTk4KY9zZUZ58ccYj_Ow,4311
@@ -100,7 +103,7 @@ scilens/report/vendors/tailwindcss_min_4.0.0-beta.4.js,sha256=fy2LOvMX7m4b1V9Wdt
100
103
  scilens/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
104
  scilens/run/models/task_results.py,sha256=hdr_QEwMnjdfdawpfuBRMGqCHWQvsF61G39CVEMXKl8,284
102
105
  scilens/run/models/task_runtime.py,sha256=VNbMPS1ocl6WUDG5ipUxp3RSAST2OZ5DqGcfJWFEed8,114
103
- scilens/run/run_task.py,sha256=EDi9Lk69DC5ik9ArWF47hZ5j9Z_TTAES7liTXzuUZEg,3183
106
+ scilens/run/run_task.py,sha256=4wR4ptsDOlDyYPYHbKPbE1wkJsl5STAjxlUWRHZTqas,3578
104
107
  scilens/run/standalone_task_runner.py,sha256=QYUZ22YPV8hlUFANRcfxy_RXAmwKSfb7glPqPdcgdMA,568
105
108
  scilens/run/task_context.py,sha256=NnujvpwnxY-YEzivYPYWaX-YChcZlEXt9y0_DXLqZkk,659
106
109
  scilens/run/tasks_collector.py,sha256=m_FQaJdQRi4fCLW17ryJxU0TvGNJN54JTw2Mg6XPojY,3174
@@ -113,7 +116,7 @@ scilens/utils/template.py,sha256=9dlXX3nmfzDRUwzPJOkoxk15UXivZ2SW-McdCwokFa4,443
113
116
  scilens/utils/time_tracker.py,sha256=DdVBoMpVLXrX0qZZXyLm4g38EwDVLlRcBqcpNex1mYY,545
114
117
  scilens/utils/vectors.py,sha256=4N2BZSC5n3HgZqPujDGF5NdjVmSL1rOHb_qw4OoABQY,103
115
118
  scilens/utils/web.py,sha256=MAFWpIFOKz7QhqDoFh-Qwstvc76KpcxstSgHFT8FOL4,901
116
- scilens-0.4.8.dist-info/METADATA,sha256=Iq6R89SiRZfEtfeFJllKZWJYnMXrsDTO6Fgbs7ztNaY,1367
117
- scilens-0.4.8.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
118
- scilens-0.4.8.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
119
- scilens-0.4.8.dist-info/RECORD,,
119
+ scilens-0.4.10.dist-info/METADATA,sha256=Vyqc2PLaiVNXgdUTsYsj8Q-d1oP-b6Hy4TiPAvmw2_o,1368
120
+ scilens-0.4.10.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
121
+ scilens-0.4.10.dist-info/entry_points.txt,sha256=DaKGgxUEUv34GJAoXtta6ecL37ercejep9sCSSRQK2s,48
122
+ scilens-0.4.10.dist-info/RECORD,,