From 4c53d4ec7e66251fa7aa7211e5af1fedd008545b Mon Sep 17 00:00:00 2001 From: Jackson Huse Date: Fri, 1 Nov 2024 13:20:13 -0400 Subject: [PATCH 1/4] Update deploy-development.yml --- .github/workflows/deploy-development.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-development.yml b/.github/workflows/deploy-development.yml index 9834c52..6391eac 100644 --- a/.github/workflows/deploy-development.yml +++ b/.github/workflows/deploy-development.yml @@ -61,6 +61,7 @@ jobs: # Run the Docker container with environment variables docker run -d --name fundna_dev \ + --restart always \ --network=jphuse_network \ -e MYSQLHOST=${{ secrets.MYSQLHOST }} \ -e MYSQLPORT=${{ secrets.MYSQLPORT }} \ From 64e57d5dd22293f139d417b05ee779ddf78b5faf Mon Sep 17 00:00:00 2001 From: Jacksonnnnn Date: Fri, 1 Nov 2024 16:55:59 -0400 Subject: [PATCH 2/4] Completed Piperine implementation --- gui/classes/PiperineObjects.py | 163 ++++++++- gui/pages/templates/partials/dna.html | 460 ++++++++++++++++++++++---- gui/templatetags/custom_filters.py | 28 ++ gui/views.py | 82 ++++- 4 files changed, 646 insertions(+), 87 deletions(-) diff --git a/gui/classes/PiperineObjects.py b/gui/classes/PiperineObjects.py index 2026aec..5b4ba0d 100644 --- a/gui/classes/PiperineObjects.py +++ b/gui/classes/PiperineObjects.py @@ -1,3 +1,5 @@ +import numpy as np + class Sequence: def __init__(self, name, seq): self.Name = name @@ -134,6 +136,32 @@ def WeightedSum(self): total += score * (weight / 100) return total + def Min(self, weighted=False): + min_score = None + min_test_name = None + for test_name, (score, weight) in self.ToDict().items(): + if score is None: + continue + # Apply weighting if specified + score_to_check = score * weight / 100 if weighted else score + if min_score is None or score_to_check < min_score: + min_score = score_to_check + min_test_name = test_name + return min_test_name, min_score + + def Max(self, weighted=False): + max_score = None + max_test_name = None + for test_name, (score, weight) in self.ToDict().items(): + if score is None: + continue + # Apply weighting if specified + score_to_check = score * weight / 100 if weighted else score + if max_score is None or score_to_check > max_score: + max_score = score_to_check + max_test_name = test_name + return max_test_name, max_score + class PiperineOutput: def __init__(self): @@ -148,13 +176,130 @@ def rank_values(self, values, reversed=False): rank_dict = {val: rank for rank, val in enumerate(unique_values)} return [rank_dict[v] for v in array] - # Worst-rank - # (weighted) - # Sum-of-ranks - # (weighted) - # Fractional-excess - # (weighted) - # Percent-badness - # (weighted) def MetaRanksArray(self): - rank_arrays = [design.RankArray.ToDict() for design in self.Designs] + meta_scores = { + "Design": [], + "Worst-rank": [], + "Worst-weighted-rank": [], + "Sum-of-ranks": [], + "Weighted Sum-of-ranks": [], + "Fractional-excess": [], + "Weighted Fractional-excess": [], + "Percent-badness": [], + "Weighted Percent-badness": [] + } + + for design in self.Designs: + # Calculate scores for each category + worst_rank = design.RankArray.Max()[1] + worst_weighted_rank = design.RankArray.Max(weighted=True)[1] + sum_of_ranks = design.RankArray.Sum() + weighted_sum_of_ranks = design.RankArray.WeightedSum() + fractional_excess = design.FractionalExcessArray.Sum() + weighted_fractional_excess = design.FractionalExcessArray.WeightedSum() + percent_badness = design.PercentBadnessArray.Sum() + weighted_percent_badness = design.PercentBadnessArray.WeightedSum() + + # Collect scores for ranking + meta_scores["Design"].append(design.Name) + meta_scores["Worst-rank"].append(worst_rank) + meta_scores["Worst-weighted-rank"].append(worst_weighted_rank) + meta_scores["Sum-of-ranks"].append(sum_of_ranks) + meta_scores["Weighted Sum-of-ranks"].append(weighted_sum_of_ranks) + meta_scores["Fractional-excess"].append(fractional_excess) + meta_scores["Weighted Fractional-excess"].append(weighted_fractional_excess) + meta_scores["Percent-badness"].append(percent_badness) + meta_scores["Weighted Percent-badness"].append(weighted_percent_badness) + + # Rank each design based on meta scores and add Meta Sum to ranked_meta_scores + ranked_meta_scores = {"Design": meta_scores["Design"]} + for category, scores in meta_scores.items(): + if category != "Design": + ranked_meta_scores[category] = self.rank_values(scores) + + # Calculate Meta Sum for each design + meta_ranks_sum = [ + sum(ranked_meta_scores[category][i] for category in ranked_meta_scores if category != "Design") + for i in range(len(self.Designs)) + ] + ranked_meta_scores["Meta Sum"] = meta_ranks_sum + + # Determine the best Meta Sum and best designs based on Meta Sum + best_meta_sum = min(meta_ranks_sum) + best_designs = [self.Designs[i].Name for i, sum_rank in enumerate(meta_ranks_sum) if sum_rank == best_meta_sum] + + # Debug output + print("Meta Scores:") + print(meta_scores) + print("Ranked Meta Scores:") + print(ranked_meta_scores) + print("Best Meta Sum:") + print(best_meta_sum) + print("Best Designs:") + print(best_designs) + + return meta_scores, ranked_meta_scores, best_meta_sum, best_designs + + def WorstRank(self): + scores = [design.RankArray.Max()[1] for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def WorstWeightedRank(self): + scores = [design.RankArray.Max(weighted=True)[1] for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def SumOfRanks(self): + scores = [design.RankArray.Sum() for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def WeightedSumOfRank(self): + scores = [design.RankArray.WeightedSum() for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def FractionalExcess(self): + scores = [design.FractionalExcessArray.Sum() for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def WeightedFractionalExcess(self): + scores = [design.FractionalExcessArray.WeightedSum() for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def PercentBadness(self): + scores = [design.PercentBadnessArray.Sum() for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) + + def WeightedPercentBadness(self): + scores = [design.PercentBadnessArray.WeightedSum() for design in self.Designs] + best_score = min(scores) + worst_score = max(scores) + best_design = [design.Name for design, score in zip(self.Designs, scores) if score == best_score] + worst_design = [design.Name for design, score in zip(self.Designs, scores) if score == worst_score] + return (best_score, best_design), (worst_score, worst_design) diff --git a/gui/pages/templates/partials/dna.html b/gui/pages/templates/partials/dna.html index 345c8a0..a0ad8d2 100644 --- a/gui/pages/templates/partials/dna.html +++ b/gui/pages/templates/partials/dna.html @@ -16,52 +16,305 @@

