|
@@ -0,0 +1,305 @@
|
|
|
+<?php
|
|
|
+$selected_csv =
|
|
|
+
|
|
|
+$branch = 'dev';
|
|
|
+$season = 'NNBAR2021';
|
|
|
+$url = "https://cmd.inp.nsk.su/~compton/gitlist/compton_tables/raw/".$branch."/tables/";
|
|
|
+$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);
|
|
|
+$selected_season = substr($selected_csv, 0, -4);
|
|
|
+
|
|
|
+?>
|
|
|
+
|
|
|
+<html>
|
|
|
+<head>
|
|
|
+ <script src="plotly-latest.min.js"></script>
|
|
|
+ <script src="fmin.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 style="display: flex; align-items: center; flex-wrap: wrap; justify-content: center; margin-top: min(20px,2%); margin-bottom: 40px;">
|
|
|
+ <h2 style="margin: 0;"><a href="index.php" style="font-size: inherit;">Pictures</a> / Season</h2>
|
|
|
+ <form name="form" action="" style="padding: 0 15px; margin: auto 0;" method="get">
|
|
|
+ <select name="csv_file" class="select-css" style="padding: 0.3em 1.3em 0.3em 0.4em;" onchange="this.form.submit()">
|
|
|
+ <?
|
|
|
+ foreach($cleanArrs as $file){
|
|
|
+ ?><option value="<?echo $file?>" <?echo isSelected($file, $selected_csv)?>><?echo substr($file, 0, -4)?></option>
|
|
|
+ <?
|
|
|
+ }
|
|
|
+ ?>
|
|
|
+ </select>
|
|
|
+ </form>
|
|
|
+ <h2 style="margin: 0;">summary</h2>
|
|
|
+</div>
|
|
|
+
|
|
|
+<div style="display: flex; align-items: center; flex-wrap: wrap; justify-content: center;">
|
|
|
+ <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
|
|
|
+ <h3>Mean energy measurements</h3>
|
|
|
+ <div id="mean_energy_plot"></div>
|
|
|
+ </div>
|
|
|
+ <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
|
|
|
+ <h3>Spread measurements</h3>
|
|
|
+ <div id="spread_plot"></div>
|
|
|
+ </div>
|
|
|
+ <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
|
|
|
+ <h3>Mean energy deviations</h3>
|
|
|
+ <div id="energy_dev_plot"></div>
|
|
|
+ </div>
|
|
|
+ <div style="max-width: 900px; width: 45%; min-width: min(100%, 600px); margin: 0 max(1%, 10px);">
|
|
|
+ <h3>Impact of mean energy deviations</h3>
|
|
|
+ <div id="impact_energy_dev_plot"></div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+<div style="margin-top: 40px; width: 100%;">
|
|
|
+ <div style="width: min(100%, 600px); margin: 0 auto;">
|
|
|
+ <h3 style="padding-right: 40px;">Methodology</h3>
|
|
|
+ <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>
|
|
|
+ <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>
|
|
|
+ <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>
|
|
|
+ <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>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+
|
|
|
+<script>
|
|
|
+ function makeplot(){
|
|
|
+ Plotly.d3.csv('<?echo $url.$selected_csv;?>', (allRows)=>{
|
|
|
+ const {point_name, energy_point, mean_energy, mean_energy_stat_err, mean_energy_sys_err, mean_spread, mean_spread_stat_err} = parseResultsTable(allRows);
|
|
|
+ makeMeanEnergyPlot(energy_point, mean_energy, mean_energy_stat_err, point_name, "mean_energy_plot");
|
|
|
+ makeSpreadPlot(mean_energy, mean_spread, mean_spread_stat_err, point_name, "spread_plot");
|
|
|
+ makeMeanDevPlot(mean_energy, mean_energy_sys_err, point_name, "energy_dev_plot");
|
|
|
+ makeImpactDevPlot(point_name, mean_spread, mean_energy_sys_err, "impact_energy_dev_plot");
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ function parseResultsTable(allRows){
|
|
|
+ // Extracts a row following the energy point in the total csv file (or null if energy point is not exists)
|
|
|
+ let data = {};
|
|
|
+ for(let key of Object.keys(allRows[0])){
|
|
|
+ data[key] = [];
|
|
|
+ }
|
|
|
+ data['point_name'] = [];
|
|
|
+
|
|
|
+ let float_keys = ['energy_point', 'mean_energy', 'mean_energy_stat_err', 'mean_spread', 'mean_spread_stat_err', 'mean_energy_sys_err'];
|
|
|
+
|
|
|
+ for (var i=0; i<allRows.length; i++){
|
|
|
+ for(let key of Object.keys(allRows[i])){
|
|
|
+ let value = allRows[i][key];
|
|
|
+ if (float_keys.includes(key)){
|
|
|
+ value = parseFloat(value);
|
|
|
+ }
|
|
|
+ data[key].push(value);
|
|
|
+ }
|
|
|
+ data['point_name'].push(allRows[i]['energy_point']+'_'+allRows[i]['first_run']);
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+ function linear_coeffs(x, y, yerr, remove_outliers=false){
|
|
|
+ // Returns a chi square minimizer for linear function
|
|
|
+ function chi2min(X){
|
|
|
+ let k = X[0], b = X[1];
|
|
|
+ let chi2 = 0;
|
|
|
+ for(let i=0; i<x.length; i++){
|
|
|
+ if (remove_outliers&&(y[i]<0.06))
|
|
|
+ continue;
|
|
|
+ y0 = k*x[i] + b;
|
|
|
+ chi2 += Math.pow((y[i] - y0)/yerr[i], 2);
|
|
|
+ }
|
|
|
+ return chi2;
|
|
|
+ }
|
|
|
+ return chi2min;
|
|
|
+ }
|
|
|
+
|
|
|
+ function getPlotlyDefaults(){
|
|
|
+ var layout = {
|
|
|
+ margin: {
|
|
|
+ l: 50,
|
|
|
+ r: 50,
|
|
|
+ b: 50,
|
|
|
+ t: 50,
|
|
|
+ pad: 4
|
|
|
+ },
|
|
|
+ font: {
|
|
|
+ size: 18,
|
|
|
+ },
|
|
|
+ xaxis: {
|
|
|
+ title: "Mean beam energy, MeV",
|
|
|
+ automargin: true,
|
|
|
+ },
|
|
|
+ yaxis: {
|
|
|
+ //domain: [0, 0.2],
|
|
|
+ automargin: true,
|
|
|
+ rangemode: 'positive',
|
|
|
+ title: "Spread, MeV",
|
|
|
+ hoverformat: '.2f',
|
|
|
+ },
|
|
|
+ showlegend: true,
|
|
|
+ legend: {
|
|
|
+ x: 0,
|
|
|
+ xanchor: 'left',
|
|
|
+ y: 1,
|
|
|
+ },
|
|
|
+ paper_bgcolor: 'rgba(0,0,0,0)',
|
|
|
+ plot_bgcolor: 'rgba(0,0,0,0)',
|
|
|
+ autosize: true,
|
|
|
+ };
|
|
|
+ var config = {
|
|
|
+ toImageButtonOptions: {
|
|
|
+ format: 'png', // one of png, svg, jpeg, webp
|
|
|
+ filename: 'spread_plot_<?echo $selected_season;?>',
|
|
|
+ scale: 4,
|
|
|
+ },
|
|
|
+ responsive: true,
|
|
|
+ modeBarButtonsToRemove: ['select2d', 'lasso2d', 'zoomIn2d', 'zoomOut2d', 'resetScale2d', 'hoverClosestGl2d', 'hoverClosestPie', 'toggleHover', 'toggleSpikelines'],
|
|
|
+ displayModeBar: true,
|
|
|
+ };
|
|
|
+ return {
|
|
|
+ "layout" : layout, "config" : config,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ function makeMeanEnergyPlot(energy_point, mean_energy, mean_energy_stat_err, texts, elementId){
|
|
|
+ // Plots mean energy - target energy vs target energy
|
|
|
+ var energy_diff = [];
|
|
|
+ Plotly.d3.zip(mean_energy, energy_point).forEach(e => energy_diff.push(e[0] - e[1]));
|
|
|
+ var trace1 = {
|
|
|
+ x: energy_point,
|
|
|
+ y: energy_diff,
|
|
|
+ yaxis: 'y',
|
|
|
+ mode: 'markers',
|
|
|
+ text: Plotly.d3.zip(texts, mean_energy),
|
|
|
+ text2: mean_energy,
|
|
|
+ hovertemplate: "Point: %{text[0]}<br>Mean energy = %{text[1]:.3f} ± %{error_y.array:.3f} MeV" + "<extra></extra>",
|
|
|
+ //hovermode: "x",
|
|
|
+ error_y: {
|
|
|
+ type: 'data',
|
|
|
+ array: mean_energy_stat_err,
|
|
|
+ color: '#260101',
|
|
|
+ },
|
|
|
+ showlegend: false,
|
|
|
+ marker: {
|
|
|
+ color: '#260101',
|
|
|
+ },
|
|
|
+ type: "scatter",
|
|
|
+ };
|
|
|
+ var traces = [trace1];
|
|
|
+
|
|
|
+ var {layout, config} = getPlotlyDefaults();
|
|
|
+ layout.xaxis.title = "Target energy, MeV";
|
|
|
+ layout.yaxis.title = "Mean energy - Target energy, MeV";
|
|
|
+
|
|
|
+ Plotly.newPlot(elementId, traces, layout, config);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function makeMeanDevPlot(mean_energy, mean_energy_sys_err, texts, elementId){
|
|
|
+ // Plots mean energy deviations vs mean measured energy
|
|
|
+ var trace1 = {
|
|
|
+ x: mean_energy,
|
|
|
+ y: mean_energy_sys_err,
|
|
|
+ text: texts,
|
|
|
+ mode: 'markers',
|
|
|
+ marker: {
|
|
|
+ size: 12,
|
|
|
+ symbol: 'diamond',
|
|
|
+ },
|
|
|
+ hovertemplate: "Point: %{text}<br>x = %{x:.2f} MeV<br>y = %{y:.3f} MeV" + "<extra></extra>",
|
|
|
+ showlegend: false,
|
|
|
+ };
|
|
|
+ var traces = [trace1];
|
|
|
+
|
|
|
+ var {layout, config} = getPlotlyDefaults()
|
|
|
+
|
|
|
+ layout.yaxis.title = "Mean energy deviation, MeV";
|
|
|
+ Plotly.newPlot(elementId, traces, layout, config);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function makeSpreadPlot(mean_energy, mean_spread, mean_spread_stat_err, texts, elementId){
|
|
|
+ // Plots spreads vs mean measured energy
|
|
|
+ var chi2min = linear_coeffs(mean_energy, mean_spread, mean_spread_stat_err, true);
|
|
|
+ var solution = fmin.nelderMead(chi2min, [0.001, 0]);
|
|
|
+
|
|
|
+ var trace1 = {
|
|
|
+ x: mean_energy,
|
|
|
+ y: mean_spread,
|
|
|
+ yaxis: 'y',
|
|
|
+ mode: 'markers',
|
|
|
+ text: texts,
|
|
|
+ hovertemplate: "Point: %{text}<br>x = %{x:.2f} MeV<br>y = %{y:.3f} ± %{error_y.array:.3f} MeV" + "<extra></extra>",
|
|
|
+ hovermode: "x",
|
|
|
+ error_y: {
|
|
|
+ type: 'data',
|
|
|
+ array: mean_spread_stat_err,
|
|
|
+ color: '#260101',
|
|
|
+ },
|
|
|
+ showlegend: false,
|
|
|
+ marker: {
|
|
|
+ color: '#260101',
|
|
|
+ },
|
|
|
+ type: "scatter",
|
|
|
+ };
|
|
|
+ var trace2 = {
|
|
|
+ x: [Plotly.d3.min(mean_energy), Plotly.d3.max(mean_energy)],
|
|
|
+ y: [solution.x[0]*Plotly.d3.min(mean_energy) + solution.x[1], solution.x[0]*Plotly.d3.max(mean_energy) + solution.x[1]],
|
|
|
+ mode: 'lines',
|
|
|
+ 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,
|
|
|
+ hovermode: false,
|
|
|
+ hoverinfo: 'none',
|
|
|
+ };
|
|
|
+ var traces = [trace1, trace2];
|
|
|
+
|
|
|
+ var {layout, config} = getPlotlyDefaults()
|
|
|
+
|
|
|
+ Plotly.newPlot(elementId, traces, layout, config);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function makeImpactDevPlot(point_name, mean_spread, mean_energy_sys_err, elementId){
|
|
|
+ let arr = Plotly.d3.zip(mean_spread, mean_energy_sys_err);
|
|
|
+ let impact_factor = [];
|
|
|
+ arr.forEach(e => impact_factor.push(e[1]/Math.pow(e[0]**2+e[1]**2, 0.5)));
|
|
|
+ var data = [{
|
|
|
+ type: 'bar',
|
|
|
+ x: impact_factor,
|
|
|
+ y: point_name,
|
|
|
+ orientation: 'h',
|
|
|
+ showlegend: false,
|
|
|
+ text: impact_factor.map(e => String(Math.round(e*1e2)) + '%'),
|
|
|
+ textposition: 'auto',
|
|
|
+ hovertemplate: "Point: %{y}<br>Impact of %{text} <extra></extra>",
|
|
|
+ //hoverinfo: 'none',
|
|
|
+ }];
|
|
|
+
|
|
|
+ var {layout, config} = getPlotlyDefaults();
|
|
|
+ layout.xaxis.range = [0, 1];
|
|
|
+ layout.yaxis.title = "";
|
|
|
+ layout.xaxis.title = "Impact of mean energy deviations";
|
|
|
+ Plotly.newPlot(elementId, data, layout, config);
|
|
|
+ }
|
|
|
+
|
|
|
+ makeplot();
|
|
|
+</script>
|
|
|
+
|
|
|
+</body>
|
|
|
+</html>
|