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.

Files changed (412) hide show
  1. plans/.velocity/metrics.json +96 -0
  2. plans/0-overview-template.md +268 -0
  3. plans/N-phase-template.md +106 -0
  4. plans/PLAN_AUDIT_SUMMARY.md +173 -0
  5. plans/TEMPLATE-USAGE-GUIDE.md +198 -0
  6. plans/__init__.py +1 -0
  7. plans/abandoned/compaction-agent-system/0-Overview.md +123 -0
  8. plans/abandoned/compaction-agent-system/agents-index-update-plan.md +109 -0
  9. plans/abandoned/compaction-agent-system/compacted_state.md +85 -0
  10. plans/abandoned/compaction-agent-system/implementation-plan.md +107 -0
  11. plans/abandoned/compaction-agent-system/system-validation-report.md +159 -0
  12. plans/abandoned/compaction-agent-system/usage-guide.md +210 -0
  13. plans/abandoned/hook-system-enhancement/0-Overview.md +214 -0
  14. plans/abandoned/hook-system-enhancement/1-Phase1-Core-Infrastructure.md +313 -0
  15. plans/abandoned/hook-system-enhancement/2-Phase2-Intelligent-Testing.md +385 -0
  16. plans/abandoned/hook-system-enhancement/3-Phase3-Physics-Validation.md +444 -0
  17. plans/abandoned/hook-system-enhancement/4-Phase4-Performance-Monitoring.md +458 -0
  18. plans/abandoned/hook-system-enhancement/5-Phase5-Developer-Experience.md +532 -0
  19. plans/abandoned/hook-system-enhancement/6-Implementation-Timeline.md +274 -0
  20. plans/abandoned/hook-system-enhancement/7-Risk-Management.md +376 -0
  21. plans/abandoned/hook-system-enhancement/8-Testing-Strategy.md +579 -0
  22. plans/abandoned/readthedocs-automation/0-Overview.md +247 -0
  23. plans/abandoned/readthedocs-automation/1-Emergency-Documentation-Fixes.md +270 -0
  24. plans/abandoned/readthedocs-automation/2-Template-System-Enhancement.md +811 -0
  25. plans/abandoned/readthedocs-automation/3-Quality-Audit-ReadTheDocs-Integration.md +844 -0
  26. plans/abandoned/readthedocs-automation/4-Plan-Consolidation-Cleanup.md +632 -0
  27. plans/abandoned/readthedocs-automation/9-Closeout.md +207 -0
  28. plans/abandoned/readthedocs-automation/ABANDONMENT_REASON.md +72 -0
  29. plans/cicd-architecture-redesign/0-Overview.md +193 -0
  30. plans/cicd-architecture-redesign/1-Workflow-Creation.md +103 -0
  31. plans/cicd-architecture-redesign/2-Version-Detection.md +123 -0
  32. plans/cicd-architecture-redesign/3-Deployment-Gates.md +169 -0
  33. plans/cicd-architecture-redesign/4-RC-Testing.md +194 -0
  34. plans/cicd-architecture-redesign/5-TestPyPI-Validation.md +264 -0
  35. plans/cicd-architecture-redesign/6-Production-Release.md +263 -0
  36. plans/cicd-architecture-redesign/7-Cleanup.md +243 -0
  37. plans/cicd-architecture-redesign/8-Documentation.md +285 -0
  38. plans/cicd-architecture-redesign/Closeout.md +225 -0
  39. plans/closeout-template.md +259 -0
  40. plans/completed/circular-import-audit/0-Overview.md +152 -0
  41. plans/completed/circular-import-audit/1-Static-Dependency-Analysis.md +62 -0
  42. plans/completed/circular-import-audit/2-Dynamic-Import-Testing.md +56 -0
  43. plans/completed/circular-import-audit/3-Performance-Impact-Assessment.md +56 -0
  44. plans/completed/circular-import-audit/4-Issue-Remediation.md +78 -0
  45. plans/completed/circular-import-audit/5-Preventive-Infrastructure.md +89 -0
  46. plans/completed/claude-settings-ecosystem-alignment/0-Overview.md +162 -0
  47. plans/completed/claude-settings-ecosystem-alignment/1-Security-Foundation.md +148 -0
  48. plans/completed/claude-settings-ecosystem-alignment/2-Hook-Integration.md +158 -0
  49. plans/completed/claude-settings-ecosystem-alignment/3-Agent-System-Integration.md +177 -0
  50. plans/completed/claude-settings-ecosystem-alignment/4-Enhanced-Workflow-Automation.md +159 -0
  51. plans/completed/claude-settings-ecosystem-alignment/5-Validation-Monitoring.md +181 -0
  52. plans/completed/claude-settings-ecosystem-alignment/compacted_session_state.md +290 -0
  53. plans/completed/combined_plan_with_checklist_documentation/1-Overview-and-Goals.md +51 -0
  54. plans/completed/combined_plan_with_checklist_documentation/2-Toolchain-and-Hosting.md +69 -0
  55. plans/completed/combined_plan_with_checklist_documentation/3-Repository-Structure.md +61 -0
  56. plans/completed/combined_plan_with_checklist_documentation/4-Configuration-and-Standards.md +70 -0
  57. plans/completed/combined_plan_with_checklist_documentation/5-Documentation-Content.md +62 -0
  58. plans/completed/combined_plan_with_checklist_documentation/6-CI-CD-and-Validation.md +58 -0
  59. plans/completed/combined_plan_with_checklist_documentation/7-Maintenance.md +55 -0
  60. plans/completed/combined_test_plan_with_checklist_fitfunctions/0-Overview.md +135 -0
  61. plans/completed/combined_test_plan_with_checklist_fitfunctions/1-Common-fixtures.md +59 -0
  62. plans/completed/combined_test_plan_with_checklist_fitfunctions/10-power_laws.md +56 -0
  63. plans/completed/combined_test_plan_with_checklist_fitfunctions/2-core.py-FitFunction.md +118 -0
  64. plans/completed/combined_test_plan_with_checklist_fitfunctions/3-gaussians.py-Gaussian-GaussianNormalized-GaussianLn.md +69 -0
  65. plans/completed/combined_test_plan_with_checklist_fitfunctions/4-trend_fits.py-TrendFit.md +99 -0
  66. plans/completed/combined_test_plan_with_checklist_fitfunctions/5-plots.py-FFPlot.md +98 -0
  67. plans/completed/combined_test_plan_with_checklist_fitfunctions/6-tex_info.py-TeXinfo.md +79 -0
  68. plans/completed/combined_test_plan_with_checklist_fitfunctions/7-Justification.md +49 -0
  69. plans/completed/combined_test_plan_with_checklist_fitfunctions/8-exponentials.md +64 -0
  70. plans/completed/combined_test_plan_with_checklist_fitfunctions/9-lines.md +58 -0
  71. plans/completed/combined_test_plan_with_checklist_plotting/0-Overview.md +142 -0
  72. plans/completed/combined_test_plan_with_checklist_plotting/1-base.py.md +90 -0
  73. plans/completed/combined_test_plan_with_checklist_plotting/10-labels-special.py.md +102 -0
  74. plans/completed/combined_test_plan_with_checklist_plotting/11-labels-chemistry.py.md +212 -0
  75. plans/completed/combined_test_plan_with_checklist_plotting/12-labels-composition.py.md +242 -0
  76. plans/completed/combined_test_plan_with_checklist_plotting/13-labels-datetime.py.md +247 -0
  77. plans/completed/combined_test_plan_with_checklist_plotting/14-labels-elemental_abundance.py.md +274 -0
  78. plans/completed/combined_test_plan_with_checklist_plotting/15-visual-validation.md +256 -0
  79. plans/completed/combined_test_plan_with_checklist_plotting/16-integration-testing.md +266 -0
  80. plans/completed/combined_test_plan_with_checklist_plotting/17-performance-benchmarks.md +267 -0
  81. plans/completed/combined_test_plan_with_checklist_plotting/18-Fixtures-and-Utilities.md +86 -0
  82. plans/completed/combined_test_plan_with_checklist_plotting/2-agg_plot.py.md +90 -0
  83. plans/completed/combined_test_plan_with_checklist_plotting/3-histograms.py.md +201 -0
  84. plans/completed/combined_test_plan_with_checklist_plotting/4-scatter.py.md +167 -0
  85. plans/completed/combined_test_plan_with_checklist_plotting/5-spiral.py.md +216 -0
  86. plans/completed/combined_test_plan_with_checklist_plotting/6-orbits.py.md +108 -0
  87. plans/completed/combined_test_plan_with_checklist_plotting/7-tools.py.md +86 -0
  88. plans/completed/combined_test_plan_with_checklist_plotting/8-select_data_from_figure.py.md +97 -0
  89. plans/completed/combined_test_plan_with_checklist_plotting/9-labels-base.py.md +88 -0
  90. plans/completed/combined_test_plan_with_checklist_solar_activity/.gitkeep +0 -0
  91. plans/completed/combined_test_plan_with_checklist_solar_activity/0-Overview.md +170 -0
  92. plans/completed/combined_test_plan_with_checklist_solar_activity/1-Package-Entry-Point-__init__.py.md +121 -0
  93. plans/completed/combined_test_plan_with_checklist_solar_activity/2-Core-Base-Classes-base.py.md +142 -0
  94. plans/completed/combined_test_plan_with_checklist_solar_activity/3-Plotting-Helpers-plots.py.md +123 -0
  95. plans/completed/combined_test_plan_with_checklist_solar_activity/4-LISIRD-Sub-package.md +119 -0
  96. plans/completed/combined_test_plan_with_checklist_solar_activity/5-Extrema-Calculator.md +103 -0
  97. plans/completed/combined_test_plan_with_checklist_solar_activity/6-Sunspot-Number-Sub-package.md +163 -0
  98. plans/completed/combined_test_plan_with_checklist_solar_activity/7-Sunspot-Number-Init.py.md +217 -0
  99. plans/completed/combined_test_plan_with_checklist_solar_activity/compacted_state.md +52 -0
  100. plans/completed/compaction-agent-modernization/0-Overview.md +156 -0
  101. plans/completed/compaction-agent-modernization/1-Architecture-Audit-Gap-Analysis.md +132 -0
  102. plans/completed/compaction-agent-modernization/2-Token-Baseline-Recalibration.md +153 -0
  103. plans/completed/compaction-agent-modernization/3-Agent-Reference-Updates.md +184 -0
  104. plans/completed/compaction-agent-modernization/4-Compression-Algorithm-Modernization.md +238 -0
  105. plans/completed/compaction-agent-modernization/5-Workflow-Integration-Streamlining.md +252 -0
  106. plans/completed/compaction-agent-modernization/6-Template-Structure-Optimization.md +240 -0
  107. plans/completed/compaction-agent-modernization/7-Integration-Testing-Validation.md +292 -0
  108. plans/completed/compaction-hook-enhancement/0-Overview.md +150 -0
  109. plans/completed/compaction-hook-enhancement/1-Token-Estimation-Enhancement.md +179 -0
  110. plans/completed/compaction-hook-enhancement/2-Compression-Intelligence.md +294 -0
  111. plans/completed/compaction-hook-enhancement/3-Git-Integration-Metadata.md +310 -0
  112. plans/completed/compaction-hook-enhancement/4-Session-Continuity-Features.md +358 -0
  113. plans/completed/compaction-hook-enhancement/5-Testing-Strategy.md +404 -0
  114. plans/completed/compaction-hook-enhancement/6-Integration-Roadmap.md +319 -0
  115. plans/completed/compaction-hook-enhancement/compacted_state.md +142 -0
  116. plans/completed/docstring-audit-enhancement/0-Overview.md +274 -0
  117. plans/completed/docstring-audit-enhancement/1-Infrastructure-Setup-and-Validation-Tools.md +206 -0
  118. plans/completed/docstring-audit-enhancement/2-Core-Physics-Modules-Enhancement.md +237 -0
  119. plans/completed/docstring-audit-enhancement/3-Fitfunctions-Mathematical-Modules-Enhancement.md +188 -0
  120. plans/completed/docstring-audit-enhancement/4-Plotting-Visualization-Modules-Enhancement.md +243 -0
  121. plans/completed/docstring-audit-enhancement/5-Specialized-Modules-Enhancement.md +216 -0
  122. plans/completed/docstring-audit-enhancement/6-Validation-and-Integration.md +216 -0
  123. plans/completed/fitfunctions-testing-implementation/0-Overview.md +130 -0
  124. plans/completed/fitfunctions-testing-implementation/1-Test-Infrastructure-Setup.md +79 -0
  125. plans/completed/fitfunctions-testing-implementation/2-Common-Fixtures-Test-Utilities.md +104 -0
  126. plans/completed/fitfunctions-testing-implementation/3-Core-FitFunction-Testing.md +168 -0
  127. plans/completed/fitfunctions-testing-implementation/4-Specialized-Function-Classes.md +210 -0
  128. plans/completed/fitfunctions-testing-implementation/5-Advanced-Classes-Testing.md +214 -0
  129. plans/completed/fitfunctions-testing-implementation/6-Plotting-Integration-Testing.md +231 -0
  130. plans/completed/fitfunctions-testing-implementation/7-Extended-Coverage-BONUS.md +184 -0
  131. plans/completed/numpy-docstring-conversion-plan/numpy-docstring-conversion-plan.md +118 -0
  132. plans/completed/pr-review-remediation/0-Overview.md +138 -0
  133. plans/completed/pr-review-remediation/1-Critical-Safety-Improvements.md +179 -0
  134. plans/completed/pr-review-remediation/2-Smart-Timeouts-Validation.md +399 -0
  135. plans/completed/pr-review-remediation/3-Enhanced-GitHub-Integration.md +258 -0
  136. plans/completed/pr-review-remediation/compacted_state.md +66 -0
  137. plans/completed/python-310-migration/0-Overview.md +390 -0
  138. plans/completed/python-310-migration/1-Planning-Setup.md +164 -0
  139. plans/completed/python-310-migration/2-Implementation.md +256 -0
  140. plans/completed/python-310-migration/3-Testing-Validation.md +335 -0
  141. plans/completed/python-310-migration/4-Documentation-Release.md +274 -0
  142. plans/completed/python-310-migration/5-Closeout.md +252 -0
  143. plans/completed/requirements-management-consolidation/0-Overview.md +118 -0
  144. plans/completed/requirements-management-consolidation/1-Documentation-Validation-Environment-Setup.md +116 -0
  145. plans/completed/requirements-management-consolidation/2-Requirements-Consolidation.md +161 -0
  146. plans/completed/requirements-management-consolidation/3-Workflow-Automation-Final-Integration.md +196 -0
  147. plans/completed/single-ecosystem-plan-implementation/0-Overview.md +83 -0
  148. plans/completed/single-ecosystem-plan-implementation/1-Plan-Preservation-Session-Management.md +38 -0
  149. plans/completed/single-ecosystem-plan-implementation/2-File-Structure-Optimization.md +43 -0
  150. plans/completed/single-ecosystem-plan-implementation/3-Plan-Migration-Archive-Setup.md +82 -0
  151. plans/completed/single-ecosystem-plan-implementation/4-Agent-System-Transformation.md +108 -0
  152. plans/completed/single-ecosystem-plan-implementation/5-Template-System-Enhancement.md +131 -0
  153. plans/completed/single-ecosystem-plan-implementation/6-Final-Validation-Testing.md +120 -0
  154. plans/completed/test-directory-consolidation/0-Overview.md +51 -0
  155. plans/completed/test-directory-consolidation/1-Structure-Preparation.md +82 -0
  156. plans/completed/test-directory-consolidation/2-File-Migration.md +100 -0
  157. plans/completed/test-directory-consolidation/3-Import-Transformation.md +117 -0
  158. plans/completed/test-directory-consolidation/4-Configuration-Consolidation.md +140 -0
  159. plans/completed/test-directory-consolidation/5-Validation.md +152 -0
  160. plans/completed/test-directory-consolidation/6-Cleanup.md +156 -0
  161. plans/completed/test-planning-agents-architecture/0-Overview.md +79 -0
  162. plans/completed/test-planning-agents-architecture/1-Branch-Isolation-Testing.md +49 -0
  163. plans/completed/test-planning-agents-architecture/2-Cross-Branch-Coordination.md +51 -0
  164. plans/completed/test-planning-agents-architecture/3-Merge-Workflow-Testing.md +48 -0
  165. plans/deployment-semver-pypi-rtd/0-Overview.md +463 -0
  166. plans/deployment-semver-pypi-rtd/1-Semantic-Versioning-Foundation.md +136 -0
  167. plans/deployment-semver-pypi-rtd/2-PyPI-Deployment-Infrastructure.md +168 -0
  168. plans/deployment-semver-pypi-rtd/3-Release-Automation.md +214 -0
  169. plans/deployment-semver-pypi-rtd/4-Plan-Closeout.md +543 -0
  170. plans/deployment-semver-pypi-rtd/compacted_session_state.md +172 -0
  171. plans/deployment-semver-pypi-rtd/compacted_state.md +131 -0
  172. plans/documentation-code-audit/0-Overview.md +393 -0
  173. plans/documentation-code-audit/1-Discovery-Inventory.md +183 -0
  174. plans/documentation-code-audit/2-Execution-Environment-Setup.md +263 -0
  175. plans/documentation-code-audit/3-Systematic-Validation.md +322 -0
  176. plans/documentation-code-audit/4-Code-Example-Remediation.md +358 -0
  177. plans/documentation-code-audit/5-Physics-MultiIndex-Compliance.md +464 -0
  178. plans/documentation-code-audit/6-Doctest-Integration.md +523 -0
  179. plans/documentation-code-audit/7-Reporting-Documentation.md +498 -0
  180. plans/documentation-code-audit/8-Closeout.md +456 -0
  181. plans/documentation-rebuild-session/compacted_state.md +109 -0
  182. plans/documentation-rendering-fixes/0-Overview.md +104 -0
  183. plans/documentation-rendering-fixes/1-Sphinx-Build-Diagnostics-Warning-Audit.md +101 -0
  184. plans/documentation-rendering-fixes/2-Configuration-Infrastructure-Fixes.md +113 -0
  185. plans/documentation-rendering-fixes/3-Docstring-Syntax-Audit-Repair.md +131 -0
  186. plans/documentation-rendering-fixes/4-HTML-Page-Rendering-Verification.md +113 -0
  187. plans/documentation-rendering-fixes/5-Advanced-Documentation-Quality-Assurance.md +119 -0
  188. plans/documentation-rendering-fixes/6-Documentation-Build-Optimization-Testing.md +129 -0
  189. plans/documentation-rendering-fixes/compacted_state.md +132 -0
  190. plans/documentation-template-fix/0-Overview.md +197 -0
  191. plans/documentation-template-fix/1-Template-System-Analysis.md +269 -0
  192. plans/documentation-template-fix/2-Template-Modification.md +609 -0
  193. plans/documentation-template-fix/3-Build-System-Integration.md +766 -0
  194. plans/documentation-template-fix/4-Testing-Validation.md +1399 -0
  195. plans/documentation-template-fix/5-Documentation-Training.md +602 -0
  196. plans/documentation-workflow-fix/0-Overview.md +222 -0
  197. plans/documentation-workflow-fix/1-Immediate-Fixes.md +238 -0
  198. plans/documentation-workflow-fix/2-Configuration-Setup.md +298 -0
  199. plans/documentation-workflow-fix/3-Pre-commit-Integration.md +382 -0
  200. plans/documentation-workflow-fix/4-Workflow-Improvements.md +446 -0
  201. plans/documentation-workflow-fix/5-Documentation-and-Training.md +527 -0
  202. plans/duplicate-object-warnings-fix-plan.md +130 -0
  203. plans/github-issues-migration/0-Overview.md +510 -0
  204. plans/github-issues-migration/1-Foundation-Label-System.md +180 -0
  205. plans/github-issues-migration/2-Migration-Tool-Rewrite.md +235 -0
  206. plans/github-issues-migration/3-CLI-Integration-Automation.md +169 -0
  207. plans/github-issues-migration/4-Validated-Migration.md +252 -0
  208. plans/github-issues-migration/5-Documentation-Training.md +171 -0
  209. plans/github-issues-migration/6-Closeout.md +179 -0
  210. plans/github-workflows-repair/repair-plan.md +299 -0
  211. plans/issues_from_plans.py +342 -0
  212. plans/pr-270-doc-validation-fixes/0-Overview.md +354 -0
  213. plans/pr-270-doc-validation-fixes/1-Critical-PR-Fixes.md +117 -0
  214. plans/pr-270-doc-validation-fixes/2-Framework-Right-Sizing.md +129 -0
  215. plans/pr-270-doc-validation-fixes/3-Sustainable-Documentation.md +126 -0
  216. plans/pr-270-doc-validation-fixes/4-Closeout-Migration.md +143 -0
  217. plans/pr-270-doc-validation-fixes/PLAN_COMPLETED.md +149 -0
  218. plans/python-310-migration/0-Overview.md +390 -0
  219. plans/python-310-migration/1-Planning-Setup.md +164 -0
  220. plans/python-310-migration/2-Implementation.md +256 -0
  221. plans/python-310-migration/3-Testing-Validation.md +335 -0
  222. plans/python-310-migration/4-Documentation-Release.md +274 -0
  223. plans/python-310-migration/5-Closeout.md +252 -0
  224. plans/readthedocs-simplified/0-Overview.md +243 -0
  225. plans/readthedocs-simplified/1-Immediate-Fixes.md +216 -0
  226. plans/readthedocs-simplified/2-Template-Simplification.md +278 -0
  227. plans/readthedocs-simplified/3-ReadTheDocs-Setup.md +298 -0
  228. plans/readthedocs-simplified/4-Testing-Validation.md +328 -0
  229. plans/readthedocs-simplified/5-Closeout.md +231 -0
  230. plans/readthedocs-simplified/compacted_state.md +127 -0
  231. plans/session-compaction-2025-08-12/compacted_state.md +114 -0
  232. plans/session-compaction-2025-08-13/compacted_state.md +145 -0
  233. plans/session-continuity-protocol/0-Overview.md +35 -0
  234. plans/session-continuity-protocol/1-Core-Principles-Framework.md +40 -0
  235. plans/session-continuity-protocol/2-Pre-Session-Validation-System.md +79 -0
  236. plans/session-continuity-protocol/3-Context-Switching-Prevention.md +87 -0
  237. plans/session-continuity-protocol/4-Progress-Tracking-Recovery.md +100 -0
  238. plans/sphinx-warnings-analysis.md +222 -0
  239. plans/systemprompt-optimization/0-Overview.md +447 -0
  240. plans/systemprompt-optimization/1-Deploy-SystemPrompt.md +114 -0
  241. plans/systemprompt-optimization/2-Documentation-Alignment.md +198 -0
  242. plans/systemprompt-optimization/3-Monitoring-Infrastructure.md +396 -0
  243. plans/systemprompt-optimization/4-Implementation-Script.md +450 -0
  244. plans/systemprompt-optimization/9-Closeout.md +165 -0
  245. plans/systemprompt-optimization/compacted_state.md +143 -0
  246. plans/template-value-propositions/0-Overview.md +357 -0
  247. plans/template-value-propositions/1-Value-Proposition-Framework-Design.md +144 -0
  248. plans/template-value-propositions/2-Plan-Template-Enhancement.md +178 -0
  249. plans/template-value-propositions/3-Value-Generator-Hook-Implementation.md +291 -0
  250. plans/template-value-propositions/4-Value-Validator-Hook-Implementation.md +274 -0
  251. plans/template-value-propositions/5-Documentation-Agent-Updates.md +219 -0
  252. plans/template-value-propositions/6-Integration-Testing-Validation.md +247 -0
  253. plans/tests-audit/0-Overview.md +410 -0
  254. plans/tests-audit/1-Discovery-Inventory.md +170 -0
  255. plans/tests-audit/2-Physics-Validation-Audit.md +195 -0
  256. plans/tests-audit/3-Architecture-Compliance.md +195 -0
  257. plans/tests-audit/4-Numerical-Stability-Analysis.md +203 -0
  258. plans/tests-audit/5-Documentation-Enhancement.md +220 -0
  259. plans/tests-audit/6-Audit-Deliverables.md +220 -0
  260. plans/tests-audit/7-Closeout.md +252 -0
  261. plans/tests-audit/artifacts/ARCHITECTURE_COMPLIANCE_REPORT.md +315 -0
  262. plans/tests-audit/artifacts/ARCHITECTURE_RECOMMENDATIONS.md +943 -0
  263. plans/tests-audit/artifacts/COMPREHENSIVE_AUDIT_REPORT.md +356 -0
  264. plans/tests-audit/artifacts/CONTRIBUTING_ENHANCED_TEMPLATE.md +419 -0
  265. plans/tests-audit/artifacts/COVERAGE_GAP_ANALYSIS.md +152 -0
  266. plans/tests-audit/artifacts/DOCUMENTATION_ENHANCEMENT_REPORT.md +502 -0
  267. plans/tests-audit/artifacts/EXECUTIVE_AUDIT_SUMMARY.md +129 -0
  268. plans/tests-audit/artifacts/IMPLEMENTATION_ROADMAP.md +647 -0
  269. plans/tests-audit/artifacts/NUMERICAL_RECOMMENDATIONS.md +739 -0
  270. plans/tests-audit/artifacts/NUMERICAL_STABILITY_GUIDE_TEMPLATE.rst +451 -0
  271. plans/tests-audit/artifacts/NUMERICAL_STABILITY_REPORT.md +301 -0
  272. plans/tests-audit/artifacts/PHASE_3_SUMMARY.md +280 -0
  273. plans/tests-audit/artifacts/PHASE_4_SUMMARY.md +229 -0
  274. plans/tests-audit/artifacts/PHASE_5_SUMMARY.md +292 -0
  275. plans/tests-audit/artifacts/PHASE_6_CLOSEOUT.md +278 -0
  276. plans/tests-audit/artifacts/PHYSICS_GUIDE_TEMPLATE.rst +268 -0
  277. plans/tests-audit/artifacts/PHYSICS_VALIDATION_REPORT.md +235 -0
  278. plans/tests-audit/artifacts/TECHNICAL_DELIVERABLES_PACKAGE.md +2502 -0
  279. plans/tests-audit/artifacts/TEST_INVENTORY.csv +1204 -0
  280. plans/tests-audit/artifacts/TEST_INVENTORY.md +135 -0
  281. plans/tests-audit/artifacts/test_discovery_analysis.py +231 -0
  282. plans/tests-audit/artifacts/test_parser.py +395 -0
  283. solarwindpy/README.md +3 -0
  284. solarwindpy/Untitled.ipynb +54 -0
  285. solarwindpy/__init__.py +74 -0
  286. solarwindpy/core/__init__.py +23 -0
  287. solarwindpy/core/alfvenic_turbulence.py +804 -0
  288. solarwindpy/core/base.py +267 -0
  289. solarwindpy/core/ions.py +309 -0
  290. solarwindpy/core/plasma.py +2133 -0
  291. solarwindpy/core/spacecraft.py +256 -0
  292. solarwindpy/core/tensor.py +90 -0
  293. solarwindpy/core/units_constants.py +199 -0
  294. solarwindpy/core/vector.py +328 -0
  295. solarwindpy/fitfunctions/__init__.py +20 -0
  296. solarwindpy/fitfunctions/core.py +734 -0
  297. solarwindpy/fitfunctions/exponentials.py +188 -0
  298. solarwindpy/fitfunctions/gaussians.py +264 -0
  299. solarwindpy/fitfunctions/lines.py +116 -0
  300. solarwindpy/fitfunctions/moyal.py +71 -0
  301. solarwindpy/fitfunctions/plots.py +751 -0
  302. solarwindpy/fitfunctions/power_laws.py +209 -0
  303. solarwindpy/fitfunctions/tex_info.py +568 -0
  304. solarwindpy/fitfunctions/trend_fits.py +482 -0
  305. solarwindpy/instabilities/__init__.py +16 -0
  306. solarwindpy/instabilities/beta_ani.py +82 -0
  307. solarwindpy/instabilities/verscharen2016.py +631 -0
  308. solarwindpy/plotting/__init__.py +33 -0
  309. solarwindpy/plotting/agg_plot.py +489 -0
  310. solarwindpy/plotting/base.py +465 -0
  311. solarwindpy/plotting/hist1d.py +405 -0
  312. solarwindpy/plotting/hist2d.py +1035 -0
  313. solarwindpy/plotting/histograms.py +1845 -0
  314. solarwindpy/plotting/labels/__init__.py +104 -0
  315. solarwindpy/plotting/labels/base.py +686 -0
  316. solarwindpy/plotting/labels/chemistry.py +19 -0
  317. solarwindpy/plotting/labels/composition.py +100 -0
  318. solarwindpy/plotting/labels/datetime.py +235 -0
  319. solarwindpy/plotting/labels/elemental_abundance.py +73 -0
  320. solarwindpy/plotting/labels/special.py +794 -0
  321. solarwindpy/plotting/orbits.py +515 -0
  322. solarwindpy/plotting/scatter.py +99 -0
  323. solarwindpy/plotting/select_data_from_figure.py +329 -0
  324. solarwindpy/plotting/spiral.py +980 -0
  325. solarwindpy/plotting/tools.py +434 -0
  326. solarwindpy/scripts/__init__.py +1 -0
  327. solarwindpy/scripts/logs/.gitignore +1 -0
  328. solarwindpy/solar_activity/__init__.py +53 -0
  329. solarwindpy/solar_activity/base.py +605 -0
  330. solarwindpy/solar_activity/lisird/__init__.py +3 -0
  331. solarwindpy/solar_activity/lisird/extrema_calculator.py +394 -0
  332. solarwindpy/solar_activity/lisird/lisird.py +319 -0
  333. solarwindpy/solar_activity/plots.py +116 -0
  334. solarwindpy/solar_activity/sunspot_number/.DS_Store +0 -0
  335. solarwindpy/solar_activity/sunspot_number/__init__.py +3 -0
  336. solarwindpy/solar_activity/sunspot_number/sidc.py +556 -0
  337. solarwindpy/solar_activity/sunspot_number/ssn_extrema.csv +72 -0
  338. solarwindpy/solar_activity/sunspot_number/ssn_extrema.csv.silso +72 -0
  339. solarwindpy/tools/__init__.py +162 -0
  340. solarwindpy-0.1.0.dist-info/METADATA +181 -0
  341. solarwindpy-0.1.0.dist-info/RECORD +409 -0
  342. {solarwindpy-0.0.1.dev0.dist-info → solarwindpy-0.1.0.dist-info}/WHEEL +1 -1
  343. solarwindpy-0.1.0.dist-info/licenses/LICENSE.rst +32 -0
  344. solarwindpy-0.1.0.dist-info/top_level.txt +3 -0
  345. tests/__init__.py +1 -0
  346. tests/conftest.py +10 -0
  347. tests/core/__init__.py +1 -0
  348. tests/core/test_alfvenic_turbulence.py +544 -0
  349. tests/core/test_base.py +112 -0
  350. tests/core/test_base_head_tail.py +29 -0
  351. tests/core/test_base_mi_tuples.py +11 -0
  352. tests/core/test_core_verify_datetimeindex.py +32 -0
  353. tests/core/test_ions.py +325 -0
  354. tests/core/test_plasma.py +2581 -0
  355. tests/core/test_plasma_io.py +12 -0
  356. tests/core/test_quantities.py +507 -0
  357. tests/core/test_spacecraft.py +210 -0
  358. tests/core/test_units_constants.py +22 -0
  359. tests/data/epoch.csv +4 -0
  360. tests/data/plasma.csv +4 -0
  361. tests/data/spacecraft.csv +4 -0
  362. tests/fitfunctions/conftest.py +60 -0
  363. tests/fitfunctions/test_core.py +193 -0
  364. tests/fitfunctions/test_exponentials.py +342 -0
  365. tests/fitfunctions/test_gaussians.py +142 -0
  366. tests/fitfunctions/test_lines.py +349 -0
  367. tests/fitfunctions/test_moyal.py +258 -0
  368. tests/fitfunctions/test_plots.py +258 -0
  369. tests/fitfunctions/test_power_laws.py +365 -0
  370. tests/fitfunctions/test_tex_info.py +183 -0
  371. tests/fitfunctions/test_trend_fit_properties.py +31 -0
  372. tests/fitfunctions/test_trend_fits.py +244 -0
  373. tests/plotting/__init__.py +1 -0
  374. tests/plotting/labels/__init__.py +1 -0
  375. tests/plotting/labels/test_chemistry.py +243 -0
  376. tests/plotting/labels/test_composition.py +345 -0
  377. tests/plotting/labels/test_datetime.py +445 -0
  378. tests/plotting/labels/test_elemental_abundance.py +366 -0
  379. tests/plotting/labels/test_init.py +66 -0
  380. tests/plotting/labels/test_labels_base.py +347 -0
  381. tests/plotting/labels/test_special.py +550 -0
  382. tests/plotting/test_agg_plot.py +602 -0
  383. tests/plotting/test_base.py +752 -0
  384. tests/plotting/test_fixtures_utilities.py +775 -0
  385. tests/plotting/test_histograms.py +546 -0
  386. tests/plotting/test_integration.py +675 -0
  387. tests/plotting/test_orbits.py +435 -0
  388. tests/plotting/test_performance.py +708 -0
  389. tests/plotting/test_scatter.py +752 -0
  390. tests/plotting/test_select_data_from_figure.py +1209 -0
  391. tests/plotting/test_spiral.py +573 -0
  392. tests/plotting/test_tools.py +607 -0
  393. tests/plotting/test_visual_validation.py +465 -0
  394. tests/solar_activity/__init__.py +1 -0
  395. tests/solar_activity/lisird/__init__.py +1 -0
  396. tests/solar_activity/lisird/test_extrema_calculator.py +593 -0
  397. tests/solar_activity/lisird/test_lisird_id.py +187 -0
  398. tests/solar_activity/sunspot_number/__init__.py +1 -0
  399. tests/solar_activity/sunspot_number/test_init.py +399 -0
  400. tests/solar_activity/sunspot_number/test_sidc.py +465 -0
  401. tests/solar_activity/sunspot_number/test_sidc_id.py +223 -0
  402. tests/solar_activity/sunspot_number/test_sidc_loader.py +275 -0
  403. tests/solar_activity/sunspot_number/test_ssn_extrema.py +406 -0
  404. tests/solar_activity/test_base.py +656 -0
  405. tests/solar_activity/test_init.py +396 -0
  406. tests/solar_activity/test_plots.py +371 -0
  407. tests/test_circular_imports.py +408 -0
  408. tests/test_issue_titles.py +25 -0
  409. tests/test_statusline.py +298 -0
  410. solarwindpy-0.0.1.dev0.dist-info/METADATA +0 -14
  411. solarwindpy-0.0.1.dev0.dist-info/RECORD +0 -4
  412. solarwindpy-0.0.1.dev0.dist-info/top_level.txt +0 -1
