Subversion Repositories f9daq

Compare Revisions

Ignore whitespace Rev 343 → Rev 344

/belle2/masterclass/JSRootExtend.js
0,0 → 1,205
function StoreAndDrawFitFunction(TH1, TF1, range, delOldFunction, divid){
// - Store fitted function in histogram functions list and draw
// works for 1D histogram
 
var ndim = 1;
var xmin = 0, xmax = 0, ymin = 0, ymax = 0;
if(range.length >= 2){
xmin = range[0];
xmax = range[1]
}else{
return 0
};//add more if needed?
var funcList = GetListOfFunctions(TH1);
if ((funcList.length == 0) || (funcList == undefined)){
throw "StoreAndDrawFitFunction: Function list has not been created - cannot store the fitted function";
}
//console.log("funcList", funcList);
// delete the function in the list only if
// the function we are fitting is not in that list
// If this is the case we re-use that function object and
// we do not create a new one (if delOldFunction is true)
//NEW: always remove old and add new!!!
var reuseOldFunction = 0;
if (delOldFunction){
var i=1
while(i<funcList.arr.length){
//skip first beacuse it is TPaveStats
//console.log(i, TF1, funcList);
if((funcList.arr[i].fName != TF1.fName) || (funcList.arr[i].fFormula.fFormula != TF1.fFormula.fFormula)){
//console.log("diff");
funcList.RemoveAt(i);
}else{
//console.log("same");
funcList.RemoveAt(i); //added
reuseOldFunction = 1;
i++;
}
}
}
 
var fnew1 = JSROOT.Create("TF1");
fnew1 = TF1;
funcList.Add(fnew1);
//console.log(JSROOT.GetMainPainter(divid));
SetRange(fnew1, xmin,xmax);
Save(fnew1, TH1, xmin, xmax);
 
//check if TH1's fit function is plotted
var isFitPlotted = TH1.fFitPlotted;
//console.log(isFitPlotted)
if(!isFitPlotted){
JSROOT.draw(divid, fnew1, "", function(obj){
divid = obj.divid.id;
var a = JSROOT.GetMainPainter(divid).draw_object;
a.fFitPlotted = 1;
});
}else{
JSROOT.redraw(divid, fnew1, "");
}
}
 
function GetListOfFunctions(TH1){
//returns TList of functions
return TH1.fFunctions
}
 
function SetRange(TF1, xmin, xmax){
TF1.Xmax = xmax;
TF1.Xmin = xmin;
}
 
function Save(TF1, TH1, xmin, xmax){
//Save values of function in array fSave
//var bin1 = TH1.fXaxis.FindBin(xmin, 0);
//var bin2 = TH1.fXaxis.FindBin(xmax, 0);
//console.log("bin1:", bin1, "bin2", bin2);
if(!TF1.fNpx) TF1.fNpx = 501; //number of points to be plotted
//var fNsave = TF1.fNpx + 3; //number of points to be plotted
var dx = (xmax - xmin) / TF1.fNpx;
 
var fSave = [];
for(var i = 0; i <= TF1.fNpx; i++){
fSave.push(TF1.evalPar(xmin + dx * i));
}
fSave.push(xmin);
fSave.push(xmax);
TF1.fSave = fSave;
}
 
function GetParameters(TF1){
//returns parameters from fFormula
var fNpar = TF1.fNpar;
var parameters = [];
for(var i = 0; i<fNpar; i++){
parameters.push(TF1.GetParValue(i));
}
return parameters;
}
 
function CreateTF1Fit(param, sframe){
//This fuction can create gaus, pol0-5, exp and Breit-Wigner functions, or their combinations.
var func = JSROOT.Create("TF1");
var formula = JSROOT.Create("TFormula");
var Npar = 0;
formula.fClingParameters = [];
formula.fFormula = "";
formula.fParams = [];
formula.fNparam = Npar;
var funList = getFunList(sframe);
if(funList[0]){
//Gaus function
var gausParameters = ["N", "#mu", "#sigma"];
formula.fClingParameters.push(param[0]);
formula.fClingParameters.push(param[1]);
formula.fClingParameters.push(param[2]);
formula.fFormula = "[N] * TMath::Gaus(x, [#mu], [#sigma])";
for(var i = 0; i<3;i++){
formula.fParams.push(JSROOT.Create("pair<TString,int,TFormulaParamOrder>"));
formula.fParams[i].first = gausParameters[i];
formula.fParams[i].second = i;
Npar += 1;
}
}
if(funList[1]){
//pol function
var n = parseInt(document.getElementById("polOrderDisplay"+sframe).value);
for(var i=0; i<=n; ++i){
if((i>0) || (Npar > 0)){
formula.fFormula += " + ";
}
 
if(i==0){
formula.fFormula += "[p" + String(i) + "]";
}else{
if(i==1){
formula.fFormula += "[p" + String(i) + "] * x";
}else{
formula.fFormula += "[p" + String(i) + "] * x^" + String(i);
}
}
formula.fClingParameters.push(param[3+i]);
formula.fParams.push(JSROOT.Create("pair<TString,int,TFormulaParamOrder>"));
formula.fParams[i+Npar].first = "p" + String(i);
formula.fParams[i+Npar].second = i+Npar;
}
Npar += n+1;
}
if(funList[2]){
var expParameters = ["N_{exp}", "K"]
if((Npar > 0)){
formula.fFormula += " + ";
}
formula.fFormula += "[N_{exp}] * exp([K] * x)";
formula.fClingParameters.push(param[8]);
formula.fClingParameters.push(param[9]);
for(var i = 0; i<2;i++){
formula.fParams.push(JSROOT.Create("pair<TString,int,TFormulaParamOrder>"));
formula.fParams[i+Npar].first = expParameters[i];
formula.fParams[i+Npar].second = i+Npar;
}
Npar += 2;
}
 
if(funList[3]){
var BWParameters = ["N_{BW}", "#Gamma", "Mean_{BW}"]
if((Npar > 0)){
formula.fFormula += " + ";
}
formula.fFormula += "[N_{BW}] * TMath::BreitWigner(x, [Mean_{BW}], [#Gamma])"; // * [Gamma] / ((x - [MeanBW])^2 + ([Gamma]/2)^2)
formula.fClingParameters.push(param[10]);
formula.fClingParameters.push(param[11]);
formula.fClingParameters.push(param[12]);
 
for(var i = 0; i<3;i++){
formula.fParams.push(JSROOT.Create("pair<TString,int,TFormulaParamOrder>"));
formula.fParams[i+Npar].first = BWParameters[i];
formula.fParams[i+Npar].second = i+Npar;
}
Npar += 3;
}
formula.fName = "Fit function";
//formula.fNdim = 1;
formula.fTitle = "Fit function";
formula.fNparam = Npar;
//func.fParErrors = [1, 1, 1]; // to display parameters' error use this line
func.fFormula = formula;
func.fNpar = formula.fNparam;
func.fTitle = formula.fTitle;
func.fName = formula.fName;
func.fLineColor = 2;
func.fLineWidth = 2;
return func
}
/belle2/masterclass/displayFormula.js
0,0 → 1,14
function showFormula(formula, sframe){
//formula to be displayed in divid formulaDisplay+sframe
spanID = 'functionDisplay' + sframe;
document.getElementById("functionDisplay"+sframe).innerHTML = '$'+formula+'$';
MathJax.Hub.Queue(["Typeset", MathJax.Hub, spanID]);
MathJax.Hub.Queue(showBlahElement);
 
}
 