DNA Simulation Results (Piperine)

-
Raw Scores
-
- - - - - {% for score_name, score in piperine_output.Designs.0.RawScores.ToDict.items %} - - {% endfor %} - - - - {% for design in piperine_output.Designs %} - - - {% for score_name, score in design.RawScores.ToDict.items %} - + +
+

🏆 Best Design(s) 🏆

+

+ {{ piperine_output.MetaRanksArray.3|join:", " }} achieved the most optimal meta ranking with a score of + {{ piperine_output.MetaRanksArray.2 }} +

+
+
+ + +
+

Meta Ranking Summary

+ + +
+
Meta Array Table
+
+
Design Name{{ score_name }}
{{ design.Name }}{{ score.0|default:"N/A" }}
+ + + + + + + + + + + + + + + + {% for row in transposed_scores %} + + {% for cell in row %} + + {% endfor %} + {% endfor %} - - {% endfor %} - -
Design NameMeta SumWorst-rankWorst-weighted-rankSum-of-ranksWeighted Sum-of-ranksFractional-excessWeighted Fractional-excessPercent-badnessWeighted Percent-badness
{{ cell|format_meta_cell }}
+ + +
+
+ + +
+
Best and Worst for Each Category
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryBestWorst
Worst-rank{{ piperine_output.WorstRank.0|score_and_rank }}{{ piperine_output.WorstRank.1|score_and_rank }}
Worst-weighted-rank{{ piperine_output.WorstWeightedRank.0|score_and_rank }}{{ piperine_output.WorstWeightedRank.1|score_and_rank }}
Sum-of-ranks{{ piperine_output.SumOfRanks.0|score_and_rank }}{{ piperine_output.SumOfRanks.1|score_and_rank }}
Weighted Sum-of-ranks{{ piperine_output.WeightedSumOfRank.0|score_and_rank }}{{ piperine_output.WeightedSumOfRank.1|score_and_rank }}
Fractional-excess{{ piperine_output.FractionalExcess.0|score_and_rank }}{{ piperine_output.FractionalExcess.1|score_and_rank }}
Weighted Fractional-excess{{ piperine_output.WeightedFractionalExcess.0|score_and_rank }}{{ piperine_output.WeightedFractionalExcess.1|score_and_rank }}
Percent-badness{{ piperine_output.PercentBadness.0|score_and_rank }}{{ piperine_output.PercentBadness.1|score_and_rank }}
Weighted Percent-badness{{ piperine_output.WeightedPercentBadness.0|score_and_rank }}{{ piperine_output.WeightedPercentBadness.1|score_and_rank }}
+
+

