microlens-submit 0.16.5__tar.gz → 0.17.0__tar.gz
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.
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/CHANGELOG.md +28 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/CITATION.cff +2 -2
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/PKG-INFO +4 -4
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/README.md +3 -3
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/__init__.py +1 -1
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/solutions.py +29 -1
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/validation.py +8 -3
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/models/solution.py +17 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/models/submission.py +4 -2
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/tier_validation.py +6 -9
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/validate_parameters.py +522 -190
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit.egg-info/PKG-INFO +4 -4
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit.egg-info/SOURCES.txt +2 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/pyproject.toml +1 -1
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/setup.py +1 -1
- microlens_submit-0.17.0/tests/test_bic_calculation.py +235 -0
- microlens_submit-0.17.0/tests/test_physical_validation.py +55 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/tests/test_tier_validation.py +2 -2
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/LICENSE +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/MANIFEST.in +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/assets/github-desktop_logo.png +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/assets/rges-pit_logo.png +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/__init__.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/__main__.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/__init__.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/dossier.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/export.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/init.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/main.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/dossier/__init__.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/dossier/dashboard.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/dossier/event_page.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/dossier/full_report.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/dossier/solution_page.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/dossier/utils.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/error_messages.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/models/__init__.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/models/event.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/text_symbols.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/utils.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit.egg-info/dependency_links.txt +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit.egg-info/entry_points.txt +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit.egg-info/requires.txt +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit.egg-info/top_level.txt +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/setup.cfg +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/tests/test_api.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/tests/test_cli.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/tests/test_dossier_generation.py +0 -0
- {microlens_submit-0.16.5 → microlens_submit-0.17.0}/tests/test_dossier_pages.py +0 -0
|
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.17.0] - 2026-02-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Physical Parameters**: Added 24 physical parameters (Mtot, M1-M4, D_L, D_S, thetaE, piE components, mu_rel components, phi) to parameter spec
|
|
12
|
+
- **Physical Parameter Validation**: Comprehensive validation including mass consistency checks, vector magnitude verification, distance constraints, and unit confusion warnings
|
|
13
|
+
- **Uncertainty Metadata**: Added three new Solution fields:
|
|
14
|
+
- `uncertainty_method`: Method used to derive uncertainties (mcmc_posterior, fisher_matrix, bootstrap, propagation, inference, literature, other)
|
|
15
|
+
- `confidence_level`: Confidence level for uncertainties (default: 0.68 for 1-sigma)
|
|
16
|
+
- `physical_parameter_uncertainties`: Uncertainties for physical parameters (symmetric or asymmetric)
|
|
17
|
+
- **CLI Options**: Added `--physical-param-uncertainty`, `--uncertainty-method`, and `--confidence-level` options to `add-solution` command
|
|
18
|
+
- **Tests**: Added 3 new comprehensive BIC calculation tests verifying parameter counting
|
|
19
|
+
- **Version Management**: Enhanced `bump_version.py` to update and validate `parameter_spec.yaml` (includes drift check)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- **BIC Calculation Bug**: Fixed critical bug where BIC calculation counted ALL parameters including metadata (t_ref, limb_darkening_coeffs) and physical parameters (Mtot, D_L, etc.) as "free parameters". Now correctly counts only fitted model parameters using new `count_model_parameters()` function. This affects relative probability calculations during export and solution comparison.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Physical parameters now validated with `validate_physical_parameters()` automatically when present
|
|
26
|
+
- Solution metadata validation now includes uncertainty metadata checks
|
|
27
|
+
- BIC calculation in `submission.py` and `validation.py` now uses `count_model_parameters()` instead of `len(s.parameters)`
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
- Added comprehensive examples of physical parameters and uncertainty metadata to tutorial and usage examples
|
|
31
|
+
- Tutorial emphasizes uncertainties are **optional but strongly recommended** for evaluation readiness
|
|
32
|
+
- Created `PHYSICAL_PARAMS_SUMMARY.md` with complete implementation guide
|
|
33
|
+
|
|
34
|
+
## [Unreleased]
|
|
35
|
+
|
|
8
36
|
## [0.16.5] - 2026-02-04
|
|
9
37
|
|
|
10
38
|
### Fixed
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
cff-version: 1.2.0
|
|
2
2
|
message: "If you use microlens-submit, please cite it as below."
|
|
3
3
|
title: "microlens-submit"
|
|
4
|
-
version: "0.
|
|
4
|
+
version: "0.17.0"
|
|
5
5
|
authors:
|
|
6
6
|
- family-names: Malpas
|
|
7
7
|
given-names: Amber
|
|
8
8
|
url: "https://github.com/AmberLee2427/microlens-submit"
|
|
9
|
-
doi: "10.5281/zenodo.
|
|
9
|
+
doi: "10.5281/zenodo.18488304"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: microlens-submit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
4
4
|
Summary: A tool for managing and submitting microlensing solutions
|
|
5
5
|
Home-page: https://github.com/AmberLee2427/microlens-submit
|
|
6
6
|
Author: Amber Malpas
|
|
@@ -210,15 +210,15 @@ import this file directly.
|
|
|
210
210
|
|
|
211
211
|
Bibtex:
|
|
212
212
|
```
|
|
213
|
-
@software{
|
|
213
|
+
@software{malpas_2025_18488304,
|
|
214
214
|
author = {Malpas, Amber},
|
|
215
215
|
title = {microlens-submit},
|
|
216
216
|
month = oct,
|
|
217
217
|
year = 2025,
|
|
218
218
|
publisher = {Zenodo},
|
|
219
219
|
version = {v0.16.3},
|
|
220
|
-
doi = {10.5281/zenodo.
|
|
221
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
220
|
+
doi = {10.5281/zenodo.18488304},
|
|
221
|
+
url = {https://doi.org/10.5281/zenodo.18488304},
|
|
222
222
|
}
|
|
223
223
|
```
|
|
224
224
|
|
|
@@ -160,15 +160,15 @@ import this file directly.
|
|
|
160
160
|
|
|
161
161
|
Bibtex:
|
|
162
162
|
```
|
|
163
|
-
@software{
|
|
163
|
+
@software{malpas_2025_18488304,
|
|
164
164
|
author = {Malpas, Amber},
|
|
165
165
|
title = {microlens-submit},
|
|
166
166
|
month = oct,
|
|
167
167
|
year = 2025,
|
|
168
168
|
publisher = {Zenodo},
|
|
169
169
|
version = {v0.16.3},
|
|
170
|
-
doi = {10.5281/zenodo.
|
|
171
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
170
|
+
doi = {10.5281/zenodo.18488304},
|
|
171
|
+
url = {https://doi.org/10.5281/zenodo.18488304},
|
|
172
172
|
}
|
|
173
173
|
```
|
|
174
174
|
|
{microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/solutions.py
RENAMED
|
@@ -187,7 +187,31 @@ def add_solution(
|
|
|
187
187
|
physical_param: Optional[List[str]] = typer.Option(
|
|
188
188
|
None,
|
|
189
189
|
"--physical-param",
|
|
190
|
-
help=("Physical parameters (
|
|
190
|
+
help=("Physical parameters (Mtot, D_L, thetaE, etc.) " "derived from model parameters [ADVANCED]"),
|
|
191
|
+
),
|
|
192
|
+
physical_param_uncertainty: Optional[List[str]] = typer.Option(
|
|
193
|
+
None,
|
|
194
|
+
"--physical-param-uncertainty",
|
|
195
|
+
help=(
|
|
196
|
+
"Physical parameter uncertainties as key=value. "
|
|
197
|
+
"Can be single value (symmetric) or [lower,upper] (asymmetric) [ADVANCED]"
|
|
198
|
+
),
|
|
199
|
+
),
|
|
200
|
+
uncertainty_method: Optional[str] = typer.Option(
|
|
201
|
+
None,
|
|
202
|
+
"--uncertainty-method",
|
|
203
|
+
help=(
|
|
204
|
+
"Method used to derive uncertainties [ADVANCED]. "
|
|
205
|
+
"Options: mcmc_posterior, fisher_matrix, bootstrap, propagation, inference, literature, other"
|
|
206
|
+
),
|
|
207
|
+
),
|
|
208
|
+
confidence_level: Optional[float] = typer.Option(
|
|
209
|
+
None,
|
|
210
|
+
"--confidence-level",
|
|
211
|
+
help=(
|
|
212
|
+
"Confidence level for uncertainties (default: 0.68 = 1σ) [ADVANCED]. "
|
|
213
|
+
"Standard values: 0.68 (1σ), 0.95 (2σ), 0.997 (3σ)"
|
|
214
|
+
),
|
|
191
215
|
),
|
|
192
216
|
relative_probability: Optional[float] = typer.Option(
|
|
193
217
|
None,
|
|
@@ -281,6 +305,10 @@ def add_solution(
|
|
|
281
305
|
sol.limb_darkening_coeffs = _parse_pairs(limb_darkening_coeff)
|
|
282
306
|
sol.parameter_uncertainties = _parse_pairs(parameter_uncertainty) or uncertainties
|
|
283
307
|
sol.physical_parameters = _parse_pairs(physical_param)
|
|
308
|
+
sol.physical_parameter_uncertainties = _parse_pairs(physical_param_uncertainty)
|
|
309
|
+
sol.uncertainty_method = uncertainty_method
|
|
310
|
+
if confidence_level is not None:
|
|
311
|
+
sol.confidence_level = confidence_level
|
|
284
312
|
sol.log_likelihood = log_likelihood
|
|
285
313
|
sol.relative_probability = relative_probability
|
|
286
314
|
sol.n_data_points = n_data_points
|
{microlens_submit-0.16.5 → microlens_submit-0.17.0}/microlens_submit/cli/commands/validation.py
RENAMED
|
@@ -12,6 +12,7 @@ from rich.table import Table
|
|
|
12
12
|
from microlens_submit.error_messages import enhance_validation_messages
|
|
13
13
|
from microlens_submit.text_symbols import symbol
|
|
14
14
|
from microlens_submit.utils import load
|
|
15
|
+
from microlens_submit.validate_parameters import count_model_parameters
|
|
15
16
|
|
|
16
17
|
console = Console()
|
|
17
18
|
|
|
@@ -196,13 +197,17 @@ def compare_solutions(
|
|
|
196
197
|
need_calc = [s for s in solutions if s.relative_probability is None]
|
|
197
198
|
if need_calc:
|
|
198
199
|
can_calc = all(
|
|
199
|
-
s.log_likelihood is not None
|
|
200
|
+
s.log_likelihood is not None
|
|
201
|
+
and s.n_data_points
|
|
202
|
+
and s.n_data_points > 0
|
|
203
|
+
and count_model_parameters(s.parameters) > 0
|
|
200
204
|
for s in need_calc
|
|
201
205
|
)
|
|
202
206
|
remaining = max(1.0 - provided_sum, 0.0)
|
|
203
207
|
if can_calc:
|
|
204
208
|
bic_vals = {
|
|
205
|
-
s.solution_id:
|
|
209
|
+
s.solution_id: count_model_parameters(s.parameters) * math.log(s.n_data_points)
|
|
210
|
+
- 2 * s.log_likelihood
|
|
206
211
|
for s in need_calc
|
|
207
212
|
}
|
|
208
213
|
bic_min = min(bic_vals.values())
|
|
@@ -219,7 +224,7 @@ def compare_solutions(
|
|
|
219
224
|
|
|
220
225
|
rows = []
|
|
221
226
|
for sol in solutions:
|
|
222
|
-
k =
|
|
227
|
+
k = count_model_parameters(sol.parameters)
|
|
223
228
|
bic = k * math.log(sol.n_data_points) - 2 * sol.log_likelihood
|
|
224
229
|
rp = sol.relative_probability if sol.relative_probability is not None else rel_prob_map.get(sol.solution_id)
|
|
225
230
|
rows.append(
|
|
@@ -134,7 +134,10 @@ class Solution(BaseModel):
|
|
|
134
134
|
limb_darkening_model: Optional[str] = None
|
|
135
135
|
limb_darkening_coeffs: Optional[dict] = None
|
|
136
136
|
parameter_uncertainties: Optional[dict] = None
|
|
137
|
+
uncertainty_method: Optional[str] = None
|
|
138
|
+
confidence_level: Optional[float] = 0.68
|
|
137
139
|
physical_parameters: Optional[dict] = None
|
|
140
|
+
physical_parameter_uncertainties: Optional[dict] = None
|
|
138
141
|
log_likelihood: Optional[float] = None
|
|
139
142
|
relative_probability: Optional[float] = None
|
|
140
143
|
n_data_points: Optional[int] = None
|
|
@@ -155,6 +158,7 @@ class Solution(BaseModel):
|
|
|
155
158
|
higher_order_effects = values.get("higher_order_effects", [])
|
|
156
159
|
bands = values.get("bands", [])
|
|
157
160
|
t_ref = values.get("t_ref")
|
|
161
|
+
limb_darkening_coeffs = values.get("limb_darkening_coeffs")
|
|
158
162
|
|
|
159
163
|
# Only check for totally broken objects (e.g., wrong types)
|
|
160
164
|
basic_errors = []
|
|
@@ -176,6 +180,7 @@ class Solution(BaseModel):
|
|
|
176
180
|
higher_order_effects=higher_order_effects,
|
|
177
181
|
bands=bands,
|
|
178
182
|
t_ref=t_ref,
|
|
183
|
+
limb_darkening_coeffs=limb_darkening_coeffs,
|
|
179
184
|
)
|
|
180
185
|
if validation_warnings:
|
|
181
186
|
warnings.warn(f"Solution created with potential issues: {'; '.join(validation_warnings)}", UserWarning)
|
|
@@ -388,6 +393,18 @@ class Solution(BaseModel):
|
|
|
388
393
|
)
|
|
389
394
|
messages.extend(consistency_messages)
|
|
390
395
|
|
|
396
|
+
# Check solution metadata (uncertainties, etc.)
|
|
397
|
+
from ..validate_parameters import validate_solution_metadata
|
|
398
|
+
|
|
399
|
+
metadata_messages = validate_solution_metadata(
|
|
400
|
+
parameter_uncertainties=self.parameter_uncertainties,
|
|
401
|
+
physical_parameters=self.physical_parameters,
|
|
402
|
+
physical_parameter_uncertainties=self.physical_parameter_uncertainties,
|
|
403
|
+
uncertainty_method=self.uncertainty_method,
|
|
404
|
+
confidence_level=self.confidence_level,
|
|
405
|
+
)
|
|
406
|
+
messages.extend(metadata_messages)
|
|
407
|
+
|
|
391
408
|
return messages
|
|
392
409
|
|
|
393
410
|
def _save(self, event_path: Path) -> None:
|
|
@@ -18,6 +18,7 @@ import psutil
|
|
|
18
18
|
from pydantic import BaseModel, Field
|
|
19
19
|
|
|
20
20
|
from ..text_symbols import symbol
|
|
21
|
+
from ..validate_parameters import count_model_parameters
|
|
21
22
|
from .event import Event
|
|
22
23
|
from .solution import Solution
|
|
23
24
|
|
|
@@ -500,14 +501,15 @@ class Submission(BaseModel):
|
|
|
500
501
|
s.log_likelihood is None
|
|
501
502
|
or s.n_data_points is None
|
|
502
503
|
or s.n_data_points <= 0
|
|
503
|
-
or
|
|
504
|
+
or count_model_parameters(s.parameters) == 0
|
|
504
505
|
):
|
|
505
506
|
can_calc = False
|
|
506
507
|
break
|
|
507
508
|
remaining = max(1.0 - provided_sum, 0.0)
|
|
508
509
|
if can_calc:
|
|
509
510
|
bic_vals = {
|
|
510
|
-
s.solution_id:
|
|
511
|
+
s.solution_id: count_model_parameters(s.parameters) * math.log(s.n_data_points)
|
|
512
|
+
- 2 * s.log_likelihood
|
|
511
513
|
for s in need_calc
|
|
512
514
|
}
|
|
513
515
|
bic_min = min(bic_vals.values())
|
|
@@ -38,21 +38,21 @@ Note:
|
|
|
38
38
|
from typing import Dict, List, Optional, Set
|
|
39
39
|
|
|
40
40
|
# Tier definitions with their associated event lists
|
|
41
|
+
# --- BEGIN AUTO-GENERATED: TIER_DEFINITIONS ---
|
|
41
42
|
TIER_DEFINITIONS = {
|
|
42
43
|
"beginner": {
|
|
43
44
|
"description": "Beginner challenge tier with limited event set",
|
|
44
45
|
"event_prefix": "rmdc26_",
|
|
45
|
-
"event_range": [0,
|
|
46
|
+
"event_range": [0, 253],
|
|
46
47
|
},
|
|
47
48
|
"experienced": {
|
|
48
49
|
"description": "Experienced challenge tier with full event set",
|
|
49
50
|
"event_prefix": "rmdc26_",
|
|
50
|
-
"event_range": [0,
|
|
51
|
+
"event_range": [0, 3000],
|
|
51
52
|
},
|
|
52
53
|
"test": {
|
|
53
54
|
"description": "Testing tier for development",
|
|
54
55
|
"event_list": [
|
|
55
|
-
# Add test events here
|
|
56
56
|
"evt",
|
|
57
57
|
"test-event",
|
|
58
58
|
"EVENT001",
|
|
@@ -68,17 +68,14 @@ TIER_DEFINITIONS = {
|
|
|
68
68
|
"description": "2018 test events tier",
|
|
69
69
|
"event_prefix": "ulwdc1_",
|
|
70
70
|
"event_range": [0, 293],
|
|
71
|
-
"event_list": [
|
|
72
|
-
# Add 2018 test events here
|
|
73
|
-
"2018-EVENT-001",
|
|
74
|
-
"2018-EVENT-002",
|
|
75
|
-
],
|
|
71
|
+
"event_list": ["2018-EVENT-001", "2018-EVENT-002"],
|
|
76
72
|
},
|
|
77
73
|
"None": {
|
|
78
74
|
"description": "No validation tier (skips event validation)",
|
|
79
|
-
"event_list": [],
|
|
75
|
+
"event_list": [],
|
|
80
76
|
},
|
|
81
77
|
}
|
|
78
|
+
# --- END AUTO-GENERATED: TIER_DEFINITIONS ---
|
|
82
79
|
|
|
83
80
|
# Cache for event lists to avoid repeated list creation
|
|
84
81
|
_EVENT_LIST_CACHE: Dict[str, Set[str]] = {}
|