function showBlahElement () {
console.log(spanID);
console.log(MathJax.Hub.getAllJax(spanID));
}
 
/belle2/masterclass/fminsearch.js
0,0 → 1,122
/*
Only core function
MIT License
 
Copyright (c) Jonas Almeida.
 
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
 
lin = function(x,P){
return x.map(function(xi){return (xi*P[1] + P[0])})
}
 
quad = function(x,P){
return x.map(function(xi){return (Math.pow(xi, 2)*P[2] + xi*P[1] + P[0])})
}
 
gaus2 = function(x, P){
return x.map(function(xi){return (P[2] * Math.exp(-0.5 * Math.pow((xi-P[0]) / P[1], 2)))})
}
 
 
chisq = function(y, yp){
var sum = 0;
for(var i = 0; i<y.length; i++){
if(y[i] != 0){
sum += Math.pow((y[i]-yp[i]),2)/y[i];
}
}
return sum
}
 
fminsearch=function(fun,Parm0,x,y,Opt){// fun = function(x,Parm)
 
// fun = function(x,P){return x.map(function(xi){return (P[0]+1/(1/(P[1]*(xi-P[2]))+1/P[3]))})}
// x=[32,37,42,47,52,57,62,67,72,77,82,87,92];y=[0,34,59,77,99,114,121,133,146,159,165,173,170];
//
// Opt is an object will all other parameters, from the objective function (cost function), to the
// number of iterations, initial step vector and the display switch, for example
// Parms=fminsearch(fun,[100,30,10,5000],x,y,{maxIter:10000,display:false})
if(!Opt){Opt={}};
if(!Opt.maxIter){Opt.maxIter=1000};
if(!Opt.step){// initial step is 1/100 of initial value (remember not to use zero in Parm0)
Opt.step=Parm0.map(function(p){return p/100});
Opt.step=Opt.step.map(function(si){if(si==0){return 1}else{ return si}}); // convert null steps into 1's
};
 
if(!Opt.objFun){Opt.objFun=function(y,yp){
//console.log(y, yp);
return chisq(y, yp)}//y.map(function(yi,i){return Math.pow((yi-yp[i]),2)}).reduce(function(a,b){return a+b})}
} //SSD
if(!Opt.mask){Opt.mask = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}; //use all parameters
if(!Opt.maskBond){Opt.maskBond = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[]]};//first element is mask, second is
if(!Opt.sframe){Opt.sframe = 'h0'};
var cloneVector=function(V){return V.map(function(v){return v})};
 
var P1, ya,y0,yb,fP0,fP1;
var P0 = cloneVector(Parm0);//, P1 = cloneVector(Parm0);
var n = P0.length;
var step = Opt.step;
var funParm=function(P){return Opt.objFun(y,fun(x,P, Opt.sframe))}//function (of Parameters) to minimize
//console.log('before:', P0);
P0 = checkIfInRange(P0, Opt.maskBond);
//console.log('after:', P0)
// silly multi-univariate screening
for(var i=0;i<Opt.maxIter;i++){
//console.log(i, P0);
for(var j=0;j<n;j++){ // take a step for each parameter
if(Opt.mask[j]==0){continue};//if parameter not used, skip it
P1=cloneVector(P0);
P1[j]+=step[j];
//console.log(i, P1)
//check if new parameter is bonded => check if out of bonds
P1 = checkIfInRange(P1, Opt.maskBond)
 
if(funParm(P1)<funParm(P0)){ // if parm value going in the righ direction
step[j]=1.2*step[j]; // then go a little faster
P0=cloneVector(P1);
}
else{
step[j]=-(0.5*step[j]); // otherwiese reverse and go slower
}
}
if(Opt.display){if(i>(Opt.maxIter-10)){console.log(i+1,funParm(P0),P0)}}
//console.log(funParm(P0), P0);
}
//console.log(funParm(P0), P0, chisq(y, fun(x,P0)));
return [P0, chisq(y, fun(x,P0, Opt.sframe))];
};
 
function checkIfInRange(P0, maskBond){
//P0 - vector of parameters
//n - number of parameters
//maskBond - first element is actual mask, second element is matrix of
var n = P0.length;
for(var j=0; j<n;j++){
if(maskBond[0][j]==1){
if(P0[j] < maskBond[1][j][0]){P0[j]=maskBond[1][j][0]};
if(P0[j] > maskBond[1][j][1]){
P0[j]=maskBond[1][j][1];
}
}
}
return P0
}
/belle2/masterclass/index.php
13,6 → 13,26
<script src="js/workspace.js"></script>
<script src="js/FileSaver.min.js"></script>
 
<link rel="shortcut icon" href="https://root.cern/js/latest/img/RootIcon.ico"/>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="JSRootExtend.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="polFitPanel.js"></script>
<script src="fminsearch.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
<script type="text/javascript" src="displayFormula.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [["$","$"],["\\(","\\)"]]
}
});
</script>
 
 
<style>
table {
border-collapse: collapse;
21,7 → 41,7
 
th, td {
padding: 0px;
text-align: right;
/*text-align: right;*/
}
 
