Upload stability_report_formatter.py
Browse files
utils/stability_report_formatter.py
CHANGED
|
@@ -326,8 +326,8 @@ class StabilityReportFormatter:
|
|
| 326 |
<!-- 4. Arrhenius & Trend Transfer -->
|
| 327 |
{StabilityReportFormatter._build_arrhenius_section(phase3)}
|
| 328 |
|
| 329 |
-
<!-- 5. Predictions
|
| 330 |
-
{StabilityReportFormatter._build_predictions_section(phase4)}
|
| 331 |
|
| 332 |
<!-- 6. Visualizations -->
|
| 333 |
{StabilityReportFormatter._build_charts_section(charts, phase4)}
|
|
@@ -591,6 +591,55 @@ class StabilityReportFormatter:
|
|
| 591 |
</div>
|
| 592 |
{steps_html}
|
| 593 |
</div>'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 594 |
|
| 595 |
@staticmethod
|
| 596 |
def _build_arrhenius_section(phase3: Dict) -> str:
|
|
|
|
| 326 |
<!-- 4. Arrhenius & Trend Transfer -->
|
| 327 |
{StabilityReportFormatter._build_arrhenius_section(phase3)}
|
| 328 |
|
| 329 |
+
<!-- 5. Predictions / Ranking -->
|
| 330 |
+
{StabilityReportFormatter._build_batch_ranking_section(phase4) if phase4.get("analysis_type") == "batch_ranking" else StabilityReportFormatter._build_predictions_section(phase4)}
|
| 331 |
|
| 332 |
<!-- 6. Visualizations -->
|
| 333 |
{StabilityReportFormatter._build_charts_section(charts, phase4)}
|
|
|
|
| 591 |
</div>
|
| 592 |
{steps_html}
|
| 593 |
</div>'''
|
| 594 |
+
|
| 595 |
+
@staticmethod
|
| 596 |
+
def _build_batch_ranking_section(phase4: Dict) -> str:
|
| 597 |
+
"""Build batch ranking section for multi-batch analysis."""
|
| 598 |
+
ranking = phase4.get("batch_ranking", [])
|
| 599 |
+
|
| 600 |
+
if not ranking:
|
| 601 |
+
return ""
|
| 602 |
+
|
| 603 |
+
rows = ""
|
| 604 |
+
for item in ranking:
|
| 605 |
+
rank = item.get("rank", "N/A")
|
| 606 |
+
batch_id = item.get("batch_id", "N/A")
|
| 607 |
+
score = item.get("score", "N/A")
|
| 608 |
+
reason = item.get("reason", "N/A")
|
| 609 |
+
|
| 610 |
+
# Highlight top rank
|
| 611 |
+
row_style = "background-color: #d4edda; font-weight:bold;" if str(rank) == "1" else ""
|
| 612 |
+
badge = '<span class="badge badge-success">推荐</span>' if str(rank) == "1" else ""
|
| 613 |
+
|
| 614 |
+
rows += f'''
|
| 615 |
+
<tr style="{row_style}">
|
| 616 |
+
<td style="font-size:18px; text-align:center;">{rank} {badge}</td>
|
| 617 |
+
<td>{batch_id}</td>
|
| 618 |
+
<td style="text-align:center;">{score}</td>
|
| 619 |
+
<td>{reason}</td>
|
| 620 |
+
</tr>'''
|
| 621 |
+
|
| 622 |
+
return f'''
|
| 623 |
+
<div class="section">
|
| 624 |
+
<div class="section-title">五、批次筛选与排名 (Batch Screening)</div>
|
| 625 |
+
<div class="alert alert-info">
|
| 626 |
+
<strong>🎯 目标:</strong> 根据稳定性数据表现,筛选最优批次。
|
| 627 |
+
</div>
|
| 628 |
+
|
| 629 |
+
<table>
|
| 630 |
+
<thead>
|
| 631 |
+
<tr>
|
| 632 |
+
<th style="width:15%">排名</th>
|
| 633 |
+
<th style="width:25%">批次 ID</th>
|
| 634 |
+
<th style="width:15%">稳定性评分</th>
|
| 635 |
+
<th>评价理由</th>
|
| 636 |
+
</tr>
|
| 637 |
+
</thead>
|
| 638 |
+
<tbody>
|
| 639 |
+
{rows}
|
| 640 |
+
</tbody>
|
| 641 |
+
</table>
|
| 642 |
+
</div>'''
|
| 643 |
|
| 644 |
@staticmethod
|
| 645 |
def _build_arrhenius_section(phase3: Dict) -> str:
|