solarwindpy 0.0.1.dev0__py3-none-any.whl → 0.1.1__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.1.dist-info/METADATA +181 -0
- solarwindpy-0.1.1.dist-info/RECORD +409 -0
- {solarwindpy-0.0.1.dev0.dist-info → solarwindpy-0.1.1.dist-info}/WHEEL +1 -1
- solarwindpy-0.1.1.dist-info/licenses/LICENSE.rst +32 -0
- solarwindpy-0.1.1.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,675 @@
|
|
|
1
|
+
"""Integration tests for plotting functionality.
|
|
2
|
+
|
|
3
|
+
Tests end-to-end workflows and cross-module integration of the plotting package.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
9
|
+
import matplotlib
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
import tempfile
|
|
13
|
+
import warnings
|
|
14
|
+
|
|
15
|
+
# Configure matplotlib for testing
|
|
16
|
+
matplotlib.use("Agg")
|
|
17
|
+
plt.ioff()
|
|
18
|
+
|
|
19
|
+
# Import SolarWindPy components
|
|
20
|
+
import solarwindpy.plotting.base as base_plotting
|
|
21
|
+
import solarwindpy.plotting.histograms as hist_plotting
|
|
22
|
+
import solarwindpy.plotting.tools as plot_tools
|
|
23
|
+
import solarwindpy.plotting.labels as labels
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import solarwindpy.plotting.scatter as scatter_plotting
|
|
27
|
+
import solarwindpy.plotting.spiral as spiral_plotting
|
|
28
|
+
import solarwindpy.plotting.orbits as orbit_plotting
|
|
29
|
+
|
|
30
|
+
ADVANCED_IMPORTS = True
|
|
31
|
+
except ImportError:
|
|
32
|
+
ADVANCED_IMPORTS = False
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TestBasicIntegrationWorkflows:
|
|
36
|
+
"""Test basic integration workflows across plotting modules."""
|
|
37
|
+
|
|
38
|
+
def setup_method(self):
|
|
39
|
+
"""Set up test data for integration tests."""
|
|
40
|
+
# Create synthetic time series data
|
|
41
|
+
self.dates = pd.date_range("2023-01-01", periods=100, freq="1h")
|
|
42
|
+
self.n_points = len(self.dates)
|
|
43
|
+
|
|
44
|
+
# Plasma parameters
|
|
45
|
+
np.random.seed(42)
|
|
46
|
+
self.density = (
|
|
47
|
+
10
|
|
48
|
+
+ 2 * np.sin(np.arange(self.n_points) / 10)
|
|
49
|
+
+ np.random.normal(0, 0.5, self.n_points)
|
|
50
|
+
)
|
|
51
|
+
self.velocity = (
|
|
52
|
+
400
|
|
53
|
+
+ 50 * np.sin(np.arange(self.n_points) / 15)
|
|
54
|
+
+ np.random.normal(0, 10, self.n_points)
|
|
55
|
+
)
|
|
56
|
+
self.temperature = (
|
|
57
|
+
1e5
|
|
58
|
+
+ 2e4 * np.sin(np.arange(self.n_points) / 8)
|
|
59
|
+
+ np.random.normal(0, 5e3, self.n_points)
|
|
60
|
+
)
|
|
61
|
+
self.magnetic_field = (
|
|
62
|
+
5
|
|
63
|
+
+ np.sin(np.arange(self.n_points) / 12)
|
|
64
|
+
+ np.random.normal(0, 0.2, self.n_points)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Create DataFrame
|
|
68
|
+
self.data = pd.DataFrame(
|
|
69
|
+
{
|
|
70
|
+
"density": self.density,
|
|
71
|
+
"velocity": self.velocity,
|
|
72
|
+
"temperature": self.temperature,
|
|
73
|
+
"b_field": self.magnetic_field,
|
|
74
|
+
},
|
|
75
|
+
index=self.dates,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def teardown_method(self):
|
|
79
|
+
"""Clean up after each test."""
|
|
80
|
+
plt.close("all")
|
|
81
|
+
|
|
82
|
+
def test_time_series_integration_workflow(self):
|
|
83
|
+
"""Test complete time series plotting workflow."""
|
|
84
|
+
fig, axes = plt.subplots(4, 1, figsize=(12, 10), sharex=True)
|
|
85
|
+
|
|
86
|
+
# Plot each parameter
|
|
87
|
+
parameters = ["density", "velocity", "temperature", "b_field"]
|
|
88
|
+
labels_text = [
|
|
89
|
+
"Density (cm⁻³)",
|
|
90
|
+
"Velocity (km/s)",
|
|
91
|
+
"Temperature (K)",
|
|
92
|
+
"B-field (nT)",
|
|
93
|
+
]
|
|
94
|
+
colors = ["blue", "red", "green", "orange"]
|
|
95
|
+
|
|
96
|
+
for i, (param, label, color) in enumerate(zip(parameters, labels_text, colors)):
|
|
97
|
+
axes[i].plot(self.data.index, self.data[param], color=color, linewidth=1.5)
|
|
98
|
+
axes[i].set_ylabel(label)
|
|
99
|
+
axes[i].grid(True, alpha=0.3)
|
|
100
|
+
|
|
101
|
+
# Add statistical info
|
|
102
|
+
mean_val = self.data[param].mean()
|
|
103
|
+
std_val = self.data[param].std()
|
|
104
|
+
axes[i].axhline(
|
|
105
|
+
mean_val,
|
|
106
|
+
color=color,
|
|
107
|
+
linestyle="--",
|
|
108
|
+
alpha=0.7,
|
|
109
|
+
label=f"Mean: {mean_val:.2f}",
|
|
110
|
+
)
|
|
111
|
+
axes[i].fill_between(
|
|
112
|
+
self.data.index,
|
|
113
|
+
mean_val - std_val,
|
|
114
|
+
mean_val + std_val,
|
|
115
|
+
alpha=0.2,
|
|
116
|
+
color=color,
|
|
117
|
+
label=f"±1σ: {std_val:.2f}",
|
|
118
|
+
)
|
|
119
|
+
axes[i].legend(fontsize=8)
|
|
120
|
+
|
|
121
|
+
axes[-1].set_xlabel("Time")
|
|
122
|
+
plt.suptitle("Solar Wind Parameters Time Series", fontsize=14)
|
|
123
|
+
plt.tight_layout()
|
|
124
|
+
|
|
125
|
+
# Validation
|
|
126
|
+
assert len(fig.axes) == 4
|
|
127
|
+
for ax in axes:
|
|
128
|
+
assert len(ax.lines) >= 1 # At least the data line
|
|
129
|
+
assert ax.get_ylabel() != ""
|
|
130
|
+
|
|
131
|
+
def test_correlation_analysis_workflow(self):
|
|
132
|
+
"""Test correlation analysis workflow."""
|
|
133
|
+
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
|
|
134
|
+
|
|
135
|
+
# Define parameter pairs for correlation
|
|
136
|
+
param_pairs = [
|
|
137
|
+
("velocity", "temperature", "V-T Correlation"),
|
|
138
|
+
("density", "b_field", "n-B Correlation"),
|
|
139
|
+
("velocity", "density", "V-n Correlation"),
|
|
140
|
+
("temperature", "b_field", "T-B Correlation"),
|
|
141
|
+
("velocity", "b_field", "V-B Correlation"),
|
|
142
|
+
("density", "temperature", "n-T Correlation"),
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
for i, (param1, param2, title) in enumerate(param_pairs):
|
|
146
|
+
row, col = divmod(i, 3)
|
|
147
|
+
ax = axes[row, col]
|
|
148
|
+
|
|
149
|
+
x = self.data[param1]
|
|
150
|
+
y = self.data[param2]
|
|
151
|
+
|
|
152
|
+
# Scatter plot
|
|
153
|
+
scatter = ax.scatter(x, y, alpha=0.6, c=range(len(x)), cmap="viridis")
|
|
154
|
+
|
|
155
|
+
# Fit line
|
|
156
|
+
z = np.polyfit(x, y, 1)
|
|
157
|
+
p = np.poly1d(z)
|
|
158
|
+
ax.plot(x, p(x), "r--", alpha=0.8, linewidth=2)
|
|
159
|
+
|
|
160
|
+
# Calculate correlation
|
|
161
|
+
correlation = np.corrcoef(x, y)[0, 1]
|
|
162
|
+
|
|
163
|
+
ax.set_xlabel(param1.title())
|
|
164
|
+
ax.set_ylabel(param2.title())
|
|
165
|
+
ax.set_title(f"{title}\nr = {correlation:.3f}")
|
|
166
|
+
ax.grid(True, alpha=0.3)
|
|
167
|
+
|
|
168
|
+
# Add colorbar for time evolution
|
|
169
|
+
if i == 0: # Only for first subplot to avoid clutter
|
|
170
|
+
plt.colorbar(scatter, ax=ax, label="Time Index")
|
|
171
|
+
|
|
172
|
+
plt.tight_layout()
|
|
173
|
+
|
|
174
|
+
# Validation
|
|
175
|
+
assert len(fig.axes) >= 6 # 6 subplots + potential colorbars
|
|
176
|
+
for ax in axes.flat:
|
|
177
|
+
assert len(ax.collections) >= 1 # Scatter plot
|
|
178
|
+
assert len(ax.lines) >= 1 # Trend line
|
|
179
|
+
|
|
180
|
+
def test_distribution_analysis_workflow(self):
|
|
181
|
+
"""Test distribution analysis workflow."""
|
|
182
|
+
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
|
|
183
|
+
|
|
184
|
+
parameters = ["density", "velocity", "temperature", "b_field"]
|
|
185
|
+
|
|
186
|
+
# Top row: Histograms
|
|
187
|
+
for i, param in enumerate(parameters):
|
|
188
|
+
ax = axes[0, i]
|
|
189
|
+
data = self.data[param]
|
|
190
|
+
|
|
191
|
+
# Histogram with statistics
|
|
192
|
+
n, bins, patches = ax.hist(
|
|
193
|
+
data,
|
|
194
|
+
bins=20,
|
|
195
|
+
alpha=0.7,
|
|
196
|
+
density=True,
|
|
197
|
+
color="skyblue",
|
|
198
|
+
edgecolor="black",
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# Add normal distribution overlay
|
|
202
|
+
mu, sigma = data.mean(), data.std()
|
|
203
|
+
x_norm = np.linspace(data.min(), data.max(), 100)
|
|
204
|
+
y_norm = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(
|
|
205
|
+
-0.5 * ((x_norm - mu) / sigma) ** 2
|
|
206
|
+
)
|
|
207
|
+
ax.plot(x_norm, y_norm, "r-", linewidth=2, label="Normal Fit")
|
|
208
|
+
|
|
209
|
+
ax.axvline(
|
|
210
|
+
mu, color="red", linestyle="--", alpha=0.7, label=f"Mean: {mu:.2f}"
|
|
211
|
+
)
|
|
212
|
+
ax.set_xlabel(param.title())
|
|
213
|
+
ax.set_ylabel("Probability Density")
|
|
214
|
+
ax.set_title(f"{param.title()} Distribution")
|
|
215
|
+
ax.legend(fontsize=8)
|
|
216
|
+
ax.grid(True, alpha=0.3)
|
|
217
|
+
|
|
218
|
+
# Bottom row: Box plots and Q-Q plots
|
|
219
|
+
# Combined box plot
|
|
220
|
+
ax_box = axes[1, 0]
|
|
221
|
+
data_normalized = [
|
|
222
|
+
self.data[param] / self.data[param].std() for param in parameters
|
|
223
|
+
]
|
|
224
|
+
box_plot = ax_box.boxplot(
|
|
225
|
+
data_normalized, labels=[p.title() for p in parameters]
|
|
226
|
+
)
|
|
227
|
+
ax_box.set_ylabel("Normalized Value")
|
|
228
|
+
ax_box.set_title("Parameter Distributions")
|
|
229
|
+
ax_box.grid(True, alpha=0.3)
|
|
230
|
+
|
|
231
|
+
# Time evolution of statistics
|
|
232
|
+
ax_stats = axes[1, 1]
|
|
233
|
+
window = 10
|
|
234
|
+
rolling_means = self.data.rolling(window=window).mean()
|
|
235
|
+
for i, param in enumerate(parameters[:2]): # Just first two to avoid clutter
|
|
236
|
+
ax_stats.plot(
|
|
237
|
+
rolling_means.index,
|
|
238
|
+
rolling_means[param],
|
|
239
|
+
label=f"{param.title()} (rolling mean)",
|
|
240
|
+
linewidth=2,
|
|
241
|
+
)
|
|
242
|
+
ax_stats.set_xlabel("Time")
|
|
243
|
+
ax_stats.set_ylabel("Rolling Mean")
|
|
244
|
+
ax_stats.set_title(f"Rolling Statistics (window={window})")
|
|
245
|
+
ax_stats.legend()
|
|
246
|
+
ax_stats.grid(True, alpha=0.3)
|
|
247
|
+
|
|
248
|
+
# Scatter matrix sample
|
|
249
|
+
ax_scatter = axes[1, 2]
|
|
250
|
+
ax_scatter.scatter(
|
|
251
|
+
self.data["velocity"], self.data["temperature"], alpha=0.6, c="purple"
|
|
252
|
+
)
|
|
253
|
+
ax_scatter.set_xlabel("Velocity")
|
|
254
|
+
ax_scatter.set_ylabel("Temperature")
|
|
255
|
+
ax_scatter.set_title("V-T Scatter")
|
|
256
|
+
ax_scatter.grid(True, alpha=0.3)
|
|
257
|
+
|
|
258
|
+
# Summary statistics
|
|
259
|
+
ax_summary = axes[1, 3]
|
|
260
|
+
ax_summary.axis("off")
|
|
261
|
+
summary_text = []
|
|
262
|
+
for param in parameters:
|
|
263
|
+
data = self.data[param]
|
|
264
|
+
summary_text.append(f"{param.title()}:")
|
|
265
|
+
summary_text.append(f" Mean: {data.mean():.2f}")
|
|
266
|
+
summary_text.append(f" Std: {data.std():.2f}")
|
|
267
|
+
summary_text.append(f" Min: {data.min():.2f}")
|
|
268
|
+
summary_text.append(f" Max: {data.max():.2f}")
|
|
269
|
+
summary_text.append("")
|
|
270
|
+
|
|
271
|
+
ax_summary.text(
|
|
272
|
+
0.1,
|
|
273
|
+
0.9,
|
|
274
|
+
"\n".join(summary_text),
|
|
275
|
+
fontfamily="monospace",
|
|
276
|
+
fontsize=10,
|
|
277
|
+
verticalalignment="top",
|
|
278
|
+
transform=ax_summary.transAxes,
|
|
279
|
+
)
|
|
280
|
+
ax_summary.set_title("Summary Statistics")
|
|
281
|
+
|
|
282
|
+
plt.tight_layout()
|
|
283
|
+
|
|
284
|
+
# Validation
|
|
285
|
+
assert len(fig.axes) == 8
|
|
286
|
+
for i in range(4): # First row histograms
|
|
287
|
+
assert len(axes[0, i].patches) > 0 # Histogram bars
|
|
288
|
+
assert len(axes[0, i].lines) >= 1 # Normal fit line
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class TestLabelIntegrationWorkflow:
|
|
292
|
+
"""Test integration of plotting with label system."""
|
|
293
|
+
|
|
294
|
+
def teardown_method(self):
|
|
295
|
+
"""Clean up after each test."""
|
|
296
|
+
plt.close("all")
|
|
297
|
+
|
|
298
|
+
def test_chemistry_labels_integration(self):
|
|
299
|
+
"""Test integration of chemistry labels with plots."""
|
|
300
|
+
try:
|
|
301
|
+
from solarwindpy.plotting.labels.chemistry import (
|
|
302
|
+
mass_per_charge,
|
|
303
|
+
fip,
|
|
304
|
+
charge,
|
|
305
|
+
mass,
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
|
|
309
|
+
|
|
310
|
+
# Mock data for chemistry plots
|
|
311
|
+
np.random.seed(42)
|
|
312
|
+
species = ["H", "He", "C", "O", "Fe"]
|
|
313
|
+
|
|
314
|
+
# Mass-to-charge ratio plot
|
|
315
|
+
mq_ratios = [1.0, 2.0, 6.0, 8.0, 28.0] # Simplified M/Q ratios
|
|
316
|
+
counts = np.random.poisson(100, len(species))
|
|
317
|
+
|
|
318
|
+
bars = axes[0, 0].bar(species, counts, alpha=0.7, color="skyblue")
|
|
319
|
+
axes[0, 0].set_xlabel(str(mass_per_charge)) # Use chemistry label
|
|
320
|
+
axes[0, 0].set_ylabel("Counts")
|
|
321
|
+
axes[0, 0].set_title("Ion Mass-to-Charge Distribution")
|
|
322
|
+
|
|
323
|
+
# FIP plot
|
|
324
|
+
fip_values = [13.6, 24.6, 11.3, 13.6, 7.9] # eV
|
|
325
|
+
axes[0, 1].bar(species, fip_values, alpha=0.7, color="lightcoral")
|
|
326
|
+
axes[0, 1].set_xlabel("Ion Species")
|
|
327
|
+
axes[0, 1].set_ylabel(str(fip)) # Use chemistry label
|
|
328
|
+
axes[0, 1].set_title("First Ionization Potential")
|
|
329
|
+
|
|
330
|
+
# Charge state plot
|
|
331
|
+
charge_states = np.random.randint(1, 8, 20)
|
|
332
|
+
charge_counts = np.bincount(charge_states)[1:] # Remove 0 count
|
|
333
|
+
|
|
334
|
+
axes[1, 0].bar(
|
|
335
|
+
range(1, len(charge_counts) + 1),
|
|
336
|
+
charge_counts,
|
|
337
|
+
alpha=0.7,
|
|
338
|
+
color="lightgreen",
|
|
339
|
+
)
|
|
340
|
+
axes[1, 0].set_xlabel(str(charge)) # Use chemistry label
|
|
341
|
+
axes[1, 0].set_ylabel("Frequency")
|
|
342
|
+
axes[1, 0].set_title("Charge State Distribution")
|
|
343
|
+
|
|
344
|
+
# Mass spectrum
|
|
345
|
+
masses = [1, 4, 12, 16, 56] # AMU
|
|
346
|
+
intensities = np.random.exponential(50, len(masses))
|
|
347
|
+
|
|
348
|
+
axes[1, 1].stem(masses, intensities, basefmt=" ")
|
|
349
|
+
axes[1, 1].set_xlabel(str(mass)) # Use chemistry label
|
|
350
|
+
axes[1, 1].set_ylabel("Intensity")
|
|
351
|
+
axes[1, 1].set_title("Mass Spectrum")
|
|
352
|
+
|
|
353
|
+
plt.tight_layout()
|
|
354
|
+
|
|
355
|
+
# Validation
|
|
356
|
+
assert len(fig.axes) == 4
|
|
357
|
+
for ax in axes.flat:
|
|
358
|
+
assert ax.get_xlabel() != ""
|
|
359
|
+
assert ax.get_ylabel() != ""
|
|
360
|
+
|
|
361
|
+
except ImportError:
|
|
362
|
+
pytest.skip("Chemistry labels not available")
|
|
363
|
+
|
|
364
|
+
def test_datetime_labels_integration(self):
|
|
365
|
+
"""Test integration of datetime labels with time series plots."""
|
|
366
|
+
try:
|
|
367
|
+
from solarwindpy.plotting.labels.datetime import Timedelta, Frequency
|
|
368
|
+
|
|
369
|
+
fig, axes = plt.subplots(2, 1, figsize=(12, 8))
|
|
370
|
+
|
|
371
|
+
# Time series with time delta labels
|
|
372
|
+
time = np.arange(0, 24, 0.1) # 24 hours in 0.1 hour steps
|
|
373
|
+
signal = np.sin(2 * np.pi * time / 6) + 0.3 * np.sin(2 * np.pi * time / 1.5)
|
|
374
|
+
|
|
375
|
+
axes[0].plot(time, signal, "b-", linewidth=2)
|
|
376
|
+
|
|
377
|
+
# Use datetime labels
|
|
378
|
+
time_delta = Timedelta("1h")
|
|
379
|
+
axes[0].set_xlabel(f"Time [{time_delta.units}]")
|
|
380
|
+
axes[0].set_ylabel("Signal Amplitude")
|
|
381
|
+
axes[0].set_title("Time Series with Time Delta Labels")
|
|
382
|
+
axes[0].grid(True, alpha=0.3)
|
|
383
|
+
|
|
384
|
+
# Frequency domain plot
|
|
385
|
+
dt = time[1] - time[0]
|
|
386
|
+
freqs = np.fft.fftfreq(len(signal), dt)
|
|
387
|
+
fft_signal = np.abs(np.fft.fft(signal))
|
|
388
|
+
|
|
389
|
+
# Plot only positive frequencies
|
|
390
|
+
pos_freqs = freqs[: len(freqs) // 2]
|
|
391
|
+
pos_fft = fft_signal[: len(fft_signal) // 2]
|
|
392
|
+
|
|
393
|
+
axes[1].plot(pos_freqs, pos_fft, "r-", linewidth=2)
|
|
394
|
+
|
|
395
|
+
frequency_label = Frequency("1h")
|
|
396
|
+
axes[1].set_xlabel(str(frequency_label))
|
|
397
|
+
axes[1].set_ylabel("Amplitude")
|
|
398
|
+
axes[1].set_title("Frequency Domain")
|
|
399
|
+
axes[1].grid(True, alpha=0.3)
|
|
400
|
+
|
|
401
|
+
plt.tight_layout()
|
|
402
|
+
|
|
403
|
+
# Validation
|
|
404
|
+
assert len(fig.axes) == 2
|
|
405
|
+
for ax in axes:
|
|
406
|
+
assert len(ax.lines) == 1
|
|
407
|
+
assert ax.get_xlabel() != ""
|
|
408
|
+
|
|
409
|
+
except ImportError:
|
|
410
|
+
pytest.skip("DateTime labels not available")
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
class TestFileIOIntegration:
|
|
414
|
+
"""Test integration with file I/O operations."""
|
|
415
|
+
|
|
416
|
+
def teardown_method(self):
|
|
417
|
+
"""Clean up after each test."""
|
|
418
|
+
plt.close("all")
|
|
419
|
+
|
|
420
|
+
def test_plot_saving_workflow(self):
|
|
421
|
+
"""Test complete workflow of creating and saving plots."""
|
|
422
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
423
|
+
temp_path = Path(temp_dir)
|
|
424
|
+
|
|
425
|
+
# Create a multi-panel plot
|
|
426
|
+
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
|
|
427
|
+
|
|
428
|
+
# Generate different types of plots
|
|
429
|
+
x = np.linspace(0, 10, 100)
|
|
430
|
+
|
|
431
|
+
# Line plot
|
|
432
|
+
axes[0, 0].plot(x, np.sin(x), "b-", linewidth=2)
|
|
433
|
+
axes[0, 0].set_title("Line Plot")
|
|
434
|
+
axes[0, 0].grid(True)
|
|
435
|
+
|
|
436
|
+
# Scatter plot
|
|
437
|
+
np.random.seed(42)
|
|
438
|
+
axes[0, 1].scatter(np.random.randn(100), np.random.randn(100), alpha=0.6)
|
|
439
|
+
axes[0, 1].set_title("Scatter Plot")
|
|
440
|
+
axes[0, 1].grid(True)
|
|
441
|
+
|
|
442
|
+
# Histogram
|
|
443
|
+
axes[1, 0].hist(np.random.normal(0, 1, 1000), bins=30, alpha=0.7)
|
|
444
|
+
axes[1, 0].set_title("Histogram")
|
|
445
|
+
axes[1, 0].grid(True)
|
|
446
|
+
|
|
447
|
+
# Contour plot
|
|
448
|
+
X, Y = np.meshgrid(x, x)
|
|
449
|
+
Z = np.sin(X) * np.cos(Y)
|
|
450
|
+
contour = axes[1, 1].contourf(X, Y, Z, levels=20)
|
|
451
|
+
axes[1, 1].set_title("Contour Plot")
|
|
452
|
+
plt.colorbar(contour, ax=axes[1, 1])
|
|
453
|
+
|
|
454
|
+
plt.tight_layout()
|
|
455
|
+
|
|
456
|
+
# Save in multiple formats
|
|
457
|
+
formats = ["png", "pdf", "svg"]
|
|
458
|
+
saved_files = []
|
|
459
|
+
|
|
460
|
+
for fmt in formats:
|
|
461
|
+
file_path = temp_path / f"test_plot.{fmt}"
|
|
462
|
+
fig.savefig(file_path, format=fmt, dpi=100, bbox_inches="tight")
|
|
463
|
+
saved_files.append(file_path)
|
|
464
|
+
|
|
465
|
+
# Verify files were saved
|
|
466
|
+
for file_path in saved_files:
|
|
467
|
+
assert file_path.exists()
|
|
468
|
+
assert file_path.stat().st_size > 0
|
|
469
|
+
|
|
470
|
+
# Test file sizes are reasonable
|
|
471
|
+
png_size = saved_files[0].stat().st_size
|
|
472
|
+
assert png_size > 1000 # Should be at least 1KB for a real plot
|
|
473
|
+
|
|
474
|
+
def test_data_export_integration(self):
|
|
475
|
+
"""Test integration of plotting with data export."""
|
|
476
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
477
|
+
temp_path = Path(temp_dir)
|
|
478
|
+
|
|
479
|
+
# Create test data
|
|
480
|
+
dates = pd.date_range("2023-01-01", periods=50, freq="1h")
|
|
481
|
+
data = pd.DataFrame(
|
|
482
|
+
{
|
|
483
|
+
"time": dates,
|
|
484
|
+
"value1": np.random.randn(50).cumsum(),
|
|
485
|
+
"value2": np.random.randn(50).cumsum(),
|
|
486
|
+
"value3": np.random.randn(50).cumsum(),
|
|
487
|
+
}
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
# Create plot
|
|
491
|
+
fig, ax = plt.subplots(figsize=(12, 6))
|
|
492
|
+
|
|
493
|
+
for column in ["value1", "value2", "value3"]:
|
|
494
|
+
ax.plot(data["time"], data[column], label=column, linewidth=2)
|
|
495
|
+
|
|
496
|
+
ax.set_xlabel("Time")
|
|
497
|
+
ax.set_ylabel("Value")
|
|
498
|
+
ax.set_title("Multi-Series Time Plot")
|
|
499
|
+
ax.legend()
|
|
500
|
+
ax.grid(True, alpha=0.3)
|
|
501
|
+
|
|
502
|
+
plt.tight_layout()
|
|
503
|
+
|
|
504
|
+
# Save plot and data
|
|
505
|
+
plot_file = temp_path / "timeseries_plot.png"
|
|
506
|
+
data_file = temp_path / "timeseries_data.csv"
|
|
507
|
+
|
|
508
|
+
fig.savefig(plot_file, dpi=100, bbox_inches="tight")
|
|
509
|
+
data.to_csv(data_file, index=False)
|
|
510
|
+
|
|
511
|
+
# Verify both files exist
|
|
512
|
+
assert plot_file.exists()
|
|
513
|
+
assert data_file.exists()
|
|
514
|
+
|
|
515
|
+
# Verify data can be read back
|
|
516
|
+
loaded_data = pd.read_csv(data_file)
|
|
517
|
+
assert len(loaded_data) == len(data)
|
|
518
|
+
assert list(loaded_data.columns) == list(data.columns)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
class TestErrorHandlingIntegration:
|
|
522
|
+
"""Test error handling across integrated workflows."""
|
|
523
|
+
|
|
524
|
+
def teardown_method(self):
|
|
525
|
+
"""Clean up after each test."""
|
|
526
|
+
plt.close("all")
|
|
527
|
+
|
|
528
|
+
def test_missing_data_integration(self):
|
|
529
|
+
"""Test handling of missing data in integrated workflows."""
|
|
530
|
+
# Create data with missing values
|
|
531
|
+
dates = pd.date_range("2023-01-01", periods=100, freq="1h")
|
|
532
|
+
data = pd.DataFrame(
|
|
533
|
+
{
|
|
534
|
+
"param1": np.random.randn(100).cumsum(),
|
|
535
|
+
"param2": np.random.randn(100).cumsum(),
|
|
536
|
+
},
|
|
537
|
+
index=dates,
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
# Introduce missing values
|
|
541
|
+
data.loc[data.index[20:30], "param1"] = np.nan
|
|
542
|
+
data.loc[data.index[50:55], "param2"] = np.nan
|
|
543
|
+
|
|
544
|
+
fig, axes = plt.subplots(3, 1, figsize=(12, 10))
|
|
545
|
+
|
|
546
|
+
# Raw data plot with gaps
|
|
547
|
+
with warnings.catch_warnings():
|
|
548
|
+
warnings.simplefilter("ignore") # Suppress NaN warnings
|
|
549
|
+
|
|
550
|
+
axes[0].plot(data.index, data["param1"], "b-", label="param1")
|
|
551
|
+
axes[0].plot(data.index, data["param2"], "r-", label="param2")
|
|
552
|
+
axes[0].set_title("Raw Data with Missing Values")
|
|
553
|
+
axes[0].legend()
|
|
554
|
+
axes[0].grid(True, alpha=0.3)
|
|
555
|
+
|
|
556
|
+
# Interpolated data
|
|
557
|
+
data_interp = data.interpolate()
|
|
558
|
+
axes[1].plot(
|
|
559
|
+
data_interp.index, data_interp["param1"], "b-", label="param1 (interp)"
|
|
560
|
+
)
|
|
561
|
+
axes[1].plot(
|
|
562
|
+
data_interp.index, data_interp["param2"], "r-", label="param2 (interp)"
|
|
563
|
+
)
|
|
564
|
+
axes[1].set_title("Interpolated Data")
|
|
565
|
+
axes[1].legend()
|
|
566
|
+
axes[1].grid(True, alpha=0.3)
|
|
567
|
+
|
|
568
|
+
# Forward filled data
|
|
569
|
+
data_ffill = data.fillna(method="ffill")
|
|
570
|
+
axes[2].plot(
|
|
571
|
+
data_ffill.index, data_ffill["param1"], "b-", label="param1 (ffill)"
|
|
572
|
+
)
|
|
573
|
+
axes[2].plot(
|
|
574
|
+
data_ffill.index, data_ffill["param2"], "r-", label="param2 (ffill)"
|
|
575
|
+
)
|
|
576
|
+
axes[2].set_title("Forward Filled Data")
|
|
577
|
+
axes[2].set_xlabel("Time")
|
|
578
|
+
axes[2].legend()
|
|
579
|
+
axes[2].grid(True, alpha=0.3)
|
|
580
|
+
|
|
581
|
+
plt.tight_layout()
|
|
582
|
+
|
|
583
|
+
# Validation
|
|
584
|
+
assert len(fig.axes) == 3
|
|
585
|
+
for ax in axes:
|
|
586
|
+
assert len(ax.lines) == 2
|
|
587
|
+
|
|
588
|
+
def test_invalid_parameter_integration(self):
|
|
589
|
+
"""Test handling of invalid parameters in integrated workflows."""
|
|
590
|
+
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
|
|
591
|
+
|
|
592
|
+
# Test with various edge cases
|
|
593
|
+
x = np.linspace(0, 10, 100)
|
|
594
|
+
|
|
595
|
+
# Normal case
|
|
596
|
+
axes[0, 0].plot(x, np.sin(x), "b-")
|
|
597
|
+
axes[0, 0].set_title("Normal Case")
|
|
598
|
+
|
|
599
|
+
# Infinite values
|
|
600
|
+
y_inf = np.sin(x)
|
|
601
|
+
y_inf[50] = np.inf
|
|
602
|
+
y_inf[60] = -np.inf
|
|
603
|
+
|
|
604
|
+
with warnings.catch_warnings():
|
|
605
|
+
warnings.simplefilter("ignore")
|
|
606
|
+
axes[0, 1].plot(x, y_inf, "r-")
|
|
607
|
+
axes[0, 1].set_title("With Infinite Values")
|
|
608
|
+
|
|
609
|
+
# Very large/small values
|
|
610
|
+
y_extreme = 1e10 * np.sin(x) + 1e-10
|
|
611
|
+
axes[1, 0].plot(x, y_extreme, "g-")
|
|
612
|
+
axes[1, 0].set_title("Extreme Values")
|
|
613
|
+
axes[1, 0].ticklabel_format(style="scientific", axis="y", scilimits=(0, 0))
|
|
614
|
+
|
|
615
|
+
# Empty/single point arrays
|
|
616
|
+
x_empty = np.array([])
|
|
617
|
+
y_empty = np.array([])
|
|
618
|
+
x_single = np.array([5.0])
|
|
619
|
+
y_single = np.array([1.0])
|
|
620
|
+
|
|
621
|
+
axes[1, 1].plot(x_empty, y_empty, "k-", label="Empty")
|
|
622
|
+
axes[1, 1].scatter(x_single, y_single, color="red", s=50, label="Single Point")
|
|
623
|
+
axes[1, 1].set_title("Edge Cases")
|
|
624
|
+
axes[1, 1].legend()
|
|
625
|
+
|
|
626
|
+
plt.tight_layout()
|
|
627
|
+
|
|
628
|
+
# All should create without errors
|
|
629
|
+
assert len(fig.axes) == 4
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
def test_module_integration():
|
|
633
|
+
"""Test that all plotting modules can be imported and work together."""
|
|
634
|
+
# Test basic imports work
|
|
635
|
+
import solarwindpy.plotting.base
|
|
636
|
+
import solarwindpy.plotting.tools
|
|
637
|
+
import solarwindpy.plotting.histograms
|
|
638
|
+
import solarwindpy.plotting.labels
|
|
639
|
+
|
|
640
|
+
# Test that classes can be instantiated
|
|
641
|
+
assert hasattr(solarwindpy.plotting.labels, "base")
|
|
642
|
+
assert hasattr(solarwindpy.plotting.labels, "special")
|
|
643
|
+
|
|
644
|
+
# Test that basic functionality works
|
|
645
|
+
fig, ax = plt.subplots()
|
|
646
|
+
x = np.linspace(0, 1, 10)
|
|
647
|
+
y = x**2
|
|
648
|
+
ax.plot(x, y)
|
|
649
|
+
|
|
650
|
+
# Should not raise any errors
|
|
651
|
+
assert len(ax.lines) == 1
|
|
652
|
+
plt.close(fig)
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
def test_cross_platform_compatibility():
|
|
656
|
+
"""Test that plotting works consistently across platforms."""
|
|
657
|
+
# Test figure creation
|
|
658
|
+
fig, ax = plt.subplots(figsize=(8, 6))
|
|
659
|
+
|
|
660
|
+
# Test with various data types
|
|
661
|
+
x = np.linspace(0, 10, 100)
|
|
662
|
+
y1 = np.sin(x).astype(np.float32) # 32-bit float
|
|
663
|
+
y2 = np.cos(x).astype(np.float64) # 64-bit float
|
|
664
|
+
y3 = (x**2).astype(int) # Integer
|
|
665
|
+
|
|
666
|
+
ax.plot(x, y1, label="float32")
|
|
667
|
+
ax.plot(x, y2, label="float64")
|
|
668
|
+
ax.plot(x, y3, label="int")
|
|
669
|
+
|
|
670
|
+
ax.legend()
|
|
671
|
+
ax.grid(True)
|
|
672
|
+
|
|
673
|
+
# Should handle all data types
|
|
674
|
+
assert len(ax.lines) == 3
|
|
675
|
+
plt.close(fig)
|