public static function read_sensor()
 {
     // Determine current percentage for processor usage
     if (phodevi::is_linux() || phodevi::is_bsd()) {
         $start_load = self::cpu_load_array(-1);
         sleep(1);
         $end_load = self::cpu_load_array(-1);
         for ($i = 0; $i < count($end_load); $i++) {
             $end_load[$i] -= $start_load[$i];
         }
         $percent = ($sum = array_sum($end_load)) == 0 ? 0 : 100 - $end_load[count($end_load) - 1] * 100 / $sum;
     } else {
         if (phodevi::is_solaris()) {
             // TODO: Add support for monitoring load on a per-core basis (through mpstat maybe?)
             $info = explode(' ', pts_strings::trim_spaces(pts_arrays::last_element(explode("\n", trim(shell_exec('sar -u 1 1 2>&1'))))));
             $percent = $info[1] + $info[2];
         } else {
             if (phodevi::is_macosx()) {
                 // CPU usage for user
                 $top = shell_exec('top -n 1 -l 1 2>&1');
                 $top = substr($top, strpos($top, 'CPU usage: ') + 11);
                 $percent = substr($top, 0, strpos($top, '%'));
             } else {
                 $percent = null;
             }
         }
     }
     if (!is_numeric($percent) || $percent < 0 || $percent > 100) {
         $percent = -1;
     }
     return pts_math::set_precision($percent, 2);
 }
 public static function run($r)
 {
     define('PHOROMATIC_PROCESS', true);
     $commands = array('detailed_system_info' => null, 'list_available_tests' => null, 'list_available_suites' => null, 'info' => array('pts/all'), 'clone_openbenchmarking_result' => array('1107247-LI-MESACOMMI48', '1509040-HA-GCCINTELS17', '1508201-HA-GTX95073337', '1508233-HA-INTELSKYL16'), 'refresh_graphs' => array('1107247-LI-MESACOMMI48'), 'result_file_to_text' => array('1107247-LI-MESACOMMI48'), 'merge_results' => array('1107247-LI-MESACOMMI48', '1509040-HA-GCCINTELS17', '1508201-HA-GTX95073337', '1508233-HA-INTELSKYL16'), 'diagnostics' => null, 'dump_possible_options' => null, 'debug_render_test' => null);
     $individual_times = array();
     phodevi::clear_cache();
     $start = microtime(true);
     foreach ($commands as $command => $args) {
         echo PHP_EOL . '### ' . $command . ' ###' . PHP_EOL;
         $individual_times[$command] = array();
         for ($i = 0; $i < 3; $i++) {
             $c_start = microtime(true);
             pts_client::execute_command($command, $args);
             $c_finish = microtime(true);
             $individual_times[$command][] = $c_finish - $c_start;
         }
     }
     $finish = microtime(true);
     echo PHP_EOL . PHP_EOL . '### OVERALL DATA ###' . PHP_EOL . PHP_EOL;
     echo 'PHP:  ' . PTS_PHP_VERSION . PHP_EOL;
     $longest_c = max(array_map('strlen', array_keys($individual_times)));
     foreach ($individual_times as $component => $times) {
         echo strtoupper($component) . ': ' . str_repeat(' ', $longest_c - strlen($component)) . pts_math::set_precision(round(array_sum($times) / count($times), 3), 3) . ' seconds' . PHP_EOL;
     }
     echo PHP_EOL . 'TOTAL ELAPSED TIME: ' . str_repeat(' ', $longest_c - strlen('ELAPSED TIME')) . round($finish - $start, 3) . ' seconds';
     echo PHP_EOL . 'PEAK MEMORY USAGE: ' . str_repeat(' ', $longest_c - strlen('PEAK MEMORY USAGE')) . round(memory_get_peak_usage(true) / 1048576, 3) . ' MB';
     echo PHP_EOL . 'PEAK MEMORY USAGE EMALLOC: ' . str_repeat(' ', $longest_c - strlen('PEAK MEMORY USAGE (emalloc)')) . round(memory_get_peak_usage() / 1048576, 3) . ' MB';
     echo PHP_EOL;
 }
 public static function run($r)
 {
     $commands = array('detailed_system_info' => null, 'list_available_tests' => null, 'list_available_suites' => null, 'info' => array('xonotic'), 'clone_openbenchmarking_result' => array('1107247-LI-MESACOMMI48'), 'result_file_to_text' => array('1107247-LI-MESACOMMI48'), 'diagnostics' => null, 'dump_possible_options' => null);
     $individual_times = array();
     phodevi::clear_cache();
     $start = microtime(true);
     foreach ($commands as $command => $args) {
         echo PHP_EOL . '### ' . $command . ' ###' . PHP_EOL;
         $individual_times[$command] = array();
         for ($i = 0; $i < 3; $i++) {
             $c_start = microtime(true);
             pts_client::execute_command($command, $args);
             $c_finish = microtime(true);
             array_push($individual_times[$command], $c_finish - $c_start);
         }
     }
     $finish = microtime(true);
     echo PHP_EOL . PHP_EOL . '### OVERALL DATA ###' . PHP_EOL . PHP_EOL;
     echo 'PHP:  ' . PTS_PHP_VERSION . PHP_EOL;
     $longest_c = max(array_map('strlen', array_keys($individual_times)));
     foreach ($individual_times as $component => $times) {
         echo strtoupper($component) . ': ' . str_repeat(' ', $longest_c - strlen($component)) . pts_math::set_precision(round(array_sum($times) / count($times), 3), 3) . ' seconds' . PHP_EOL;
     }
     echo PHP_EOL . 'ELAPSED TIME: ' . str_repeat(' ', $longest_c - strlen('ELAPSED TIME')) . round($finish - $start, 3) . ' seconds';
     echo PHP_EOL . 'PEAK MEMORY USAGE: ' . str_repeat(' ', $longest_c - strlen('PEAK MEMORY USAGE')) . round(memory_get_peak_usage(true) / 1048576, 3) . ' MB';
     echo PHP_EOL . 'PEAK MEMORY USAGE (emalloc): ' . str_repeat(' ', $longest_c - strlen('PEAK MEMORY USAGE (emalloc)')) . round(memory_get_peak_usage() / 1048576, 3) . ' MB';
     echo PHP_EOL;
 }
 private function mem_usage_bsd($TYPE = 'TOTAL', $READ = 'USED')
 {
     $vmstats = explode("\n", shell_exec('vm_stat 2>&1'));
     // buffers_and_cache
     foreach ($vmstats as $vmstat_line) {
         $line_parts = pts_strings::colon_explode($vmstat_line);
         if (self::$page_size == -1) {
             strtok($vmstat_line, ':');
             $tok = strtok(' ');
             while (self::$page_size == -1) {
                 if (is_numeric($tok)) {
                     self::$page_size = $tok;
                 } else {
                     $tok = strtok(' ');
                 }
             }
             continue;
         }
         //$line_parts[1] = pts_strings::trim_spaces($line_parts[1]);
         $line_type = strtok($vmstat_line, ':');
         $line_value = strtok(' .');
         if ($TYPE == 'MEMORY') {
             if ($line_type == 'Pages active' && $READ == 'USED') {
                 $mem_usage = $line_value / (1048576 / self::$page_size);
                 break;
             }
             if ($line_type == 'Pages free' && $READ == 'FREE') {
                 $mem_usage = $line_value / (1048576 / self::$page_size);
                 break;
             }
         }
     }
     return pts_math::set_precision($mem_usage);
 }
 private function cpu_temp_linux()
 {
     $temp_c = -1;
     // Try hwmon interface
     $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp2_input', 'POSITIVE_NUMERIC', array('name' => 'coretemp'));
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => 'k10temp'));
     }
     if ($raw_temp == -1) {
         // Try ACPI thermal
         // Assuming the system thermal sensor comes 2nd to the ACPI CPU temperature
         // It appears that way on a ThinkPad T60, but TODO find a better way to validate
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/thermal/thermal_zone*/temp', 'POSITIVE_NUMERIC', null, 2);
     }
     if ($raw_temp != -1) {
         if ($raw_temp > 1000) {
             $raw_temp = $raw_temp / 1000;
         }
         $temp_c = pts_math::set_precision($raw_temp, 2);
     }
     if ($temp_c == -1) {
         // Try LM_Sensors
         $sensors = phodevi_linux_parser::read_sensors(array('CPU Temp', 'Core 0', 'Core0 Temp', 'Core1 Temp'));
         if ($sensors != false && is_numeric($sensors) && $sensors > 0) {
             $temp_c = $sensors;
         }
     }
     if (pts_client::executable_in_path('ipmitool')) {
         $ipmi = phodevi_linux_parser::read_ipmitool_sensor('Temp 0');
         if ($ipmi > 0 && is_numeric($ipmi)) {
             $temp_c = $ipmi;
         }
     }
     return $temp_c;
 }
 protected function render_graph_bars()
 {
     $bar_count = count($this->graph_data);
     $separator_width = ($a = 8 - floor($bar_count / 2) * 2) > 0 ? $a : 0;
     $bar_width = floor(($this->i['identifier_width'] - $separator_width - $bar_count * $separator_width) / $bar_count);
     for ($i_o = 0; $i_o < $bar_count; $i_o++) {
         $paint_color = $this->get_paint_color(isset($this->graph_data_title[$i_o]) ? $this->graph_data_title[$i_o] : null);
         foreach (array_keys($this->graph_data[$i_o]) as $i) {
             $value = pts_math::set_precision($this->graph_data[$i_o][$i], 2);
             $graph_size = round($value / $this->i['graph_max_value'] * ($this->i['graph_top_end'] - $this->i['top_start']));
             $value_plot_top = max($this->i['graph_top_end'] + 1 - $graph_size, 1);
             $px_bound_left = $this->i['left_start'] + $this->i['identifier_width'] * $i + $bar_width * $i_o + $separator_width * ($i_o + 1);
             $px_bound_right = $px_bound_left + $bar_width;
             $title_tooltip = $this->graph_identifiers[$i] . ': ' . $value;
             $run_std_deviation = isset($this->graph_data_raw[$i_o][$i]) ? pts_math::standard_deviation(pts_strings::colon_explode($this->graph_data_raw[$i_o][$i])) : 0;
             if ($run_std_deviation > 0) {
                 $title_tooltip .= ' || ' . pts_math::set_precision($run_std_deviation, 1) . ' STD';
             }
             $this->svg_dom->add_element('rect', array('x' => $px_bound_left + 1, 'y' => $value_plot_top, 'width' => $bar_width, 'height' => $this->i['graph_top_end'] - $value_plot_top, 'fill' => in_array($this->graph_identifiers[$i], $this->value_highlights) ? self::$c['color']['alert'] : $paint_color, 'stroke' => self::$c['color']['body_light'], 'stroke-width' => 1, 'xlink:title' => $title_tooltip));
             if ($px_bound_right - $px_bound_left < 15) {
                 // The bars are too skinny to be able to plot anything on them
                 continue;
             }
             $x = $px_bound_left + ($px_bound_right - $px_bound_left) / 2;
             if ($graph_size > 18) {
                 $this->svg_dom->add_text_element($value, array('x' => $x, 'y' => $value_plot_top + 2, 'font-size' => floor(self::$c['size']['bars'] * 0.9), 'fill' => self::$c['color']['body_text'], 'text-anchor' => 'middle', 'dominant-baseline' => 'text-before-edge'));
             } else {
                 // Make things more compact
                 $this->svg_dom->add_text_element($value, array('x' => $x, 'y' => $value_plot_top + 2, 'font-size' => floor(self::$c['size']['bars'] * 0.6), 'fill' => self::$c['color']['body_text'], 'text-anchor' => 'middle', 'dominant-baseline' => 'text-before-edge'));
             }
         }
     }
     // write a new line along the bottom since the draw_rectangle_with_border above had written on top of it
     $this->svg_dom->draw_svg_line($this->i['left_start'], $this->i['graph_top_end'], $this->i['graph_left_end'], $this->i['graph_top_end'], self::$c['color']['notches'], 1);
 }
 public function read_sensor()
 {
     $temp = -1;
     if (phodevi::is_linux()) {
         $temp = $this->hdd_temp_linux();
     }
     return pts_math::set_precision($temp, 2);
 }
 public function read_sensor()
 {
     $write_speed = -1;
     if (phodevi::is_linux()) {
         $write_speed = $this->hdd_write_speed_linux();
     }
     return pts_math::set_precision($write_speed, 2);
 }
 protected function bytes_to_download_size($bytes)
 {
     $mb = pts_math::set_precision($bytes / 1048576, 2);
     if ($mb > 99) {
         $mb = ceil($mb);
     }
     return $mb;
 }
 public function read_sensor()
 {
     $net_speed = -1;
     if (phodevi::is_bsd() || phodevi::is_macosx()) {
         $net_speed = $this->network_usage_bsd();
     }
     return pts_math::set_precision($net_speed, 2);
 }
 public static function read_sensor()
 {
     // Read the processor temperature
     $temp_c = -1;
     if (phodevi::is_bsd()) {
         $cpu_temp = phodevi_bsd_parser::read_sysctl(array('hw.sensors.acpi_tz0.temp0', 'dev.cpu.0.temperature', 'hw.sensors.cpu0.temp0'));
         if ($cpu_temp != false) {
             if (($end = strpos($cpu_temp, 'degC')) || ($end = strpos($cpu_temp, 'C')) > 0) {
                 $cpu_temp = substr($cpu_temp, 0, $end);
             }
             if (is_numeric($cpu_temp)) {
                 $temp_c = $cpu_temp;
             }
         } else {
             $acpi = phodevi_bsd_parser::read_sysctl('hw.acpi.thermal.tz0.temperature');
             if (($end = strpos($acpi, 'C')) > 0) {
                 $acpi = substr($acpi, 0, $end);
             }
             if (is_numeric($acpi)) {
                 $temp_c = $acpi;
             }
         }
     } else {
         if (phodevi::is_linux()) {
             // Try hwmon interface
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => 'coretemp'));
             if ($raw_temp == -1) {
                 $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => 'k10temp'));
             }
             if ($raw_temp == -1) {
                 // Try ACPI thermal
                 // Assuming the system thermal sensor comes 2nd to the ACPI CPU temperature
                 // It appears that way on a ThinkPad T60, but TODO find a better way to validate
                 $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/thermal/thermal_zone*/temp', 'POSITIVE_NUMERIC', null, 2);
             }
             if ($raw_temp != -1) {
                 if ($raw_temp > 1000) {
                     $raw_temp = $raw_temp / 1000;
                 }
                 $temp_c = pts_math::set_precision($raw_temp, 2);
             }
             if ($temp_c == -1) {
                 // Try LM_Sensors
                 $sensors = phodevi_linux_parser::read_sensors(array('CPU Temp', 'Core 0', 'Core0 Temp', 'Core1 Temp'));
                 if ($sensors != false && is_numeric($sensors) && $sensors > 0) {
                     $temp_c = $sensors;
                 }
             }
             if (pts_client::executable_in_path('ipmitool')) {
                 $ipmi = phodevi_linux_parser::read_ipmitool_sensor('Temp 0');
                 if ($ipmi > 0 && is_numeric($ipmi)) {
                     $temp_c = $ipmi;
                 }
             }
         }
     }
     return $temp_c;
 }
 public function get_change_formatted()
 {
     $direction = '-';
     if ($this->test_proportion == 'HIB' && $this->get_regressed_value() > $this->get_base_value()) {
         $direction = '+';
     } else {
         if ($this->test_proportion == 'LIB' && $this->get_regressed_value() < $this->get_base_value()) {
             $direction = '+';
         }
     }
     return $direction . pts_math::set_precision($this->get_change() * 100, 2);
 }
 public static function read_sensor()
 {
     // Reads the system's temperature
     $temp_c = -1;
     if (phodevi::is_linux()) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp3_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp2_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         }
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
         }
         if ($raw_temp == -1) {
             $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp1_input', 'POSITIVE_NUMERIC');
         }
         if ($raw_temp != -1) {
             if ($raw_temp > 1000) {
                 $raw_temp = $raw_temp / 1000;
             }
             $temp_c = pts_math::set_precision($raw_temp, 2);
         }
         if ($temp_c == -1) {
             $acpi = phodevi_linux_parser::read_acpi(array('/thermal_zone/THM1/temperature', '/thermal_zone/TZ00/temperature', '/thermal_zone/TZ01/temperature'), 'temperature');
             if (($end = strpos($acpi, ' ')) > 0) {
                 $temp_c = substr($acpi, 0, $end);
             }
         }
         if ($temp_c == -1) {
             $sensors = phodevi_linux_parser::read_sensors(array('Sys Temp', 'Board Temp'));
             if ($sensors != false && is_numeric($sensors)) {
                 $temp_c = $sensors;
             }
         }
         if ($temp_c == -1 && is_file('/sys/class/thermal/thermal_zone0/temp')) {
             $temp_c = pts_file_io::file_get_contents('/sys/class/thermal/thermal_zone0/temp');
             if ($temp_c > 1000) {
                 $temp_c = pts_math::set_precision($temp_c / 1000, 1);
             }
         }
     } else {
         if (phodevi::is_bsd()) {
             $acpi = phodevi_bsd_parser::read_sysctl(array('hw.sensors.acpi_tz1.temp0', 'hw.acpi.thermal.tz1.temperature'));
             if (($end = strpos($acpi, ' degC')) > 0 || ($end = strpos($acpi, 'C')) > 0) {
                 $acpi = substr($acpi, 0, $end);
                 if (is_numeric($acpi)) {
                     $temp_c = $acpi;
                 }
             }
         }
     }
     return $temp_c;
 }
 private function swap_usage_linux()
 {
     $proc_meminfo = explode("\n", file_get_contents('/proc/meminfo'));
     $mem = array();
     foreach ($proc_meminfo as $mem_line) {
         $line_split = preg_split('/\\s+/', $mem_line);
         if (count($line_split) == 3) {
             $mem[$line_split[0]] = intval($line_split[1]);
         }
     }
     $used_mem = $mem['SwapTotal:'] - $mem['SwapFree:'];
     return pts_math::set_precision($used_mem / 1024, 0);
 }
 public function read_sensor()
 {
     $start_sys_jiffies = self::cpu_jiffies_count();
     $start_cgroup_jiffies = self::cgroup_cpu_jiffies_count();
     usleep(500000);
     $end_sys_jiffies = self::cpu_jiffies_count();
     $end_cgroup_jiffies = self::cgroup_cpu_jiffies_count();
     $diff_sys_jiffies = $end_sys_jiffies - $start_sys_jiffies;
     $diff_cgroup_jiffies = $end_cgroup_jiffies - $start_cgroup_jiffies;
     $percent = $diff_sys_jiffies == 0 ? 0 : $diff_cgroup_jiffies / $diff_sys_jiffies * 100;
     if (!is_numeric($percent) || $percent < 0 || $percent > 100) {
         $percent = -1;
     }
     return pts_math::set_precision($percent, 2);
 }
 private function cpu_power_linux()
 {
     $cpu_watts = -1;
     // Try hwmon interface for AMD 15h (Bulldozer FX CPUs) where this support was introduced for AMD CPUs and exposed by the fam15h_power hwmon driver
     // The fam15h_power driver doesn't expose the power consumption on a per-core/per-package basis but only an average
     $hwmon_watts = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/power1_input', 'POSITIVE_NUMERIC', array('name' => 'fam15h_power'));
     if ($hwmon_watts != -1) {
         if ($hwmon_watts > 1000000) {
             // convert to Watts
             $hwmon_watts = $hwmon_watts / 1000000;
         }
         $cpu_watts = pts_math::set_precision($hwmon_watts, 2);
     }
     return $cpu_watts;
 }
 public static function read_sensor()
 {
     $iowait = -1;
     if (phodevi::is_linux() && is_file('/proc/stat')) {
         $start_stat = pts_file_io::file_get_contents('/proc/stat');
         sleep(1);
         $end_stat = pts_file_io::file_get_contents('/proc/stat');
         $start_stat = explode(' ', substr($start_stat, 0, strpos($start_stat, "\n")));
         $end_stat = explode(' ', substr($end_stat, 0, strpos($end_stat, "\n")));
         for ($i = 2, $diff_cpu_total = 0; $i < 9; $i++) {
             $diff_cpu_total += $end_stat[$i] - $start_stat[$i];
         }
         $diff_iowait = $end_stat[6] - $start_stat[6];
         $iowait = pts_math::set_precision(1000 * $diff_iowait / $diff_cpu_total / 10, 2);
     }
     return $iowait;
 }
 public function render_graph_finish()
 {
     $this->render_graph_identifiers();
     $this->render_graph_heading(false);
     $pie_slices = count($this->graph_identifiers);
     $radius = min($this->i['graph_height'] - $this->i['top_start'] - $this->i['top_end_bottom'], $this->i['graph_width'] - $this->i['left_start'] - $this->i['left_end_right']) / 2;
     $center_x = $this->i['graph_width'] / 2;
     $center_y = $this->i['top_start'] + ($this->i['graph_height'] - $this->i['top_start'] - $this->i['top_end_bottom']) / 2;
     $offset_percent = 0;
     for ($i = 0; $i < $pie_slices; $i++) {
         $percent = pts_math::set_precision($this->graph_data[0][$i] / $this->i['pie_sum'], 3);
         $this->svg_dom->draw_svg_arc($center_x, $center_y, $radius, $offset_percent, $percent, array('fill' => $this->get_paint_color($i), 'stroke' => self::$c['color']['border'], 'stroke-width' => 2, 'xlink:title' => $this->graph_identifiers[$i] . ': ' . $this->graph_data[0][$i]));
         $offset_percent += $percent;
     }
     if (!empty(self::$c['text']['watermark'])) {
         $this->svg_dom->add_text_element(self::$c['text']['watermark'], array('x' => $this->i['graph_width'] / 2, 'y' => $this->i['graph_height'] - 15, 'font-size' => 10, 'fill' => self::$c['color']['text'], 'text-anchor' => 'middle', 'dominant-baseline' => 'text-before-edge'));
     }
 }
 public static function read_sensor()
 {
     // Determine the current processor frequency
     $cpu_core = 0;
     // TODO: for now just monitoring the first core
     $info = 0;
     if (phodevi::is_linux()) {
         // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
         if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_cur_freq')) {
             $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_cur_freq');
             $info = intval($info) / 1000;
         } else {
             if (is_file('/proc/cpuinfo')) {
                 $cpu_speeds = phodevi_linux_parser::read_cpuinfo('cpu MHz');
                 if (isset($cpu_speeds[0])) {
                     $cpu_core = isset($cpu_speeds[$cpu_core]) ? $cpu_core : 0;
                     $info = intval($cpu_speeds[$cpu_core]);
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $info = shell_exec('psrinfo -v | grep MHz');
             $info = substr($info, strrpos($info, 'at') + 3);
             $info = trim(substr($info, 0, strpos($info, 'MHz')));
         } else {
             if (phodevi::is_bsd()) {
                 $info = phodevi_bsd_parser::read_sysctl('dev.cpu.0.freq');
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ProcessorSpeed');
                     if (($cut_point = strpos($info, ' ')) > 0) {
                         $info = substr($info, 0, $cut_point);
                         $info = str_replace(',', '.', $info);
                     }
                     if ($info < 100) {
                         $info *= 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }
 public function read_sensor()
 {
     // Determine current percentage for core usage
     // Default core to read is the first one (number 0)
     if (phodevi::is_linux() || phodevi::is_bsd()) {
         $percent = $this->cpu_usage_linux_bsd();
     } else {
         if (phodevi::is_solaris()) {
             $percent = $this->cpu_usage_solaris();
         } else {
             if (phodevi::is_macosx()) {
                 $percent = $this->cpu_usage_macosx();
             }
         }
     }
     if (!isset($percent) || !is_numeric($percent) || $percent < 0 || $percent > 100) {
         $percent = -1;
     }
     return pts_math::set_precision($percent, 2);
 }
 private function sys_temp_linux()
 {
     $temp_c = -1;
     $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp3_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp2_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     }
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/device/temp1_input', 'POSITIVE_NUMERIC', array('name' => '!coretemp,!radeon,!nouveau'));
     }
     if ($raw_temp == -1) {
         $raw_temp = phodevi_linux_parser::read_sysfs_node('/sys/class/hwmon/hwmon*/temp1_input', 'POSITIVE_NUMERIC');
     }
     if ($raw_temp != -1) {
         if ($raw_temp > 1000) {
             $raw_temp = $raw_temp / 1000;
         }
         $temp_c = pts_math::set_precision($raw_temp, 2);
     }
     if ($temp_c == -1) {
         $acpi = phodevi_linux_parser::read_acpi(array('/thermal_zone/THM1/temperature', '/thermal_zone/TZ00/temperature', '/thermal_zone/TZ01/temperature'), 'temperature');
         if (($end = strpos($acpi, ' ')) > 0) {
             $temp_c = substr($acpi, 0, $end);
         }
     }
     if ($temp_c == -1) {
         $sensors = phodevi_linux_parser::read_sensors(array('Sys Temp', 'Board Temp'));
         if ($sensors != false && is_numeric($sensors)) {
             $temp_c = $sensors;
         }
     }
     if ($temp_c == -1 && is_file('/sys/class/thermal/thermal_zone0/temp')) {
         $temp_c = pts_file_io::file_get_contents('/sys/class/thermal/thermal_zone0/temp');
         if ($temp_c > 1000) {
             $temp_c = pts_math::set_precision($temp_c / 1000, 1);
         }
     }
     return $temp_c;
 }
 public function render_graph_start()
 {
     // Needs to be at least 86px wide for the PTS logo
     $this->i['left_start'] = ceil(max(86, $this->text_string_width($this->longest_row_identifier, $this->i['identifier_size']) * 1.1 + 12));
     if ($this->column_heading_vertical) {
         $top_identifier_height = round($this->text_string_width($this->longest_column_identifier, $this->i['identifier_size']) * 1.1) + 12;
         $table_identifier_width = $this->text_string_height($this->longest_column_identifier, $this->i['identifier_size']);
     } else {
         $top_identifier_height = $this->text_string_height($this->longest_column_identifier, $this->i['identifier_size']) + 8;
         $table_identifier_width = round($this->text_string_width($this->longest_column_identifier, $this->i['identifier_size']) * 1.1) + 8;
     }
     // Needs to be at least 46px tall for the PTS logo
     $top_identifier_height = max($top_identifier_height, 48);
     if (defined('PHOROMATIC_TRACKER') || $this->is_multi_way) {
         $extra_heading_height = round($this->text_string_height($this->longest_column_identifier, self::$c['size']['headers']) * 1.25);
         $top_identifier_height += 6 + $extra_heading_height;
     }
     $this->i['top_heading_height'] = 8;
     if ($this->graph_title != null) {
         $this->i['top_heading_height'] += round(self::$c['size']['headers'] + count($this->graph_sub_titles) * (self::$c['size']['sub_headers'] + 4));
     }
     $table_max_value_width = ceil($this->text_string_width($this->i['graph_max_value'], $this->i['identifier_size']) * 1.02) + 2;
     $table_item_width = max($table_max_value_width, $table_identifier_width) + 2;
     $table_width = max($table_item_width * count($this->columns), floor($this->text_string_width($this->graph_title, 12) / $table_item_width) * $table_item_width);
     //$table_width = $table_item_width * count($this->columns);
     $table_line_height = round($this->text_string_height($this->i['graph_max_value'], $this->i['identifier_size']) + 8);
     $table_line_height_half = round($table_line_height / 2);
     $table_height = $table_line_height * count($this->rows);
     $table_proper_height = $this->i['top_heading_height'] + $table_height + $top_identifier_height;
     $this->i['graph_width'] = $table_width + $this->i['left_start'];
     $this->i['graph_height'] = round($table_proper_height + $table_line_height);
     if (!empty($this->i['notes'])) {
         $this->i['graph_height'] += $this->note_display_height();
     }
     // Do the actual work
     $this->render_graph_pre_init();
     $this->render_graph_init();
     $this->svg_dom->add_element('rect', array('x' => 1, 'y' => 1, 'width' => $this->i['graph_width'] - 1, 'height' => $this->i['graph_height'] - 1, 'fill' => self::$c['color']['background'], 'stroke' => self::$c['color']['border'], 'stroke-width' => 1));
     // Start drawing
     if ($this->i['left_start'] >= 170 && $top_identifier_height >= 90) {
         $this->svg_dom->add_element('image', array('http_link' => 'http://www.phoronix-test-suite.com/', 'xlink:href' => 'https://openbenchmarking.org/static/images/pts-160x83.png', 'x' => round($this->i['left_start'] / 2 - 80), 'y' => round($top_identifier_height / 2 - 41.5 + $this->i['top_heading_height']), 'width' => 160, 'height' => 83));
     } else {
         $this->svg_dom->add_element('image', array('http_link' => 'http://www.phoronix-test-suite.com/', 'xlink:href' => 'https://openbenchmarking.org/static/images/pts-80x42.png', 'x' => round($this->i['left_start'] / 2 - 40), 'y' => round($top_identifier_height / 2 - 21 + $this->i['top_heading_height']), 'width' => 80, 'height' => 42));
     }
     // Draw the vertical table lines
     $v = round(($top_identifier_height + $table_height) / 2 + $this->i['top_heading_height']);
     $table_columns_end = $this->i['left_start'] + $table_item_width * count($this->columns);
     $this->svg_dom->draw_svg_line($this->i['left_start'], $v, $table_columns_end, $v, self::$c['color']['body'], $table_height + $top_identifier_height, array('stroke-dasharray' => $table_item_width . ',' . $table_item_width));
     if ($table_columns_end < $this->i['graph_width']) {
         $this->svg_dom->add_element('rect', array('x' => $table_columns_end, 'y' => $this->i['top_heading_height'], 'width' => $this->i['graph_width'] - $table_columns_end, 'height' => $table_height + $top_identifier_height, 'fill' => self::$c['color']['body_light']));
     }
     // Background horizontal
     $this->svg_dom->draw_svg_line(round($table_columns_end / 2), $top_identifier_height + $this->i['top_heading_height'], round($table_columns_end / 2), $table_proper_height, self::$c['color']['body_light'], $table_columns_end, array('stroke-dasharray' => $table_line_height . ',' . $table_line_height));
     // Draw the borders
     $this->svg_dom->draw_svg_line($this->i['left_start'], $v, $table_columns_end + ($table_columns_end < $this->i['graph_width'] ? $table_item_width : 0), $v, self::$c['color']['border'], $table_height + $top_identifier_height, array('stroke-dasharray' => '1,' . ($table_item_width - 1)));
     // Heading
     if ($this->graph_title != null) {
         $this->svg_dom->add_element('rect', array('x' => 1, 'y' => 1, 'width' => $this->i['graph_width'] - 2, 'height' => $this->i['top_heading_height'], 'fill' => self::$c['color']['main_headers']));
         $this->svg_dom->add_text_element($this->graph_title, array('x' => 5, 'y' => self::$c['size']['headers'] + 2, 'font-size' => self::$c['size']['headers'], 'fill' => self::$c['color']['background'], 'text-anchor' => 'start'));
         foreach ($this->graph_sub_titles as $i => $sub_title) {
             $vertical_offset = 16 + self::$c['size']['headers'] + $i * self::$c['size']['sub_headers'];
             $this->svg_dom->add_text_element($sub_title, array('x' => 5, 'y' => $vertical_offset, 'font-size' => self::$c['size']['sub_headers'], 'fill' => self::$c['color']['background'], 'text-anchor' => 'start'));
         }
         $this->svg_dom->draw_svg_line(1, $this->i['top_heading_height'], $this->i['graph_width'] - 1, $this->i['top_heading_height'], self::$c['color']['border'], 1);
     }
     // Write the rows
     $row = 1;
     $g = $this->svg_dom->make_g(array('font-size' => $this->i['identifier_size'], 'font-weight' => 'bold', 'text-anchor' => 'end', 'fill' => self::$c['color']['text']));
     foreach ($this->rows as $i => $row_string) {
         if ($row_string instanceof pts_graph_ir_value == false) {
             $row_string = new pts_graph_ir_value($row_string);
         }
         $v = round($top_identifier_height + $this->i['top_heading_height'] + $row * $table_line_height - 4);
         $r = array('x' => $this->i['left_start'] - 2, 'y' => $v, 'fill' => self::$c['color']['text'], 'xlink:href' => $row_string->get_attribute('href'));
         if ($row_string->get_attribute('alert')) {
             $r['fill'] = self::$c['color']['alert'];
         }
         $this->svg_dom->add_text_element($row_string, $r, $g);
         $row++;
     }
     // Write the identifiers
     if (defined('PHOROMATIC_TRACKER') || $this->is_multi_way) {
         $last_identifier = null;
         $last_changed_col = 0;
         $show_keys = array_keys($this->table_data);
         array_push($show_keys, 'Temp: Temp');
         $g1 = $this->svg_dom->make_g(array());
         $g2 = $this->svg_dom->make_g(array('font-size' => self::$c['size']['axis_headers'], 'fill' => self::$c['color']['background'], 'font-weight' => 'bold', 'text-anchor' => 'middle'));
         foreach ($show_keys as $current_col => $system_identifier) {
             $identifier = pts_strings::colon_explode($system_identifier);
             if (isset($identifier[0]) && $identifier[0] != $last_identifier) {
                 if ($current_col == $last_changed_col) {
                     $last_identifier = $identifier[0];
                     continue;
                 }
                 $paint_color = $this->get_paint_color($identifier[0]);
                 if ($this->i['top_heading_height'] > 0) {
                     $extra_heading_height = $this->i['top_heading_height'];
                 }
                 $x = $this->i['left_start'] + 1 + $last_changed_col * $table_item_width;
                 $x_end = $this->i['left_start'] + $last_changed_col * $table_item_width + $table_item_width * ($current_col - $last_changed_col);
                 $this->svg_dom->add_element('rect', array('x' => $x, 'y' => 0, 'width' => $table_item_width * ($current_col - $last_changed_col) - 2, 'height' => $extra_heading_height, 'fill' => $paint_color), $g1);
                 if ($identifier[0] != 'Temp') {
                     $this->svg_dom->draw_svg_line($this->i['left_start'] + $current_col * $table_item_width + 1, 1, $this->i['left_start'] + $current_col * $table_item_width + 1, $table_proper_height, $paint_color, 1);
                 }
                 //$x = $this->i['left_start'] + ($last_changed_col * $table_item_width) + ($this->i['left_start'] + ($current_col * $table_item_width) - $this->i['left_start'] + ($last_changed_col * $table_item_width));
                 $this->svg_dom->add_text_element($last_identifier, array('x' => round($x + ($x_end - $x) / 2), 'y' => self::$c['size']['axis_headers'] + 4), $g2);
                 $last_identifier = $identifier[0];
                 $last_changed_col = $current_col;
             }
         }
     }
     $table_identifier_offset = $table_item_width / 2 + $table_identifier_width / 2 - 1;
     $g_opts = array('font-size' => $this->i['identifier_size'], 'fill' => self::$c['color']['text'], 'font-weight' => 'bold');
     if ($this->column_heading_vertical) {
         $g_opts['text-anchor'] = 'end';
     } else {
         $g_opts['text-anchor'] = 'middle';
         $g_opts['dominant-baseline'] = 'text-before-edge';
     }
     $g = $this->svg_dom->make_g($g_opts);
     foreach ($this->columns as $i => $col_string) {
         if ($this->column_heading_vertical) {
             $x = $this->i['left_start'] + $i * $table_item_width + $table_identifier_offset;
             $y = $this->i['top_heading_height'] + $top_identifier_height - 4;
             $this->svg_dom->add_text_element($col_string, array('x' => $x, 'y' => $y, 'transform' => 'rotate(90 ' . $x . ' ' . $y . ')'), $g);
         } else {
             $x = $this->i['left_start'] + $i * $table_item_width + $table_item_width / 2;
             $y = $this->i['top_heading_height'] + $top_identifier_height / 2;
             $this->svg_dom->add_text_element($col_string, array('x' => $x, 'y' => $y), $g);
         }
     }
     // Write the columns
     $g_background = $this->svg_dom->make_g(array());
     $g = $this->svg_dom->make_g(array('text-anchor' => 'middle', 'font-size' => $this->i['identifier_size']));
     foreach ($this->table_data as $index => &$table_values) {
         if (!is_array($table_values)) {
             // TODO: determine why sometimes $table_values is empty or not an array
             continue;
         }
         if ($this->is_multi_way && ($c = strpos($index, ':')) !== false) {
             $index = substr($index, $c + 1);
         }
         $col = array_search(strval($index), $this->columns);
         if ($col === false) {
             continue;
         } else {
             // unset this since it shouldn't be needed anymore and will then wipe out it from where multiple results have same name
             unset($this->columns[$col]);
         }
         foreach ($table_values as $i => &$result_table_value) {
             $row = $i - 1;
             // if using $row, the alignment may be off sometimes
             $hover = array();
             $text_color = self::$c['color']['text'];
             $bold = false;
             if ($result_table_value == null) {
                 continue;
             }
             if ($result_table_value instanceof pts_graph_ir_value) {
                 if (($t = $result_table_value->get_attribute('std_percent')) > 0) {
                     array_push($hover, 'STD Dev: ' . $t . '%');
                 }
                 if (($t = $result_table_value->get_attribute('std_error')) != 0) {
                     array_push($hover, ' STD Error: ' . $t);
                 }
                 if (defined('PHOROMATIC_TRACKER') && ($t = $result_table_value->get_attribute('delta')) != 0) {
                     $bold = true;
                     $text_color = $t < 0 ? self::$c['color']['alert'] : self::$c['color']['headers'];
                     array_push($hover, ' Change: ' . pts_math::set_precision(100 * $t, 2) . '%');
                 } else {
                     if ($result_table_value->get_attribute('highlight') == true) {
                         $text_color = self::$c['color']['highlight'];
                     } else {
                         if ($result_table_value->get_attribute('alert') == true) {
                             $text_color = self::$c['color']['alert'];
                         }
                     }
                 }
                 $value = $result_table_value->get_value();
                 $spans_col = $result_table_value->get_attribute('spans_col');
             } else {
                 $value = $result_table_value;
                 $spans_col = 1;
             }
             $left_bounds = $this->i['left_start'] + $col * $table_item_width;
             $right_bounds = $this->i['left_start'] + ($col + max(1, $spans_col)) * $table_item_width;
             if ($spans_col > 1) {
                 if ($col == 1) {
                     $background_paint = $i % 2 == 1 ? self::$c['color']['background'] : self::$c['color']['body'];
                 } else {
                     $background_paint = $i % 2 == 0 ? self::$c['color']['body_light'] : self::$c['color']['body'];
                 }
                 $y = round($this->i['top_heading_height'] + $top_identifier_height + ($row + 1) * $table_line_height);
                 $this->svg_dom->add_element('rect', array('x' => $left_bounds, 'y' => $y + 1, 'width' => $right_bounds - $left_bounds, 'height' => $table_line_height, 'fill' => $background_paint), $g_background);
             }
             $x = $left_bounds + ($right_bounds - $left_bounds) / 2;
             $this->svg_dom->add_text_element($result_table_value, array('x' => $x, 'y' => round($this->i['top_heading_height'] + $top_identifier_height + ($row + 2) * $table_line_height - 3), 'fill' => $text_color, 'xlink:title' => implode('; ', $hover), 'xlink:href' => $result_table_value->get_attribute('href')), $g);
             //$row++;
         }
     }
     //$this->svg_dom->draw_svg_line(($table_columns_end / 2), ($top_identifier_height + $this->i['top_heading_height']), round($table_columns_end / 2), $this->i['graph_height'], self::$c['color']['border'], $table_columns_end, array('stroke-dasharray' => '1,' . ($table_line_height - 1)));
     $this->svg_dom->draw_svg_line(round($table_columns_end / 2), $top_identifier_height + $this->i['top_heading_height'], round($table_columns_end / 2), $table_proper_height, self::$c['color']['body_light'], $table_columns_end, array('stroke-dasharray' => 1 . ',' . ($table_line_height - 1)));
     // Bottom part
     $this->svg_dom->add_element('rect', array('x' => 0, 'y' => $table_proper_height, 'width' => $this->i['graph_width'], 'height' => $this->i['graph_height'] - $table_proper_height, 'fill' => self::$c['color']['headers']));
     $this->svg_dom->add_text_element(self::$c['text']['watermark'], array('x' => $this->i['graph_width'] - 2, 'y' => $this->i['graph_height'] - 3, 'font-size' => $this->i['identifier_size'], 'fill' => self::$c['color']['body_text'], 'text-anchor' => 'end', 'xlink:show' => 'new', 'xlink:href' => self::$c['text']['watermark_url']));
     if (isset($this->d['link_alternate_view']) && $this->d['link_alternate_view']) {
         $this->svg_dom->add_text_element(0, array('x' => 6, 'y' => $this->i['graph_height'] - 3, 'font-size' => 7, 'fill' => self::$c['color']['background'], 'text-anchor' => 'start', 'xlink:show' => 'new', 'xlink:href' => $this->d['link_alternate_view'], 'show' => 'replace', 'font-weight' => 'bold'));
     }
     if (!empty($this->i['notes'])) {
         $estimated_height = 0;
         $previous_section = null;
         $g = $this->svg_dom->make_g(array('fill' => self::$c['color']['background'], 'text-anchor' => 'start'));
         foreach ($this->i['notes'] as $i => $note_r) {
             if ($note_r['section'] != null && $note_r['section'] !== $previous_section) {
                 $estimated_height += 2;
                 $this->svg_dom->add_textarea_element($note_r['section'] . ' Details', array('x' => 6, 'y' => $table_proper_height + $table_line_height + $estimated_height, 'xlink:title' => $note_r['hover-title'], 'style' => 'font-weight: bold', 'fill' => self::$c['color']['background'], 'font-size' => self::$c['size']['key'] - 1), $estimated_height, $g);
                 $estimated_height += 2;
                 $previous_section = $note_r['section'];
             }
             $this->svg_dom->add_textarea_element('- ' . $note_r['note'], array('x' => 6, 'y' => $table_proper_height + $table_line_height + $estimated_height, 'xlink:title' => $note_r['hover-title'], 'fill' => self::$c['color']['background'], 'font-size' => self::$c['size']['key'] - 1), $estimated_height, $g);
         }
     }
     $this->rendered_rows = $row;
 }
 public static function generate_overview_object(&$overview_table, $overview_type)
 {
     switch ($overview_type) {
         case 'GEOMETRIC_MEAN':
             $title = 'Geometric Mean';
             $math_call = array('pts_math', 'geometric_mean');
             break;
         case 'HARMONIC_MEAN':
             $title = 'Harmonic Mean';
             $math_call = array('pts_math', 'harmonic_mean');
             break;
         case 'AGGREGATE_SUM':
             $title = 'Aggregate Sum';
             $math_call = 'array_sum';
             break;
         default:
             return false;
     }
     $result_buffer = new pts_test_result_buffer();
     if ($overview_table instanceof pts_result_file) {
         list($days_keys1, $days_keys, $shred) = pts_ResultFileTable::result_file_to_result_table($overview_table);
         foreach ($shred as $system_key => &$system) {
             $to_show = array();
             foreach ($system as &$days) {
                 $days = $days->get_value();
             }
             array_push($to_show, pts_math::set_precision(call_user_func($math_call, $system), 2));
             $result_buffer->add_test_result($system_key, implode(',', $to_show), null);
         }
     } else {
         $days_keys = null;
         foreach ($overview_table as $system_key => &$system) {
             if ($days_keys == null) {
                 // TODO: Rather messy and inappropriate way of getting the days keys
                 $days_keys = array_keys($system);
                 break;
             }
         }
         foreach ($overview_table as $system_key => &$system) {
             $to_show = array();
             foreach ($system as &$days) {
                 array_push($to_show, call_user_func($math_call, $days));
             }
             $result_buffer->add_test_result($system_key, implode(',', $to_show), null);
         }
     }
     $test_profile = new pts_test_profile(null, null, false);
     $test_profile->set_test_title($title);
     $test_profile->set_result_scale($title);
     $test_profile->set_display_format('BAR_GRAPH');
     $test_result = new pts_test_result($test_profile);
     $test_result->set_used_arguments_description('Analytical Overview');
     $test_result->set_test_result_buffer($result_buffer);
     return $test_result;
 }
 protected function render_graph_key()
 {
     if (isset($this->i['force_simple_keys']) && $this->i['force_simple_keys']) {
         return parent::render_graph_key();
     }
     if (!$this->i['plot_overview_text']) {
         return;
     }
     if ($this->i['key_line_height'] == 0) {
         return;
     }
     $square_length = 10;
     $precision = $this->i['graph_max_value'] > 999 ? 0 : 1;
     $num_rows = max(1, ceil($this->test_result->test_result_buffer->get_count() / $this->i['keys_per_line']));
     $num_cols = ceil($this->test_result->test_result_buffer->get_count() / $num_rows);
     $y_start = $this->i['top_heading_height'] + 24;
     //$y_start = $this->i['top_start'] - $this->graph_key_height() + $this->getStatisticsHeaderHeight();
     $y_end = $y_start + $this->i['key_line_height'] * $num_rows;
     $x_start = $this->i['left_start'];
     $x_end = $x_start + $this->i['key_item_width'] * ($num_cols - 1);
     // draw the "Min Avg Max" text
     $stat_header_offset = $this->i['key_longest_string_width'] + $square_length + 10;
     $g_text = $this->svg_dom->make_g(array('font-size' => 6.5, 'fill' => self::$c['color']['notches']));
     for ($x = $x_start + $stat_header_offset; $x <= $x_end + $stat_header_offset; $x += $this->i['key_item_width']) {
         $stat_words = array('Min', 'Avg', 'Max');
         $stat_word_width = $this->get_stat_word_width();
         $attributes = array('y' => $y_start - 14);
         foreach ($stat_words as &$stat_word) {
             $attributes['x'] = $x;
             $this->svg_dom->add_text_element($stat_word, $attributes, $g_text);
             $x += $stat_word_width;
         }
     }
     // draw the keys and the min,avg,max values
     $g_rect = $this->svg_dom->make_g(array('stroke' => self::$c['color']['notches'], 'stroke-width' => 1));
     for ($i = 0, $x = $x_start; $x <= $x_end; $x += $this->i['key_item_width']) {
         for ($y = $y_start; $y <= $y_end; $y += $this->i['key_line_height'], ++$i) {
             if (!isset($this->test_result->test_result_buffer->buffer_items[$i])) {
                 break;
             }
             $identifier_title = $this->test_result->test_result_buffer->buffer_items[$i]->get_result_identifier();
             $this_color = $this->get_paint_color($identifier_title);
             // draw square
             $this->svg_dom->add_element('rect', array('x' => $x, 'y' => $y - $square_length, 'width' => $square_length, 'height' => $square_length, 'fill' => $this_color), $g_rect);
             // draw text
             $g_text = $this->svg_dom->make_g(array('font-size' => self::$c['size']['key'], 'fill' => $this_color));
             $this->svg_dom->add_text_element($identifier_title, array('x' => $x + $square_length + 4, 'y' => $y), $g_text);
             // draw min/avg/max
             $x_stat_loc = $x + $square_length + $this->i['key_longest_string_width'] + 10;
             $vals = $this->test_result->test_result_buffer->buffer_items[$i]->get_result_value();
             $attributes = array('y' => $y);
             $stat_word_width = $this->get_stat_word_width();
             $stat_array = $this->calc_min_avg_max($vals);
             $precise_stat_array = array();
             foreach ($stat_array as $stat_value) {
                 array_push($precise_stat_array, pts_math::set_precision($stat_value, $precision));
             }
             $attributes['x'] = $x_stat_loc;
             foreach ($precise_stat_array as $stat_value) {
                 $this->svg_dom->add_text_element(strval($stat_value), $attributes, $g_text);
                 $attributes['x'] += $stat_word_width;
             }
         }
     }
 }
 public function normalize_buffer_values($normalize_against = false)
 {
     if ($this->test_profile->get_display_format() != 'BAR_GRAPH') {
         return false;
     }
     $is_multi_way = pts_render::multi_way_identifier_check($this->test_result_buffer->get_identifiers());
     $keys = array_keys($this->test_result_buffer->buffer_items);
     if ($is_multi_way) {
         $key_sets = array();
         foreach ($keys as $k) {
             $identifier_r = pts_strings::trim_explode(': ', $this->test_result_buffer->buffer_items[$k]->get_result_identifier());
             if (!isset($key_sets[$identifier_r[0]])) {
                 $key_sets[$identifier_r[0]] = array();
             }
             $key_sets[$identifier_r[0]][] = $k;
         }
     } else {
         $key_sets = array($keys);
     }
     foreach ($key_sets as $keys) {
         if ($this->test_profile->get_result_proportion() == 'LIB') {
             // Invert values for LIB
             foreach ($keys as $k) {
                 $this->test_result_buffer->buffer_items[$k]->reset_result_value(1 / $this->test_result_buffer->buffer_items[$k]->get_result_value());
             }
         }
         $divide_value = -1;
         if ($normalize_against != false) {
             foreach ($keys as $k) {
                 if ($is_multi_way && strpos($this->test_result_buffer->buffer_items[$k]->get_result_identifier(), ': ' . $normalize_against) !== false) {
                     // This allows it to just normalize against part of the string
                     $divide_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
                     break;
                 } else {
                     if ($this->test_result_buffer->buffer_items[$k]->get_result_identifier() == $normalize_against) {
                         $divide_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
                         break;
                     }
                 }
             }
         }
         if ($divide_value == -1) {
             foreach ($keys as $k) {
                 if ($this->test_result_buffer->buffer_items[$k]->get_result_value() < $divide_value || $divide_value == -1) {
                     $divide_value = $this->test_result_buffer->buffer_items[$k]->get_result_value();
                 }
             }
         }
         if ($divide_value != 0) {
             foreach ($keys as $k) {
                 $normalized = pts_math::set_precision($this->test_result_buffer->buffer_items[$k]->get_result_value() / $divide_value, max(3, $this->result_precision));
                 $this->test_result_buffer->buffer_items[$k]->reset_result_value($normalized);
                 $this->test_result_buffer->buffer_items[$k]->reset_raw_value(0);
             }
         }
     }
     $this->test_profile->set_result_proportion('HIB');
     $this->test_profile->set_result_scale('Relative Performance');
     return true;
 }
 private static function process_perf_per_watt_collection(&$test_run_manager)
 {
     if (count(self::$perf_per_watt_collection) > 2) {
         // Performance per watt overall
         $avg = array_sum(self::$perf_per_watt_collection) / count(self::$perf_per_watt_collection);
         $test_profile = new pts_test_profile();
         $test_result = new pts_test_result($test_profile);
         $test_result->test_profile->set_test_title('Meta Performance Per Watt');
         $test_result->test_profile->set_identifier(null);
         $test_result->test_profile->set_version(null);
         $test_result->test_profile->set_result_proportion(null);
         $test_result->test_profile->set_display_format('BAR_GRAPH');
         $test_result->test_profile->set_result_scale('Performance Per Watt');
         $test_result->test_profile->set_result_proportion('HIB');
         $test_result->set_used_arguments_description('Performance Per Watt');
         $test_result->set_used_arguments('Per-Per-Watt');
         $test_result->test_result_buffer = new pts_test_result_buffer();
         $test_result->test_result_buffer->add_test_result(self::$result_identifier, pts_math::set_precision($avg));
         $test_run_manager->result_file->add_result($test_result);
     }
 }
 protected function render_graph_bars()
 {
     $bar_count = count($this->results);
     $separator_height = ($a = 6 - floor($bar_count / 2) * 2) > 0 ? $a : 0;
     $bar_height = floor(($this->i['identifier_height'] - ($this->is_multi_way_comparison ? 4 : 0) - $separator_height - $bar_count * $separator_height) / $bar_count);
     $this->i['graph_max_value'] = $this->i['graph_max_value'] != 0 ? $this->i['graph_max_value'] : 1;
     $work_area_width = $this->i['graph_left_end'] - $this->i['left_start'];
     $group_offsets = array();
     $id_offsets = array();
     $g_bars = $this->svg_dom->make_g(array('stroke' => self::$c['color']['body_light'], 'stroke-width' => 1));
     $g_se = $this->svg_dom->make_g(array('font-size' => $this->i['identifier_size'] - 2, 'fill' => self::$c['color']['text'], 'text-anchor' => 'end'));
     $g_values = $this->svg_dom->make_g(array('font-size' => $this->i['identifier_size'], 'fill' => self::$c['color']['body_text']));
     $bar_x = $this->i['left_start'] + 0.5;
     foreach ($this->results as $identifier => &$group) {
         $paint_color = $this->get_paint_color($identifier);
         foreach ($group as &$buffer_item) {
             // if identifier is 0, not a multi-way comparison or anything special
             if ($identifier == 0 && !$this->is_multi_way_comparison) {
                 // See if the result identifier matches something to be color-coded better
                 $result_identifier = strtolower($buffer_item->get_result_identifier());
                 if (strpos($result_identifier, 'geforce') !== false || strpos($result_identifier, 'nvidia') !== false) {
                     $paint_color = '#77b900';
                 } else {
                     if (strpos($result_identifier, 'radeon') !== false || strpos($result_identifier, 'amd ') !== false) {
                         $paint_color = '#f1052d';
                     } else {
                         if (strpos($result_identifier, 'intel ') !== false) {
                             $paint_color = '#0b5997';
                         }
                     }
                 }
             }
             $i_o = $this->calc_offset($group_offsets, $identifier);
             $i = $this->calc_offset($id_offsets, $buffer_item->get_result_identifier());
             $value = $buffer_item->get_result_value();
             $graph_size = max(0, round($value / $this->i['graph_max_value'] * $work_area_width));
             $value_end_right = max($this->i['left_start'] + $graph_size, 1);
             $px_bound_top = $this->i['top_start'] + ($this->is_multi_way_comparison ? 5 : 0) + $this->i['identifier_height'] * $i + $bar_height * $i_o + $separator_height * ($i_o + 1);
             $px_bound_bottom = $px_bound_top + $bar_height;
             $middle_of_bar = $px_bound_top + $bar_height / 2 + ($this->i['identifier_size'] - 4);
             $title_tooltip = $buffer_item->get_result_identifier() . ': ' . $value;
             $std_error = -1;
             if ($raw_values = $buffer_item->get_result_raw()) {
                 $std_error = pts_strings::colon_explode($raw_values);
                 switch (count($std_error)) {
                     case 0:
                         $std_error = -1;
                         break;
                     case 1:
                         $std_error = 0;
                         break;
                     default:
                         $std_error = pts_math::standard_error($std_error);
                         break;
                 }
             }
             $this->svg_dom->add_element('rect', array('x' => $bar_x, 'y' => $px_bound_top + 0.5, 'height' => $bar_height, 'width' => $graph_size, 'fill' => in_array($buffer_item->get_result_identifier(), $this->value_highlights) ? self::$c['color']['highlight'] : $paint_color, 'xlink:title' => $title_tooltip), $g_bars);
             if ($std_error != -1 && $value != null) {
                 $std_error_height = 8;
                 if ($std_error > 0 && is_numeric($std_error)) {
                     $std_error_rel_size = round($std_error / $this->i['graph_max_value'] * ($this->i['graph_left_end'] - $this->i['left_start']));
                     if ($std_error_rel_size > 4) {
                         $std_error_base_left = $value_end_right - $std_error_rel_size + 0.5;
                         $std_error_base_right = $value_end_right + $std_error_rel_size + 0.5;
                         $this->svg_dom->draw_svg_line($std_error_base_left, $px_bound_top, $std_error_base_left, $px_bound_top + $std_error_height, self::$c['color']['notches'], 1);
                         $this->svg_dom->draw_svg_line($std_error_base_right, $px_bound_top, $std_error_base_right, $px_bound_top + $std_error_height, self::$c['color']['notches'], 1);
                         $this->svg_dom->draw_svg_line($std_error_base_left, $px_bound_top + 0.5, $std_error_base_right, $px_bound_top + 0.5, self::$c['color']['notches'], 1);
                     }
                 }
                 $bar_offset_34 = round($middle_of_bar + ($this->is_multi_way_comparison ? 0 : $bar_height / 5 + 1));
                 $this->svg_dom->add_text_element('SE +/- ' . pts_math::set_precision($std_error, 2), array('y' => $bar_offset_34, 'x' => $this->i['left_start'] - 5), $g_se);
             }
             if (self::text_string_width($value, $this->i['identifier_size']) + 2 < $graph_size) {
                 if (isset($this->d['identifier_notes'][$buffer_item->get_result_identifier()]) && $this->i['compact_result_view'] == false && !$this->is_multi_way_comparison) {
                     $note_size = self::$c['size']['key'] - 2;
                     $this->svg_dom->add_text_element($this->d['identifier_notes'][$buffer_item->get_result_identifier()], array('x' => $this->i['left_start'] + 4, 'y' => $px_bound_top + self::$c['size']['key'], 'font-size' => $note_size, 'fill' => self::$c['color']['body_text'], 'text-anchor' => 'start'));
                 }
                 $this->svg_dom->add_text_element($value, array('x' => $value_end_right - 5, 'y' => $middle_of_bar, 'text-anchor' => 'end'), $g_values);
             } else {
                 if ($value > 0) {
                     // Write it in front of the result
                     $this->svg_dom->add_text_element($value, array('x' => $value_end_right + 6, 'y' => $middle_of_bar, 'fill' => self::$c['color']['text'], 'text-anchor' => 'start'), $g_values);
                 }
             }
         }
     }
 }
 public static function calculate_end_result(&$test_result, &$active_result_buffer)
 {
     $trial_results = $active_result_buffer->results;
     if (count($trial_results) == 0) {
         $test_result->active->set_result(0);
         return false;
     }
     $END_RESULT = 0;
     switch ($test_result->test_profile->get_display_format()) {
         case 'NO_RESULT':
             // Nothing to do, there are no results
             break;
         case 'LINE_GRAPH':
         case 'FILLED_LINE_GRAPH':
         case 'TEST_COUNT_PASS':
             // Just take the first result
             $END_RESULT = $trial_results[0];
             break;
         case 'IMAGE_COMPARISON':
             // Capture the image
             $iqc_image_png = $trial_results[0];
             if (is_file($iqc_image_png)) {
                 $img_file_64 = base64_encode(file_get_contents($iqc_image_png, FILE_BINARY));
                 $END_RESULT = $img_file_64;
                 unlink($iqc_image_png);
             }
             break;
         case 'PASS_FAIL':
         case 'MULTI_PASS_FAIL':
             // Calculate pass/fail type
             $END_RESULT = -1;
             if (count($trial_results) == 1) {
                 $END_RESULT = $trial_results[0];
             } else {
                 foreach ($trial_results as $result) {
                     if ($result == 'FALSE' || $result == '0' || $result == 'FAIL' || $result == 'FAILED') {
                         if ($END_RESULT == -1 || $END_RESULT == 'PASS') {
                             $END_RESULT = 'FAIL';
                         }
                     } else {
                         if ($END_RESULT == -1) {
                             $END_RESULT = 'PASS';
                         }
                     }
                 }
             }
             break;
         case 'BAR_GRAPH':
         default:
             // Result is of a normal numerical type
             switch ($test_result->test_profile->get_result_quantifier()) {
                 case 'MAX':
                     $END_RESULT = max($trial_results);
                     break;
                 case 'MIN':
                     $END_RESULT = min($trial_results);
                     break;
                 case 'AVG':
                 default:
                     // assume AVG (average)
                     $is_float = false;
                     $TOTAL_RESULT = 0;
                     $TOTAL_COUNT = 0;
                     foreach ($trial_results as $result) {
                         $result = trim($result);
                         if (is_numeric($result)) {
                             $TOTAL_RESULT += $result;
                             $TOTAL_COUNT++;
                             if (!$is_float && strpos($result, '.') !== false) {
                                 $is_float = true;
                             }
                         }
                     }
                     $END_RESULT = pts_math::set_precision($TOTAL_RESULT / ($TOTAL_COUNT > 0 ? $TOTAL_COUNT : 1), $test_result->get_result_precision());
                     if (!$is_float) {
                         $END_RESULT = round($END_RESULT);
                     }
                     if (count($min = $active_result_buffer->min_results) > 0) {
                         $min = round(min($min), 2);
                         if ($min < $END_RESULT && is_numeric($min) && $min != 0) {
                             $test_result->active->set_min_result($min);
                         }
                     }
                     if (count($max = $active_result_buffer->max_results) > 0) {
                         $max = round(max($max), 2);
                         if ($max > $END_RESULT && is_numeric($max) && $max != 0) {
                             $test_result->active->set_max_result($max);
                         }
                     }
                     break;
             }
             break;
     }
     $test_result->active->set_result($END_RESULT);
 }
 public static function __event_results_process(&$test_run_manager)
 {
     if (count(self::$perf_per_dollar_collection) > 2) {
         $avg = array_sum(self::$perf_per_dollar_collection) / count(self::$perf_per_dollar_collection);
         $avg_perf_dollar = $avg / self::$COST_PERF_PER_DOLLAR;
         $test_profile = new pts_test_profile();
         $test_result = new pts_test_result($test_profile);
         $test_result->test_profile->set_test_title('Meta Performance Per Dollar');
         $test_result->test_profile->set_identifier(null);
         $test_result->test_profile->set_version(null);
         $test_result->test_profile->set_result_proportion(null);
         $test_result->test_profile->set_display_format('BAR_GRAPH');
         $test_result->test_profile->set_result_scale('Performance Per Dollar');
         $test_result->test_profile->set_result_proportion('HIB');
         $test_result->set_used_arguments_description('Performance Per Dollar');
         $test_result->set_used_arguments('Per-Per-Dollar');
         $test_result->test_result_buffer = new pts_test_result_buffer();
         $test_result->test_result_buffer->add_test_result(self::$result_identifier, pts_math::set_precision($avg_perf_dollar), null, array('install-footnote' => '$' . self::$COST_PERF_PER_DOLLAR . ' reported cost. Average result: ' . pts_math::set_precision($avg) . '.'));
         $test_run_manager->result_file->add_result($test_result);
     }
 }
 public static function cpu_default_frequency($cpu_core = 0)
 {
     // Find out the processor frequency
     $info = null;
     // First, the ideal way, with modern CPUs using CnQ or EIST and cpuinfo reporting the current
     if (is_file('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq')) {
         $info = pts_file_io::file_get_contents('/sys/devices/system/cpu/cpu' . $cpu_core . '/cpufreq/scaling_max_freq');
         $info = intval($info) / 1000000;
         if ($info > 9) {
             // For some reason on Linux 3.10 the scaling_max_freq is reported as 25GHz...
             $info = null;
         }
     }
     if ($info == null && isset(phodevi::$vfs->cpuinfo)) {
         $cpu_mhz = self::read_cpuinfo_line('cpu MHz');
         $info = $cpu_mhz / 1000;
         if (empty($info)) {
             $cpu_mhz = self::read_cpuinfo_line('clock');
             $info = $cpu_mhz / 1000;
         }
     } else {
         if ($info == null && phodevi::is_bsd()) {
             $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq_levels'));
             if ($info != null) {
                 // Popping the top speed off of dev.cpu.0.freq_levels should be the default/highest supported frequency
                 $info = pts_arrays::first_element(explode(' ', str_replace('/', ' ', $info)));
                 if (!is_numeric($info)) {
                     $info = null;
                 }
             }
             if ($info == null) {
                 $info = phodevi_bsd_parser::read_sysctl(array('hw.acpi.cpu.px_global', 'machdep.est.frequency.target', 'hw.cpuspeed'));
             }
             if ($info == null) {
                 // dev.cpu.0.freq seems to be the real/current frequency, affected by power management, etc so only use as last fallback
                 $info = phodevi_bsd_parser::read_sysctl(array('dev.cpu.0.freq'));
             }
             if (is_numeric($info)) {
                 $info = $info / 1000;
             } else {
                 $info = null;
             }
         } else {
             if ($info == null && phodevi::is_windows()) {
                 $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Stock frequency');
                 if ($info != null) {
                     if (($e = strpos($info, ' MHz')) !== false) {
                         $info = substr($info, 0, $e);
                     }
                     $info = $info / 1000;
                 }
             } else {
                 if ($info == null) {
                     $info = phodevi::read_sensor(array('cpu', 'freq'));
                     if ($info > 1000) {
                         // Convert from MHz to GHz
                         $info = $info / 1000;
                     }
                 }
             }
         }
     }
     return pts_math::set_precision($info, 2);
 }