Local Python tooling for PEC battery test metadata cleaning, dataset mapping, semantic retrieval, and hybrid test selection.
- Loads and cleans the PEC Excel log
- Standardizes core metadata fields
- Builds relational battery metadata tables
- Saves cleaned metadata to parquet
- Generates a battery data map report
- Builds a local semantic index with
sentence-transformersandFAISS - Supports structured filtering and hybrid free-text querying
- Optionally uses a local Ollama model to parse natural-language queries
pick-relevant-tests/
├── data/
│ ├── 2026_PEC_log.xlsx
│ └── TestXXXXX.csv or nested folders containing Test*.csv
├── outputs/
│ └── battery_data_system/
├── src/
│ └── pick_relevant_tests/
│ ├── cli.py
│ ├── config.py
│ ├── system.py
│ └── utils.py
├── main.py
├── pyproject.toml
└── README.md
- Python 3.12+
- Local filesystem access to the Excel metadata log and CSV test files
- Enough disk space for parquet outputs, plots, and the FAISS index
Optional:
- Ollama running locally on
http://127.0.0.1:11434 - A pulled model such as
llama3
uv syncRun the tool:
uv run pick-relevant-testspython3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .Run the tool:
pick-relevant-testsIf editable install is not desired:
pip install .
python3 main.pyDefault input path:
data/2026_PEC_log.xlsx
The loader accepts a base path of data/2026_PEC_log and automatically resolves .xlsx or .xls.
The code attempts to normalize and map source columns into canonical fields such as:
cell_idlot_numbertest_idregimetemperaturec_ratestatuscommentschemistrymanufacturercapacitytimestamp
The tool searches for Test*.csv under the configured CSV directory.
Default CSV search root:
data/
It also checks common nested locations such as:
data/timeseriesdata/csvdata/test_csvs
Run the full local pipeline:
pick-relevant-testsEquivalent:
python3 main.pyUse explicit paths:
pick-relevant-tests \
--metadata-path data/2026_PEC_log.xlsx \
--csv-dir data/timeseries \
--output-dir outputs/battery_data_systemUse a non-default sheet:
pick-relevant-tests --sheet-name 0Skip semantic indexing:
pick-relevant-tests --skip-semanticRun a hybrid query directly from the CLI:
pick-relevant-tests --query "NMC aging tests at 25 C with fast charge"Limit results:
pick-relevant-tests --query "formation tests lot ABC123" --top-k 5Use Ollama only for query parsing:
pick-relevant-tests \
--query "find NMC tests at 25 C related to fast charge" \
--use-ollama \
--ollama-model llama3Default output directory:
outputs/battery_data_system/
Generated artifacts:
tables/cleaned_metadata.parquettables/cells_df.parquettables/tests_df.parquettables/lifecycle_df.parquet- CSV summary tables for report sections
figures/tests_per_cell_histogram.pngfigures/chemistry_bar_chart.pngfigures/temperature_c_rate_heatmap.pngfigures/lifecycle_distribution.pngsemantic/tests.faisssemantic/semantic_metadata.parquetsemantic/model_name.txt
from pathlib import Path
from pick_relevant_tests import BatteryDataSystem
system = BatteryDataSystem(
metadata_path=Path("data/2026_PEC_log.xlsx"),
csv_dir=Path("data"),
output_dir=Path("outputs/battery_data_system"),
)
system.load_and_clean_data()
system.build_relational_tables()
system.build_data_map_report()
system.build_semantic_index()
filtered = system.query_tests(
chemistry="NMC",
temperature=25,
regime="aging",
)
semantic_hits = system.semantic_search("fast charge swelling", k=10)
hybrid_hits = system.hybrid_query("NMC aging tests at 25 C with fast charge", k=10)
csv_paths = system.get_csv_paths(filtered)
print(filtered[["test_id", "cell_id", "regime"]].head())
print(csv_paths[:5])--metadata-path: Excel log path or base path without extension--csv-dir: root directory containingTest*.csv--output-dir: where tables, figures, and semantic artifacts are written--sheet-name: Excel sheet name or index--model-name: sentence-transformers model name--query: run a hybrid search after pipeline build--top-k: number of query results to return--skip-semantic: disable embedding generation and FAISS index creation--use-ollama: use Ollama to parse the query into structured fields--ollama-model: Ollama model name, for examplellama3
Install Ollama and start the local service, then pull a model:
ollama pull llama3Verify the service is running:
curl http://127.0.0.1:11434/api/tagsOllama is optional. The system works locally without it. Ollama is only used to parse natural-language queries into structured filters.
- Semantic search is fully local and does not require cloud APIs
- The first sentence-transformers run may download the model weights locally
- If your environment is offline, pre-download the embedding model before running semantic indexing
- CSV files are resolved by
test_idusing names likeTest123.csv,Test00123.csv, or recursive matches under the configured CSV root
Syntax check:
python3 -m py_compile main.py src/pick_relevant_tests/*.pyRun with local data:
pick-relevant-tests --metadata-path data/2026_PEC_log.xlsx --csv-dir data