Commit df0863dc authored by Caillat Michel's avatar Caillat Michel
Browse files

Refactored the code. Mostly created wrappers for viewers

parent 92ffa4a3
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<script src="https://kit.fontawesome.com/33cc1a1919.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<!--script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"
integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script src="https://code.highcharts.com/modules/boost.js"></script>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css">
<link rel="stylesheet" type="text/css" href="/stylesheets/overlay.css">
<link rel="stylesheet" type="text/css" href="/stylesheets/olqv.css">
<script src="../javascript/FITSHeaderTable.js"></script>
<script src="../javascript/olqv_utils.js"></script>
<script src="../javascript/olqv_customcontrols.js"></script>
<script src="../javascript/olqv_infosblock.js"></script>
<script src="../javascript/olqv_reset.js"></script>
<script src="../javascript/olqv_settings.js"></script>
<script src="../javascript/olqv_shapes.js"></script>
<script src="../javascript/olqv_contours.js"></script>
<script src="../javascript/olqv_samp_publisher.js"></script>
<script src="../javascript/olqv_boxes.js"></script>
<script src="../javascript/olqv_markers.js"></script>
<script src="../javascript/olqv_keyboardevents.js"></script>
<script src="../javascript/olqv_viewer.js"></script>
<script src="../javascript/olqv_lastclickinfos.js"></script>
<!-- <script src="https://openlayers.org/en/v4.6.4/build/ol.js" type="text/javascript"></script> -->
<!-- Conditional code generation -->
<!-- <%if(useSAMP){%> -->
<script src="../javascript/samp.js"></script>
<script src="../javascript/samp_utils.js"></script>
<!-- <%}%> -->
<!-- End of conditional code generation -->
</head>
<body>
<div id="loading"></div>
<div id="FITSHDR" class="overlay" style="overflow:scroll"></div>
<div class="pos-f-t">
<div class="collapse" id="sampRegistry"></div>
<div class="collapse" id="navbarToggleExternalContent">
<div class="p-4">
<% if (renderingCapabilities) { %>
<nav class="navbar navbar-light bg-light">
<ul class="list-group list-group-horizontal img-configuration">
<li class="list-group-item ">
<label for="LUTSelector">LUTs</label>
<select name="LUTs" class="form-control" id="LUTSelector">
<% renderingCapabilities["luts"].forEach(function(lut) { %>
<option> <%=lut%></option>
<% }) %>
</select>
</li>
<li class="list-group-item ">
<label for="ITTSelector">ITTs</label>
<select class="form-control" id="ITTSelector">
<% renderingCapabilities["itts"].forEach(function(itt) { %>
<option> <%=itt%></option>
<% }) %>
</select>
</li>
<li class="list-group-item ">
<label for="VideoModeSelector">Video mode</label>
<select class="form-control" id="VideoModeSelector">
<% renderingCapabilities["vmodes"].forEach(function(vmode) { %>
<option> <%=vmode%></option>
<% }) %>
</select>
</li>
<li class="list-group-item">
<button id="rccap" class="btn btn-default btn-control">Apply</button>
</li>
</ul>
</nav>
</div>
<%}%>
</div>
</div>
<div><div id="cubeInfos" class="cube-infos"></div></div>
<nav class="navbar navbar-light navbar-title">
<button class="navbar-toggler" type="button"
data-toggle="collapse" data-target="#navbarToggleExternalContent"
aria-controls="navbarToggleExternalContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!--<div><a id="jupyter" href="#" target="_blank"><img src="../jupyter.png" style="width:30px; height:30px" title="jupyter"/></a></div>-->
<a href="#" class="btn btn-link btn-sm" onclick="viewIn3D(); return false;"> Show 3D model </a>
<div><a href="http://artemix.obspm.fr/fits/browse" target="_blank" class="btn btn-link btn-sm">Show Fits file browser</a></div>
<div><a id='showFITSHEADER' href='#'>Show FITS header</a></div>
<img src="../samphub.png" class="samp-img"
data-toggle="collapse" data-target="#sampRegistry" title="Transfer data to another application with SAMP protocol"
aria-controls="sampRegistry" aria-expanded="false" aria-label="Toggle navigation"/>
</nav>
</div>
<div class="container chart-container">
<div class="row">
<div class="col">
<!-- <div id="external_mouse_position_1_" class="external_mouse_position_"></div> -->
<div id="infos_line_1" class="infos_line">&nbsp;</div>
</div>
<div class="col">
<div id="spectrum_info_title" class="chart-title"></div>
</div>
</div>
<div class="row">
<div class="col chart-img">
<div id="slice" class="map" style="background-color:darkblue"></div>
</div>
<div class="col chart-plot">
<div id="spectrum"></div>
</div>
<div class="col">
<div>
<p><button id="zoomin" class="btn btn-default btn-control">Zoom in</button></p>
<p><button id="zoomout" class="btn btn-default btn-control">Zoom out</button></p>
<p><button id="zoomreset" class="btn btn-default btn-control">Reset</button></p>
<div id="publish_spectrum"></div>
</div>
</div>
</div>
<div class="row">
</div>
<div class="row">
<div class="col">
<!-- <div id="external_mouse_position_2_" class="external_mouse_position_"></div> -->
<div id="infos_line_2" class="infos_line">&nbsp;</div>
</div>
<div class="col">
<div class="chart-title">
<span id="chart_title"></span>
</div>
</div>
</div>
<div class="row">
<div class="col chart-img">
<div id="summedslices" class="map"></div>
</div>
<div class="col chart-plot">
<div id="summedpixelsspectrum"></div>
</div>
<div class="col">
<div id="publish_summedpixelsspectrum"></div>
</div>
</div>
</div>
<div class="container chart-container hidden">
<div class="row">
<div class="col">
<canvas id="hiddenSlice"></canvas>
</div>
<div class="col">
<canvas id="hiddenSummedSlices"></canvas>
</div>
</div>
</div>
<div class="hidden">
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
</div>
<!-- Modal for samp cassis-->
<div class="modal fade hidden" id="sampModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Send spectrum by SAMP (Cassis)</h4>
</div>
<div class="modal-body">
<p>
This link is intended to send the current artemix spectrum to Cassis tool,
or any other tool that runs with the SAMP protocol and accepts our file fits format.
</p>
<p>
For the transfer to work, Check that Cassis is running.
</p>
<h3>How to launch Cassis</h3>
<p>
<strong>- Cassis with command line:</strong>
</p>
<p>
Open a terminal and run: javaws http://cassis.irap.omp.eu/online/cassis.jnlp
</p>
<p>
<strong>- Cassis online:</strong>
</p>
<ul>
<li>1- Go to the Cassis <a href="http://cassis.irap.omp.eu/?page=installation"> website</a></li>
<li>2- Use Cassis online application or download the latest version </li>
</ul>
<p>
If you encounter a problem during the installation, check that you have the correct Java version
compatible with Cassis, and allow the installation in your computer.
Please read <a href="images/enablejava.png">here</a> on how to do with a Mac.
</p>
<p>
In case you encounter any problem with Cassis please contact the Cassis project manager <a href="#">Jean-Michel.Glorian{at}irap.omp.eu</a>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Modal for samp aladin -->
<div class="modal fade" id="sampModalAladin" role="dialog" style="display:none">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Send image by SAMP (Aladin)</h4>
</div>
<div class="modal-body">
<p>
This link is intended to send the current Artemix image to Aladin tool,
or any other tool that runs with the SAMP protocol and accepts our file png format.
</p>
<p>
For the transfer to work, Check that Aladin is running.
</p>
<p>
How to launch Aladin :
</p>
<p>
<strong>- Aladin with command line:</strong>
</p>
<p>
Open a terminal and run: javaws https://aladin.u-strasbg.fr/java/nph-aladin.pl
</p>
<p>
<strong>- Aladin online:</strong>
</p>
<ul>
<li>1- Go to the Aladin <a href="https://aladin.u-strasbg.fr/java/nph-aladin.pl?frame=downloading"> website</a></li>
<li>2- Use Aladin online application or download the latest version </li>
</ul>
<p>
If you encounter a problem during the installation, check that you have the correct Java version compatible with Aladin,
and allow the installation on your computer.
</p>
<p>
Please look <a href="images/enablejava.png">here</a> to know how to do with MacOS.
</p>
<p>
If you encouter any problem with Aladin please contact the Aladin team AT <a href="#"> unistra.fr?Subject=Aladin</a>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
<script>
var ENTER = function () { console.log(arguments.callee.name + ": entering."); };
var EXIT = function () { console.log(arguments.callee.name + ": exiting."); };
const PLOT_WIDTH = 780;
const PLOT_RATIO = "65%";
const PLOT_COLOR = "#F5F101";
/*<%if (useSAMP) {%>*/
var sAMPPublisher = null;
/*<%}%>*/
var ROI;
var summedPixelsSpectrumChart;
var spectrumChart;
var viewIn3D = function () {
window.open("getYtObj?relFITSFilePath=" + relFITSFilePath + "&iRA0=" + ROI.iRA0 + "&iRA1=" + ROI.iRA1 + "&iDEC0=" + ROI.iDEC0 + "&iDEC1=" + ROI.iDEC1 + "&iFREQ0=" + ROI.iFREQ0 + "&iFREQ1=" + ROI.iFREQ1);
};
var showLoaderAction = function (enable) {
if (enable) {
document.getElementById('loading').style.display = 'block';
} else {
document.getElementById('loading').style.display = 'none';
}
}
var handleEvent = function (evt) {
console.log(JSON.stringify(evt, null, 4));
return true;
};
/**
Add a series where Y=0 in the given chart
*/
function addYAxisSeries(chart) {
chart.addSeries({
lineWidth: 1,
enableMouseTracking: false,
showInLegend: false,
color: "#000000",
marker: {
enabled: false
},
data: [[chart.xAxis[0].dataMin, 0], [chart.xAxis[0].dataMax, 0]]
});
}
/**
Returns index of slice to be displayed
plotData : spectrum
x : x position clicked on graph
*/
function computeSliceIndex(plotData, x) {
var rlen = plotData.x.length;
switch (ctype3) {
case 'FREQ':
if (cdelt3 > 0) {
var forigin = plotData.x[rlen - 1];
var deltaf = plotData.x[0] - plotData.x[1];
}
else {
var forigin = plotData.x[0];
var deltaf = plotData.x[1] - plotData.x[0];
}
break;
case 'VRAD':
case 'WAVE':
case 'WAVN':
case 'AWAV':
if (cdelt3 > 0) {
var forigin = plotData.x[0];
var deltaf = plotData.x[1] - plotData.x[0];
}
else {
var forigin = plotData.x[rlen - 1];
var deltaf = plotData.x[0] - plotData.x[1];
}
break;
default:
console.log("This should not happen");
}
return phys2Index(x, forigin, deltaf);
}
/**
calculate the value displayed as title of summed average spectrum
avgSpectrum array is reversed if data are radial velocities and
cdelt3 < 0
*/
function getSummedSpectrumTitle(avgSpectrum, imin, imax, cdelt3prim) {
var result = 0;
if (ctype3 === 'VRAD' && cdelt3 < 0) {
var copy = (x) => x;
var arraycopy = avgSpectrum.map(copy);
result = sumArr(arraycopy.reverse(), imin, imax, cdelt3prim);
} else {
result = sumArr(avgSpectrum, imin, imax, cdelt3prim);
}
return result / unitRescale(summedPixelsSpectrumUnit(bunit));
}
function getCalculatedIndex(value) {
var result = 0;
if (ctype3 === 'VRAD') {
var step1 = (unitFactor[defaultOutputUnit[ctype3]] / unitFactor[getCunit3()]) / cdelt3;
result = Math.abs(value * step1) - crval3 + crpix3 - 1;
} else if (ctype3 === 'FREQ') {
// if ctype is FREQ we have to read defaultOutputUnit['VRAD']
var step1 = v2f(value * unitFactor[defaultOutputUnit['VRAD']], restfreq);
var step2 = (step1 - crval3) / cdelt3;
result = step2 + crpix3 - 1;
}
return Math.round(result);
}
/*function jyToK(flux) {
var kb = 1.380649e-23;
var sec = 4.8481368110954e-06;
var factor = 1 / (2 * kb * ((crval3 / speedOfLight) ** 2) * ((bmaj * bmin * sec * sec * Math.PI / 4 / Math.log(2)) / 1e-26));
return flux * factor;
}*/
function janskyPerKelvin() {
var kb = 1.380649e-23;
var bmin = degToRad(bmin);
var bmax = degToRad(bmaj);
lambda = null;
if (origin.startsWith("GILDAS")) {
lambda = speedOfLight / restfreq;
} else {
lambda = speedOfLight / crval3;
}
var omega = Math.PI * bmin * bmax / 4 / Math.log(2);
step1 = 2 * kb * omega / (lambda * lambda);
var result = step1 / 1e-26;
return result;
}
function kelvinPerJansky() {
var jperk = janskyPerKelvin();
var result = 1. / jperk;
return result;
}
function arcsecToDeg(arcsec) {
return arcsec / 3600;
}
function degToArcsec(deg) {
return deg * 3600;
}
function degToRad(deg) {
return deg * (Math.PI / 180);
}
//
// A object to mark informations related to a position
// in a popup bow located close to the position passed
// as a parameter.
//
function LastClickMarker(map) {
var _map = map;
var _overlay = null;
var _container = document.getElementById('popup');
var _content = document.getElementById('popup-content');
var _closer = document.getElementById('popup-closer');
var _lastChanIndex = null;
var _lastCoordinate = null;
var _lastRADEC = null;
var _lastFluxDensity = null;
// popup creation and addition to an ol overlay to the map passed
// as a parameter.
//
var _popupLastClickInfos = function () {
if (_overlay == null) {
/**
* Create an overlay to anchor the popup to the map.
*/
_overlay = new ol.Overlay({
element: _container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
/**
* Add a click handler to hide the popup.
* @return {boolean} Don't follow the href.
*/
_closer.onclick = function () {
_overlay.setPosition(undefined);
_closer.blur();
return false;
};
_map.addOverlay(_overlay);
}
};
//
// update the content of the popup by using the informations
// stored in _lastCoordinate, _lastRADEC and _lastFluxDensity
//
var _updateLastClickInfos = function () {
if (_lastCoordinate == null) return;
_content.innerHTML = 'Chan#' + _lastChanIndex + '<br>' + 'x = '
+ _lastCoordinate[0].toFixed(0)
+ ', y = '
+ _lastCoordinate[1].toFixed(0) + '<br>' +
'RA=' + _lastRADEC['RA'] + '<br>' +
'DEC=' + _lastRADEC['DEC'] + '<br>' +
'Value=' + Number(_lastFluxDensity).toExponential(4);
_overlay.setPosition(_lastCoordinate);
}
//
// public method to register the values to be displayed
// in the popup and update its content.
//
this.setPositionAndFluxDensity = function (data) {
console.log("this.setPosition = function(coordinate) { : entering");
_lastChanIndex = data["chanIndex"]
_lastCoordinate = data["coordinate"];
_lastRADEC = data["RADEC"];
_lastFluxDensity = data["fluxDensity"];
_updateLastClickInfos();
console.log("this.setPosition = function(coordinate) { : exiting");
};
//
// public method to register the fluxDensity value passed as a parameter
// and update the popup content accordingly.
//
this.setFluxDensity = function (fluxDensity, sliceIndex) {
console.log("this.setFluxDensity = function(fluxDensity) { : entering");
_lastFluxDensity = fluxDensity;
_lastChanIndex = sliceIndex;
_updateLastClickInfos();
console.log("this.setFluxDensity = function(fluxDensity) { : exiting");
};
// create our popup.
_popupLastClickInfos();
};
/*
** A function to start/stop an hold-on animation while
** an image is prepared by the server until it serves it to the client.
** This function is dedicated to be passed a the value
** of the option imageLoadFunction of an ImageStatic constructor.
**
*/
var _image = null;
function _onProgress(event) {
if (event.lengthComputable) {
var percentComplete = (event.loaded / event.total) * 100;
console.log("Transfert: %d%%", percentComplete);
} else {
// Impossible de calculer la progression puisque la taille totale est inconnue
}
}
function _onError(event) {
console.error("Error " + event.target.status + " during the transfert.");
}
function _onLoad(event) {
// Ici, this.readyState XMLHttpRequest.DONE .
if (this.status === 200) {
console.log("Transfert done - " + this.responseText.length + "bytes.");
var _srcURI = "data:image/png," + this.responseText;
console.log("_srcURI=" + _srcURI);
_image.getImage().src = _srcURI;
} else {
console.log("Response status: %d (%s)", this.status, this.statusText);
}
showLoaderAction(false);
}
var hidden_canvas_1 = document.getElementById("hiddenSlice");
var hidden_canvas_2 = document.getElementById("hiddenSummedSlices");
var SAMPPNGPublishControl = (function (Control) {
function SAMPPNGPublishControl(opt_options) {
var options = opt_options || {};
var button = document.createElement('button');
button.innerHTML = '&#8663';
var element = document.createElement('div');
element.className = 'samp-publish-png ol-unselectable ol-control';
element.appendChild(button);
Control.call(this, {
element: element,
target: options.target
});
this.handlePublish = function () { ; }
button.addEventListener('click', this.handlePublish.bind(this), false);
this.setHandler = function (handler) { console.log("Changing handler"); button.addEventListener('click', handler.bind(this), false) };
}
if (Control) SAMPPNGPublishControl.__proto__ = Control;
SAMPPNGPublishControl.prototype = Object.create(Control && Control.prototype);
SAMPPNGPublishControl.prototype.constructor = SAMPPNGPublishControl;
return SAMPPNGPublishControl;
}(ol.control.Control));
/*
** A class definition for the object in charge of displaying
** two imagee - one for a slice ( at a given frequency ), one for the sum of
** slices ( belonging to a frequency range) of a data cube.
*/
var _canvasContext_1 = null;