/** * Calculate average Vertical Ratio * @return int [%o] */ public function average() { if (empty($this->VerticalRatio)) { return 0; } if (!$this->Trackdata->has(Trackdata\Entity::TIME)) { return round(array_sum($this->VerticalRatio) / $this->Trackdata->num()); } $Series = new TimeSeries($this->VerticalRatio, $this->Trackdata->time()); $Series->calculateStatistic(); return round($Series->mean()); }
/** * Calculate strides array * @return array */ public function calculate() { if (!$this->Trackdata->has(Trackdata\Entity::TIME) || !$this->Trackdata->has(Trackdata\Entity::DISTANCE) || !$this->Trackdata->has(Trackdata\Entity::CADENCE)) { return []; } $Time = $this->Trackdata->time(); $Distance = $this->Trackdata->distance(); $Cadence = $this->Trackdata->cadence(); $Size = $this->Trackdata->num(); $this->Strides[] = $Cadence[0] > 0 && $Time[0] > 0 ? round($Distance[0] * 1000 * 100 / ($Cadence[0] * 2 / 60 * $Time[0])) : 0; for ($i = 1; $i < $Size; ++$i) { $this->Strides[] = $Cadence[$i] > 0 && $Time[$i] - $Time[$i - 1] > 0 ? round(($Distance[$i] - $Distance[$i - 1]) * 1000 * 100 / ($Cadence[$i] * 2 / 60 * ($Time[$i] - $Time[$i - 1]))) : 0; } return $this->Strides; }
/** * Calculate by trackdata * @param \Runalyze\Model\Trackdata\Entity $trackdata */ public function calculateByTrackdata(Trackdata\Entity $trackdata) { if (!$trackdata->has(Trackdata\Entity::HEARTRATE)) { return; } return $this->calculateByHeartrate(new TimeSeries($trackdata->get(Trackdata\Entity::HEARTRATE), $trackdata->get(Trackdata\Entity::TIME))); }
/** * Update power for trackdata * @param array $powerData */ protected function updatePowerForTrackdata(array $powerData) { if (null !== $this->Trackdata && (empty($powerData) && $this->Trackdata->has(Model\Trackdata\Entity::POWER) || !empty($powerData) && !$this->Trackdata->has(Model\Trackdata\Entity::POWER))) { $this->Trackdata->set(Model\Trackdata\Entity::POWER, $powerData); $TrackdataUpdater = new Model\Trackdata\Updater($this->PDO); $TrackdataUpdater->setAccountID($this->AccountID); $TrackdataUpdater->update($this->Trackdata, array(Model\Trackdata\Entity::POWER)); } }
/** * Find limit for pauses */ protected function findLimitForPauses() { if (!is_null($this->Trackdata) && $this->Trackdata->has(Trackdata\Entity::DISTANCE)) { $SecondsForDist = (int) Configuration::ActivityView()->routeBreak()->value(); $AveragePace = $this->Trackdata->totalDistance() > 0 ? $this->Trackdata->totalTime() / $this->Trackdata->totalDistance() : 0; if ($AveragePace > 0) { $this->PauseLimit = max($this->PauseLimit, $SecondsForDist / $AveragePace); } } $this->PauseLimit *= (int) Configuration::ActivityView()->routePrecision()->value(); }
/** * Construct collector * @param \Runalyze\Model\Trackdata\Entity $trackdata * @param int $key * @param \Runalyze\Model\Swimdata\Entity $swimdata * @throws \InvalidArgumentException */ public function __construct(Trackdata $trackdata, $key, Swimdata $swimdata) { if (!$swimdata->has($key)) { throw new \InvalidArgumentException('Swimdata has no data for "' . $key . '".'); } $this->Key = $key; $this->Precision = Configuration::ActivityView()->plotPrecision(); $this->KnowsDistance = $trackdata->has(Trackdata::DISTANCE); $this->init($trackdata); $this->LoopSwimdata = new Loop($swimdata); $this->collect(); }
/** * Init data * @param \Runalyze\Model\Trackdata\Entity $trackdata * @param string $key * @param boolean $fillGaps try to fill gaps (zero values) */ protected function initData(Trackdata $trackdata, $key, $fillGaps = false) { if (!$trackdata->has($key)) { $this->Data = array(); return; } if ($fillGaps) { $this->fillGaps($trackdata, $key); } $Collector = new DataCollector($trackdata, $key); $this->Data = $Collector->data(); $this->XAxis = $Collector->xAxis(); }
/** * Construct time series for trackdata object * @param \Runalyze\Model\Trackdata\Entity $trackdata * @param int $indexKey enum * @param int[] $sumDifferencesKeys enums * @param int[] $avgValuesKeys enums * @throws \InvalidArgumentException */ public function __construct(Trackdata\Entity $trackdata, $indexKey, $sumDifferencesKeys = array(), $avgValuesKeys = array()) { $this->Trackdata = $trackdata; $this->IndexKey = $indexKey; $this->SumDifferencesKeys = $sumDifferencesKeys; $this->AvgValuesKeys = $avgValuesKeys; foreach (array_merge($sumDifferencesKeys, $avgValuesKeys) as $key) { if (!$trackdata->has($key)) { $trackdata->set($key, array_fill(0, $trackdata->num(), 0)); } } parent::__construct($trackdata->get($indexKey), $trackdata->get(Trackdata\Entity::TIME)); $this->collectData(); }
/** * Calculate trimp * @return int */ public function calculateTrimp() { if ($this->knowsTrackdata() && $this->Trackdata->has(Model\Trackdata\Entity::HEARTRATE)) { $Collector = new Trimp\DataCollector($this->Trackdata->heartRate(), $this->Trackdata->time()); $data = $Collector->result(); } elseif ($this->Activity->hrAvg() > 0) { $data = array($this->Activity->hrAvg() => $this->Activity->duration()); } else { $Factory = Context::Factory(); if ($this->Activity->typeid() > 0) { $data = array($Factory->type($this->Activity->typeid())->hrAvg() => $this->Activity->duration()); } else { $data = array($Factory->sport($this->Activity->sportid())->avgHR() => $this->Activity->duration()); } } $Athlete = Context::Athlete(); $Calculator = new Trimp\Calculator($Athlete, $data); return round($Calculator->value()); }
/** * Calculate power array * * A constant factor of 1.5 was used in previous versions - and I don't know why. * Without this factor results equal standard tools. * * @author Nils Frohberg * @author Hannes Christiansen * @see http://www.blog.ultracycle.net/2010/05/cycling-power-calculations * @param int $weight [kg] Weight of rider and bike * @param float $powerFactor constant factor * @return array */ public function calculate($weight = 75, $powerFactor = 1.0) { if (!$this->Trackdata->has(Trackdata\Entity::TIME) || !$this->Trackdata->has(Trackdata\Entity::DISTANCE)) { return []; } $everyNthPoint = ceil($this->Size / 1000); $n = $everyNthPoint; $grade = 0; $calcGrade = $this->knowsRoute() && $this->Route->hasElevations(); $ArrayTime = $this->Trackdata->time(); $ArrayDist = $this->Trackdata->distance(); $ArrayElev = $this->knowsRoute() ? $this->Route->elevations() : array(); $Frl = $weight * self::GRAVITY * self::CRR; $Fwpr = 0.5 * self::AREA * self::CW * $this->rho(); $Fslp = $weight * self::GRAVITY; for ($i = 0; $i < $this->Size - 1; $i++) { if ($i % $everyNthPoint == 0) { if ($i + $n > $this->Size - 1) { $n = $this->Size - $i - 1; } $distance = ($ArrayDist[$i + $n] - $ArrayDist[$i]) * 1000; $grade = $distance == 0 || !$calcGrade ? 0 : ($ArrayElev[$i + $n] - $ArrayElev[$i]) / $distance; } $distance = $ArrayDist[$i + 1] - $ArrayDist[$i]; $time = $ArrayTime[$i + 1] - $ArrayTime[$i]; if ($time > 0) { $Vmps = $distance * 1000 / $time; $Fw = $Fwpr * $Vmps * $Vmps; $Fsl = $Fslp * $grade; $this->Power[] = round(max($powerFactor * ($Frl + $Fw + $Fsl) * $Vmps, 0)); } else { $this->Power[] = 0; } } $this->Power[] = $this->Power[$this->Size - 2]; /* XXX */ return $this->Power; }
public function fillSwolfArray(Trackdata\Entity &$trackdata) { if ($this->stroke() && $trackdata->has(Trackdata\Entity::TIME)) { $TrackLoop = new Trackdata\Loop($trackdata); $Loop = new Loop($this); $max = $Loop->num(); $swolf = array(); $swolfcycles = array(); for ($i = 1; $i <= $max; ++$i) { $duration = $TrackLoop->difference(Trackdata\Entity::TIME); $swolf[] = $duration + $Loop->stroke(); $swolfcycles[] = $duration + $Loop->stroke() / 2; $Loop->nextStep(); $TrackLoop->nextStep(); } $this->set(Entity::SWOLF, $swolf); $this->set(Entity::SWOLFCYCLES, $swolfcycles); } }
/** * @param \Runalyze\Model\Trackdata\Entity $Object * @param array $AdditionalData */ protected function addTrackdataAveragesToDataFrom(Trackdata\Entity $Object, array &$AdditionalData) { $KeysToAverage = array(Activity\Entity::CADENCE => Trackdata\Entity::CADENCE, Activity\Entity::STRIDE_LENGTH => Trackdata\Entity::STRIDE_LENGTH, Activity\Entity::GROUNDCONTACT => Trackdata\Entity::GROUNDCONTACT, Activity\Entity::GROUNDCONTACT_BALANCE => Trackdata\Entity::GROUNDCONTACT_BALANCE, Activity\Entity::VERTICAL_OSCILLATION => Trackdata\Entity::VERTICAL_OSCILLATION, Activity\Entity::VERTICAL_RATIO => Trackdata\Entity::VERTICAL_RATIO, Activity\Entity::POWER => Trackdata\Entity::POWER); $NewLoop = new Trackdata\Loop($Object); $NewLoop->goToEnd(); foreach ($KeysToAverage as $objectKey => $trackdataKey) { if ($Object->has($trackdataKey)) { $AdditionalData[$objectKey] = $NewLoop->average($trackdataKey); } } }
/** * Define x-axis * @param \Runalyze\Model\Trackdata\Entity $trackdata */ protected function defineXAxis(Trackdata $trackdata) { if (Configuration::ActivityView()->usesTimeAsXAxis() && $trackdata->has(Trackdata::TIME) && $trackdata->totalTime() > 0) { $this->XAxis = self::X_AXIS_TIME; } elseif ($trackdata->has(Trackdata::DISTANCE) && $trackdata->totalDistance() > 0) { $this->XAxis = self::X_AXIS_DISTANCE; } elseif ($trackdata->has(Trackdata::TIME) && $trackdata->totalTime() > 0) { $this->XAxis = self::X_AXIS_TIME; } else { $this->XAxis = self::X_AXIS_INDEX; } }
/** * Calculate pace array * @param \Runalyze\Model\Trackdata\Entity $trackdata */ public function __construct(Trackdata\Entity $trackdata) { if ($trackdata->has(Trackdata\Entity::TIME) && $trackdata->has(Trackdata\Entity::DISTANCE)) { $this->Smoother = new PaceSmoother($trackdata, true); } }