@@ -0,0 +1,775 @@
1
+ """Test fixtures and utilities for plotting functionality.
2
+
3
+ Comprehensive test infrastructure, fixtures, and utility functions for the plotting test
4
+ suite.
5
+ """
6
+
7
+ import pytest
8
+ import numpy as np
9
+ import pandas as pd
10
+ import matplotlib
11
+ import matplotlib.pyplot as plt
12
+ from pathlib import Path
13
+ import tempfile
14
+ import warnings
15
+ from unittest.mock import patch, MagicMock
16
+ import pickle
17
+
18
+ # Configure matplotlib for testing
19
+ matplotlib.use("Agg")
20
+ plt.ioff()
21
+
22
+
23
+ # ============================================================================
24
+ # Core Fixtures
25
+ # ============================================================================
26
+
27
+
28
+ @pytest.fixture(scope="session")
29
+ def matplotlib_backend():
30
+ """Ensure consistent matplotlib backend for all tests."""
31
+ original_backend = matplotlib.get_backend()
32
+ matplotlib.use("Agg")
33
+ yield "Agg"
34
+ matplotlib.use(original_backend)
35
+
36
+
37
+ @pytest.fixture(scope="function")
38
+ def clean_matplotlib():
39
+ """Clean matplotlib state before and after each test."""
40
+ plt.close("all")
41
+ plt.rcdefaults() # Reset to default rc parameters
42
+ yield
43
+ plt.close("all")
44
+
45
+
46
+ @pytest.fixture(scope="function")
47
+ def suppress_warnings():
48
+ """Suppress common matplotlib and numpy warnings during tests."""
49
+ with warnings.catch_warnings():
50
+ warnings.simplefilter("ignore", UserWarning)
51
+ warnings.simplefilter("ignore", RuntimeWarning)
52
+ warnings.simplefilter("ignore", FutureWarning)
53
+ yield
54
+
55
+
56
+ # ============================================================================
57
+ # Data Fixtures
58
+ # ============================================================================
59
+
60
+
61
+ @pytest.fixture(scope="session")
62
+ def synthetic_time_series():
63
+ """Generate synthetic time series data for testing."""
64
+ dates = pd.date_range("2023-01-01", periods=1000, freq="1h")
65
+ np.random.seed(42)
66
+
67
+ # Solar wind parameters with realistic variations
68
+ n = len(dates)
69
+ time_index = np.arange(n)
70
+
71
+ data = {
72
+ "density": 10 + 2 * np.sin(time_index / 100) + np.random.normal(0, 0.5, n),
73
+ "velocity": 400 + 50 * np.sin(time_index / 150) + np.random.normal(0, 10, n),
74
+ "temperature": 1e5
75
+ + 2e4 * np.sin(time_index / 80)
76
+ + np.random.normal(0, 5e3, n),
77
+ "b_field": 5 + np.sin(time_index / 120) + np.random.normal(0, 0.2, n),
78
+ "pressure": 1.5 + 0.3 * np.sin(time_index / 90) + np.random.normal(0, 0.1, n),
79
+ }
80
+
81
+ return pd.DataFrame(data, index=dates)
82
+
83
+
84
+ @pytest.fixture(scope="session")
85
+ def synthetic_plasma_data():
86
+ """Generate synthetic plasma data for correlation analysis."""
87
+ np.random.seed(42)
88
+ n_points = 500
89
+
90
+ # Correlated plasma parameters
91
+ density = np.random.lognormal(mean=2.3, sigma=0.5, size=n_points) # ~10 cm^-3
92
+ velocity = (
93
+ 400 + 100 * (1 / density) + np.random.normal(0, 20, n_points)
94
+ ) # Anti-corr with density
95
+ temperature = 1e5 * (velocity / 400) ** 1.5 + np.random.normal(
96
+ 0, 2e4, n_points
97
+ ) # Corr with velocity
98
+ b_field = 5 * np.sqrt(density) + np.random.normal(
99
+ 0, 1, n_points
100
+ ) # Corr with density
101
+
102
+ return pd.DataFrame(
103
+ {
104
+ "density": density,
105
+ "velocity": velocity,
106
+ "temperature": temperature,
107
+ "b_field": b_field,
108
+ }
109
+ )
110
+
111
+
112
+ @pytest.fixture(scope="function")
113
+ def small_dataset():
114
+ """Small dataset for quick tests."""
115
+ np.random.seed(42)
116
+ x = np.linspace(0, 10, 50)
117
+ y = np.sin(x) + 0.1 * np.random.randn(50)
118
+ return x, y
119
+
120
+
121
+ @pytest.fixture(scope="function")
122
+ def medium_dataset():
123
+ """Medium dataset for standard tests."""
124
+ np.random.seed(42)
125
+ x = np.linspace(0, 20, 1000)
126
+ y = np.sin(x) * np.exp(-x / 10) + 0.1 * np.random.randn(1000)
127
+ return x, y
128
+
129
+
130
+ @pytest.fixture(scope="function")
131
+ def large_dataset():
132
+ """Large dataset for performance tests."""
133
+ np.random.seed(42)
134
+ x = np.linspace(0, 100, 100000)
135
+ y = np.sin(x / 10) + 0.1 * np.random.randn(100000)
136
+ return x, y
137
+
138
+
139
+ @pytest.fixture(scope="function")
140
+ def scatter_data():
141
+ """Scatter plot data with color mapping."""
142
+ np.random.seed(42)
143
+ n = 200
144
+ x = np.random.randn(n)
145
+ y = np.random.randn(n)
146
+ colors = np.random.rand(n)
147
+ sizes = 20 + 50 * np.random.rand(n)
148
+ return x, y, colors, sizes
149
+
150
+
151
+ @pytest.fixture(scope="function")
152
+ def histogram_data():
153
+ """Data for histogram testing."""
154
+ np.random.seed(42)
155
+ return {
156
+ "normal": np.random.normal(0, 1, 1000),
157
+ "exponential": np.random.exponential(2, 1000),
158
+ "uniform": np.random.uniform(-3, 3, 1000),
159
+ "mixed": np.concatenate(
160
+ [np.random.normal(-2, 0.5, 300), np.random.normal(2, 0.8, 700)]
161
+ ),
162
+ }
163
+
164
+
165
+ @pytest.fixture(scope="function")
166
+ def contour_data():
167
+ """2D data for contour/surface plots."""
168
+ x = np.linspace(-5, 5, 50)
169
+ y = np.linspace(-5, 5, 50)
170
+ X, Y = np.meshgrid(x, y)
171
+ Z = np.sin(np.sqrt(X**2 + Y**2)) * np.exp(-0.1 * (X**2 + Y**2))
172
+ return X, Y, Z
173
+
174
+
175
+ # ============================================================================
176
+ # Figure and Axes Fixtures
177
+ # ============================================================================
178
+
179
+
180
+ @pytest.fixture(scope="function")
181
+ def single_axis(clean_matplotlib):
182
+ """Single axis figure for basic plots."""
183
+ fig, ax = plt.subplots(figsize=(8, 6))
184
+ yield fig, ax
185
+ plt.close(fig)
186
+
187
+
188
+ @pytest.fixture(scope="function")
189
+ def multi_axis(clean_matplotlib):
190
+ """Multi-axis figure for subplot tests."""
191
+ fig, axes = plt.subplots(2, 2, figsize=(12, 10))
192
+ yield fig, axes
193
+ plt.close(fig)
194
+
195
+
196
+ @pytest.fixture(scope="function")
197
+ def time_series_axes(clean_matplotlib):
198
+ """Specialized axes for time series plots."""
199
+ fig, axes = plt.subplots(3, 1, figsize=(12, 10), sharex=True)
200
+ yield fig, axes
201
+ plt.close(fig)
202
+
203
+
204
+ @pytest.fixture(scope="function")
205
+ def correlation_axes(clean_matplotlib):
206
+ """Correlation plot axes configuration."""
207
+ fig, axes = plt.subplots(2, 3, figsize=(15, 10))
208
+ yield fig, axes
209
+ plt.close(fig)
210
+
211
+
212
+ # ============================================================================
213
+ # Temporary File Fixtures
214
+ # ============================================================================
215
+
216
+
217
+ @pytest.fixture(scope="function")
218
+ def temp_dir():
219
+ """Temporary directory for file operations."""
220
+ with tempfile.TemporaryDirectory() as tmpdir:
221
+ yield Path(tmpdir)
222
+
223
+
224
+ @pytest.fixture(scope="function")
225
+ def temp_plot_file(temp_dir):
226
+ """Temporary file for plot saving."""
227
+ return temp_dir / "test_plot.png"
228
+
229
+
230
+ @pytest.fixture(scope="function")
231
+ def temp_data_file(temp_dir):
232
+ """Temporary file for data saving."""
233
+ return temp_dir / "test_data.csv"
234
+
235
+
236
+ # ============================================================================
237
+ # Mock Fixtures
238
+ # ============================================================================
239
+
240
+
241
+ @pytest.fixture(scope="function")
242
+ def mock_figure():
243
+ """Mock matplotlib figure for unit testing."""
244
+ with patch("matplotlib.pyplot.figure") as mock_fig:
245
+ mock_instance = MagicMock()
246
+ mock_fig.return_value = mock_instance
247
+ yield mock_instance
248
+
249
+
250
+ @pytest.fixture(scope="function")
251
+ def mock_axes():
252
+ """Mock matplotlib axes for unit testing."""
253
+ mock_ax = MagicMock()
254
+ mock_ax.plot.return_value = [MagicMock()] # Line2D objects
255
+ mock_ax.scatter.return_value = MagicMock() # PathCollection
256
+ mock_ax.hist.return_value = (
257
+ np.array([1, 2, 3]),
258
+ np.array([0, 1, 2, 3]),
259
+ [MagicMock()],
260
+ )
261
+ return mock_ax
262
+
263
+
264
+ # ============================================================================
265
+ # Utility Classes and Functions
266
+ # ============================================================================
267
+
268
+
269
+ class PlotTestHelper:
270
+ """Helper class for common plotting test operations."""
271
+
272
+ @staticmethod
273
+ def assert_plot_elements(
274
+ ax,
275
+ expected_lines=None,
276
+ expected_collections=None,
277
+ expected_patches=None,
278
+ has_legend=None,
279
+ has_grid=None,
280
+ ):
281
+ """Assert expected plot elements are present."""
282
+ if expected_lines is not None:
283
+ assert (
284
+ len(ax.lines) == expected_lines
285
+ ), f"Expected {expected_lines} lines, got {len(ax.lines)}"
286
+
287
+ if expected_collections is not None:
288
+ assert (
289
+ len(ax.collections) == expected_collections
290
+ ), f"Expected {expected_collections} collections, got {len(ax.collections)}"
291
+
292
+ if expected_patches is not None:
293
+ assert (
294
+ len(ax.patches) == expected_patches
295
+ ), f"Expected {expected_patches} patches, got {len(ax.patches)}"
296
+
297
+ if has_legend is not None:
298
+ legend_exists = ax.legend_ is not None
299
+ assert (
300
+ legend_exists == has_legend
301
+ ), f"Legend existence mismatch: expected {has_legend}, got {legend_exists}"
302
+
303
+ if has_grid is not None:
304
+ # Check if grid is visible
305
+ grid_on = (
306
+ ax.xaxis.get_gridlines()[0].get_visible()
307
+ if ax.xaxis.get_gridlines()
308
+ else False
309
+ )
310
+ assert (
311
+ grid_on == has_grid
312
+ ), f"Grid visibility mismatch: expected {has_grid}, got {grid_on}"
313
+
314
+ @staticmethod
315
+ def assert_axes_labels(ax, xlabel=None, ylabel=None, title=None):
316
+ """Assert axes labels are set correctly."""
317
+ if xlabel is not None:
318
+ assert (
319
+ ax.get_xlabel() == xlabel
320
+ ), f"X-label mismatch: expected '{xlabel}', got '{ax.get_xlabel()}'"
321
+
322
+ if ylabel is not None:
323
+ assert (
324
+ ax.get_ylabel() == ylabel
325
+ ), f"Y-label mismatch: expected '{ylabel}', got '{ax.get_ylabel()}'"
326
+
327
+ if title is not None:
328
+ assert (
329
+ ax.get_title() == title
330
+ ), f"Title mismatch: expected '{title}', got '{ax.get_title()}'"
331
+
332
+ @staticmethod
333
+ def assert_data_ranges(ax, xlim=None, ylim=None, tolerance=1e-10):
334
+ """Assert data ranges are within expected limits."""
335
+ if xlim is not None:
336
+ actual_xlim = ax.get_xlim()
337
+ assert (
338
+ abs(actual_xlim[0] - xlim[0]) < tolerance
339
+ and abs(actual_xlim[1] - xlim[1]) < tolerance
340
+ ), f"X-limits mismatch: expected {xlim}, got {actual_xlim}"
341
+
342
+ if ylim is not None:
343
+ actual_ylim = ax.get_ylim()
344
+ assert (
345
+ abs(actual_ylim[0] - ylim[0]) < tolerance
346
+ and abs(actual_ylim[1] - ylim[1]) < tolerance
347
+ ), f"Y-limits mismatch: expected {ylim}, got {actual_ylim}"
348
+
349
+ @staticmethod
350
+ def save_and_verify_plot(fig, filepath, formats=["png"], dpi=100):
351
+ """Save plot in multiple formats and verify files."""
352
+ saved_files = []
353
+
354
+ for fmt in formats:
355
+ if isinstance(filepath, Path):
356
+ file_path = filepath.with_suffix(f".{fmt}")
357
+ else:
358
+ file_path = Path(str(filepath)).with_suffix(f".{fmt}")
359
+
360
+ fig.savefig(file_path, format=fmt, dpi=dpi, bbox_inches="tight")
361
+
362
+ # Verify file was created and has content
363
+ assert file_path.exists(), f"File {file_path} was not created"
364
+ assert file_path.stat().st_size > 0, f"File {file_path} is empty"
365
+
366
+ saved_files.append(file_path)
367
+
368
+ return saved_files
369
+
370
+
371
+ @pytest.fixture(scope="function")
372
+ def plot_helper():
373
+ """Provide PlotTestHelper instance."""
374
+ return PlotTestHelper()
375
+
376
+
377
+ # ============================================================================
378
+ # Test Data Generators
379
+ # ============================================================================
380
+
381
+
382
+ def generate_solar_wind_event(duration_hours=24, cadence_minutes=1, event_type="shock"):
383
+ """Generate synthetic solar wind event data."""
384
+ n_points = int(duration_hours * 60 / cadence_minutes)
385
+ times = pd.date_range("2023-01-01", periods=n_points, freq=f"{cadence_minutes}min")
386
+
387
+ if event_type == "shock":
388
+ # Sudden jump in parameters
389
+ shock_time = n_points // 2
390
+
391
+ density = np.ones(n_points) * 5
392
+ density[shock_time:] = 20 # Density jump
393
+ density += np.random.normal(0, 1, n_points)
394
+
395
+ velocity = np.ones(n_points) * 350
396
+ velocity[shock_time:] = 600 # Velocity jump
397
+ velocity += np.random.normal(0, 15, n_points)
398
+
399
+ temperature = np.ones(n_points) * 5e4
400
+ temperature[shock_time:] = 2e5 # Temperature jump
401
+ temperature += np.random.normal(0, 1e4, n_points)
402
+
403
+ elif event_type == "cme":
404
+ # Gradual rotation in magnetic field
405
+ b_x = 5 * np.sin(np.linspace(0, 4 * np.pi, n_points))
406
+ b_y = 5 * np.cos(np.linspace(0, 4 * np.pi, n_points))
407
+ b_z = 2 * np.sin(np.linspace(0, 2 * np.pi, n_points))
408
+
409
+ density = 15 + 5 * np.sin(np.linspace(0, 2 * np.pi, n_points))
410
+ velocity = 450 + 100 * np.sin(np.linspace(0, np.pi, n_points))
411
+ temperature = 1e5 + 5e4 * np.sin(np.linspace(0, np.pi, n_points))
412
+
413
+ return pd.DataFrame(
414
+ {
415
+ "density": density + np.random.normal(0, 1, n_points),
416
+ "velocity": velocity + np.random.normal(0, 20, n_points),
417
+ "temperature": temperature + np.random.normal(0, 1e4, n_points),
418
+ "b_x": b_x + np.random.normal(0, 0.5, n_points),
419
+ "b_y": b_y + np.random.normal(0, 0.5, n_points),
420
+ "b_z": b_z + np.random.normal(0, 0.5, n_points),
421
+ },
422
+ index=times,
423
+ )
424
+
425
+ return pd.DataFrame(
426
+ {"density": density, "velocity": velocity, "temperature": temperature},
427
+ index=times,
428
+ )
429
+
430
+
431
+ @pytest.fixture(scope="function", params=["shock", "cme"])
432
+ def solar_wind_event(request):
433
+ """Generate solar wind event data."""
434
+ return generate_solar_wind_event(event_type=request.param)
435
+
436
+
437
+ # ============================================================================
438
+ # Performance Testing Utilities
439
+ # ============================================================================
440
+
441
+
442
+ class PerformanceTracker:
443
+ """Track performance metrics for plotting operations."""
444
+
445
+ def __init__(self):
446
+ self.metrics = {}
447
+
448
+ def time_operation(self, operation_name, func, *args, **kwargs):
449
+ """Time a plotting operation and store metrics."""
450
+ import time
451
+
452
+ start_time = time.time()
453
+ result = func(*args, **kwargs)
454
+ end_time = time.time()
455
+
456
+ elapsed = end_time - start_time
457
+
458
+ if operation_name not in self.metrics:
459
+ self.metrics[operation_name] = []
460
+ self.metrics[operation_name].append(elapsed)
461
+
462
+ return result, elapsed
463
+
464
+ def get_average_time(self, operation_name):
465
+ """Get average time for an operation."""
466
+ if operation_name in self.metrics:
467
+ return np.mean(self.metrics[operation_name])
468
+ return None
469
+
470
+ def assert_performance(self, operation_name, max_time):
471
+ """Assert operation performance meets expectations."""
472
+ avg_time = self.get_average_time(operation_name)
473
+ if avg_time is not None:
474
+ assert (
475
+ avg_time < max_time
476
+ ), f"{operation_name} took {avg_time:.3f}s (expected < {max_time}s)"
477
+
478
+
479
+ @pytest.fixture(scope="function")
480
+ def performance_tracker():
481
+ """Provide PerformanceTracker instance."""
482
+ return PerformanceTracker()
483
+
484
+
485
+ # ============================================================================
486
+ # Test Infrastructure Classes
487
+ # ============================================================================
488
+
489
+
490
+ class TestFixturesAndUtilities:
491
+ """Test the test infrastructure itself."""
492
+
493
+ def test_synthetic_time_series_fixture(self, synthetic_time_series):
494
+ """Test synthetic time series data fixture."""
495
+ assert isinstance(synthetic_time_series, pd.DataFrame)
496
+ assert len(synthetic_time_series) == 1000
497
+ assert synthetic_time_series.index.freq is not None
498
+
499
+ expected_columns = ["density", "velocity", "temperature", "b_field", "pressure"]
500
+ for col in expected_columns:
501
+ assert col in synthetic_time_series.columns
502
+ assert not synthetic_time_series[col].isna().any()
503
+
504
+ def test_synthetic_plasma_data_fixture(self, synthetic_plasma_data):
505
+ """Test synthetic plasma data fixture."""
506
+ assert isinstance(synthetic_plasma_data, pd.DataFrame)
507
+ assert len(synthetic_plasma_data) == 500
508
+
509
+ # Check that correlations exist (anti-correlation between density and velocity)
510
+ density_velocity_corr = synthetic_plasma_data["density"].corr(
511
+ synthetic_plasma_data["velocity"]
512
+ )
513
+ assert (
514
+ density_velocity_corr < 0
515
+ ), "Expected anti-correlation between density and velocity"
516
+
517
+ def test_plot_helper_functionality(self, plot_helper, single_axis):
518
+ """Test PlotTestHelper functionality."""
519
+ fig, ax = single_axis
520
+
521
+ # Create a simple plot
522
+ x = np.linspace(0, 10, 100)
523
+ y = np.sin(x)
524
+ ax.plot(x, y, label="sin(x)")
525
+ ax.set_xlabel("X")
526
+ ax.set_ylabel("Y")
527
+ ax.set_title("Test Plot")
528
+ ax.legend()
529
+ ax.grid(True)
530
+
531
+ # Test assertions
532
+ plot_helper.assert_plot_elements(
533
+ ax, expected_lines=1, has_legend=True, has_grid=True
534
+ )
535
+ plot_helper.assert_axes_labels(ax, xlabel="X", ylabel="Y", title="Test Plot")
536
+
537
+ def test_temporary_file_fixtures(self, temp_dir, temp_plot_file, temp_data_file):
538
+ """Test temporary file fixtures."""
539
+ assert temp_dir.exists()
540
+ assert temp_dir.is_dir()
541
+
542
+ # Test that parent directory of temp files exists
543
+ assert temp_plot_file.parent.exists()
544
+ assert temp_data_file.parent.exists()
545
+
546
+ # Test file creation
547
+ temp_plot_file.write_text("test plot data")
548
+ temp_data_file.write_text("test,data\n1,2\n")
549
+
550
+ assert temp_plot_file.exists()
551
+ assert temp_data_file.exists()
552
+
553
+ def test_dataset_fixtures(self, small_dataset, medium_dataset, large_dataset):
554
+ """Test dataset fixtures have expected properties."""
555
+ x_small, y_small = small_dataset
556
+ x_medium, y_medium = medium_dataset
557
+ x_large, y_large = large_dataset
558
+
559
+ # Check sizes
560
+ assert len(x_small) == 50
561
+ assert len(x_medium) == 1000
562
+ assert len(x_large) == 100000
563
+
564
+ # Check data types
565
+ for x, y in [(x_small, y_small), (x_medium, y_medium), (x_large, y_large)]:
566
+ assert isinstance(x, np.ndarray)
567
+ assert isinstance(y, np.ndarray)
568
+ assert len(x) == len(y)
569
+
570
+ def test_scatter_data_fixture(self, scatter_data):
571
+ """Test scatter data fixture."""
572
+ x, y, colors, sizes = scatter_data
573
+
574
+ assert len(x) == len(y) == len(colors) == len(sizes) == 200
575
+ assert 0 <= colors.min() and colors.max() <= 1 # Color values in [0,1]
576
+ assert sizes.min() >= 20 and sizes.max() <= 70 # Size range
577
+
578
+ def test_histogram_data_fixture(self, histogram_data):
579
+ """Test histogram data fixture."""
580
+ expected_types = ["normal", "exponential", "uniform", "mixed"]
581
+
582
+ for data_type in expected_types:
583
+ assert data_type in histogram_data
584
+ data = histogram_data[data_type]
585
+ assert len(data) == 1000 or (data_type == "mixed" and len(data) == 1000)
586
+
587
+ def test_contour_data_fixture(self, contour_data):
588
+ """Test contour data fixture."""
589
+ X, Y, Z = contour_data
590
+
591
+ assert X.shape == Y.shape == Z.shape == (50, 50)
592
+ assert not np.isnan(Z).any()
593
+ assert not np.isinf(Z).any()
594
+
595
+ def test_performance_tracker(self, performance_tracker):
596
+ """Test performance tracking functionality."""
597
+ import time
598
+
599
+ def slow_operation():
600
+ time.sleep(0.1)
601
+ return "result"
602
+
603
+ def fast_operation():
604
+ return "result"
605
+
606
+ # Time operations
607
+ result1, time1 = performance_tracker.time_operation("slow", slow_operation)
608
+ result2, time2 = performance_tracker.time_operation("fast", fast_operation)
609
+
610
+ assert result1 == "result"
611
+ assert result2 == "result"
612
+ assert time1 > time2
613
+ assert time1 >= 0.1
614
+
615
+ # Test performance assertions
616
+ performance_tracker.assert_performance("fast", 0.1)
617
+
618
+ with pytest.raises(AssertionError):
619
+ performance_tracker.assert_performance("slow", 0.05)
620
+
621
+ def test_solar_wind_event_generator(self, solar_wind_event):
622
+ """Test solar wind event data generator."""
623
+ assert isinstance(solar_wind_event, pd.DataFrame)
624
+ assert "density" in solar_wind_event.columns
625
+ assert "velocity" in solar_wind_event.columns
626
+ assert "temperature" in solar_wind_event.columns
627
+
628
+ # Check that data shows event characteristics
629
+ density_std = solar_wind_event["density"].std()
630
+ velocity_std = solar_wind_event["velocity"].std()
631
+
632
+ # Events should show significant variation
633
+ assert density_std > 1.0
634
+ assert velocity_std > 10.0
635
+
636
+
637
+ class TestMockingUtilities:
638
+ """Test mocking utilities for unit testing."""
639
+
640
+ def test_mock_figure_fixture(self, mock_figure):
641
+ """Test mock figure fixture."""
642
+ assert mock_figure is not None
643
+
644
+ # Test that mock can be called
645
+ mock_figure.savefig("test.png")
646
+ mock_figure.savefig.assert_called_with("test.png")
647
+
648
+ def test_mock_axes_fixture(self, mock_axes):
649
+ """Test mock axes fixture."""
650
+ assert mock_axes is not None
651
+
652
+ # Test plotting methods return expected types
653
+ line = mock_axes.plot([1, 2, 3], [1, 2, 3])
654
+ assert line is not None
655
+
656
+ scatter = mock_axes.scatter([1, 2, 3], [1, 2, 3])
657
+ assert scatter is not None
658
+
659
+ hist_result = mock_axes.hist([1, 2, 3])
660
+ assert len(hist_result) == 3 # n, bins, patches
661
+
662
+
663
+ class TestFixtureIntegration:
664
+ """Test integration between different fixtures."""
665
+
666
+ def test_plot_with_synthetic_data(
667
+ self, single_axis, synthetic_time_series, plot_helper
668
+ ):
669
+ """Test plotting with synthetic data using fixtures."""
670
+ fig, ax = single_axis
671
+
672
+ # Plot first parameter
673
+ param = "density"
674
+ ax.plot(
675
+ synthetic_time_series.index,
676
+ synthetic_time_series[param],
677
+ label=param,
678
+ linewidth=1.5,
679
+ )
680
+ ax.set_xlabel("Time")
681
+ ax.set_ylabel("Density (cm⁻³)")
682
+ ax.set_title("Synthetic Time Series Test")
683
+ ax.legend()
684
+ ax.grid(True, alpha=0.3)
685
+
686
+ # Use helper to validate
687
+ plot_helper.assert_plot_elements(
688
+ ax, expected_lines=1, has_legend=True, has_grid=True
689
+ )
690
+ plot_helper.assert_axes_labels(
691
+ ax,
692
+ xlabel="Time",
693
+ ylabel="Density (cm⁻³)",
694
+ title="Synthetic Time Series Test",
695
+ )
696
+
697
+ def test_save_plot_with_temp_files(
698
+ self, single_axis, small_dataset, temp_dir, plot_helper
699
+ ):
700
+ """Test saving plots using temporary file fixtures."""
701
+ fig, ax = single_axis
702
+ x, y = small_dataset
703
+
704
+ ax.plot(x, y, "b-", linewidth=2)
705
+ ax.set_xlabel("X")
706
+ ax.set_ylabel("Y")
707
+ ax.set_title("Save Test Plot")
708
+
709
+ # Save using helper
710
+ plot_file = temp_dir / "integration_test"
711
+ saved_files = plot_helper.save_and_verify_plot(
712
+ fig, plot_file, formats=["png", "pdf"]
713
+ )
714
+
715
+ assert len(saved_files) == 2
716
+ for file_path in saved_files:
717
+ assert file_path.exists()
718
+
719
+
720
+ def pytest_configure(config):
721
+ """Configure pytest with custom markers."""
722
+ config.addinivalue_line(
723
+ "markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')"
724
+ )
725
+ config.addinivalue_line("markers", "integration: marks tests as integration tests")
726
+ config.addinivalue_line("markers", "performance: marks tests as performance tests")
727
+
728
+
729
+ # ============================================================================
730
+ # Utility Functions for External Use
731
+ # ============================================================================
732
+
733
+
734
+ def create_test_plot(plot_type="line", data_size="medium", **kwargs):
735
+ """Create a test plot for external testing use."""
736
+ if data_size == "small":
737
+ n = 50
738
+ elif data_size == "medium":
739
+ n = 1000
740
+ elif data_size == "large":
741
+ n = 10000
742
+ else:
743
+ n = int(data_size)
744
+
745
+ fig, ax = plt.subplots(figsize=kwargs.get("figsize", (8, 6)))
746
+
747
+ if plot_type == "line":
748
+ x = np.linspace(0, 10, n)
749
+ y = np.sin(x) + 0.1 * np.random.randn(n)
750
+ ax.plot(x, y, **kwargs)
751
+
752
+ elif plot_type == "scatter":
753
+ x = np.random.randn(n)
754
+ y = np.random.randn(n)
755
+ ax.scatter(x, y, **kwargs)
756
+
757
+ elif plot_type == "histogram":
758
+ data = np.random.normal(0, 1, n)
759
+ ax.hist(data, bins=kwargs.get("bins", 30), **kwargs)
760
+
761
+ return fig, ax
762
+
763
+
764
+ def validate_plot_output(ax, plot_type="line"):
765
+ """Validate that plot output meets basic requirements."""
766
+ if plot_type == "line":
767
+ assert len(ax.lines) > 0, "No lines found in line plot"
768
+ elif plot_type == "scatter":
769
+ assert len(ax.collections) > 0, "No scatter collections found"
770
+ elif plot_type == "histogram":
771
+ assert len(ax.patches) > 0, "No histogram patches found"
772
+
773
+ # General validations
774
+ assert ax.get_xlabel() != "" or ax.get_ylabel() != "", "No axis labels set"
775
+ return True