tr:hover{background-color:#ffffff}
125,6 → 145,7
 
function startAction() {
var btnstart = document.getElementById('btnstart');
first = 0;
if (btnstart.value=== "Stop Analysis"){
stopTask();
} else {
185,29 → 206,22
//var r = document.getElementById('results');
var r = document.getElementById('drawing');
if (document.getElementById(sframe) == null ){
r.insertAdjacentHTML('beforeend', '<div id="' + sframe +'" style="width:1000px; height:600px"></div><br/>');
//console.log('insert HTML for', sframe)
r.insertAdjacentHTML('beforeend', '<div id="' + sframe +'" style="width:800px; height:500px"></div><br/>');//narise histogram
r.insertAdjacentHTML('beforeend', '<div id="fit' + sframe +'" style="display: none"></div><br/>');
var fit = document.getElementById('fit'+ sframe);
mform ='<form method="post" action="th1fit.php" onsubmit="return fitpanel(this);">';
mform += ' Function:<input type="text" size="20" value="gaus" name="fitfun" /><br/>';
mform += ' Range: min=<input type="text" size="2" value="0" name="min" />';
mform += ' max=<input type="text" size="2" value="20" name="max" /><br/>';
mform += ' Initial parameters (separated by ,)<input type="text" size="20" value="" name="prm" /><br/>';
mform += ' <input id="data'+ sframe +'" type="hidden" value="'+ result.message +'" name="data" />';
mform += ' <input type="hidden" value="'+ sframe +'" name="name" />';
mform += ' <input class="mybutton" type="submit" value=" Fit "/>';
mform += '</form>';
fit.insertAdjacentHTML('beforeend', '<div id="param' + sframe +'"></div><br/>');
fit.insertAdjacentHTML('beforeend', mform);
insertHTML(sframe);
r.insertAdjacentHTML('beforeend','<input type="button" onclick="togglevisibility(\'fit'+sframe+'\');" class="mybutton" value="Show/Hide Fit Panel" />' );
r.insertAdjacentHTML('beforeend','&nbsp;<input type="button" onclick="toProcess();" class="mybutton" value="To Process" /><hr/>' );
document.getElementById('data'+ sframe).value=result.message;
//r.insertAdjacentHTML('beforeend', JSON.stringify(result.message));
}
var frame = document.getElementById(sframe);
JSROOT.redraw(sframe, jsonobj, "hist");
JSROOT.redraw(sframe, jsonobj, "hist", function(){
initSliders(sframe);
});
 
frame.scrollIntoView();
}
347,12 → 361,46
alert(e);
}
}
Blockly.Blocks['simple_analysis'] = {
init: function() {
this.appendDummyInput()
.appendField("Belle II Masterclass");
this.appendDummyInput()
.appendField("Number of events: ")
.appendField(new Blockly.FieldNumber(5000, 0), "neve");
this.appendDummyInput()
.appendField("First event: ")
.appendField(new Blockly.FieldNumber(0, 0), "first");
this.appendDummyInput()
.appendField("Data Source")
.appendField(new Blockly.FieldDropdown([
<?php
$files = array_slice(scandir('../data/'), 2);
$cnt=0;
foreach($files as $f){
echo "[\"$f\",\"$f\"],";
$cnt++;
}
?>]), "datasource");
this.appendDummyInput()
.appendField("Print particle list?")
.appendField(new Blockly.FieldDropdown([["No", "0"], ["Yes", "1"]]), "print");
this.appendValueInput("list")
.setCheck("particle list")
.appendField("Particle List");
this.setColour(230);
this.setTooltip('Run the analysis, specify data source, number of events, first event and a list of particles to process.');
this.setHelpUrl('http://belle2.jp/');
}
};
 
 
</script>
</head>
<body>
 
<h1>Belle II Particle Discovery: Describe process &rarr;Analyse &rarr;Fit results &rarr;Discover</h1>
<!-- <input type="button" onclick="showCode();" class="mybutton" value="Show JavaScript" /> -->
<input type="button" id="btnstart" onclick="startAction();" class="mybutton" value="Run Analysis" />
/belle2/masterclass/js/belle2_def.js
133,7 → 133,7
.appendField(new Blockly.FieldNumber(0, -Infinity, Infinity, 0.0001), "max");
this.appendDummyInput()
.appendField("Variable")
.appendField(new Blockly.FieldDropdown([["mass", "GetMass"], ["momentum", "GetMomentum"], ["energy", "GetEnergy"],["charge", "GetCharge"], ["identity", "GetPid"],["polar angle", "GetTheta"],["cos(polar ang.)", "GetCosTheta"],["px", "GetXMomentum"],["py", "GetYMomentum"],["pz", "GetZMomentum"],["pT", "GetTransverseMomentum"],["m-m1","GetDeltaMass1"],["m-m2","GetDeltaMass2"],["m-m3","GetDeltaMass3"]]), "varname");
.appendField(new Blockly.FieldDropdown([["mass", "GetMass"], ["momentum", "GetMomentum"], ["energy", "GetEnergy"],["charge", "GetCharge"], ["identity", "GetPid"],["polar angle", "GetTheta"],["cos(polar ang.)", "GetCosTheta"],["px", "GetXMomentum"],["py", "GetYMomentum"],["pz", "GetZMomentum"],["pT", "GetTransverseMomentum"]]), "varname");
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setNextStatement(true);
/belle2/masterclass/polFitPanel.js
0,0 → 1,849
var funMatrix = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]
 
function initSliders(sframe){
genFunList(sframe);
var obj = JSROOT.GetMainPainter(sframe).draw_object; //get the histogram
//Initialise all ParameterSliders
$( function() {
$(".ParamSlider"+sframe).each(function() {
var ID = String('#'+this.id);
var n = ID.length;
var paramName = ID.slice(6,n-5);
switch (paramName) {
case 'Amplitude':
var min = 0;
var max = 10000;
var value = 100;
break;
 
case 'Mu':
var min = 0;
var max = 1;
var value = 0;
break;
 
case 'Sigma':
var min = 0;
var max = 1;
var value = 0.05;
break;
 
case 'AmpBW':
var min = 0;
var max = 100;
var value = 1000;
break;
 
case 'Gamma':
var min = 0;
var max = 1;
var value = 0.5;
break;
 
case 'M':
var min = 0;
var max = 5;
var value = 0;
break;
 
default:
var min = -10;
var max = 10;
var value = 0;
break;
}
 
$(this).slider({
range: false, min: min, max: max, value:value, step: 0.0001,
slide: function( event, ui ) {
$( ID.slice(0,n-5)+sframe ).val(ui.value);
calculate(sframe);
},
change: function( event, ui ){
$( ID.slice(0,n-5)+sframe ).val(ui.value);
calculate(sframe);
}
});
setDefaultParameters(paramName, sframe);
})
})
//Script for initialising range sliders
$( function() {
$( "#slider-range"+sframe ).slider({
range: true,
min: obj.fXaxis.fXmin,
max: obj.fXaxis.fXmax,
step: (obj.fXaxis.fXmax-obj.fXaxis.fXmin)/1000,
values: [ obj.fXaxis.fXmin, obj.fXaxis.fXmax ],
slide: function( event, ui ) {
document.getElementById("minRange"+sframe).value = ui.values[0];
document.getElementById("maxRange"+sframe).value = ui.values[1];
calculate(sframe);
}
});
$("#minRange"+sframe).val($( "#slider-range"+sframe ).slider( "values", 0));
$("#maxRange"+sframe).val($( "#slider-range"+sframe ).slider( "values", 1));
});
 
//Script for choosing polynomial order
$( function() {
$( "#slider-polOrder"+sframe ).slider({
range: false,
min: 0,
max: 4,
step: 1,
value: 1,
slide: function( event, ui ) {
$( "#polOrderDisplay" + sframe ).val(ui.value);
updatePolParamList(ui.value, sframe);
calculate(sframe);
}
});
$( "#polOrderDisplay" + sframe ).val( $("#slider-polOrder"+sframe).slider("value") );
updatePolParamList($("#slider-polOrder"+sframe).slider("value"), sframe);
});
}
 
