@@ -70,6 +70,7 @@ mod eko {
7070 V0 ( MetadataV0 ) ,
7171 V1 ( MetadataV1 ) ,
7272 V2 ( MetadataV2 ) ,
73+ V3 ( MetadataV3 ) ,
7374 }
7475
7576 const BASES_V1_DEFAULT_PIDS : [ i32 ; 14 ] = [ 22 , -6 , -5 , -4 , -3 , -2 , -1 , 21 , 1 , 2 , 3 , 4 , 5 , 6 ] ;
@@ -86,6 +87,12 @@ mod eko {
8687 configs : OperatorConfigsV1 ,
8788 }
8889
90+ #[ derive( Deserialize ) ]
91+ struct OperatorV2 {
92+ init : Vec < f64 > ,
93+ configs : OperatorConfigsV1 ,
94+ }
95+
8996 #[ derive( Deserialize ) ]
9097 struct OperatorInfoV1 {
9198 scale : f64 ,
@@ -105,13 +112,18 @@ mod eko {
105112 bases : BasesV1 ,
106113 }
107114
115+ #[ derive( Deserialize ) ]
116+ struct MetadataV3 {
117+ xgrid : Vec < f64 > ,
118+ }
119+
108120 pub enum EkoSlices {
109121 V0 {
110122 fac1 : Vec < f64 > ,
111123 info : OperatorSliceInfo ,
112124 operator : Array5 < f64 > ,
113125 } ,
114- // V1 is a special case of V2
126+ // V1 and V3 are special cases of V2
115127 V2 {
116128 fac1 : HashMap < OsString , f64 > ,
117129 info : OperatorSliceInfo ,
@@ -142,6 +154,7 @@ mod eko {
142154 Metadata :: V0 ( v0) => Self :: with_v0 ( v0, eko_path) ,
143155 Metadata :: V1 ( v1) => Self :: with_v1 ( v1, eko_path) ,
144156 Metadata :: V2 ( v2) => Self :: with_v2 ( v2, eko_path) ,
157+ Metadata :: V3 ( v3) => Self :: with_v3 ( v3, eko_path) ,
145158 }
146159 }
147160
@@ -325,6 +338,51 @@ mod eko {
325338 } )
326339 }
327340
341+ fn with_v3 ( metadata : MetadataV3 , eko_path : & Path ) -> Result < Self > {
342+ let mut fac1 = HashMap :: new ( ) ;
343+ let mut operator: Option < OperatorV2 > = None ;
344+
345+ for entry in Archive :: new ( File :: open ( eko_path) ?) . entries_with_seek ( ) ? {
346+ let entry = entry?;
347+ let path = entry. path ( ) ?;
348+
349+ if path. starts_with ( "./operators" )
350+ && ( path. extension ( ) . is_some_and ( |ext| ext == "yaml" ) )
351+ {
352+ let Some ( file_stem) = path. file_stem ( ) . map ( ToOwned :: to_owned) else {
353+ continue ;
354+ } ;
355+
356+ let op_info: OperatorInfoV1 = serde_yaml:: from_reader ( entry) ?;
357+ fac1. insert ( file_stem, op_info. scale ) ;
358+ } else if path. as_os_str ( ) == "./operator.yaml" {
359+ operator = Some ( serde_yaml:: from_reader ( entry) ?) ;
360+ }
361+ }
362+
363+ let operator =
364+ operator. ok_or_else ( || anyhow ! ( "no file 'operator.yaml' in EKO archive found" ) ) ?;
365+
366+ // NOTE: Since v0.15, EKOs are always in the flavour basis
367+ Ok ( Self :: V2 {
368+ fac1,
369+ info : OperatorSliceInfo {
370+ pid_basis : PidBasis :: Pdg ,
371+ fac0 : operator. init [ 0 ] * operator. init [ 0 ] ,
372+ pids0 : BASES_V1_DEFAULT_PIDS . to_vec ( ) ,
373+ x0 : metadata. xgrid . clone ( ) ,
374+ fac1 : 0.0 ,
375+ pids1 : BASES_V1_DEFAULT_PIDS . to_vec ( ) ,
376+ x1 : metadata. xgrid ,
377+ conv_type : ConvType :: new (
378+ operator. configs . polarized ,
379+ operator. configs . time_like ,
380+ ) ,
381+ } ,
382+ archive : Archive :: new ( File :: open ( eko_path) ?) ,
383+ } )
384+ }
385+
328386 pub fn iter_mut ( & mut self ) -> EkoSlicesIter {
329387 match self {
330388 Self :: V0 {
0 commit comments