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

Last change on this file since 17886 was 17856, checked in by tbretz, 11 years ago
Added the possibility to retrieve different file names in the additional controls and the possibility to get the geometry.
File size: 44.2 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", "fact");
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 setFileChecks()
207{
208 var list = document.getElementById("file").data;
209 if (!list)
210 return;
211
212 var file = document.getElementById("file").value;
213 var drs = document.getElementById("drsfile");
214
215 var hasDrs = list[file]&2;
216 var hasCal = list[file]&4;
217 var isMC = list[file]&8;
218
219 if (!hasDrs || isMC)
220 $('#drsfile').prop('checked', false);
221 if (!hasCal || isMC)
222 $('#calibrated').prop('checked', false);
223
224 $('#calibrated').prop('disabled', (!hasCal && !drs.checked) || isMC);
225 $('#drsfile').prop('disabled', !hasDrs || isMC);
226
227 $('#txtcalibrated').css('color', (!hasCal && !drs.checked) || isMC ? 'darkgrey' : 'black');
228 $('#txtdrsfile').css( 'color', !hasDrs || isMC ? 'darkgrey' : 'black');
229 $('#txtmontecarlo').css('color', !isMC ? 'darkgrey' : 'black');
230
231 $('#montecarlo').prop('checked', isMC);
232}
233
234function disableControls(disabled)
235{
236 $('#submit').prop('disabled', disabled);
237 $('#getcamera').prop('disabled', disabled);
238 $('#getwaveforms').prop('disabled', disabled);
239 $('#event').prop('disabled', disabled);
240 $('#pixel').prop('disabled', disabled);
241 $('#cbpx').prop('disabled', disabled);
242 $('#cbpx-c').prop('disabled', disabled);
243 $('#cbpx-b').prop('disabled', disabled);
244 $('#cbpx-p').prop('disabled', disabled);
245 $('#cbpx-x').prop('disabled', disabled);
246 $('#file').prop('disabled', disabled);
247
248 if (disabled)
249 {
250 $('#calibrated').prop('disabled', true);
251 $('#drsfile').prop('disabled', true);
252 $('#montecarlo').prop('disabled', true);
253 }
254 else
255 setFileChecks();
256}
257
258function onGetCameras()
259{
260 var arr =
261 [
262 document.getElementById("camera1").dataAbs,
263 document.getElementById("camera2").dataAbs,
264 document.getElementById("camera3").dataAbs,
265 document.getElementById("camera4").dataAbs,
266 ];
267
268 $('#controls > input[name=data]').val(JSON.stringify(arr));
269 $('#controls > input[name=name]').val('cameras.txt');
270 $('#controls').attr('action','index.php');
271 $('#controls').submit();
272}
273
274function onGetWaveforms()
275{
276 var arr = document.getElementById("waveform").data;
277
278 $('#controls > input[name=data]').val(JSON.stringify(arr));
279 $('#controls > input[name=name]').val('waveforms.txt');
280 $('#controls').attr('action','index.php');
281 $('#controls').submit();
282}
283
284function onGetGeometry()
285{
286 var sqrt32 = Math.sqrt(3)/2;
287
288 var arr = [ new Array(1440), new Array(1440) ];
289
290 for (var i=0; i<1440; i++)
291 {
292 arr[0][i] = coord[i][0]*0.1111;
293 arr[1][i] = coord[i][1]*0.1111*sqrt32;
294 }
295
296 $('#controls > input[name=data]').val(JSON.stringify(arr));
297 $('#controls > input[name=name]').val('geometry.txt');
298 $('#controls').attr('action','index.php');
299 $('#controls').submit();
300}
301
302function onReady()
303{
304 CodeMirror.colorize(null, 'javascript');
305
306 //$('input,select').keypress(function(event) { return event.keyCode != 13; });
307
308 //colorizeHTML("code0");
309 //colorizeHTML("code1");
310
311 $("#accordion").accordion({collapsible:true,active:false,heightStyle:'content'});
312 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
313 if (location.href.search('debug')==-1)
314 $("#accordion").find('h3').filter(':contains(Debug)').hide();
315
316 $("#textcontainer1").resizable({handles:"s",autoHide:true,});
317 $("#textcontainer1").on("resize", onResize);
318
319 $("#textcontainer2").resizable({handles:"s",autoHide:true,});
320 $("#textcontainer2").on("resize", onResize);
321
322 $("#cameracontainer").on("resize", onResizeCameras);
323 onResizeCameras();
324
325 $("#histcontainer").on("resize", onResizeHistograms);
326 onResizeHistograms();
327
328 $("#contcamera1").click(onClickContCamera);
329 $("#contcamera2").click(onClickContCamera);
330 $("#contcamera3").click(onClickContCamera);
331 $("#contcamera4").click(onClickContCamera);
332
333 $("#conthist1").click(onClickContHist);
334 $("#conthist2").click(onClickContHist);
335 $("#conthist3").click(onClickContHist);
336 $("#conthist4").click(onClickContHist);
337
338 $("#camera1").click(onClick);
339 $("#camera2").click(onClick);
340 $("#camera3").click(onClick);
341 $("#camera4").click(onClick);
342
343 $('#camera1').mousedown(onRightMouseClick);
344 $('#camera2').mousedown(onRightMouseClick);
345 $('#camera3').mousedown(onRightMouseClick);
346 $('#camera4').mousedown(onRightMouseClick);
347
348 editor1 = createEditor("editor1");
349 editor2 = createEditor("editor2");
350
351 setupAccordion('#accordion5', '#editorcontainer1', true);
352 setupAccordion('#accordion1', '#editorcontainer2');
353
354 $('#accordion5').on("accordionactivate", function() { $('#editorcontainer1fake').hide(); editor1.refresh(); });
355 $('#accordion1').on("accordionactivate", function() { $('#editorcontainer2fake').hide(); editor2.refresh(); });
356
357 setupAccordion('#accordion2', '#cameracontainer');
358 setupAccordion('#accordion7', '#histcontainer', true);
359 setupAccordion('#accordion3', '#waveformcontainer');
360 setupAccordion('#accordion4', '#helpcontainer', true);
361 setupAccordion('#accordion6', '#ctrlcontainer', true);
362
363 $("#selectfile1").on('change', onFile);
364 $("#selectfile2").on('change', onFile);
365
366 $(document).ajaxStart(function() { disableControls(true) }).ajaxStop(function() { disableControls(false); });
367
368
369 $.ajax({
370 type: "POST",
371 cache: false,
372 url: "index.php",
373 success: onFilelistReceived,
374 error: function(xhr) { if (xhr.status==0) alert("ERROR[0] - Request failed!"); else alert("ERROR[0] - "+xhr.statusText+" ["+xhr.status+"]"); }
375 });
376}
377
378function onFileSelect(event, ui)
379{
380 setFileChecks();
381 document.getElementById("event").value = 0;
382 onSubmit(ui.item.value);
383}
384
385function onFilelistReceived(result)
386{
387 //var dbg = document.getElementById("debug");
388
389 //var pre = document.createElement("pre");
390 //pre.appendChild(document.createTextNode(rc));
391 //dbg.appendChild(pre);
392
393 var rc;
394 try
395 {
396 rc = JSON.parse(result);
397 }
398 catch (e)
399 {
400 alert("ERROR[0] - Decoding answer:\n"+e);
401 debug(result);
402 return;
403 }
404
405 document.getElementById("file").data = rc;
406
407 var list = [ ];
408 for (var file in rc)
409 list.push(file);
410
411 var opts =
412 {
413 source: list,
414 select: onFileSelect,
415 position: { my: "right top", at: "right bottom", collision: "flipfit" },
416 };
417
418 $("#file").autocomplete(opts);
419 document.getElementById("file").value = "2014/04/17-181";
420
421 onSubmit("2014/04/17-181");
422}
423
424function setZoom(xfrom, xto, yfrom, yto)
425{
426 var xaxis = plot.getXAxes()[0];
427 var yaxis = plot.getYAxes()[0];
428
429 if (xfrom!==undefined)
430 xaxis.options.min = xfrom;
431 if (xto!==undefined)
432 xaxis.options.max = xto;
433
434 if (yfrom!==undefined)
435 yaxis.options.min = yfrom;
436 if (yto!==undefined)
437 yaxis.options.max = yto;
438
439 plot.setupGrid();
440 plot.draw();
441 plot.clearSelection();
442}
443
444function onPlotHover(event, pos, item)
445{
446 if (!item)
447 {
448 $("#tooltip").hide();//fadeOut(100);
449 return;
450 }
451
452 var x = item.datapoint[0].toFixed(2);
453 var y = item.datapoint[1].toFixed(2);
454
455 var tooltip = $("#tooltip");
456 tooltip.html(parseInt(x) + " / " + y);
457 tooltip.css({top: item.pageY-20, left: item.pageX+5});
458 tooltip.show();//fadeIn(200);
459}
460
461function drawHist(n)
462{
463 var canv = document.getElementById("camera"+n);
464 var hist = document.getElementById("hist"+n);
465
466 var xmin = parseFloat(document.getElementById("histmin"+n).value);
467 var xmax = parseFloat(document.getElementById("histmax"+n).value);
468 var nbins = 100;//parseInt(xmax-xmin);
469 var step = (xmax-xmin)/nbins;
470 if (step<1)
471 {
472 step = 1;
473 nbins = parseInt(xmax-xmin)+1;
474 }
475
476 var bins = new Array(nbins);
477 for (var i=0; i<nbins; i++)
478 bins[i] = [ xmin+i*step, 0 ];
479
480 var data = canv.dataAbs;
481 for (var i=0; i<1440; i++)
482 if (data[i]!==undefined/* && data[i]!==null*/)
483 {
484 var ix = parseInt((data[i]-xmin)/step);
485 if (ix>=0 && ix<nbins)
486 bins[ix][1] ++;
487 }
488
489 var opts =
490 {
491 grid: {
492 hoverable: true,
493 }
494 };
495
496 var hist = $.plot("#hist"+n, [ { data:bins, bars: {show:true} } ], opts);
497 $('#hist'+n).bind("plothover", onPlotHover);
498}
499
500function processCameraData(n, data)
501{
502 var canv = document.getElementById("camera"+n);
503 canv.dataRel = null;
504
505 if (!Array.isArray(data))
506 return;
507
508 canv.dataAbs = new Array(1440);
509 for (var i=0; i<1440; i++)
510 {
511 var val = data[map[i]];
512 if (!isNaN(val) && val!==null)
513 canv.dataAbs[i] = val;
514 }
515
516 canv.min = Math.min.apply(Math, canv.dataAbs.filter(function(e){return e!==undefined;}));
517 canv.max = Math.max.apply(Math, canv.dataAbs.filter(function(e){return e!==undefined;}));
518
519 canv.dataRel = new Array(1440);
520 for (var i=0; i<1440; i++)
521 {
522 var val = canv.dataAbs[i];
523 if (val!==undefined)
524 canv.dataRel[i] = (val-canv.min)/canv.max;
525 }
526
527 if (document.getElementById("cameraminon"+n).checked)
528 document.getElementById("cameramin"+n).value = canv.min;
529 if (document.getElementById("cameramaxon"+n).checked)
530 document.getElementById("cameramax"+n).value = canv.max;
531
532 // ---------------------------
533
534 var hist = document.getElementById("hist"+n);
535
536 hist.min = canv.min;
537 hist.max = canv.max;
538
539 if (document.getElementById("histminon"+n).checked)
540 document.getElementById("histmin"+n).value = canv.min;
541 if (document.getElementById("histmaxon"+n).checked)
542 document.getElementById("histmax"+n).value = canv.max;
543
544 drawHist(n);
545}
546
547function onDataReceived(result)
548{
549 var err = document.getElementById("error");
550 var dbg = document.getElementById("debug");
551 var con = document.getElementById("console");
552
553 //var pre = document.createElement("pre");
554 //pre.appendChild(document.createTextNode(rc));
555 //dbg.appendChild(pre);
556
557 var rc;
558 try
559 {
560 rc = JSON.parse(result);
561 if (!rc)
562 return;
563 }
564 catch (e)
565 {
566 alert("ERROR[1] - Decoding answer:\n"+e);
567 debug(result);
568 return;
569 }
570
571 var evt = rc.event;
572 var file = rc.file;
573
574 document.getElementById("event").max = file.numEvents-1;
575 var el = document.getElementById("numevents");
576 if (el.firstChild)
577 el.removeChild(el.firstChild);
578 el.appendChild(document.createTextNode(file.numEvents));
579
580 var infotxt = "<pre>";
581 infotxt += "\nStart time: "+new Date(file.runStart*24*3600*1000).toUTCString();
582 infotxt += "\nEnd time: "+new Date(file.runEnd*24*3600*1000).toUTCString();
583 infotxt += "\nRun type: "+file.runType;
584 if (file.drsFile>=0)
585 infotxt += " [drs-step "+file.drsFile+"]";
586
587 $("#runinfo").html(infotxt);
588 $("#eventinfo").html("Trigger: "+evt.trigger.join(' | ')+" [0x"+evt.triggerType.toString(16)+"]");
589
590 if (rc.ret)
591 {
592 while (con.lastChild)
593 con.removeChild(con.lastChild);
594 }
595
596 if (rc.err)
597 {
598 while (err.lastChild)
599 err.removeChild(err.lastChild);
600
601 err.appendChild(document.createTextNode("Javascript runtime exception: "+rc.err.file+":"+rc.err.lineNumber));
602 err.appendChild(document.createTextNode("\n"));
603 err.appendChild(document.createTextNode(rc.err.sourceLine));
604 err.appendChild(document.createTextNode("\n"));
605 err.appendChild(document.createTextNode(rc.err.trace));
606
607 var editor = rc.err.file=="main" ? editor2 : editor1;
608 editor.setCursor(rc.err.lineNumber-1, 1);
609
610 $("#accordion").find('h3').filter(':contains(Runtime)').show();
611 $("#accordion").accordion("option", "active", 0);
612 }
613
614 if (rc.debug!==undefined)
615 {
616 con.appendChild(document.createTextNode(rc.debug));
617
618 debug("PHP execution:");
619 debug("Time Javascripts = "+(rc.timeJs[0]*1000).toFixed(2)+","+(rc.timeJs[1]*1000).toFixed(2)+","+(rc.timeJs[2]*1000).toFixed(2)+ " [ms]");
620 }
621
622 if (rc.ret!==undefined && Array.isArray(rc.ret))
623 {
624 var now = new Date();
625
626 if (rc.ret[0] instanceof Object)
627 processCameraData(1, rc.ret[0]);
628 else
629 processCameraData(1, rc.ret);
630
631 if (rc.ret.length>1)
632 processCameraData(2, rc.ret[1]);
633
634 if (rc.ret.length>2)
635 processCameraData(3, rc.ret[2]);
636
637 if (rc.ret.length>3)
638 processCameraData(4, rc.ret[3]);
639
640 debug("Calc Time = "+(new Date()-now)+" ms");
641 }
642
643 // We have to redraw all of them to display the changed pixel value
644 onCameraMinMax(1);
645 onCameraMinMax(2);
646 onCameraMinMax(3);
647 onCameraMinMax(4);
648
649 debug("Total time = "+(rc.timePhp*1000).toFixed(1)+" ms");
650 debug("Peak memory = "+rc.memory+" MiB");
651
652 if (Array.isArray(rc.waveform))
653 {
654 var waveform = document.getElementById("waveform");
655 waveform.data = [ ];
656
657 var data = [
658 { label: "[0] ", data: new Array(evt.numRoi) },
659 { label: "[1] ", data: new Array(evt.numRoi) },
660 { label: "[2] ", data: new Array(evt.numRoi) },
661 { label: "[3] ", data: new Array(evt.numRoi) },
662 ];
663
664 var min = [];
665 var max = [];
666 if (Array.isArray(rc.waveform) && rc.waveform.length==evt.numRoi)
667 {
668 min.push(Math.min.apply(Math, rc.waveform));
669 max.push(Math.max.apply(Math, rc.waveform));
670
671 var d = data[0].data;
672 for (var i=0; i<evt.numRoi; i++)
673 d[i] = [ i, rc.waveform[i] ];
674
675 waveform.data[0] = rc.waveform;
676 }
677
678 for (var j=0; j<4; j++)
679 {
680 var ref = rc.waveform[j];
681
682 if (Array.isArray(ref) && ref.length==evt.numRoi)
683 {
684 min.push(Math.min.apply(Math, ref));
685 max.push(Math.max.apply(Math, ref));
686
687 var d = data[j].data;
688 for (var i=0; i<evt.numRoi; i++)
689 d[i] = [ i, ref[i] ];
690
691 waveform.data[j] = ref;
692 }
693 }
694
695 waveform.ymin = Math.min.apply(Math, min);
696 waveform.ymax = Math.max.apply(Math, max);
697 waveform.xmin = 0;
698 waveform.xmax = evt.numRoi;
699
700 if (document.getElementById("waveformxminon").checked)
701 document.getElementById("waveformxmin").value = waveform.xmin;
702 if (document.getElementById("waveformxmaxon").checked)
703 document.getElementById("waveformxmax").value = waveform.xmax;
704
705 if (document.getElementById("waveformminon").checked)
706 document.getElementById("waveformmin").value = waveform.ymin;
707 if (document.getElementById("waveformmaxon").checked)
708 document.getElementById("waveformmax").value = waveform.ymax;
709
710 var xmin = document.getElementById("waveformxminon").checked ? waveform.xmin : parseInt(document.getElementById("waveformxmin").value);
711 var xmax = document.getElementById("waveformxmaxon").checked ? waveform.xmax : parseInt(document.getElementById("waveformxmax").value);
712
713 var ymin = document.getElementById("waveformminon").checked ? waveform.ymin : parseInt(document.getElementById("waveformmin").value);
714 var ymax = document.getElementById("waveformmaxon").checked ? waveform.ymax : parseInt(document.getElementById("waveformmax").value);
715
716 var opts =
717 {
718 xaxis: {
719 min: xmin-1,
720 max: xmax+1,
721 },
722 yaxis: {
723 min: ymin-5,
724 max: ymax+5,
725 },
726 series: {
727 lines: {
728 show: true
729 },
730 points: {
731 show: true,
732 symbol: 'cross',
733 }
734 },
735 selection: {
736 mode: "xy"
737 },
738 grid: {
739 hoverable: true,
740 }
741 };
742
743 plot = $.plot("#waveform", data, opts);
744
745 waveform = $('#waveform');
746 waveform.bind("plotselected", function (event, ranges)
747 {
748 setZoom(ranges.xaxis.from, ranges.xaxis.to,
749 ranges.yaxis.from, ranges.yaxis.to);
750 });
751
752 waveform.dblclick(function ()
753 {
754 var waveform = document.getElementById("waveform");
755 setZoom(waveform.xmin-1, waveform.xmax+1, waveform.ymin-5, waveform.ymax+5);
756 });
757 waveform.bind("plothover", onPlotHover);
758 }
759}
760
761function onSubmit(file, pixelOnly)
762{
763 if (!file)
764 file = document.getElementById("file").value;
765
766 var dbg = document.getElementById("debug");
767 while (dbg.lastChild)
768 dbg.removeChild(dbg.lastChild);
769
770 var active = $("#accordion").accordion("option", "active");
771 if (active==0)
772 {
773 $("#accordion").accordion("option", "active", false);
774 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
775 }
776
777 var calibrated = document.getElementById("calibrated");
778 var drsfile = document.getElementById("drsfile");
779 var montecarlo = document.getElementById("montecarlo");
780 var ismc = montecarlo.checked;
781 var calib = !calibrated.disabled && calibrated.checked;
782 var drs = !drsfile.disabled && drsfile.checked;
783 var event = document.getElementById("event").value;
784 var pixel = document.getElementById("pixel").value;
785 var source1 = editor1.getValue();
786 var source2 = editor2.getValue();
787
788 var uri = "file="+file+"&event="+event+"&pixel="+map[pixel];
789 uri += "&source1="+encodeURIComponent(source1);
790 if (!pixelOnly)
791 uri += "&source2="+encodeURIComponent(source2);
792 if (calib)
793 uri += "&calibrated=1";
794 if (drs)
795 uri += "&drsfile=1";
796 if (ismc)
797 uri += "&montecarlo=1";
798
799 $.ajax({
800 type: "POST",
801 cache: false,
802 url: "index.php",
803 data: uri,
804 success: onDataReceived,
805 error: function(xhr) { if (xhr.status==0) alert("ERROR[1] - Request failed!"); else alert("ERROR[1] - "+xhr.statusText+" ["+xhr.status+"]"); }
806 });
807}
808
809function onFile(event, ui)
810{
811 var f = event.target.files[0];
812 if (!f)
813 return;
814
815 if (!f.type.match('text/plain') && !f.type.match('application/javascript') && !f.type.match('application/x-javascript'))
816 {
817 alert("ERROR - Unknown file type: "+f.type);
818 return;
819 }
820
821 var id = event.target.id;
822 var editor = id[id.length-1]=='1' ? editor1 : editor2;
823
824 var reader = new FileReader();
825
826 // Closure to capture the file information.
827 reader.onload = (function(theFile) { return function(e) { editor.setValue(e.target.result); }; })(f);
828 // onloadstart
829 // onloadend
830 // onprogress
831
832 // Read in the text file
833 reader.readAsText(f);
834}
835
836function refreshCameras()
837{
838 drawFullCam("camera1");
839 drawFullCam("camera2");
840 drawFullCam("camera3");
841 drawFullCam("camera4");
842}
843
844function onEvent()
845{
846 onSubmit();
847}
848
849function checkPixel()
850{
851 var pix = parseInt(document.getElementById("pixel").value);
852 var c = parseInt(document.getElementById("cbpx-c").value);
853 var b = parseInt(document.getElementById("cbpx-b").value);
854 var p = parseInt(document.getElementById("cbpx-p").value);
855 var x = parseInt(document.getElementById("cbpx-x").value);
856 var cbpx = parseInt(document.getElementById("cbpx").value);;
857
858 if (pix >=0 && pix <1440 &&
859 c >=0 && c < 4 &&
860 b >=0 && b < 10 &&
861 p >=0 && p < 4 &&
862 x >=0 && x < 9 &&
863 cbpx>=0 && cbpx<1440)
864 return;
865
866 document.getElementById("pixel").value = 0;
867 document.getElementById("cbpx-c").value = 1;
868 document.getElementById("cbpx-b").value = 0;
869 document.getElementById("cbpx-p").value = 3;
870 document.getElementById("cbpx-x").value = 6;
871 document.getElementById("cbpx").value = 393;
872}
873
874
875function onPixel()
876{
877 checkPixel();
878
879 var p = parseInt(document.getElementById("pixel").value);
880
881 var cbpx = map[p];
882
883 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
884 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
885 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
886 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
887 document.getElementById("cbpx").value = parseInt(cbpx);
888
889 onSubmit("", true);
890}
891
892function onCBPX()
893{
894 checkPixel();
895
896 var c = parseInt(document.getElementById("cbpx-c").value);
897 var b = parseInt(document.getElementById("cbpx-b").value);
898 var p = parseInt(document.getElementById("cbpx-p").value);
899 var x = parseInt(document.getElementById("cbpx-x").value);
900
901 var cbpx = c*360 + b*36 + p*9 + x;
902
903 document.getElementById("cbpx").value = parseInt(cbpx);
904 document.getElementById("pixel").value = map.indexOf(cbpx);
905
906 onSubmit("", true);
907}
908
909function onHW()
910{
911 checkPixel();
912
913 var cbpx = parseInt(document.getElementById("cbpx").value);;
914
915 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
916 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
917 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
918 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
919
920 document.getElementById("pixel").value = map.indexOf(cbpx);
921
922 onSubmit("", true);
923}
924
925function isInside(x, y, mouse)
926{
927 var dist = Math.sqrt((mouse.x-x)*(mouse.x-x)+(mouse.y-y)*(mouse.y-y));
928 return dist<0.5;
929
930 /*
931 ctx.translate(x, y);
932 ctx.scale(1/2, 1/3);
933
934 ctx.beginPath();
935 ctx.moveTo( 1, 1);
936 ctx.lineTo( 0, 2);
937 ctx.lineTo(-1, 1);
938 ctx.lineTo(-1, -1);
939 ctx.lineTo( 0, -2);
940 ctx.lineTo( 1, -1);
941 ctx.fill();
942
943 ctx.restore();
944 */
945}
946
947var inprogress = { };
948function moveElement(id, n, target, callback)
949{
950 if (inprogress[id]==n || inprogress[id]<0)
951 return;
952
953 inprogress[id] = target ? -n : n;
954
955 var element = $("#"+id+n); //Allow passing in either a JQuery object or selector
956 var newParent = $(target ? target : "#cont"+id+n); //Allow passing in either a JQuery object or selector
957
958 var oldOffset = element.offset();
959
960 var newOffset = newParent.offset();
961
962 var w = newParent.width();
963 var h = newParent.height();
964
965 var temp = element.appendTo('body');
966 temp.css('position', 'absolute')
967 .css('left', oldOffset.left)
968 .css('top', oldOffset.top)
969 .css('zIndex', 999);
970
971 temp.animate( {'top': newOffset.top, 'left':newOffset.left, 'width':w, 'height': h},
972 'slow', function()
973 {
974 temp = temp.appendTo(newParent);
975 temp.css('position', 'relative');
976 temp.css('width', '');
977 temp.css('height', '');
978 temp.css('zIndex', '');
979 temp.css('left', '0');
980 temp.css('top', '0');
981
982 setSize(id+n, w, h);
983
984 if (callback)
985 callback(id+n);
986
987 inprogress[id] = 0;
988 });
989}
990
991function onClickCont(event, callback)
992{
993 var id = event.target.id;
994 if (!id)
995 id = event.target.parentNode.id;
996
997 var n = parseInt(id[id.length-1]);
998 var type = id.substr(0, id.length-1);
999
1000 if (id.substr(0, 4)=="cont")
1001 id = id.substr(4, id.length-4);
1002 if (type.substr(0, 4)=="cont")
1003 type = type.substr(4, type.length-4);
1004
1005 if (id.substr(0, type.length)==type)
1006 {
1007 var cont = document.getElementById("center"+type).childNodes[0];
1008 if (cont)
1009 {
1010 var nn = parseInt(cont.id[cont.id.length-1]);
1011 moveElement(type, nn, null, callback);
1012 }
1013 moveElement(type, n, "#center"+type, callback);
1014
1015 }
1016 else
1017 moveElement(type, n, null, callback);
1018
1019}
1020
1021function onClickContCamera(event)
1022{
1023 onClickCont(event, function(el) { drawFullCam(el); });
1024}
1025
1026function onClickContHist(event)
1027{
1028 onClickCont(event);
1029}
1030
1031function onClick(event)
1032{
1033 var cont = document.getElementById("centercamera").childNodes[0];
1034 if (!cont)
1035 return;
1036
1037 if (cont.id!=event.target.id)
1038 return;
1039
1040 // get click position relative to canvas
1041 var rect = event.target.getBoundingClientRect();
1042
1043 var x = event.clientX - rect.left;
1044 var y = event.clientY - rect.top;
1045
1046 var mouse = { x: x, y: y };
1047
1048 // convert click position to pixel index
1049 var index = getIndex(event.target.id, mouse);
1050 if (index<0)
1051 return;
1052
1053 document.getElementById("pixel").value = index;
1054
1055 onPixel();
1056}
1057
1058function getClickPosition(event)
1059{
1060 var rect = event.target.getBoundingClientRect();
1061
1062 var x = event.clientX - rect.left;
1063 var y = event.clientY - rect.top;
1064
1065 return { x: x, y: y };
1066}
1067
1068function onMinMax(id, n)
1069{
1070 var el = document.getElementById(id+n);
1071
1072 el.zmin = document.getElementById(id+"min"+n).value;
1073 el.zmax = document.getElementById(id+"max"+n).value;
1074}
1075
1076function onCameraMinMax(n)
1077{
1078 onMinMax("camera", n);
1079 drawFullCam("camera"+n);
1080}
1081
1082function onHistMinMax(n)
1083{
1084 onMinMax("hist", n);
1085 drawHist(n);
1086}
1087
1088function onMinMaxOn(id, n)
1089{
1090 var el = document.getElementById(id+n);
1091
1092 var redraw;
1093 if (document.getElementById(id+"minon"+n).checked)
1094 {
1095 document.getElementById(id+"min"+n).setAttribute("disabled", "true");
1096 document.getElementById(id+"min"+n).value = el.min;
1097 redraw = true;
1098 }
1099 else
1100 document.getElementById(id+"min"+n).removeAttribute("disabled");
1101
1102 if (document.getElementById(id+"maxon"+n).checked)
1103 {
1104 document.getElementById(id+"max"+n).setAttribute("disabled", "true");
1105 document.getElementById(id+"max"+n).value = el.max;
1106 redraw = true;
1107 }
1108 else
1109 document.getElementById(id+"max"+n).removeAttribute("disabled");
1110
1111 return redraw;
1112}
1113
1114function onCameraMinMaxOn(n)
1115{
1116 if (onMinMaxOn("camera", n))
1117 onCameraMinMax(n);
1118}
1119
1120function onHistMinMaxOn(n)
1121{
1122 if (onMinMaxOn("hist", n))
1123 onHistMinMax(n);
1124}
1125
1126function onWaveformMinMax()
1127{
1128 var wf = document.getElementById("waveform");
1129
1130 var xmin, xmax, ymin, ymax;
1131
1132 var redraw;
1133 if (!document.getElementById("waveformxminon").checked)
1134 xmin = document.getElementById("waveformxmin").value;
1135 if (!document.getElementById("waveformxmaxon").checked)
1136 xmax = document.getElementById("waveformxmax").value;
1137 if (!document.getElementById("waveformminon").checked)
1138 ymin = document.getElementById("waveformmin").value;
1139 if (!document.getElementById("waveformmaxon").checked)
1140 ymax = document.getElementById("waveformmax").value;
1141
1142 setZoom(xmin, xmax, ymin, ymax);
1143
1144}
1145
1146function onWaveformMinMaxOn()
1147{
1148 var wf = document.getElementById("waveform");
1149
1150 var xmin, xmax, ymin, ymax;
1151
1152 var redraw;
1153 if (document.getElementById("waveformxminon").checked)
1154 {
1155 document.getElementById("waveformxmin").setAttribute("disabled", "true");
1156 document.getElementById("waveformxmin").value = wf.xmin;
1157 xmin = wf.xmin-1;
1158 }
1159 else
1160 document.getElementById("waveformxmin").removeAttribute("disabled");
1161
1162 if (document.getElementById("waveformxmaxon").checked)
1163 {
1164 document.getElementById("waveformxmax").setAttribute("disabled", "true");
1165 document.getElementById("waveformxmax").value = wf.xmax;
1166 xmax = wf.xmax+1;
1167 }
1168 else
1169 document.getElementById("waveformxmax").removeAttribute("disabled");
1170
1171 if (document.getElementById("waveformminon").checked)
1172 {
1173 document.getElementById("waveformmin").setAttribute("disabled", "true");
1174 document.getElementById("waveformmin").value = wf.ymin;
1175 ymin = wf.ymin-5;
1176 }
1177 else
1178 document.getElementById("waveformmin").removeAttribute("disabled");
1179
1180 if (document.getElementById("waveformmaxon").checked)
1181 {
1182 document.getElementById("waveformmax").setAttribute("disabled", "true");
1183 document.getElementById("waveformmax").value = wf.ymax;
1184 ymax = wf.ymax+5;
1185 }
1186 else
1187 document.getElementById("waveformmax").removeAttribute("disabled");
1188
1189 setZoom(xmin, xmax, ymin, ymax);
1190}
1191
1192//document.addEventListener("click", getClickPosition, false);
1193
1194$(document).ready(onReady);
1195
1196// ================================== Pixel mapping =================================================
1197
1198var map = new Array(1440);
1199
1200function initPixelMap()
1201{
1202 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:";
1203 // first: decode the pixel mapping!
1204 var sum = 1036080;
1205 for (var i=0; i<1440; i++)
1206 {
1207 var d0 = codedMap.charCodeAt(i*2) -48;
1208 var d1 = codedMap.charCodeAt(i*2+1)-48;
1209
1210 map[i] = d0 | (d1<<6);
1211 sum -= map[i];
1212 }
1213 if (sum!=0)
1214 alert("Pixel mapping table corrupted!");
1215}
1216
1217initPixelMap();
1218
1219// ================================== Camera Display ================================================
1220
1221var coord = new Array(1440);
1222function initCameraCoordinates()
1223{
1224 coord[0] = [0, 0];
1225 var cnt = 1;
1226 for (var ring=1; ring<24; ring++)
1227 {
1228 for (var s=0; s<6; s++)
1229 {
1230 for (var i=1; i<=ring; i++)
1231 {
1232 var pos = new Position(s, ring, i);
1233 if (pos.d() - pos.x > 395.75)
1234 continue;
1235
1236 coord[cnt++] = [ pos.x, pos.y];
1237 }
1238 }
1239 }
1240
1241 coord[1438] = [7, -22];
1242 coord[1439] = [7, 22];
1243}
1244
1245initCameraCoordinates();
1246
1247function getIndex(id, mouse)
1248{
1249 var canv = document.getElementById(id);
1250
1251 var scale = 83;
1252
1253 var w = Math.min(canv.width/scale, canv.height/scale);
1254
1255 //ctx.translate(canv.width/2, canv.height/2);
1256 //ctx.scale(w*2, w*2);
1257 //ctx.scale(1, Math.sqrt(3)/2);
1258 //ctx.translate(-0.5, 0);
1259
1260 mouse.x -= canv.width/2;
1261 mouse.y -= canv.height/2;
1262 mouse.x /= w*2;
1263 mouse.y /= w*2;
1264 mouse.y /= Math.sqrt(3)/2;
1265 mouse.x -= -0.5;
1266
1267 for (var i=0; i<1440; i++)
1268 if (isInside(coord[i][0], coord[i][1], mouse))
1269 return i;
1270
1271 return -1;
1272}
1273
1274
1275function hueToRGB(hue)
1276{
1277 hue /= 3;
1278 hue %= 6;
1279
1280 if (hue<1) return parseInt(255*hue, 10);
1281 if (hue<3) return parseInt(255, 10);
1282 if (hue<4) return parseInt(255*(4-hue), 10);
1283
1284 return 0.
1285}
1286
1287function hueToHex(flt)
1288{
1289 var s = hueToRGB(flt).toString(16);
1290 return s.length==2 ? s : "0"+s;
1291}
1292
1293function HLStoRGB(hue)
1294{
1295 if (isNaN(hue))
1296 return "fff";
1297
1298 if (hue<0)
1299 return "eef"; // 555
1300
1301 if (hue>1)
1302 return "dde";//"700"; // 666
1303
1304 hue *= 14;
1305
1306 var sr = hueToHex(20-hue);
1307 var sg = hueToHex(14-hue);
1308 var sb = hueToHex(26-hue);
1309
1310 return sr+sg+sb;
1311}
1312
1313function outlineHex(ctx)
1314{
1315 ctx.scale(1/2, 1/3);
1316
1317 ctx.beginPath();
1318 ctx.moveTo( 1, 1);
1319 ctx.lineTo( 0, 2);
1320 ctx.lineTo(-1, 1);
1321 ctx.lineTo(-1, -1);
1322 ctx.lineTo( 0, -2);
1323 ctx.lineTo( 1, -1);
1324 ctx.lineTo( 1, 1);
1325}
1326
1327function fillHex(ctx, i, col, min, max)
1328{
1329 if (col===undefined/* || col===null*/)
1330 return false;
1331
1332 var lvl = max==min ? 0.5 : (col-min)/(max-min);
1333
1334 ctx.fillStyle = "#"+HLStoRGB(lvl);
1335
1336 ctx.save();
1337 ctx.translate(coord[i][0], coord[i][1]);
1338 outlineHex(ctx);
1339 ctx.fill();
1340 ctx.restore();
1341
1342 return true;
1343}
1344
1345function drawHex(ctx, i)
1346{
1347 ctx.save();
1348 ctx.translate(coord[i][0], coord[i][1]);
1349 outlineHex(ctx);
1350 ctx.stroke();
1351 ctx.restore();
1352}
1353
1354
1355function Position(s, ring, i)
1356{
1357 switch (s)
1358 {
1359 case 1: this.x = ring - i*0.5; this.y = + i; break;
1360 case 2: this.x = ring*0.5 - i; this.y = ring ; break;
1361 case 3: this.x = -ring*0.5 - i*0.5; this.y = ring - i; break;
1362 case 4: this.x = -ring + i*0.5; this.y = - i; break;
1363 case 5: this.x = -ring*0.5 + i; this.y = -ring ; break;
1364 case 0: this.x = ring*0.5 + i*0.5; this.y = -ring + i; break;
1365 }
1366 this.d = (function () { return this.x*this.x + this.y*this.y*3/4; });
1367}
1368
1369function drawFullCam(id)
1370{
1371 var canv = document.getElementById(id);
1372 if (!canv)
1373 return;
1374
1375 var ctx = canv.getContext("2d");
1376
1377 ctx.clearRect(0, 0, canv.width, canv.height);
1378
1379 // ======================= Draw Graphics ======================
1380
1381 var data = canv.dataRel;
1382 if (!data)
1383 return;
1384
1385 var pixel = document.getElementById('pixel').value;
1386
1387 var min = (canv.zmin-canv.min)/canv.max;
1388 var max = (canv.zmax-canv.min)/canv.max;
1389
1390 var scale = 83;
1391
1392 var w = Math.min(canv.width/scale, canv.height/scale);
1393
1394 ctx.save();
1395 ctx.translate(canv.width/2, canv.height/2);
1396 ctx.scale(w*2, w*2);
1397 // ctx.rotate(Math.PI/3);
1398
1399 ctx.scale(1, Math.sqrt(3)/2);
1400 ctx.translate(-0.5, 0);
1401
1402 if (document.getElementById('grid').checked)
1403 {
1404 ctx.lineWidth = 0.02;
1405 ctx.strokeStyle = "#000";
1406 for (var i=0; i<1440; i++)
1407 drawHex(ctx, i);
1408 }
1409
1410 var hasData = false;
1411 if (max>=min)
1412 for (var i=0; i<1440; i++)
1413 hasData |= fillHex(ctx, i, data[i], min, max);
1414
1415 // ======================= Draw Ellipse ======================
1416
1417 if (document.getElementById('image').checked)
1418 {
1419 var h = Hillas(canv.dataAbs, canv.zmin, canv.zmax);
1420 if (h)
1421 {
1422 ctx.save();
1423
1424 ctx.scale(1, 2/Math.sqrt(3));
1425
1426 ctx.beginPath();
1427 ctx.moveTo(0.5, 0);
1428 ctx.lineTo(h.mean[0], h.mean[1]);
1429
1430 ctx.strokeStyle = "#CCC";
1431 ctx.lineWidth = 0.1;
1432 ctx.stroke();
1433
1434 ctx.translate(h.mean[0], h.mean[1]);
1435 ctx.rotate(h.phi);
1436
1437 ctx.beginPath();
1438 ctx.moveTo(0, -h.disp);
1439 ctx.lineTo(0, h.disp);
1440
1441 ctx.strokeStyle = "#888";
1442 ctx.lineWidth = 0.15;
1443 ctx.stroke();
1444
1445 ctx.save();
1446 ctx.scale(h.axis[0], h.axis[1]);
1447 ctx.beginPath();
1448 ctx.arc(0, 0, 1, 0, 2*Math.PI);
1449 ctx.restore();
1450
1451 ctx.strokeStyle = "#555";
1452 ctx.lineWidth = 0.15;
1453 ctx.stroke();
1454
1455 ctx.restore();
1456 }
1457 }
1458
1459 // =================== Draw Pixel marker ====================
1460
1461 if (document.getElementById('marker').checked)
1462 {
1463 // Draw marker
1464 ctx.lineWidth = 0.25;
1465 ctx.strokeStyle = "#000";
1466 drawHex(ctx, pixel);
1467 }
1468
1469
1470 ctx.restore();
1471
1472 if (!hasData)
1473 return;
1474
1475 // ======================= Draw Legend ======================
1476
1477 var v0 = parseFloat(canv.zmin);
1478 var v1 = parseFloat(canv.zmax);
1479
1480 var diff = v1-v0;
1481
1482 var cw = canv.width;
1483 //var ch = canv.height;
1484
1485 ctx.font = "8pt Arial";
1486 ctx.textAlign = "right";
1487 ctx.textBaseline = "top";
1488
1489 for (var i=0; i<11; i++)
1490 {
1491 ctx.strokeStyle = "#"+HLStoRGB(i/10);
1492 ctx.strokeText((v0+diff*i/10).toPrecision(3), cw-5, 125-i*12);
1493 }
1494
1495 var pval = parseFloat(canv.dataAbs[pixel]).toFixed(1);
1496 var lmin = parseFloat(canv.min).toFixed(1);
1497 var lmax = parseFloat(canv.max).toFixed(1);
1498
1499 if (isNaN(pval))
1500 pval = "";
1501
1502 var mw = Math.max(ctx.measureText(lmin).width,
1503 ctx.measureText(pval).width,
1504 ctx.measureText(lmax).width);
1505
1506 ctx.textBaseline = "top";
1507 ctx.strokeStyle = "#000";
1508
1509 ctx.strokeText(lmax, 5+mw, 5+24);
1510 ctx.strokeText(pval, 5+mw, 5+12);
1511 ctx.strokeText(lmin, 5+mw, 5);
1512}
1513
1514// ===================================================================
1515
1516function Hillas(data, min, max)
1517{
1518 var mx = 0;
1519 var my = 0;
1520 var sz = 0;
1521
1522 var mx2 = 0;
1523 var my2 = 0;
1524 var mxy = 0;
1525
1526 var cnt = 0;
1527 for (var i=0; i<1440; i++)
1528 {
1529 if (data[i]===undefined || data[i]<min || data[i]>max)
1530 continue;
1531
1532 sz += data[i];
1533 mx += data[i] * coord[i][0];
1534 my += data[i] * coord[i][1];
1535
1536 mx2 += data[i] * coord[i][0]*coord[i][0];
1537 my2 += data[i] * coord[i][1]*coord[i][1];
1538 mxy += data[i] * coord[i][0]*coord[i][1];
1539
1540 cnt++;
1541 }
1542
1543 if (sz==0 || cnt<3)
1544 return;
1545
1546 // Coordinates need to be scaled in y
1547 var f = Math.sqrt(3)/2;
1548
1549 my *= f;
1550 mxy *= f;
1551 my2 *= f*f;
1552
1553 var xx = mx2 - mx*mx/sz;
1554 var yy = my2 - my*my/sz;
1555 var xy = mxy - mx*my/sz;
1556
1557 var d0 = yy - xx;
1558 var d1 = xy*2;
1559 var d2 = Math.sqrt(d0*d0 + d1*d1) + d0;
1560
1561 var phi = 0;
1562 var cos = 0;
1563 var sin = 1;
1564
1565 var axis1 = yy;
1566 var axis2 = xx;
1567
1568 // Correction for scale in x
1569 var ratio = xx/yy;
1570
1571 if (d1!=0 || d2==0)
1572 {
1573 var tand = d2==0 ? 0 : d2 / d1;
1574 var tand2 = tand*tand;
1575
1576 var s2 = tand2+1;
1577 var s = Math.sqrt(s2);
1578
1579 phi = Math.atan(tand)-Math.PI/2;
1580 cos = 1.0 /s;
1581 sin = tand/s;
1582
1583 axis1 = (tand2*yy + d2 + xx);
1584 axis2 = (tand2*xx - d2 + yy);
1585
1586 ratio = axis2/axis1;
1587
1588 axis1 /= s2;
1589 axis2 /= s2;
1590 }
1591
1592 var length = axis1<0 ? 0 : Math.sqrt(axis1/sz);
1593 var width = axis2<0 ? 0 : Math.sqrt(axis2/sz);
1594
1595 return {
1596 "mean": [ mx/sz, my/sz ],
1597 "axis": [ width, length ],
1598 "phi": phi,
1599 "delta": [ cos, sin ],
1600 "sumw": sz,
1601 "count": cnt,
1602 "disp": 1.47/0.1111*(1-Math.sqrt(ratio)),
1603 };
1604}
Note: See TracBrowser for help on using the repository browser.