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,275 @@
1
+ #!/usr/bin/env python
2
+ """Simplified test SIDCLoader class.
3
+
4
+ This module tests the core SIDCLoader functionality from solar_activity.sunspot_number.sidc:
5
+ - Data conversion and NaN handling
6
+ - Basic inheritance and method existence
7
+ - URL and key handling
8
+ """
9
+
10
+ import pytest
11
+ import pandas as pd
12
+ import numpy as np
13
+ from pathlib import Path
14
+ from unittest.mock import Mock, patch, MagicMock
15
+
16
+ from solarwindpy.solar_activity.sunspot_number.sidc import SIDCLoader, SIDC_ID
17
+
18
+
19
+ class TestSIDCLoaderCore:
20
+ """Test core SIDCLoader functionality."""
21
+
22
+ def test_convert_nans_basic(self):
23
+ """Test convert_nans replaces -1 with np.nan."""
24
+ # Create a minimal loader instance for testing convert_nans method
25
+ with patch.object(SIDCLoader, "_init_logger"):
26
+ loader = SIDCLoader("m", "http://example.com")
27
+
28
+ # Create test DataFrame with -1 values
29
+ test_data = pd.DataFrame(
30
+ {
31
+ "ssn": [10.5, -1, 25.3, -1, 8.7],
32
+ "std": [2.1, 3.4, -1, 5.6, -1],
33
+ "n_obs": [12, 15, -1, 18, 20],
34
+ }
35
+ )
36
+
37
+ loader.convert_nans(test_data)
38
+
39
+ # Check that -1 values are replaced with NaN
40
+ assert pd.isna(test_data.loc[1, "ssn"])
41
+ assert pd.isna(test_data.loc[3, "ssn"])
42
+ assert pd.isna(test_data.loc[2, "std"])
43
+ assert pd.isna(test_data.loc[4, "std"])
44
+ assert pd.isna(test_data.loc[2, "n_obs"])
45
+
46
+ # Check that other values remain unchanged
47
+ assert test_data.loc[0, "ssn"] == 10.5
48
+ assert test_data.loc[2, "ssn"] == 25.3
49
+ assert test_data.loc[4, "ssn"] == 8.7
50
+
51
+ def test_convert_nans_no_minus_ones(self):
52
+ """Test convert_nans when there are no -1 values."""
53
+ with patch.object(SIDCLoader, "_init_logger"):
54
+ loader = SIDCLoader("m", "http://example.com")
55
+
56
+ test_data = pd.DataFrame({"ssn": [10.5, 20.3, 25.3], "std": [2.1, 3.4, 4.2]})
57
+ original_data = test_data.copy()
58
+
59
+ loader.convert_nans(test_data)
60
+
61
+ # Data should remain unchanged
62
+ pd.testing.assert_frame_equal(test_data, original_data)
63
+
64
+ def test_convert_nans_all_minus_ones(self):
65
+ """Test convert_nans when all values are -1."""
66
+ with patch.object(SIDCLoader, "_init_logger"):
67
+ loader = SIDCLoader("m", "http://example.com")
68
+
69
+ test_data = pd.DataFrame({"ssn": [-1, -1, -1], "std": [-1, -1, -1]})
70
+
71
+ loader.convert_nans(test_data)
72
+
73
+ # All values should be NaN
74
+ assert test_data.isna().all().all()
75
+
76
+ def test_inheritance_from_data_loader(self):
77
+ """Test that SIDCLoader inherits from DataLoader."""
78
+ from solarwindpy.solar_activity.base import DataLoader
79
+
80
+ with patch.object(SIDCLoader, "_init_logger"):
81
+ loader = SIDCLoader("m", "http://example.com")
82
+
83
+ assert isinstance(loader, DataLoader)
84
+ # Check that it has key properties from the base class
85
+ assert loader.key == "m"
86
+ assert loader.url == "http://example.com"
87
+
88
+ def test_data_path_property_structure(self):
89
+ """Test that data_path property creates correct path structure."""
90
+ # Mock the parent data_path to avoid filesystem dependencies
91
+ with patch.object(
92
+ SIDCLoader.__bases__[0], "data_path", new_callable=lambda: Path("/tmp/test")
93
+ ):
94
+ with patch.object(SIDCLoader, "_init_logger"):
95
+ loader = SIDCLoader("m", "http://example.com")
96
+
97
+ expected_path = Path("/tmp/test") / "sidc" / "m"
98
+ assert loader.data_path == expected_path
99
+
100
+ def test_data_path_with_different_keys(self):
101
+ """Test data_path property with different SIDC keys."""
102
+ test_keys = ["d", "m", "m13", "y", "hd", "hm", "hm13"]
103
+
104
+ for key in test_keys:
105
+ with patch.object(
106
+ SIDCLoader.__bases__[0],
107
+ "data_path",
108
+ new_callable=lambda: Path("/tmp/test"),
109
+ ):
110
+ with patch.object(SIDCLoader, "_init_logger"):
111
+ loader = SIDCLoader(key, "http://example.com")
112
+ expected_path = Path("/tmp/test") / "sidc" / key
113
+ assert loader.data_path == expected_path
114
+
115
+ def test_method_existence(self):
116
+ """Test that required methods exist."""
117
+ with patch.object(SIDCLoader, "_init_logger"):
118
+ loader = SIDCLoader("m", "http://example.com")
119
+
120
+ # Check that key methods exist
121
+ assert hasattr(loader, "convert_nans")
122
+ assert callable(loader.convert_nans)
123
+ assert hasattr(loader, "download_data")
124
+ assert callable(loader.download_data)
125
+ assert hasattr(loader, "load_data")
126
+ assert callable(loader.load_data)
127
+ assert hasattr(loader, "data_path")
128
+
129
+ @patch("pandas.read_csv")
130
+ def test_download_data_calls_read_csv(self, mock_read_csv, tmp_path):
131
+ """Test that download_data calls pandas.read_csv."""
132
+ # Create a simple mock CSV response
133
+ mock_csv = pd.DataFrame(
134
+ {
135
+ "year": [1996],
136
+ "month": [1],
137
+ "year_fraction": [1996.042],
138
+ "ssn": [17.5],
139
+ "std": [8.0],
140
+ "n_obs": [14],
141
+ "definitive": [True],
142
+ }
143
+ )
144
+ mock_read_csv.return_value = mock_csv
145
+
146
+ with patch.object(SIDCLoader, "_init_logger"):
147
+ loader = SIDCLoader("m", "http://example.com/snmtotcsv.php")
148
+ loader._logger = Mock() # Mock the logger to avoid logging issues
149
+
150
+ new_data_path = tmp_path / "new_data"
151
+ old_data_path = tmp_path / "old_data"
152
+
153
+ loader.download_data(new_data_path, old_data_path)
154
+
155
+ # Verify that read_csv was called with the URL
156
+ mock_read_csv.assert_called_once()
157
+ args, kwargs = mock_read_csv.call_args
158
+ assert args[0] == "http://example.com/snmtotcsv.php"
159
+ assert kwargs["sep"] == ";"
160
+ assert kwargs["header"] is None
161
+
162
+ def test_download_data_invalid_key_raises_error(self, tmp_path):
163
+ """Test that invalid keys in download_data raise NotImplementedError."""
164
+ with patch.object(SIDCLoader, "_init_logger"):
165
+ loader = SIDCLoader("invalid_key", "http://example.com")
166
+ loader._logger = Mock()
167
+
168
+ new_data_path = tmp_path / "new_data"
169
+ old_data_path = tmp_path / "old_data"
170
+
171
+ with pytest.raises(
172
+ NotImplementedError, match="You have not yet used the SSN specified"
173
+ ):
174
+ loader.download_data(new_data_path, old_data_path)
175
+
176
+ @patch.object(SIDCLoader.__bases__[0], "load_data") # Mock parent load_data
177
+ @patch("solarwindpy.solar_activity.sunspot_number.sidc.SSNExtrema")
178
+ def test_load_data_calls_parent_and_ssn_extrema(
179
+ self, mock_ssn_extrema_class, mock_parent_load_data
180
+ ):
181
+ """Test that load_data calls parent load_data and uses SSNExtrema."""
182
+ with patch.object(SIDCLoader, "_init_logger"):
183
+ loader = SIDCLoader("m", "http://example.com")
184
+ loader._logger = Mock()
185
+
186
+ # Create mock data for the loader
187
+ test_dates = pd.date_range("2008-01-01", "2010-12-31", freq="MS")
188
+ test_data = pd.DataFrame(
189
+ {
190
+ "ssn": np.random.uniform(10, 100, len(test_dates)),
191
+ "std": np.random.uniform(5, 15, len(test_dates)),
192
+ },
193
+ index=test_dates,
194
+ )
195
+ loader._data = test_data
196
+
197
+ # Mock SSNExtrema
198
+ mock_extrema = Mock()
199
+ mock_intervals = pd.DataFrame(
200
+ {
201
+ "Cycle": [
202
+ pd.Interval(pd.Timestamp("2008-01-01"), pd.Timestamp("2019-12-31")),
203
+ pd.Interval(pd.Timestamp("2020-01-01"), pd.Timestamp("2030-12-31")),
204
+ ]
205
+ },
206
+ index=[24, 25],
207
+ )
208
+ mock_intervals.index.name = "Number"
209
+ mock_extrema.cycle_intervals = mock_intervals
210
+ mock_ssn_extrema_class.return_value = mock_extrema
211
+
212
+ loader.load_data()
213
+
214
+ # Verify parent load_data was called
215
+ mock_parent_load_data.assert_called_once()
216
+
217
+ # Verify SSNExtrema was instantiated
218
+ mock_ssn_extrema_class.assert_called_once()
219
+
220
+
221
+ class TestSIDCLoaderEdgeCases:
222
+ """Test edge cases for SIDCLoader."""
223
+
224
+ def test_convert_nans_mixed_dtypes(self):
225
+ """Test convert_nans with mixed data types."""
226
+ with patch.object(SIDCLoader, "_init_logger"):
227
+ loader = SIDCLoader("m", "http://example.com")
228
+
229
+ test_data = pd.DataFrame(
230
+ {
231
+ "ssn": [10.5, -1, 25.3], # float
232
+ "n_obs": [12, -1, 18], # int
233
+ "definitive": [True, False, True], # bool, shouldn't change
234
+ }
235
+ )
236
+
237
+ loader.convert_nans(test_data)
238
+
239
+ # Check float column
240
+ assert pd.isna(test_data.loc[1, "ssn"])
241
+ assert test_data.loc[0, "ssn"] == 10.5
242
+
243
+ # Check int column
244
+ assert pd.isna(test_data.loc[1, "n_obs"])
245
+ assert test_data.loc[0, "n_obs"] == 12
246
+
247
+ # Check bool column (should remain unchanged)
248
+ assert test_data.loc[0, "definitive"] == True
249
+ assert test_data.loc[1, "definitive"] == False
250
+
251
+ def test_initialization_with_real_sidc_id(self):
252
+ """Test initialization with a real SIDC_ID object."""
253
+ sidc_id = SIDC_ID("m")
254
+
255
+ with patch.object(SIDCLoader, "_init_logger"):
256
+ loader = SIDCLoader(sidc_id.key, sidc_id.url)
257
+
258
+ assert loader.key == "m"
259
+ assert "snmtotcsv.php" in loader.url
260
+ assert isinstance(loader, SIDCLoader)
261
+
262
+ def test_path_creation_does_not_create_directories(self):
263
+ """Test that accessing data_path doesn't create actual directories."""
264
+ with patch.object(
265
+ SIDCLoader.__bases__[0],
266
+ "data_path",
267
+ new_callable=lambda: Path("/nonexistent/test"),
268
+ ):
269
+ with patch.object(SIDCLoader, "_init_logger"):
270
+ loader = SIDCLoader("m", "http://example.com")
271
+
272
+ path = loader.data_path
273
+ # Path object should be created but directory shouldn't exist
274
+ assert isinstance(path, Path)
275
+ assert not path.exists() # Should not create actual directory
@@ -0,0 +1,406 @@
1
+ #!/usr/bin/env python
2
+ """Test SSNExtrema class.
3
+
4
+ This module tests the SSNExtrema class from solar_activity.sunspot_number.sidc:
5
+ - CSV parsing and data loading
6
+ - Error handling for invalid arguments
7
+ - Data format validation
8
+ """
9
+
10
+ import pytest
11
+ import pandas as pd
12
+ import numpy as np
13
+ from pathlib import Path
14
+ from unittest.mock import Mock, patch, mock_open
15
+
16
+ from solarwindpy.solar_activity.sunspot_number.sidc import SSNExtrema
17
+
18
+
19
+ class TestSSNExtrema:
20
+ """Test the SSNExtrema class for solar cycle extrema data."""
21
+
22
+ @pytest.fixture
23
+ def sample_ssn_extrema_csv(self):
24
+ """Sample SSN extrema CSV content for testing."""
25
+ # Simulate the format of ssn_extrema.csv with header rows and data
26
+ csv_content = (
27
+ """# Solar Cycle Extrema Data
28
+ # Source: SIDC - Royal Observatory of Belgium
29
+ # Data format: Cycle Number, Minimum Date, Maximum Date
30
+ #
31
+ # Additional header lines (total 45 lines to skip)
32
+ """
33
+ + "\n" * 40
34
+ + """Number,Min,Max
35
+ 20,1964-10-01,1968-11-01
36
+ 21,1976-03-01,1979-12-01
37
+ 22,1986-09-01,1989-07-01
38
+ 23,1996-05-01,2000-03-01
39
+ 24,2008-12-01,2014-04-01
40
+ 25,2019-12-01,2025-07-01"""
41
+ )
42
+ return csv_content
43
+
44
+ def test_initialization_no_args(self):
45
+ """Test SSNExtrema initialization with no arguments."""
46
+ # This should work without raising errors
47
+ with (
48
+ patch("pandas.read_csv") as mock_read_csv,
49
+ patch("pathlib.Path.exists", return_value=True),
50
+ ):
51
+
52
+ # Mock the CSV data
53
+ mock_data = pd.DataFrame(
54
+ {
55
+ "Min": ["1964-10-01", "1976-03-01", "1986-09-01"],
56
+ "Max": ["1968-11-01", "1979-12-01", "1989-07-01"],
57
+ },
58
+ index=[20, 21, 22],
59
+ )
60
+ mock_read_csv.return_value = mock_data
61
+
62
+ extrema = SSNExtrema()
63
+
64
+ # Verify that the load_or_set_data method was called implicitly
65
+ assert hasattr(extrema, "_data")
66
+
67
+ def test_load_or_set_data_empty_args(self, sample_ssn_extrema_csv):
68
+ """Test load_or_set_data with empty args and kwargs."""
69
+ extrema = SSNExtrema.__new__(SSNExtrema)
70
+
71
+ # Mock file reading
72
+ with (
73
+ patch("pandas.read_csv") as mock_read_csv,
74
+ patch("pathlib.Path.exists", return_value=True),
75
+ ):
76
+
77
+ # Create mock DataFrame that simulates the CSV structure
78
+ raw_data = pd.DataFrame(
79
+ {
80
+ "Min": ["1964-10-01", "1976-03-01", "1986-09-01"],
81
+ "Max": ["1968-11-01", "1979-12-01", "1989-07-01"],
82
+ },
83
+ index=[20, 21, 22],
84
+ )
85
+
86
+ # Mock the stack/unstack operations
87
+ stacked = pd.Series(
88
+ [
89
+ "1964-10-01",
90
+ "1968-11-01",
91
+ "1976-03-01",
92
+ "1979-12-01",
93
+ "1986-09-01",
94
+ "1989-07-01",
95
+ ]
96
+ )
97
+ unstacked = pd.DataFrame(
98
+ {
99
+ "Min": [
100
+ pd.Timestamp("1964-10-01"),
101
+ pd.Timestamp("1976-03-01"),
102
+ pd.Timestamp("1986-09-01"),
103
+ ],
104
+ "Max": [
105
+ pd.Timestamp("1968-11-01"),
106
+ pd.Timestamp("1979-12-01"),
107
+ pd.Timestamp("1989-07-01"),
108
+ ],
109
+ },
110
+ index=[20, 21, 22],
111
+ )
112
+ unstacked.columns.names = ["kind"]
113
+
114
+ mock_read_csv.return_value = raw_data
115
+
116
+ with (
117
+ patch.object(pd.DataFrame, "stack", return_value=stacked),
118
+ patch("pandas.to_datetime", return_value=stacked),
119
+ patch.object(pd.Series, "unstack", return_value=unstacked),
120
+ ):
121
+
122
+ extrema.load_or_set_data()
123
+
124
+ # Verify CSV was read with correct parameters
125
+ mock_read_csv.assert_called_once()
126
+ args, kwargs = mock_read_csv.call_args
127
+ assert kwargs["header"] == 0
128
+ assert kwargs["skiprows"] == 45
129
+ assert kwargs["index_col"] == 0
130
+
131
+ # Verify data was set
132
+ assert hasattr(extrema, "_data")
133
+ assert extrema._data.columns.names == ["kind"]
134
+
135
+ def test_load_or_set_data_with_args_raises_error(self):
136
+ """Test that passing args/kwargs raises ValueError."""
137
+ extrema = SSNExtrema.__new__(SSNExtrema)
138
+
139
+ # Should raise ValueError when passing arguments
140
+ with pytest.raises(
141
+ ValueError, match="SSNExtrema expects empty args and kwargs"
142
+ ):
143
+ extrema.load_or_set_data("some_arg")
144
+
145
+ def test_load_or_set_data_with_kwargs_raises_error(self):
146
+ """Test that passing kwargs raises ValueError."""
147
+ extrema = SSNExtrema.__new__(SSNExtrema)
148
+
149
+ # Should raise ValueError when passing keyword arguments
150
+ with pytest.raises(
151
+ ValueError, match="SSNExtrema expects empty args and kwargs"
152
+ ):
153
+ extrema.load_or_set_data(some_kwarg="value")
154
+
155
+ def test_load_or_set_data_with_both_args_and_kwargs_raises_error(self):
156
+ """Test that passing both args and kwargs raises ValueError."""
157
+ extrema = SSNExtrema.__new__(SSNExtrema)
158
+
159
+ # Should raise ValueError when passing both
160
+ with pytest.raises(
161
+ ValueError, match="SSNExtrema expects empty args and kwargs"
162
+ ):
163
+ extrema.load_or_set_data("arg", kwarg="value")
164
+
165
+ def test_inheritance_from_indicator_extrema(self):
166
+ """Test that SSNExtrema inherits from IndicatorExtrema."""
167
+ from solarwindpy.solar_activity.base import IndicatorExtrema
168
+
169
+ with (
170
+ patch("pandas.read_csv") as mock_read_csv,
171
+ patch("pathlib.Path.exists", return_value=True),
172
+ ):
173
+
174
+ # Mock the CSV data
175
+ mock_data = pd.DataFrame(
176
+ {"Min": ["1964-10-01"], "Max": ["1968-11-01"]}, index=[20]
177
+ )
178
+ mock_read_csv.return_value = mock_data
179
+
180
+ extrema = SSNExtrema()
181
+ assert isinstance(extrema, IndicatorExtrema)
182
+
183
+ def test_csv_file_path_resolution(self):
184
+ """Test that the CSV file path is resolved correctly."""
185
+ extrema = SSNExtrema.__new__(SSNExtrema)
186
+
187
+ with (
188
+ patch("pandas.read_csv") as mock_read_csv,
189
+ patch("pathlib.Path.exists", return_value=True),
190
+ ):
191
+
192
+ mock_data = pd.DataFrame(
193
+ {"Min": ["1964-10-01"], "Max": ["1968-11-01"]}, index=[20]
194
+ )
195
+ mock_read_csv.return_value = mock_data
196
+
197
+ extrema.load_or_set_data()
198
+
199
+ # Check that read_csv was called with the expected path
200
+ args, kwargs = mock_read_csv.call_args
201
+ called_path = args[0]
202
+
203
+ # The path should end with ssn_extrema.csv
204
+ assert str(called_path).endswith("ssn_extrema.csv")
205
+ assert "sunspot_number" in str(called_path)
206
+
207
+ def test_data_format_after_loading(self):
208
+ """Test that data has correct format after loading."""
209
+ with (
210
+ patch("pandas.read_csv") as mock_read_csv,
211
+ patch("pathlib.Path.exists", return_value=True),
212
+ ):
213
+
214
+ # Mock the CSV reading and processing
215
+ raw_data = pd.DataFrame(
216
+ {
217
+ "Min": ["2008-12-01", "2019-12-01"],
218
+ "Max": ["2014-04-01", "2025-07-01"],
219
+ },
220
+ index=[24, 25],
221
+ )
222
+
223
+ processed_data = pd.DataFrame(
224
+ {
225
+ "Min": [pd.Timestamp("2008-12-01"), pd.Timestamp("2019-12-01")],
226
+ "Max": [pd.Timestamp("2014-04-01"), pd.Timestamp("2025-07-01")],
227
+ },
228
+ index=[24, 25],
229
+ )
230
+ processed_data.columns.names = ["kind"]
231
+
232
+ mock_read_csv.return_value = raw_data
233
+
234
+ # Mock the datetime conversion process
235
+ with patch("solarwindpy.solar_activity.sunspot_number.sidc.pd.to_datetime") as mock_to_datetime:
236
+ # Mock stack operation
237
+ stacked_data = pd.Series(
238
+ ["2008-12-01", "2014-04-01", "2019-12-01", "2025-07-01"]
239
+ )
240
+
241
+ # Mock to_datetime to return datetime series
242
+ datetime_series = pd.Series(
243
+ [
244
+ pd.Timestamp("2008-12-01"),
245
+ pd.Timestamp("2014-04-01"),
246
+ pd.Timestamp("2019-12-01"),
247
+ pd.Timestamp("2025-07-01"),
248
+ ]
249
+ )
250
+ mock_to_datetime.return_value = datetime_series
251
+
252
+ with (
253
+ patch.object(pd.DataFrame, "stack", return_value=stacked_data),
254
+ patch.object(pd.Series, "unstack", return_value=processed_data),
255
+ patch.object(SSNExtrema, "calculate_intervals"), # Skip interval calculation that uses "today"
256
+ ):
257
+
258
+ extrema = SSNExtrema()
259
+
260
+ # Verify data structure
261
+ assert hasattr(extrema, "_data")
262
+ assert extrema._data.columns.names == ["kind"]
263
+ assert "Min" in extrema._data.columns
264
+ assert "Max" in extrema._data.columns
265
+
266
+
267
+ class TestSSNExtremaEdgeCases:
268
+ """Test edge cases and error conditions for SSNExtrema."""
269
+
270
+ def test_file_not_found_handling(self):
271
+ """Test behavior when CSV file doesn't exist."""
272
+ with (
273
+ patch("pathlib.Path.exists", return_value=False),
274
+ patch("pandas.read_csv") as mock_read_csv,
275
+ ):
276
+
277
+ # read_csv should still be called even if file check fails
278
+ # (pandas will handle the FileNotFoundError)
279
+ mock_read_csv.side_effect = FileNotFoundError("File not found")
280
+
281
+ with pytest.raises(FileNotFoundError):
282
+ SSNExtrema()
283
+
284
+ def test_malformed_csv_handling(self):
285
+ """Test behavior with malformed CSV data."""
286
+ with (
287
+ patch("pandas.read_csv") as mock_read_csv,
288
+ patch("pathlib.Path.exists", return_value=True),
289
+ ):
290
+
291
+ # Simulate malformed CSV that causes parsing error
292
+ mock_read_csv.side_effect = pd.errors.ParserError("Malformed CSV")
293
+
294
+ with pytest.raises(pd.errors.ParserError):
295
+ SSNExtrema()
296
+
297
+ def test_empty_csv_handling(self):
298
+ """Test behavior with empty CSV data."""
299
+ with (
300
+ patch("pandas.read_csv") as mock_read_csv,
301
+ patch("pathlib.Path.exists", return_value=True),
302
+ ):
303
+
304
+ # Empty DataFrame
305
+ empty_data = pd.DataFrame()
306
+ mock_read_csv.return_value = empty_data
307
+
308
+ extrema = SSNExtrema.__new__(SSNExtrema)
309
+
310
+ # Should handle empty data gracefully (might raise error in stack/unstack)
311
+ try:
312
+ extrema.load_or_set_data()
313
+ except (ValueError, IndexError):
314
+ # These are acceptable errors for empty data
315
+ pass
316
+
317
+ def test_invalid_date_format_handling(self):
318
+ """Test behavior with invalid date formats in CSV."""
319
+ with (
320
+ patch("pandas.read_csv") as mock_read_csv,
321
+ patch("pathlib.Path.exists", return_value=True),
322
+ ):
323
+
324
+ # Data with invalid date formats
325
+ invalid_data = pd.DataFrame(
326
+ {
327
+ "Min": ["invalid-date", "1976-03-01"],
328
+ "Max": ["1968-11-01", "another-invalid-date"],
329
+ },
330
+ index=[20, 21],
331
+ )
332
+ mock_read_csv.return_value = invalid_data
333
+
334
+ extrema = SSNExtrema.__new__(SSNExtrema)
335
+
336
+ # pandas.to_datetime should handle invalid dates (might raise error or coerce)
337
+ with patch("solarwindpy.solar_activity.sunspot_number.sidc.pd.to_datetime") as mock_to_datetime:
338
+ mock_to_datetime.side_effect = ValueError("Invalid date format")
339
+
340
+ with pytest.raises(ValueError):
341
+ extrema.load_or_set_data()
342
+
343
+ def test_class_name_in_error_message(self):
344
+ """Test that class name appears correctly in error messages."""
345
+ extrema = SSNExtrema.__new__(SSNExtrema)
346
+
347
+ # Test that the error message contains the correct class name
348
+ with pytest.raises(ValueError) as exc_info:
349
+ extrema.load_or_set_data("arg")
350
+
351
+ assert "SSNExtrema" in str(exc_info.value)
352
+
353
+ def test_method_signature_validation(self):
354
+ """Test that method accepts various argument patterns for validation."""
355
+ extrema = SSNExtrema.__new__(SSNExtrema)
356
+
357
+ # Test different argument patterns that should all raise errors
358
+ error_cases = [
359
+ (["arg1"], {}),
360
+ ([], {"key": "value"}),
361
+ (["arg1", "arg2"], {}),
362
+ (["arg"], {"key": "value"}),
363
+ ([], {"key1": "value1", "key2": "value2"}),
364
+ ]
365
+
366
+ for args, kwargs in error_cases:
367
+ with pytest.raises(
368
+ ValueError, match="SSNExtrema expects empty args and kwargs"
369
+ ):
370
+ extrema.load_or_set_data(*args, **kwargs)
371
+
372
+ def test_successful_initialization_creates_expected_attributes(self):
373
+ """Test that successful initialization creates expected attributes."""
374
+ with (
375
+ patch("pandas.read_csv") as mock_read_csv,
376
+ patch("pathlib.Path.exists", return_value=True),
377
+ ):
378
+
379
+ # Mock successful CSV loading
380
+ mock_data = pd.DataFrame(
381
+ {"Min": ["2008-12-01"], "Max": ["2014-04-01"]}, index=[24]
382
+ )
383
+
384
+ processed_data = pd.DataFrame(
385
+ {
386
+ "Min": [pd.Timestamp("2008-12-01")],
387
+ "Max": [pd.Timestamp("2014-04-01")],
388
+ },
389
+ index=[24],
390
+ )
391
+ processed_data.columns.names = ["kind"]
392
+
393
+ mock_read_csv.return_value = mock_data
394
+
395
+ with (
396
+ patch("pandas.to_datetime"),
397
+ patch.object(pd.DataFrame, "stack"),
398
+ patch.object(pd.Series, "unstack", return_value=processed_data),
399
+ ):
400
+
401
+ extrema = SSNExtrema()
402
+
403
+ # Check that the object has expected attributes from parent class
404
+ assert hasattr(extrema, "_data")
405
+ # IndicatorExtrema parent should provide additional attributes
406
+ assert hasattr(extrema, "data") # Property from parent