Repository navigation
I26: one data model and user API (DataManager on the four tables; by, run_id, polars) - #26
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…run_id and polars everywhere DataManager reads any source (convert.read_dataset) or a converted folder (add_dataset) as format v1 StoredDatasets; data.py's classes and the global data_id counter are gone. Metrics, plots, indicators and align group on run_id, take by, and return polars. Removed names fail with an upgrade hint from one table (_upgrade.py). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cuted; version 0.1.0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ith line counts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
…drops the mean run_id Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r, inf, group_cols); first hit on ties turbo_align and get_data_ecdf(turbo=) are removed with upgrade hints. Metric outputs were compared against the previous code on the example, test and maximisation fixtures (monotonic and raw); the differences are the documented fixes in CHANGELOG.md (Alignment). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review follow-up (the user's decisions in the controller session):
Verification: every function that aligns (
Left for I10: alignment decides fixed-budget vs fixed-target by |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd docs) The run id hash input is unchanged (the integer index), so run ids stay the same. The extdata fixture's runs.parquet is rewritten with the renamed column; its trace and descriptors are byte-identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…un_index) This reverts commit 8b8b18e. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
matplotlib is a required dependency and apply gets an Axes, so the check could never fail; an earlier lint fix had left an empty try block. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WP I26: One data model and user API
Branch: wp/I26-one-data-model
Status: ready for review
Done
step 1: inventory (this file)
steps 2-3:
_upgrade.py;DataManageron the four tables;read_dataset;data.pyis a stub; metrics, plots, indicators andalignonrun_id,by,polars; tests updated; notebooks updated and running;
examples/parquetremoved.step 4:
CHANGELOG.md(every rename and removal), README,FUNCTION_REFERENCE.md;notebooks re-executed (stored outputs match; stderr outputs dropped, they held local
paths);
pyproject.tomlversion 0.1.0 for the tag.step 5: tests for
add_folderwith a CSV mapping and for the metric upgrade hints;old-vs-new comparison of the metrics; line counts; these notes.
Next step
Review (D6: dvermetten, it touches metric code). HUMAN: tag 0.1.0 after merge.
Result
src/iohinspector11,873 -> 11,412 (-461);tests9,259 -> 9,009(-250). The data model (
data.py+manager.py) went from 873 to 252 lines, plus93 for the shared upgrade hints (
_upgrade.py).pytest -q: 650 passed, 3 skipped, 2 xfailed (13 s; was 26 s), notebooks and READMEincluded; also with polars 1.33.1 and 1.44.
from iohinspector import *gives 43 names (was 120 with the leaks).Before:
DataManageroverdata.Dataset/Scenario/Runobjects,data_id,free_vars/free_variables/free_var/alg_vars,return_as_pandas(pandas bydefault). After:
DataManagerover the four format v1 tables (add_folderanyformat,
add_dataset,select(**any column),load),run_id,byeverywhere,polars everywhere; removed names fail with a hint.
examples/SO_Dataand threetests/test_datafolders foraggregate_running_time,aggregate_convergence,get_data_ecdf(both alignments),get_trajectory,get_eaf_dataandget_aocc(old code vs new, same groups, ids dropped). Existing metric tests keep their values.
Baseline
src/iohinspector: 11,873 lines of Python;tests: 9,259 lines.pytest -q: 664 passed, 3 skipped, 2 xfailed (26 s), notebooks included(
tests/test_tutorials.py).Inventory: public names (
from iohinspector import *, 0.0.8 + I25)There is no
__all__, so the star import gives 120 names, about 40 of them leakedimports. After I26 the package defines
__all__at every level.DataManagerdata.DatasetobjectsDataset,Scenario,Run,Function,Algorithm,Solution,METADATA_SCHEMAdata.py)AttributeError/ImportErrorwith an upgrade hintcheck_keys,try_eval,get_polars_type,count_dat_runs,count_coco_runs,monotone_per_run,process_headerdata.pyhelpersCOCO_KINDS,IohJson,IohScenario,load_ioh_json,parse_dat,parse_coco_dat,header_style,merge_files,parse_infofrom .data import *iohinspector.io.*(reader internals)np,pl,os,re,ast,glob,warnings,deepcopy,dataclass,field,partial,Callable,Iterable,version,PackageNotFoundError,hypervolume,igd_plus,epsilon_additive,epsilon_mult,filter_dominated,is_nondominated,get_reference_directions__all__)align,data,manager,io,format,metrics,plots,indicators,anytime,final,aocc,ecdf,eaf, ...databecomes a stub that fails with a hintalign_data,turbo_aligndata_idrun_id(group_colsdefault("run_id",))aggregate_convergence,aggregate_running_time,get_data_ecdf,get_aoccfree_vars,return_as_pandasby; return polarsget_trajectoryfree_variables,return_as_pandasby; polarsget_tournament_ratingsalg_vars,fid_vars,return_as_pandasby(wasalg_vars),fid_varskept (the problem key, not a grouping of results); polarsget_discritized_eaf_single_objective,get_eaf_data,get_eaf_pareto_data,get_eaf_diff_datareturn_as_pandasget_heatmap_single_run_datareturn_as_pandas, asserts onedata_idrun_idget_attractor_networkget_robustrank_over_time,get_robustrank_changesget_sequence,normalize_objectives,add_normalized_objectives,transform_fvaladd_indicatordata_idrun_idHyperVolume,Epsilon,IGDPlus,R2,NonDominated,get_reference_setindicators.anytime.NonDominated(shadowed byfinal.NonDominated) goesplot_single_function_fixed_target,plot_single_function_fixed_budget,plot_ecdffree_vars; return pandasby; return polarsplot_paretofronts_2d,plot_indicator_over_timefree_var: strby: listplot_tournament_rankingalg_varsbyplot_*,BasePlotArgs,LinePlotArgsmetrics.multi_objective.get_pareto_front_2d,get_indicator_over_time_datareturn_as_pandasDataManager attributes
add_folder(path)convert(format,mappingfor CSV,dataset_id,tags,tags_from_path)add_folders(paths)add_dataset(path)scan_dataset)add_json,add_coco_infoadd_folder(path)add_data_set,extend_overviewadd_folder/add_datasetdata_setsdatasets(format v1StoredDatasets)runs,descriptors,trace,positionsoverviewevals->evals_used,data_idgone,run_idthe stable hash)select(...)function_ids,algorithms,dimensions,instances,run_ids, and any runs column or descriptor askey=[values];data_ids->run_ids;experiment_attributes->key=[value];data_attributesremovedselect_indexesselect(run_ids=...)functions,algorithms,dimensions,instancesFunction/Algorithmobjects with repeats)experiment_attributes,data_attributesdescriptor_keys; trace columns viatrace.collect_schema()n_runs,any,__add__,load(...)loadbuilds the same wide frame from the tablesInventory: call sites of the removed names (before I26)
data_id/free_vars(incl.free_variables,free_var,alg_vars) /return_as_pandas, lines per file:align.py10,manager.py5,data.py11,indicators/__init__.py3,metrics/aocc 8, attractor_network 2, eaf 16, ecdf 7, fixed_budget 7,fixed_target 7, multi_objective 6, ranking 8, single_run 4, trajectory 6;
plots/eaf 1, ecdf 9, fixed_budget 6, fixed_target 6, multi_objective 8,ranking 5, single_run 3.
test_align.py24,test_data.py12,test_manager.py24 (incl.data_sets,add_json, ...),io/conftest.py3,io/test_ioh.py1,io/test_ioh_defects.py1,test_metrics/aocc 7, attractor_network 1, eaf 24,ecdf 1, fixed_budget 11, fixed_target 12, multi_objective 4, ranking 2,
single_run 5, trajectory 11;
test_plots/attractor_network 1, eaf 4,multi_objective 3, ranking 2, single_run 1.
examples/SO_Examples.ipynb10,examples/MO_Examples.ipynb12,FUNCTION_REFERENCE.md28.Decisions
DataManager.add_folderreads any source throughconvert.read_dataset: itconverts to a temporary folder and opens it with
scan_dataset, so a source and aconverted dataset are the same
StoredDataset(one code path, the writer's). Thetemporary folder lives as long as the dataset object (
StoredDataset.files).selectreturns a manager over the same datasetswith their four tables filtered on the selected
run_ids.dataset_idis already loaded fails; passdataset_id=.(0.0.8's
add_jsonwarned and skipped;add_foldersilently duplicated.)load()keepsevaluationsas UInt64 as before (the indicators join on UInt64).run_idis the format's stable hash, so it is not 1, 2, ... per file any more.Two places used the old per-file number: the robustranking pairing (now a run number
per algorithm in data order,
_indicator_table, the same pairing for data fromload) and moocore's set ids (now a dense rank ofrun_id,eaf._points).get_discritized_eaf_single_objectivereturnseaf_targetas a column (it was thepandas index), and one column per evaluation value named by its value.
get_attractor_networkreturns polars; a node's number is its row number.by(a list) and return the polars frame they drew;_huegives seabornthe one column, or tuples for several (one
bycolumn now gives plain legend labelsinstead of 1-tuples).
NotImplementedError(
plot_multi_function_fixed_target,plot_multi_function_fixed_budget,robustranking,stats_comparison,winnning_fraction_heatmap), and the deadindicators.anytime.NonDominated(shadowed byfinal.NonDominated).iohinspector/_upgrade.py): a decorator forremoved keyword arguments, and a
__getattr__for removed module and class names.fid_varsofget_tournament_ratingsstays: it names the problems, not a groupingof the output.
Open questions / Blocked
index in its file). Kept, as a run number per algorithm in data order. Is pairing by
index intended (D6)?
get_data_ecdfaverages every numeric column per group, so its output has ameaningless mean
run_id(0.0.8: meandata_id). Dropping it changes the output;left for I12.
align_data(deprecated, handles non-monotone data)and
turbo_align; merging them is I10's job.add_folderon IOHexperimenter data always issues the manifest'slimited_precisionDatasetWarning(the logger writes%.10f). Correct but noisyin notebooks; silence it in
DataManager?StoredDataset.run_columns(by)overlaps withDataManager.overview; kept for thewebsite, which works on one
StoredDataset.Work package from the IOHanalyzer rebuild plan (
plan/in IOHprofiler/ioh-web). Review and merge are done by a person. It changes metric code, so it asks dvermetten to review (decision D6).🤖 Generated with Claude Code