function autoFit(sframe){
//works only if histogram is on canvas
//document.getElementById('status').style.display='block';
var xmin = parseFloat(document.getElementById("minRange"+sframe).value);
var xmax = parseFloat(document.getElementById("maxRange"+sframe).value);
//var initParam = getManualParameters();//unused
var data = getDataFromHisto(sframe);
var N = data.length;
var x = [], y = []; //data points
var NdataPoints = 0;
for(var i=0; i<N; ++i){
if( (data[i][0] > xmin) && (data[i][0] < xmax)){
x.push(data[i][0]);
y.push(data[i][1]);
if(data[i][1]>0){NdataPoints++;}
}
}
var p0 = getManualParameters(sframe);
var maskParam = getParametersMask(sframe); //use only these parameters, all others are fixed or un used
var maskParamRange = getParamRangeMask(sframe);
var result = fminsearch(calcMasterFun2, p0, x, y, {maxIter:100, mask:maskParam, maskBond:maskParamRange, sframe:sframe});
var Parm0 = result[0];
var chi2 = result[1];
setManualParameters(Parm0, maskParam, sframe); // set parameters' values
var obj = JSROOT.GetMainPainter(sframe).draw_object;
funkcija = CreateTF1Fit(Parm0, sframe);
funkcija.fChisquare = chi2;
funkcija.fNDF = NdataPoints-getNparameters(sframe); //calculate ndf
StoreAndDrawFitFunction(obj, funkcija, [xmin, xmax], 1, sframe);
}
 
function getParamRangeMask(sframe){
//return mask to bond parameters inside of range
var varList = ['Amplitude', 'Mu', 'Sigma', 'A0', 'A1', 'A2', 'A3', 'A4', 'AmpExp', 'K', 'AmpBW', 'Gamma', 'M'];
var x = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var ranges = [];
for(var i=0; i<varList.length; i++){
//find fixed values and mask them
if(document.getElementById('bond'+varList[i] + sframe).checked){
x[i]=1;
ranges.push([parseFloat(document.getElementById('Param'+varList[i]+'min'+sframe).value), parseFloat(document.getElementById('Param'+varList[i]+'max'+sframe).value)]);
}else{
ranges.push([0, 0]);
}
}
return [x, ranges]
}
 
function calculate(h){
//var x = parseFloat(document.getElementById("xValue").value);
var N = 501; // number of points for function ploting
//var funfit = document.getElementById("fitfun").value;
 
var xmin = parseFloat(document.getElementById("minRange"+h).value);
var xmax = parseFloat(document.getElementById("maxRange"+h).value);
var parameters = [];
parameters = getManualParameters(h);
fitMasterFun(xmin, xmax, N, parameters, h);
}
 
function getManualParameters(sframe){
var parametri = [];
var mu = parseFloat(document.getElementById("ParamMu"+sframe).value);
var sigma = parseFloat(document.getElementById("ParamSigma"+sframe).value);
var amplitude = parseFloat(document.getElementById("ParamAmplitude"+sframe).value);
parametri = [amplitude, mu, sigma];
 
var n = document.getElementById("polOrderDisplay" + sframe).value;
for(var i=0; i<5; ++i){
if(i<=n){
parametri.push(parseFloat(document.getElementById("ParamA"+i+sframe).value));
}else{
parametri.push(0); //set higher orders to 0
}
}
 
parametri.push(parseFloat(document.getElementById("ParamAmpExp"+sframe).value));
parametri.push(parseFloat(document.getElementById("ParamK"+sframe).value));
 
parametri.push(parseFloat(document.getElementById("ParamAmpBW"+sframe).value));
parametri.push(parseFloat(document.getElementById("ParamGamma"+sframe).value));
parametri.push(parseFloat(document.getElementById("ParamM"+sframe).value));
return parametri
}
 
function setManualParameters(p, mask, sframe){
//sets the value of parameters and correct max or min value if p greater or smaller
var paramNames = ["Amplitude", "Mu", "Sigma", "A0", "A1", "A2", "A3", "A4", "AmpExp", "K", 'AmpBW', 'Gamma', 'M'];
 
for(var i = 0; i<paramNames.length; i++){
if(mask[i]){
document.getElementById("Param"+paramNames[i]+sframe).value = p[i];
 
var max = $("#Param"+paramNames[i]+"Set"+sframe).slider("option", "max");
var min = $("#Param"+paramNames[i]+"Set"+sframe).slider("option", "min");
if(p[i] > max){
$("#Param"+paramNames[i]+"Set"+sframe).slider("option", "max", p[i]);
document.getElementById("Param"+paramNames[i]+"max"+sframe).value = p[i];
};
if(p[i] < min){
$("#Param"+paramNames[i]+"Set"+sframe).slider("option", "min", p[i]);
document.getElementById("Param"+paramNames[i]+"min"+sframe).value = p[i];
}
$("#Param"+paramNames[i]+"Set"+sframe).slider("value", p[i]);
}
}
}
 
function fitMasterFun(xmin, xmax, N, parametri, sframe){
var x = [];
var y = [];
 
for(var i = 0; i<N; i++){
x.push((xmax-xmin)*i/N+xmin);
y.push(calcMasterFun(x[i], parametri, sframe));
}
var data = getDataFromHisto(sframe);
var sum = 0;
var NdataPoints = 0;
for(var i=0; i<data.length; ++i){
//calculate sum of residuals
if( (data[i][0] > xmin) && (data[i][0] < xmax) && (data[i][1] != 0)){
var yfit = calcMasterFun(data[i][0], parametri, sframe);
var ydata = data[i][1];
sum += Math.pow(ydata-yfit, 2) / ydata;
NdataPoints++;
}
}
var chi2 = sum.toPrecision(4);
//display chi^2
document.getElementById("chi2Output"+sframe).innerHTML = chi2;
//calculate ndf
var ndf = NdataPoints;
var Nparameters = getNparameters(sframe);
ndf -= Nparameters;
 
document.getElementById("ndfOutput"+sframe).innerHTML = ndf;
document.getElementById("chi2Red"+sframe).innerHTML = (chi2/ndf).toPrecision(4);
var g = JSROOT.CreateTGraph(N, x, y);
var isTGraphOn = JSROOT.GetMainPainter(sframe).draw_object.fTGraphPlotted;
if (typeof isTGraphOn === "undefined") {
//TGraph does not exist yet
var a = JSROOT.GetMainPainter(sframe).draw_object;
a.fTGraphPlotted = 0;
JSROOT.draw(sframe, g, "", function(){
var obj = JSROOT.GetMainPainter(sframe).draw_object;
obj.fTGraphPlotted = 1;
});
} else {
//replot only if TGraph is already plotted, else: it is plotting
if(isTGraphOn==1){JSROOT.redraw(sframe, g, "");}
}
 
}
 
function getNparameters(sframe){
var x = 0;
var funList = getFunList(sframe);
if(funList[0]==1){
//Gaus has 3 parameters
x += 3;
}
 
if(funList[1]){
//Substract (polynomial order + 1)
x += parseInt(document.getElementById("polOrderDisplay" + sframe).value)+1;
}
 
if(funList[2]){
//Exponential function has 2 parameters
x += 2;
}
return x
}
 
