9 if (typeof JSROOT ==
"object") {
10 var e1 =
new Error(
"JSROOT is already defined");
11 e1.source =
"JSRootCore.js";
17 JSROOT.version =
"3.1a 9/12/2014";
19 JSROOT.source_dir =
function(){
20 var scripts = document.getElementsByTagName(
'script');
22 for (var n in scripts) {
23 if (scripts[n][
'type'] !=
'text/javascript')
continue;
25 var src = scripts[n][
'src'];
26 if ((src == null) || (src.length == 0))
continue;
28 var pos = src.indexOf(
"scripts/JSRootCore.js");
31 console.log(
"Set JSROOT.source_dir to " + src.substr(0, pos));
32 return src.substr(0, pos);
38 JSROOT.clone =
function(obj) {
39 return jQuery.extend(
true, {}, obj);
42 JSROOT.id_counter = 0;
44 JSROOT.function_list = [];
46 JSROOT.BIT =
function(n) {
return 1 << (n); }
49 JSROOT.TH1StatusBits = {
50 kNoStats : JSROOT.BIT(9),
51 kUserContour : JSROOT.BIT(10),
52 kCanRebin : JSROOT.BIT(11),
53 kLogX : JSROOT.BIT(15),
54 kIsZoomed : JSROOT.BIT(16),
55 kNoTitle : JSROOT.BIT(17),
56 kIsAverage : JSROOT.BIT(18)
60 kTickPlus : JSROOT.BIT(9),
61 kTickMinus : JSROOT.BIT(10),
62 kAxisRange : JSROOT.BIT(11),
63 kCenterTitle : JSROOT.BIT(12),
64 kCenterLabels : JSROOT.BIT(14),
65 kRotateTitle : JSROOT.BIT(15),
66 kPalette : JSROOT.BIT(16),
67 kNoExponent : JSROOT.BIT(17),
68 kLabelsHori : JSROOT.BIT(18),
69 kLabelsVert : JSROOT.BIT(19),
70 kLabelsDown : JSROOT.BIT(20),
71 kLabelsUp : JSROOT.BIT(21),
72 kIsInteger : JSROOT.BIT(22),
73 kMoreLogLabels : JSROOT.BIT(23),
74 kDecimals : JSROOT.BIT(11)
82 JSROOT.JSONR_unref =
function(value, dy)
87 switch (typeof value) {
89 if ((value.length > 5) && (value.substr(0, 5) ==
"$ref:")) {
90 c = parseInt(value.substr(5));
91 if (!isNaN(c) && (c < dy.length)) {
101 if (Object.prototype.toString.apply(value) ===
'[object Array]') {
102 for (i = 0; i < value.length; i++) {
103 value[i] = JSROOT.JSONR_unref(value[i], dy);
108 if (dy.indexOf(value) === -1) {
114 if ((
'_typename' in value) && (typeof JSROOT ==
"object"))
115 JSROOT.addMethods(value);
117 ks = Object.keys(value);
118 for (i = 0; i < ks.length; i++) {
121 value[k] = JSROOT.JSONR_unref(value[k], dy);
131 JSROOT.parse =
function(arg) {
132 if ((arg==null) || (arg==
""))
return null;
133 var obj = JSON.parse(arg);
134 if (obj!=null) obj = JSROOT.JSONR_unref(obj)
138 JSROOT.GetUrlOption =
function(opt, url, dflt) {
144 if ((opt==null) || (typeof opt !=
'string') || (opt.length==0))
return dflt;
146 if (!url) url = document.URL;
148 var pos = url.indexOf(
"?");
149 if (pos<0)
return null;
150 url = url.slice(pos+1);
152 while (url.length>0) {
154 if (url==opt)
return "";
156 pos = url.indexOf(
"&");
157 if (pos < 0) pos = url.length;
159 if (url.indexOf(opt) == 0) {
160 if (url.charAt(opt.length)==
"&")
return "";
163 if (url.charAt(opt.length)==
"=")
164 return url.slice(opt.length+1, pos).replace(/%27/g,
"'").replace(/%22/g,
'"').replace(/%20/g,
' ').replace(/%3C/g,
'<').replace(/%3E/g,
'>');
167 url = url.slice(pos+1);
172 JSROOT.NewHttpRequest =
function(url, kind, user_call_back) {
184 function callback(res) {
185 if (typeof user_call_back ==
'function') user_call_back(res);
188 var xhr =
new XMLHttpRequest();
191 if (window.ActiveXObject) {
194 xhr.onreadystatechange =
function() {
196 if (xhr.readyState != 4)
return;
198 if (xhr.status != 200 && xhr.status != 206) {
200 return callback(null);
203 if (kind ==
"xml")
return callback(xhr.responseXML);
205 if (kind ==
"text")
return callback(xhr.responseText);
207 if (kind ==
"object")
return callback(JSROOT.parse(xhr.responseText));
209 if (kind ==
"head")
return callback(xhr);
211 var filecontent =
new String(
"");
212 var array =
new VBArray(xhr.responseBody).toArray();
213 for (var i = 0; i < array.length; i++) {
214 filecontent = filecontent + String.fromCharCode(array[i]);
217 callback(filecontent);
221 xhr.open(kind ==
'head' ?
'HEAD' :
'GET', url,
true);
225 xhr.onreadystatechange =
function() {
226 if (xhr.readyState != 4)
return;
228 if (xhr.status != 0 && xhr.status != 200 && xhr.status != 206) {
229 return callback(null);
231 if (kind ==
"xml")
return callback(xhr.responseXML);
232 if (kind ==
"text")
return callback(xhr.responseText);
233 if (kind ==
"object")
return callback(JSROOT.parse(xhr.responseText));
234 if (kind ==
"head")
return callback(xhr);
236 var HasArrayBuffer = (
'ArrayBuffer' in window &&
'Uint8Array' in window);
237 var Buf, filecontent;
238 if (HasArrayBuffer &&
'mozResponse' in xhr) {
239 Buf = xhr.mozResponse;
240 }
else if (HasArrayBuffer && xhr.mozResponseArrayBuffer) {
241 Buf = xhr.mozResponseArrayBuffer;
242 }
else if (
'responseType' in xhr) {
245 Buf = xhr.responseText;
246 HasArrayBuffer =
false;
249 if (HasArrayBuffer) {
250 filecontent =
new String(
"");
251 var bLen = Buf.byteLength;
252 var u8Arr =
new Uint8Array(Buf, 0, bLen);
253 for (var i = 0; i < u8Arr.length; i++) {
254 filecontent = filecontent + String.fromCharCode(u8Arr[i]);
261 callback(filecontent);
266 xhr.open(kind ==
'head' ?
'HEAD' :
'GET', url,
true);
269 var HasArrayBuffer = (
'ArrayBuffer' in window &&
'Uint8Array' in window);
270 if (HasArrayBuffer &&
'mozResponseType' in xhr) {
271 xhr.mozResponseType =
'arraybuffer';
272 }
else if (HasArrayBuffer &&
'responseType' in xhr) {
273 xhr.responseType =
'arraybuffer';
276 xhr.overrideMimeType(
"text/plain; charset=x-user-defined");
283 JSROOT.loadScript =
function(urllist, callback, debugout) {
292 function debug(str) {
294 document.getElementById(debugout).innerHTML = str;
299 function completeLoad() {
300 if ((urllist!=null) && (urllist.length>0))
301 return JSROOT.loadScript(urllist, callback, debugout);
304 document.getElementById(debugout).innerHTML =
"";
306 if (typeof callback ==
'function') callback();
309 if ((urllist==null) || (urllist.length==0))
310 return completeLoad();
312 var filename = urllist;
313 var separ = filename.indexOf(
";");
315 filename = filename.substr(0, separ);
316 urllist = urllist.slice(separ+1);
321 var isrootjs =
false;
322 if (filename.indexOf(
"$$$")==0) {
324 filename = filename.slice(3);
326 var isstyle = filename.indexOf(
'.css') > 0;
329 var styles = document.getElementsByTagName(
'link');
330 for (var n in styles) {
331 if ((styles[n][
'type'] !=
'text/css') || (styles[n][
'rel'] !=
'stylesheet'))
continue;
333 var href = styles[n][
'href'];
334 if ((href == null) || (href.length == 0))
continue;
336 if (href.indexOf(filename)>=0) {
337 console.log(
"style "+ filename +
" already loaded");
338 return completeLoad();
343 var scripts = document.getElementsByTagName(
'script');
345 for (var n in scripts) {
346 if (scripts[n][
'type'] !=
'text/javascript')
continue;
348 var src = scripts[n][
'src'];
349 if ((src == null) || (src.length == 0))
continue;
351 if (src.indexOf(filename)>=0) {
353 return completeLoad();
358 if (isrootjs && (JSROOT.source_dir!=null)) filename = JSROOT.source_dir + filename;
362 debug(
"loading " + filename +
" ...");
365 element = document.createElement(
"link");
366 element.setAttribute(
"rel",
"stylesheet");
367 element.setAttribute(
"type",
"text/css");
368 element.setAttribute(
"href", filename);
370 element = document.createElement(
"script");
371 element.setAttribute(
'type',
"text/javascript");
372 element.setAttribute(
'src', filename);
375 if (element.readyState) {
376 element.onreadystatechange =
function() {
377 if (element.readyState ==
"loaded" || element.readyState ==
"complete") {
378 element.onreadystatechange = null;
383 element.onload =
function() {
384 element.onload = null;
389 document.getElementsByTagName(
"head")[0].appendChild(element);
392 JSROOT.AssertPrerequisites =
function(kind, andThan, debugout) {
400 if (typeof kind ==
'function') { andThan = kind; kind = null; }
402 if (typeof kind !=
'string') kind =
"2d";
403 if (kind.charAt(kind.length-1)!=
";") kind+=
";";
406 var allfiles =
'$$$scripts/jquery.min.js';
408 if (kind.indexOf(
'io;')>=0)
409 allfiles +=
";$$$scripts/rawinflate.js" +
410 ";$$$scripts/JSRootIOEvolution.js";
412 if (kind.indexOf(
'2d;')>=0)
413 allfiles +=
';$$$style/jquery-ui.css' +
414 ';$$$scripts/jquery-ui.min.js' +
415 ';$$$scripts/d3.v3.min.js' +
416 ';$$$scripts/JSRootPainter.js' +
417 ';$$$style/JSRootPainter.css';
419 if (kind.indexOf(
"3d;")>=0)
420 allfiles +=
";$$$scripts/jquery.mousewheel.js" +
421 ";$$$scripts/three.min.js" +
422 ";$$$scripts/helvetiker_regular.typeface.js" +
423 ";$$$scripts/helvetiker_bold.typeface.js" +
424 ";$$$scripts/JSRoot3DPainter.js";
426 if (kind.indexOf(
"simple;")>=0)
427 allfiles +=
';$$$scripts/JSRootInterface.js' +
428 ';$$$style/JSRootInterface.css';
430 var pos = kind.indexOf(
"user:");
432 allfiles +=
";" + kind.slice(pos+5);
434 JSROOT.loadScript(allfiles, andThan, debugout);
437 JSROOT.BuildSimpleGUI =
function(user_scripts, andThen) {
438 if (typeof user_scripts ==
'function') {
439 andThen = user_scripts;
445 var requirements =
"2d;io;simple;";
447 if (document.getElementById(
'simpleGUI')) debugout =
'simpleGUI';
else
448 if (document.getElementById(
'onlineGUI')) { debugout =
'onlineGUI'; requirements =
"2d;simple;"; }
450 if (user_scripts == null)
451 user_scripts = JSROOT.GetUrlOption(
"autoload");
453 if (user_scripts != null)
454 requirements +=
"user:" + user_scripts +
";";
456 JSROOT.AssertPrerequisites(requirements,
function() {
457 if (typeof BuildSimpleGUI ==
'function') BuildSimpleGUI();
458 if (typeof andThen ==
'function') andThen();
462 JSROOT.addFormula =
function(obj) {
463 var formula = obj[
'fTitle'];
464 formula = formula.replace(
'abs(',
'Math.abs(');
465 formula = formula.replace(
'sin(',
'Math.sin(');
466 formula = formula.replace(
'cos(',
'Math.cos(');
467 var code = obj[
'fName'] +
" = function(x) { return " + formula +
" };";
469 var sig = obj[
'fName']+
'(x)';
471 var pos = JSROOT.function_list.indexOf(sig);
473 JSROOT.function_list.splice(pos, 1);
475 JSROOT.function_list.push(sig);
478 JSROOT.Create =
function(
typename, target) {
481 obj = { _typename:
typename };
483 if (
typename ==
'TObject')
484 jQuery.extend(obj, { fUniqueID: 0, fBits: 0x3000008 });
486 if (
typename ==
'TNamed')
487 jQuery.extend(obj, { fUniqueID: 0, fBits: 0x3000008, fName:
"", fTitle:
"" });
489 if (
typename ==
'TList')
490 jQuery.extend(obj, { name:
"TList", arr : [], opt : [] });
492 if (
typename ==
'TAttAxis') {
493 jQuery.extend(obj, { fNdivisions: 510, fAxisColor: 1,
494 fLabelColor: 1, fLabelFont: 42, fLabelOffset: 0.05, fLabelSize: 0.035, fTickLength: 0.03,
495 fTitleOffset: 1, fTitleSize: 0.035, fTitleColor: 1, fTitleFont : 42 });
497 if (
typename ==
'TAxis') {
498 JSROOT.Create(
"TNamed", obj);
499 JSROOT.Create(
"TAttAxis", obj);
500 jQuery.extend(obj, { fNbins: 0, fXmin: 0, fXmax: 0, fXbins : [], fFirst: 0, fLast: 0,
501 fBits2: 0, fTimeDisplay:
false, fTimeFormat:
"", fLabels: null });
503 if (
typename ==
'TAttLine') {
504 jQuery.extend(obj, { fLineColor: 1, fLineStyle : 1, fLineWidth : 1 });
506 if (
typename ==
'TAttFill') {
507 jQuery.extend(obj, { fFillColor: 0, fFillStyle : 0 } );
509 if (
typename ==
'TAttMarker') {
510 jQuery.extend(obj, { fMarkerColor: 1, fMarkerStyle : 1, fMarkerSize : 1. });
512 if (
typename ==
'TBox') {
513 JSROOT.Create(
"TObject", obj);
514 JSROOT.Create(
"TAttLine", obj);
515 JSROOT.Create(
"TAttFill", obj);
516 jQuery.extend(obj, { fX1: 0, fY1: 0, fX2: 1, fY2: 1 });
518 if (
typename ==
'TPave') {
519 JSROOT.Create(
"TBox", obj);
520 jQuery.extend(obj, { fX1NDC : 0., fY1NDC: 0, fX2NDC: 1, fY2NDC: 1,
521 fBorderSize: 0, fInit: 1, fShadowColor: 1,
522 fCornerRadius: 0, fOption:
"blNDC", fName:
"title" });
524 if (
typename ==
'TAttText') {
525 jQuery.extend(obj, { fTextAngle: 0, fTextSize: 0, fTextAlign: 22, fTextColor: 1, fTextFont: 42});
527 if (
typename ==
'TPaveText') {
528 JSROOT.Create(
"TPave", obj);
529 JSROOT.Create(
"TAttText", obj);
530 jQuery.extend(obj, { fLabel:
"", fLongest: 27, fMargin: 0.05, fLines: JSROOT.Create(
"TList") });
532 if (
typename ==
'TPaveStats') {
533 JSROOT.Create(
"TPaveText", obj);
534 jQuery.extend(obj, { fOptFit: 0, fOptStat: 0, fFitFormat:
"", fStatFormat:
"", fParent: null });
536 if (
typename ==
'TH1') {
537 JSROOT.Create(
"TNamed", obj);
538 JSROOT.Create(
"TAttLine", obj);
539 JSROOT.Create(
"TAttFill", obj);
540 JSROOT.Create(
"TAttMarker", obj);
544 fXaxis: JSROOT.Create(
"TAxis"),
545 fYaxis: JSROOT.Create(
"TAxis"),
546 fZaxis: JSROOT.Create(
"TAxis"),
547 fBarOffset : 0, fBarWidth : 1000, fEntries : 0.,
548 fTsumw : 0., fTsumw2 : 0., fTsumwx : 0., fTsumwx2 : 0.,
549 fMaximum : -1111., fMinimum : -1111, fNormFactor : 0., fContour : [],
550 fSumw2 : [], fOption :
"",
551 fFunctions : JSROOT.Create(
"TList"),
552 fBufferSize : 0, fBuffer : [], fBinStatErrOpt : 0 });
554 if (
typename ==
'TH1I' ||
typename ==
'TH1F' ||
typename ==
'TH1D' ||
typename ==
'TH1S' ||
typename ==
'TH1C') {
555 JSROOT.Create(
"TH1", obj);
556 jQuery.extend(obj, { fN : 0, fArray: [] });
558 if (
typename ==
'TH2') {
559 JSROOT.Create(
"TH1", obj);
560 jQuery.extend(obj, { fScalefactor: 1., fTsumwy: 0., fTsumwy2: 0, fTsumwxy : 0});
562 if (
typename ==
'TH2I' ||
typename ==
'TH2F' ||
typename ==
'TH2D' ||
typename ==
'TH2S' ||
typename ==
'TH2C') {
563 JSROOT.Create(
"TH2", obj);
564 jQuery.extend(obj, { fN : 0, fArray: [] });
566 if (
typename ==
'TGraph') {
567 JSROOT.Create(
"TNamed", obj);
568 JSROOT.Create(
"TAttLine", obj);
569 JSROOT.Create(
"TAttFill", obj);
570 JSROOT.Create(
"TAttMarker", obj);
571 jQuery.extend(obj, { fFunctions: JSROOT.Create(
"TList"), fHistogram: JSROOT.CreateTH1(),
572 fMaxSize: 0, fMaximum:0, fMinimum:0, fNpoints: 0, fX: [], fY: [] });
575 JSROOT.addMethods(obj,
typename);
580 JSROOT.CreateTList =
function() {
return JSROOT.Create(
"TList"); }
581 JSROOT.CreateTAxis =
function() {
return JSROOT.Create(
"TAxis"); }
583 JSROOT.CreateTH1 =
function(nbinsx) {
584 var histo = JSROOT.Create(
"TH1I");
585 jQuery.extend(histo, { fName:
"dummy_histo_" + this.id_counter++, fTitle:
"dummytitle" });
588 histo[
'fN'] = histo[
'fNcells'] = nbinsx+2;
589 for (var i=0;i<histo[
'fNcells'];i++) histo[
'fArray'].push(0);
590 jQuery.extend(histo[
'fXaxis'], { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx });
595 JSROOT.CreateTH2 =
function(nbinsx, nbinsy) {
596 var histo = JSROOT.Create(
"TH2I");
597 jQuery.extend(histo, { fName:
"dummy_histo_" + this.id_counter++, fTitle:
"dummytitle" });
599 if ((nbinsx!=null) && (nbinsy!=null)) {
600 histo[
'fN'] = histo[
'fNcells'] = (nbinsx+2) * (nbinsy+2);
601 for (var i=0;i<histo[
'fNcells'];i++) histo[
'fArray'].push(0);
602 jQuery.extend(histo[
'fXaxis'], { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx });
603 jQuery.extend(histo[
'fYaxis'], { fNbins: nbinsy, fXmin: 0, fXmax: nbinsy });
608 JSROOT.CreateTGraph =
function(npoints) {
609 var graph = JSROOT.Create(
"TGraph");
610 jQuery.extend(graph, { fBits: 0x3000408, fName:
"dummy_graph_" + this.id_counter++, fTitle:
"dummytitle" });
613 graph[
'fMaxSize'] = graph[
'fNpoints'] = npoints;
614 for (var i=0;i<npoints;i++) {
618 JSROOT.AdjustTGraphRanges(graph);
624 JSROOT.AdjustTGraphRanges =
function(graph) {
625 if (graph[
'fNpoints']==0)
return;
627 var minx = graph[
'fX'][0], maxx = minx;
628 var miny = graph[
'fY'][0], maxy = miny;
630 for (var i=1;i<graph[
'fNpoints'];i++) {
631 if (graph[
'fX'][i] < minx) minx = graph[
'fX'][i];
632 if (graph[
'fX'][i] > maxx) maxx = graph[
'fX'][i];
633 if (graph[
'fY'][i] < miny) miny = graph[
'fY'][i];
634 if (graph[
'fY'][i] > maxy) maxy = graph[
'fY'][i];
637 if (miny==maxy) maxy = miny + 1;
639 graph[
'fHistogram'][
'fXaxis'][
'fXmin'] = minx;
640 graph[
'fHistogram'][
'fXaxis'][
'fXmax'] = maxx;
642 graph[
'fHistogram'][
'fYaxis'][
'fXmin'] = miny;
643 graph[
'fHistogram'][
'fYaxis'][
'fXmax'] = maxy;
646 JSROOT.addMethods =
function(obj, obj_typename) {
648 if ((
'fBits' in obj) && !(
'TestBit' in obj)) {
649 obj[
'TestBit'] =
function (f) {
650 return ((obj[
'fBits'] & f) != 0);
655 if (!(
'_typename' in obj))
return;
656 obj_typename = obj[
'_typename'];
672 if (obj_typename.indexOf(
"TAxis") == 0) {
673 obj[
'getFirst'] =
function() {
674 if (!this.TestBit(JSROOT.EAxisBits.kAxisRange))
return 1;
675 return this[
'fFirst'];
677 obj[
'getLast'] =
function() {
678 if (!this.TestBit(JSROOT.EAxisBits.kAxisRange))
return this[
'fNbins'];
679 return this[
'fLast'];
681 obj[
'getBinCenter'] =
function(bin) {
684 if (!
this[
'fN'] || bin < 1 || bin >
this[
'fNbins']) {
685 binwidth = (
this[
'fXmax'] -
this[
'fXmin']) /
this[
'fNbins'];
686 return this[
'fXmin'] + (bin-1) * binwidth + 0.5*binwidth;
688 binwidth =
this[
'fXbins'][bin] -
this[
'fXbins'][bin-1];
689 return this[
'fXbins'][bin-1] + 0.5*binwidth;
694 if (obj_typename ==
"TList") {
695 obj[
'Clear'] =
function() {
696 this[
'arr'] =
new Array;
697 this[
'opt'] =
new Array;
699 obj[
'Add'] =
function(obj,opt) {
700 this[
'arr'].push(obj);
701 this[
'opt'].push((typeof opt==
'string') ? opt :
"");
705 if ((obj_typename ==
"TPaveText") || (obj_typename ==
"TPaveStats")) {
706 obj[
'AddText'] =
function(txt) {
707 this[
'fLines'].Add({
'fTitle' : txt,
"fTextColor" : 1 });
709 obj[
'Clear'] =
function() {
710 this[
'fLines'].Clear();
714 if ((obj_typename.indexOf(
"TFormula") != -1) ||
715 (obj_typename.indexOf(
"TF1") == 0)) {
716 obj[
'evalPar'] =
function(x) {
717 var i, _function =
this[
'fTitle'];
718 _function = _function.replace(
'TMath::Exp(',
'Math.exp(');
719 _function = _function.replace(
'TMath::Abs(',
'Math.abs(');
720 _function = _function.replace(
'gaus(',
'JSROOT.Math.gaus(this, ' + x +
', ');
721 _function = _function.replace(
'gausn(',
'JSROOT.Math.gausn(this, ' + x +
', ');
722 _function = _function.replace(
'expo(',
'JSROOT.Math.expo(this, ' + x +
', ');
723 _function = _function.replace(
'landau(',
'JSROOT.Math.landau(this, ' + x +
', ');
724 _function = _function.replace(
'landaun(',
'JSROOT.Math.landaun(this, ' + x +
', ');
725 _function = _function.replace(
'pi',
'Math.PI');
726 for (i=0;i<
this[
'fNpar'];++i) {
727 while(_function.indexOf(
'['+i+
']') != -1)
728 _function = _function.replace(
'['+i+
']',
this[
'fParams'][i])
730 for (i=0;i<JSROOT.function_list.length;++i) {
731 var f = JSROOT.function_list[i].substring(0, JSROOT.function_list[i].indexOf(
'('));
732 if (_function.indexOf(f) != -1) {
733 var fa = JSROOT.function_list[i].replace(
'(x)',
'(' + x +
')');
734 _function = _function.replace(f, fa);
738 _function = _function.replace(/\b(x)\b/gi, x)
739 _function = _function.replace(/\b(sin)\b/gi,
'Math.sin')
740 _function = _function.replace(/\b(cos)\b/gi,
'Math.cos')
741 _function = _function.replace(/\b(tan)\b/gi,
'Math.tan')
742 var ret = eval(_function);
746 if ((obj_typename.indexOf(
"TGraph") == 0) || (obj_typename ==
"TCutG")) {
747 obj[
'ComputeRange'] =
function() {
749 var res = { xmin: 0, xmax: 0, ymin: 0, ymax: 0 };
750 if (
this[
'fNpoints'] > 0) {
751 res.xmin = res.xmax =
this[
'fX'][0];
752 res.ymin = res.ymax =
this[
'fY'][0];
753 for (var i=1; i<
this[
'fNpoints']; i++) {
754 if (
this[
'fX'][i] < res.xmin) res.xmin =
this[
'fX'][i];
755 if (
this[
'fX'][i] > res.xmax) res.xmax =
this[
'fX'][i];
756 if (
this[
'fY'][i] < res.ymin) res.ymin =
this[
'fY'][i];
757 if (
this[
'fY'][i] > res.ymax) res.ymax =
this[
'fY'][i];
763 obj[
'IsInside'] =
function(xp,yp) {
764 var j =
this[
'fNpoints'] - 1 ;
765 var x =
this[
'fX'], y =
this[
'fY'];
766 var oddNodes =
false;
768 for (var i=0; i<
this[
'fNpoints']; i++) {
769 if ((y[i]<yp && y[j]>=yp) || (y[j]<yp && y[i]>=yp)) {
770 if (x[i]+(yp-y[i])/(y[j]-y[i])*(x[j]-x[i])<xp) {
771 oddNodes = !oddNodes;
780 if (obj_typename.indexOf(
"TH1") == 0 ||
781 obj_typename.indexOf(
"TH2") == 0 ||
782 obj_typename.indexOf(
"TH3") == 0) {
783 obj[
'getBinError'] =
function(bin) {
788 if (bin < 0) bin = 0;
789 if (bin >=
this[
'fNcells']) bin =
this[
'fNcells'] - 1;
790 if (
this[
'fN'] &&
this[
'fSumw2'].length > 0) {
791 var err2 =
this[
'fSumw2'][bin];
792 return Math.sqrt(err2);
794 var error2 = Math.abs(
this[
'fArray'][bin]);
795 return Math.sqrt(error2);
797 obj[
'getBinErrorLow'] =
function(bin) {
801 if (
this[
'fBinStatErrOpt'] == EBinErrorOpt.kNormal ||
this[
'fN'])
return this.getBinError(bin);
802 if (bin < 0) bin = 0;
803 if (bin >=
this[
'fNcells']) bin =
this[
'fNcells'] - 1;
804 var alpha = 1.0 - 0.682689492;
805 if (
this[
'fBinStatErrOpt'] == EBinErrorOpt.kPoisson2) alpha = 0.05;
806 var c =
this[
'fArray'][bin];
807 var n = Math.round(c);
809 alert(
"GetBinErrorLow : Histogram has negative bin content-force usage to normal errors");
810 this[
'fBinStatErrOpt'] = EBinErrorOpt.kNormal;
811 return this.getBinError(bin);
813 if (n == 0)
return 0;
814 return c - JSROOT.Math.gamma_quantile( alpha/2, n, 1.);
816 obj[
'getBinErrorUp'] =
function(bin) {
820 if (
this[
'fBinStatErrOpt'] == EBinErrorOpt.kNormal ||
this[
'fN'])
return this.getBinError(bin);
821 if (bin < 0) bin = 0;
822 if (bin >=
this[
'fNcells']) bin =
this[
'fNcells'] - 1;
823 var alpha = 1.0 - 0.682689492;
824 if (
this[
'fBinStatErrOpt'] == EBinErrorOpt.kPoisson2) alpha = 0.05;
825 var c =
this[
'fArray'][bin];
826 var n = Math.round(c);
828 alert(
"GetBinErrorLow : Histogram has negative bin content-force usage to normal errors");
829 this[
'fBinStatErrOpt'] = EBinErrorOpt.kNormal;
830 return this.getBinError(bin);
835 return JSROOT.Math.gamma_quantile_c( alpha/2, n+1, 1) - c;
837 obj[
'getBinLowEdge'] =
function(bin) {
839 if (
this[
'fXaxis'][
'fXbins'][
'fN'] && bin > 0 && bin <=
this[
'fXaxis'][
'fNbins'])
840 return this[
'fXaxis'][
'fXbins'][
'fArray'][bin-1];
841 var binwidth = (
this[
'fXaxis'][
'fXmax'] -
this[
'fXaxis'][
'fXmin']) /
this[
'fXaxis'][
'fNbins'];
842 return this[
'fXaxis'][
'fXmin'] + (bin-1) * binwidth;
844 obj[
'getBinUpEdge'] =
function(bin) {
847 if (!
this[
'fXaxis'][
'fXbins'][
'fN'] || bin < 1 || bin >
this[
'fXaxis'][
'fNbins']) {
848 binwidth = (
this[
'fXaxis'][
'fXmax'] -
this[
'fXaxis'][
'fXmin']) /
this[
'fXaxis'][
'fNbins'];
849 return this[
'fXaxis'][
'fXmin'] + bin * binwidth;
851 binwidth =
this[
'fArray'][bin] -
this[
'fArray'][bin-1];
852 return this[
'fArray'][bin-1] + binwidth;
855 obj[
'getBinWidth'] =
function(bin) {
857 if (
this[
'fXaxis'][
'fNbins'] <= 0)
return 0;
858 if (
this[
'fXaxis'][
'fXbins'][
'fN'] <= 0)
859 return (
this[
'fXaxis'][
'fXmax'] -
this[
'fXaxis'][
'fXmin']) /
this[
'fXaxis'][
'fNbins'];
860 if (bin >
this[
'fXaxis'][
'fNbins']) bin =
this[
'fXaxis'][
'fNbins'];
861 if (bin < 1) bin = 1;
862 return this[
'fArray'][bin] -
this[
'fArray'][bin-1];
864 obj[
'add'] =
function(h1, c1) {
869 if (!h1 || typeof(h1) ==
'undefined') {
870 alert(
"Add : Attempt to add a non-existing histogram");
873 if (!c1 || typeof(c1) ==
'undefined') c1 = 1;
874 var nbinsx =
this[
'fXaxis'][
'fNbins'],
875 nbinsy =
this[
'fYaxis'][
'fNbins'],
876 nbinsz =
this[
'fZaxis'][
'fNbins'];
878 if (
this[
'fDimension'] < 2) nbinsy = -1;
879 if (
this[
'fDimension'] < 3) nbinsz = -1;
882 if (
this[
'fSumw2'][
'fN'] == 0 && h1[
'fSumw2'][
'fN'] != 0) this.sumw2();
885 if (
this[
'fEntries'] == NaN)
this[
'fEntries'] = 0;
886 var entries = Math.abs(
this[
'fEntries'] + c1 * h1[
'fEntries'] );
890 var resetStats = (c1 < 0);
895 s1 = this.getStats();
898 this[
'fMinimum'] = -1111;
899 this[
'fMaximum'] = -1111;
902 var bin, binx, biny, binz;
904 if (Math.abs(h1[
'fNormFactor']) > 2e-308) factor = h1[
'fNormFactor'] / h1.getSumOfWeights();
905 for (binz=0;binz<=nbinsz+1;binz++) {
906 for (biny=0;biny<=nbinsy+1;biny++) {
907 for (binx=0;binx<=nbinsx+1;binx++) {
908 bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
910 if (this.TestBit(JSROOT.TH1StatusBits.kIsAverage)
911 && h1.TestBit(JSROOT.TH1StatusBits.kIsAverage)) {
912 var y1 = h1.getBinContent(bin),
913 y2 = this.getBinContent(bin),
914 e1 = h1.getBinError(bin),
915 e2 = this.getBinError(bin),
920 w1 = 1.0 / (e1 * e1);
921 else if (h1[
'fSumw2'][
'fN']) {
925 var sf = (s2[0] != 0) ? s2[1] / s2[0] : 1;
926 w1 = 1.0 / (sf * sf);
930 w2 = 1.0 / (e2 * e2);
931 else if (
this[
'fSumw2'][
'fN']) {
935 var sf = (s1[0] != 0) ? s1[1] / s1[0] : 1;
936 w2 = 1.0 / (sf * sf);
939 var y = (w1 * y1 + w2 * y2) / (w1 + w2);
940 this.setBinContent(bin, y);
941 if (
this[
'fSumw2'][
'fN']) {
942 var err2 = 1.0 / (w1 + w2);
943 if (err2 < 1.E-200) err2 = 0;
944 this[
'fSumw2'][
'fArray'][bin] = err2;
949 cu = c1 * factor * h1.getBinContent(bin);
950 this[
'fArray'][bin] += cu;
951 if (
this[
'fSumw2'][
'fN']) {
952 var e1 = factor * h1.getBinError(bin);
953 this[
'fSumw2'][
'fArray'][bin] += c1 * c1 * e1 * e1;
966 for (var i=0;i<kNstat;i++) {
967 if (i == 1) s1[i] += c1 * c1 * s2[i];
968 else s1[i] += c1 * s2[i];
971 this[
'fTsumw'] = s1[0];
972 this[
'fTsumw2'] = s1[1];
973 this[
'fTsumwx'] = s1[2];
974 this[
'fTsumwx2'] = s1[3];
975 this[
'fEntries'] = entries;
979 obj[
'getBin'] =
function(binx, biny, binz) {
982 if (
this[
'fDimension'] < 2) {
983 nx =
this[
'fXaxis'][
'fNbins']+2;
984 if (binx < 0) binx = 0;
985 if (binx >= nx) binx = nx-1;
988 if (
this[
'fDimension'] < 3) {
989 nx =
this[
'fXaxis'][
'fNbins']+2;
990 if (binx < 0) binx = 0;
991 if (binx >= nx) binx = nx-1;
992 ny =
this[
'fYaxis'][
'fNbins']+2;
993 if (biny < 0) biny = 0;
994 if (biny >= ny) biny = ny-1;
995 return binx + nx*biny;
997 if (
this[
'fDimension'] < 4) {
998 nx =
this[
'fXaxis'][
'fNbins']+2;
999 if (binx < 0) binx = 0;
1000 if (binx >= nx) binx = nx-1;
1001 ny =
this[
'fYaxis'][
'fNbins']+2;
1002 if (biny < 0) biny = 0;
1003 if (biny >= ny) biny = ny-1;
1004 nz =
this[
'fZaxis'][
'fNbins']+2;
1005 if (binz < 0) binz = 0;
1006 if (binz >= nz) binz = nz-1;
1007 return binx + nx*(biny +ny*binz);
1011 obj[
'getBinXYZ'] =
function(binglobal) {
1014 var binx, biny, binz;
1015 var nx =
this[
'fXaxis'][
'fNbins']+2;
1016 var ny =
this[
'fYaxis'][
'fNbins']+2;
1017 if (
this[
'fDimension'] < 2) {
1018 binx = binglobal%nx;
1022 if (
this[
'fDimension'] < 3) {
1023 binx = binglobal%nx;
1024 biny = ((binglobal-binx)/nx)%ny;
1027 if (
this[
'fDimension'] < 4) {
1028 binx = binglobal%nx;
1029 biny = ((binglobal-binx)/nx)%ny;
1030 binz = ((binglobal-binx)/nx -biny)/ny;
1032 return { binsx: binx, biny: biny, binz: binz };
1034 obj[
'getMaximum'] =
function(maxval) {
1044 if (
this[
'fMaximum'] != -1111)
return this[
'fMaximum'];
1045 if (!maxval || typeof(maxval) ==
'undefined') maxval = Number.MAX_VALUE;
1046 var bin, binx, biny, binz;
1047 var xfirst =
this[
'fXaxis'].getFirst();
1048 xlast =
this[
'fXaxis'].getLast(),
1049 yfirst =
this[
'fYaxis'].getFirst(),
1050 ylast =
this[
'fYaxis'].getLast(),
1051 zfirst =
this[
'fZaxis'].getFirst(),
1052 zlast =
this[
'fZaxis'].getLast();
1053 var maximum = -Number.MAX_VALUE, val;
1054 for (binz=zfirst;binz<=zlast;binz++) {
1055 for (biny=yfirst;biny<=ylast;biny++) {
1056 for (binx=xfirst;binx<=xlast;binx++) {
1057 bin = this.getBin(binx,biny,binz);
1058 val = this.getBinContent(bin);
1059 if (val > maximum && val < maxval) maximum = val;
1065 obj[
'getMinimum'] =
function(minval) {
1070 if (
this[
'fMinimum'] != -1111)
return this[
'fMinimum'];
1071 if (!minval || typeof(minval) ==
'undefined') minval = -Number.MAX_VALUE;
1072 var bin, binx, biny, binz;
1073 var xfirst =
this[
'fXaxis'].getFirst();
1074 xlast =
this[
'fXaxis'].getLast(),
1075 yfirst =
this[
'fYaxis'].getFirst(),
1076 ylast =
this[
'fYaxis'].getLast(),
1077 zfirst =
this[
'fZaxis'].getFirst(),
1078 zlast =
this[
'fZaxis'].getLast();
1079 var minimum = Number.MAX_VALUE, val;
1080 for (binz=zfirst;binz<=zlast;binz++) {
1081 for (biny=yfirst;biny<=ylast;biny++) {
1082 for (binx=xfirst;binx<=xlast;binx++) {
1083 bin = this.getBin(binx,biny,binz);
1084 val = this.getBinContent(bin);
1085 if (val < minimum && val > minval) minimum = val;
1091 obj[
'getSumOfWeights'] =
function() {
1093 var bin, binx, biny, binz, sum = 0;
1094 for (binz=1; binz<=
this[
'fZaxis'][
'fXbins'][
'fN']; binz++) {
1095 for (biny=1; biny<=
this[
'fYaxis'][
'fXbins'][
'fN']; biny++) {
1096 for (binx=1; binx<=
this[
'fXaxis'][
'fXbins'][
'fN']; binx++) {
1097 bin = this.getBin(binx,biny,binz);
1098 sum += this.getBinContent(bin);
1104 obj[
'labelsInflate'] =
function(ax) {
1109 var achoice = ax[0].toUpperCase();
1110 if (achoice ==
'X') axis =
this[
'fXaxis'];
1111 if (achoice ==
'Y') axis =
this[
'fYaxis'];
1112 if (achoice ==
'Z') axis =
this[
'fZaxis'];
1113 if (axis == null)
return;
1115 var hold = JSROOT.clone(
this);
1117 var timedisp = axis[
'fTimeDisplay'];
1118 var nbxold =
this[
'fXaxis'][
'fNbins'];
1119 var nbyold =
this[
'fYaxis'][
'fNbins'];
1120 var nbzold =
this[
'fZaxis'][
'fNbins'];
1121 var nbins = axis[
'fNbins'];
1122 var xmin = axis[
'fXmin'];
1123 var xmax = axis[
'fXmax'];
1124 xmax = xmin + 2 * (xmax - xmin);
1126 axis[
'fLast'] = axis[
'fNbins'];
1127 this[
'fBits'] &= ~(JSROOT.EAxisBits.kAxisRange & 0x00ffffff);
1129 axis[
'fNbins'] = 2*nbins;
1130 axis[
'fXmin'] = xmin;
1131 axis[
'fXmax'] = xmax;
1132 this[
'fNcells'] = -1;
1133 this[
'fArray'].length = -1;
1134 var errors =
this[
'fSumw2'][
'fN'];
1135 if (errors) [
'fSumw2'].length =
this[
'fNcells'];
1136 axis[
'fTimeDisplay'] = timedisp;
1139 this[
'fSumw2'].splice(0,
this[
'fSumw2'].length);
1140 this[
'fMinimum'] = -1111;
1141 this[
'fMaximum'] = -1111;
1144 var oldEntries =
this[
'fEntries'];
1145 var bin, ibin, bins;
1146 for (ibin = 0; ibin <
this[
'fNcells']; ibin++) {
1147 bins = this.getBinXYZ(ibin);
1148 bin = hold.getBin(bins[
'binx'],bins[
'biny'],bins[
'binz']);
1150 if (bins[
'binx'] > nbxold || bins[
'biny'] > nbyold || bins[
'binz'] > nbzold) bin = -1;
1152 var cu = hold.getBinContent(bin);
1153 this[
'fArray'][bin] += cu;
1154 if (errors)
this[
'fSumw2'][
'fArray'][ibin] += hold[
'fSumw2'][
'fArray'][bin];
1157 this[
'fEntries'] = oldEntries;
1160 obj[
'resetStats'] =
function() {
1166 this[
'fEntries'] = 1;
1167 var stats = this.getStats();
1168 this[
'fTsumw'] = stats[0];
1169 this[
'fTsumw2'] = stats[1];
1170 this[
'fTsumwx'] = stats[2];
1171 this[
'fTsumwx2'] = stats[3];
1172 this[
'fEntries'] = Math.abs(
this[
'fTsumw']);
1174 if (
this[
'fSumw2'][
'fN'] > 0 &&
this[
'fTsumw'] > 0 && stats[1] > 0 )
1175 this[
'fEntries'] = stats[0] * stats[0] / stats[1];
1177 obj[
'setBinContent'] =
function(bin, content) {
1186 if (bin < 0)
return;
1187 if (bin >=
this[
'fNcells']-1) {
1188 if (
this[
'fXaxis'][
'fTimeDisplay'] || this.TestBit(JSROOT.TH1StatusBits.kCanRebin) ) {
1189 while (bin >=
this[
'fNcells']-1) this.labelsInflate();
1191 if (bin ==
this[
'fNcells']-1)
this[
'fArray'][bin] = content;
1195 this[
'fArray'][bin] = content;
1197 obj[
'sumw2'] =
function() {
1209 if (
this[
'fSumw2'][
'fN'] ==
this[
'fNcells']) {
1212 this[
'fSumw2'].length =
this[
'fNcells'];
1213 if (
this[
'fEntries'] > 0 ) {
1214 for (var bin=0; bin<
this[
'fNcells']; bin++) {
1215 this[
'fSumw2'][
'fArray'][bin] = Math.abs(this.getBinContent(bin));
1220 if (obj_typename.indexOf(
"TH1") == 0) {
1221 obj[
'fDimension'] = 1;
1222 obj[
'getBinContent'] =
function(bin) {
1223 if (bin < 0) bin = 0;
1224 if (bin >=
this[
'fNcells']) bin =
this[
'fNcells']-1;
1225 return this[
'fArray'][bin];
1227 obj[
'getStats'] =
function() {
1235 var bin, binx, w, err, x, stats =
new Array(0,0,0,0,0);
1238 if (
this[
'fXaxis'][
'fLabels'] && this.TestBit(JSROOT.TH1StatusBits.kCanRebin) ) {
1239 stats[0] =
this[
'fTsumw'];
1240 stats[1] =
this[
'fTsumw2'];
1244 else if ((
this[
'fTsumw'] == 0 &&
this[
'fEntries'] > 0) ||
1245 this[
'fXaxis'].TestBit(JSROOT.EAxisBits.kAxisRange)) {
1246 for (bin=0;bin<4;bin++) stats[bin] = 0;
1248 var firstBinX =
this[
'fXaxis'].getFirst();
1249 var lastBinX =
this[
'fXaxis'].getLast();
1250 for (binx = firstBinX; binx <= lastBinX; binx++) {
1251 x =
this[
'fXaxis'].getBinCenter(binx);
1252 w = this.getBinContent(binx);
1253 err = Math.abs(this.getBinError(binx));
1255 stats[1] += err*err;
1260 stats[0] =
this[
'fTsumw'];
1261 stats[1] =
this[
'fTsumw2'];
1262 stats[2] =
this[
'fTsumwx'];
1263 stats[3] =
this[
'fTsumwx2'];
1268 if (obj_typename.indexOf(
"TH2") == 0) {
1269 obj[
'fDimension'] = 2;
1270 obj[
'getBin'] =
function(x, y) {
1271 var nx =
this[
'fXaxis'][
'fNbins']+2;
1272 return (x + nx * y);
1274 obj[
'getBinContent'] =
function(x, y) {
1275 return this[
'fArray'][this.getBin(x, y)];
1277 obj[
'getStats'] =
function() {
1278 var bin, binx, biny, stats =
new Array(0,0,0,0,0,0,0,0,0,0,0,0,0);
1279 if ((
this[
'fTsumw'] == 0 &&
this[
'fEntries'] > 0) ||
this[
'fXaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) ||
this[
'fYaxis'].TestBit(JSROOT.EAxisBits.kAxisRange)) {
1280 var firstBinX =
this[
'fXaxis'].getFirst();
1281 var lastBinX =
this[
'fXaxis'].getLast();
1282 var firstBinY =
this[
'fYaxis'].getFirst();
1283 var lastBinY =
this[
'fYaxis'].getLast();
1285 if (
this[
'fgStatOverflows']) {
1286 if ( !
this[
'fXaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) ) {
1287 if (firstBinX == 1) firstBinX = 0;
1288 if (lastBinX ==
this[
'fXaxis'][
'fNbins'] ) lastBinX += 1;
1290 if ( !
this[
'fYaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) ) {
1291 if (firstBinY == 1) firstBinY = 0;
1292 if (lastBinY ==
this[
'fYaxis'][
'fNbins'] ) lastBinY += 1;
1295 for (biny = firstBinY; biny <= lastBinY; biny++) {
1296 y =
this[
'fYaxis'].getBinCenter(biny);
1297 for (binx = firstBinX; binx <= lastBinX; binx++) {
1298 bin = this.getBin(binx,biny);
1299 x =
this[
'fXaxis'].getBinCenter(binx);
1300 w = this.GetBinContent(bin);
1301 err = Math.abs(this.getBinError(bin));
1303 stats[1] += err*err;
1312 stats[0] =
this[
'fTsumw'];
1313 stats[1] =
this[
'fTsumw2'];
1314 stats[2] =
this[
'fTsumwx'];
1315 stats[3] =
this[
'fTsumwx2'];
1316 stats[4] =
this[
'fTsumwy'];
1317 stats[5] =
this[
'fTsumwy2'];
1318 stats[6] =
this[
'fTsumwxy'];
1323 if (obj_typename.indexOf(
"TH3") == 0) {
1324 obj[
'fDimension'] = 3;
1325 obj[
'getBin'] =
function(x, y, z) {
1326 var nx =
this[
'fXaxis'][
'fNbins']+2;
1328 if (x >= nx) x = nx-1;
1329 var ny =
this[
'fYaxis'][
'fNbins']+2;
1331 if (y >= ny) y = ny-1;
1332 return (x + nx * (y + ny * z));
1334 obj[
'getBinContent'] =
function(x, y, z) {
1335 return this[
'fArray'][this.getBin(x, y, z)];
1337 obj[
'getStats'] =
function() {
1338 var bin, binx, biny, binz, stats =
new Array(0,0,0,0,0,0,0,0,0,0,0,0,0);
1339 if ((obj[
'fTsumw'] == 0 && obj[
'fEntries'] > 0) || obj[
'fXaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) || obj[
'fYaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) || obj[
'fZaxis'].TestBit(JSROOT.EAxisBits.kAxisRange)) {
1340 var firstBinX = obj[
'fXaxis'].getFirst();
1341 var lastBinX = obj[
'fXaxis'].getLast();
1342 var firstBinY = obj[
'fYaxis'].getFirst();
1343 var lastBinY = obj[
'fYaxis'].getLast();
1344 var firstBinZ = obj[
'fZaxis'].getFirst();
1345 var lastBinZ = obj[
'fZaxis'].getLast();
1347 if (obj[
'fgStatOverflows']) {
1348 if ( !obj[
'fXaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) ) {
1349 if (firstBinX == 1) firstBinX = 0;
1350 if (lastBinX == obj[
'fXaxis'][
'fNbins'] ) lastBinX += 1;
1352 if ( !obj[
'fYaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) ) {
1353 if (firstBinY == 1) firstBinY = 0;
1354 if (lastBinY == obj[
'fYaxis'][
'fNbins'] ) lastBinY += 1;
1356 if ( !obj[
'fZaxis'].TestBit(JSROOT.EAxisBits.kAxisRange) ) {
1357 if (firstBinZ == 1) firstBinZ = 0;
1358 if (lastBinZ == obj[
'fZaxis'][
'fNbins'] ) lastBinZ += 1;
1361 for (binz = firstBinZ; binz <= lastBinZ; binz++) {
1362 z = obj[
'fZaxis'].getBinCenter(binz);
1363 for (biny = firstBinY; biny <= lastBinY; biny++) {
1364 y = obj[
'fYaxis'].getBinCenter(biny);
1365 for (binx = firstBinX; binx <= lastBinX; binx++) {
1366 bin = obj.getBin(binx,biny,binz);
1367 x = obj[
'fXaxis'].getBinCenter(binx);
1368 w = obj.GetBinContent(bin);
1369 err = Math.abs(obj.getBinError(bin));
1371 stats[1] += err*err;
1385 stats[0] = obj[
'fTsumw'];
1386 stats[1] = obj[
'fTsumw2'];
1387 stats[2] = obj[
'fTsumwx'];
1388 stats[3] = obj[
'fTsumwx2'];
1389 stats[4] = obj[
'fTsumwy'];
1390 stats[5] = obj[
'fTsumwy2'];
1391 stats[6] = obj[
'fTsumwxy'];
1392 stats[7] = obj[
'fTsumwz'];
1393 stats[8] = obj[
'fTsumwz2'];
1394 stats[9] = obj[
'fTsumwxz'];
1395 stats[10] =obj[
'fTsumwyz'];
1400 if (obj_typename.indexOf(
"THStack") == 0) {
1401 obj[
'buildStack'] =
function() {
1404 if (
'fStack' in
this)
return;
1405 if (!
'fHists' in
this)
return;
1406 var nhists =
this[
'fHists'].arr.length;
1407 if (nhists <= 0)
return;
1408 this[
'fStack'] = JSROOT.Create(
"TList");
1409 var h = JSROOT.clone(
this[
'fHists'].arr[0]);
1410 this[
'fStack'].arr.push(h);
1411 for (var i=1;i<nhists;i++) {
1412 h = JSROOT.clone(
this[
'fHists'].arr[i]);
1413 h.add(
this[
'fStack'].arr[i-1]);
1414 this[
'fStack'].arr.splice(i, 1, h);
1417 obj[
'getMaximum'] =
function(option) {
1420 var opt = option.toLowerCase();
1422 if (opt.indexOf(
"e") != -1) lerr =
true;
1423 var them = 0, themax = -1e300, c1, e1;
1424 if (!
'fHists' in
this)
return 0;
1425 var nhists =
this[
'fHists'].arr.length;
1427 if (opt.indexOf(
"nostack") == -1) {
1429 var h =
this[
'fStack'].arr[nhists-1];
1430 themax = h.getMaximum();
1432 for (var i=0;i<nhists;i++) {
1433 h =
this[
'fHists'].arr[i];
1434 them = h.getMaximum();
1435 if (them > themax) themax = them;
1439 for (var i=0;i<nhists;i++) {
1440 h =
this[
'fHists'].arr[i];
1441 first = h[
'fXaxis'].getFirst();
1442 last = h[
'fXaxis'].getLast();
1443 for (var j=first; j<=last;j++) {
1444 e1 = h.getBinError(j);
1445 c1 = h.getBinContent(j);
1446 themax = Math.max(themax, c1+e1);
1452 obj[
'getMinimum'] =
function(option, pad) {
1455 var opt = option.toLowerCase();
1457 if (opt.indexOf(
"e") == -1) lerr =
true;
1458 var them = 0, themin = 1e300, c1, e1;
1459 if (!
'fHists' in
this)
return 0;
1460 var nhists =
this[
'fHists'].arr.length;
1462 if (opt.indexOf(
"nostack") == -1) {
1464 var h =
this[
'fStack'].arr[nhists-1];
1465 themin = h.getMinimum();
1467 for (var i=0;i<nhists;i++) {
1468 h =
this[
'fHists'].arr[i];
1469 them = h.getMinimum();
1470 if (them <= 0 && pad && pad[
'fLogy']) them = h.getMinimum(0);
1471 if (them < themin) themin = them;
1475 for (var i=0;i<nhists;i++) {
1476 h =
this[
'fHists'].arr[i];
1477 first = h[
'fXaxis'].getFirst();
1478 last = h[
'fXaxis'].getLast();
1479 for (var j=first;j<=last;j++) {
1480 e1 = h.getBinError(j);
1481 c1 = h.getBinContent(j);
1482 themin = Math.min(themin, c1 - e1);
1489 if ((obj_typename.indexOf(
"TH1") == 0) ||
1490 (obj_typename.indexOf(
"TH2") == 0) ||
1491 (obj_typename.indexOf(
"TH3") == 0) ||
1492 (obj_typename.indexOf(
"TProfile") == 0)) {
1493 obj[
'getMean'] =
function(axis) {
1494 if (axis < 1 || (axis > 3 && axis < 11) || axis > 13)
return 0;
1495 var stats = this.getStats();
1496 if (stats[0] == 0)
return 0;
1497 var ax =
new Array(2,4,7);
1498 return stats[ax[axis-1]]/stats[0];
1500 obj[
'getRMS'] =
function(axis) {
1501 if (axis < 1 || (axis > 3 && axis < 11) || axis > 13)
return 0;
1502 var stats = this.getStats();
1503 if (stats[0] == 0)
return 0;
1504 var ax =
new Array(2,4,7);
1505 var axm = ax[axis%10 - 1];
1506 var x = stats[axm]/stats[0];
1507 var rms2 = Math.abs(stats[axm+1]/stats[0] -x*x);
1508 return Math.sqrt(rms2);
1511 if (obj_typename.indexOf(
"TProfile") == 0) {
1512 obj[
'getBinContent'] =
function(bin) {
1513 if (bin < 0 || bin >=
this[
'fNcells'])
return 0;
1514 if (
this[
'fBinEntries'][bin] < 1e-300)
return 0;
1515 if (!
this[
'fArray'])
return 0;
1516 return this[
'fArray'][bin]/
this[
'fBinEntries'][bin];
1518 obj[
'getBinEffectiveEntries'] =
function(bin) {
1519 if (bin < 0 || bin >=
this[
'fNcells'])
return 0;
1520 var sumOfWeights =
this[
'fBinEntries'][bin];
1521 if (
this[
'fBinSumw2'].length == 0 ||
this[
'fBinSumw2'].length !=
this[
'fNcells']) {
1523 return sumOfWeights;
1525 var sumOfWeightsSquare =
this[
'fSumw2'][bin];
1526 return ( sumOfWeightsSquare > 0 ? sumOfWeights * sumOfWeights / sumOfWeightsSquare : 0 );
1528 obj[
'getStats'] =
function() {
1529 var bin, binx, stats =
new Array(0,0,0,0,0,0,0,0,0,0,0,0,0);
1530 if (
this[
'fTsumw'] < 1e-300 ||
this[
'fXaxis'].TestBit(JSROOT.EAxisBits.kAxisRange)) {
1531 var firstBinX =
this[
'fXaxis'].getFirst();
1532 var lastBinX =
this[
'fXaxis'].getLast();
1533 for (binx =
this[
'firstBinX']; binx <= lastBinX; binx++) {
1534 var w = onj[
'fBinEntries'][binx];
1535 var w2 = (
this[
'fN'] ?
this[
'fBinSumw2'][binx] : w);
1536 var x = fXaxis.GetBinCenter(binx);
1541 stats[4] +=
this[
'fArray'][binx];
1542 stats[5] +=
this[
'fSumw2'][binx];
1545 if (
this[
'fTsumwy'] < 1e-300 &&
this[
'fTsumwy2'] < 1e-300) {
1547 for (binx=
this[
'fXaxis'].getFirst();binx<=
this[
'fXaxis'].getLast();binx++) {
1548 this[
'fTsumwy'] +=
this[
'fArray'][binx];
1549 this[
'fTsumwy2'] +=
this[
'fSumw2'][binx];
1552 stats[0] =
this[
'fTsumw'];
1553 stats[1] =
this[
'fTsumw2'];
1554 stats[2] =
this[
'fTsumwx'];
1555 stats[3] =
this[
'fTsumwx2'];
1556 stats[4] =
this[
'fTsumwy'];
1557 stats[5] =
this[
'fTsumwy2'];
1561 obj[
'getBinError'] =
function(bin) {
1562 if (bin < 0 || bin >=
this[
'fNcells'])
return 0;
1563 var cont =
this[
'fArray'][bin];
1564 var sum =
this[
'fBinEntries'][bin];
1565 var err2 =
this[
'fSumw2'][bin];
1566 var neff = this.getBinEffectiveEntries(bin);
1567 if (sum < 1e-300)
return 0;
1569 if (
this[
'fErrorMode'] == EErrorType.kERRORSPREADG) {
1570 return (1.0/Math.sqrt(sum));
1573 var contsum = cont/sum;
1574 var eprim2 = Math.abs(err2/sum - contsum*contsum);
1575 var eprim = Math.sqrt(eprim2);
1576 if (
this[
'fErrorMode'] == EErrorType.kERRORSPREADI) {
1577 if (eprim != 0)
return eprim/Math.sqrt(neff);
1580 return (1.0/Math.sqrt(12*neff));
1585 if (err2 != 0 && neff < 5) testing = eprim2*sum/err2;
1586 if (
this[
'fgApproximate'] && (testing < 1.e-4 || eprim2 < 1e-6)) {
1587 var stats = this.getStats();
1588 var ssum = stats[0];
1591 var scont = stats[idx];
1592 var serr2 = stats[idx+1];
1594 var scontsum = scont/ssum;
1595 var seprim2 = Math.abs(serr2/ssum - scontsum*scontsum);
1596 eprim = 2*Math.sqrt(seprim2);
1599 sum = Math.abs(sum);
1601 if (
this[
'fErrorMode'] == EErrorType.kERRORSPREAD)
return eprim;
1604 return (eprim/Math.sqrt(neff));
1615 JSROOT.Math.lgam =
function( x ) {
1621 if (x >= Number.POSITIVE_INFINITY)
1622 return(Number.POSITIVE_INFINITY);
1629 return (Number.POSITIVE_INFINITY);
1640 z = q * Math.sin( Math.PI * z );
1642 return (Number.POSITIVE_INFINITY);
1643 z = Math.log(Math.PI) - Math.log( z ) - w;
1650 while ( u >= 3.0 ) {
1657 return (Number.POSITIVE_INFINITY);
1669 return( Math.log(z) );
1672 p = x * this.Polynomialeval(x, B, 5 ) / this.Polynomial1eval( x, C, 6);
1673 return( Math.log(z) + p );
1676 return( sgngam * Number.POSITIVE_INFINITY );
1678 q = ( x - 0.5 ) * Math.log(x) - x + LS2PI;
1684 q += ((7.9365079365079365079365e-4 * p
1685 - 2.7777777777777777777778e-3) *p
1686 + 0.0833333333333333333333) / x;
1688 q += this.Polynomialeval( p, A, 4 ) / x;
1696 JSROOT.Math.Polynomialeval =
function(x, a, N) {
1697 if (N==0)
return a[0];
1700 for (var i=1; i <= N; i++)
1701 pom = pom *x + a[i];
1710 JSROOT.Math.Polynomial1eval =
function(x, a, N) {
1711 if (N==0)
return a[0];
1714 for (var i=1; i < N; i++)
1715 pom = pom *x + a[i];
1720 JSROOT.Math.ndtri =
function( y0 ) {
1722 return( Number.NEGATIVE_INFINITY );
1724 return( Number.POSITIVE_INFINITY );
1727 -5.99633501014107895267E1,
1728 9.80010754185999661536E1,
1729 -5.66762857469070293439E1,
1730 1.39312609387279679503E1,
1731 -1.23916583867381258016E0
1735 1.95448858338141759834E0,
1736 4.67627912898881538453E0,
1737 8.63602421390890590575E1,
1738 -2.25462687854119370527E2,
1739 2.00260212380060660359E2,
1740 -8.20372256168333339912E1,
1741 1.59056225126211695515E1,
1742 -1.18331621121330003142E0
1746 4.05544892305962419923E0,
1747 3.15251094599893866154E1,
1748 5.71628192246421288162E1,
1749 4.40805073893200834700E1,
1750 1.46849561928858024014E1,
1751 2.18663306850790267539E0,
1752 -1.40256079171354495875E-1,
1753 -3.50424626827848203418E-2,
1754 -8.57456785154685413611E-4
1758 1.57799883256466749731E1,
1759 4.53907635128879210584E1,
1760 4.13172038254672030440E1,
1761 1.50425385692907503408E1,
1762 2.50464946208309415979E0,
1763 -1.42182922854787788574E-1,
1764 -3.80806407691578277194E-2,
1765 -9.33259480895457427372E-4
1769 3.23774891776946035970E0,
1770 6.91522889068984211695E0,
1771 3.93881025292474443415E0,
1772 1.33303460815807542389E0,
1773 2.01485389549179081538E-1,
1774 1.23716634817820021358E-2,
1775 3.01581553508235416007E-4,
1776 2.65806974686737550832E-6,
1777 6.23974539184983293730E-9
1781 6.02427039364742014255E0,
1782 3.67983563856160859403E0,
1783 1.37702099489081330271E0,
1784 2.16236993594496635890E-1,
1785 1.34204006088543189037E-2,
1786 3.28014464682127739104E-4,
1787 2.89247864745380683936E-6,
1788 6.79019408009981274425E-9
1791 var s2pi = 2.50662827463100050242e0;
1794 var x, z, y2, x0, x1;
1796 if ( y > (1.0 - 0.13533528323661269189) ) {
1800 if ( y > 0.13533528323661269189 ) {
1803 x = y + y * (y2 * this.Polynomialeval( y2, P0, 4)/ this.Polynomial1eval( y2, Q0, 8 ));
1807 x = Math.sqrt( -2.0 * Math.log(y) );
1808 x0 = x - Math.log(x)/x;
1811 x1 = z * this.Polynomialeval( z, P1, 8 )/ this.Polynomial1eval( z, Q1, 8 );
1813 x1 = z * this.Polynomialeval( z, P2, 8 )/ this.Polynomial1eval( z, Q2, 8 );
1820 JSROOT.Math.igami =
function(a, y0) {
1821 var x0, x1, x, yl, yh, y, d, lgm, dithresh;
1823 var kMACHEP = 1.11022302462515654042363166809e-16;
1827 alert(
"igami : Wrong domain for parameter a (must be > 0)");
1831 return Number.POSITIVE_INFINITY;
1837 var kMAXNUM = Number.MAX_VALUE;
1842 dithresh = 5.0 * kMACHEP;
1846 y = ( 1.0 - d - this.ndtri(y0) * Math.sqrt(d) );
1851 for( i=0; i<10; i++ ) {
1852 if ( x > x0 || x < x1 )
1855 if ( y < yl || y > yh )
1866 d = (a - 1.0) * Math.log(x) - x - lgm;
1872 if ( Math.abs(d/x) < kMACHEP )
1878 if ( x0 == kMAXNUM ) {
1881 while ( x0 == kMAXNUM ) {
1895 for( i=0; i<400; i++ ) {
1896 x = x1 + d * (x0 - x1);
1898 lgm = (x0 - x1)/(x1 + x0);
1899 if ( Math.abs(lgm) < dithresh )
1902 if ( Math.abs(lgm) < dithresh )
1916 d = (y0 - yl)/(yh - yl);
1926 else if ( dir < -1 )
1929 d = (y0 - yl)/(yh - yl);
1936 JSROOT.Math.gamma_quantile_c =
function(z, alpha, theta) {
1937 return theta * this.igami( alpha, z);
1940 JSROOT.Math.gamma_quantile =
function(z, alpha, theta) {
1941 return theta * this.igami( alpha, 1.- z);
1944 JSROOT.Math.log10 =
function(n) {
1945 return Math.log(n) / Math.log(10);
1948 JSROOT.Math.landau_pdf =
function(x, xi, x0) {
1951 if (xi <= 0)
return 0;
1952 var v = (x - x0)/xi;
1953 var u, ue, us, denlan;
1954 var p1 =
new Array(0.4259894875,-0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253);
1955 var q1 =
new Array(1.0 ,-0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063);
1956 var p2 =
new Array(0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211);
1957 var q2 =
new Array(1.0 , 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714);
1958 var p3 =
new Array(0.1788544503, 0.09359161662,0.006325387654, 0.00006611667319,-0.000002031049101);
1959 var q3 =
new Array(1.0 , 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675);
1960 var p4 =
new Array(0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186);
1961 var q4 =
new Array(1.0 , 106.8615961, 337.6496214, 2016.712389, 1597.063511);
1962 var p5 =
new Array(1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910);
1963 var q5 =
new Array(1.0 , 156.9424537, 3745.310488, 9834.698876, 66924.28357);
1964 var p6 =
new Array(1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109);
1965 var q6 =
new Array(1.0 , 651.4101098, 56974.73333, 165917.4725, -2815759.939);
1966 var a1 =
new Array(0.04166666667,-0.01996527778, 0.02709538966);
1967 var a2 =
new Array(-1.845568670,-4.284640743);
1970 u = Math.exp(v+1.0);
1971 if (u < 1e-10)
return 0.0;
1972 ue = Math.exp(-1/u);
1974 denlan = 0.3989422803*(ue/us)*(1+(a1[0]+(a1[1]+a1[2]*u)*u)*u);
1977 denlan = Math.exp(-u)*Math.sqrt(u)*
1978 (p1[0]+(p1[1]+(p1[2]+(p1[3]+p1[4]*v)*v)*v)*v)/
1979 (q1[0]+(q1[1]+(q1[2]+(q1[3]+q1[4]*v)*v)*v)*v);
1981 denlan = (p2[0]+(p2[1]+(p2[2]+(p2[3]+p2[4]*v)*v)*v)*v)/
1982 (q2[0]+(q2[1]+(q2[2]+(q2[3]+q2[4]*v)*v)*v)*v);
1984 denlan = (p3[0]+(p3[1]+(p3[2]+(p3[3]+p3[4]*v)*v)*v)*v)/
1985 (q3[0]+(q3[1]+(q3[2]+(q3[3]+q3[4]*v)*v)*v)*v);
1988 denlan = u*u*(p4[0]+(p4[1]+(p4[2]+(p4[3]+p4[4]*u)*u)*u)*u)/
1989 (q4[0]+(q4[1]+(q4[2]+(q4[3]+q4[4]*u)*u)*u)*u);
1992 denlan = u*u*(p5[0]+(p5[1]+(p5[2]+(p5[3]+p5[4]*u)*u)*u)*u)/
1993 (q5[0]+(q5[1]+(q5[2]+(q5[3]+q5[4]*u)*u)*u)*u);
1994 }
else if(v < 300) {
1996 denlan = u*u*(p6[0]+(p6[1]+(p6[2]+(p6[3]+p6[4]*u)*u)*u)*u)/
1997 (q6[0]+(q6[1]+(q6[2]+(q6[3]+q6[4]*u)*u)*u)*u);
1999 u = 1/(v-v*Math.log(v)/(v+1));
2000 denlan = u*u*(1+(a2[0]+a2[1]*u)*u);
2005 JSROOT.Math.Landau =
function(x, mpv, sigma, norm) {
2006 if (sigma <= 0)
return 0;
2007 var den = JSROOT.Math.landau_pdf((x - mpv) / sigma, 1, 0);
2008 if (!norm)
return den;
2012 JSROOT.Math.gaus =
function(f, x, i) {
2013 return f[
'fParams'][i+0] * Math.exp(-0.5 * Math.pow((x-f[
'fParams'][i+1]) / f[
'fParams'][i+2], 2));
2016 JSROOT.Math.gausn =
function(f, x, i) {
2017 return JSROOT.Math.gaus(f, x, i)/(Math.sqrt(2 * Math.PI) * f[
'fParams'][i+2]);
2020 JSROOT.Math.expo =
function(f, x, i) {
2021 return Math.exp(f[
'fParams'][i+0] + f[
'fParams'][i+1] * x);
2024 JSROOT.Math.landau =
function(f, x, i) {
2025 return JSROOT.Math.Landau(x, f[
'fParams'][i+1],f[
'fParams'][i+2],
false);
2028 JSROOT.Math.landaun =
function(f, x, i) {
2029 return JSROOT.Math.Landau(x, f[
'fParams'][i+1],f[
'fParams'][i+2],
true);