source: trunk/FACT++/www/viewer/index.js@ 17810

Last change on this file since 17810 was 17810, checked in by tbretz, 10 years ago
Recalculate the image parameters with each redraw to allow to use the lower limit (min) value.
File size: 41.7 KB
Line 
1'use strict';
2
3// ==========================================================================
4
5function onRightMouseClick(event)
6{
7 if (event.button!=2)
8 return;
9
10 var strData = event.target.toDataURL("image/png");
11
12 var img = document.createElement("img");
13 img.src = strData;
14
15 $(img).css({ "z-index": "9999", "position": "absolute" });
16 $(img).insertBefore($(event.target));
17
18 setTimeout(function () { $(img).remove(); }, 100);
19}
20
21(function ($)
22 {
23
24 $.plot.plugins.push({
25 init: function(plot, classes)
26 {
27 plot.hooks.bindEvents.push(function(plot, eventHolder) { eventHolder.mousedown(onRightMouseClick); });
28 plot.hooks.shutdown.push(function(plot, eventHolder) { eventHolder.unbind("mousedown", onRightMouseClick); });
29 },
30 name: 'saveAsImage',
31 version: '1.0'
32 });
33
34 })(jQuery);
35
36// ==========================================================================
37
38var editor1;
39var editor2;
40var plot;
41
42function debug(txt)
43{
44 var dbg = document.getElementById("debug");
45 dbg.appendChild(document.createTextNode(txt));
46 dbg.appendChild(document.createElement("br"));
47}
48
49function setupAccordion(accordion, container, inactive)
50{
51 function onAccordion(event, ui)
52 {
53 if (ui.oldHeader.length==0)
54 $(container).slideDown(400);
55 else
56 $(container).slideUp(400);
57 }
58
59 var config = { collapsible: true };
60
61 if (inactive)
62 {
63 config.active = false;
64 $(container).hide();
65 }
66
67 var acc = $(accordion);
68
69 acc.accordion(config);
70 acc.on("accordionbeforeactivate", onAccordion);
71}
72
73function onResize(event, ui)
74{
75 if (!ui.size)
76 return;
77
78 $(event.target.id).css({marginRight:'2px'});
79
80 var editor = event.target.id=="textcontainer1" ? editor1 : editor2;
81
82 editor.setSize("100%", ui.size.height);
83 editor.refresh();
84}
85
86function setSize(id, w, h)
87{
88 w = parseInt(w);
89 h = parseInt(h);
90
91 $("#"+id).width(w);
92 $("#"+id).height(h);
93
94 document.getElementById(id).width=w;
95 document.getElementById(id).height=h;
96}
97
98function onResizeGrid(id)
99{
100 var w = document.getElementById(id+"container").clientWidth/4;
101
102 var offy = 0;
103 var offx = 5;
104
105 var cont = document.getElementById("center"+id).childNodes[0];
106
107 var nn;
108 if (cont)
109 {
110 nn = parseInt(cont.id[cont.id.length-1]);
111 setSize(id+nn, w*2, w*2);
112 }
113
114 if (nn!=1)
115 setSize(id+'1', w-offx, w-offy);
116 if (nn!=2)
117 setSize(id+'2', w-offx, w-offy);
118 if (nn!=3)
119 setSize(id+'3', w-offx, w-offy);
120 if (nn!=4)
121 setSize(id+'4', w-offx, w-offy);
122
123 document.getElementById("center"+id).width=parseInt(w*2);
124
125 setSize('cont'+id+'1', w, w);
126 setSize('cont'+id+'2', w, w);
127 setSize('cont'+id+'3', w, w);
128 setSize('cont'+id+'4', w, w);
129}
130
131function onResizeCameras(event, ui)
132{
133 onResizeGrid('camera');
134
135 drawFullCam("camera1");
136 drawFullCam("camera2");
137 drawFullCam("camera3");
138 drawFullCam("camera4");
139}
140
141function onResizeHistograms(event, ui)
142{
143 onResizeGrid('hist');
144}
145
146function createEditor(textarea)
147{
148 var editor;
149
150 var config =
151 {
152 //value: "function myScript(){return 100;}\n",
153 mode: { name: "text/typescript", globalVars: true },
154 indentUnit: 4,
155 styleActiveLine: true,
156 matchBrackets: true,
157 lineNumbers: true,
158 foldGutter: true,
159 lint: true,
160 highlightSelectionMatches: {showToken: /\w/},
161 gutters: ["CodeMirror-lint-markers", "CodeMirror-linenumbers", "CodeMirror-foldgutter"],
162 extraKeys: {
163 //"Ctrl-D": "duplicateLine",
164 //"Alt--": "goToBracket",
165 //"Ctrl-H": "findPrev",
166 "Ctrl-Down": "autocomplete",
167 "Tab": "indentAuto",
168 "Ctrl-Y": "deleteLine",
169 "Ctrl-.": function(cm) {
170 cm.foldCode(cm.getCursor());
171 },
172 "F11": function(cm) {
173 editor.setOption("fullScreen", !editor.getOption("fullScreen"));
174 },
175 "Ctrl-R": function(cm) {
176 editor.execCommand("replace");
177 },
178 "Esc": function(cm) {
179 if (editor.getOption("fullScreen")) editor.setOption("fullScreen", false);
180 },
181 "Enter": function(cm) {
182 editor.execCommand("indentAuto");
183 editor.execCommand("newlineAndIndent");
184 },
185 }
186 };
187
188 editor = CodeMirror.fromTextArea(document.getElementById(textarea), config);
189 editor.setOption("theme", "blackboard");
190
191 return editor;
192}
193
194function colorizeHTML(textarea)
195{
196 var config =
197 {
198 //value: "function myScript(){return 100;}\n",
199 mode: { name: "text/typescript", globalVars: true },
200 readOnly: true,
201 };
202
203 CodeMirror.fromTextArea(document.getElementById(textarea), config);
204}
205
206function disableControls(disabled)
207{
208 $('#submit').prop('disabled', disabled);
209 $('#getcamera').prop('disabled', disabled);
210 $('#getwaveforms').prop('disabled', disabled);
211 $('#event').prop('disabled', disabled);
212 $('#pixel').prop('disabled', disabled);
213 $('#cbpx').prop('disabled', disabled);
214 $('#cbpx-c').prop('disabled', disabled);
215 $('#cbpx-b').prop('disabled', disabled);
216 $('#cbpx-p').prop('disabled', disabled);
217 $('#cbpx-x').prop('disabled', disabled);
218 $('#file').prop('disabled', disabled);
219
220 if (disabled)
221 $('#calibrated').prop('disabled', true);
222 else
223 {
224 var list = document.getElementById("file").data;
225 if (list)
226 {
227 var file = document.getElementById("file").value;
228 $('#calibrated').prop('disabled', !list[file]);
229 }
230 }
231}
232
233function onGetCameras()
234{
235 var arr =
236 [
237 document.getElementById("camera1").dataAbs,
238 document.getElementById("camera2").dataAbs,
239 document.getElementById("camera3").dataAbs,
240 document.getElementById("camera4").dataAbs,
241 ];
242
243 $('#controls > input[name=data]').val(JSON.stringify(arr));
244 $('#controls').attr('action','index.php');
245 $('#controls').submit();
246}
247
248function onGetWaveforms()
249{
250 var arr = document.getElementById("waveform").data;
251
252 $('#controls > input[name=data]').val(JSON.stringify(arr));
253 $('#controls').attr('action','index.php');
254 $('#controls').submit();
255}
256
257function onReady()
258{
259 CodeMirror.colorize(null, 'javascript');
260
261 //$('input,select').keypress(function(event) { return event.keyCode != 13; });
262
263 //colorizeHTML("code0");
264 //colorizeHTML("code1");
265
266 $("#accordion").accordion({collapsible:true,active:false,heightStyle:'content'});
267 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
268 if (location.href.search('debug')==-1)
269 $("#accordion").find('h3').filter(':contains(Debug)').hide();
270
271 $("#textcontainer1").resizable({handles:"s",autoHide:true,});
272 $("#textcontainer1").on("resize", onResize);
273
274 $("#textcontainer2").resizable({handles:"s",autoHide:true,});
275 $("#textcontainer2").on("resize", onResize);
276
277 $("#cameracontainer").on("resize", onResizeCameras);
278 onResizeCameras();
279
280 $("#histcontainer").on("resize", onResizeHistograms);
281 onResizeHistograms();
282
283 $("#contcamera1").click(onClickContCamera);
284 $("#contcamera2").click(onClickContCamera);
285 $("#contcamera3").click(onClickContCamera);
286 $("#contcamera4").click(onClickContCamera);
287
288 $("#conthist1").click(onClickContHist);
289 $("#conthist2").click(onClickContHist);
290 $("#conthist3").click(onClickContHist);
291 $("#conthist4").click(onClickContHist);
292
293 $("#camera1").click(onClick);
294 $("#camera2").click(onClick);
295 $("#camera3").click(onClick);
296 $("#camera4").click(onClick);
297
298 $('#camera1').mousedown(onRightMouseClick);
299 $('#camera2').mousedown(onRightMouseClick);
300 $('#camera3').mousedown(onRightMouseClick);
301 $('#camera4').mousedown(onRightMouseClick);
302
303 editor1 = createEditor("editor1");
304 editor2 = createEditor("editor2");
305
306 setupAccordion('#accordion5', '#editorcontainer1', true);
307 setupAccordion('#accordion1', '#editorcontainer2');
308
309 $('#accordion5').on("accordionactivate", function() { $('#editorcontainer1fake').hide(); editor1.refresh(); });
310 $('#accordion1').on("accordionactivate", function() { $('#editorcontainer2fake').hide(); editor2.refresh(); });
311
312 setupAccordion('#accordion2', '#cameracontainer');
313 setupAccordion('#accordion7', '#histcontainer', true);
314 setupAccordion('#accordion3', '#waveformcontainer');
315 setupAccordion('#accordion4', '#helpcontainer', true);
316 setupAccordion('#accordion6', '#ctrlcontainer', true);
317
318 $("#selectfile1").on('change', onFile);
319 $("#selectfile2").on('change', onFile);
320
321 $(document).ajaxStart(function() { disableControls(true) }).ajaxStop(function() { disableControls(false); });
322
323
324 $.ajax({
325 type: "POST",
326 cache: false,
327 url: "index.php",
328 success: onFilelistReceived,
329 error: function(xhr) { if (xhr.status==0) alert("ERROR[0] - Request failed!"); else alert("ERROR[0] - "+xhr.statusText+" ["+xhr.status+"]"); }
330 });
331}
332
333function onFileSelect(event, ui)
334{
335 var list = document.getElementById("file").data;
336 var file = ui.item.value;
337
338 $('#calibrated').prop('disabled', !list[file]);
339 if (!list[file])
340 $('#calibrated').prop('checked', false);
341
342 document.getElementById("event").value = 0;
343 onSubmit(ui.item.value);
344}
345
346function onFilelistReceived(result)
347{
348 //var dbg = document.getElementById("debug");
349
350 //var pre = document.createElement("pre");
351 //pre.appendChild(document.createTextNode(rc));
352 //dbg.appendChild(pre);
353
354 var rc;
355 try
356 {
357 rc = JSON.parse(result);
358 }
359 catch (e)
360 {
361 alert("ERROR[0] - Decoding answer:\n"+e);
362 return;
363 }
364
365 document.getElementById("file").data = rc;
366
367 var list = [ ];
368 for (var file in rc)
369 list.push(file);
370
371 var opts =
372 {
373 source: list,
374 select: onFileSelect,
375 position: { my: "right top", at: "right bottom", collision: "flipfit" },
376 };
377
378 $("#file").autocomplete(opts);
379 document.getElementById("file").value = "2014/04/17-181";
380
381 onSubmit("2014/04/17-181");
382}
383
384function setZoom(xfrom, xto, yfrom, yto)
385{
386 var xaxis = plot.getXAxes()[0];
387 var yaxis = plot.getYAxes()[0];
388
389 if (xfrom!==undefined)
390 xaxis.options.min = xfrom;
391 if (xto!==undefined)
392 xaxis.options.max = xto;
393
394 if (yfrom!==undefined)
395 yaxis.options.min = yfrom;
396 if (yto!==undefined)
397 yaxis.options.max = yto;
398
399 plot.setupGrid();
400 plot.draw();
401 plot.clearSelection();
402}
403
404function onPlotHover(event, pos, item)
405{
406 if (!item)
407 {
408 $("#tooltip").fadeOut(100);
409 return;
410 }
411
412 var x = item.datapoint[0].toFixed(2);
413 var y = item.datapoint[1].toFixed(2);
414
415 var tooltip = $("#tooltip");
416 tooltip.html(parseInt(x) + " / " + y);
417 tooltip.css({top: item.pageY-20, left: item.pageX+5});
418 tooltip.fadeIn(200);
419}
420
421function drawHist(n)
422{
423 var canv = document.getElementById("camera"+n);
424 var hist = document.getElementById("hist"+n);
425
426 var xmin = parseFloat(document.getElementById("histmin"+n).value);
427 var xmax = parseFloat(document.getElementById("histmax"+n).value);
428 var nbins = 100;//parseInt(xmax-xmin);
429 var step = (xmax-xmin)/nbins;
430 if (step<1)
431 {
432 step = 1;
433 nbins = parseInt(xmax-xmin)+1;
434 }
435
436 var bins = new Array(nbins);
437 for (var i=0; i<nbins; i++)
438 bins[i] = [ xmin+i*step, 0 ];
439
440 var data = canv.dataAbs;
441 for (var i=0; i<1440; i++)
442 if (data[i]!==undefined && data[i]!==null)
443 {
444 var ix = parseInt((data[i]-xmin)/step);
445 if (ix>=0 && ix<nbins)
446 bins[ix][1] ++;
447 }
448
449 var opts =
450 {
451 grid: {
452 hoverable: true,
453 }
454 };
455
456 var hist = $.plot("#hist"+n, [ { data:bins, bars: {show:true} } ], opts);
457 $('#hist'+n).bind("plothover", onPlotHover);
458}
459
460function processCameraData(n, data)
461{
462 var canv = document.getElementById("camera"+n);
463
464 canv.dataAbs = new Array(1440);
465 for (var i=0; i<1440; i++)
466 {
467 var val = data[map[i]];
468 if (val!==undefined && val!==null)
469 canv.dataAbs[i] = val;
470 }
471
472 canv.min = Math.min.apply(Math, canv.dataAbs.filter(function(e){return !isNaN(e)}));
473 canv.max = Math.max.apply(Math, canv.dataAbs.filter(function(e){return !isNaN(e)}));
474
475 canv.dataRel = new Array(1440);
476 for (var i=0; i<1440; i++)
477 {
478 val = data[map[i]];
479 if (val!==undefined && val!==null)
480 canv.dataRel[i] = (val-canv.min)/canv.max;
481 }
482
483 if (document.getElementById("cameraminon"+n).checked)
484 document.getElementById("cameramin"+n).value = canv.min;
485 if (document.getElementById("cameramaxon"+n).checked)
486 document.getElementById("cameramax"+n).value = canv.max;
487
488 // ---------------------------
489
490 var hist = document.getElementById("hist"+n);
491
492 hist.min = canv.min;
493 hist.max = canv.max;
494
495 if (document.getElementById("histminon"+n).checked)
496 document.getElementById("histmin"+n).value = canv.min;
497 if (document.getElementById("histmaxon"+n).checked)
498 document.getElementById("histmax"+n).value = canv.max;
499
500 drawHist(n);
501}
502
503
504function onDataReceived(rc)
505{
506 var err = document.getElementById("error");
507 var dbg = document.getElementById("debug");
508 var con = document.getElementById("console");
509
510 //var pre = document.createElement("pre");
511 //pre.appendChild(document.createTextNode(rc));
512 //dbg.appendChild(pre);
513
514 try
515 {
516 rc = JSON.parse(rc);
517 if (!rc)
518 return;
519 }
520 catch (e)
521 {
522 alert("ERROR[1] - Decoding answer:\n"+e);
523 return;
524 }
525
526 var evt = rc.event;
527 var file = rc.file;
528
529 document.getElementById("event").max = file.numEvents;
530 var el = document.getElementById("numevents");
531 if (el.firstChild)
532 el.removeChild(el.firstChild);
533 el.appendChild(document.createTextNode(file.numEvents));
534
535 var infotxt = "<pre>";
536 infotxt += "\nStart time: "+new Date(file.runStart*24*3600*1000).toUTCString();
537 infotxt += "\nEnd time: "+new Date(file.runEnd*24*3600*1000).toUTCString();
538 infotxt += "\nRun type: "+file.runType;
539 if (file.drsFile>=0)
540 infotxt += " [drs-step "+file.drsFile+"]";
541
542 $("#runinfo").html(infotxt);
543 $("#eventinfo").html("Trigger: "+evt.trigger.join(' | ')+" [0x"+evt.triggerType.toString(16)+"]");
544
545 if (rc.ret)
546 {
547 while (con.lastChild)
548 con.removeChild(con.lastChild);
549 }
550
551 if (rc.err)
552 {
553 while (err.lastChild)
554 err.removeChild(err.lastChild);
555
556 err.appendChild(document.createTextNode("Javascript runtime exception: "+rc.err.file+":"+rc.err.lineNumber));
557 err.appendChild(document.createTextNode("\n"));
558 err.appendChild(document.createTextNode(rc.err.sourceLine));
559 err.appendChild(document.createTextNode("\n"));
560 err.appendChild(document.createTextNode(rc.err.trace));
561
562 var editor = rc.err.file=="main" ? editor2 : editor1;
563 editor.setCursor(rc.err.lineNumber-1, 1);
564
565 $("#accordion").find('h3').filter(':contains(Runtime)').show();
566 $("#accordion").accordion("option", "active", 0);
567 }
568
569 if (rc.debug!==undefined)
570 {
571 con.appendChild(document.createTextNode(rc.debug));
572
573 debug("PHP execution:");
574 debug("Time Javascripts = "+(rc.timeJs[0]*1000).toFixed(2)+","+(rc.timeJs[1]*1000).toFixed(2)+","+(rc.timeJs[2]*1000).toFixed(2)+ " [ms]");
575 }
576
577 if (rc.ret!==undefined && Array.isArray(rc.ret))
578 {
579 var now = new Date();
580
581 if (rc.ret[0] instanceof Object)
582 processCameraData(1, rc.ret[0]);
583 else
584 processCameraData(1, rc.ret);
585
586 if (rc.ret.length>1)
587 processCameraData(2, rc.ret[1]);
588
589 if (rc.ret.length>2)
590 processCameraData(3, rc.ret[2]);
591
592 if (rc.ret.length>3)
593 processCameraData(4, rc.ret[3]);
594
595 debug("Calc Time = "+(new Date()-now)+" ms");
596 }
597
598 // We have to redraw all of them to display the changed pixel value
599 onCameraMinMax(1);
600 onCameraMinMax(2);
601 onCameraMinMax(3);
602 onCameraMinMax(4);
603
604 debug("Total time = "+(rc.timePhp*1000).toFixed(1)+" ms");
605 debug("Peak memory = "+rc.memory+" MiB");
606
607 if (Array.isArray(rc.waveform))
608 {
609 var waveform = document.getElementById("waveform");
610 waveform.data = [ ];
611
612 var data = [
613 { label: "[0] ", data: new Array(evt.numRoi) },
614 { label: "[1] ", data: new Array(evt.numRoi) },
615 { label: "[2] ", data: new Array(evt.numRoi) },
616 { label: "[3] ", data: new Array(evt.numRoi) },
617 ];
618
619 var min = [];
620 var max = [];
621 if (Array.isArray(rc.waveform) && rc.waveform.length==evt.numRoi)
622 {
623 min.push(Math.min.apply(Math, rc.waveform));
624 max.push(Math.max.apply(Math, rc.waveform));
625
626 var d = data[0].data;
627 for (var i=0; i<evt.numRoi; i++)
628 d[i] = [ i, rc.waveform[i] ];
629
630 waveform.data[0] = rc.waveform;
631 }
632
633 for (var j=0; j<4; j++)
634 {
635 var ref = rc.waveform[j];
636
637 if (Array.isArray(ref) && ref.length==evt.numRoi)
638 {
639 min.push(Math.min.apply(Math, ref));
640 max.push(Math.max.apply(Math, ref));
641
642 var d = data[j].data;
643 for (var i=0; i<evt.numRoi; i++)
644 d[i] = [ i, ref[i] ];
645
646 waveform.data[j] = ref;
647 }
648 }
649
650 waveform.ymin = Math.min.apply(Math, min);
651 waveform.ymax = Math.max.apply(Math, max);
652 waveform.xmin = 0;
653 waveform.xmax = evt.numRoi;
654
655 if (document.getElementById("waveformxminon").checked)
656 document.getElementById("waveformxmin").value = waveform.xmin;
657 if (document.getElementById("waveformxmaxon").checked)
658 document.getElementById("waveformxmax").value = waveform.xmax;
659
660 if (document.getElementById("waveformminon").checked)
661 document.getElementById("waveformmin").value = waveform.ymin;
662 if (document.getElementById("waveformmaxon").checked)
663 document.getElementById("waveformmax").value = waveform.ymax;
664
665 var xmin = document.getElementById("waveformxminon").checked ? waveform.xmin : parseInt(document.getElementById("waveformxmin").value);
666 var xmax = document.getElementById("waveformxmaxon").checked ? waveform.xmax : parseInt(document.getElementById("waveformxmax").value);
667
668 var ymin = document.getElementById("waveformminon").checked ? waveform.ymin : parseInt(document.getElementById("waveformmin").value);
669 var ymax = document.getElementById("waveformmaxon").checked ? waveform.ymax : parseInt(document.getElementById("waveformmax").value);
670
671 var opts =
672 {
673 xaxis: {
674 min: xmin-1,
675 max: xmax+1,
676 },
677 yaxis: {
678 min: ymin-5,
679 max: ymax+5,
680 },
681 series: {
682 lines: {
683 show: true
684 },
685 points: {
686 show: true,
687 symbol: 'cross',
688 }
689 },
690 selection: {
691 mode: "xy"
692 },
693 grid: {
694 hoverable: true,
695 }
696 };
697
698 plot = $.plot("#waveform", data, opts);
699
700 waveform = $('#waveform');
701 waveform.bind("plotselected", function (event, ranges)
702 {
703 setZoom(ranges.xaxis.from, ranges.xaxis.to,
704 ranges.yaxis.from, ranges.yaxis.to);
705 });
706
707 waveform.dblclick(function ()
708 {
709 var waveform = document.getElementById("waveform");
710 setZoom(waveform.xmin-1, waveform.xmax+1, waveform.ymin-5, waveform.ymax+5);
711 });
712 waveform.bind("plothover", onPlotHover);
713 }
714}
715
716function onSubmit(file, pixelOnly)
717{
718 if (!file)
719 file = document.getElementById("file").value;
720
721 var dbg = document.getElementById("debug");
722 while (dbg.lastChild)
723 dbg.removeChild(dbg.lastChild);
724
725 var active = $("#accordion").accordion("option", "active");
726 if (active==0)
727 {
728 $("#accordion").accordion("option", "active", false);
729 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
730 }
731
732 var calibrated = document.getElementById("calibrated");
733 var calib = !calibrated.disabled && calibrated.checked;
734 var event = document.getElementById("event").value;
735 var pixel = document.getElementById("pixel").value;
736 var source1 = editor1.getValue();
737 var source2 = editor2.getValue();
738
739 var uri = "file="+file+"&event="+event+"&pixel="+map[pixel];
740 uri += "&source1="+encodeURIComponent(source1);
741 if (!pixelOnly)
742 uri += "&source2="+encodeURIComponent(source2);
743 if (calib)
744 uri += "&calibrated=1";
745
746 $.ajax({
747 type: "POST",
748 cache: false,
749 url: "index.php",
750 data: uri,
751 success: onDataReceived,
752 error: function(xhr) { if (xhr.status==0) alert("ERROR[1] - Request failed!"); else alert("ERROR[1] - "+xhr.statusText+" ["+xhr.status+"]"); }
753 });
754}
755
756function onFile(event, ui)
757{
758 var f = event.target.files[0];
759 if (!f)
760 return;
761
762 if (!f.type.match('text/plain') && !f.type.match('application/javascript'))
763 {
764 alert("ERROR - Unknown file type.");
765 return;
766 }
767
768 var id = event.target.id;
769 var editor = id[id.length-1]=='1' ? editor1 : editor2;
770
771 var reader = new FileReader();
772
773 // Closure to capture the file information.
774 reader.onload = (function(theFile) { return function(e) { editor.setValue(e.target.result); }; })(f);
775 // onloadstart
776 // onloadend
777 // onprogress
778
779 // Read in the text file
780 reader.readAsText(f);
781}
782
783function refreshCameras()
784{
785 drawFullCam("camera1");
786 drawFullCam("camera2");
787 drawFullCam("camera3");
788 drawFullCam("camera4");
789}
790
791function onEvent()
792{
793 onSubmit();
794}
795
796function checkPixel()
797{
798 var pix = parseInt(document.getElementById("pixel").value);
799 var c = parseInt(document.getElementById("cbpx-c").value);
800 var b = parseInt(document.getElementById("cbpx-b").value);
801 var p = parseInt(document.getElementById("cbpx-p").value);
802 var x = parseInt(document.getElementById("cbpx-x").value);
803 var cbpx = parseInt(document.getElementById("cbpx").value);;
804
805 if (pix >=0 && pix <1440 &&
806 c >=0 && c < 4 &&
807 b >=0 && b < 10 &&
808 p >=0 && p < 4 &&
809 x >=0 && x < 9 &&
810 cbpx>=0 && cbpx<1440)
811 return;
812
813 document.getElementById("pixel").value = 0;
814 document.getElementById("cbpx-c").value = 1;
815 document.getElementById("cbpx-b").value = 0;
816 document.getElementById("cbpx-p").value = 3;
817 document.getElementById("cbpx-x").value = 6;
818 document.getElementById("cbpx").value = 393;
819}
820
821
822function onPixel()
823{
824 checkPixel();
825
826 var p = parseInt(document.getElementById("pixel").value);
827
828 var cbpx = map[p];
829
830 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
831 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
832 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
833 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
834 document.getElementById("cbpx").value = parseInt(cbpx);
835
836 onSubmit("", true);
837}
838
839function onCBPX()
840{
841 checkPixel();
842
843 var c = parseInt(document.getElementById("cbpx-c").value);
844 var b = parseInt(document.getElementById("cbpx-b").value);
845 var p = parseInt(document.getElementById("cbpx-p").value);
846 var x = parseInt(document.getElementById("cbpx-x").value);
847
848 var cbpx = c*360 + b*36 + p*9 + x;
849
850 document.getElementById("cbpx").value = parseInt(cbpx);
851 document.getElementById("pixel").value = map.indexOf(cbpx);
852
853 onSubmit("", true);
854}
855
856function onHW()
857{
858 checkPixel();
859
860 var cbpx = parseInt(document.getElementById("cbpx").value);;
861
862 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
863 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
864 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
865 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
866
867 document.getElementById("pixel").value = map.indexOf(cbpx);
868
869 onSubmit("", true);
870}
871
872function isInside(x, y, mouse)
873{
874 var dist = Math.sqrt((mouse.x-x)*(mouse.x-x)+(mouse.y-y)*(mouse.y-y));
875 return dist<0.5;
876
877 /*
878 ctx.translate(x, y);
879 ctx.scale(1/2, 1/3);
880
881 ctx.beginPath();
882 ctx.moveTo( 1, 1);
883 ctx.lineTo( 0, 2);
884 ctx.lineTo(-1, 1);
885 ctx.lineTo(-1, -1);
886 ctx.lineTo( 0, -2);
887 ctx.lineTo( 1, -1);
888 ctx.fill();
889
890 ctx.restore();
891 */
892}
893
894var inprogress = { };
895function moveElement(id, n, target, callback)
896{
897 if (inprogress[id]==n || inprogress[id]<0)
898 return;
899
900 inprogress[id] = target ? -n : n;
901
902 var element = $("#"+id+n); //Allow passing in either a JQuery object or selector
903 var newParent = $(target ? target : "#cont"+id+n); //Allow passing in either a JQuery object or selector
904
905 var oldOffset = element.offset();
906
907 var newOffset = newParent.offset();
908
909 var w = newParent.width();
910 var h = newParent.height();
911
912 var temp = element.appendTo('body');
913 temp.css('position', 'absolute')
914 .css('left', oldOffset.left)
915 .css('top', oldOffset.top)
916 .css('zIndex', 999);
917
918 temp.animate( {'top': newOffset.top, 'left':newOffset.left, 'width':w, 'height': h},
919 'slow', function()
920 {
921 temp = temp.appendTo(newParent);
922 temp.css('position', 'relative');
923 temp.css('width', '');
924 temp.css('height', '');
925 temp.css('zIndex', '');
926 temp.css('left', '0');
927 temp.css('top', '0');
928
929 setSize(id+n, w, h);
930
931 if (callback)
932 callback(id+n);
933
934 inprogress[id] = 0;
935 });
936}
937
938function onClickCont(event, callback)
939{
940 var id = event.target.id;
941 if (!id)
942 id = event.target.parentNode.id;
943
944 var n = parseInt(id[id.length-1]);
945 var type = id.substr(0, id.length-1);
946
947 if (id.substr(0, 4)=="cont")
948 id = id.substr(4, id.length-4);
949 if (type.substr(0, 4)=="cont")
950 type = type.substr(4, type.length-4);
951
952 if (id.substr(0, type.length)==type)
953 {
954 var cont = document.getElementById("center"+type).childNodes[0];
955 if (cont)
956 {
957 var nn = parseInt(cont.id[cont.id.length-1]);
958 moveElement(type, nn, null, callback);
959 }
960 moveElement(type, n, "#center"+type, callback);
961
962 }
963 else
964 moveElement(type, n, null, callback);
965
966}
967
968function onClickContCamera(event)
969{
970 onClickCont(event, function(el) { drawFullCam(el); });
971}
972
973function onClickContHist(event)
974{
975 onClickCont(event);
976}
977
978function onClick(event)
979{
980 var cont = document.getElementById("centercamera").childNodes[0];
981 if (!cont)
982 return;
983
984 if (cont.id!=event.target.id)
985 return;
986
987 // get click position relative to canvas
988 var rect = event.target.getBoundingClientRect();
989
990 var x = event.clientX - rect.left;
991 var y = event.clientY - rect.top;
992
993 var mouse = { x: x, y: y };
994
995 // convert click position to pixel index
996 var index = getIndex(event.target.id, mouse);
997 if (index<0)
998 return;
999
1000 document.getElementById("pixel").value = index;
1001
1002 onPixel();
1003}
1004
1005function getClickPosition(event)
1006{
1007 var rect = event.target.getBoundingClientRect();
1008
1009 var x = event.clientX - rect.left;
1010 var y = event.clientY - rect.top;
1011
1012 return { x: x, y: y };
1013}
1014
1015function onMinMax(id, n)
1016{
1017 var el = document.getElementById(id+n);
1018
1019 el.zmin = document.getElementById(id+"min"+n).value;
1020 el.zmax = document.getElementById(id+"max"+n).value;
1021}
1022
1023function onCameraMinMax(n)
1024{
1025 onMinMax("camera", n);
1026 drawFullCam("camera"+n);
1027}
1028
1029function onHistMinMax(n)
1030{
1031 onMinMax("hist", n);
1032 drawHist(n);
1033}
1034
1035function onMinMaxOn(id, n)
1036{
1037 var el = document.getElementById(id+n);
1038
1039 var redraw;
1040 if (document.getElementById(id+"minon"+n).checked)
1041 {
1042 document.getElementById(id+"min"+n).setAttribute("disabled", "true");
1043 document.getElementById(id+"min"+n).value = el.min;
1044 redraw = true;
1045 }
1046 else
1047 document.getElementById(id+"min"+n).removeAttribute("disabled");
1048
1049 if (document.getElementById(id+"maxon"+n).checked)
1050 {
1051 document.getElementById(id+"max"+n).setAttribute("disabled", "true");
1052 document.getElementById(id+"max"+n).value = el.max;
1053 redraw = true;
1054 }
1055 else
1056 document.getElementById(id+"max"+n).removeAttribute("disabled");
1057
1058 return redraw;
1059}
1060
1061function onCameraMinMaxOn(n)
1062{
1063 if (onMinMaxOn("camera", n))
1064 onCameraMinMax(n);
1065}
1066
1067function onHistMinMaxOn(n)
1068{
1069 if (onMinMaxOn("hist", n))
1070 onHistMinMax(n);
1071}
1072
1073function onWaveformMinMax()
1074{
1075 var wf = document.getElementById("waveform");
1076
1077 var xmin, xmax, ymin, ymax;
1078
1079 var redraw;
1080 if (!document.getElementById("waveformxminon").checked)
1081 xmin = document.getElementById("waveformxmin").value;
1082 if (!document.getElementById("waveformxmaxon").checked)
1083 xmax = document.getElementById("waveformxmax").value;
1084 if (!document.getElementById("waveformminon").checked)
1085 ymin = document.getElementById("waveformmin").value;
1086 if (!document.getElementById("waveformmaxon").checked)
1087 ymax = document.getElementById("waveformmax").value;
1088
1089 setZoom(xmin, xmax, ymin, ymax);
1090
1091}
1092
1093function onWaveformMinMaxOn()
1094{
1095 var wf = document.getElementById("waveform");
1096
1097 var xmin, xmax, ymin, ymax;
1098
1099 var redraw;
1100 if (document.getElementById("waveformxminon").checked)
1101 {
1102 document.getElementById("waveformxmin").setAttribute("disabled", "true");
1103 document.getElementById("waveformxmin").value = wf.xmin;
1104 xmin = wf.xmin-1;
1105 }
1106 else
1107 document.getElementById("waveformxmin").removeAttribute("disabled");
1108
1109 if (document.getElementById("waveformxmaxon").checked)
1110 {
1111 document.getElementById("waveformxmax").setAttribute("disabled", "true");
1112 document.getElementById("waveformxmax").value = wf.xmax;
1113 xmax = wf.xmax+1;
1114 }
1115 else
1116 document.getElementById("waveformxmax").removeAttribute("disabled");
1117
1118 if (document.getElementById("waveformminon").checked)
1119 {
1120 document.getElementById("waveformmin").setAttribute("disabled", "true");
1121 document.getElementById("waveformmin").value = wf.ymin;
1122 ymin = wf.ymin-5;
1123 }
1124 else
1125 document.getElementById("waveformmin").removeAttribute("disabled");
1126
1127 if (document.getElementById("waveformmaxon").checked)
1128 {
1129 document.getElementById("waveformmax").setAttribute("disabled", "true");
1130 document.getElementById("waveformmax").value = wf.ymax;
1131 ymax = wf.ymax+5;
1132 }
1133 else
1134 document.getElementById("waveformmax").removeAttribute("disabled");
1135
1136 setZoom(xmin, xmax, ymin, ymax);
1137}
1138
1139//document.addEventListener("click", getClickPosition, false);
1140
1141$(document).ready(onReady);
1142
1143// ================================== Pixel mapping =================================================
1144
1145var map = new Array(1440);
1146
1147function initPixelMap()
1148{
1149 var codedMap = "966676:6:A;68656364626Y?\\?;A=A<AGADAN4K4i5g5h5o506W?Z?]?_?>A@A?AJAIAFACAM4J4H4f5d5e5l5m5n516X?[?^?N?P?AA1ABAVAUAKAHAEAO4L4I4G4E4c5a5b5M6j5k5V6Y6\\6_6G?J?O?Q?S?2A4A3AYAXAWAbA_AnAkAhA3404F4D4B4`5^5_5J6K6L6S6T6W6Z6]6E?H?K?M?R?T?V?5A7A6A\\A[AZAeAdAaA^AmAjAgA24o3m3C4A4?4]5[5\\5G6H6I6P6Q6R6U6X6[6^6F?I?L?<?>?U?;@=@8Ah@9AMALA]ABCACfAcA`AoAlAiA4414n3l3<4@4>425Z5X5Y5D6E6F698N6O608E8H8K8H>K>N>?>B>=???A?<@>@@@i@k@j@PAOANAECDCCC<C9CZCWCTC=3:3734313=4;4943515o4W5U5V5A6B6C6687888m7n7C8F8I8F>I>L>=>@>C>E>@?B?D??@A@C@l@n@m@SARAQAHCGCFC?C>C;C8CYCVCSC<393633303n2:4846405n4l4T5R5S5>6?6@6384858j7k7l7o7D8G8J8G>J>M>>>A>D>4>6>C?3?5?B@2@4@o@_@0ALBKBTA0CoBIC8D7D@C=C:C[CXCUC>3;3835323o2m2k27454j3m4k4i4Q5O5P5C7<6=6g71828o8h7i7S9<8?8B8Q>T>W>@=C=F=e<h<5>7>9>4?6?8?3@5@7@`@b@a@OBNBMB3C2C1C;D:D9D_D\\DQCNCKCF3C3@3>2;282Z1W1l2j2h2k3i3g3j4h4f4N5L5M5@7A7B7d7e7f7l8m8n8P9Q9:8=8@8O>R>U>>=A=D=c<f<i<k<8>:><>7?9?;?6@8@:@c@e@d@RBQBPB6C5C4C>D=D<DbDaD^D[DPCMCJCE3B3?3=2:272Y1V1T1i2g2e2h3f3d3g4e4c4K5I5J5=7>7?7a7b7c7i8j8k8M9N9O9R9;8>8A8P>S>V>?=B=E=d<g<j<Z<\\<;>k=m=:?j>l>9@i?k?f@V@g@CBBBSBgBfB7CoCnC?DSDRDcD`D]DRCOCLCG3D3A3?2<292[1X1U1S1Q1f2d2b2e3c3a3d4b4`4H5F5G5:7;7<7^7_7`7f8g8h8J9K9L97:::=:@:C:F:I:I=L=O=7=:===n<1=[<]<_<l=n=0>k>m>o>j?l?n?W@Y@X@FBEBDBjBiBhB2D1D0DVDUDTDCE@EOELEIEXEUERE5222o1l1i1f1c1`1R1P1N1c2a2_2b3`3^3a4_4]4<5:5;5778797[7\\7]7c8d8e8G9H9I94:5:8:;:>:A:D:G:G=J=M=5=8=;=l<o<2=4=^<`<b<o=1>3>n>0?2?m?o?1@Z@\\@[@IBHBGBmBlBkB5D4D3DYDXDWDFEEEBE?ENEKEHEWETEQE4212n1k1h1e1b1_1]1O1M1K1`2^2\\2_3]3[3^4\\4Z4957585475767X7Y7Z7`8a8b8D9E9F91:2:3:6:9:<:?:B:E:H:H=K=N=6=9=<=m<0=3=d;f;a<H<J<2>b=d=1?a>c>0@`?b?]@D@^@:B9BJB^B]BnBfCeC6DJDIDZDnDmDGEDEAEPEMEJEYEVESE623202m1j1g1d1a1^1\\1[0L1J1?1]2[2Y2\\3Z3X3[4Y4W4654555172737U7V7W7]8^8_8A9B9C9e9o90:n9g:j:m:L:O:R:U:X:[:];`;c;T;W;Z;7<9<e;g;i;I<K<M<c=e=g=b>d>f>a?c?e?E@G@F@=B<B;BaB`B_BiChCgCMDLDKD1E0EoD9E7E<F9F6FaE^E[EjEgEdER0O0L0I0F0C0n0l0\\0Z0X0@1>1<1Z2X2V2Y3W3U3X4V4T4E5C5D5n6o607R7S7T7Z8[8\\8>9?9@9b9c9d9l9m9e:h:k:J:M:P:S:V:Y:[;^;a;R;U;X;6<8<:<;<h;j;l;L<N<P<f=h=j=e>g>i>d?f?h?N@Q@H@@B?B>BdBcBbBlCkCjCPDODND4E3E2E;E:E8E6E;F8F5F`E]EZEiEfEcEQ0N0K0H0E0B0m0k0j0Y0W0U0=1;191W2U2S2V3T3R3U4S4Q4B5@5A5k6l6m6O7P7Q7W8X8Y8;9<9=9_9`9a9j9k9\\:_:f:i:l:K:N:Q:T:W:Z:\\;_;b;S;V;Y;C<E<G<<<m;k;1<2<O<Q<S<i=[=P=h>X>Z>g?M@O@R@U@S@J@I@AB1B0BeBTB\\CmCAD@DQDiDhD5EdD<E4F2F0F=F:F7FbE_E\\EkEhEeES0P0M0J0G0D011o0h0g0e0V0T0`0:181Q2T2R2H2S3Q3P3R4P4K3?5=5>5c6i6j6h6M7N7L7U8V8T899:9W9]9^9\\9g9h9i9]:`:c:5;2;o:>;;;8;P;M;J;G;D;A;?<A<D<F<=<><n;o;3<5<R<T<Y=Z=Q=R=Y>[>\\>^>P@T@L@K@5B4B3B2BVBUB^C]CCDBDkDjDfDeD>E=E3F1FnElE@FCFFFIFLFOF;0>0A0205080513101i0f0d0c0b0_0I1H1D1P2O2G2F2D2O3N3M3J3H3a6b6e6f6g6I7J7K7R8S8397989V9Y9Z9[9f9^:a:d:4;1;n:=;:;7;O;L;I;F;C;@;@<B<0<4<U<V<X<`=]=\\=S=U=W=]>_>`>8B7B6BZBXBWB_CaC`CFDEDDDlDgDoEmE>FAFDFGFJFMF90<0?0003060714121a0^0]0G1C1B1N2L2E2C2B2@2L3I3`6d6E7F7G7H7O8Q8192969T9U9X96;3;0;?;<;9;Q;N;K;H;E;B;W<Y<^=_=a=T=V=X=\\B[BYBdCcCbCHDGD?FBFEFHFKFNF:0=0@0104070F1E1A1M2K2J2I2A2D7L8M8N8P809495961b:";
1150 // first: decode the pixel mapping!
1151 var sum = 1036080;
1152 for (var i=0; i<1440; i++)
1153 {
1154 var d0 = codedMap.charCodeAt(i*2) -48;
1155 var d1 = codedMap.charCodeAt(i*2+1)-48;
1156
1157 map[i] = d0 | (d1<<6);
1158 sum -= map[i];
1159 }
1160 if (sum!=0)
1161 alert("Pixel mapping table corrupted!");
1162}
1163
1164initPixelMap();
1165
1166// ================================== Camera Display ================================================
1167
1168var coord = new Array(1440);
1169function initCameraCoordinates()
1170{
1171 coord[0] = [0, 0];
1172 var cnt = 1;
1173 for (var ring=1; ring<24; ring++)
1174 {
1175 for (var s=0; s<6; s++)
1176 {
1177 for (var i=1; i<=ring; i++)
1178 {
1179 var pos = new Position(s, ring, i);
1180 if (pos.d() - pos.x > 395.75)
1181 continue;
1182
1183 coord[cnt++] = [ pos.x, pos.y];
1184 }
1185 }
1186 }
1187
1188 coord[1438] = [7, -22];
1189 coord[1439] = [7, 22];
1190}
1191
1192initCameraCoordinates();
1193
1194function getIndex(id, mouse)
1195{
1196 var canv = document.getElementById(id);
1197
1198 var scale = 83;
1199
1200 var w = Math.min(canv.width/scale, canv.height/scale);
1201
1202 //ctx.translate(canv.width/2, canv.height/2);
1203 //ctx.scale(w*2, w*2);
1204 //ctx.scale(1, Math.sqrt(3)/2);
1205 //ctx.translate(-0.5, 0);
1206
1207 mouse.x -= canv.width/2;
1208 mouse.y -= canv.height/2;
1209 mouse.x /= w*2;
1210 mouse.y /= w*2;
1211 mouse.y /= Math.sqrt(3)/2;
1212 mouse.x -= -0.5;
1213
1214 for (var i=0; i<1440; i++)
1215 if (isInside(coord[i][0], coord[i][1], mouse))
1216 return i;
1217
1218 return -1;
1219}
1220
1221
1222function hueToRGB(hue)
1223{
1224 hue /= 3;
1225 hue %= 6;
1226
1227 if (hue<1) return parseInt(255*hue, 10);
1228 if (hue<3) return parseInt(255, 10);
1229 if (hue<4) return parseInt(255*(4-hue), 10);
1230
1231 return 0.
1232}
1233
1234function hueToHex(flt)
1235{
1236 var s = hueToRGB(flt).toString(16);
1237 return s.length==2 ? s : "0"+s;
1238}
1239
1240function HLStoRGB(hue)
1241{
1242 if (isNaN(hue))
1243 return "fff";
1244
1245 if (hue<0)
1246 return "eef"; // 555
1247
1248 if (hue>1)
1249 return "700"; // 666
1250
1251 hue *= 14;
1252
1253 var sr = hueToHex(20-hue);
1254 var sg = hueToHex(14-hue);
1255 var sb = hueToHex(26-hue);
1256
1257 return sr+sg+sb;
1258}
1259
1260function outlineHex(ctx)
1261{
1262 ctx.scale(1/2, 1/3);
1263
1264 ctx.beginPath();
1265 ctx.moveTo( 1, 1);
1266 ctx.lineTo( 0, 2);
1267 ctx.lineTo(-1, 1);
1268 ctx.lineTo(-1, -1);
1269 ctx.lineTo( 0, -2);
1270 ctx.lineTo( 1, -1);
1271 ctx.lineTo( 1, 1);
1272}
1273
1274function drawHex(ctx, x, y, col, min, max)
1275{
1276 if (col===undefined || col===null || max<min)
1277 return;
1278
1279 var lvl = (col-min)/(max-min);
1280
1281 ctx.fillStyle = "#"+HLStoRGB(lvl);
1282
1283 ctx.save();
1284 ctx.translate(x, y);
1285 outlineHex(ctx);
1286 ctx.fill();
1287 ctx.restore();
1288}
1289
1290function Position(s, ring, i)
1291{
1292 switch (s)
1293 {
1294 case 1: this.x = ring - i*0.5; this.y = + i; break;
1295 case 2: this.x = ring*0.5 - i; this.y = ring ; break;
1296 case 3: this.x = -ring*0.5 - i*0.5; this.y = ring - i; break;
1297 case 4: this.x = -ring + i*0.5; this.y = - i; break;
1298 case 5: this.x = -ring*0.5 + i; this.y = -ring ; break;
1299 case 0: this.x = ring*0.5 + i*0.5; this.y = -ring + i; break;
1300 }
1301 this.d = (function () { return this.x*this.x + this.y*this.y*3/4; });
1302}
1303
1304function drawFullCam(id)
1305{
1306 var canv = document.getElementById(id);
1307 if (!canv)
1308 return;
1309
1310 var ctx = canv.getContext("2d");
1311
1312 ctx.clearRect(0, 0, canv.width, canv.height);
1313
1314 // ======================= Draw Graphics ======================
1315
1316 var data = canv.dataRel;
1317 if (!data)
1318 return;
1319
1320 var pixel = document.getElementById('pixel').value;
1321
1322 var min = (canv.zmin-canv.min)/canv.max;
1323 var max = (canv.zmax-canv.min)/canv.max;
1324
1325 var scale = 83;
1326
1327 var w = Math.min(canv.width/scale, canv.height/scale);
1328
1329 ctx.save();
1330 ctx.translate(canv.width/2, canv.height/2);
1331 ctx.scale(w*2, w*2);
1332 // ctx.rotate(Math.PI/3);
1333
1334 ctx.scale(1, Math.sqrt(3)/2);
1335 ctx.translate(-0.5, 0);
1336
1337 for (var i=0; i<1440; i++)
1338 drawHex(ctx, coord[i][0], coord[i][1], data[i], min, max);
1339
1340 // =================== Draw Pixel marker ====================
1341
1342 if (document.getElementById('marker').checked)
1343 {
1344 // Draw marker
1345 ctx.save();
1346
1347 ctx.lineWidth = 0.25;
1348 ctx.fillStyle = "#000";
1349
1350 ctx.translate(coord[pixel][0], coord[pixel][1]);
1351 outlineHex(ctx);
1352 ctx.stroke();
1353
1354 ctx.restore();
1355 }
1356
1357 // ======================= Draw Ellipse ======================
1358
1359 if (document.getElementById('image').checked)
1360 {
1361 var h = Hillas(canv.dataAbs, canv.zmin);
1362 if (h)
1363 {
1364 ctx.save();
1365
1366 ctx.translate(h.mean[0], h.mean[1]);
1367 ctx.rotate(h.phi);
1368
1369 ctx.save();
1370 ctx.scale(h.axis[0], h.axis[1]);
1371 ctx.beginPath();
1372 ctx.arc(0, 0, 1, 0, 2*Math.PI);
1373 ctx.restore();
1374
1375 ctx.lineWidth = 0.15;
1376 ctx.strokeStyle = "#555";
1377 ctx.stroke();
1378
1379 ctx.strokeStyle = "#888";
1380 ctx.beginPath();
1381 ctx.moveTo(0, -h.disp);
1382 ctx.lineTo(0, h.disp);
1383 ctx.stroke();
1384
1385 ctx.restore();
1386 }
1387 }
1388
1389 ctx.restore();
1390
1391 // ======================= Draw Legend ======================
1392
1393 var pval = parseFloat(canv.dataAbs[pixel]).toFixed(1);
1394 var lmin = parseFloat(canv.min).toFixed(1);
1395 var lmax = parseFloat(canv.max).toFixed(1);
1396
1397 var v0 = parseFloat(canv.zmin);
1398 var v1 = parseFloat(canv.zmax);
1399
1400 var diff = v1-v0;
1401
1402 var cw = canv.width;
1403 //var ch = canv.height;
1404
1405 ctx.font = "8pt Arial";
1406 ctx.textAlign = "right";
1407 ctx.textBaseline = "top";
1408
1409 for (var i=0; i<11; i++)
1410 {
1411 ctx.strokeStyle = "#"+HLStoRGB(i/10);
1412 ctx.strokeText((v0+diff*i/10).toPrecision(3), cw-5, 125-i*12);
1413 }
1414
1415 var mw = Math.max(ctx.measureText(lmin).width,
1416 ctx.measureText(pval).width,
1417 ctx.measureText(lmax).width);
1418
1419 ctx.textBaseline = "top";
1420 ctx.strokeStyle = "#000";
1421
1422 ctx.strokeText(lmax, 5+mw, 5+24);
1423 ctx.strokeText(pval, 5+mw, 5+12);
1424 ctx.strokeText(lmin, 5+mw, 5);
1425}
1426
1427// ===================================================================
1428
1429function Hillas(data, min)
1430{
1431 var mx = 0;
1432 var my = 0;
1433 var sz = 0;
1434
1435 var mx2 = 0;
1436 var my2 = 0;
1437 var mxy = 0;
1438
1439 var cnt = 0;
1440 for (var i=0; i<1440; i++)
1441 {
1442 if (data[i]===undefined || data[i]<min)
1443 continue;
1444
1445 sz += data[i];
1446 mx += data[i] * coord[i][0];
1447 my += data[i] * coord[i][1];
1448
1449 mx2 += data[i] * coord[i][0]*coord[i][0];
1450 my2 += data[i] * coord[i][1]*coord[i][1];
1451 mxy += data[i] * coord[i][0]*coord[i][1];
1452
1453 cnt++;
1454 }
1455
1456 if (sz==0 || cnt<3)
1457 return;
1458
1459 var xx = mx2 - mx*mx/sz;
1460 var yy = my2 - my*my/sz;
1461 var xy = mxy - mx*my/sz;
1462
1463 var d0 = yy - xx;
1464 var d1 = xy*2;
1465 var d2 = Math.sqrt(d0*d0 + d1*d1) + d0;
1466
1467 var phi = 0;
1468 var cos = 0;
1469 var sin = 1;
1470
1471 var axis1 = yy;
1472 var axis2 = xx;
1473 var ratio = xx/yy;
1474
1475 if (d1!=0 || d2==0)
1476 {
1477 var tand = d2==0 ? 0 : d2 / d1;
1478 var tand2 = tand*tand;
1479
1480 var s2 = tand2+1;
1481 var s = Math.sqrt(s2);
1482
1483 phi = Math.atan(tand)-Math.PI/2;
1484 cos = 1.0 /s;
1485 sin = tand/s;
1486
1487 axis1 = (tand2*yy + d2 + xx)/s2;
1488 axis2 = (tand2*xx - d2 + yy)/s2;
1489 ratio = (tand2*xx - d2 + yy)/(tand2*yy + d2 + xx);
1490 }
1491
1492 var length = axis1<0 ? 0 : Math.sqrt(axis1/sz);
1493 var width = axis2<0 ? 0 : Math.sqrt(axis2/sz);
1494
1495 return {
1496 "mean": [ mx/sz, my/sz ],
1497 "axis": [ width, length ],
1498 "phi": phi,
1499 "delta": [ cos, sin ],
1500 "sumw": sz,
1501 "count": cnt,
1502 "disp": 1.42/0.1111*(1-Math.sqrt(ratio)),
1503 };
1504}
Note: See TracBrowser for help on using the repository browser.