function getParametersMask(sframe){
//return mask to fix parameters
var x = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var varList = ['Amplitude', 'Mu', 'Sigma', 'A0', 'A1', 'A2', 'A3', 'A4', 'AmpExp', 'K', 'AmpBW', 'Gamma', 'M'];
var i;
var funList = getFunList(sframe);
if(funList[0]==1){
//Gaus has 3 parameters
for(i = 0; i < 3; i++){
x[i] = 1;
}
}
i = 3;
if(funList[1]){
//Substract (polynomial order + 1)
var order = parseInt(document.getElementById("polOrderDisplay" + sframe).value);
for(var j=0; j < order+1; j++){
x[i] = 1;
i++;
}
}
 
if(funList[2]){
//Exponential function has 2 parameters
x[8] = 1;
x[9] = 1;
}
 
if(funList[3]){
//BW function has 3 parameters
x[10] = 1;
x[11] = 1;
x[12] = 1;
}
 
for(var i=0; i<varList.length; i++){
//find fixed values and mask them
if(document.getElementById('fix'+varList[i]+sframe).checked){
x[i]=0;
}
}
return x
}
 
function getDataFromHisto(divid){
//get x and y from ploted histogram, and compute y_fit for ploted x and calculate chi^2
var obj = JSROOT.GetMainPainter(divid).draw_object;
var N = obj.fNcells;
var x = [];
var y = [];
var data = [];
for(var i=1; i<=N-2; ++i){
data.push([obj.fXaxis.GetBinCenter(i), obj.fArray[i]]);
}
 
return data
}
 
function calcMasterFun(x, parametri, sframe){
//calculates function gaus + pol + exp
parametriGaus = [parametri[0], parametri[1], parametri[2]];
parametriPol = [parametri[3], parametri[4], parametri[5], parametri[6], parametri[7]];
parametriExp = [parametri[8], parametri[9]];
parametriBW = [parametri[10], parametri[11], parametri[12]];
var funList = getFunList(sframe);
return funList[0]*gaus(x, parametriGaus) + funList[1]*pol(x, parametriPol) + funList[2]*expo(x, parametriExp) + funList[3]*BW(x, parametriBW);
}
 
function calcMasterFun2(x, parametri, sframe){
//calculates function gaus + pol + exp, x must be vector
return x.map(function(xi){return (calcMasterFun(xi, parametri, sframe))});
}
 
function pol(x, p){
var n = p.length;
if(n > 5){
alert("Only pol5 is implemented");
return "Error"
} else {
for(var i = n; i<5; i++){
p[i] = 0;
}
return p[0] + x * p[1] + x**2 * p[2] + x**3 * p[3] + x**4 * p[4];
}
}
 
function gaus(x, p){
var amplitude = p[0]
var mu = p[1];
var sigma = p[2];
return amplitude * Math.exp(-0.5 * Math.pow((x-mu) / sigma, 2));
}
 
function expo(x, p){
var a = p[0];
var k = p[1];
return a * Math.exp(k * x);
}
 
function BW(x, p){
var a = p[0];
var gamma = p[1];
var M = p[2];
return a / (2 * Math.PI) * gamma / (Math.pow(x-M, 2) + Math.pow(gamma/2, 2));
}
 
function divClean(divid){
JSROOT.cleanup(divid);
}
 
function getFunList(sframe){
//returns funList from funMatrix
var k = parseInt(sframe.slice(1)); //get histogram number 0, 1, 2, ...
return funMatrix[k]
}
 
function genFunList(sframe){
//sframe - string name: h0, h1, ...
//actualy does not show, but only creates funList, funList should go in TH1.funList?
var funfit = document.getElementById("selectFitFun"+sframe).value;
var funfit2 = funfit.split(/[ +]/);
var implementedFun = ["gaus", "pol", "expo", "BW"] //
var funList = getFunList(sframe);
var k = parseInt(sframe.slice(1)); //get histogram number 0, 1, 2, ...
 
for (var i = 0; i < implementedFun.length; i++) {
if (funfit2.includes(implementedFun[i])) {
funList[i] = 1;
funMatrix[k][i] = 1;
document.getElementById(implementedFun[i]+"FitPanel"+sframe).style.display = "block";
} else {
funList[i] = 0;
funMatrix[k][i] = 0;
document.getElementById(implementedFun[i]+"FitPanel"+sframe).style.display = "none";
}
}
 
fName = genFunctionName(sframe);
showFormula(fName, sframe);
if((funMatrix[k][0]+funMatrix[k][1]+funMatrix[k][2]+funMatrix[k][3]) == 0){ alert("These are implemented functions:\n" + implementedFun.toString()) } //
}
 
function genFunctionName(sframe){
var funList = getFunList(sframe);
var fName = "";
var Npar = 0;
if(funList[0]){
//Gaus function
fName = "N \\cdot e^{-(\\frac{x-\\mu}{2 \\sigma})^2}";
Npar += 3;
}
if(funList[1]){
//pol function
var n = parseInt(document.getElementById("polOrderDisplay"+sframe).value);
for(var i=0; i<=n; ++i){
if((i>0) || (Npar > 0)){
fName += " + ";
}
 
if(i==0){
fName += "p" + String(i);
}else{
if(i==1){
fName += "p" + String(i) + " \\cdot x";
}else{
fName += "p" + String(i) + " \\cdot x^" + String(i);
}
}
}
Npar += n+1;
}
if(funList[2]){
if((Npar > 0)){
fName += " + ";
}
fName += "N_{exp} \\cdot e^{K \\cdot x}";
Npar += 2;
}
 
if(funList[3]){
if((Npar > 0)){
fName += " + ";
}
fName += "N_{BW} \\cdot \\frac{1}{2 \\pi} \\frac{\\Gamma}{(x - Mean_{BW})^2 + (\\Gamma/2)^2)} "; // * [Gamma] / ((x - [MeanBW])^2 + ([Gamma]/2)^2)
Npar += 3;
}
return fName;
}
 
function updatePolParamList(n, sframe){
//disables or enables inputs in table for diferent parameters
if(n>=0){
disableInput(false, "listA0"+sframe, sframe);
}else{
disableInput(true, "listA0"+sframe, sframe);
}
if(n>=1){
disableInput(false, "listA1"+sframe, sframe);
}else{
disableInput(true, "listA1"+sframe, sframe);
}
if(n>=2){
disableInput(false, "listA2"+sframe, sframe);
}else{
disableInput(true, "listA2"+sframe, sframe);
}
if(n>=3){
disableInput(false, "listA3"+sframe, sframe);
}else{
disableInput(true, "listA3"+sframe, sframe);
}
if(n>=4){
disableInput(false, "listA4"+sframe, sframe);
}else{
disableInput(true, "listA4"+sframe, sframe);
}
if(n>4){
alert("Only pol4 is inplemented!");
}else{
if(n<0){alert("Error, wrong number " + n);}
}
}
 
function disableInput(state, objId, sframe){
//Change disabled state of parameters inputs
disableParamSlider(state, objId, sframe);
var obj = document.getElementById(objId).getElementsByTagName("input");//find inputs inside of row
for (var i = 0; i < obj.length; i++) {
obj[i].disabled = state; //set state of inputs
}
}
 
