solarwindpy 0.0.1.dev0__py3-none-any.whl → 0.1.0__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.
Potentially problematic release.
This version of solarwindpy might be problematic. Click here for more details.
- plans/.velocity/metrics.json +96 -0
- plans/0-overview-template.md +268 -0
- plans/N-phase-template.md +106 -0
- plans/PLAN_AUDIT_SUMMARY.md +173 -0
- plans/TEMPLATE-USAGE-GUIDE.md +198 -0
- plans/__init__.py +1 -0
- plans/abandoned/compaction-agent-system/0-Overview.md +123 -0
- plans/abandoned/compaction-agent-system/agents-index-update-plan.md +109 -0
- plans/abandoned/compaction-agent-system/compacted_state.md +85 -0
- plans/abandoned/compaction-agent-system/implementation-plan.md +107 -0
- plans/abandoned/compaction-agent-system/system-validation-report.md +159 -0
- plans/abandoned/compaction-agent-system/usage-guide.md +210 -0
- plans/abandoned/hook-system-enhancement/0-Overview.md +214 -0
- plans/abandoned/hook-system-enhancement/1-Phase1-Core-Infrastructure.md +313 -0
- plans/abandoned/hook-system-enhancement/2-Phase2-Intelligent-Testing.md +385 -0
- plans/abandoned/hook-system-enhancement/3-Phase3-Physics-Validation.md +444 -0
- plans/abandoned/hook-system-enhancement/4-Phase4-Performance-Monitoring.md +458 -0
- plans/abandoned/hook-system-enhancement/5-Phase5-Developer-Experience.md +532 -0
- plans/abandoned/hook-system-enhancement/6-Implementation-Timeline.md +274 -0
- plans/abandoned/hook-system-enhancement/7-Risk-Management.md +376 -0
- plans/abandoned/hook-system-enhancement/8-Testing-Strategy.md +579 -0
- plans/abandoned/readthedocs-automation/0-Overview.md +247 -0
- plans/abandoned/readthedocs-automation/1-Emergency-Documentation-Fixes.md +270 -0
- plans/abandoned/readthedocs-automation/2-Template-System-Enhancement.md +811 -0
- plans/abandoned/readthedocs-automation/3-Quality-Audit-ReadTheDocs-Integration.md +844 -0
- plans/abandoned/readthedocs-automation/4-Plan-Consolidation-Cleanup.md +632 -0
- plans/abandoned/readthedocs-automation/9-Closeout.md +207 -0
- plans/abandoned/readthedocs-automation/ABANDONMENT_REASON.md +72 -0
- plans/cicd-architecture-redesign/0-Overview.md +193 -0
- plans/cicd-architecture-redesign/1-Workflow-Creation.md +103 -0
- plans/cicd-architecture-redesign/2-Version-Detection.md +123 -0
- plans/cicd-architecture-redesign/3-Deployment-Gates.md +169 -0
- plans/cicd-architecture-redesign/4-RC-Testing.md +194 -0
- plans/cicd-architecture-redesign/5-TestPyPI-Validation.md +264 -0
- plans/cicd-architecture-redesign/6-Production-Release.md +263 -0
- plans/cicd-architecture-redesign/7-Cleanup.md +243 -0
- plans/cicd-architecture-redesign/8-Documentation.md +285 -0
- plans/cicd-architecture-redesign/Closeout.md +225 -0
- plans/closeout-template.md +259 -0
- plans/completed/circular-import-audit/0-Overview.md +152 -0
- plans/completed/circular-import-audit/1-Static-Dependency-Analysis.md +62 -0
- plans/completed/circular-import-audit/2-Dynamic-Import-Testing.md +56 -0
- plans/completed/circular-import-audit/3-Performance-Impact-Assessment.md +56 -0
- plans/completed/circular-import-audit/4-Issue-Remediation.md +78 -0
- plans/completed/circular-import-audit/5-Preventive-Infrastructure.md +89 -0
- plans/completed/claude-settings-ecosystem-alignment/0-Overview.md +162 -0
- plans/completed/claude-settings-ecosystem-alignment/1-Security-Foundation.md +148 -0
- plans/completed/claude-settings-ecosystem-alignment/2-Hook-Integration.md +158 -0
- plans/completed/claude-settings-ecosystem-alignment/3-Agent-System-Integration.md +177 -0
- plans/completed/claude-settings-ecosystem-alignment/4-Enhanced-Workflow-Automation.md +159 -0
- plans/completed/claude-settings-ecosystem-alignment/5-Validation-Monitoring.md +181 -0
- plans/completed/claude-settings-ecosystem-alignment/compacted_session_state.md +290 -0
- plans/completed/combined_plan_with_checklist_documentation/1-Overview-and-Goals.md +51 -0
- plans/completed/combined_plan_with_checklist_documentation/2-Toolchain-and-Hosting.md +69 -0
- plans/completed/combined_plan_with_checklist_documentation/3-Repository-Structure.md +61 -0
- plans/completed/combined_plan_with_checklist_documentation/4-Configuration-and-Standards.md +70 -0
- plans/completed/combined_plan_with_checklist_documentation/5-Documentation-Content.md +62 -0
- plans/completed/combined_plan_with_checklist_documentation/6-CI-CD-and-Validation.md +58 -0
- plans/completed/combined_plan_with_checklist_documentation/7-Maintenance.md +55 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/0-Overview.md +135 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/1-Common-fixtures.md +59 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/10-power_laws.md +56 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/2-core.py-FitFunction.md +118 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/3-gaussians.py-Gaussian-GaussianNormalized-GaussianLn.md +69 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/4-trend_fits.py-TrendFit.md +99 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/5-plots.py-FFPlot.md +98 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/6-tex_info.py-TeXinfo.md +79 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/7-Justification.md +49 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/8-exponentials.md +64 -0
- plans/completed/combined_test_plan_with_checklist_fitfunctions/9-lines.md +58 -0
- plans/completed/combined_test_plan_with_checklist_plotting/0-Overview.md +142 -0
- plans/completed/combined_test_plan_with_checklist_plotting/1-base.py.md +90 -0
- plans/completed/combined_test_plan_with_checklist_plotting/10-labels-special.py.md +102 -0
- plans/completed/combined_test_plan_with_checklist_plotting/11-labels-chemistry.py.md +212 -0
- plans/completed/combined_test_plan_with_checklist_plotting/12-labels-composition.py.md +242 -0
- plans/completed/combined_test_plan_with_checklist_plotting/13-labels-datetime.py.md +247 -0
- plans/completed/combined_test_plan_with_checklist_plotting/14-labels-elemental_abundance.py.md +274 -0
- plans/completed/combined_test_plan_with_checklist_plotting/15-visual-validation.md +256 -0
- plans/completed/combined_test_plan_with_checklist_plotting/16-integration-testing.md +266 -0
- plans/completed/combined_test_plan_with_checklist_plotting/17-performance-benchmarks.md +267 -0
- plans/completed/combined_test_plan_with_checklist_plotting/18-Fixtures-and-Utilities.md +86 -0
- plans/completed/combined_test_plan_with_checklist_plotting/2-agg_plot.py.md +90 -0
- plans/completed/combined_test_plan_with_checklist_plotting/3-histograms.py.md +201 -0
- plans/completed/combined_test_plan_with_checklist_plotting/4-scatter.py.md +167 -0
- plans/completed/combined_test_plan_with_checklist_plotting/5-spiral.py.md +216 -0
- plans/completed/combined_test_plan_with_checklist_plotting/6-orbits.py.md +108 -0
- plans/completed/combined_test_plan_with_checklist_plotting/7-tools.py.md +86 -0
- plans/completed/combined_test_plan_with_checklist_plotting/8-select_data_from_figure.py.md +97 -0
- plans/completed/combined_test_plan_with_checklist_plotting/9-labels-base.py.md +88 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/.gitkeep +0 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/0-Overview.md +170 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/1-Package-Entry-Point-__init__.py.md +121 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/2-Core-Base-Classes-base.py.md +142 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/3-Plotting-Helpers-plots.py.md +123 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/4-LISIRD-Sub-package.md +119 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/5-Extrema-Calculator.md +103 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/6-Sunspot-Number-Sub-package.md +163 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/7-Sunspot-Number-Init.py.md +217 -0
- plans/completed/combined_test_plan_with_checklist_solar_activity/compacted_state.md +52 -0
- plans/completed/compaction-agent-modernization/0-Overview.md +156 -0
- plans/completed/compaction-agent-modernization/1-Architecture-Audit-Gap-Analysis.md +132 -0
- plans/completed/compaction-agent-modernization/2-Token-Baseline-Recalibration.md +153 -0
- plans/completed/compaction-agent-modernization/3-Agent-Reference-Updates.md +184 -0
- plans/completed/compaction-agent-modernization/4-Compression-Algorithm-Modernization.md +238 -0
- plans/completed/compaction-agent-modernization/5-Workflow-Integration-Streamlining.md +252 -0
- plans/completed/compaction-agent-modernization/6-Template-Structure-Optimization.md +240 -0
- plans/completed/compaction-agent-modernization/7-Integration-Testing-Validation.md +292 -0
- plans/completed/compaction-hook-enhancement/0-Overview.md +150 -0
- plans/completed/compaction-hook-enhancement/1-Token-Estimation-Enhancement.md +179 -0
- plans/completed/compaction-hook-enhancement/2-Compression-Intelligence.md +294 -0
- plans/completed/compaction-hook-enhancement/3-Git-Integration-Metadata.md +310 -0
- plans/completed/compaction-hook-enhancement/4-Session-Continuity-Features.md +358 -0
- plans/completed/compaction-hook-enhancement/5-Testing-Strategy.md +404 -0
- plans/completed/compaction-hook-enhancement/6-Integration-Roadmap.md +319 -0
- plans/completed/compaction-hook-enhancement/compacted_state.md +142 -0
- plans/completed/docstring-audit-enhancement/0-Overview.md +274 -0
- plans/completed/docstring-audit-enhancement/1-Infrastructure-Setup-and-Validation-Tools.md +206 -0
- plans/completed/docstring-audit-enhancement/2-Core-Physics-Modules-Enhancement.md +237 -0
- plans/completed/docstring-audit-enhancement/3-Fitfunctions-Mathematical-Modules-Enhancement.md +188 -0
- plans/completed/docstring-audit-enhancement/4-Plotting-Visualization-Modules-Enhancement.md +243 -0
- plans/completed/docstring-audit-enhancement/5-Specialized-Modules-Enhancement.md +216 -0
- plans/completed/docstring-audit-enhancement/6-Validation-and-Integration.md +216 -0
- plans/completed/fitfunctions-testing-implementation/0-Overview.md +130 -0
- plans/completed/fitfunctions-testing-implementation/1-Test-Infrastructure-Setup.md +79 -0
- plans/completed/fitfunctions-testing-implementation/2-Common-Fixtures-Test-Utilities.md +104 -0
- plans/completed/fitfunctions-testing-implementation/3-Core-FitFunction-Testing.md +168 -0
- plans/completed/fitfunctions-testing-implementation/4-Specialized-Function-Classes.md +210 -0
- plans/completed/fitfunctions-testing-implementation/5-Advanced-Classes-Testing.md +214 -0
- plans/completed/fitfunctions-testing-implementation/6-Plotting-Integration-Testing.md +231 -0
- plans/completed/fitfunctions-testing-implementation/7-Extended-Coverage-BONUS.md +184 -0
- plans/completed/numpy-docstring-conversion-plan/numpy-docstring-conversion-plan.md +118 -0
- plans/completed/pr-review-remediation/0-Overview.md +138 -0
- plans/completed/pr-review-remediation/1-Critical-Safety-Improvements.md +179 -0
- plans/completed/pr-review-remediation/2-Smart-Timeouts-Validation.md +399 -0
- plans/completed/pr-review-remediation/3-Enhanced-GitHub-Integration.md +258 -0
- plans/completed/pr-review-remediation/compacted_state.md +66 -0
- plans/completed/python-310-migration/0-Overview.md +390 -0
- plans/completed/python-310-migration/1-Planning-Setup.md +164 -0
- plans/completed/python-310-migration/2-Implementation.md +256 -0
- plans/completed/python-310-migration/3-Testing-Validation.md +335 -0
- plans/completed/python-310-migration/4-Documentation-Release.md +274 -0
- plans/completed/python-310-migration/5-Closeout.md +252 -0
- plans/completed/requirements-management-consolidation/0-Overview.md +118 -0
- plans/completed/requirements-management-consolidation/1-Documentation-Validation-Environment-Setup.md +116 -0
- plans/completed/requirements-management-consolidation/2-Requirements-Consolidation.md +161 -0
- plans/completed/requirements-management-consolidation/3-Workflow-Automation-Final-Integration.md +196 -0
- plans/completed/single-ecosystem-plan-implementation/0-Overview.md +83 -0
- plans/completed/single-ecosystem-plan-implementation/1-Plan-Preservation-Session-Management.md +38 -0
- plans/completed/single-ecosystem-plan-implementation/2-File-Structure-Optimization.md +43 -0
- plans/completed/single-ecosystem-plan-implementation/3-Plan-Migration-Archive-Setup.md +82 -0
- plans/completed/single-ecosystem-plan-implementation/4-Agent-System-Transformation.md +108 -0
- plans/completed/single-ecosystem-plan-implementation/5-Template-System-Enhancement.md +131 -0
- plans/completed/single-ecosystem-plan-implementation/6-Final-Validation-Testing.md +120 -0
- plans/completed/test-directory-consolidation/0-Overview.md +51 -0
- plans/completed/test-directory-consolidation/1-Structure-Preparation.md +82 -0
- plans/completed/test-directory-consolidation/2-File-Migration.md +100 -0
- plans/completed/test-directory-consolidation/3-Import-Transformation.md +117 -0
- plans/completed/test-directory-consolidation/4-Configuration-Consolidation.md +140 -0
- plans/completed/test-directory-consolidation/5-Validation.md +152 -0
- plans/completed/test-directory-consolidation/6-Cleanup.md +156 -0
- plans/completed/test-planning-agents-architecture/0-Overview.md +79 -0
- plans/completed/test-planning-agents-architecture/1-Branch-Isolation-Testing.md +49 -0
- plans/completed/test-planning-agents-architecture/2-Cross-Branch-Coordination.md +51 -0
- plans/completed/test-planning-agents-architecture/3-Merge-Workflow-Testing.md +48 -0
- plans/deployment-semver-pypi-rtd/0-Overview.md +463 -0
- plans/deployment-semver-pypi-rtd/1-Semantic-Versioning-Foundation.md +136 -0
- plans/deployment-semver-pypi-rtd/2-PyPI-Deployment-Infrastructure.md +168 -0
- plans/deployment-semver-pypi-rtd/3-Release-Automation.md +214 -0
- plans/deployment-semver-pypi-rtd/4-Plan-Closeout.md +543 -0
- plans/deployment-semver-pypi-rtd/compacted_session_state.md +172 -0
- plans/deployment-semver-pypi-rtd/compacted_state.md +131 -0
- plans/documentation-code-audit/0-Overview.md +393 -0
- plans/documentation-code-audit/1-Discovery-Inventory.md +183 -0
- plans/documentation-code-audit/2-Execution-Environment-Setup.md +263 -0
- plans/documentation-code-audit/3-Systematic-Validation.md +322 -0
- plans/documentation-code-audit/4-Code-Example-Remediation.md +358 -0
- plans/documentation-code-audit/5-Physics-MultiIndex-Compliance.md +464 -0
- plans/documentation-code-audit/6-Doctest-Integration.md +523 -0
- plans/documentation-code-audit/7-Reporting-Documentation.md +498 -0
- plans/documentation-code-audit/8-Closeout.md +456 -0
- plans/documentation-rebuild-session/compacted_state.md +109 -0
- plans/documentation-rendering-fixes/0-Overview.md +104 -0
- plans/documentation-rendering-fixes/1-Sphinx-Build-Diagnostics-Warning-Audit.md +101 -0
- plans/documentation-rendering-fixes/2-Configuration-Infrastructure-Fixes.md +113 -0
- plans/documentation-rendering-fixes/3-Docstring-Syntax-Audit-Repair.md +131 -0
- plans/documentation-rendering-fixes/4-HTML-Page-Rendering-Verification.md +113 -0
- plans/documentation-rendering-fixes/5-Advanced-Documentation-Quality-Assurance.md +119 -0
- plans/documentation-rendering-fixes/6-Documentation-Build-Optimization-Testing.md +129 -0
- plans/documentation-rendering-fixes/compacted_state.md +132 -0
- plans/documentation-template-fix/0-Overview.md +197 -0
- plans/documentation-template-fix/1-Template-System-Analysis.md +269 -0
- plans/documentation-template-fix/2-Template-Modification.md +609 -0
- plans/documentation-template-fix/3-Build-System-Integration.md +766 -0
- plans/documentation-template-fix/4-Testing-Validation.md +1399 -0
- plans/documentation-template-fix/5-Documentation-Training.md +602 -0
- plans/documentation-workflow-fix/0-Overview.md +222 -0
- plans/documentation-workflow-fix/1-Immediate-Fixes.md +238 -0
- plans/documentation-workflow-fix/2-Configuration-Setup.md +298 -0
- plans/documentation-workflow-fix/3-Pre-commit-Integration.md +382 -0
- plans/documentation-workflow-fix/4-Workflow-Improvements.md +446 -0
- plans/documentation-workflow-fix/5-Documentation-and-Training.md +527 -0
- plans/duplicate-object-warnings-fix-plan.md +130 -0
- plans/github-issues-migration/0-Overview.md +510 -0
- plans/github-issues-migration/1-Foundation-Label-System.md +180 -0
- plans/github-issues-migration/2-Migration-Tool-Rewrite.md +235 -0
- plans/github-issues-migration/3-CLI-Integration-Automation.md +169 -0
- plans/github-issues-migration/4-Validated-Migration.md +252 -0
- plans/github-issues-migration/5-Documentation-Training.md +171 -0
- plans/github-issues-migration/6-Closeout.md +179 -0
- plans/github-workflows-repair/repair-plan.md +299 -0
- plans/issues_from_plans.py +342 -0
- plans/pr-270-doc-validation-fixes/0-Overview.md +354 -0
- plans/pr-270-doc-validation-fixes/1-Critical-PR-Fixes.md +117 -0
- plans/pr-270-doc-validation-fixes/2-Framework-Right-Sizing.md +129 -0
- plans/pr-270-doc-validation-fixes/3-Sustainable-Documentation.md +126 -0
- plans/pr-270-doc-validation-fixes/4-Closeout-Migration.md +143 -0
- plans/pr-270-doc-validation-fixes/PLAN_COMPLETED.md +149 -0
- plans/python-310-migration/0-Overview.md +390 -0
- plans/python-310-migration/1-Planning-Setup.md +164 -0
- plans/python-310-migration/2-Implementation.md +256 -0
- plans/python-310-migration/3-Testing-Validation.md +335 -0
- plans/python-310-migration/4-Documentation-Release.md +274 -0
- plans/python-310-migration/5-Closeout.md +252 -0
- plans/readthedocs-simplified/0-Overview.md +243 -0
- plans/readthedocs-simplified/1-Immediate-Fixes.md +216 -0
- plans/readthedocs-simplified/2-Template-Simplification.md +278 -0
- plans/readthedocs-simplified/3-ReadTheDocs-Setup.md +298 -0
- plans/readthedocs-simplified/4-Testing-Validation.md +328 -0
- plans/readthedocs-simplified/5-Closeout.md +231 -0
- plans/readthedocs-simplified/compacted_state.md +127 -0
- plans/session-compaction-2025-08-12/compacted_state.md +114 -0
- plans/session-compaction-2025-08-13/compacted_state.md +145 -0
- plans/session-continuity-protocol/0-Overview.md +35 -0
- plans/session-continuity-protocol/1-Core-Principles-Framework.md +40 -0
- plans/session-continuity-protocol/2-Pre-Session-Validation-System.md +79 -0
- plans/session-continuity-protocol/3-Context-Switching-Prevention.md +87 -0
- plans/session-continuity-protocol/4-Progress-Tracking-Recovery.md +100 -0
- plans/sphinx-warnings-analysis.md +222 -0
- plans/systemprompt-optimization/0-Overview.md +447 -0
- plans/systemprompt-optimization/1-Deploy-SystemPrompt.md +114 -0
- plans/systemprompt-optimization/2-Documentation-Alignment.md +198 -0
- plans/systemprompt-optimization/3-Monitoring-Infrastructure.md +396 -0
- plans/systemprompt-optimization/4-Implementation-Script.md +450 -0
- plans/systemprompt-optimization/9-Closeout.md +165 -0
- plans/systemprompt-optimization/compacted_state.md +143 -0
- plans/template-value-propositions/0-Overview.md +357 -0
- plans/template-value-propositions/1-Value-Proposition-Framework-Design.md +144 -0
- plans/template-value-propositions/2-Plan-Template-Enhancement.md +178 -0
- plans/template-value-propositions/3-Value-Generator-Hook-Implementation.md +291 -0
- plans/template-value-propositions/4-Value-Validator-Hook-Implementation.md +274 -0
- plans/template-value-propositions/5-Documentation-Agent-Updates.md +219 -0
- plans/template-value-propositions/6-Integration-Testing-Validation.md +247 -0
- plans/tests-audit/0-Overview.md +410 -0
- plans/tests-audit/1-Discovery-Inventory.md +170 -0
- plans/tests-audit/2-Physics-Validation-Audit.md +195 -0
- plans/tests-audit/3-Architecture-Compliance.md +195 -0
- plans/tests-audit/4-Numerical-Stability-Analysis.md +203 -0
- plans/tests-audit/5-Documentation-Enhancement.md +220 -0
- plans/tests-audit/6-Audit-Deliverables.md +220 -0
- plans/tests-audit/7-Closeout.md +252 -0
- plans/tests-audit/artifacts/ARCHITECTURE_COMPLIANCE_REPORT.md +315 -0
- plans/tests-audit/artifacts/ARCHITECTURE_RECOMMENDATIONS.md +943 -0
- plans/tests-audit/artifacts/COMPREHENSIVE_AUDIT_REPORT.md +356 -0
- plans/tests-audit/artifacts/CONTRIBUTING_ENHANCED_TEMPLATE.md +419 -0
- plans/tests-audit/artifacts/COVERAGE_GAP_ANALYSIS.md +152 -0
- plans/tests-audit/artifacts/DOCUMENTATION_ENHANCEMENT_REPORT.md +502 -0
- plans/tests-audit/artifacts/EXECUTIVE_AUDIT_SUMMARY.md +129 -0
- plans/tests-audit/artifacts/IMPLEMENTATION_ROADMAP.md +647 -0
- plans/tests-audit/artifacts/NUMERICAL_RECOMMENDATIONS.md +739 -0
- plans/tests-audit/artifacts/NUMERICAL_STABILITY_GUIDE_TEMPLATE.rst +451 -0
- plans/tests-audit/artifacts/NUMERICAL_STABILITY_REPORT.md +301 -0
- plans/tests-audit/artifacts/PHASE_3_SUMMARY.md +280 -0
- plans/tests-audit/artifacts/PHASE_4_SUMMARY.md +229 -0
- plans/tests-audit/artifacts/PHASE_5_SUMMARY.md +292 -0
- plans/tests-audit/artifacts/PHASE_6_CLOSEOUT.md +278 -0
- plans/tests-audit/artifacts/PHYSICS_GUIDE_TEMPLATE.rst +268 -0
- plans/tests-audit/artifacts/PHYSICS_VALIDATION_REPORT.md +235 -0
- plans/tests-audit/artifacts/TECHNICAL_DELIVERABLES_PACKAGE.md +2502 -0
- plans/tests-audit/artifacts/TEST_INVENTORY.csv +1204 -0
- plans/tests-audit/artifacts/TEST_INVENTORY.md +135 -0
- plans/tests-audit/artifacts/test_discovery_analysis.py +231 -0
- plans/tests-audit/artifacts/test_parser.py +395 -0
- solarwindpy/README.md +3 -0
- solarwindpy/Untitled.ipynb +54 -0
- solarwindpy/__init__.py +74 -0
- solarwindpy/core/__init__.py +23 -0
- solarwindpy/core/alfvenic_turbulence.py +804 -0
- solarwindpy/core/base.py +267 -0
- solarwindpy/core/ions.py +309 -0
- solarwindpy/core/plasma.py +2133 -0
- solarwindpy/core/spacecraft.py +256 -0
- solarwindpy/core/tensor.py +90 -0
- solarwindpy/core/units_constants.py +199 -0
- solarwindpy/core/vector.py +328 -0
- solarwindpy/fitfunctions/__init__.py +20 -0
- solarwindpy/fitfunctions/core.py +734 -0
- solarwindpy/fitfunctions/exponentials.py +188 -0
- solarwindpy/fitfunctions/gaussians.py +264 -0
- solarwindpy/fitfunctions/lines.py +116 -0
- solarwindpy/fitfunctions/moyal.py +71 -0
- solarwindpy/fitfunctions/plots.py +751 -0
- solarwindpy/fitfunctions/power_laws.py +209 -0
- solarwindpy/fitfunctions/tex_info.py +568 -0
- solarwindpy/fitfunctions/trend_fits.py +482 -0
- solarwindpy/instabilities/__init__.py +16 -0
- solarwindpy/instabilities/beta_ani.py +82 -0
- solarwindpy/instabilities/verscharen2016.py +631 -0
- solarwindpy/plotting/__init__.py +33 -0
- solarwindpy/plotting/agg_plot.py +489 -0
- solarwindpy/plotting/base.py +465 -0
- solarwindpy/plotting/hist1d.py +405 -0
- solarwindpy/plotting/hist2d.py +1035 -0
- solarwindpy/plotting/histograms.py +1845 -0
- solarwindpy/plotting/labels/__init__.py +104 -0
- solarwindpy/plotting/labels/base.py +686 -0
- solarwindpy/plotting/labels/chemistry.py +19 -0
- solarwindpy/plotting/labels/composition.py +100 -0
- solarwindpy/plotting/labels/datetime.py +235 -0
- solarwindpy/plotting/labels/elemental_abundance.py +73 -0
- solarwindpy/plotting/labels/special.py +794 -0
- solarwindpy/plotting/orbits.py +515 -0
- solarwindpy/plotting/scatter.py +99 -0
- solarwindpy/plotting/select_data_from_figure.py +329 -0
- solarwindpy/plotting/spiral.py +980 -0
- solarwindpy/plotting/tools.py +434 -0
- solarwindpy/scripts/__init__.py +1 -0
- solarwindpy/scripts/logs/.gitignore +1 -0
- solarwindpy/solar_activity/__init__.py +53 -0
- solarwindpy/solar_activity/base.py +605 -0
- solarwindpy/solar_activity/lisird/__init__.py +3 -0
- solarwindpy/solar_activity/lisird/extrema_calculator.py +394 -0
- solarwindpy/solar_activity/lisird/lisird.py +319 -0
- solarwindpy/solar_activity/plots.py +116 -0
- solarwindpy/solar_activity/sunspot_number/.DS_Store +0 -0
- solarwindpy/solar_activity/sunspot_number/__init__.py +3 -0
- solarwindpy/solar_activity/sunspot_number/sidc.py +556 -0
- solarwindpy/solar_activity/sunspot_number/ssn_extrema.csv +72 -0
- solarwindpy/solar_activity/sunspot_number/ssn_extrema.csv.silso +72 -0
- solarwindpy/tools/__init__.py +162 -0
- solarwindpy-0.1.0.dist-info/METADATA +181 -0
- solarwindpy-0.1.0.dist-info/RECORD +409 -0
- {solarwindpy-0.0.1.dev0.dist-info → solarwindpy-0.1.0.dist-info}/WHEEL +1 -1
- solarwindpy-0.1.0.dist-info/licenses/LICENSE.rst +32 -0
- solarwindpy-0.1.0.dist-info/top_level.txt +3 -0
- tests/__init__.py +1 -0
- tests/conftest.py +10 -0
- tests/core/__init__.py +1 -0
- tests/core/test_alfvenic_turbulence.py +544 -0
- tests/core/test_base.py +112 -0
- tests/core/test_base_head_tail.py +29 -0
- tests/core/test_base_mi_tuples.py +11 -0
- tests/core/test_core_verify_datetimeindex.py +32 -0
- tests/core/test_ions.py +325 -0
- tests/core/test_plasma.py +2581 -0
- tests/core/test_plasma_io.py +12 -0
- tests/core/test_quantities.py +507 -0
- tests/core/test_spacecraft.py +210 -0
- tests/core/test_units_constants.py +22 -0
- tests/data/epoch.csv +4 -0
- tests/data/plasma.csv +4 -0
- tests/data/spacecraft.csv +4 -0
- tests/fitfunctions/conftest.py +60 -0
- tests/fitfunctions/test_core.py +193 -0
- tests/fitfunctions/test_exponentials.py +342 -0
- tests/fitfunctions/test_gaussians.py +142 -0
- tests/fitfunctions/test_lines.py +349 -0
- tests/fitfunctions/test_moyal.py +258 -0
- tests/fitfunctions/test_plots.py +258 -0
- tests/fitfunctions/test_power_laws.py +365 -0
- tests/fitfunctions/test_tex_info.py +183 -0
- tests/fitfunctions/test_trend_fit_properties.py +31 -0
- tests/fitfunctions/test_trend_fits.py +244 -0
- tests/plotting/__init__.py +1 -0
- tests/plotting/labels/__init__.py +1 -0
- tests/plotting/labels/test_chemistry.py +243 -0
- tests/plotting/labels/test_composition.py +345 -0
- tests/plotting/labels/test_datetime.py +445 -0
- tests/plotting/labels/test_elemental_abundance.py +366 -0
- tests/plotting/labels/test_init.py +66 -0
- tests/plotting/labels/test_labels_base.py +347 -0
- tests/plotting/labels/test_special.py +550 -0
- tests/plotting/test_agg_plot.py +602 -0
- tests/plotting/test_base.py +752 -0
- tests/plotting/test_fixtures_utilities.py +775 -0
- tests/plotting/test_histograms.py +546 -0
- tests/plotting/test_integration.py +675 -0
- tests/plotting/test_orbits.py +435 -0
- tests/plotting/test_performance.py +708 -0
- tests/plotting/test_scatter.py +752 -0
- tests/plotting/test_select_data_from_figure.py +1209 -0
- tests/plotting/test_spiral.py +573 -0
- tests/plotting/test_tools.py +607 -0
- tests/plotting/test_visual_validation.py +465 -0
- tests/solar_activity/__init__.py +1 -0
- tests/solar_activity/lisird/__init__.py +1 -0
- tests/solar_activity/lisird/test_extrema_calculator.py +593 -0
- tests/solar_activity/lisird/test_lisird_id.py +187 -0
- tests/solar_activity/sunspot_number/__init__.py +1 -0
- tests/solar_activity/sunspot_number/test_init.py +399 -0
- tests/solar_activity/sunspot_number/test_sidc.py +465 -0
- tests/solar_activity/sunspot_number/test_sidc_id.py +223 -0
- tests/solar_activity/sunspot_number/test_sidc_loader.py +275 -0
- tests/solar_activity/sunspot_number/test_ssn_extrema.py +406 -0
- tests/solar_activity/test_base.py +656 -0
- tests/solar_activity/test_init.py +396 -0
- tests/solar_activity/test_plots.py +371 -0
- tests/test_circular_imports.py +408 -0
- tests/test_issue_titles.py +25 -0
- tests/test_statusline.py +298 -0
- solarwindpy-0.0.1.dev0.dist-info/METADATA +0 -14
- solarwindpy-0.0.1.dev0.dist-info/RECORD +0 -4
- solarwindpy-0.0.1.dev0.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"""Tests for exponential fit functions."""
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from solarwindpy.fitfunctions.exponentials import (
|
|
8
|
+
Exponential,
|
|
9
|
+
ExponentialPlusC,
|
|
10
|
+
ExponentialCDF,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.mark.parametrize(
|
|
15
|
+
"cls, expected_params, sample_args, expected_shape",
|
|
16
|
+
[
|
|
17
|
+
(Exponential, ("x", "c", "A"), (0.0, 1.0, 2.0), ()),
|
|
18
|
+
(ExponentialPlusC, ("x", "c", "A", "d"), (0.0, 1.0, 2.0, 0.5), ()),
|
|
19
|
+
(ExponentialCDF, ("x", "c"), (0.0, 1.0), ()),
|
|
20
|
+
],
|
|
21
|
+
)
|
|
22
|
+
def test_function_signature_and_output(
|
|
23
|
+
cls, expected_params, sample_args, expected_shape
|
|
24
|
+
):
|
|
25
|
+
"""Test function signatures and basic output for exponential classes."""
|
|
26
|
+
x = np.linspace(0.0, 2.0, 10)
|
|
27
|
+
y = np.ones_like(x)
|
|
28
|
+
obj = cls(x, y)
|
|
29
|
+
|
|
30
|
+
# ExponentialCDF needs y0 to be set before function can be called
|
|
31
|
+
if cls.__name__ == "ExponentialCDF":
|
|
32
|
+
obj.set_y0(1.0)
|
|
33
|
+
|
|
34
|
+
# Test function signature
|
|
35
|
+
sig = inspect.signature(obj.function)
|
|
36
|
+
assert tuple(sig.parameters.keys()) == expected_params
|
|
37
|
+
|
|
38
|
+
# Test function call
|
|
39
|
+
result = obj.function(*sample_args)
|
|
40
|
+
assert np.isscalar(result) or result.shape == expected_shape
|
|
41
|
+
assert np.isfinite(result)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.fixture
|
|
45
|
+
def exponential_data():
|
|
46
|
+
"""Generate synthetic exponential data for testing."""
|
|
47
|
+
np.random.seed(42)
|
|
48
|
+
x = np.linspace(0, 3, 30)
|
|
49
|
+
c, A = 0.8, 3.0
|
|
50
|
+
noise = np.random.normal(0, 0.1, size=x.shape)
|
|
51
|
+
y = A * np.exp(-c * x) + noise
|
|
52
|
+
w = np.ones_like(x)
|
|
53
|
+
return x, y, w
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.mark.parametrize("cls", [Exponential, ExponentialPlusC, ExponentialCDF])
|
|
57
|
+
def test_p0_zero_size_input(cls):
|
|
58
|
+
"""Test p0 behavior with zero-size input arrays."""
|
|
59
|
+
x = np.array([])
|
|
60
|
+
y = np.array([])
|
|
61
|
+
obj = cls(x, y)
|
|
62
|
+
|
|
63
|
+
with pytest.raises((ValueError, AssertionError)):
|
|
64
|
+
_ = obj.p0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_exponential_p0_estimation(exponential_data):
|
|
68
|
+
"""Test initial parameter estimation for Exponential class."""
|
|
69
|
+
x, y, w = exponential_data
|
|
70
|
+
obj = Exponential(x, y)
|
|
71
|
+
obj.make_fit()
|
|
72
|
+
|
|
73
|
+
p0 = obj.p0
|
|
74
|
+
assert len(p0) == 2
|
|
75
|
+
assert isinstance(p0[0], (int, float)) # c
|
|
76
|
+
assert isinstance(p0[1], (int, float)) # A
|
|
77
|
+
assert p0[1] > 0 # A should be positive for exponential decay
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_exponential_plus_c_p0_estimation(exponential_data):
|
|
81
|
+
"""Test initial parameter estimation for ExponentialPlusC class."""
|
|
82
|
+
x, y, w = exponential_data
|
|
83
|
+
# Add constant offset to data
|
|
84
|
+
y_offset = y + 0.5
|
|
85
|
+
obj = ExponentialPlusC(x, y_offset)
|
|
86
|
+
obj.make_fit()
|
|
87
|
+
|
|
88
|
+
p0 = obj.p0
|
|
89
|
+
assert len(p0) == 3
|
|
90
|
+
assert isinstance(p0[0], (int, float)) # c
|
|
91
|
+
assert isinstance(p0[1], (int, float)) # A
|
|
92
|
+
assert isinstance(p0[2], (int, float)) # d
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_exponential_cdf_p0_estimation(exponential_data):
|
|
96
|
+
"""Test initial parameter estimation for ExponentialCDF class."""
|
|
97
|
+
x, y, w = exponential_data
|
|
98
|
+
# Transform to CDF-like data
|
|
99
|
+
y_cdf = np.cumsum(y) / np.sum(y)
|
|
100
|
+
obj = ExponentialCDF(x, y_cdf)
|
|
101
|
+
obj.set_y0(1.0) # Set amplitude before fitting
|
|
102
|
+
|
|
103
|
+
p0 = obj.p0
|
|
104
|
+
assert len(p0) == 1
|
|
105
|
+
assert isinstance(p0[0], (int, float)) # c
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@pytest.mark.parametrize(
|
|
109
|
+
"cls, expected_tex",
|
|
110
|
+
[
|
|
111
|
+
(Exponential, r"f(x)=A \cdot e^{-cx}"),
|
|
112
|
+
(ExponentialPlusC, r"f(x)=A \cdot e^{-cx} + d"),
|
|
113
|
+
(ExponentialCDF, r"f(x)=A \left(1 - e^{-cx}\right)"),
|
|
114
|
+
],
|
|
115
|
+
)
|
|
116
|
+
def test_TeX_function_strings(cls, expected_tex):
|
|
117
|
+
"""Test TeX function representation strings."""
|
|
118
|
+
x = np.array([1.0, 2.0])
|
|
119
|
+
y = np.array([1.0, 0.5])
|
|
120
|
+
obj = cls(x, y)
|
|
121
|
+
assert obj.TeX_function == expected_tex
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_make_fit_success_regular(exponential_data):
|
|
125
|
+
"""Test successful fitting for regular exponential classes."""
|
|
126
|
+
x, y, w = exponential_data
|
|
127
|
+
|
|
128
|
+
for cls in [Exponential, ExponentialPlusC]:
|
|
129
|
+
obj = cls(x, y)
|
|
130
|
+
|
|
131
|
+
# Test fitting succeeds
|
|
132
|
+
obj.make_fit()
|
|
133
|
+
|
|
134
|
+
# Test fit results are available
|
|
135
|
+
assert obj.popt is not None
|
|
136
|
+
assert obj.pcov is not None
|
|
137
|
+
assert obj.chisq_dof is not None
|
|
138
|
+
assert obj.fit_result is not None
|
|
139
|
+
|
|
140
|
+
# Test output shapes
|
|
141
|
+
assert len(obj.popt) == len(obj.p0)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_make_fit_success_cdf(exponential_data):
|
|
145
|
+
"""Test successful fitting for ExponentialCDF class."""
|
|
146
|
+
x, y, w = exponential_data
|
|
147
|
+
# Transform to CDF-like data
|
|
148
|
+
y_cdf = np.cumsum(y) / np.sum(y)
|
|
149
|
+
|
|
150
|
+
obj = ExponentialCDF(x, y_cdf)
|
|
151
|
+
obj.set_y0(1.0) # Set amplitude before fitting
|
|
152
|
+
|
|
153
|
+
# Test fitting succeeds
|
|
154
|
+
obj.make_fit()
|
|
155
|
+
|
|
156
|
+
# Test fit results are available
|
|
157
|
+
assert obj.popt is not None
|
|
158
|
+
assert obj.pcov is not None
|
|
159
|
+
assert obj.chisq_dof is not None
|
|
160
|
+
assert obj.fit_result is not None
|
|
161
|
+
|
|
162
|
+
# Test output shapes
|
|
163
|
+
assert len(obj.popt) == len(obj.p0)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def test_make_fit_insufficient_data():
|
|
167
|
+
"""Test fitting failure with insufficient data."""
|
|
168
|
+
# Test Exponential and ExponentialPlusC
|
|
169
|
+
for cls in [Exponential, ExponentialPlusC]:
|
|
170
|
+
x = np.array([1.0]) # Single point
|
|
171
|
+
y = np.array([1.0])
|
|
172
|
+
obj = cls(x, y)
|
|
173
|
+
|
|
174
|
+
# By default, make_fit returns exceptions rather than raising them
|
|
175
|
+
result = obj.make_fit()
|
|
176
|
+
assert isinstance(result, ValueError)
|
|
177
|
+
assert "insufficient data" in str(result).lower()
|
|
178
|
+
|
|
179
|
+
# Test ExponentialCDF (needs special setup)
|
|
180
|
+
# Note: ExponentialCDF has only 1 parameter (c) so 1 data point is technically sufficient
|
|
181
|
+
# The fit will succeed but may not be meaningful
|
|
182
|
+
x = np.array([1.0])
|
|
183
|
+
y = np.array([1.0])
|
|
184
|
+
obj = ExponentialCDF(x, y)
|
|
185
|
+
obj.set_y0(1.0)
|
|
186
|
+
|
|
187
|
+
result = obj.make_fit()
|
|
188
|
+
# For ExponentialCDF with 1 point, the fit technically succeeds
|
|
189
|
+
# (1 point for 1 parameter), so it returns None
|
|
190
|
+
assert result is None or isinstance(result, ValueError)
|
|
191
|
+
if isinstance(result, ValueError):
|
|
192
|
+
assert "insufficient data" in str(result).lower()
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def test_exponential_numerical_stability():
|
|
196
|
+
"""Test exponential function handles large negative exponents."""
|
|
197
|
+
x = np.array([0.0, 10.0, 100.0]) # Large x values
|
|
198
|
+
y = np.array([1.0, 0.1, 0.01])
|
|
199
|
+
obj = Exponential(x, y)
|
|
200
|
+
|
|
201
|
+
# Should not raise overflow warnings
|
|
202
|
+
result = obj.function(100.0, 1.0, 1.0) # exp(-100) -> very small
|
|
203
|
+
assert np.isfinite(result)
|
|
204
|
+
assert result >= 0
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def test_exponential_plus_c_constant_term():
|
|
208
|
+
"""Test that ExponentialPlusC handles constant offset correctly."""
|
|
209
|
+
x = np.linspace(0, 2, 20)
|
|
210
|
+
c, A, d = 1.0, 2.0, 0.5
|
|
211
|
+
y_true = A * np.exp(-c * x) + d
|
|
212
|
+
|
|
213
|
+
obj = ExponentialPlusC(x, y_true)
|
|
214
|
+
result = obj.function(x, c, A, d)
|
|
215
|
+
|
|
216
|
+
assert np.allclose(result, y_true, rtol=1e-10)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def test_exponential_cdf_monotonicity():
|
|
220
|
+
"""Test that ExponentialCDF produces monotonically increasing output."""
|
|
221
|
+
x = np.linspace(0, 5, 20)
|
|
222
|
+
c = 0.5
|
|
223
|
+
|
|
224
|
+
obj = ExponentialCDF(x, np.ones_like(x)) # Dummy y data
|
|
225
|
+
obj.set_y0(1.0) # Set amplitude
|
|
226
|
+
result = obj.function(x, c)
|
|
227
|
+
|
|
228
|
+
# CDF should be monotonically increasing
|
|
229
|
+
assert np.all(np.diff(result) >= 0)
|
|
230
|
+
# Should approach y0 as x increases
|
|
231
|
+
assert result[-1] < obj.y0 # Not quite reaching y0 for finite x
|
|
232
|
+
assert result[-1] > 0.9 * obj.y0 # But close to it
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def test_str_and_call_methods_regular(exponential_data):
|
|
236
|
+
"""Test string representation and callable interface for regular exponentials."""
|
|
237
|
+
x, y, w = exponential_data
|
|
238
|
+
|
|
239
|
+
for cls in [Exponential, ExponentialPlusC]:
|
|
240
|
+
obj = cls(x, y)
|
|
241
|
+
obj.make_fit()
|
|
242
|
+
|
|
243
|
+
# Test string representation
|
|
244
|
+
str_repr = str(obj)
|
|
245
|
+
assert cls.__name__ in str_repr
|
|
246
|
+
|
|
247
|
+
# Test callable interface
|
|
248
|
+
x_test = np.array([0.5, 1.0, 1.5])
|
|
249
|
+
y_pred = obj(x_test)
|
|
250
|
+
assert y_pred.shape == x_test.shape
|
|
251
|
+
assert np.all(np.isfinite(y_pred))
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def test_str_and_call_methods_cdf(exponential_data):
|
|
255
|
+
"""Test string representation and callable interface for ExponentialCDF."""
|
|
256
|
+
x, y, w = exponential_data
|
|
257
|
+
# Transform to CDF-like data
|
|
258
|
+
y_cdf = np.cumsum(y) / np.sum(y)
|
|
259
|
+
|
|
260
|
+
obj = ExponentialCDF(x, y_cdf)
|
|
261
|
+
obj.set_y0(1.0) # Set amplitude before fitting
|
|
262
|
+
obj.make_fit()
|
|
263
|
+
|
|
264
|
+
# Test string representation
|
|
265
|
+
str_repr = str(obj)
|
|
266
|
+
assert "ExponentialCDF" in str_repr
|
|
267
|
+
|
|
268
|
+
# Test callable interface
|
|
269
|
+
x_test = np.array([0.5, 1.0, 1.5])
|
|
270
|
+
y_pred = obj(x_test)
|
|
271
|
+
assert y_pred.shape == x_test.shape
|
|
272
|
+
assert np.all(np.isfinite(y_pred))
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def test_exponential_decay_behavior():
|
|
276
|
+
"""Test that Exponential produces proper decay behavior."""
|
|
277
|
+
x = np.linspace(0, 3, 10)
|
|
278
|
+
y = 2.0 * np.exp(-0.5 * x) # True exponential decay
|
|
279
|
+
|
|
280
|
+
obj = Exponential(x, y)
|
|
281
|
+
obj.make_fit()
|
|
282
|
+
|
|
283
|
+
# Check that function values decrease with x
|
|
284
|
+
x_test = np.array([0.0, 1.0, 2.0, 3.0])
|
|
285
|
+
y_test = obj(x_test)
|
|
286
|
+
|
|
287
|
+
# Should be decreasing
|
|
288
|
+
assert np.all(np.diff(y_test) < 0)
|
|
289
|
+
# Should be positive
|
|
290
|
+
assert np.all(y_test > 0)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@pytest.mark.parametrize("cls", [Exponential, ExponentialPlusC, ExponentialCDF])
|
|
294
|
+
def test_property_access_before_fit(cls):
|
|
295
|
+
"""Test accessing properties before fitting raises appropriate errors."""
|
|
296
|
+
x = np.array([1.0, 2.0, 3.0])
|
|
297
|
+
y = np.array([1.0, 0.5, 0.25])
|
|
298
|
+
obj = cls(x, y)
|
|
299
|
+
|
|
300
|
+
# These should work before fitting
|
|
301
|
+
assert obj.TeX_function is not None
|
|
302
|
+
assert obj.p0 is not None
|
|
303
|
+
|
|
304
|
+
# These should raise AttributeError before fitting
|
|
305
|
+
with pytest.raises(AttributeError):
|
|
306
|
+
_ = obj.popt
|
|
307
|
+
with pytest.raises(AttributeError):
|
|
308
|
+
_ = obj.pcov
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def test_exponential_with_weights(exponential_data):
|
|
312
|
+
"""Test exponential fitting with observation weights."""
|
|
313
|
+
x, y, w = exponential_data
|
|
314
|
+
|
|
315
|
+
# Create varying weights (higher weight for early points)
|
|
316
|
+
w_varied = np.linspace(2.0, 0.5, len(x))
|
|
317
|
+
|
|
318
|
+
obj = Exponential(x, y, weights=w_varied)
|
|
319
|
+
obj.make_fit()
|
|
320
|
+
|
|
321
|
+
# Should complete successfully
|
|
322
|
+
assert obj.popt is not None
|
|
323
|
+
assert len(obj.popt) == 2
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
@pytest.mark.parametrize("cls", [Exponential, ExponentialPlusC, ExponentialCDF])
|
|
327
|
+
def test_edge_case_single_parameter_bounds(cls):
|
|
328
|
+
"""Test behavior with extreme parameter values."""
|
|
329
|
+
x = np.array([0.0, 1.0, 2.0])
|
|
330
|
+
y = np.array([1.0, 0.5, 0.25])
|
|
331
|
+
obj = cls(x, y)
|
|
332
|
+
|
|
333
|
+
# Test with very small decay constant
|
|
334
|
+
if cls == Exponential:
|
|
335
|
+
result = obj.function(x, 1e-6, 1.0) # Very slow decay
|
|
336
|
+
assert np.allclose(result, 1.0, atol=1e-5)
|
|
337
|
+
|
|
338
|
+
# Test with very large decay constant
|
|
339
|
+
if cls == Exponential:
|
|
340
|
+
result = obj.function(x, 100.0, 1.0) # Very fast decay
|
|
341
|
+
assert result[0] == 1.0 # At x=0
|
|
342
|
+
assert result[-1] < 1e-40 # At x=2, essentially zero
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from solarwindpy.fitfunctions.gaussians import (
|
|
6
|
+
Gaussian,
|
|
7
|
+
GaussianNormalized,
|
|
8
|
+
GaussianLn,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.parametrize(
|
|
13
|
+
"cls, expected_params, sample_args, expected_output",
|
|
14
|
+
[
|
|
15
|
+
(Gaussian, ("x", "mu", "sigma", "A"), (0.0, 0.0, 1.0, 1.0), 1.0),
|
|
16
|
+
(
|
|
17
|
+
GaussianNormalized,
|
|
18
|
+
("x", "mu", "sigma", "n"),
|
|
19
|
+
(0.0, 0.0, 1.0, 1.0),
|
|
20
|
+
1.0 / (np.sqrt(2 * np.pi)),
|
|
21
|
+
),
|
|
22
|
+
(GaussianLn, ("x", "m", "s", "A"), (1.0, 0.0, 1.0, 1.0), 1.0),
|
|
23
|
+
],
|
|
24
|
+
)
|
|
25
|
+
def test_function_signature_and_output(
|
|
26
|
+
cls, expected_params, sample_args, expected_output
|
|
27
|
+
):
|
|
28
|
+
x = np.linspace(-1.0, 1.0, 5)
|
|
29
|
+
y = np.ones_like(x)
|
|
30
|
+
obj = cls(x, y)
|
|
31
|
+
sig = inspect.signature(obj.function)
|
|
32
|
+
assert tuple(sig.parameters.keys()) == expected_params
|
|
33
|
+
xval, *params = sample_args
|
|
34
|
+
assert np.allclose(obj.function(xval, *params), expected_output)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.mark.parametrize("cls", [Gaussian, GaussianNormalized, GaussianLn])
|
|
38
|
+
def test_p0_zero_size_input(cls):
|
|
39
|
+
x = np.array([])
|
|
40
|
+
y = np.array([])
|
|
41
|
+
obj = cls(x, y)
|
|
42
|
+
with pytest.raises(ValueError, match="insufficient data"):
|
|
43
|
+
_ = obj.p0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.mark.parametrize(
|
|
47
|
+
"cls, params",
|
|
48
|
+
[
|
|
49
|
+
(Gaussian, dict(mu=1.0, sigma=0.5, amp=2.0)),
|
|
50
|
+
(GaussianNormalized, dict(mu=1.0, sigma=0.5, n=5.0)),
|
|
51
|
+
(GaussianLn, dict(m=0.3, s=0.2, A=3.0)),
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
def test_p0_estimation(cls, params):
|
|
55
|
+
if cls is Gaussian:
|
|
56
|
+
x = np.linspace(
|
|
57
|
+
params["mu"] - 5 * params["sigma"], params["mu"] + 5 * params["sigma"], 100
|
|
58
|
+
)
|
|
59
|
+
y = params["amp"] * np.exp(-0.5 * ((x - params["mu"]) / params["sigma"]) ** 2)
|
|
60
|
+
mean = (x * y).sum() / y.sum()
|
|
61
|
+
std = np.sqrt(((x - mean) ** 2 * y).sum() / y.sum())
|
|
62
|
+
peak = y.max()
|
|
63
|
+
expected = [mean, std, peak]
|
|
64
|
+
elif cls is GaussianNormalized:
|
|
65
|
+
x = np.linspace(
|
|
66
|
+
params["mu"] - 5 * params["sigma"], params["mu"] + 5 * params["sigma"], 100
|
|
67
|
+
)
|
|
68
|
+
A = params["n"] / (np.sqrt(2 * np.pi) * params["sigma"])
|
|
69
|
+
y = A * np.exp(-0.5 * ((x - params["mu"]) / params["sigma"]) ** 2)
|
|
70
|
+
mean = (x * y).sum() / y.sum()
|
|
71
|
+
std = np.sqrt(((x - mean) ** 2 * y).sum() / y.sum())
|
|
72
|
+
peak = y.max()
|
|
73
|
+
n_est = peak * std * np.sqrt(2 * np.pi)
|
|
74
|
+
expected = [mean, std, n_est]
|
|
75
|
+
else: # GaussianLn
|
|
76
|
+
x = np.linspace(
|
|
77
|
+
np.exp(params["m"] - 5 * params["s"]),
|
|
78
|
+
np.exp(params["m"] + 5 * params["s"]),
|
|
79
|
+
100,
|
|
80
|
+
)
|
|
81
|
+
lnx = np.log(x)
|
|
82
|
+
y = params["A"] * np.exp(-0.5 * ((lnx - params["m"]) / params["s"]) ** 2)
|
|
83
|
+
mean = (x * y).sum() / y.sum()
|
|
84
|
+
std = ((x - mean) ** 2 * y).sum() / y.sum()
|
|
85
|
+
peak = y.max()
|
|
86
|
+
expected = [np.log(mean), np.log(std), np.log(peak)]
|
|
87
|
+
obj = cls(x, y)
|
|
88
|
+
assert np.allclose(obj.p0, expected)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@pytest.mark.parametrize(
|
|
92
|
+
"cls, expected",
|
|
93
|
+
[
|
|
94
|
+
(
|
|
95
|
+
Gaussian,
|
|
96
|
+
r"f(x)=A \cdot e^{-\frac{1}{2} \left(\frac{x-\mu}{\sigma}\right)^2}",
|
|
97
|
+
),
|
|
98
|
+
(
|
|
99
|
+
GaussianNormalized,
|
|
100
|
+
r"f(x)=\frac{n}{\sqrt{2 \pi} \sigma} e^{-\frac{1}{2} \left(\frac{x-\mu}{\sigma}\right)^2}",
|
|
101
|
+
),
|
|
102
|
+
(
|
|
103
|
+
GaussianLn,
|
|
104
|
+
(
|
|
105
|
+
r"f(x) =A \cdot"
|
|
106
|
+
r"\exp\left["
|
|
107
|
+
r"\frac{\left(\ln x - m\right)^2}{2 s^2}"
|
|
108
|
+
r"\right]"
|
|
109
|
+
),
|
|
110
|
+
),
|
|
111
|
+
],
|
|
112
|
+
)
|
|
113
|
+
def test_TeX_function_strings(cls, expected):
|
|
114
|
+
x = np.linspace(0.0, 1.0, 5)
|
|
115
|
+
y = np.ones_like(x)
|
|
116
|
+
obj = cls(x, y)
|
|
117
|
+
assert obj.TeX_function == expected
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@pytest.mark.parametrize("cls", [Gaussian, GaussianNormalized])
|
|
121
|
+
def test_make_fit_TeX_argnames_success(cls):
|
|
122
|
+
mu, sigma = 0.0, 0.5
|
|
123
|
+
x = np.linspace(mu - sigma, mu + sigma, 5)
|
|
124
|
+
if cls is Gaussian:
|
|
125
|
+
A = 1.0
|
|
126
|
+
y = A * np.exp(-0.5 * ((x - mu) / sigma) ** 2)
|
|
127
|
+
else:
|
|
128
|
+
n = 1.0
|
|
129
|
+
A = n / (np.sqrt(2 * np.pi) * sigma)
|
|
130
|
+
y = A * np.exp(-0.5 * ((x - mu) / sigma) ** 2)
|
|
131
|
+
obj = cls(x, y)
|
|
132
|
+
obj.make_fit()
|
|
133
|
+
assert obj.TeX_info.TeX_argnames == {"mu": r"\mu", "sigma": r"\sigma"}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@pytest.mark.parametrize("cls", [Gaussian, GaussianNormalized])
|
|
137
|
+
def test_make_fit_TeX_argnames_failure(cls):
|
|
138
|
+
x = np.linspace(0.0, 1.0, 2)
|
|
139
|
+
y = np.ones_like(x)
|
|
140
|
+
obj = cls(x, y)
|
|
141
|
+
obj.make_fit(return_exception=True)
|
|
142
|
+
assert not hasattr(obj, "_TeX_info")
|