0
0

plots.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <!-- https://www.createwithdata.com/chartjs-and-csv/ -->
  2. <!-- https://towardsdatascience.com/4-ways-to-improve-your-plotly-graphs-517c75947f7e -->
  3. <?php
  4. $selected_csv =
  5. $branch = 'dev';
  6. $season = 'NNBAR2021';
  7. $url = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/".$season."/";
  8. $url_total_info = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/".$season.".csv";
  9. $text = file_get_contents($url);
  10. $arrays = explode("\n", $text);
  11. $cleanArrs = array_filter($arrays, function($value) {
  12. return end(explode('.', $value)) == "csv";
  13. });
  14. function isSelected($a, $b){
  15. if ($a==$b){
  16. return "selected";
  17. }
  18. return "";
  19. }
  20. $selected_csv = isset($_GET["csv_file"]) ? $_GET["csv_file"] : reset($cleanArrs);
  21. ?>
  22. <html>
  23. <head>
  24. <!--<script src="plotly-2.11.1.min.js"></script> -->
  25. <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
  26. <meta name="viewport" content="width=device-width, initial-scale=1">
  27. <link rel="stylesheet" href="main.css">
  28. <title>Compton interactive plots</title>
  29. <!-- <script src="chart.js"></script> -->
  30. </head>
  31. <body>
  32. <div id="gd" style="height: max(70vh, 400px); padding-bottom: 20px;"></div>
  33. <form name="form" action="" method="get">
  34. <p style="text-align: center;">Select energy point:</p>
  35. <select name="csv_file" class="select-css" onchange="this.form.submit()">
  36. <?
  37. foreach($cleanArrs as $file){
  38. ?><option value="<?echo $file?>" <?echo isSelected($file, $selected_csv)?>><?echo $file?></option>
  39. <?
  40. }
  41. ?>
  42. </select>
  43. </form>
  44. <script>
  45. function makeplot(){
  46. Plotly.d3.csv('<?echo $url_total_info;?>', (allRows)=>{
  47. const getEnergy = () => {
  48. for (var i=0; i<allRows.length; i++){
  49. if (allRows[i].energy_point == <?echo reset(explode('_', $selected_csv));?> ){
  50. return allRows[i].mean_energy;
  51. }
  52. }
  53. return null;
  54. };
  55. Plotly.d3.csv('<?echo $url.$selected_csv;?>', function(data){processData(data, getEnergy())});
  56. }
  57. );
  58. }
  59. function kde(x, y, w) {
  60. const ts = (t) => t.getTime()/1000;
  61. const toDateTime = (secs) => {
  62. let t = new Date(0);
  63. t.setSeconds(secs);
  64. return t;
  65. };
  66. const steps = 1000;
  67. const dt = (ts(x[x.length - 1]) - ts(x[0]))/steps;
  68. const kernel = (x, x0, w0, y0) => {
  69. if (Math.abs(x-x0)>w0){
  70. return 0;
  71. }
  72. return y0/w0;
  73. //return y0*3*(1-((x-x0)/w0/2)**2)/4;
  74. };
  75. const get_est = (timestamp) => {
  76. let val = 0
  77. for (var i=0; i<x.length; i++){
  78. val += kernel(timestamp, ts(x[i]), w[i], y[i]);
  79. }
  80. return val;
  81. };
  82. //console.log(x, y);
  83. const timestamp_arr = Plotly.d3.range(steps).map(function(i){return ts(x[0])+i*dt;});
  84. let kdex = [];
  85. let kdey = [];
  86. for (var j=0; j<timestamp_arr.length; j++){
  87. kdex.push(toDateTime(timestamp_arr[j]));
  88. kdey.push(get_est(timestamp_arr[j]));
  89. }
  90. //console.log(kdex, kdey);
  91. return [kdex, kdey]
  92. }
  93. function oldAverage(E, L){
  94. //console.log(E, L);
  95. if (E.length !== L.length){
  96. return null;
  97. }
  98. let EL = 0;
  99. let sL = 0;
  100. for (let i = 0; i<E.length; i++){
  101. EL += parseFloat(E[i])*parseFloat(L[i]);
  102. sL += parseFloat(L[i]);
  103. }
  104. //console.log(EL, sL, EL/sL);
  105. return EL/sL;
  106. }
  107. function processData(allRows, mean_energy) {
  108. // console.log(allRows);
  109. var x = [], y = [], std_y = [];
  110. var dict = {};
  111. dict['compton'] = [];
  112. dict['lum'] = [];
  113. dict['twidth'] = [];
  114. for (var i=0; i<allRows.length; i++){
  115. row = allRows[i];
  116. start_time = Date.parse(row['compton_start']);
  117. stop_time = Date.parse(row['compton_stop']);
  118. center_time = new Date((start_time + stop_time)/2);
  119. let timedelta = (stop_time - start_time)/2/1000; // in seconds
  120. x.push( center_time );
  121. y.push( row['e_mean'] );
  122. std_y.push( row['e_std'] );
  123. text_str = "<b>Compton</b><br>" + "<i>Start: </i>" +
  124. row['compton_start'] + "<br><i>Stop: </i>" + row['compton_stop'] + "<br><br>";
  125. text_str = text_str + "<b>Runs: </b>" + row['run_first'] + " - " + row['run_last'] + "<br><br>";
  126. dict['compton'].push(text_str);
  127. dict['lum'].push(row['luminosity']);
  128. dict['twidth'].push(timedelta);
  129. }
  130. //console.log( 'X',x, 'Y',y, 'SD', dict );
  131. const [a, b] = kde(x, dict['lum'], dict['twidth']);
  132. dict['kdex'] = a;
  133. dict['kdey'] = b;
  134. //console.log(dict['kdex'], dict['kdey']);
  135. //oldAverage(y, dict['lum']);
  136. makePlotly( x, y, std_y, dict, mean_energy, oldAverage(y, dict['lum']));
  137. }
  138. function makePlotly( x, y, std_y, dict, mean_energy, old_mean){
  139. var plotDiv = document.getElementById("gd");
  140. var trace1 = {
  141. x: x,
  142. y: y,
  143. yaxis: 'y2',
  144. mode: 'markers',
  145. text: dict['compton'],
  146. hovertemplate: "%{text}<br><br>" + "<extra></extra>",
  147. hovermode: "x",
  148. error_y: {
  149. type: 'data',
  150. array: std_y,
  151. color: '#260101',
  152. },
  153. showlegend: false,
  154. marker: {
  155. color: '#260101',
  156. },
  157. type: "scatter",
  158. };
  159. var trace2 = {
  160. x: dict['kdex'],
  161. y: dict['kdey'],
  162. hovertemplate: "%{y}<br><br>" + "<extra></extra>",
  163. hovermode: "x",
  164. showlegend: false,
  165. marker: {
  166. color: '#F23030',
  167. },
  168. line: {
  169. shape: 'hvh',
  170. },
  171. type: "scatter",
  172. };
  173. var traces = [trace1, trace2];
  174. var updatemenus = [];
  175. if (mean_energy){
  176. updatemenus = [{
  177. buttons: [
  178. {
  179. args:[{'shapes[0].visible': true, 'shapes[1].visible': false, 'title': 'Mean energy: ' + parseFloat(mean_energy).toFixed(3) + ' MeV',}],
  180. label: 'Current average method',
  181. method: 'relayout'
  182. }, {
  183. args:[{'shapes[0].visible': false, 'shapes[1].visible': true, 'title': 'Mean energy: ' + old_mean.toFixed(3) + ' MeV',}],
  184. label: 'Former average method',
  185. method: 'relayout'
  186. },
  187. ],
  188. direction: 'center',
  189. showactive: 'true',
  190. type: 'dropdown',
  191. y: 1.1,
  192. xanchor: 'left',
  193. yanchor: 'top',
  194. active: 0,
  195. }];
  196. }
  197. var layout = {
  198. title: 'Mean energy: ' + mean_energy + ' MeV',
  199. updatemenus: updatemenus,
  200. font: {
  201. size: 18,
  202. },
  203. xaxis: {
  204. title: "Time, NSK",
  205. automargin: true,
  206. },
  207. yaxis2: {
  208. domain: [0.3, 1],
  209. title: "Measured energy, MeV",
  210. automargin: true,
  211. //showspikes: true,
  212. //spikemode: "across",
  213. //spikesnap: "data",
  214. },
  215. yaxis: {
  216. domain: [0, 0.2],
  217. automargin: true,
  218. zeroline: true,
  219. rangemode: 'positive',
  220. title: "L, nb<sup>-1</sup>/s",
  221. hoverformat: '.2f',
  222. },
  223. paper_bgcolor: 'rgba(0,0,0,0)',
  224. plot_bgcolor: 'rgba(0,0,0,0)',
  225. autosize: true,
  226. };
  227. if (mean_energy){
  228. layout['shapes'] = [{
  229. type: 'line',
  230. yref: 'y2',
  231. xref: 'paper',
  232. x0: 0,
  233. x1: 1,
  234. y0: mean_energy,
  235. y1: mean_energy,
  236. line: {
  237. color: '#590A0A',
  238. },
  239. },
  240. {
  241. type: 'line',
  242. yref: 'y2',
  243. xref: 'paper',
  244. x0: 0,
  245. x1: 1,
  246. y0: old_mean,
  247. y1: old_mean,
  248. line: {
  249. color: '#590A0A',
  250. },
  251. visible: false,
  252. }];
  253. }
  254. Plotly.newPlot('gd', traces, layout, {modeBarButtonsToRemove: ['toImage'], responsive: true,});
  255. }
  256. makeplot();
  257. </script>
  258. </body>
  259. </html>