PI
Extraction calculation
To calculate the amount extracted from the ESI PI endpoint is more complex then just pulling from the ESI and using the values, snippets below walk through calculating each stage with its variations.
Example
int[] CalculateExtractorValues() {
//Inputs - these are set from the API results.
//Note that all times are in seconds.
int duration = 171000; //1d 23h 30m; from API expiryTime-installTime
int cycleTime = 30 * 60; //30 minutes, value from API cycleTime * 60
int quantityPerCycle = 6965;
//These constants are the defaults in dgmAttributeTypes. They may change.
const float decayFactor = 0.012f; //Dogma attribute 1683 for this pin typeID
const float noiseFactor = 0.8f; //Dogma attribute 1687 for this pin typeID
int numIterations = duration / cycleTime;
float barWidth = cycleTime / 900f;
int[] values = new int[numIterations];
for (int i = 0; i < numIterations; i++) {
float t = (i + 0.5f)*barWidth;
float decayValue = quantityPerCycle/(1 + t * decayFactor);
double phaseShift = Math.Pow(quantityPerCycle, 0.7f);
double sinA = Math.Cos(phaseShift + t * (1/12f));
double sinB = Math.Cos(phaseShift / 2 + t * 0.2f);
double sinC = Math.Cos(t * 0.5f);
double sinStuff = Math.Max((sinA + sinB + sinC) / 3, 0);
double barHeight = decayValue * (1 + noiseFactor * sinStuff);
values[i] = (int) (barWidth * barHeight);
}
return values;
}
import java.time.Duration
import kotlin.math.*
private const val SEC = 10000000L
/**
* @param baseValue This is the "qty_per_cycle" value as returned by ESI
* @param cycleDuration Cycle duration, e.g. 2 hours
* @param length The number of cycles in this extraction
*/
fun calculateExtractorValues(baseValue: Int, cycleDuration: Duration, length: Int): List<Long> {
return buildList {
val startTime = 0L
val cycleTime = cycleDuration.toSeconds() * SEC
for (i in 0 until length) {
val currentTime = (i + 1) * cycleTime
add(calculateExtractorValue(baseValue, startTime, currentTime, cycleTime))
}
}
}
private fun calculateExtractorValue(baseValue: Int, startTime: Long, currentTime: Long, cycleTime: Long): Long {
val decayFactor = 0.012
val noiseFactor = 0.8
val cycleNum = max((currentTime - startTime + SEC) / cycleTime - 1, 0)
val barWidth = cycleTime / SEC / 900.0
val t = (cycleNum + 0.5) * barWidth
val decayValue = baseValue / (1 + t * decayFactor)
val phaseShift = baseValue.toDouble().pow(0.7)
val sinA = cos(phaseShift + t * (1.0 / 12.0))
val sinB = cos(phaseShift / 2.0 + t * (1.0 / 5.0))
val sinC = cos(t * (1.0 / 2.0))
val sinStuff = max(0.0, (sinA + sinB + sinC) / 3.0)
val barHeight = decayValue * (1 + noiseFactor * sinStuff)
val output = barWidth * barHeight
// Round down, with integers also rounded down (123.0 -> 122)
return if (output - output.toLong() == 0.0) output.toLong() - 1 else output.toLong()
}
import math
# These constants are the defaults in dgmAttributeTypes. They may change.
decay_factor = 0.012 # Dogma attribute 1683 for this pin typeID
noise_factor = 0.8 # Dogma attribute 1687 for this pin typeID
def calculateExtractorValues(total_cycles = 30, cycle_time = 30 * 60, qty_per_cycle = 6965):
"""
:param int total_cycles: End time in seconds - start time in seconds / cycle_time
:param int cycle_time: Cycle time, in seconds
:returns Generator[int]: A generaotr that iterates over all values
"""
bar_width = float(cycle_time) / 900.0
for cycle in range(0, total_cycles):
t = (cycle + 0.5) * bar_width
decay_value = qty_per_cycle / (1 + t * decay_factor)
phase_shift = pow(qty_per_cycle, 0.7)
sin_a = math.cos(phase_shift + t * (1 / 12))
sin_b = math.cos(phase_shift / 2 + t * 0.2)
sin_c = math.cos(t * 0.5)
sin_stuff = max((sin_a + sin_b + sin_c) / 3, 0)
bar_height = decay_value * (1 + noise_factor * sin_stuff)
yield bar_width * bar_height