-
Weighted Scores
-
- - - - - {% for score_name, score in piperine_output.Designs.0.RawScores.ToDict.items %} - - {% endfor %} - - - - {% for design in piperine_output.Designs %} - - - {% for score_name, score in design.RawScores.ToDict.items %} - + + +
+

Raw Scores

+
+
Raw & Weighted Scores of Each Piperine Design
+
+
Design Name{{ score_name }}
{{ design.Name }}{{ score|weighted_score }}
+ + + + {% for score_name, score in piperine_output.Designs.0.RawScores.ToDict.items %} + + {% endfor %} + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.RawScores.ToDict.items %} + {% if score.0 is not None %} + + {% else %} + + {% endif %} + {% endfor %} + {% endfor %} - - {% endfor %} - -
Design Name{{ score_name }}
{{ design.Name }}{{ score.0 }}N/A
+ + + + + + {% for design in piperine_output.Designs %} + + {{ design.Name }} (Weighted) + {% for score_name, score in design.RawScores.ToDict.items %} + {{ score|weighted_score }} + {% endfor %} + + {% endfor %} + + +
+ + +
+ + +
+

Rank Array

+
+
Ranked & Weighted-Ranked Scores of Each Piperine Design
+
+ + + + + {% for score_name, score in piperine_output.Designs.0.RankArray.ToDict.items %} + + {% endfor %} + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.RankArray.ToDict.items %} + {% if score.0 is not None %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.RankArray.ToDict.items %} + + {% endfor %} + + {% endfor %} + +
Design Name{{ score_name }}
{{ design.Name }}{{ score.0 }}N/A
{{ design.Name }} (Weighted){{ score|weighted_score }}
+
+
+
+
+ + +
+

Fractional Excess Array

+
+
Fractional Excess & Weighted Fractional Excess Scores of Each Piperine Design
+
+ + + + + {% for score_name, score in piperine_output.Designs.0.FractionalExcessArray.ToDict.items %} + + {% endfor %} + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.FractionalExcessArray.ToDict.items %} + {% if score.0 is not None %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.FractionalExcessArray.ToDict.items %} + + {% endfor %} + + {% endfor %} + +
Design Name{{ score_name }}
{{ design.Name }}{{ score.0 }}N/A
{{ design.Name }} (Weighted){{ score|weighted_score }}
+
+
+
+
+ + +
+

Percent Badness Array

+
+
Percent Badness & Weighted Percent Badness Scores of Each Piperine Design
+
+ + + + + {% for score_name, score in piperine_output.Designs.0.PercentBadnessArray.ToDict.items %} + + {% endfor %} + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.PercentBadnessArray.ToDict.items %} + {% if score.0 is not None %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + + + + + + {% for design in piperine_output.Designs %} + + + {% for score_name, score in design.PercentBadnessArray.ToDict.items %} + + {% endfor %} + + {% endfor %} + +
Design Name{{ score_name }}
{{ design.Name }}{{ score.0 }}N/A
{{ design.Name }} (Weighted){{ score|weighted_score }}
+
+
@@ -71,32 +324,38 @@
Weighted Scores

{{ design.Name }}

-
Raw Scores
-
- - - - - {% for score_name, score in piperine_output.Designs.0.RawScores.ToDict.items %} - - {% endfor %} - - - - - - {% for score_name, score in design.RawScores.ToDict.items %} - - {% endfor %} - +
+
Raw & Weighted Scores for {{ design.Name }}
+
+
Type{{ score_name }}
Raw{{ score.0|default:"N/A" }}
+ - - {% for score_name, score in design.RawScores.ToDict.items %} - + + {% for score_name, score in piperine_output.Designs.0.RawScores.ToDict.items %} + {% endfor %} - -
Weighted{{ score|weighted_score }}Type{{ score_name }}
+ + + + Raw + {% for score_name, score in design.RawScores.ToDict.items %} + {% if score.0 is not None %} + {{ score.0 }} + {% else %} + N/A + {% endif %} + {% endfor %} + + + Weighted + {% for score_name, score in design.RawScores.ToDict.items %} + {{ score|weighted_score }} + {% endfor %} + + + +

@@ -189,6 +448,10 @@
{{ complex.Name }} {% if complex.IsFuel %}(Fuel Cmp.){% endif %}
--bs-table-color-type: var(--bs-table-striped-color); --bs-table-bg-type: var(--bs-table-striped-bg); } + + .table-divider td { + padding: 0 !important; + } + + +