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

Last change on this file since 17808 was 17808, checked in by tbretz, 11 years ago
Added debug for caluclation time and removed the second loop from the image parameter calculation.
File size: 41.6 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.hillas = Hillas(canv.dataAbs);
473
474 canv.min = Math.min.apply(Math, canv.dataAbs.filter(function(e){return !isNaN(e)}));
475 canv.max = Math.max.apply(Math, canv.dataAbs.filter(function(e){return !isNaN(e)}));
476
477 canv.dataRel = new Array(1440);
478 for (var i=0; i<1440; i++)
479 {
480 val = data[map[i]];
481 if (val!==undefined && val!==null)
482 canv.dataRel[i] = (val-canv.min)/canv.max;
483 }
484
485 if (document.getElementById("cameraminon"+n).checked)
486 document.getElementById("cameramin"+n).value = canv.min;
487 if (document.getElementById("cameramaxon"+n).checked)
488 document.getElementById("cameramax"+n).value = canv.max;
489
490 // ---------------------------
491
492 var hist = document.getElementById("hist"+n);
493
494 hist.min = canv.min;
495 hist.max = canv.max;
496
497 if (document.getElementById("histminon"+n).checked)
498 document.getElementById("histmin"+n).value = canv.min;
499 if (document.getElementById("histmaxon"+n).checked)
500 document.getElementById("histmax"+n).value = canv.max;
501
502 drawHist(n);
503}
504
505
506function onDataReceived(rc)
507{
508 var err = document.getElementById("error");
509 var dbg = document.getElementById("debug");
510 var con = document.getElementById("console");
511
512 //var pre = document.createElement("pre");
513 //pre.appendChild(document.createTextNode(rc));
514 //dbg.appendChild(pre);
515
516 try
517 {
518 rc = JSON.parse(rc);
519 if (!rc)
520 return;
521 }
522 catch (e)
523 {
524 alert("ERROR[1] - Decoding answer:\n"+e);
525 return;
526 }
527
528 var evt = rc.event;
529 var file = rc.file;
530
531 document.getElementById("event").max = file.numEvents;
532 var el = document.getElementById("numevents");
533 if (el.firstChild)
534 el.removeChild(el.firstChild);
535 el.appendChild(document.createTextNode(file.numEvents));
536
537 var infotxt = "<pre>";
538 infotxt += "\nStart time: "+new Date(file.runStart*24*3600*1000).toUTCString();
539 infotxt += "\nEnd time: "+new Date(file.runEnd*24*3600*1000).toUTCString();
540 infotxt += "\nRun type: "+file.runType;
541 if (file.drsFile>=0)
542 infotxt += " [drs-step "+file.drsFile+"]";
543
544 $("#runinfo").html(infotxt);
545 $("#eventinfo").html("Trigger: "+evt.trigger.join(' | ')+" [0x"+evt.triggerType.toString(16)+"]");
546
547 if (rc.ret)
548 {
549 while (con.lastChild)
550 con.removeChild(con.lastChild);
551 }
552
553 if (rc.err)
554 {
555 while (err.lastChild)
556 err.removeChild(err.lastChild);
557
558 err.appendChild(document.createTextNode("Javascript runtime exception: "+rc.err.file+":"+rc.err.lineNumber));
559 err.appendChild(document.createTextNode("\n"));
560 err.appendChild(document.createTextNode(rc.err.sourceLine));
561 err.appendChild(document.createTextNode("\n"));
562 err.appendChild(document.createTextNode(rc.err.trace));
563
564 var editor = rc.err.file=="main" ? editor2 : editor1;
565 editor.setCursor(rc.err.lineNumber-1, 1);
566
567 $("#accordion").find('h3').filter(':contains(Runtime)').show();
568 $("#accordion").accordion("option", "active", 0);
569 }
570
571 if (rc.debug!==undefined)
572 {
573 con.appendChild(document.createTextNode(rc.debug));
574
575 debug("PHP execution:");
576 debug("Time Javascripts = "+(rc.timeJs[0]*1000).toFixed(2)+","+(rc.timeJs[1]*1000).toFixed(2)+","+(rc.timeJs[2]*1000).toFixed(2)+ " [ms]");
577 }
578
579 if (rc.ret!==undefined && Array.isArray(rc.ret))
580 {
581 var now = new Date();
582
583 if (rc.ret[0] instanceof Object)
584 processCameraData(1, rc.ret[0]);
585 else
586 processCameraData(1, rc.ret);
587
588 if (rc.ret.length>1)
589 processCameraData(2, rc.ret[1]);
590
591 if (rc.ret.length>2)
592 processCameraData(3, rc.ret[2]);
593
594 if (rc.ret.length>3)
595 processCameraData(4, rc.ret[3]);
596
597 debug("Calc Time = "+(new Date()-now)+" ms");
598 }
599
600 // We have to redraw all of them to display the changed pixel value
601 onCameraMinMax(1);
602 onCameraMinMax(2);
603 onCameraMinMax(3);
604 onCameraMinMax(4);
605
606 debug("Total time = "+(rc.timePhp*1000).toFixed(1)+" ms");
607 debug("Peak memory = "+rc.memory+" MiB");
608
609 if (Array.isArray(rc.waveform))
610 {
611 var waveform = document.getElementById("waveform");
612 waveform.data = [ ];
613
614 var data = [
615 { label: "[0] ", data: new Array(evt.numRoi) },
616 { label: "[1] ", data: new Array(evt.numRoi) },
617 { label: "[2] ", data: new Array(evt.numRoi) },
618 { label: "[3] ", data: new Array(evt.numRoi) },
619 ];
620
621 var min = [];
622 var max = [];
623 if (Array.isArray(rc.waveform) && rc.waveform.length==evt.numRoi)
624 {
625 min.push(Math.min.apply(Math, rc.waveform));
626 max.push(Math.max.apply(Math, rc.waveform));
627
628 var d = data[0].data;
629 for (var i=0; i<evt.numRoi; i++)
630 d[i] = [ i, rc.waveform[i] ];
631
632 waveform.data[0] = rc.waveform;
633 }
634
635 for (var j=0; j<4; j++)
636 {
637 var ref = rc.waveform[j];
638
639 if (Array.isArray(ref) && ref.length==evt.numRoi)
640 {
641 min.push(Math.min.apply(Math, ref));
642 max.push(Math.max.apply(Math, ref));
643
644 var d = data[j].data;
645 for (var i=0; i<evt.numRoi; i++)
646 d[i] = [ i, ref[i] ];
647
648 waveform.data[j] = ref;
649 }
650 }
651
652 waveform.ymin = Math.min.apply(Math, min);
653 waveform.ymax = Math.max.apply(Math, max);
654 waveform.xmin = 0;
655 waveform.xmax = evt.numRoi;
656
657 if (document.getElementById("waveformxminon").checked)
658 document.getElementById("waveformxmin").value = waveform.xmin;
659 if (document.getElementById("waveformxmaxon").checked)
660 document.getElementById("waveformxmax").value = waveform.xmax;
661
662 if (document.getElementById("waveformminon").checked)
663 document.getElementById("waveformmin").value = waveform.ymin;
664 if (document.getElementById("waveformmaxon").checked)
665 document.getElementById("waveformmax").value = waveform.ymax;
666
667 var xmin = document.getElementById("waveformxminon").checked ? waveform.xmin : parseInt(document.getElementById("waveformxmin").value);
668 var xmax = document.getElementById("waveformxmaxon").checked ? waveform.xmax : parseInt(document.getElementById("waveformxmax").value);
669
670 var ymin = document.getElementById("waveformminon").checked ? waveform.ymin : parseInt(document.getElementById("waveformmin").value);
671 var ymax = document.getElementById("waveformmaxon").checked ? waveform.ymax : parseInt(document.getElementById("waveformmax").value);
672
673 var opts =
674 {
675 xaxis: {
676 min: xmin-1,
677 max: xmax+1,
678 },
679 yaxis: {
680 min: ymin-5,
681 max: ymax+5,
682 },
683 series: {
684 lines: {
685 show: true
686 },
687 points: {
688 show: true,
689 symbol: 'cross',
690 }
691 },
692 selection: {
693 mode: "xy"
694 },
695 grid: {
696 hoverable: true,
697 }
698 };
699
700 plot = $.plot("#waveform", data, opts);
701
702 waveform = $('#waveform');
703 waveform.bind("plotselected", function (event, ranges)
704 {
705 setZoom(ranges.xaxis.from, ranges.xaxis.to,
706 ranges.yaxis.from, ranges.yaxis.to);
707 });
708
709 waveform.dblclick(function ()
710 {
711 var waveform = document.getElementById("waveform");
712 setZoom(waveform.xmin-1, waveform.xmax+1, waveform.ymin-5, waveform.ymax+5);
713 });
714 waveform.bind("plothover", onPlotHover);
715 }
716}
717
718function onSubmit(file, pixelOnly)
719{
720 if (!file)
721 file = document.getElementById("file").value;
722
723 var dbg = document.getElementById("debug");
724 while (dbg.lastChild)
725 dbg.removeChild(dbg.lastChild);
726
727 var active = $("#accordion").accordion("option", "active");
728 if (active==0)
729 {
730 $("#accordion").accordion("option", "active", false);
731 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
732 }
733
734 var calibrated = document.getElementById("calibrated");
735 var calib = !calibrated.disabled && calibrated.checked;
736 var event = document.getElementById("event").value;
737 var pixel = document.getElementById("pixel").value;
738 var source1 = editor1.getValue();
739 var source2 = editor2.getValue();
740
741 var uri = "file="+file+"&event="+event+"&pixel="+map[pixel];
742 uri += "&source1="+encodeURIComponent(source1);
743 if (!pixelOnly)
744 uri += "&source2="+encodeURIComponent(source2);
745 if (calib)
746 uri += "&calibrated=1";
747
748 $.ajax({
749 type: "POST",
750 cache: false,
751 url: "index.php",
752 data: uri,
753 success: onDataReceived,
754 error: function(xhr) { if (xhr.status==0) alert("ERROR[1] - Request failed!"); else alert("ERROR[1] - "+xhr.statusText+" ["+xhr.status+"]"); }
755 });
756}
757
758function onFile(event, ui)
759{
760 var f = event.target.files[0];
761 if (!f)
762 return;
763
764 if (!f.type.match('text/plain') && !f.type.match('application/javascript'))
765 {
766 alert("ERROR - Unknown file type.");
767 return;
768 }
769
770 var id = event.target.id;
771 var editor = id[id.length-1]=='1' ? editor1 : editor2;
772
773 var reader = new FileReader();
774
775 // Closure to capture the file information.
776 reader.onload = (function(theFile) { return function(e) { editor.setValue(e.target.result); }; })(f);
777 // onloadstart
778 // onloadend
779 // onprogress
780
781 // Read in the text file
782 reader.readAsText(f);
783}
784
785function refreshCameras()
786{
787 drawFullCam("camera1");
788 drawFullCam("camera2");
789 drawFullCam("camera3");
790 drawFullCam("camera4");
791}
792
793function onEvent()
794{
795 onSubmit();
796}
797
798function checkPixel()
799{
800 var pix = parseInt(document.getElementById("pixel").value);
801 var c = parseInt(document.getElementById("cbpx-c").value);
802 var b = parseInt(document.getElementById("cbpx-b").value);
803 var p = parseInt(document.getElementById("cbpx-p").value);
804 var x = parseInt(document.getElementById("cbpx-x").value);
805 var cbpx = parseInt(document.getElementById("cbpx").value);;
806
807 if (pix >=0 && pix <1440 &&
808 c >=0 && c < 4 &&
809 b >=0 && b < 10 &&
810 p >=0 && p < 4 &&
811 x >=0 && x < 9 &&
812 cbpx>=0 && cbpx<1440)
813 return;
814
815 document.getElementById("pixel").value = 0;
816 document.getElementById("cbpx-c").value = 1;
817 document.getElementById("cbpx-b").value = 0;
818 document.getElementById("cbpx-p").value = 3;
819 document.getElementById("cbpx-x").value = 6;
820 document.getElementById("cbpx").value = 393;
821}
822
823
824function onPixel()
825{
826 checkPixel();
827
828 var p = parseInt(document.getElementById("pixel").value);
829
830 var cbpx = map[p];
831
832 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
833 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
834 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
835 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
836 document.getElementById("cbpx").value = parseInt(cbpx);
837
838 onSubmit("", true);
839}
840
841function onCBPX()
842{
843 checkPixel();
844
845 var c = parseInt(document.getElementById("cbpx-c").value);
846 var b = parseInt(document.getElementById("cbpx-b").value);
847 var p = parseInt(document.getElementById("cbpx-p").value);
848 var x = parseInt(document.getElementById("cbpx-x").value);
849
850 var cbpx = c*360 + b*36 + p*9 + x;
851
852 document.getElementById("cbpx").value = parseInt(cbpx);
853 document.getElementById("pixel").value = map.indexOf(cbpx);
854
855 onSubmit("", true);
856}
857
858function onHW()
859{
860 checkPixel();
861
862 var cbpx = parseInt(document.getElementById("cbpx").value);;
863
864 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
865 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
866 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
867 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
868
869 document.getElementById("pixel").value = map.indexOf(cbpx);
870
871 onSubmit("", true);
872}
873
874function isInside(x, y, mouse)
875{
876 var dist = Math.sqrt((mouse.x-x)*(mouse.x-x)+(mouse.y-y)*(mouse.y-y));
877 return dist<0.5;
878
879 /*
880 ctx.translate(x, y);
881 ctx.scale(1/2, 1/3);
882
883 ctx.beginPath();
884 ctx.moveTo( 1, 1);
885 ctx.lineTo( 0, 2);
886 ctx.lineTo(-1, 1);
887 ctx.lineTo(-1, -1);
888 ctx.lineTo( 0, -2);
889 ctx.lineTo( 1, -1);
890 ctx.fill();
891
892 ctx.restore();
893 */
894}
895
896var inprogress = { };
897function moveElement(id, n, target, callback)
898{
899 if (inprogress[id]==n || inprogress[id]<0)
900 return;
901
902 inprogress[id] = target ? -n : n;
903
904 var element = $("#"+id+n); //Allow passing in either a JQuery object or selector
905 var newParent = $(target ? target : "#cont"+id+n); //Allow passing in either a JQuery object or selector
906
907 var oldOffset = element.offset();
908
909 var newOffset = newParent.offset();
910
911 var w = newParent.width();
912 var h = newParent.height();
913
914 var temp = element.appendTo('body');
915 temp.css('position', 'absolute')
916 .css('left', oldOffset.left)
917 .css('top', oldOffset.top)
918 .css('zIndex', 999);
919
920 temp.animate( {'top': newOffset.top, 'left':newOffset.left, 'width':w, 'height': h},
921 'slow', function()
922 {
923 temp = temp.appendTo(newParent);
924 temp.css('position', 'relative');
925 temp.css('width', '');
926 temp.css('height', '');
927 temp.css('zIndex', '');
928 temp.css('left', '0');
929 temp.css('top', '0');
930
931 setSize(id+n, w, h);
932
933 if (callback)
934 callback(id+n);
935
936 inprogress[id] = 0;
937 });
938}
939
940function onClickCont(event, callback)
941{
942 var id = event.target.id;
943 if (!id)
944 id = event.target.parentNode.id;
945
946 var n = parseInt(id[id.length-1]);
947 var type = id.substr(0, id.length-1);
948
949 if (id.substr(0, 4)=="cont")
950 id = id.substr(4, id.length-4);
951 if (type.substr(0, 4)=="cont")
952 type = type.substr(4, type.length-4);
953
954 if (id.substr(0, type.length)==type)
955 {
956 var cont = document.getElementById("center"+type).childNodes[0];
957 if (cont)
958 {
959 var nn = parseInt(cont.id[cont.id.length-1]);
960 moveElement(type, nn, null, callback);
961 }
962 moveElement(type, n, "#center"+type, callback);
963
964 }
965 else
966 moveElement(type, n, null, callback);
967
968}
969
970function onClickContCamera(event)
971{
972 onClickCont(event, function(el) { drawFullCam(el); });
973}
974
975function onClickContHist(event)
976{
977 onClickCont(event);
978}
979
980function onClick(event)
981{
982 var cont = document.getElementById("centercamera").childNodes[0];
983 if (!cont)
984 return;
985
986 if (cont.id!=event.target.id)
987 return;
988
989 // get click position relative to canvas
990 var rect = event.target.getBoundingClientRect();
991
992 var x = event.clientX - rect.left;
993 var y = event.clientY - rect.top;
994
995 var mouse = { x: x, y: y };
996
997 // convert click position to pixel index
998 var index = getIndex(event.target.id, mouse);
999 if (index<0)
1000 return;
1001
1002 document.getElementById("pixel").value = index;
1003
1004 onPixel();
1005}
1006
1007function getClickPosition(event)
1008{
1009 var rect = event.target.getBoundingClientRect();
1010
1011 var x = event.clientX - rect.left;
1012 var y = event.clientY - rect.top;
1013
1014 return { x: x, y: y };
1015}
1016
1017function onMinMax(id, n)
1018{
1019 var el = document.getElementById(id+n);
1020
1021 el.zmin = document.getElementById(id+"min"+n).value;
1022 el.zmax = document.getElementById(id+"max"+n).value;
1023}
1024
1025function onCameraMinMax(n)
1026{
1027 onMinMax("camera", n);
1028 drawFullCam("camera"+n);
1029}
1030
1031function onHistMinMax(n)
1032{
1033 onMinMax("hist", n);
1034 drawHist(n);
1035}
1036
1037function onMinMaxOn(id, n)
1038{
1039 var el = document.getElementById(id+n);
1040
1041 var redraw;
1042 if (document.getElementById(id+"minon"+n).checked)
1043 {
1044 document.getElementById(id+"min"+n).setAttribute("disabled", "true");
1045 document.getElementById(id+"min"+n).value = el.min;
1046 redraw = true;
1047 }
1048 else
1049 document.getElementById(id+"min"+n).removeAttribute("disabled");
1050
1051 if (document.getElementById(id+"maxon"+n).checked)
1052 {
1053 document.getElementById(id+"max"+n).setAttribute("disabled", "true");
1054 document.getElementById(id+"max"+n).value = el.max;
1055 redraw = true;
1056 }
1057 else
1058 document.getElementById(id+"max"+n).removeAttribute("disabled");
1059
1060 return redraw;
1061}
1062
1063function onCameraMinMaxOn(n)
1064{
1065 if (onMinMaxOn("camera", n))
1066 onCameraMinMax(n);
1067}
1068
1069function onHistMinMaxOn(n)
1070{
1071 if (onMinMaxOn("hist", n))
1072 onHistMinMax(n);
1073}
1074
1075function onWaveformMinMax()
1076{
1077 var wf = document.getElementById("waveform");
1078
1079 var xmin, xmax, ymin, ymax;
1080
1081 var redraw;
1082 if (!document.getElementById("waveformxminon").checked)
1083 xmin = document.getElementById("waveformxmin").value;
1084 if (!document.getElementById("waveformxmaxon").checked)
1085 xmax = document.getElementById("waveformxmax").value;
1086 if (!document.getElementById("waveformminon").checked)
1087 ymin = document.getElementById("waveformmin").value;
1088 if (!document.getElementById("waveformmaxon").checked)
1089 ymax = document.getElementById("waveformmax").value;
1090
1091 setZoom(xmin, xmax, ymin, ymax);
1092
1093}
1094
1095function onWaveformMinMaxOn()
1096{
1097 var wf = document.getElementById("waveform");
1098
1099 var xmin, xmax, ymin, ymax;
1100
1101 var redraw;
1102 if (document.getElementById("waveformxminon").checked)
1103 {
1104 document.getElementById("waveformxmin").setAttribute("disabled", "true");
1105 document.getElementById("waveformxmin").value = wf.xmin;
1106 xmin = wf.xmin-1;
1107 }
1108 else
1109 document.getElementById("waveformxmin").removeAttribute("disabled");
1110
1111 if (document.getElementById("waveformxmaxon").checked)
1112 {
1113 document.getElementById("waveformxmax").setAttribute("disabled", "true");
1114 document.getElementById("waveformxmax").value = wf.xmax;
1115 xmax = wf.xmax+1;
1116 }
1117 else
1118 document.getElementById("waveformxmax").removeAttribute("disabled");
1119
1120 if (document.getElementById("waveformminon").checked)
1121 {
1122 document.getElementById("waveformmin").setAttribute("disabled", "true");
1123 document.getElementById("waveformmin").value = wf.ymin;
1124 ymin = wf.ymin-5;
1125 }
1126 else
1127 document.getElementById("waveformmin").removeAttribute("disabled");
1128
1129 if (document.getElementById("waveformmaxon").checked)
1130 {
1131 document.getElementById("waveformmax").setAttribute("disabled", "true");
1132 document.getElementById("waveformmax").value = wf.ymax;
1133 ymax = wf.ymax+5;
1134 }
1135 else
1136 document.getElementById("waveformmax").removeAttribute("disabled");
1137
1138 setZoom(xmin, xmax, ymin, ymax);
1139}
1140
1141//document.addEventListener("click", getClickPosition, false);
1142
1143$(document).ready(onReady);
1144
1145// ================================== Pixel mapping =================================================
1146
1147var map = new Array(1440);
1148
1149function initPixelMap()
1150{
1151 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:";
1152 // first: decode the pixel mapping!
1153 var sum = 1036080;
1154 for (var i=0; i<1440; i++)
1155 {
1156 var d0 = codedMap.charCodeAt(i*2) -48;
1157 var d1 = codedMap.charCodeAt(i*2+1)-48;
1158
1159 map[i] = d0 | (d1<<6);
1160 sum -= map[i];
1161 }
1162 if (sum!=0)
1163 alert("Pixel mapping table corrupted!");
1164}
1165
1166initPixelMap();
1167
1168// ================================== Camera Display ================================================
1169
1170var coord = new Array(1440);
1171function initCameraCoordinates()
1172{
1173 coord[0] = [0, 0];
1174 var cnt = 1;
1175 for (var ring=1; ring<24; ring++)
1176 {
1177 for (var s=0; s<6; s++)
1178 {
1179 for (var i=1; i<=ring; i++)
1180 {
1181 var pos = new Position(s, ring, i);
1182 if (pos.d() - pos.x > 395.75)
1183 continue;
1184
1185 coord[cnt++] = [ pos.x, pos.y];
1186 }
1187 }
1188 }
1189
1190 coord[1438] = [7, -22];
1191 coord[1439] = [7, 22];
1192}
1193
1194initCameraCoordinates();
1195
1196function getIndex(id, mouse)
1197{
1198 var canv = document.getElementById(id);
1199
1200 var scale = 83;
1201
1202 var w = Math.min(canv.width/scale, canv.height/scale);
1203
1204 //ctx.translate(canv.width/2, canv.height/2);
1205 //ctx.scale(w*2, w*2);
1206 //ctx.scale(1, Math.sqrt(3)/2);
1207 //ctx.translate(-0.5, 0);
1208
1209 mouse.x -= canv.width/2;
1210 mouse.y -= canv.height/2;
1211 mouse.x /= w*2;
1212 mouse.y /= w*2;
1213 mouse.y /= Math.sqrt(3)/2;
1214 mouse.x -= -0.5;
1215
1216 for (var i=0; i<1440; i++)
1217 if (isInside(coord[i][0], coord[i][1], mouse))
1218 return i;
1219
1220 return -1;
1221}
1222
1223
1224function hueToRGB(hue)
1225{
1226 hue /= 3;
1227 hue %= 6;
1228
1229 if (hue<1) return parseInt(255*hue, 10);
1230 if (hue<3) return parseInt(255, 10);
1231 if (hue<4) return parseInt(255*(4-hue), 10);
1232
1233 return 0.
1234}
1235
1236function hueToHex(flt)
1237{
1238 var s = hueToRGB(flt).toString(16);
1239 return s.length==2 ? s : "0"+s;
1240}
1241
1242function HLStoRGB(hue)
1243{
1244 if (isNaN(hue))
1245 return "fff";
1246
1247 if (hue<0)
1248 return "eef"; // 555
1249
1250 if (hue>1)
1251 return "700"; // 666
1252
1253 hue *= 14;
1254
1255 var sr = hueToHex(20-hue);
1256 var sg = hueToHex(14-hue);
1257 var sb = hueToHex(26-hue);
1258
1259 return sr+sg+sb;
1260}
1261
1262function outlineHex(ctx)
1263{
1264 ctx.scale(1/2, 1/3);
1265
1266 ctx.beginPath();
1267 ctx.moveTo( 1, 1);
1268 ctx.lineTo( 0, 2);
1269 ctx.lineTo(-1, 1);
1270 ctx.lineTo(-1, -1);
1271 ctx.lineTo( 0, -2);
1272 ctx.lineTo( 1, -1);
1273 ctx.lineTo( 1, 1);
1274}
1275
1276function drawHex(ctx, x, y, col, min, max)
1277{
1278 if (col===undefined || col===null || max<min)
1279 return;
1280
1281 var lvl = (col-min)/(max-min);
1282
1283 ctx.fillStyle = "#"+HLStoRGB(lvl);
1284
1285 ctx.save();
1286 ctx.translate(x, y);
1287 outlineHex(ctx);
1288 ctx.fill();
1289 ctx.restore();
1290}
1291
1292function Position(s, ring, i)
1293{
1294 switch (s)
1295 {
1296 case 1: this.x = ring - i*0.5; this.y = + i; break;
1297 case 2: this.x = ring*0.5 - i; this.y = ring ; break;
1298 case 3: this.x = -ring*0.5 - i*0.5; this.y = ring - i; break;
1299 case 4: this.x = -ring + i*0.5; this.y = - i; break;
1300 case 5: this.x = -ring*0.5 + i; this.y = -ring ; break;
1301 case 0: this.x = ring*0.5 + i*0.5; this.y = -ring + i; break;
1302 }
1303 this.d = (function () { return this.x*this.x + this.y*this.y*3/4; });
1304}
1305
1306function drawFullCam(id)
1307{
1308 var canv = document.getElementById(id);
1309 if (!canv)
1310 return;
1311
1312 var ctx = canv.getContext("2d");
1313
1314 ctx.clearRect(0, 0, canv.width, canv.height);
1315
1316 // ======================= Draw Graphics ======================
1317
1318 var data = canv.dataRel;
1319 if (!data)
1320 return;
1321
1322 var pixel = document.getElementById('pixel').value;
1323
1324 var min = (canv.zmin-canv.min)/canv.max;
1325 var max = (canv.zmax-canv.min)/canv.max;
1326
1327 var scale = 83;
1328
1329 var w = Math.min(canv.width/scale, canv.height/scale);
1330
1331 ctx.save();
1332 ctx.translate(canv.width/2, canv.height/2);
1333 ctx.scale(w*2, w*2);
1334 // ctx.rotate(Math.PI/3);
1335
1336 ctx.scale(1, Math.sqrt(3)/2);
1337 ctx.translate(-0.5, 0);
1338
1339 for (var i=0; i<1440; i++)
1340 drawHex(ctx, coord[i][0], coord[i][1], data[i], min, max);
1341
1342 // =================== Draw Pixel marker ====================
1343
1344 if (document.getElementById('marker').checked)
1345 {
1346 // Draw marker
1347 ctx.save();
1348
1349 ctx.lineWidth = 0.25;
1350 ctx.fillStyle = "#000";
1351
1352 ctx.translate(coord[pixel][0], coord[pixel][1]);
1353 outlineHex(ctx);
1354 ctx.stroke();
1355
1356 ctx.restore();
1357 }
1358
1359 // ======================= Draw Ellipse ======================
1360
1361 var h = canv.hillas;
1362 if (h && document.getElementById('image').checked)
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 = "#444";
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 ctx.restore();
1389
1390 // ======================= Draw Legend ======================
1391
1392 var pval = parseFloat(canv.dataAbs[pixel]).toFixed(1);
1393 var lmin = parseFloat(canv.min).toFixed(1);
1394 var lmax = parseFloat(canv.max).toFixed(1);
1395
1396 var v0 = parseFloat(canv.zmin);
1397 var v1 = parseFloat(canv.zmax);
1398
1399 var diff = v1-v0;
1400
1401 var cw = canv.width;
1402 //var ch = canv.height;
1403
1404 ctx.font = "8pt Arial";
1405 ctx.textAlign = "right";
1406 ctx.textBaseline = "top";
1407
1408 for (var i=0; i<11; i++)
1409 {
1410 ctx.strokeStyle = "#"+HLStoRGB(i/10);
1411 ctx.strokeText((v0+diff*i/10).toPrecision(3), cw-5, 125-i*12);
1412 }
1413
1414 var mw = Math.max(ctx.measureText(lmin).width,
1415 ctx.measureText(pval).width,
1416 ctx.measureText(lmax).width);
1417
1418 ctx.textBaseline = "top";
1419 ctx.strokeStyle = "#000";
1420
1421 ctx.strokeText(lmax, 5+mw, 5+24);
1422 ctx.strokeText(pval, 5+mw, 5+12);
1423 ctx.strokeText(lmin, 5+mw, 5);
1424}
1425
1426// ===================================================================
1427
1428function Hillas(data)
1429{
1430 var mx = 0;
1431 var my = 0;
1432 var sz = 0;
1433
1434 var mx2 = 0;
1435 var my2 = 0;
1436 var mxy = 0;
1437
1438 var cnt = 0;
1439 for (var i=0; i<1440; i++)
1440 {
1441 if (data[i]===undefined)
1442 continue;
1443
1444 sz += data[i];
1445 mx += data[i] * coord[i][0];
1446 my += data[i] * coord[i][1];
1447
1448 mx2 += data[i] * coord[i][0]*coord[i][0];
1449 my2 += data[i] * coord[i][1]*coord[i][1];
1450 mxy += data[i] * coord[i][0]*coord[i][1];
1451
1452 cnt++;
1453 }
1454
1455 if (sz==0 || cnt<3)
1456 return;
1457
1458 var xx = mx2 - mx*mx/sz;
1459 var yy = my2 - my*my/sz;
1460 var xy = mxy - mx*my/sz;
1461
1462 var d0 = yy - xx;
1463 var d1 = xy*2;
1464 var d2 = Math.sqrt(d0*d0 + d1*d1) + d0;
1465
1466 var phi = 0;
1467 var cos = 0;
1468 var sin = 1;
1469
1470 var axis1 = yy;
1471 var axis2 = xx;
1472 var ratio = xx/yy;
1473
1474 if (d1!=0 || d2==0)
1475 {
1476 var tand = d2==0 ? 0 : d2 / d1;
1477 var tand2 = tand*tand;
1478
1479 var s2 = tand2+1;
1480 var s = Math.sqrt(s2);
1481
1482 phi = Math.atan(tand)-Math.PI/2;
1483 cos = 1.0 /s;
1484 sin = tand/s;
1485
1486 axis1 = (tand2*yy + d2 + xx)/s2;
1487 axis2 = (tand2*xx - d2 + yy)/s2;
1488 ratio = (tand2*xx - d2 + yy)/(tand2*yy + d2 + xx);
1489 }
1490
1491 var length = axis1<0 ? 0 : Math.sqrt(axis1/sz);
1492 var width = axis2<0 ? 0 : Math.sqrt(axis2/sz);
1493
1494 return {
1495 "mean": [ mx/sz, my/sz ],
1496 "axis": [ width, length ],
1497 "phi": phi,
1498 "delta": [ cos, sin ],
1499 "sumw": sz,
1500 "count": cnt,
1501 "disp": 1.42/0.1111*(1-Math.sqrt(ratio)),
1502 };
1503}
Note: See TracBrowser for help on using the repository browser.