123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- <!-- https://www.createwithdata.com/chartjs-and-csv/ -->
- <!-- https://towardsdatascience.com/4-ways-to-improve-your-plotly-graphs-517c75947f7e -->
- <?php
- $branch = 'dev';
- function getsmth($branch){
- $url = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/";
- $text = file_get_contents($url);
- $arrays = explode("\n", $text);
- $clean_arrs = array_filter($arrays, function($value){
- $temp_arr = explode('/', $value);
- return preg_match("/[A-Z]+[0-9]+\//", $value);
- });
- foreach($clean_arrs as &$val){
- $val = substr($val, 0, -1);
- }
- return $clean_arrs;
- }
- $availableSeasons = getsmth($branch);
- $season = isset($_GET["season"])&&in_array($_GET["season"], $availableSeasons) ? $_GET["season"] : reset($availableSeasons);
- $url = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/".$season."/";
- $url_total_info = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/".$season.".csv";
- $text = file_get_contents($url);
- $arrays = explode("\n", $text);
- $cleanArrs = array_filter($arrays, function($value) {
- return end(explode('.', $value)) == "csv";
- });
- function isSelected($a, $b){
- if ($a==$b){
- return "selected";
- }
- return "";
- }
- $selected_csv = isset($_GET["csv_file"])&&in_array($_GET["csv_file"], $cleanArrs) ? $_GET["csv_file"] : reset($cleanArrs);
- ?>
- <html>
- <head>
- <script src="plotly-latest.min.js"></script>
- <!-- <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> -->
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="stylesheet" href="main.css">
- <title>Compton interactive plots</title>
- <!-- <script src="chart.js"></script> -->
- </head>
- <body>
- <div id="gd" style="height: max(80vh, 600px); padding-bottom: 20px;"></div>
-
- <form name="form" action="" method="get">
- <p style="text-align: center;">Select energy point:</p>
- <div style="margin: 0 auto; display: flex; justify-content: center;">
- <select name="season" class="select-css" style="margin: 0;" onchange="this.form.submit()">
- <? foreach($availableSeasons as $s){ ?>
- <option value="<?echo $s?>" <?echo isSelected($s, $season)?>><?echo $s?></option>
- <? } ?>
- </select>
- <select name="csv_file" class="select-css" style="margin: 0;" onchange="this.form.submit()">
- <? foreach($cleanArrs as $file){ ?>
- <option value="<?echo $file?>" <?echo isSelected($file, $selected_csv)?>><?echo $file?></option>
- <? } ?>
- </select>
- </div>
- </form>
- <script>
- function makeplot(){
- Plotly.d3.csv('<?echo $url_total_info;?>', (allRows)=>{
- const {mean_energy, mean_spread, mean_energy_stat_err} = parseResultsTable(allRows, "<?echo $selected_csv;?>");
- Plotly.d3.csv('<?echo $url.$selected_csv;?>', function(data){processData(data, mean_energy, mean_spread, mean_energy_stat_err)});
- }
- );
- }
-
- function parseResultsTable(allRows, energy_point){
- // Extracts a row following the energy point in the total csv file (or null if energy point is not exists)
- data = energy_point.slice(0, -4).split('_');
- for (var i=0; i<allRows.length; i++){
- if (allRows[i].first_run == data[1] ){
- return allRows[i];
- }
- }
- return null;
- }
-
- function parseRow(row){
- // Parses a row from the detailed csv file
- row['start_time'] = Date.parse(row['compton_start']);
- row['stop_time'] = Date.parse(row['compton_stop']);
- row['center_time'] = new Date((row['start_time'] + row['stop_time'])/2);
- row['timedelta'] = (row['stop_time'] - row['start_time'])/2/1000; // in seconds
- text_energy = "E = " + parseFloat(row['e_mean']).toFixed(2) + "±" + parseFloat(row['e_std']).toFixed(2) + " MeV<br>";
- text_spread = "spread = " + parseFloat(row['spread_mean']).toFixed(2) + "±" + parseFloat(row['spread_std']).toFixed(2) + " MeV<br>";
- text_str = text_energy + text_spread + "<b>Compton</b><br>" + "<i>Start: </i>" +
- row['compton_start'] + "<br><i>Stop: </i>" + row['compton_stop'] + "<br><br>";
- row['text_str'] = text_str + "<b>Runs: </b>" + row['run_first'] + " - " + row['run_last'] + "<br><br>";
- return row;
- }
-
- function processSpread(data, elementId, mean_value){
- let x = [], y = [], std_y = []
- for (var i=0; i<data.length; i++){
- const {center_time, spread_mean, spread_std} = parseRow(data[i]);
- x.push(center_time);
- y.push(spread_mean);
- std_y.push(spread_std);
- }
- makeSpreadPlot(elementId, x, y, std_y, mean_value);
- }
-
- function kde(x, y, w) {
- const ts = (t) => t.getTime()/1000;
- const toDateTime = (secs) => {
- let t = new Date(0);
- t.setSeconds(secs);
- return t;
- };
- const steps = 1000;
- const dt = (ts(x[x.length - 1]) - ts(x[0]))/steps;
- const kernel = (x, x0, w0, y0) => {
- if (Math.abs(x-x0)>w0){
- return 0;
- }
- return y0/w0;
- //return y0*3*(1-((x-x0)/w0/2)**2)/4;
- };
- const get_est = (timestamp) => {
- let val = 0
- for (var i=0; i<x.length; i++){
- val += kernel(timestamp, ts(x[i]), w[i], y[i]);
- }
- return val;
- };
- //console.log(x, y);
- const timestamp_arr = Plotly.d3.range(steps).map(function(i){return ts(x[0])+i*dt;});
-
- let kdex = [];
- let kdey = [];
- for (var j=0; j<timestamp_arr.length; j++){
- kdex.push(toDateTime(timestamp_arr[j]));
- kdey.push(get_est(timestamp_arr[j]));
- }
- //console.log(kdex, kdey);
- return [kdex, kdey]
- }
-
- function oldAverage(E, L){
- //Averager by the old method with E and L only
- if (E.length !== L.length){
- return null;
- }
- let EL = 0;
- let sL = 0;
- for (let i = 0; i<E.length; i++){
- EL += parseFloat(E[i])*parseFloat(L[i]);
- sL += parseFloat(L[i]);
- }
- return EL/sL;
- }
-
- function processData(allRows, mean_energy, mean_spread, mean_energy_stat_err) {
- // Processes all data rows
- var dict = {};
- dict['x'] = [];
- dict['e_mean'] = [];
- dict['e_std'] = [];
- dict['spread_mean'] = [];
- dict['spread_std'] = [];
- dict['compton'] = [];
- dict['lum'] = [];
- dict['twidth'] = [];
-
- for (var i=0; i<allRows.length; i++){
- const row = parseRow(allRows[i]);
-
- dict['x'].push( row['center_time'] );
- dict['e_mean'].push( row['e_mean'] );
- dict['e_std'].push( row['e_std'] );
- dict['spread_mean'].push( row['spread_mean'] );
- dict['spread_std'].push( row['spread_std'] );
- dict['compton'].push( row['text_str'] );
- dict['lum'].push( row['luminosity'] );
- dict['twidth'].push( row['timedelta'] );
- }
-
- const [a, b] = kde(dict['x'], dict['lum'], dict['twidth']);
- dict['kdex'] = a;
- dict['kdey'] = b;
- //console.log(dict['kdex'], dict['kdey']);
- //oldAverage(y, dict['lum']);
-
- dict['mean_energy_total'] = mean_energy;
- dict['old_mean_energy_total'] = oldAverage(dict['e_mean'], dict['lum']);
- dict['mean_spread_total'] = mean_spread;
- dict['mean_energy_stat_err'] = mean_energy_stat_err;
-
- makePlotly(dict, "gd");
- }
-
- function makePlotly(dict, elementId){
- const getYRange = (y, std_y) => {
- const ys = [...y].sort();
- const std_ys = [...std_y].sort();
- let idx = Math.floor(ys.length/2);
- const y0 = parseFloat(ys[idx]);
- const std0 = parseFloat(std_ys[idx]);
- return [y0-6*std0, y0+6*std0];
- };
-
- var trace1 = {
- x: dict['x'],
- y: dict['e_mean'],
- yaxis: 'y3',
- mode: 'markers',
- text: dict['compton'],
- hovertemplate: "%{text}<br><br>" + "<extra></extra>",
- hovermode: "x",
- error_y: {
- type: 'data',
- array: dict['e_std'],
- color: '#260101',
- },
- showlegend: false,
- marker: {
- color: '#260101',
- },
- type: "scatter",
- };
- var trace2 = {
- x: dict['x'],
- y: dict['spread_mean'],
- yaxis: 'y2',
- mode: 'markers',
- text: dict['compton'],
- hovertemplate: "%{text}<br><br>" + "<extra></extra>",
- hovermode: "x",
- error_y: {
- type: 'data',
- array: dict['spread_std'],
- color: '#260101',
- },
- showlegend: false,
- marker: {
- color: '#260101',
- },
- type: "scatter",
- };
- var trace3 = {
- x: dict['kdex'],
- y: dict['kdey'],
- hovertemplate: "%{y}<br><br>" + "<extra></extra>",
- hovermode: "x",
- showlegend: false,
- marker: {
- color: '#F23030',
- },
- line: {
- shape: 'hvh',
- },
- type: "scatter",
- };
- var traces = [trace1, trace2, trace3];
-
- var updatemenus = [];
- console.log(dict);
- if (dict['mean_energy_total']){
- updatemenus = [{
- buttons: [
- {
- args:[{'shapes[0].visible': true, 'shapes[1].visible': false, 'title': '<E> = ' + parseFloat(dict['mean_energy_total']).toFixed(3) + '±' + parseFloat(dict['mean_energy_stat_err']).toFixed(3) + ' MeV, ' + '<Spread> = ' + parseFloat(dict['mean_spread_total']).toFixed(3) + ' MeV',}],
- label: 'Current average method',
- method: 'relayout'
- }, {
- args:[{'shapes[0].visible': false, 'shapes[1].visible': true, 'title': '<E> = ' + parseFloat(dict['old_mean_energy_total']).toFixed(3) + ' MeV, ' + '<Spread> = ' + parseFloat(dict['mean_spread_total']).toFixed(3) + ' MeV',}],
- label: 'Former average method',
- method: 'relayout'
- },
- ],
- direction: 'center',
- showactive: 'true',
- type: 'dropdown',
- y: 1.1,
- xanchor: 'left',
- yanchor: 'top',
- active: 0,
- }];
- }
-
- var layout = {
- title: '<E> = ' + parseFloat(dict['mean_energy_total']).toFixed(3) + '±' + parseFloat(dict['mean_energy_stat_err']).toFixed(3) + ' MeV, ' + '<Spread> = ' + parseFloat(dict['mean_spread_total']).toFixed(3) + ' MeV',
- updatemenus: updatemenus,
- font: {
- size: 16,
- },
- xaxis: {
- title: "Time, NSK",
- automargin: true,
- },
- yaxis3: {
- domain: [0.6, 1],
- title: "Mean energy, MeV",
- automargin: true,
- //showspikes: true,
- //spikemode: "across",
- //spikesnap: "data",
- },
- yaxis2: {
- domain: [0.3, 0.5],
- title: "Spread, MeV",
- autorange: false,
- range: getYRange(dict['spread_mean'], dict['spread_std']),
- //showspikes: true,
- //spikemode: "across",
- //spikesnap: "data",
- },
- yaxis: {
- domain: [0, 0.2],
- automargin: true,
- zeroline: true,
- rangemode: 'positive',
- title: "L, nb<sup>-1</sup>/s",
- hoverformat: '.2f',
- },
- paper_bgcolor: 'rgba(0,0,0,0)',
- plot_bgcolor: 'rgba(0,0,0,0)',
- autosize: true,
- };
-
- if (dict['mean_energy_total']){
- layout['shapes'] = [{
- type: 'line',
- yref: 'y3',
- xref: 'paper',
- x0: 0,
- x1: 1,
- y0: dict['mean_energy_total'],
- y1: dict['mean_energy_total'],
- line: {
- color: '#590A0A',
- },
- },
- {
- type: 'line',
- yref: 'y3',
- xref: 'paper',
- x0: 0,
- x1: 1,
- y0: dict['old_mean_energy_total'],
- y1: dict['old_mean_energy_total'],
- line: {
- color: '#590A0A',
- },
- visible: false,
- },
- {
- type: 'line',
- yref: 'y2',
- xref: 'paper',
- x0: 0,
- x1: 1,
- y0: dict['mean_spread_total'],
- y1: dict['mean_spread_total'],
- line: {
- color: '#590A0A',
- },
- visible: true,
- }];
- }
-
- Plotly.newPlot('gd', traces, layout, {modeBarButtonsToRemove: ['toImage'], responsive: true,});
-
- }
-
- makeplot();
-
- </script>
- </body>
- </html>
|