# ============================================================================= # Copyright (C) 2026 # # This file is part of pyfa. # # pyfa is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # pyfa is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with pyfa. If not, see . # ============================================================================= from eos.const import FittingSlot from graphs.data.base import SmoothPointGetter from .calc import get_first_burnout_samples, get_rack_heat_value class _BaseTime2RackHeatGetter(SmoothPointGetter): rack_slot = None def _getCommonData(self, miscParams, src, tgt): return {"fit": src.item} def _calculatePoint(self, x, miscParams, src, tgt, commonData): fit = commonData["fit"] heat_value = get_rack_heat_value(fit, self.rack_slot, x) return heat_value * 100.0 class Time2RackHeatHiGetter(_BaseTime2RackHeatGetter): rack_slot = FittingSlot.HIGH class Time2RackHeatMedGetter(_BaseTime2RackHeatGetter): rack_slot = FittingSlot.MED class Time2RackHeatLowGetter(_BaseTime2RackHeatGetter): rack_slot = FittingSlot.LOW class _BaseTime2BurnoutCdfGetter(SmoothPointGetter): rack_slot = None _iterations = 200 def getRange(self, xRange, miscParams, src, tgt): fit = src.item # Fixed simulation horizon so CDF does not depend on view range max_sim_time = self.graph._limiters["time"](src, tgt)[1] iterations = miscParams.get("iterations", self._iterations) try: iterations = int(iterations) except (TypeError, ValueError): iterations = self._iterations if iterations <= 0: iterations = self._iterations samples = get_first_burnout_samples( fit=fit, rack_slot=self.rack_slot, max_time_s=max_sim_time, iterations=iterations ) xs = [] ys = [] if not samples: for x in self._xIterLinear(xRange): xs.append(x) ys.append(0.0) return xs, ys samples = sorted(samples) total = float(len(samples)) index = 0 for x in self._xIterLinear(xRange): while index < len(samples) and samples[index] <= x: index += 1 xs.append(x) ys.append(index / total) return xs, ys def _calculatePoint(self, x, miscParams, src, tgt, commonData): return self.getPoint(x=x, miscParams=miscParams, src=src, tgt=tgt) def getPoint(self, x, miscParams, src, tgt): fit = src.item max_sim_time = self.graph._limiters["time"](src, tgt)[1] iterations = miscParams.get("iterations", self._iterations) try: iterations = int(iterations) except (TypeError, ValueError): iterations = self._iterations if iterations <= 0: iterations = self._iterations samples = get_first_burnout_samples( fit=fit, rack_slot=self.rack_slot, max_time_s=max_sim_time, iterations=iterations ) if not samples: return 0.0 samples = sorted(samples) total = float(len(samples)) index = 0 while index < len(samples) and samples[index] <= x: index += 1 return index / total class Time2BurnoutCdfHiGetter(_BaseTime2BurnoutCdfGetter): rack_slot = FittingSlot.HIGH class Time2BurnoutCdfMedGetter(_BaseTime2BurnoutCdfGetter): rack_slot = FittingSlot.MED class Time2BurnoutCdfLowGetter(_BaseTime2BurnoutCdfGetter): rack_slot = FittingSlot.LOW