function disableParamSlider(state, objId, sframe){
//Disables slider if state is true and enables if state is false.
var name = String(objId[objId.length-2])+ String(objId[objId.length-1]);
switch (state) {
case true:
$("#Param"+name+"Set"+sframe).slider("disable");
break;
case false:
$("#Param"+name+"Set"+sframe).slider("enable");
break;
 
default:
break;
}
}
 
 
function setDefaultParameters(name, sframe){
//this function is used for setting parameters back to their default value after page refresh
$( "#Param"+name+sframe).val( $("#Param"+name+"Set"+sframe).slider("value") );
$( "#Param"+name+"min"+sframe ).val( $("#Param"+name+"Set"+sframe).slider("option", "min") );
$( "#Param"+name+"max"+sframe ).val( $("#Param"+name+"Set"+sframe).slider("option", "max") );
$( "#Param"+name+"step"+sframe ).val( $("#Param"+name+"Set"+sframe).slider("option", "step") );
}
 
function updateSetSlider(id){
//Get id to update its slider ?min? value
var sframe = id.id.slice(id.id.length-2);
var last = id.id[id.id.length-3]; //it can be steP, maX or miN
switch (last) {
case "p":
$("#Param"+id.name+"Set"+sframe).slider("option", "step", parseFloat(id.value));
break;
 
case "x":
$("#Param"+id.name+"Set"+sframe).slider("option", "max", parseFloat(id.value));
break;
 
case "n":
$("#Param"+id.name+"Set"+sframe).slider("option", "min", parseFloat(id.value));
break;
 
default:
if(id.value > $("#Param"+id.name+"Set"+sframe).slider("option", "max")){ alert("Inserted value is to big."); }
if(id.value < $("#Param"+id.name+"Set"+sframe).slider("option", "min")){ alert("Inserted value is to small."); }
$("#Param"+id.name+"Set"+sframe).slider("value", parseFloat(id.value));
break;
}
}
 
function insertHTML(sframe, callback){
var r = document.getElementById('fit'+sframe);
var htmlCode = generateHTMLcode(sframe);
r.insertAdjacentHTML('beforeend', htmlCode);
if(callback!=null){callback(sframe)}
}
 
function generateHTMLcode(sframe){
 
mform = '<button type="button" onclick="calculate('+ "'" + sframe + "'"+')">Draw Function</button>';
mform += '<button type="button" onclick="autoFit('+ "'" + sframe + "'"+')">Click to fit</button>';
mform += '<div class="rangeSettings">';
mform += 'Range: min = <input type="text" size="2" value="-5" name="min" id="minRange'+sframe+'" disabled=true>';
mform += 'max = <input type="text" size="2" value="5" name="max" id="maxRange'+sframe+'" disabled=true>';
mform += '<div style="display: inline-block;">';
mform += '&nbsp; &chi;²/ndf = <output id="chi2Output'+ sframe +'"></output> / <output id="ndfOutput'+ sframe +'"></output> = <output id="chi2Red'+ sframe +'"></output> <br>';
mform += '</div>';
mform += '<div class="slidecontainer" style="width:600px">';
mform += '<div class="slider-range" id="slider-range'+ sframe +'"></div>';
mform += '</div>';
mform += '</div>'
mform += ' <div id="fitPanel">'
mform += ' <div class="functionSelect">'
mform += ' Function:'
mform += ' <select name="fitfun" id="selectFitFun'+sframe+'" onclick="genFunList(' + "'" + sframe + "'"+ ')">'
mform += ' <option value="gaus">Gaus</option>'
mform += ' <option value="pol">Poly</option>'
mform += ' <option value="expo">Expo</option>'
mform += ' <option value="BW">Breit-Wigner</option>'
mform += ' <option value="gaus+pol">Gaus + Poly</option>'
mform += ' <option value="gaus+expo">Gaus + Expo</option>'
mform += ' <option value="BW+gaus">Gaus + Breit-Wigner</option>'
mform += ' <option value="pol+expo">Poly + Expo</option>'
mform += ' <option value="BW+pol">Poly + Breit-Wigner</option>'
mform += ' <option value="BW+expo">Expo + Breit-Wigner</option>'
mform += ' <option value="BW+expo+pol">Breit-Wigner + Poly + Expo</option>'
mform += ' <option value="BW+gaus+pol">Breit-Wigner + Poly + Gaus</option>'
mform += ' <option value="BW+expo+gaus">Breit-Wigner + Expo + Gaus</option>'
mform += ' <option value="gaus+pol+expo">Gaus + Poly + Expo</option>'
mform += ' <option value="BW+expo+gaus+pol">Breit-Wigner + Expo + Gaus + Poly</option>'
mform += ' </select>'
mform += ' <span id="functionDisplay'+sframe+'"></span>'
mform += ' </div>'
mform += ' <!--'
mform += ' This was replaced b select:option'
mform += ' <input type="text" name="fitfun" id="fitfun" value="pol" onblur="genFunList()"><br>'
mform += ' -->'
mform += ' <div id="gausFitPanel' + sframe + '" class="FitPanel">'
mform += ' <table class="inputParametersTable" id="inputParamTableGaus">'
mform += ' <tbody>'
mform += ' <tr class="description">'
mform += ' <td>Name</td>'
mform += ' <td>Fix</td>'
mform += ' <td>Bond</td>'
mform += ' <td>Value</td>'
mform += ' <td>Min</td>'
mform += ' <td>Set</td>'
mform += ' <td>Max</td>'
mform += ' <td>Step</td>'
mform += ' </tr>'
mform += ' <tr id="listMu">'
mform += ' <td><li>&mu;:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixMu'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondMu'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMu'+sframe+'" name="Mu" value="0" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMumin'+sframe+'" name="Mu" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamMuSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMumax'+sframe+'" name="Mu" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMustep'+sframe+'" name="Mu" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr id="listSigma">'
mform += ' <td><li>&sigma;:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixSigma'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondSigma'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamSigma'+sframe+'" name="Sigma" value="1" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamSigmamin'+sframe+'" name="Sigma" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamSigmaSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamSigmamax'+sframe+'" name="Sigma" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamSigmastep'+sframe+'" name="Sigma" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr id="listAmplitude">'
mform += ' <td><li>A:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixAmplitude'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondAmplitude'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmplitude'+sframe+'" name="Amplitude" value="1" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmplitudemin'+sframe+'" name="Amplitude" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamAmplitudeSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmplitudemax'+sframe+'" name="Amplitude" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmplitudestep'+sframe+'" name="Amplitude" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' </tbody>'
mform += ' </table>'
mform += ' </div>'
 
mform += ' <div id="polFitPanel' + sframe + '" class="FitPanel">'
mform += ' Polynomial order: <input type="text" name="polOrder" id="polOrderDisplay' + sframe + '" size="1" disabled=true>'
mform += ' <div style="width: 100px;display: inline-block;" id="slider-polOrder' + sframe + '"></div>'
mform += ' <table class="inputParametersTable">'
mform += ' <tbody>'
mform += ' <tr class="description">'
mform += ' <td>Name</td>'
mform += ' <td>Fix</td>'
mform += ' <td>Bond</td>'
mform += ' <td>Value</td>'
mform += ' <td>Min</td>'
mform += ' <td>Set</td>'
mform += ' <td>Max</td>'
mform += ' <td>Step</td>'
mform += ' </tr>'
mform += ' <tr class="pol" id="listA0'+sframe+'">'
mform += ' <td><li>A0:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixA0'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondA0'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA0'+sframe+'" name="A0" value="0" disabled=true onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA0min'+sframe+'" name="A0" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamA0Set'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA0max'+sframe+'" name="A0" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA0step'+sframe+'" name="A0" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr class="pol" id="listA1'+sframe+'">'
mform += ' <div id="rowA1">'
mform += ' <td><li>A1:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixA1'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondA1'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA1'+sframe+'" name="A1" value="0" disabled=true onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA1min'+sframe+'" name="A1" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamA1Set'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA1max'+sframe+'" name="A1" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA1step'+sframe+'" name="A1" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </div>'
mform += ' </tr>'
mform += ' <tr class="pol" id="listA2'+sframe+'">'
mform += ' <td><li>A2:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixA2'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondA2'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA2'+sframe+'" name="A2" value="0" disabled=true onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA2min'+sframe+'" name="A2" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamA2Set'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA2max'+sframe+'" name="A2" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA2step'+sframe+'" name="A2" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr class="pol" id="listA3'+sframe+'">'
mform += ' <td><li>A3:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixA3'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondA3'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA3'+sframe+'" name="A3" value="0" disabled=true onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA3min'+sframe+'" name="A3" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamA3Set'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA3max'+sframe+'" name="A3" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA3step'+sframe+'" name="A3" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr class="pol" id="listA4'+sframe+'">'
mform += ' <td><li>A4:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixA4'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondA4'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA4'+sframe+'" name="A4" value="0" disabled=true onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA4min'+sframe+'" name="A4" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamA4Set'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA4max'+sframe+'" name="A4" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamA4step'+sframe+'" name="A4" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' </tbody>'
mform += ' </table>'
mform += ' </div>'
 
 
mform += ' <div id="BWFitPanel' + sframe + '" class="FitPanel">'
mform += ' <table class="inputParametersTable" id="inputParamTableBW">'
mform += ' <tbody>'
mform += ' <tr class="description">'
mform += ' <td>Name</td>'
mform += ' <td>Fix</td>'
mform += ' <td>Bond</td>'
mform += ' <td>Value</td>'
mform += ' <td>Min</td>'
mform += ' <td>Set</td>'
mform += ' <td>Max</td>'
mform += ' <td>Step</td>'
mform += ' </tr>'
mform += ' <tr id="listGamma">'
mform += ' <td><li>&Gamma;:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixGamma'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondGamma'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamGamma'+sframe+'" name="Gamma" value="0" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamGammamin'+sframe+'" name="Gamma" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamGammaSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamGammamax'+sframe+'" name="Gamma" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamGammastep'+sframe+'" name="Gamma" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr id="listM">'
mform += ' <td><li>M:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixM'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondM'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamM'+sframe+'" name="M" value="1" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMmin'+sframe+'" name="M" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamMSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMmax'+sframe+'" name="M" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamMstep'+sframe+'" name="M" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr id="listAmpBW">'
mform += ' <td><li>A:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixAmpBW'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondAmpBW'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpBW'+sframe+'" name="AmpBW" value="1" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpBWmin'+sframe+'" name="AmpBW" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamAmpBWSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpBWmax'+sframe+'" name="AmpBW" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpBWstep'+sframe+'" name="AmpBW" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' </tbody>'
mform += ' </table>'
mform += ' </div>'
 
mform += ' <div id="expoFitPanel' + sframe + '" class="FitPanel">'
mform += ' <table class="inputParametersTable" id="inputParamTableExpo">'
mform += ' <tbody>'
mform += ' <tr class="description">'
mform += ' <td>Name</td>'
mform += ' <td>Fix</td>'
mform += ' <td>Bond</td>'
mform += ' <td>Value</td>'
mform += ' <td>Min</td>'
mform += ' <td>Set</td>'
mform += ' <td>Max</td>'
mform += ' <td>Step</td>'
mform += ' </tr>'
mform += ' <tr id="listK">'
mform += ' <td><li>K:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixK'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondK'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamK'+sframe+'" name="K" value="0" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamKmin'+sframe+'" name="K" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamKSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamKmax'+sframe+'" name="K" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamKstep'+sframe+'" name="K" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' <tr id="listAmpExp">'
mform += ' <td><li>A:</td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="fixAmpExp'+sframe+'"></td>'
mform += ' <td><input type="checkbox" class="inputParamBox" id="bondAmpExp'+sframe+'"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpExp'+sframe+'" name="AmpExp" value="1" onblur="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpExpmin'+sframe+'" name="AmpExp" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><div name="ParamSlider" class="ParamSlider'+sframe+'" id="ParamAmpExpSet'+sframe+'"></div></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpExpmax'+sframe+'" name="AmpExp" onkeyup="updateSetSlider(this)"></td>'
mform += ' <td><input type="text" class="inputParam" id="ParamAmpExpstep'+sframe+'" name="AmpExp" value="0.1" onkeyup="updateSetSlider(this)"></td>'
mform += ' </tr>'
mform += ' </tbody>'
mform += ' </table>'
mform += ' </div>'
mform += ' </div>'
 
return mform
}
 
