0
0

summary.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <?php
  2. $selected_csv =
  3. $branch = 'dev';
  4. $season = 'NNBAR2021';
  5. $url = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/";
  6. $url_total_info = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/".$season.".csv";
  7. $text = file_get_contents($url);
  8. $arrays = explode("\n", $text);
  9. $cleanArrs = array_filter($arrays, function($value) {
  10. return end(explode('.', $value)) == "csv";
  11. });
  12. function isSelected($a, $b){
  13. if ($a==$b){
  14. return "selected";
  15. }
  16. return "";
  17. }
  18. $selected_csv = isset($_GET["csv_file"]) ? $_GET["csv_file"] : reset($cleanArrs);
  19. $selected_season = substr($selected_csv, 0, -4);
  20. ?>
  21. <html>
  22. <head>
  23. <script src="plotly-latest.min.js"></script>
  24. <script src="fmin.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 style="display: flex; align-items: center; flex-wrap: wrap; justify-content: center; margin-top: min(20px,2%); margin-bottom: 40px;">
  33. <h2 style="margin: 0;"><a href="index.php" style="font-size: inherit;">Pictures</a> / Season</h2>
  34. <form name="form" action="" style="padding: 0 15px; margin: auto 0;" method="get">
  35. <select name="csv_file" class="select-css" style="padding: 0.3em 1.3em 0.3em 0.4em;" onchange="this.form.submit()">
  36. <?
  37. foreach($cleanArrs as $file){
  38. ?><option value="<?echo $file?>" <?echo isSelected($file, $selected_csv)?>><?echo substr($file, 0, -4)?></option>
  39. <?
  40. }
  41. ?>
  42. </select>
  43. </form>
  44. <h2 style="margin: 0;">summary</h2>
  45. </div>
  46. <div style="display: flex; align-items: center; flex-wrap: wrap; justify-content: center;">
  47. <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
  48. <h3>Mean energy measurements</h3>
  49. <div id="mean_energy_plot"></div>
  50. </div>
  51. <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
  52. <h3>Spread measurements</h3>
  53. <div id="spread_plot"></div>
  54. </div>
  55. <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
  56. <h3>Mean energy deviations</h3>
  57. <div id="energy_dev_plot"></div>
  58. </div>
  59. <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
  60. <h3>Impact of mean energy deviations</h3>
  61. <div id="impact_energy_dev_plot"></div>
  62. </div>
  63. </div>
  64. <div style="margin-top: 40px; width: 100%;">
  65. <div style="width: min(100%, 600px); margin: 0 auto;">
  66. <h3 style="padding-right: 40px;">Methodology</h3>
  67. <p style="font-size: inherit;"><b>Mean energy measurements:</b> a difference between measured mean beam energy and target beam energy vs target beam energy.</p>
  68. <p style="font-size: inherit;"><b>Spread measurements:</b> a measured mean beam spread vs measured mean beam energy for the given energy points. A line shows the best fit of these points to a linear function (as a result of chi-square minimization)</p>
  69. <p style="font-size: inherit;"><b>Mean energy deviations:</b> a measured mean energy deviations (so-called mean_energy_sys_err) vs measured mean beam energy for the given energy points.</p>
  70. <p style="font-size: inherit;"><b>Impact of mean energy deviations:</b> a part of the mean energy deviation in total uncertainty (as d/√(d<sup>2</sup> + s<sup>2</sup>), where d is the mean energy deviation and s is the mean spread) for the given energy points.</p>
  71. </div>
  72. </div>
  73. <script>
  74. function makeplot(){
  75. Plotly.d3.csv('<?echo $url.$selected_csv;?>', (allRows)=>{
  76. const {point_name, energy_point, mean_energy, mean_energy_stat_err, mean_energy_sys_err, mean_spread, mean_spread_stat_err} = parseResultsTable(allRows);
  77. makeMeanEnergyPlot(energy_point, mean_energy, mean_energy_stat_err, point_name, "mean_energy_plot");
  78. makeSpreadPlot(mean_energy, mean_spread, mean_spread_stat_err, point_name, "spread_plot");
  79. makeMeanDevPlot(mean_energy, mean_energy_sys_err, point_name, "energy_dev_plot");
  80. makeImpactDevPlot(point_name, mean_spread, mean_energy_sys_err, "impact_energy_dev_plot");
  81. }
  82. );
  83. }
  84. function parseResultsTable(allRows){
  85. // Extracts a row following the energy point in the total csv file (or null if energy point is not exists)
  86. let data = {};
  87. for(let key of Object.keys(allRows[0])){
  88. data[key] = [];
  89. }
  90. data['point_name'] = [];
  91. let float_keys = ['energy_point', 'mean_energy', 'mean_energy_stat_err', 'mean_spread', 'mean_spread_stat_err', 'mean_energy_sys_err'];
  92. for (var i=0; i<allRows.length; i++){
  93. for(let key of Object.keys(allRows[i])){
  94. let value = allRows[i][key];
  95. if (float_keys.includes(key)){
  96. value = parseFloat(value);
  97. }
  98. data[key].push(value);
  99. }
  100. data['point_name'].push(allRows[i]['energy_point']+'_'+allRows[i]['first_run']);
  101. }
  102. return data;
  103. }
  104. function linear_coeffs(x, y, yerr, remove_outliers=false){
  105. // Returns a chi square minimizer for linear function
  106. function chi2min(X){
  107. let k = X[0], b = X[1];
  108. let chi2 = 0;
  109. for(let i=0; i<x.length; i++){
  110. if (remove_outliers&&(y[i]<0.06))
  111. continue;
  112. y0 = k*x[i] + b;
  113. chi2 += Math.pow((y[i] - y0)/yerr[i], 2);
  114. }
  115. return chi2;
  116. }
  117. return chi2min;
  118. }
  119. function getPlotlyDefaults(){
  120. var layout = {
  121. margin: {
  122. l: 50,
  123. r: 50,
  124. b: 50,
  125. t: 50,
  126. pad: 4
  127. },
  128. font: {
  129. size: 18,
  130. },
  131. xaxis: {
  132. title: "Mean beam energy, MeV",
  133. automargin: true,
  134. },
  135. yaxis: {
  136. //domain: [0, 0.2],
  137. automargin: true,
  138. rangemode: 'positive',
  139. title: "Spread, MeV",
  140. hoverformat: '.2f',
  141. },
  142. showlegend: true,
  143. legend: {
  144. x: 0,
  145. xanchor: 'left',
  146. y: 1,
  147. },
  148. paper_bgcolor: 'rgba(0,0,0,0)',
  149. plot_bgcolor: 'rgba(0,0,0,0)',
  150. autosize: true,
  151. };
  152. var config = {
  153. toImageButtonOptions: {
  154. format: 'png', // one of png, svg, jpeg, webp
  155. filename: 'spread_plot_<?echo $selected_season;?>',
  156. scale: 4,
  157. },
  158. responsive: true,
  159. modeBarButtonsToRemove: ['select2d', 'lasso2d', 'zoomIn2d', 'zoomOut2d', 'resetScale2d', 'hoverClosestGl2d', 'hoverClosestPie', 'toggleHover', 'toggleSpikelines'],
  160. displayModeBar: true,
  161. };
  162. return {
  163. "layout" : layout, "config" : config,
  164. };
  165. }
  166. function makeMeanEnergyPlot(energy_point, mean_energy, mean_energy_stat_err, texts, elementId){
  167. // Plots mean energy - target energy vs target energy
  168. var energy_diff = [];
  169. Plotly.d3.zip(mean_energy, energy_point).forEach(e => energy_diff.push(e[0] - e[1]));
  170. var trace1 = {
  171. x: energy_point,
  172. y: energy_diff,
  173. yaxis: 'y',
  174. mode: 'markers',
  175. text: Plotly.d3.zip(texts, mean_energy),
  176. text2: mean_energy,
  177. hovertemplate: "Point: %{text[0]}<br>Mean energy = %{text[1]:.3f} ± %{error_y.array:.3f} MeV" + "<extra></extra>",
  178. //hovermode: "x",
  179. error_y: {
  180. type: 'data',
  181. array: mean_energy_stat_err,
  182. color: '#260101',
  183. },
  184. showlegend: false,
  185. marker: {
  186. color: '#260101',
  187. },
  188. type: "scatter",
  189. };
  190. var traces = [trace1];
  191. var {layout, config} = getPlotlyDefaults();
  192. layout.xaxis.title = "Target energy, MeV";
  193. layout.yaxis.title = "Mean energy - Target energy, MeV";
  194. Plotly.newPlot(elementId, traces, layout, config);
  195. }
  196. function makeMeanDevPlot(mean_energy, mean_energy_sys_err, texts, elementId){
  197. // Plots mean energy deviations vs mean measured energy
  198. var trace1 = {
  199. x: mean_energy,
  200. y: mean_energy_sys_err,
  201. text: texts,
  202. mode: 'markers',
  203. marker: {
  204. size: 12,
  205. symbol: 'diamond',
  206. },
  207. hovertemplate: "Point: %{text}<br>x = %{x:.2f} MeV<br>y = %{y:.3f} MeV" + "<extra></extra>",
  208. showlegend: false,
  209. };
  210. var traces = [trace1];
  211. var {layout, config} = getPlotlyDefaults()
  212. layout.yaxis.title = "Mean energy deviation, MeV";
  213. Plotly.newPlot(elementId, traces, layout, config);
  214. }
  215. function makeSpreadPlot(mean_energy, mean_spread, mean_spread_stat_err, texts, elementId){
  216. // Plots spreads vs mean measured energy
  217. var chi2min = linear_coeffs(mean_energy, mean_spread, mean_spread_stat_err, true);
  218. var solution = fmin.nelderMead(chi2min, [0.001, 0]);
  219. var trace1 = {
  220. x: mean_energy,
  221. y: mean_spread,
  222. yaxis: 'y',
  223. mode: 'markers',
  224. text: texts,
  225. hovertemplate: "Point: %{text}<br>x = %{x:.2f} MeV<br>y = %{y:.3f} ± %{error_y.array:.3f} MeV" + "<extra></extra>",
  226. hovermode: "x",
  227. error_y: {
  228. type: 'data',
  229. array: mean_spread_stat_err,
  230. color: '#260101',
  231. },
  232. showlegend: false,
  233. marker: {
  234. color: '#260101',
  235. },
  236. type: "scatter",
  237. };
  238. var trace2 = {
  239. x: [Plotly.d3.min(mean_energy), Plotly.d3.max(mean_energy)],
  240. y: [solution.x[0]*Plotly.d3.min(mean_energy) + solution.x[1], solution.x[0]*Plotly.d3.max(mean_energy) + solution.x[1]],
  241. mode: 'lines',
  242. name: 'Fit: y = ' + Math.round(parseFloat(solution.x[0])*1e5)/1e5 + 'x ' + (Math.sign(solution.x[1])>0 ? "+" : "") + Math.round(solution.x[1]*1e3)/1e3,
  243. hovermode: false,
  244. hoverinfo: 'none',
  245. };
  246. var traces = [trace1, trace2];
  247. var {layout, config} = getPlotlyDefaults()
  248. Plotly.newPlot(elementId, traces, layout, config);
  249. }
  250. function makeImpactDevPlot(point_name, mean_spread, mean_energy_sys_err, elementId){
  251. let arr = Plotly.d3.zip(mean_spread, mean_energy_sys_err);
  252. let impact_factor = [];
  253. arr.forEach(e => impact_factor.push(e[1]/Math.pow(e[0]**2+e[1]**2, 0.5)));
  254. var data = [{
  255. type: 'bar',
  256. x: impact_factor,
  257. y: point_name,
  258. orientation: 'h',
  259. showlegend: false,
  260. text: impact_factor.map(e => String(Math.round(e*1e2)) + '%'),
  261. textposition: 'auto',
  262. hovertemplate: "Point: %{y}<br>Impact of %{text} <extra></extra>",
  263. //hoverinfo: 'none',
  264. }];
  265. var {layout, config} = getPlotlyDefaults();
  266. layout.xaxis.range = [0, 1];
  267. layout.yaxis.title = "";
  268. layout.xaxis.title = "Impact of mean energy deviations";
  269. Plotly.newPlot(elementId, data, layout, config);
  270. }
  271. makeplot();
  272. </script>
  273. </body>
  274. </html>