solarwindpy 0.0.1.dev0__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of solarwindpy might be problematic. Click here for more details.

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.1.dist-info/METADATA +181 -0
  341. solarwindpy-0.1.1.dist-info/RECORD +409 -0
  342. {solarwindpy-0.0.1.dev0.dist-info → solarwindpy-0.1.1.dist-info}/WHEEL +1 -1
  343. solarwindpy-0.1.1.dist-info/licenses/LICENSE.rst +32 -0
  344. solarwindpy-0.1.1.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,794 @@
1
+ #!/usr/bin/env python
2
+ r"""Special labels not handled by :py:class:`TeXlabel`."""
3
+ import pdb # noqa: F401
4
+ from pathlib import Path
5
+ from string import Template as StringTemplate
6
+ from string import Formatter as StringFormatter
7
+ from abc import abstractmethod
8
+ from . import base
9
+
10
+
11
+ class ArbitraryLabel(base.Base):
12
+ """Abstract base class for custom labels."""
13
+
14
+ def __init__(self):
15
+ super().__init__()
16
+
17
+ @abstractmethod
18
+ def __str__(self):
19
+ pass
20
+
21
+
22
+ # @abstractproperty
23
+ # def tex(self):
24
+ # pass
25
+
26
+ # @abstractproperty
27
+ # def path(self):
28
+ # pass
29
+
30
+
31
+ class ManualLabel(ArbitraryLabel):
32
+ r"""Label defined by raw LaTeX text and unit."""
33
+
34
+ def __init__(self, tex, unit, path=None):
35
+ super().__init__()
36
+ self.set_tex(tex)
37
+ self.set_unit(unit)
38
+ self._path = path
39
+
40
+ def __str__(self):
41
+ return (
42
+ r"$\mathrm{%s} \; [%s]$"
43
+ % (
44
+ self.tex.replace(" ", r" \; "),
45
+ self.unit,
46
+ )
47
+ ).replace(r"\; []", "")
48
+
49
+ @property
50
+ def tex(self):
51
+ return self._tex
52
+
53
+ @property
54
+ def unit(self):
55
+ return self._unit
56
+
57
+ @property
58
+ def path(self):
59
+ path = self._path
60
+ if path is None:
61
+ path = self.tex.replace(" ", "-")
62
+ path = Path(path)
63
+ return path
64
+
65
+ def set_tex(self, tex):
66
+ self._tex = tex.strip("$")
67
+
68
+ def set_unit(self, unit):
69
+ unit = base._inU.get(unit, unit)
70
+ self._unit = unit.strip("$")
71
+
72
+
73
+ class Vsw(base.Base):
74
+ """Solar wind speed."""
75
+
76
+ def __init__(self):
77
+ super().__init__()
78
+
79
+ # def __str__(self):
80
+ # return r"$%s \; [\mathrm{km \, s^{-1}}]$" % self.tex
81
+
82
+ @property
83
+ def tex(self):
84
+ return r"V_\mathrm{SW}"
85
+
86
+ @property
87
+ def units(self):
88
+ return r"\mathrm{km \, s^{-1}}"
89
+
90
+ @property
91
+ def path(self):
92
+ return Path("vsw")
93
+
94
+
95
+ class CarringtonRotation(ArbitraryLabel):
96
+ """Carrington rotation count."""
97
+
98
+ def __init__(self, short_label=True):
99
+ """Instantiate the label."""
100
+ super().__init__()
101
+ self._short_label = bool(short_label)
102
+
103
+ def __str__(self):
104
+ return r"$%s \; [\#]$" % self.tex
105
+
106
+ @property
107
+ def short_label(self):
108
+ return self._short_label
109
+
110
+ @property
111
+ def tex(self):
112
+ if self.short_label:
113
+ return r"\mathrm{CR}"
114
+ else:
115
+ return r"\mathrm{Carrington \; Rotation}"
116
+
117
+ @property
118
+ def path(self):
119
+ return Path("CarrRot")
120
+
121
+
122
+ class Count(ArbitraryLabel):
123
+ """Count histogram label."""
124
+
125
+ def __init__(self, norm=None):
126
+ super().__init__()
127
+ self.set_axnorm(norm)
128
+ self.build_label()
129
+
130
+ def __str__(self):
131
+ return r"${} \; [{}]$".format(self.tex, self.units)
132
+
133
+ @property
134
+ def tex(self):
135
+ return self._tex
136
+
137
+ @property
138
+ def units(self):
139
+ return r"\#"
140
+
141
+ @property
142
+ def path(self):
143
+ return self._path
144
+
145
+ @property
146
+ def axnorm(self):
147
+ return self._axnorm
148
+
149
+ def set_axnorm(self, norm):
150
+ if norm is not None:
151
+ norm = norm.lower()
152
+
153
+ assert norm in base._trans_axnorm.keys()
154
+ self._axnorm = norm
155
+
156
+ def _build_tex(self):
157
+ axnorm = self.axnorm
158
+ if axnorm:
159
+ if axnorm in ("r", "c", "t"):
160
+ tex = r"\mathrm{%s Norm Count}" % base._trans_axnorm.get(axnorm)
161
+ elif axnorm == "cd":
162
+ tex = r"\mathrm{1D Probability Density}"
163
+ elif axnorm == "rd":
164
+ tex = r"\mathrm{1D Probability Density}"
165
+ elif axnorm == "d":
166
+ tex = r"\mathrm{Probability Density}"
167
+ else:
168
+ raise ValueError(f"Unrecognized axis normalization `{axnorm}`")
169
+ else:
170
+ tex = r"\mathrm{Count}"
171
+
172
+ return tex.replace(" ", r" \, ")
173
+
174
+ def _build_path(self):
175
+ path = Path("count")
176
+
177
+ norm = self.axnorm
178
+ if norm is not None:
179
+ path = path / (norm.upper() + "norm")
180
+
181
+ return path
182
+
183
+ def build_label(self):
184
+ self._tex = self._build_tex()
185
+ self._path = self._build_path()
186
+
187
+
188
+ class Power(ArbitraryLabel):
189
+ """Power spectrum label."""
190
+
191
+ def __init__(self):
192
+ super().__init__()
193
+
194
+ def __str__(self):
195
+ return rf"${self.tex} \; [{self.units}]$"
196
+
197
+ @property
198
+ def tex(self):
199
+ return r"\mathrm{Power}"
200
+
201
+ @property
202
+ def units(self):
203
+ return base._inU["dimless"]
204
+
205
+ @property
206
+ def path(self):
207
+ return Path("power")
208
+
209
+
210
+ class Probability(ArbitraryLabel):
211
+ """Probability that a quantity meets a comparison criterion."""
212
+
213
+ def __init__(self, other_label, comparison=None):
214
+ """Instantiate the label."""
215
+ super().__init__()
216
+ self.set_other_label(other_label)
217
+ self.set_comparison(comparison)
218
+ self.build_label()
219
+
220
+ def __str__(self):
221
+ return r"${} \; [{}]$".format(self.tex, self.units)
222
+
223
+ @property
224
+ def tex(self):
225
+ return self._tex
226
+
227
+ @property
228
+ def units(self):
229
+ return r"\%"
230
+
231
+ @property
232
+ def path(self):
233
+ return self._path
234
+
235
+ @property
236
+ def other_label(self):
237
+ return self._other_label
238
+
239
+ @property
240
+ def comparison(self):
241
+ return self._comparison
242
+
243
+ def set_other_label(self, other):
244
+ assert isinstance(other, (str, base.Base))
245
+ self._other_label = other
246
+
247
+ def set_comparison(self, new):
248
+ if new is None:
249
+ new = ""
250
+ self._comparison = str(new)
251
+
252
+ def _build_tex(self):
253
+ other = self.other_label
254
+ tex = r"\mathrm{Prob.}(%s %s)" % (other.tex, self.comparison)
255
+
256
+ self._tex = tex.replace(" ", r" \, ")
257
+
258
+ def _build_path(self):
259
+ other = self.other_label
260
+ other = str(other.path)
261
+ other = other.replace(" ", "-")
262
+
263
+ comp = (
264
+ self.comparison.replace(">", "GT")
265
+ .replace("<", "LT")
266
+ .replace(r"\gt", "GT")
267
+ .replace(r"\lt", "GT")
268
+ .replace(r"\geq", "GEQ")
269
+ .replace(r"\leq", "LEQ")
270
+ .replace(r"\gt", "GT")
271
+ .replace(r"\neq", "NEQ")
272
+ .replace(r"\eq", "EQ")
273
+ .replace(r"==", "EQ")
274
+ .replace(r"!=", "NEQ")
275
+ .replace(r" ", "_")
276
+ )
277
+
278
+ path = Path(f"prob-{other}-{comp}")
279
+
280
+ self._path = path
281
+
282
+ def build_label(self):
283
+ self._build_tex()
284
+ self._build_path()
285
+
286
+
287
+ class CountOther(ArbitraryLabel):
288
+ """Count of samples of another label fulfilling a comparison."""
289
+
290
+ def __init__(self, other_label, comparison=None, new_line_for_units=False):
291
+ """Instantiate the label."""
292
+ super().__init__()
293
+ self.set_other_label(other_label)
294
+ self.set_comparison(comparison)
295
+ self.set_new_line_for_units(new_line_for_units)
296
+
297
+ self.build_label()
298
+
299
+ def __str__(self):
300
+ return r"${tex} {sep} [{units}]$".format(
301
+ tex=self.tex,
302
+ sep="$\n$" if self.new_line_for_units else r"\;",
303
+ units=self.units,
304
+ )
305
+
306
+ @property
307
+ def tex(self):
308
+ return self._tex
309
+
310
+ @property
311
+ def units(self):
312
+ return r"\#"
313
+
314
+ @property
315
+ def path(self):
316
+ return self._path
317
+
318
+ @property
319
+ def other_label(self):
320
+ return self._other_label
321
+
322
+ @property
323
+ def comparison(self):
324
+ return self._comparison
325
+
326
+ @property
327
+ def new_line_for_units(self):
328
+ return self._new_line_for_units
329
+
330
+ def set_new_line_for_units(self, new):
331
+ self._new_line_for_units = bool(new)
332
+
333
+ def set_other_label(self, other):
334
+ assert isinstance(other, (str, base.Base))
335
+ self._other_label = other
336
+
337
+ def set_comparison(self, new):
338
+ if new is None:
339
+ new = ""
340
+ self._comparison = str(new)
341
+
342
+ def _build_tex(self):
343
+ other = self.other_label
344
+ tex = r"\mathrm{Count.}(%s %s)" % (other.tex, self.comparison)
345
+
346
+ self._tex = tex.replace(" ", r" \, ")
347
+
348
+ def _build_path(self):
349
+ other = self.other_label
350
+ other = str(other.path)
351
+ other = other.replace(" ", "-")
352
+
353
+ comp = (
354
+ self.comparison.replace(">", "GT")
355
+ .replace("<", "LT")
356
+ .replace(r"\gt", "GT")
357
+ .replace(r"\lt", "GT")
358
+ .replace(r"\geq", "GEQ")
359
+ .replace(r"\leq", "LEQ")
360
+ .replace(r"\gt", "GT")
361
+ .replace(r"\neq", "NEQ")
362
+ .replace(r"\eq", "EQ")
363
+ .replace(r"==", "EQ")
364
+ .replace(r"!=", "NEQ")
365
+ )
366
+
367
+ path = Path(f"cnt-{other}-{comp}")
368
+
369
+ self._path = path
370
+
371
+ def build_label(self):
372
+ self._build_tex()
373
+ self._build_path()
374
+
375
+
376
+ class MathFcn(ArbitraryLabel):
377
+ """Math function applied to another label."""
378
+
379
+ def __init__(self, fcn, other_label, dimensionless=True, new_line_for_units=False):
380
+ """Instantiate the label."""
381
+ super().__init__()
382
+ self.set_other_label(other_label)
383
+ self.set_function(fcn)
384
+ self.set_dimensionless(dimensionless)
385
+ self.set_new_line_for_units(new_line_for_units)
386
+ self.build_label()
387
+
388
+ def __str__(self):
389
+ sep = "$\n$" if self.new_line_for_units else r"\;"
390
+ return rf"""${self.tex} {sep} \left[{self.units}\right]$"""
391
+
392
+ @property
393
+ def tex(self):
394
+ return self._tex
395
+
396
+ @property
397
+ def units(self):
398
+ if self.dimensionless:
399
+ return base._inU["dimless"]
400
+
401
+ return r"\mathrm{%s}\left(%s\right)" % (self.function, self.other_label.units)
402
+
403
+ @property
404
+ def path(self):
405
+ return self._path
406
+
407
+ @property
408
+ def other_label(self):
409
+ return self._other_label
410
+
411
+ @property
412
+ def function(self):
413
+ return self._function
414
+
415
+ @property
416
+ def dimensionless(self):
417
+ return self._dimensionless
418
+
419
+ @property
420
+ def new_line_for_units(self):
421
+ return self._new_line_for_units
422
+
423
+ def set_new_line_for_units(self, new):
424
+ self._new_line_for_units = bool(new)
425
+
426
+ def set_other_label(self, other):
427
+ assert isinstance(other, (str, base.Base))
428
+ self._other_label = other
429
+
430
+ def set_function(self, new):
431
+ if new is None:
432
+ new = ""
433
+ self._function = str(new)
434
+
435
+ def set_dimensionless(self, new):
436
+ self._dimensionless = bool(new)
437
+
438
+ def _build_tex(self):
439
+ # try:
440
+ # tex = other.tex
441
+ # except AttributeError:
442
+ tex = r"\mathrm{%s}(%s)" % (self.function, self.other_label.tex)
443
+
444
+ return tex.replace(" ", r" \, ")
445
+
446
+ def _build_path(self):
447
+ other = self.other_label
448
+ other = str(other.path)
449
+ # fcn = self.function
450
+ fcn = (
451
+ self.function.replace(r"\mathrm", "")
452
+ .replace("{", "")
453
+ .replace("}", "")
454
+ .replace("\\", "")
455
+ .replace(r"/", "-OV-")
456
+ )
457
+
458
+ path = Path(f"{fcn}-{other}")
459
+
460
+ return path
461
+
462
+ def build_label(self):
463
+ self._tex = self._build_tex()
464
+ self._path = self._build_path()
465
+
466
+
467
+ class Distance2Sun(ArbitraryLabel):
468
+ """Distance to the Sun."""
469
+
470
+ def __init__(self, units):
471
+ super().__init__()
472
+ self.set_units(units)
473
+
474
+ def __str__(self):
475
+ return r"$%s \; [\mathrm{%s}]$" % (self.tex, self.units)
476
+
477
+ @property
478
+ def units(self):
479
+ return self._units
480
+
481
+ @property
482
+ def path(self):
483
+ return Path("distance2sun")
484
+
485
+ @property
486
+ def tex(self):
487
+ return r"\mathrm{Distance \; to \; Sun}"
488
+
489
+ def set_units(self, units):
490
+ units = units.lower()
491
+ trans = {"rs": r"R_{\bigodot}", "re": r"R_{\oplus}", "au": r"\mathrm{AU}"}
492
+ units = trans.get(units, units)
493
+
494
+ if units not in [*trans.values()] + ["m", "km"]:
495
+ raise NotImplementedError("Unrecognized distance2sun units %s" % units)
496
+
497
+ self._units = units
498
+
499
+
500
+ class SSN(ArbitraryLabel):
501
+ """Sunspot number label."""
502
+
503
+ def __init__(self, key):
504
+ super().__init__()
505
+ self.set_kind(key)
506
+
507
+ def __str__(self):
508
+ return r"$%s \; [\#]$" % self.tex
509
+
510
+ @property
511
+ def kind(self):
512
+ return self._kind
513
+
514
+ @property
515
+ def path(self):
516
+ return self._path
517
+
518
+ @property
519
+ def pretty_kind(self):
520
+ kind = self.kind
521
+ transform = {
522
+ "M": "Monthly",
523
+ "M13": "13 Month Smoothed",
524
+ "D": "Daily",
525
+ "Y": "Annual",
526
+ "NM": "Normalized Monthly",
527
+ "NM13": "Normalized 13 Month Smoothed",
528
+ "ND": "Normalized Daily",
529
+ "NY": "Normalized Yearly",
530
+ }
531
+ return transform[kind]
532
+
533
+ @property
534
+ def tex(self):
535
+ return (r"\mathrm{%s SSN}" % self.pretty_kind).replace(" ", r" \; ")
536
+
537
+ @property
538
+ def units(self):
539
+ return base._inU["dimless"]
540
+
541
+ def set_kind(self, new):
542
+ new = new.upper()
543
+ assert new in ("M", "M13", "D", "Y", "NM", "NM13", "ND", "NY")
544
+ self._kind = new
545
+ self._path = Path(f"""{new.upper()!s}ssn""")
546
+
547
+
548
+ class ComparisonLable(ArbitraryLabel):
549
+ """Label comparing two other labels via a function."""
550
+
551
+ def __init__(self, labelA, labelB, fcn_name, fcn=None):
552
+ """Instantiate the label."""
553
+ super().__init__()
554
+ self.set_constituents(labelA, labelB)
555
+ self.set_function(fcn_name, fcn)
556
+ self.build_label()
557
+
558
+ def __str__(self):
559
+ return r"${} \; [{}]$".format(self.tex, self.units)
560
+
561
+ @property
562
+ def tex(self):
563
+ return self._tex
564
+
565
+ @property
566
+ def units(self):
567
+ return self._units
568
+
569
+ @property
570
+ def path(self):
571
+ return self._path
572
+
573
+ @property
574
+ def labelA(self):
575
+ return self._labelA
576
+
577
+ @property
578
+ def labelB(self):
579
+ return self._labelB
580
+
581
+ @property
582
+ def function(self):
583
+ return self._function
584
+
585
+ @property
586
+ def function_name(self):
587
+ r"""Basically for use with building :py:meth:`path`."""
588
+ return self._function_name
589
+
590
+ def set_constituents(self, labelA, labelB):
591
+ if not isinstance(labelA, (str, base.Base)):
592
+ raise TypeError
593
+ if not isinstance(labelB, (str, base.Base)):
594
+ raise TypeError
595
+
596
+ if (
597
+ hasattr(labelA, "units")
598
+ and hasattr(labelB, "units")
599
+ and not (labelA.units == labelB.units)
600
+ ):
601
+ raise ValueError(
602
+ rf"""If both {self.__class__.__name__} labels have units, they must be the same.
603
+ labelA : {labelA.units}
604
+ labelB : {labelB.units}
605
+ """
606
+ )
607
+ elif hasattr(labelA, "units") and hasattr(labelB, "units"):
608
+ units = labelA.units
609
+
610
+ else:
611
+ units = "???"
612
+
613
+ self._labelA = labelA
614
+ self._labelB = labelB
615
+ self._units = units
616
+
617
+ def set_function(self, fcn_name, fcn):
618
+
619
+ if fcn is None:
620
+ get_fcn = fcn_name.lower()
621
+ translate = {
622
+ "subtract": r"{$labelA} - {$labelB}",
623
+ "add": r"{$labelA} + {$labelB}",
624
+ "multiply": r"{$labelA} \times {$labelB}",
625
+ }
626
+ fcn = translate.get(get_fcn)
627
+
628
+ keys = [x[1] for x in StringFormatter().parse(fcn)]
629
+ if not (("$labelA" in keys) and ("$labelB" in keys)):
630
+ raise ValueError(
631
+ rf"""{self.__class__.__name__}'s function must have the keys "$labelA" and "$labelB".
632
+ keys : {",".join(keys)}
633
+ """
634
+ )
635
+ self._function = fcn
636
+ self._function_name = fcn_name
637
+
638
+ def _build_tex(self):
639
+ labelA = self.labelA
640
+ labelB = self.labelB
641
+ function = self.function
642
+
643
+ try:
644
+ texA = labelA.tex
645
+ except AttributeError:
646
+ texA = labelA
647
+
648
+ try:
649
+ texB = labelB.tex
650
+ except AttributeError:
651
+ texB = labelB
652
+
653
+ template = StringTemplate(function)
654
+ tex = template.safe_substitute(labelA=texA, labelB=texB)
655
+
656
+ while tex.find(r"\,\,") >= 0:
657
+ tex = tex.replace(r"\,\,", r"\,")
658
+
659
+ self._tex = tex
660
+
661
+ def _build_path(self):
662
+ labelA = self.labelA
663
+ labelB = self.labelB
664
+
665
+ try:
666
+ pathA = labelA.path
667
+ except AttributeError:
668
+ pathA = labelA
669
+
670
+ try:
671
+ pathB = labelB.path
672
+ except AttributeError:
673
+ pathB = labelB
674
+
675
+ pathA = str(pathA).replace(" ", "-")
676
+ pathB = str(pathB).replace(" ", "-")
677
+
678
+ function = self.function_name
679
+ path = Path(f"{function}-{pathA}-{pathB}")
680
+
681
+ self._path = path
682
+
683
+ def build_label(self):
684
+ self._build_tex()
685
+ self._build_path()
686
+
687
+
688
+ class Xcorr(ArbitraryLabel):
689
+ """Cross-correlation coefficient between two labels."""
690
+
691
+ def __init__(self, labelA, labelB, method, short_tex=False):
692
+ """Instantiate the label."""
693
+ super().__init__()
694
+ self.set_constituents(labelA, labelB)
695
+ self.set_method(method)
696
+ self.set_short_tex(short_tex)
697
+ self.build_label()
698
+
699
+ def __str__(self):
700
+ return r"${} \; [{}]$".format(self.tex, self.units)
701
+
702
+ @property
703
+ def tex(self):
704
+ return self._tex
705
+
706
+ @property
707
+ def units(self):
708
+ return r"\#"
709
+
710
+ @property
711
+ def short_tex(self):
712
+ return self._short_tex
713
+
714
+ @property
715
+ def path(self):
716
+ return self._path
717
+
718
+ @property
719
+ def labelA(self):
720
+ return self._labelA
721
+
722
+ @property
723
+ def labelB(self):
724
+ return self._labelB
725
+
726
+ @property
727
+ def method(self):
728
+ return self._method
729
+
730
+ def set_constituents(self, labelA, labelB):
731
+ if not isinstance(labelA, (str, base.Base)):
732
+ raise TypeError
733
+ if not isinstance(labelB, (str, base.Base)):
734
+ raise TypeError
735
+
736
+ self._labelA = labelA
737
+ self._labelB = labelB
738
+
739
+ def set_method(self, new):
740
+ self._method = str(new).title()
741
+
742
+ def set_short_tex(self, new):
743
+ self._short_tex = bool(new)
744
+
745
+ def _build_tex(self):
746
+ labelA = self.labelA
747
+ labelB = self.labelB
748
+
749
+ try:
750
+ texA = labelA.tex
751
+ except AttributeError:
752
+ texA = labelA
753
+
754
+ try:
755
+ texB = labelB.tex
756
+ except AttributeError:
757
+ texB = labelB
758
+
759
+ if self.short_tex:
760
+ tex = r"\rho_{%s}(%s,%s)" % (self.method[0], texA, texB)
761
+ else:
762
+ tex = r"\mathrm{{%s}}(%s,%s)" % (self.method, texA, texB)
763
+
764
+ tex = tex.replace(" ", r" \, ").replace(r" \, ", r"\,")
765
+ while tex.find(r"\,\,") >= 0:
766
+ tex = tex.replace(r"\,\,", r"\,")
767
+
768
+ self._tex = tex
769
+
770
+ def _build_path(self):
771
+ labelA = self.labelA
772
+ labelB = self.labelB
773
+
774
+ try:
775
+ pathA = labelA.path
776
+ except AttributeError:
777
+ pathA = labelA
778
+
779
+ try:
780
+ pathB = labelB.path
781
+ except AttributeError:
782
+ pathB = labelB
783
+
784
+ pathA = str(pathA).replace(" ", "-")
785
+ pathB = str(pathB).replace(" ", "-")
786
+
787
+ method = self.method
788
+ path = Path(f"Xcorr{method}-{pathA}-{pathB}")
789
+
790
+ self._path = path
791
+
792
+ def build_label(self):
793
+ self._build_tex()
794
+ self._build_path()