/belle2/masterclass/runscript.php
286,7 → 286,7
$init = PHP_EOL . "void Blab2::Init(){" . PHP_EOL ;
$init .="fNeve=$neve;" . PHP_EOL ;
$init .="fNfirst=$first;" . PHP_EOL ;
$init .="fData=$source;" . PHP_EOL ;
$init .='fData="' . $source . '";' . PHP_EOL ;
$init .="fPrint=$evprint;" . PHP_EOL ;
foreach ($nodelist as $node) {
$init .= $node->nodeName . "(";
/belle2/masterclass/src/Blab2.cc
40,7 → 40,7
UInt_t fNeve;
UInt_t fNfirst;
UInt_t fPrint;
int fData;
TString fData;
TH1F *fH[100];
UInt_t fHtype[100];
TClonesArray *fList[100];
58,7 → 58,7
int combiner3(int id0 ,int id1 , int id2, int same, SIMPLEPID particlename, double min, double max, int hid, int id );
int combiner3(int id0 ,int id1 , int id2, int same, SIMPLEPID particlename, double min, double max, std::vector<int>hid, int id );
int fix_mass(int id);
int Fill(std::vector<int> hid, std::vector<BParticle *> p);
int Fill(std::vector<int> hid, BParticle *p);
void plist(int i);
 
 
67,7 → 67,7
 
ClassImp(Blab2)
 
Blab2::Blab2():fNfirst(0), fNeve(0), fData(0), fPrint(0) {
Blab2::Blab2():fNfirst(0), fNeve(0), fData(), fPrint(0) {
 
Process();
};
84,7 → 84,7
"momentum (GeV/c)",
"momentum (GeV/c)",
"angle (deg.)",
"cos(theta)", "#Deltamass_{1}(GeV/c2)", "#Deltamass_{2}(GeV/c2)", "#Delta mass_{3}(GeV/c2)"};
"cos(theta)"};
fHtype[id] = 0;
if (svar.Contains("GetMass" )) fHtype[id]=0;
if (svar.Contains("GetMomentum")) fHtype[id]=1;
97,9 → 97,6
if (svar.Contains("GetTransverseMomentum")) fHtype[id]=8;
if (svar.Contains("GetTheta")) fHtype[id]=9;
if (svar.Contains("GetCosTheta")) fHtype[id]=10;
if (svar.Contains("GetDeltaMass1" )) fHtype[id]=11;
if (svar.Contains("GetDeltaMass2" )) fHtype[id]=12;
if (svar.Contains("GetDeltaMass3" )) fHtype[id]=13;
 
