<?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>
