|
@@ -0,0 +1,285 @@
|
|
|
+<!-- https://www.createwithdata.com/chartjs-and-csv/ -->
|
|
|
+<!-- https://towardsdatascience.com/4-ways-to-improve-your-plotly-graphs-517c75947f7e -->
|
|
|
+
|
|
|
+<?php
|
|
|
+$selected_csv =
|
|
|
+
|
|
|
+$branch = 'dev';
|
|
|
+$season = 'NNBAR2021';
|
|
|
+$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"]) ? $_GET["csv_file"] : reset($cleanArrs);
|
|
|
+
|
|
|
+?>
|
|
|
+
|
|
|
+<html>
|
|
|
+<head>
|
|
|
+ <!--<script src="plotly-2.11.1.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(70vh, 400px); padding-bottom: 20px;"></div>
|
|
|
+
|
|
|
+ <form name="form" action="" method="get">
|
|
|
+ <p style="text-align: center;">Select energy point:</p>
|
|
|
+ <select name="csv_file" class="select-css" onchange="this.form.submit()">
|
|
|
+ <?
|
|
|
+ foreach($cleanArrs as $file){
|
|
|
+ ?><option value="<?echo $file?>" <?echo isSelected($file, $selected_csv)?>><?echo $file?></option>
|
|
|
+ <?
|
|
|
+ }
|
|
|
+ ?>
|
|
|
+ </select>
|
|
|
+ </form>
|
|
|
+
|
|
|
+
|
|
|
+ <script>
|
|
|
+ function makeplot(){
|
|
|
+ Plotly.d3.csv('<?echo $url_total_info;?>', (allRows)=>{
|
|
|
+ const getEnergy = () => {
|
|
|
+ for (var i=0; i<allRows.length; i++){
|
|
|
+ if (allRows[i].energy_point == <?echo reset(explode('_', $selected_csv));?> ){
|
|
|
+ return allRows[i].mean_energy;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ };
|
|
|
+ Plotly.d3.csv('<?echo $url.$selected_csv;?>', function(data){processData(data, getEnergy())});
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ 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){
|
|
|
+ //console.log(E, L);
|
|
|
+ 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]);
|
|
|
+ }
|
|
|
+ //console.log(EL, sL, EL/sL);
|
|
|
+ return EL/sL;
|
|
|
+ }
|
|
|
+
|
|
|
+ function processData(allRows, mean_energy) {
|
|
|
+ // console.log(allRows);
|
|
|
+ var x = [], y = [], std_y = [];
|
|
|
+ var dict = {};
|
|
|
+ dict['compton'] = [];
|
|
|
+ dict['lum'] = [];
|
|
|
+ dict['twidth'] = [];
|
|
|
+
|
|
|
+ for (var i=0; i<allRows.length; i++){
|
|
|
+ row = allRows[i];
|
|
|
+ start_time = Date.parse(row['compton_start']);
|
|
|
+ stop_time = Date.parse(row['compton_stop']);
|
|
|
+ center_time = new Date((start_time + stop_time)/2);
|
|
|
+ let timedelta = (stop_time - start_time)/2/1000; // in seconds
|
|
|
+
|
|
|
+ x.push( center_time );
|
|
|
+ y.push( row['e_mean'] );
|
|
|
+ std_y.push( row['e_std'] );
|
|
|
+
|
|
|
+ text_str = "<b>Compton</b><br>" + "<i>Start: </i>" +
|
|
|
+ row['compton_start'] + "<br><i>Stop: </i>" + row['compton_stop'] + "<br><br>";
|
|
|
+ text_str = text_str + "<b>Runs: </b>" + row['run_first'] + " - " + row['run_last'] + "<br><br>";
|
|
|
+ dict['compton'].push(text_str);
|
|
|
+ dict['lum'].push(row['luminosity']);
|
|
|
+ dict['twidth'].push(timedelta);
|
|
|
+ }
|
|
|
+ //console.log( 'X',x, 'Y',y, 'SD', dict );
|
|
|
+ const [a, b] = kde(x, dict['lum'], dict['twidth']);
|
|
|
+ dict['kdex'] = a;
|
|
|
+ dict['kdey'] = b;
|
|
|
+ //console.log(dict['kdex'], dict['kdey']);
|
|
|
+ //oldAverage(y, dict['lum']);
|
|
|
+ makePlotly( x, y, std_y, dict, mean_energy, oldAverage(y, dict['lum']));
|
|
|
+ }
|
|
|
+
|
|
|
+ function makePlotly( x, y, std_y, dict, mean_energy, old_mean){
|
|
|
+ var plotDiv = document.getElementById("gd");
|
|
|
+ var trace1 = {
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ yaxis: 'y2',
|
|
|
+ mode: 'markers',
|
|
|
+ text: dict['compton'],
|
|
|
+ hovertemplate: "%{text}<br><br>" + "<extra></extra>",
|
|
|
+ hovermode: "x",
|
|
|
+ error_y: {
|
|
|
+ type: 'data',
|
|
|
+ array: std_y,
|
|
|
+ color: '#260101',
|
|
|
+ },
|
|
|
+ showlegend: false,
|
|
|
+ marker: {
|
|
|
+ color: '#260101',
|
|
|
+ },
|
|
|
+ type: "scatter",
|
|
|
+ };
|
|
|
+ var trace2 = {
|
|
|
+ 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];
|
|
|
+
|
|
|
+ var updatemenus = [];
|
|
|
+ if (mean_energy){
|
|
|
+ updatemenus = [{
|
|
|
+ buttons: [
|
|
|
+ {
|
|
|
+ args:[{'shapes[0].visible': true, 'shapes[1].visible': false, 'title': 'Mean energy: ' + parseFloat(mean_energy).toFixed(3) + ' MeV',}],
|
|
|
+ label: 'Current average method',
|
|
|
+ method: 'relayout'
|
|
|
+ }, {
|
|
|
+ args:[{'shapes[0].visible': false, 'shapes[1].visible': true, 'title': 'Mean energy: ' + old_mean.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: 'Mean energy: ' + mean_energy + ' MeV',
|
|
|
+ updatemenus: updatemenus,
|
|
|
+ font: {
|
|
|
+ size: 18,
|
|
|
+ },
|
|
|
+ xaxis: {
|
|
|
+ title: "Time, NSK",
|
|
|
+ automargin: true,
|
|
|
+ },
|
|
|
+ yaxis2: {
|
|
|
+ domain: [0.3, 1],
|
|
|
+ title: "Measured energy, MeV",
|
|
|
+ automargin: true,
|
|
|
+ //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 (mean_energy){
|
|
|
+ layout['shapes'] = [{
|
|
|
+ type: 'line',
|
|
|
+ yref: 'y2',
|
|
|
+ xref: 'paper',
|
|
|
+ x0: 0,
|
|
|
+ x1: 1,
|
|
|
+ y0: mean_energy,
|
|
|
+ y1: mean_energy,
|
|
|
+ line: {
|
|
|
+ color: '#590A0A',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ yref: 'y2',
|
|
|
+ xref: 'paper',
|
|
|
+ x0: 0,
|
|
|
+ x1: 1,
|
|
|
+ y0: old_mean,
|
|
|
+ y1: old_mean,
|
|
|
+ line: {
|
|
|
+ color: '#590A0A',
|
|
|
+ },
|
|
|
+ visible: false,
|
|
|
+ }];
|
|
|
+ }
|
|
|
+
|
|
|
+ Plotly.newPlot('gd', traces, layout, {modeBarButtonsToRemove: ['toImage'], responsive: true,});
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ makeplot();
|
|
|
+
|
|
|
+ </script>
|
|
|
+
|
|
|
+</body>
|
|
|
+</html>
|