//fH[id]= new TH1F(TString::Format("h%d",id), TString::Format("%s;%s;N",name,axis[fHtype[id]].Data()), nbins, min, max);
if (fHtype[id]==4) {
114,10 → 111,9
 
 
 
int Blab2::Fill(std::vector<int> id, std::vector<BParticle *> particle){
int Blab2::Fill(std::vector<int> id, BParticle *p){
for (int i=0; i< id.size(); i++){
int hid = id[i];
BParticle *p= particle[0];
int hid = id[i];
if (hid>=0 && fH[hid]) {
double val;
switch (fHtype[hid]){
132,12 → 128,6
case 8 : val = p->GetTransverseMomentum(); break;
case 9 : val = (p->GetMomentum()!=0) ? p->pz()/p->GetMomentum() : 0; val = 180.0*TMath::ACos(val)/TMath::Pi(); break;
case 10: val = (p->GetMomentum()!=0) ? p->pz()/p->GetMomentum() : 0; break;
case 11 :
case 12 :
case 13 : {
int idx = fHtype[hid]-10;
val = (particle.size()>idx) ? p->GetMass() - particle[idx]->GetMass() : 0; break;
}
default: val = 0 ; break;
}
fH[hid]->Fill(val);
164,7 → 154,6
 
fList[_p2]->Clear();
std::vector<BParticle *> pall(3);
int nprt=0;
for(TIter next1(fList[_p0]);BParticle * p1 =(BParticle *) next1();) {
172,13 → 161,9
// in the case the second parti
for(TIter next2 = (_p0!=_p1 && same==0) ? TIter(fList[_p1]): TIter(next1) ; BParticle * p2 =(BParticle *) next2();) {
if (p1==p2) continue; // do not use the same particle in the combinations
BParticle p = *p1 + *p2; // Combine two particles into a new particle
pall[0] = &p;
pall[1] = p1;
pall[2] = p2;
 
BParticle p = *p1 + *p2; // Combine two particles into a new particle
if (p.InMassRange(min, max)){
Fill(hid, pall);
Fill(hid, &p);
p.SetPid(pid); // set PID to particlename to fix the particle mass
p.SetEnergyFromPid();
TClonesArray& list = *fList[_p2];
201,8 → 186,6
 
fList[_p3]->Clear();
std::vector<BParticle *> pall(4);
 
int nprt=0;
for(TIter next1(fList[_p0]);BParticle * p1 =(BParticle *) next1();) {
212,15 → 195,9
if (p1==p2) continue; // do not use the same particle in the combinations
for(TIter next3 = (_p1!=_p2 && same==0) ? TIter(fList[_p2]): TIter(next2) ; BParticle * p3 =(BParticle *) next3();) {
if (p2==p3) continue; // do not use the same particle in the combinations
BParticle p = *p1 + *p2 + *p3 ; // Combine two particles into a new particle
pall[0] = &p;
pall[1] = p1;
pall[2] = p2;
pall[3] = p3;
 
BParticle p = *p1 + *p2 + *p3; // Combine two particles into a new particle
if (p.InMassRange(min, max)){
Fill(hid, pall);
Fill(hid, &p);
p.SetPid(pid); // set PID to particlename to fix the particle mass
p.SetEnergyFromPid();
TClonesArray& list = *fList[_p3];
244,7 → 221,6
fList[pout]->Clear();
int nprt=0;
std::vector<BParticle *> pall(1);
for(TIter next(fList[pin]); BParticle * p =(BParticle *) next();) {
if (p->charge()== charge || charge > 1){
251,8 → 227,7
if ( p->pid()== type || type == ALL ) {
TClonesArray& list = *fList[pout];
new (list[nprt++]) BParticle ( *p );
pall[0] = p ;
Fill(hid, pall);
Fill(hid, p);
}
}
}
294,8 → 269,8
 
Init();
 
TFile * f = new TFile(TString::Format("../../data/hadron-%d.root",fData)); // Open a data file
if(f->IsZombie()) { send_message(0,TString::Format("File %d not found\n",fData), 0 ); return; }
TFile * f = new TFile(TString::Format("../../data/%s",fData.Data())); // Open a data file
if(f->IsZombie()) { send_message(0,TString::Format("File %s not found\n",fData.Data()), 0 ); return; }
TTree * t =(TTree *) f-> Get( "T"); // Obtain a pointer to a tree of "event" data in the file
BEvent * mevent = new BEvent(); // Create a "BEvent" object where data from the file will be loaded
TBranch * branch = t-> GetBranch( "BEvent"); // Obtain a branch for "BEvent" in the tree
/belle2/masterclass/style.css
0,0 → 1,89
.slidecontainer {
width: 100%; /* Width of the outside container */
}
/* The slider itself */
.slider {
/*Trak*/
-webkit-appearance: none; /* Override default CSS styles */
appearance: none;
width: 25%; /* Full-width */
height: 12px; /* Specified height */
background: #e9e9e9; /* Grey background */
outline: none; /* Remove outline */
opacity: 1; /* Set transparency (for mouse-over effects on hover) */
-webkit-transition: .2s; /* 0.2 seconds transition on hover */
transition: opacity .2s;
border: 1px solid #c5c5c5;
opacity: 0.7;
}
 
/* Mouse-over effects */
.slider:hover {
opacity: 1; /* Fully shown on mouse-over */
 
}
 
/* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */
.slider::-webkit-slider-thumb {
-webkit-appearance: none; /* Override default look */
appearance: none;
width: 25px; /* Set a specific slider handle width */
height: 25px; /* Slider handle height */
background: #4CAF50; /* Green background ?*/
cursor: pointer; /* Cursor on hover */
}
 
.slider::-moz-range-thumb {
border: 1px solid #c4c4c4;
width: 20px; /* Set a specific slider handle width */
height: 20px; /* Slider handle height */
background: #f9f9f9; /* Green background */
opacity: 0.9;
cursor: pointer; /* Cursor on hover */
}
 
.slider::-moz-range-thumb:active{
background: #007fff;
border: 1px solid #003eff;
}
 
.inputParam{
width: 100px;
}
 
.inputParametersTable{
text-align: center;
width: 700px;
}
 
.polParamSlider{
margin-left: 5px;
margin-right: 7px;
width: 100px;
}
 
.ParamSlider{
/*Should be same as polParamSlider*/
margin-left: 7px;
margin-right: 7px;
width: 100px;
}
 
div[name="ParamSlider"]{
margin-left: 5px;
margin-right: 7px;
width: 100px;
}
 
.functionSelect{
padding-top: 10px;
}
 
.FitPanel{
padding-top: 10px;
}
 
.rangeSettings{
padding-top: 10px;
}