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,943 @@
|
|
|
1
|
+
# Architecture Test Recommendations - SolarWindPy Enhancement
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
Based on the Architecture Compliance Analysis (Grade: B+), this document provides **actionable recommendations for 42 specific architecture tests** that will enhance DataFrame structure validation, memory efficiency, and performance benchmarking in the SolarWindPy test suite.
|
|
6
|
+
|
|
7
|
+
**Target Coverage Increase**: +5-6% (from 77.1% to 82-83%)
|
|
8
|
+
**Estimated Implementation**: 8-12 hours
|
|
9
|
+
**Priority**: High (foundational architecture validation)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. MultiIndex Structure Validation Tests (12 tests)
|
|
14
|
+
|
|
15
|
+
### 1.1 Core Structure Tests (4 tests)
|
|
16
|
+
|
|
17
|
+
**File**: `tests/core/test_multiindex_validation.py` (NEW)
|
|
18
|
+
|
|
19
|
+
#### Test 1: `test_multiindex_column_names_required`
|
|
20
|
+
```python
|
|
21
|
+
def test_multiindex_column_names_required():
|
|
22
|
+
"""Test that MultiIndex columns must have correct names."""
|
|
23
|
+
# Test with missing names
|
|
24
|
+
tuples = [("v", "x", "p1"), ("b", "y", "")]
|
|
25
|
+
bad_index = pd.MultiIndex.from_tuples(tuples) # No names
|
|
26
|
+
|
|
27
|
+
# Should warn or fail when creating DataFrame with unnamed levels
|
|
28
|
+
with pytest.warns(UserWarning, match="MultiIndex levels should be named"):
|
|
29
|
+
# Test DataFrame creation validation
|
|
30
|
+
pass
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
#### Test 2: `test_multiindex_level_order_validation`
|
|
34
|
+
```python
|
|
35
|
+
def test_multiindex_level_order_validation():
|
|
36
|
+
"""Test that MultiIndex levels must be in correct order."""
|
|
37
|
+
# Test incorrect level order (S, C, M instead of M, C, S)
|
|
38
|
+
tuples = [("p1", "x", "v"), ("", "y", "b")]
|
|
39
|
+
wrong_order = pd.MultiIndex.from_tuples(tuples, names=["S", "C", "M"])
|
|
40
|
+
|
|
41
|
+
# Should detect incorrect level ordering
|
|
42
|
+
with pytest.raises(ValueError, match="MultiIndex levels must be in order"):
|
|
43
|
+
# Test validation function
|
|
44
|
+
pass
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### Test 3: `test_multiindex_empty_component_scalar_validation`
|
|
48
|
+
```python
|
|
49
|
+
def test_multiindex_empty_component_scalar_validation():
|
|
50
|
+
"""Test proper handling of empty components for scalar measurements."""
|
|
51
|
+
# Density (scalar) should have empty component
|
|
52
|
+
density_tuples = [("n", "", "p1"), ("n", "", "p2")]
|
|
53
|
+
|
|
54
|
+
# Velocity (vector) should not have empty component
|
|
55
|
+
with pytest.raises(ValueError, match="Vector measurements require components"):
|
|
56
|
+
velocity_tuples = [("v", "", "p1")] # Invalid: missing component
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Test 4: `test_multiindex_empty_species_bfield_validation`
|
|
60
|
+
```python
|
|
61
|
+
def test_multiindex_empty_species_bfield_validation():
|
|
62
|
+
"""Test proper handling of empty species for magnetic field."""
|
|
63
|
+
# Magnetic field should have empty species
|
|
64
|
+
bfield_tuples = [("b", "x", ""), ("b", "y", ""), ("b", "z", "")]
|
|
65
|
+
|
|
66
|
+
# Ion measurements should not have empty species
|
|
67
|
+
with pytest.raises(ValueError, match="Ion measurements require species"):
|
|
68
|
+
ion_tuples = [("n", "", "")] # Invalid: missing species
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 1.2 Hierarchy Consistency Tests (4 tests)
|
|
72
|
+
|
|
73
|
+
#### Test 5: `test_measurement_component_consistency`
|
|
74
|
+
```python
|
|
75
|
+
def test_measurement_component_consistency():
|
|
76
|
+
"""Test M-C level consistency rules."""
|
|
77
|
+
# Scalar measurements (n, w scalar) must have empty C
|
|
78
|
+
# Vector measurements (v, b) must have x,y,z components
|
|
79
|
+
# Tensor measurements (w tensor) must have par,per components
|
|
80
|
+
|
|
81
|
+
valid_combinations = [
|
|
82
|
+
("n", "", "p1"), # Valid: scalar density
|
|
83
|
+
("v", "x", "p1"), # Valid: vector velocity
|
|
84
|
+
("w", "par", "p1"), # Valid: tensor thermal speed
|
|
85
|
+
("b", "z", ""), # Valid: vector magnetic field
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
invalid_combinations = [
|
|
89
|
+
("n", "x", "p1"), # Invalid: scalar with component
|
|
90
|
+
("v", "", "p1"), # Invalid: vector without component
|
|
91
|
+
("b", "par", ""), # Invalid: wrong component for B-field
|
|
92
|
+
]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Test 6: `test_species_measurement_consistency`
|
|
96
|
+
```python
|
|
97
|
+
def test_species_measurement_consistency():
|
|
98
|
+
"""Test M-S level consistency rules."""
|
|
99
|
+
# Magnetic field (b) must have empty species
|
|
100
|
+
# Ion measurements must have valid species
|
|
101
|
+
# Multi-species combinations validation
|
|
102
|
+
|
|
103
|
+
valid_species = ["p1", "p2", "a", "e"]
|
|
104
|
+
invalid_species = ["", "x", "invalid"]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Test 7: `test_multiindex_dataframe_creation_validation`
|
|
108
|
+
```python
|
|
109
|
+
def test_multiindex_dataframe_creation_validation():
|
|
110
|
+
"""Test DataFrame creation with various MultiIndex configurations."""
|
|
111
|
+
# Test successful creation with proper structure
|
|
112
|
+
# Test failure modes with invalid structures
|
|
113
|
+
# Test warning generation for questionable structures
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Test 8: `test_multiindex_level_access_patterns`
|
|
117
|
+
```python
|
|
118
|
+
def test_multiindex_level_access_patterns():
|
|
119
|
+
"""Test proper level access methods."""
|
|
120
|
+
# Test level="M" vs level=0 (should prefer level name)
|
|
121
|
+
# Test xs() vs iloc/loc patterns
|
|
122
|
+
# Test IndexSlice usage patterns
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 1.3 Integration Tests (4 tests)
|
|
126
|
+
|
|
127
|
+
#### Test 9: `test_plasma_multiindex_integration`
|
|
128
|
+
```python
|
|
129
|
+
def test_plasma_multiindex_integration():
|
|
130
|
+
"""Test Plasma class MultiIndex requirements."""
|
|
131
|
+
# Test Plasma object creation with various MultiIndex configurations
|
|
132
|
+
# Test validation of input DataFrames
|
|
133
|
+
# Test error handling for invalid structures
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### Test 10: `test_ion_multiindex_integration`
|
|
137
|
+
```python
|
|
138
|
+
def test_ion_multiindex_integration():
|
|
139
|
+
"""Test Ion class MultiIndex requirements."""
|
|
140
|
+
# Test Ion object creation with species-specific data
|
|
141
|
+
# Test validation of M-C level consistency for ions
|
|
142
|
+
# Test error handling for invalid ion data structures
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Test 11: `test_spacecraft_multiindex_integration`
|
|
146
|
+
```python
|
|
147
|
+
def test_spacecraft_multiindex_integration():
|
|
148
|
+
"""Test spacecraft data MultiIndex patterns."""
|
|
149
|
+
# Test coordinate system MultiIndex structures
|
|
150
|
+
# Test position/velocity MultiIndex validation
|
|
151
|
+
# Test spacecraft data integration with plasma data
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Test 12: `test_cross_module_multiindex_consistency`
|
|
155
|
+
```python
|
|
156
|
+
def test_cross_module_multiindex_consistency():
|
|
157
|
+
"""Test MultiIndex consistency across modules."""
|
|
158
|
+
# Test data exchange between Plasma, Ion, Spacecraft
|
|
159
|
+
# Test MultiIndex preservation during operations
|
|
160
|
+
# Test consistency validation across module boundaries
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 2. Memory Efficiency Tests (10 tests)
|
|
166
|
+
|
|
167
|
+
### 2.1 View vs Copy Tests (4 tests)
|
|
168
|
+
|
|
169
|
+
**File**: `tests/core/test_dataframe_memory.py` (NEW)
|
|
170
|
+
|
|
171
|
+
#### Test 13: `test_xs_returns_view_not_copy`
|
|
172
|
+
```python
|
|
173
|
+
def test_xs_returns_view_not_copy():
|
|
174
|
+
"""Test that xs() operations return views, not copies."""
|
|
175
|
+
data = create_test_plasma_data()
|
|
176
|
+
|
|
177
|
+
# Test that xs() returns view
|
|
178
|
+
view = data.xs("v", level="M")
|
|
179
|
+
original_value = data.iloc[0, 0]
|
|
180
|
+
|
|
181
|
+
# Modify view
|
|
182
|
+
view.iloc[0, 0] = original_value + 1000
|
|
183
|
+
|
|
184
|
+
# Original should be modified (proving it's a view)
|
|
185
|
+
assert data.iloc[0, 0] == original_value + 1000
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Test 14: `test_memory_usage_comparison_view_vs_copy`
|
|
189
|
+
```python
|
|
190
|
+
def test_memory_usage_comparison_view_vs_copy():
|
|
191
|
+
"""Compare memory usage of view vs copy operations."""
|
|
192
|
+
large_data = create_large_test_data(n_points=50000)
|
|
193
|
+
|
|
194
|
+
# Measure view memory
|
|
195
|
+
view = large_data.xs("v", level="M")
|
|
196
|
+
view_memory = view.memory_usage(deep=True).sum()
|
|
197
|
+
|
|
198
|
+
# Measure copy memory
|
|
199
|
+
copy = large_data.xs("v", level="M").copy()
|
|
200
|
+
copy_memory = copy.memory_usage(deep=True).sum()
|
|
201
|
+
|
|
202
|
+
# View should use significantly less memory
|
|
203
|
+
assert view_memory < copy_memory * 0.1 # View should be <10% of copy
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### Test 15: `test_chained_xs_operations_memory`
|
|
207
|
+
```python
|
|
208
|
+
def test_chained_xs_operations_memory():
|
|
209
|
+
"""Test memory efficiency of chained xs() operations."""
|
|
210
|
+
data = create_test_plasma_data()
|
|
211
|
+
|
|
212
|
+
# Single operation
|
|
213
|
+
single_op = data.xs("v", level="M").xs("p1", level="S")
|
|
214
|
+
|
|
215
|
+
# Chained operations should not create intermediate copies
|
|
216
|
+
memory_before = get_process_memory()
|
|
217
|
+
result = data.xs("v", level="M").xs("p1", level="S")
|
|
218
|
+
memory_after = get_process_memory()
|
|
219
|
+
|
|
220
|
+
memory_increase = memory_after - memory_before
|
|
221
|
+
assert memory_increase < 1.0 # Less than 1MB increase
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### Test 16: `test_dataframe_slice_memory_efficiency`
|
|
225
|
+
```python
|
|
226
|
+
def test_dataframe_slice_memory_efficiency():
|
|
227
|
+
"""Test memory efficiency of different slicing methods."""
|
|
228
|
+
data = create_test_plasma_data()
|
|
229
|
+
|
|
230
|
+
# Compare memory usage of different access patterns
|
|
231
|
+
patterns = [
|
|
232
|
+
lambda df: df.xs("v", level="M"),
|
|
233
|
+
lambda df: df.loc[:, pd.IndexSlice["v", :, :]],
|
|
234
|
+
lambda df: df[df.columns[df.columns.get_level_values("M") == "v"]],
|
|
235
|
+
]
|
|
236
|
+
|
|
237
|
+
# Test that xs() is most memory efficient
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 2.2 Large Dataset Tests (3 tests)
|
|
241
|
+
|
|
242
|
+
#### Test 17: `test_large_multiindex_dataframe_memory`
|
|
243
|
+
```python
|
|
244
|
+
def test_large_multiindex_dataframe_memory():
|
|
245
|
+
"""Test memory usage with large MultiIndex DataFrames."""
|
|
246
|
+
sizes = [1000, 10000, 100000]
|
|
247
|
+
memory_usages = []
|
|
248
|
+
|
|
249
|
+
for size in sizes:
|
|
250
|
+
data = create_test_data(n_points=size)
|
|
251
|
+
memory = data.memory_usage(deep=True).sum()
|
|
252
|
+
memory_usages.append(memory)
|
|
253
|
+
|
|
254
|
+
# Memory should scale linearly with data size
|
|
255
|
+
assert_linear_scaling(sizes, memory_usages, tolerance=0.2)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Test 18: `test_memory_usage_by_data_type`
|
|
259
|
+
```python
|
|
260
|
+
def test_memory_usage_by_data_type():
|
|
261
|
+
"""Test memory usage with different data types."""
|
|
262
|
+
dtypes = [np.float32, np.float64, np.int32, np.int64]
|
|
263
|
+
|
|
264
|
+
for dtype in dtypes:
|
|
265
|
+
data = create_test_data(dtype=dtype)
|
|
266
|
+
memory = data.memory_usage(deep=True).sum()
|
|
267
|
+
|
|
268
|
+
# Verify expected memory usage based on dtype
|
|
269
|
+
expected_memory = calculate_expected_memory(data.shape, dtype)
|
|
270
|
+
assert abs(memory - expected_memory) / expected_memory < 0.1
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### Test 19: `test_memory_cleanup_after_operations`
|
|
274
|
+
```python
|
|
275
|
+
def test_memory_cleanup_after_operations():
|
|
276
|
+
"""Test that temporary DataFrames are properly cleaned up."""
|
|
277
|
+
initial_memory = get_process_memory()
|
|
278
|
+
|
|
279
|
+
# Perform operations that create temporary objects
|
|
280
|
+
for i in range(100):
|
|
281
|
+
data = create_test_data()
|
|
282
|
+
result = data.xs("v", level="M").xs("p1", level="S")
|
|
283
|
+
processed = result.groupby(level=0).mean()
|
|
284
|
+
del data, result, processed
|
|
285
|
+
|
|
286
|
+
gc.collect()
|
|
287
|
+
final_memory = get_process_memory()
|
|
288
|
+
|
|
289
|
+
# Memory should return close to initial level
|
|
290
|
+
memory_increase = final_memory - initial_memory
|
|
291
|
+
assert memory_increase < 10.0 # Less than 10MB permanent increase
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 2.3 Memory Profiling Tests (3 tests)
|
|
295
|
+
|
|
296
|
+
#### Test 20: `test_multiindex_operation_memory_profile`
|
|
297
|
+
```python
|
|
298
|
+
@memory_profiler.profile
|
|
299
|
+
def test_multiindex_operation_memory_profile():
|
|
300
|
+
"""Profile memory usage of common MultiIndex operations."""
|
|
301
|
+
data = create_large_test_data()
|
|
302
|
+
|
|
303
|
+
# Profile common operations
|
|
304
|
+
operations = [
|
|
305
|
+
lambda: data.xs("v", level="M"),
|
|
306
|
+
lambda: data.loc[:, pd.IndexSlice["v", :, "p1"]],
|
|
307
|
+
lambda: data.groupby(level=["M", "S"]).mean(),
|
|
308
|
+
lambda: data.reindex(columns=data.columns.sort_values()),
|
|
309
|
+
]
|
|
310
|
+
|
|
311
|
+
for op in operations:
|
|
312
|
+
memory_before = get_process_memory()
|
|
313
|
+
result = op()
|
|
314
|
+
memory_after = get_process_memory()
|
|
315
|
+
|
|
316
|
+
# Log memory usage for each operation
|
|
317
|
+
memory_delta = memory_after - memory_before
|
|
318
|
+
assert memory_delta < 100.0 # Reasonable memory usage
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### Test 21: `test_memory_leak_detection`
|
|
322
|
+
```python
|
|
323
|
+
def test_memory_leak_detection():
|
|
324
|
+
"""Test for memory leaks in DataFrame operations."""
|
|
325
|
+
baseline_memory = get_process_memory()
|
|
326
|
+
|
|
327
|
+
# Repeat operations many times
|
|
328
|
+
for iteration in range(1000):
|
|
329
|
+
data = create_test_data()
|
|
330
|
+
|
|
331
|
+
# Perform various operations
|
|
332
|
+
v_data = data.xs("v", level="M")
|
|
333
|
+
species_data = v_data.xs("p1", level="S")
|
|
334
|
+
stats = species_data.describe()
|
|
335
|
+
|
|
336
|
+
# Clean up explicitly
|
|
337
|
+
del data, v_data, species_data, stats
|
|
338
|
+
|
|
339
|
+
# Check memory every 100 iterations
|
|
340
|
+
if iteration % 100 == 0:
|
|
341
|
+
gc.collect()
|
|
342
|
+
current_memory = get_process_memory()
|
|
343
|
+
memory_growth = current_memory - baseline_memory
|
|
344
|
+
|
|
345
|
+
# Should not have significant memory growth
|
|
346
|
+
assert memory_growth < 50.0 # Less than 50MB growth
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### Test 22: `test_dataframe_copy_detection`
|
|
350
|
+
```python
|
|
351
|
+
def test_dataframe_copy_detection():
|
|
352
|
+
"""Test detection of unexpected DataFrame copies."""
|
|
353
|
+
data = create_test_data()
|
|
354
|
+
original_id = id(data._mgr) # Access internal data manager
|
|
355
|
+
|
|
356
|
+
# Operations that should return views
|
|
357
|
+
view_ops = [
|
|
358
|
+
lambda: data.xs("v", level="M"),
|
|
359
|
+
lambda: data.loc[:10],
|
|
360
|
+
lambda: data.iloc[:10],
|
|
361
|
+
]
|
|
362
|
+
|
|
363
|
+
for op in view_ops:
|
|
364
|
+
result = op()
|
|
365
|
+
# Verify result shares data with original (implementation dependent)
|
|
366
|
+
# This test helps identify when operations unexpectedly create copies
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 3. Performance Benchmark Tests (8 tests)
|
|
372
|
+
|
|
373
|
+
### 3.1 Access Pattern Benchmarks (3 tests)
|
|
374
|
+
|
|
375
|
+
**File**: `tests/core/test_dataframe_performance.py` (NEW)
|
|
376
|
+
|
|
377
|
+
#### Test 23: `test_multiindex_access_performance`
|
|
378
|
+
```python
|
|
379
|
+
def test_multiindex_access_performance():
|
|
380
|
+
"""Benchmark different MultiIndex access patterns."""
|
|
381
|
+
data = create_large_test_data(n_points=100000)
|
|
382
|
+
|
|
383
|
+
# Test access methods
|
|
384
|
+
access_methods = {
|
|
385
|
+
'xs_method': lambda: data.xs("v", level="M"),
|
|
386
|
+
'loc_indexslice': lambda: data.loc[:, pd.IndexSlice["v", :, :]],
|
|
387
|
+
'boolean_mask': lambda: data[data.columns.get_level_values("M") == "v"],
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
# Benchmark each method
|
|
391
|
+
results = {}
|
|
392
|
+
for name, method in access_methods.items():
|
|
393
|
+
times = []
|
|
394
|
+
for _ in range(10):
|
|
395
|
+
start = time.time()
|
|
396
|
+
result = method()
|
|
397
|
+
end = time.time()
|
|
398
|
+
times.append(end - start)
|
|
399
|
+
|
|
400
|
+
results[name] = np.mean(times)
|
|
401
|
+
|
|
402
|
+
# xs() should be fastest
|
|
403
|
+
assert results['xs_method'] < results['boolean_mask']
|
|
404
|
+
assert results['xs_method'] < results['loc_indexslice']
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### Test 24: `test_hierarchical_groupby_performance`
|
|
408
|
+
```python
|
|
409
|
+
def test_hierarchical_groupby_performance():
|
|
410
|
+
"""Test performance of groupby operations on MultiIndex."""
|
|
411
|
+
data = create_large_test_data(n_points=100000)
|
|
412
|
+
|
|
413
|
+
groupby_operations = [
|
|
414
|
+
lambda: data.groupby(level="M").mean(),
|
|
415
|
+
lambda: data.groupby(level=["M", "S"]).mean(),
|
|
416
|
+
lambda: data.groupby(level=["M", "C", "S"]).mean(),
|
|
417
|
+
]
|
|
418
|
+
|
|
419
|
+
# Test that performance scales reasonably with groupby complexity
|
|
420
|
+
for i, op in enumerate(groupby_operations):
|
|
421
|
+
start = time.time()
|
|
422
|
+
result = op()
|
|
423
|
+
duration = time.time() - start
|
|
424
|
+
|
|
425
|
+
# More complex groupbys should take longer but reasonably so
|
|
426
|
+
assert duration < 10.0 # Should complete within 10 seconds
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### Test 25: `test_multiindex_sorting_performance`
|
|
430
|
+
```python
|
|
431
|
+
def test_multiindex_sorting_performance():
|
|
432
|
+
"""Test performance of MultiIndex sorting operations."""
|
|
433
|
+
# Create unsorted data
|
|
434
|
+
data = create_test_data(sorted=False)
|
|
435
|
+
|
|
436
|
+
sorting_operations = [
|
|
437
|
+
lambda: data.sort_index(axis=1),
|
|
438
|
+
lambda: data.sort_index(axis=1, level="M"),
|
|
439
|
+
lambda: data.sort_index(axis=1, level=["M", "C", "S"]),
|
|
440
|
+
]
|
|
441
|
+
|
|
442
|
+
# Test sorting performance
|
|
443
|
+
for op in sorting_operations:
|
|
444
|
+
start = time.time()
|
|
445
|
+
result = op()
|
|
446
|
+
duration = time.time() - start
|
|
447
|
+
|
|
448
|
+
assert duration < 5.0 # Should complete within 5 seconds
|
|
449
|
+
assert result.columns.is_monotonic_increasing
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### 3.2 Scalability Tests (3 tests)
|
|
453
|
+
|
|
454
|
+
#### Test 26: `test_dataframe_size_scalability`
|
|
455
|
+
```python
|
|
456
|
+
def test_dataframe_size_scalability():
|
|
457
|
+
"""Test DataFrame operation performance at different scales."""
|
|
458
|
+
sizes = [1000, 10000, 100000]
|
|
459
|
+
operation_times = []
|
|
460
|
+
|
|
461
|
+
for size in sizes:
|
|
462
|
+
data = create_test_data(n_points=size)
|
|
463
|
+
|
|
464
|
+
start = time.time()
|
|
465
|
+
# Standard operations
|
|
466
|
+
v_data = data.xs("v", level="M")
|
|
467
|
+
p1_data = v_data.xs("p1", level="S")
|
|
468
|
+
stats = p1_data.describe()
|
|
469
|
+
end = time.time()
|
|
470
|
+
|
|
471
|
+
operation_times.append(end - start)
|
|
472
|
+
|
|
473
|
+
# Performance should scale sub-quadratically
|
|
474
|
+
assert_subquadratic_scaling(sizes, operation_times)
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### Test 27: `test_multiindex_column_count_scalability`
|
|
478
|
+
```python
|
|
479
|
+
def test_multiindex_column_count_scalability():
|
|
480
|
+
"""Test performance with increasing column counts."""
|
|
481
|
+
column_counts = [10, 50, 100, 500]
|
|
482
|
+
access_times = []
|
|
483
|
+
|
|
484
|
+
for count in column_counts:
|
|
485
|
+
data = create_test_data(n_columns=count)
|
|
486
|
+
|
|
487
|
+
start = time.time()
|
|
488
|
+
result = data.xs("v", level="M")
|
|
489
|
+
duration = time.time() - start
|
|
490
|
+
|
|
491
|
+
access_times.append(duration)
|
|
492
|
+
|
|
493
|
+
# Access time should scale linearly with column count
|
|
494
|
+
assert_linear_scaling(column_counts, access_times, tolerance=0.3)
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
#### Test 28: `test_datetime_index_scalability`
|
|
498
|
+
```python
|
|
499
|
+
def test_datetime_index_scalability():
|
|
500
|
+
"""Test performance with large datetime indices."""
|
|
501
|
+
durations = ['1D', '7D', '30D', '365D'] # Data spanning different periods
|
|
502
|
+
|
|
503
|
+
for duration in durations:
|
|
504
|
+
data = create_time_series_data(duration=duration, freq='1min')
|
|
505
|
+
|
|
506
|
+
start = time.time()
|
|
507
|
+
# Common time series operations
|
|
508
|
+
hourly = data.resample('1H').mean()
|
|
509
|
+
daily = data.resample('1D').mean()
|
|
510
|
+
end = time.time()
|
|
511
|
+
|
|
512
|
+
operation_time = end - start
|
|
513
|
+
assert operation_time < 30.0 # Should complete within 30 seconds
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### 3.3 Regression Tests (2 tests)
|
|
517
|
+
|
|
518
|
+
#### Test 29: `test_performance_regression_baseline`
|
|
519
|
+
```python
|
|
520
|
+
def test_performance_regression_baseline():
|
|
521
|
+
"""Establish performance baselines for regression testing."""
|
|
522
|
+
# Standard test data
|
|
523
|
+
data = create_standard_test_data()
|
|
524
|
+
|
|
525
|
+
# Baseline operations with expected completion times
|
|
526
|
+
baselines = {
|
|
527
|
+
'xs_access': (lambda: data.xs("v", level="M"), 0.01), # 10ms
|
|
528
|
+
'species_select': (lambda: data.xs("p1", level="S"), 0.01), # 10ms
|
|
529
|
+
'component_select': (lambda: data.xs("x", level="C"), 0.01), # 10ms
|
|
530
|
+
'groupby_mean': (lambda: data.groupby(level="M").mean(), 0.1), # 100ms
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
for name, (operation, max_time) in baselines.items():
|
|
534
|
+
times = []
|
|
535
|
+
for _ in range(5):
|
|
536
|
+
start = time.time()
|
|
537
|
+
result = operation()
|
|
538
|
+
end = time.time()
|
|
539
|
+
times.append(end - start)
|
|
540
|
+
|
|
541
|
+
avg_time = np.mean(times)
|
|
542
|
+
assert avg_time < max_time, f"{name} took {avg_time:.3f}s, expected <{max_time}s"
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
#### Test 30: `test_memory_usage_regression_baseline`
|
|
546
|
+
```python
|
|
547
|
+
def test_memory_usage_regression_baseline():
|
|
548
|
+
"""Establish memory usage baselines for regression testing."""
|
|
549
|
+
# Standard operations with expected memory usage
|
|
550
|
+
data = create_standard_test_data()
|
|
551
|
+
|
|
552
|
+
memory_baselines = {
|
|
553
|
+
'full_dataframe': (lambda: data, 10.0), # 10MB
|
|
554
|
+
'velocity_data': (lambda: data.xs("v", level="M"), 2.0), # 2MB
|
|
555
|
+
'single_species': (lambda: data.xs("p1", level="S"), 5.0), # 5MB
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
for name, (operation, max_mb) in memory_baselines.items():
|
|
559
|
+
result = operation()
|
|
560
|
+
memory_mb = result.memory_usage(deep=True).sum() / 1024**2
|
|
561
|
+
|
|
562
|
+
assert memory_mb < max_mb, f"{name} used {memory_mb:.1f}MB, expected <{max_mb}MB"
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## 4. Edge Case & Integration Tests (7 tests)
|
|
568
|
+
|
|
569
|
+
### 4.1 Index Consistency Tests (3 tests)
|
|
570
|
+
|
|
571
|
+
**File**: `tests/core/test_dataframe_edge_cases.py` (NEW)
|
|
572
|
+
|
|
573
|
+
#### Test 31: `test_datetime_index_validation`
|
|
574
|
+
```python
|
|
575
|
+
def test_datetime_index_validation():
|
|
576
|
+
"""Test DateTime index validation and naming."""
|
|
577
|
+
# Test proper datetime index
|
|
578
|
+
good_index = pd.date_range('2020-01-01', periods=100, freq='1min')
|
|
579
|
+
good_index.name = 'Epoch'
|
|
580
|
+
data = create_test_data(index=good_index)
|
|
581
|
+
|
|
582
|
+
# Test invalid indices
|
|
583
|
+
bad_indices = [
|
|
584
|
+
pd.RangeIndex(100), # Non-datetime
|
|
585
|
+
pd.date_range('2020-01-01', periods=100)[::-1], # Non-monotonic
|
|
586
|
+
pd.date_range('2020-01-01', periods=100, name='time'), # Wrong name
|
|
587
|
+
]
|
|
588
|
+
|
|
589
|
+
for bad_index in bad_indices:
|
|
590
|
+
with pytest.warns(UserWarning):
|
|
591
|
+
invalid_data = create_test_data(index=bad_index)
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
#### Test 32: `test_multiindex_duplicate_handling`
|
|
595
|
+
```python
|
|
596
|
+
def test_multiindex_duplicate_handling():
|
|
597
|
+
"""Test handling of duplicate MultiIndex columns."""
|
|
598
|
+
# Create data with duplicate columns
|
|
599
|
+
tuples = [("v", "x", "p1"), ("v", "x", "p1"), ("b", "y", "")]
|
|
600
|
+
duplicate_columns = pd.MultiIndex.from_tuples(tuples, names=["M", "C", "S"])
|
|
601
|
+
|
|
602
|
+
# Test detection and handling of duplicates
|
|
603
|
+
with pytest.raises(ValueError, match="Duplicate columns detected"):
|
|
604
|
+
data = pd.DataFrame(np.random.randn(100, 3), columns=duplicate_columns)
|
|
605
|
+
validate_multiindex_structure(data)
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
#### Test 33: `test_missing_level_handling`
|
|
609
|
+
```python
|
|
610
|
+
def test_missing_level_handling():
|
|
611
|
+
"""Test handling of missing MultiIndex levels."""
|
|
612
|
+
# Test missing M level
|
|
613
|
+
tuples = [("", "x", "p1"), ("", "y", "p1")]
|
|
614
|
+
missing_m = pd.MultiIndex.from_tuples(tuples, names=["M", "C", "S"])
|
|
615
|
+
|
|
616
|
+
# Test missing C level
|
|
617
|
+
tuples = [("v", "", "p1"), ("v", "", "p2")]
|
|
618
|
+
missing_c = pd.MultiIndex.from_tuples(tuples, names=["M", "C", "S"])
|
|
619
|
+
|
|
620
|
+
# Test validation of missing required levels
|
|
621
|
+
for invalid_index in [missing_m, missing_c]:
|
|
622
|
+
with pytest.raises(ValueError, match="Required level values missing"):
|
|
623
|
+
validate_multiindex_structure(pd.DataFrame(columns=invalid_index))
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### 4.2 Data Type Edge Cases (2 tests)
|
|
627
|
+
|
|
628
|
+
#### Test 34: `test_mixed_data_types_multiindex`
|
|
629
|
+
```python
|
|
630
|
+
def test_mixed_data_types_multiindex():
|
|
631
|
+
"""Test MultiIndex with mixed data types."""
|
|
632
|
+
# Create DataFrame with mixed types
|
|
633
|
+
data = pd.DataFrame({
|
|
634
|
+
('n', '', 'p1'): np.random.randn(100).astype(np.float32),
|
|
635
|
+
('v', 'x', 'p1'): np.random.randn(100).astype(np.float64),
|
|
636
|
+
('w', 'par', 'p1'): np.random.randn(100).astype(np.int32),
|
|
637
|
+
})
|
|
638
|
+
data.columns = pd.MultiIndex.from_tuples(data.columns, names=["M", "C", "S"])
|
|
639
|
+
|
|
640
|
+
# Test that operations work correctly with mixed types
|
|
641
|
+
result = data.xs("p1", level="S")
|
|
642
|
+
assert isinstance(result, pd.DataFrame)
|
|
643
|
+
|
|
644
|
+
# Test type preservation
|
|
645
|
+
assert data[('n', '', 'p1')].dtype == np.float32
|
|
646
|
+
assert data[('v', 'x', 'p1')].dtype == np.float64
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
#### Test 35: `test_nan_handling_multiindex_operations`
|
|
650
|
+
```python
|
|
651
|
+
def test_nan_handling_multiindex_operations():
|
|
652
|
+
"""Test NaN handling in MultiIndex operations."""
|
|
653
|
+
data = create_test_data()
|
|
654
|
+
|
|
655
|
+
# Introduce NaN values
|
|
656
|
+
data.iloc[10:20, :] = np.nan
|
|
657
|
+
data.iloc[:, 2] = np.nan # Entire column
|
|
658
|
+
|
|
659
|
+
# Test that MultiIndex operations handle NaN correctly
|
|
660
|
+
v_data = data.xs("v", level="M")
|
|
661
|
+
assert v_data.isna().any().any() # Should contain NaN
|
|
662
|
+
|
|
663
|
+
# Test statistics with NaN
|
|
664
|
+
stats = v_data.describe()
|
|
665
|
+
assert not stats.isna().all().any() # Should compute valid statistics
|
|
666
|
+
|
|
667
|
+
# Test groupby with NaN
|
|
668
|
+
grouped = data.groupby(level="M").mean()
|
|
669
|
+
assert isinstance(grouped, pd.DataFrame)
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
### 4.3 Integration Edge Cases (2 tests)
|
|
673
|
+
|
|
674
|
+
#### Test 36: `test_cross_module_dataframe_compatibility`
|
|
675
|
+
```python
|
|
676
|
+
def test_cross_module_dataframe_compatibility():
|
|
677
|
+
"""Test DataFrame compatibility across modules."""
|
|
678
|
+
# Create data in plasma format
|
|
679
|
+
plasma_data = create_test_plasma_data()
|
|
680
|
+
|
|
681
|
+
# Test Ion object creation
|
|
682
|
+
ion_data = plasma_data.xs("p1", level="S")
|
|
683
|
+
ion = ions.Ion(ion_data, "p1")
|
|
684
|
+
assert isinstance(ion, ions.Ion)
|
|
685
|
+
|
|
686
|
+
# Test Spacecraft data integration
|
|
687
|
+
sc_data = create_test_spacecraft_data()
|
|
688
|
+
combined = pd.concat([plasma_data, sc_data], axis=1)
|
|
689
|
+
|
|
690
|
+
# Test that combined data maintains MultiIndex structure
|
|
691
|
+
assert combined.columns.nlevels == 3
|
|
692
|
+
assert list(combined.columns.names) == ["M", "C", "S"]
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
#### Test 37: `test_large_dataset_edge_cases`
|
|
696
|
+
```python
|
|
697
|
+
def test_large_dataset_edge_cases():
|
|
698
|
+
"""Test edge cases with large datasets."""
|
|
699
|
+
# Create very large dataset
|
|
700
|
+
large_data = create_test_data(n_points=1000000) # 1M points
|
|
701
|
+
|
|
702
|
+
# Test memory-efficient operations
|
|
703
|
+
subset = large_data.iloc[::1000] # Sample every 1000th point
|
|
704
|
+
v_subset = subset.xs("v", level="M")
|
|
705
|
+
|
|
706
|
+
# Test that operations complete without memory errors
|
|
707
|
+
stats = v_subset.describe()
|
|
708
|
+
assert isinstance(stats, pd.DataFrame)
|
|
709
|
+
|
|
710
|
+
# Test chunked operations
|
|
711
|
+
chunk_size = 10000
|
|
712
|
+
chunk_stats = []
|
|
713
|
+
for i in range(0, len(large_data), chunk_size):
|
|
714
|
+
chunk = large_data.iloc[i:i+chunk_size]
|
|
715
|
+
chunk_stat = chunk.xs("v", level="M").mean()
|
|
716
|
+
chunk_stats.append(chunk_stat)
|
|
717
|
+
|
|
718
|
+
# Verify chunked processing works
|
|
719
|
+
assert len(chunk_stats) > 1
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
## 5. Specialized Architecture Tests (5 tests)
|
|
725
|
+
|
|
726
|
+
### 5.1 IndexSlice Pattern Tests (2 tests)
|
|
727
|
+
|
|
728
|
+
**File**: `tests/core/test_indexslice_patterns.py` (NEW)
|
|
729
|
+
|
|
730
|
+
#### Test 38: `test_indexslice_multiindex_selection`
|
|
731
|
+
```python
|
|
732
|
+
def test_indexslice_multiindex_selection():
|
|
733
|
+
"""Test IndexSlice patterns for MultiIndex selection."""
|
|
734
|
+
data = create_test_data()
|
|
735
|
+
|
|
736
|
+
# Test various IndexSlice patterns
|
|
737
|
+
patterns = [
|
|
738
|
+
pd.IndexSlice["v", :, :], # All velocity data
|
|
739
|
+
pd.IndexSlice["v", "x", :], # All x-components of velocity
|
|
740
|
+
pd.IndexSlice["v", :, "p1"], # All velocity components for p1
|
|
741
|
+
pd.IndexSlice[["v", "b"], :, :], # Velocity and magnetic field
|
|
742
|
+
pd.IndexSlice[:, ["x", "y"], :], # x and y components only
|
|
743
|
+
]
|
|
744
|
+
|
|
745
|
+
for pattern in patterns:
|
|
746
|
+
result = data.loc[:, pattern]
|
|
747
|
+
assert isinstance(result, pd.DataFrame)
|
|
748
|
+
|
|
749
|
+
# Verify selection worked correctly
|
|
750
|
+
if pattern == pd.IndexSlice["v", :, :]:
|
|
751
|
+
assert all(result.columns.get_level_values("M") == "v")
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
#### Test 39: `test_complex_indexslice_combinations`
|
|
755
|
+
```python
|
|
756
|
+
def test_complex_indexslice_combinations():
|
|
757
|
+
"""Test complex IndexSlice combinations."""
|
|
758
|
+
data = create_test_data()
|
|
759
|
+
|
|
760
|
+
# Complex selection patterns
|
|
761
|
+
complex_patterns = [
|
|
762
|
+
# Velocity x,y components for protons
|
|
763
|
+
(pd.IndexSlice["v", ["x", "y"], ["p1", "p2"]],
|
|
764
|
+
lambda df: (df.columns.get_level_values("M") == "v") &
|
|
765
|
+
df.columns.get_level_values("C").isin(["x", "y"]) &
|
|
766
|
+
df.columns.get_level_values("S").isin(["p1", "p2"])),
|
|
767
|
+
|
|
768
|
+
# All vector components (exclude scalars)
|
|
769
|
+
(pd.IndexSlice[:, ["x", "y", "z"], :],
|
|
770
|
+
lambda df: df.columns.get_level_values("C").isin(["x", "y", "z"])),
|
|
771
|
+
]
|
|
772
|
+
|
|
773
|
+
for pattern, validator in complex_patterns:
|
|
774
|
+
result = data.loc[:, pattern]
|
|
775
|
+
expected_mask = validator(data)
|
|
776
|
+
expected = data.loc[:, expected_mask]
|
|
777
|
+
|
|
778
|
+
pd.testing.assert_frame_equal(result.sort_index(axis=1),
|
|
779
|
+
expected.sort_index(axis=1))
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### 5.2 Performance Optimization Tests (3 tests)
|
|
783
|
+
|
|
784
|
+
#### Test 40: `test_multiindex_operation_optimization`
|
|
785
|
+
```python
|
|
786
|
+
def test_multiindex_operation_optimization():
|
|
787
|
+
"""Test optimization of common MultiIndex operations."""
|
|
788
|
+
data = create_large_test_data()
|
|
789
|
+
|
|
790
|
+
# Compare optimized vs unoptimized approaches
|
|
791
|
+
approaches = {
|
|
792
|
+
'optimized_xs': lambda: data.xs("v", level="M").xs("p1", level="S"),
|
|
793
|
+
'chained_loc': lambda: data.loc[:, pd.IndexSlice["v", :, "p1"]],
|
|
794
|
+
'boolean_filter': lambda: data[
|
|
795
|
+
(data.columns.get_level_values("M") == "v") &
|
|
796
|
+
(data.columns.get_level_values("S") == "p1")
|
|
797
|
+
],
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
# Time each approach
|
|
801
|
+
times = {}
|
|
802
|
+
for name, approach in approaches.items():
|
|
803
|
+
start = time.time()
|
|
804
|
+
result = approach()
|
|
805
|
+
times[name] = time.time() - start
|
|
806
|
+
|
|
807
|
+
# Optimized approach should be fastest
|
|
808
|
+
assert times['optimized_xs'] <= min(times.values()) * 1.1 # Within 10%
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
#### Test 41: `test_dataframe_reindexing_performance`
|
|
812
|
+
```python
|
|
813
|
+
def test_dataframe_reindexing_performance():
|
|
814
|
+
"""Test performance of DataFrame reindexing operations."""
|
|
815
|
+
data = create_test_data(sorted=False)
|
|
816
|
+
|
|
817
|
+
# Test different reindexing strategies
|
|
818
|
+
strategies = [
|
|
819
|
+
lambda df: df.sort_index(axis=1),
|
|
820
|
+
lambda df: df.reindex(columns=df.columns.sort_values()),
|
|
821
|
+
lambda df: df[df.columns.sort_values()],
|
|
822
|
+
]
|
|
823
|
+
|
|
824
|
+
results = []
|
|
825
|
+
for strategy in strategies:
|
|
826
|
+
start = time.time()
|
|
827
|
+
result = strategy(data)
|
|
828
|
+
duration = time.time() - start
|
|
829
|
+
results.append((duration, result))
|
|
830
|
+
|
|
831
|
+
# Verify result is correctly sorted
|
|
832
|
+
assert result.columns.is_monotonic_increasing
|
|
833
|
+
|
|
834
|
+
# All strategies should complete in reasonable time
|
|
835
|
+
for duration, _ in results:
|
|
836
|
+
assert duration < 1.0 # Less than 1 second
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
#### Test 42: `test_memory_efficient_aggregations`
|
|
840
|
+
```python
|
|
841
|
+
def test_memory_efficient_aggregations():
|
|
842
|
+
"""Test memory-efficient aggregation operations."""
|
|
843
|
+
data = create_large_test_data()
|
|
844
|
+
|
|
845
|
+
# Test aggregations that should be memory efficient
|
|
846
|
+
aggregations = [
|
|
847
|
+
('mean_by_measurement', lambda df: df.groupby(level="M").mean()),
|
|
848
|
+
('std_by_species', lambda df: df.groupby(level="S").std()),
|
|
849
|
+
('sum_by_component', lambda df: df.groupby(level="C").sum()),
|
|
850
|
+
]
|
|
851
|
+
|
|
852
|
+
for name, aggregation in aggregations:
|
|
853
|
+
memory_before = get_process_memory()
|
|
854
|
+
result = aggregation(data)
|
|
855
|
+
memory_after = get_process_memory()
|
|
856
|
+
|
|
857
|
+
memory_increase = memory_after - memory_before
|
|
858
|
+
data_memory = data.memory_usage(deep=True).sum() / 1024**2
|
|
859
|
+
|
|
860
|
+
# Memory increase should be reasonable compared to data size
|
|
861
|
+
assert memory_increase < data_memory * 2 # Less than 2x data size
|
|
862
|
+
assert isinstance(result, pd.DataFrame)
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
---
|
|
866
|
+
|
|
867
|
+
## 6. Implementation Plan
|
|
868
|
+
|
|
869
|
+
### 6.1 Phase 1: Core Infrastructure (Tests 1-12, 31-33)
|
|
870
|
+
**Duration**: 3-4 hours
|
|
871
|
+
**Files**:
|
|
872
|
+
- `tests/core/test_multiindex_validation.py`
|
|
873
|
+
- `tests/core/test_dataframe_edge_cases.py`
|
|
874
|
+
|
|
875
|
+
**Priority**: High - foundational validation
|
|
876
|
+
|
|
877
|
+
### 6.2 Phase 2: Memory & Performance (Tests 13-30)
|
|
878
|
+
**Duration**: 4-5 hours
|
|
879
|
+
**Files**:
|
|
880
|
+
- `tests/core/test_dataframe_memory.py`
|
|
881
|
+
- `tests/core/test_dataframe_performance.py`
|
|
882
|
+
|
|
883
|
+
**Priority**: High - performance bottleneck identification
|
|
884
|
+
|
|
885
|
+
### 6.3 Phase 3: Advanced Patterns (Tests 34-42)
|
|
886
|
+
**Duration**: 2-3 hours
|
|
887
|
+
**Files**:
|
|
888
|
+
- `tests/core/test_indexslice_patterns.py`
|
|
889
|
+
- Additional tests in existing files
|
|
890
|
+
|
|
891
|
+
**Priority**: Medium - optimization and edge cases
|
|
892
|
+
|
|
893
|
+
### 6.4 Integration & Validation
|
|
894
|
+
**Duration**: 1 hour
|
|
895
|
+
- Run full test suite
|
|
896
|
+
- Validate coverage increase
|
|
897
|
+
- Performance regression testing
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## 7. Expected Outcomes
|
|
902
|
+
|
|
903
|
+
### 7.1 Coverage Metrics
|
|
904
|
+
- **Current**: 77.1% overall coverage
|
|
905
|
+
- **Target**: 82-83% overall coverage
|
|
906
|
+
- **New Architecture Tests**: 42 tests
|
|
907
|
+
- **Estimated Coverage Increase**: +5-6%
|
|
908
|
+
|
|
909
|
+
### 7.2 Quality Improvements
|
|
910
|
+
- **Architecture Validation**: Comprehensive MultiIndex structure testing
|
|
911
|
+
- **Memory Efficiency**: Systematic memory usage validation
|
|
912
|
+
- **Performance Baselines**: Regression testing infrastructure
|
|
913
|
+
- **Edge Case Coverage**: Robust handling of boundary conditions
|
|
914
|
+
|
|
915
|
+
### 7.3 Maintenance Benefits
|
|
916
|
+
- **Regression Prevention**: Performance and memory baselines
|
|
917
|
+
- **Development Velocity**: Clear architecture compliance validation
|
|
918
|
+
- **Documentation**: Living examples of proper DataFrame usage
|
|
919
|
+
- **Onboarding**: Clear patterns for new developers
|
|
920
|
+
|
|
921
|
+
---
|
|
922
|
+
|
|
923
|
+
## 8. Metrics & Success Criteria
|
|
924
|
+
|
|
925
|
+
### 8.1 Quantitative Metrics
|
|
926
|
+
- [ ] 42 new architecture tests implemented
|
|
927
|
+
- [ ] Test suite coverage ≥82%
|
|
928
|
+
- [ ] Architecture compliance grade improves to A-
|
|
929
|
+
- [ ] Memory usage tests coverage ≥90%
|
|
930
|
+
- [ ] Performance regression tests established
|
|
931
|
+
|
|
932
|
+
### 8.2 Qualitative Metrics
|
|
933
|
+
- [ ] Clear MultiIndex validation patterns documented
|
|
934
|
+
- [ ] Memory efficiency best practices established
|
|
935
|
+
- [ ] Performance baselines for regression testing
|
|
936
|
+
- [ ] Edge case handling comprehensively tested
|
|
937
|
+
- [ ] Integration patterns validated across modules
|
|
938
|
+
|
|
939
|
+
---
|
|
940
|
+
|
|
941
|
+
*Generated: 2025-08-21*
|
|
942
|
+
*DataFrameArchitect Agent - Architecture Enhancement Recommendations*
|
|
943
|
+
*SolarWindPy Test Suite Audit - Phase 3 Deliverable*
|