From e7b7d578e7810b4df38cdd4dc43603a9180e070c Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Sat, 4 Nov 2017 22:57:32 +0100 Subject: [PATCH 01/14] DAVE-347: Local permissions of DAVE, sudo not required anymore --- setup/setup.bash | 13 +++-- src/main/js/electron/main.js | 23 ++++---- src/main/resources/bash/create_env.bash | 54 ++++++++++++++----- .../resources/static/scripts/master_page.js | 13 +++-- src/main/resources/templates/splash_page.html | 22 +++++--- 5 files changed, 88 insertions(+), 37 deletions(-) diff --git a/setup/setup.bash b/setup/setup.bash index bc4553a..16e77d9 100755 --- a/setup/setup.bash +++ b/setup/setup.bash @@ -3,6 +3,11 @@ # Source this script to set up the environment for developing DAVE. # - Download miniconda and install packages and virtual env # - Download node and install packages +# - Install Python dependencies +# - Install Stingray and Astropy Helpers +# - Install Hendrics +# - Install LibMagic +# - Install node modules # First check if the script is being sourced... if [[ "${BASH_SOURCE[0]}" == "${0}" ]] ; then @@ -114,7 +119,7 @@ NODE_FILENAME="node-v$NODE_VERSION" fi fi - sudo installer -pkg $NODE_TAR -target / + installer -pkg $NODE_TAR -target / else # Unknown. @@ -220,12 +225,12 @@ if [ ! -e $STINGRAY_FOLDER ]; then # Mac OSX #Build stingray - sudo python setup.py install + python setup.py install cd $STINGRAY_FOLDER/astropy_helpers #Build astropy_helpers - sudo python setup.py install + python setup.py install cd $DIR/.. @@ -274,7 +279,7 @@ if [ ! -e $HENDRICS_FOLDER ]; then # Mac OSX #Build HENDRICS - sudo python setup.py install + python setup.py install cd $DIR/.. diff --git a/src/main/js/electron/main.js b/src/main/js/electron/main.js index 596a404..a3f6c88 100644 --- a/src/main/js/electron/main.js +++ b/src/main/js/electron/main.js @@ -8,6 +8,7 @@ var rq = require('request-promise'); var Config = require('config-js'); var Menu = require("menu"); var request = require('request'); +var fs = require('fs'); let mainWindow, windowParams = { @@ -85,7 +86,7 @@ function launchPythonServer(config, callback) { } else if (config.pythonEnabled) { launchProcess ("python", [config.pythonPath, '/tmp', '..', port, 'PY_ENV'], "Python"); } else if (config.envEnabled) { - launchProcess ("/bin/bash", [config.envScriptPath], "Env&Python"); + launchProcess ("/bin/bash", [config.envScriptPath], "E&P"); } if (callback != null) { @@ -261,15 +262,17 @@ function connectionLost (){ } function getTailFromLogFile (logFilePath) { - log('Getting log info from: ' + logFilePath, "Warn"); - var tailProc = cp.spawn("tail", [ "-10", logFilePath ]); - var stdout = ""; - tailProc.stdout.on('data', (data) => { - stdout += data; - }); - tailProc.on('close', (code) => { - log("LOGFILE: " + stdout); - }); + if (fs.existsSync(logFilePath)) { + log('Getting log info from: ' + logFilePath, "Warn"); + var tailProc = cp.spawn("tail", [ "-10", logFilePath ]); + var stdout = ""; + tailProc.stdout.on('data', (data) => { + stdout += data; + }); + tailProc.on('close', (code) => { + log("LOGFILE: " + stdout); + }); + } } function escapeSpecialChars (text) { diff --git a/src/main/resources/bash/create_env.bash b/src/main/resources/bash/create_env.bash index 70a797a..3ecf004 100644 --- a/src/main/resources/bash/create_env.bash +++ b/src/main/resources/bash/create_env.bash @@ -39,28 +39,58 @@ if [[ "$OSTYPE" == "darwin"* ]]; then #This is for MagicFile but only applies to macosx if [ ! -f /usr/local/bin/brew ]; then + # HomeBrew is not installed if hash /opt/local/bin/port 2>/dev/null; then + # MacPorts is installed + libmagic_lines_count=`/opt/local/bin/port echo installed 2>/dev/null | grep libmagic | wc -l` + if [[ $libmagic_lines_count -eq 0 ]]; then + # LibMagic not installed with MacPorts - # Make sure only root can run our script if [ "$(id -u)" != "0" ]; then - echo "You need Administrator privileges to continue with the installation." - echo "LibMagic will be installed with MacPorts, try relanching the application as root" - echo "or run this HomeBrew installation command on a terminal and relanch DAVE:" - echo '/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"' - sendError "Administrator privileges requiered" + # We don't have administrator rights, suggest how to proceed + echo "==========================================================================" + echo "LibMagic is required. There are three available options to continue:" + echo "==========================================================================" + echo "|" + echo "| 1 - Relaunch DAVE as root running this command on the terminal:" + echo "| sudo DAVEApp.app/Contents/MacOS/DAVEApp" + echo "|" + echo "| 2 - Or install LibMagic by yourself running this MacPorts command on the terminal and relanch DAVE:" + echo "| sudo /opt/local/bin/port install file" + echo "|" + echo "| 3 - Or run this HomeBrew installation command on a terminal and relanch DAVE:" + echo '| /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"' + echo "|" + echo "==========================================================================" + sendError "LibMagic is required, read the logs to proceed" + + else + # If we have administrator rights just install LibMagic + echo "Installing LibMagic with MacPorts" + sudo /opt/local/bin/port install file fi - echo "Installing LibMagic with MacPorts" - su /opt/local/bin/port install file + else + # LibMagic already installed with MacPorts + echo "LibMagic already installed with MacPorts" + fi else + # No MacPorts or HomeBrew is installed + echo "==========================================================================" echo "Please install HomeBrew or MacPorts before continue." - echo "Run this HomeBrew installation command on a terminal and relanch DAVE:" - echo '/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"' - echo "Or install MacPorts with this guide:" - echo 'https://www.macports.org/install.php' + echo "==========================================================================" + echo "|" + echo "| Run this HomeBrew installation command on a terminal and relanch DAVE:" + echo '| /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"' + echo "|" + echo "| Or install MacPorts with this guide:" + echo '| https://www.macports.org/install.php' + echo "|" + echo "==========================================================================" sendError "HomeBrew or MacPorts requiered" fi else + # HomeBrew is installed echo "Installing LibMagic with HomeBrew" /usr/local/bin/brew install libmagic fi diff --git a/src/main/resources/static/scripts/master_page.js b/src/main/resources/static/scripts/master_page.js index 13d622c..d44c739 100644 --- a/src/main/resources/static/scripts/master_page.js +++ b/src/main/resources/static/scripts/master_page.js @@ -9,12 +9,10 @@ $(document).ready(function () { gaTracker.sendPage("MasterPage"); window.onerror = function (errorMsg, url, lineNumber) { - logErr(errorMsg + ", line: " + lineNumber); - return false; + return uncaugthError(errorMsg + ", line: " + lineNumber); }; window.addEventListener("error", function (e) { - logErr(e.error.message); - return false; + return uncaugthError(e.error.message); }); theService = new Service(CONFIG.DOMAIN_URL); @@ -187,6 +185,13 @@ function hideWaitingDialogDelayed (delay) { }, delay); } +function uncaugthError(errorMsg) { + if (!errorMsg.toLowerCase().includes("invalid or unexpected token")){ + logErr(errorMsg + ", line: " + lineNumber); + } + return false; +} + function showError(errorMsg, exception, options) { if (isNull(errorMsg)) { errorMsg = "Something went wrong!"; } diff --git a/src/main/resources/templates/splash_page.html b/src/main/resources/templates/splash_page.html index ccb4346..82d0777 100644 --- a/src/main/resources/templates/splash_page.html +++ b/src/main/resources/templates/splash_page.html @@ -71,12 +71,10 @@ $(document).ready(function () { window.onerror = function (errorMsg, url, lineNumber) { - logErr(errorMsg + ", line: " + lineNumber); - return false; + return uncaugthError(errorMsg + ", line: " + lineNumber); }; window.addEventListener("error", function (e) { - logErr(e.error.message); - return false; + return uncaugthError(e.error.message); }); Logger.show(); @@ -96,12 +94,22 @@ return (value === undefined) || (value == null); } + function uncaugthError(errorMsg) { + if (!errorMsg.toLowerCase().includes("invalid or unexpected token")){ + logErr(errorMsg + ", line: " + lineNumber); + } + return false; + } + function showError(errorMsg) { var errorArr = errorMsg.split("|"); waitingDialog.show(errorArr[0], { progressType: "warning" }); - logErr("PYTHON SERVER LOG:"); - logError(errorArr[1], "LogError"); - gaTracker.sendEvent("SplashPage", "LogError", errorArr[1]); + if (errorArr[1].trim() != ""){ + logErr("PYTHON SERVER LOG:"); + logError(errorArr[1], "LogError"); + gaTracker.sendEvent("SplashPage", "LogError", JSON.stringify(errorArr[1])); + } + gaTracker.sendEvent("SplashPage", "showError", JSON.stringify(errorArr[0])); Logger.open(); } From 99b2d07f53cd90ad27c47e4bdd6fc4fef73e2a86 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Sat, 4 Nov 2017 23:06:42 +0100 Subject: [PATCH 02/14] Changed installation proccess on README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eb5923a..5787c45 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,9 @@ You will see that there's plenty left to do! NOTE: Mac OSX dependencies * At least Homebrew installed (http://brew.sh/) or MacPorts installed (https://www.macports.org) -* Administrator rights are required for using MacPorts, please run Dave using: sudo DAVEApp.app/Contents/MacOS/DAVEApp +* If MacPorts will be used, you have two available options: +* 1 - Install LibMagic by yourself running this MacPorts command `sudo /opt/local/bin/port install file` on the terminal and then launch DAVE running `DAVEApp.app/Contents/MacOS/DAVEApp`. +* 2 - Launch DAVE as root running this command on the terminal: `sudo DAVEApp.app/Contents/MacOS/DAVEApp` ## Contribute From 447dcbd34aee9a0ebba11a59eac1399902fa56f2 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Sun, 5 Nov 2017 12:30:36 +0100 Subject: [PATCH 03/14] Removed debuggin logs from get_phaseogram --- src/main/python/utils/dave_engine.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index 2cc7666..121dc2b 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -1731,13 +1731,8 @@ def get_phaseogram(src_destination, bck_destination, gti_destination, filters, a profile = np.sum(phaseogr, axis=1) mean_profile = np.mean(profile) if np.all(mean_phases < 1.5): - logging.debug("np.all < 1.5") mean_phases = np.concatenate((mean_phases, mean_phases + 1)) profile = np.concatenate((profile, profile)) - logging.debug("mean_phases:" + str(mean_phases.shape)) - logging.debug("mean_phases data:" + str(mean_phases)) - logging.debug("profile:" + str(profile.shape)) - logging.debug("profile data:" + str(profile)) err_low, err_high = poisson_conf_interval(mean_profile, interval='frequentist-confidence', sigma=1) error_dist = [err_low, err_high] From b3c3bf1b8ded24a3b212f91344ecf282a69378ac Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Sat, 11 Nov 2017 01:46:55 +0100 Subject: [PATCH 04/14] DAVE-292: Give numbers for the phaseogram --- setup/setup.bash | 8 +- src/main/python/server.py | 8 +- src/main/python/utils/dave_endpoint.py | 8 +- src/main/python/utils/dave_engine.py | 38 ++- src/main/resources/static/scripts/config.js | 3 +- .../resources/static/scripts/master_page.js | 2 +- .../static/scripts/plots/freqRangePlot.js | 94 ++++++ .../resources/static/scripts/plots/pdsPlot.js | 2 +- .../resources/static/scripts/plots/phPlot.js | 81 ++++- .../static/scripts/plots/plotWithSettings.js | 6 +- .../resources/static/scripts/projectConfig.js | 1 + .../static/scripts/selectors/binSelector.js | 1 + .../static/scripts/tabPanels/phTabpanel.js | 312 +++++++++++++++++- .../static/scripts/tabPanels/wfTabpanel.js | 2 +- .../static/scripts/tabPanels/xsTabpanel.js | 4 + .../resources/static/scripts/toolpanel.js | 2 +- .../templates/includes/output_panel.html | 1 + 17 files changed, 537 insertions(+), 36 deletions(-) create mode 100644 src/main/resources/static/scripts/plots/freqRangePlot.js diff --git a/setup/setup.bash b/setup/setup.bash index 16e77d9..757d10b 100755 --- a/setup/setup.bash +++ b/setup/setup.bash @@ -174,8 +174,8 @@ source activate dave STINGRAY_FOLDER=$DIR/stingray STINGRAY_URL=https://github.com/StingraySoftware/stingray.git # Sets the specific commit to checkout: -# Oct 22th, 2017 -> https://github.com/StingraySoftware/stingray/commit/b64aceb3197062ffd65bfd735ebff190a34e1066 -STINGRAY_COMMIT_HASH=b64aceb3197062ffd65bfd735ebff190a34e1066 +# Nov 7th, 2017 -> https://github.com/StingraySoftware/stingray/commit/0870c2051dadd9fd921fe286132971eb31b6a199 +STINGRAY_COMMIT_HASH=0870c2051dadd9fd921fe286132971eb31b6a199 LINUX_COMPILATION=lib.linux-x86_64-3.5 DARWIN_COMPILATION=lib.macosx-10.5-x86_64-3.5 @@ -244,8 +244,8 @@ fi HENDRICS_FOLDER=$DIR/hendrics HENDRICS_URL=https://github.com/StingraySoftware/HENDRICS.git # Sets the specific commit to checkout: -# Oct 20th, 2017 -> https://github.com/StingraySoftware/HENDRICS/commit/9c4f95ec30837bc0bc8077b369e4957bcccefb16 -HENDRICS_COMMIT_HASH=9c4f95ec30837bc0bc8077b369e4957bcccefb16 +# Oct 27th, 2017 -> https://github.com/StingraySoftware/HENDRICS/commit/53ebffd826583027acc7ccad565029babd08d24d +HENDRICS_COMMIT_HASH=53ebffd826583027acc7ccad565029babd08d24d if [ ! -e $HENDRICS_FOLDER ]; then diff --git a/src/main/python/server.py b/src/main/python/server.py index c53af08..15d5853 100644 --- a/src/main/python/server.py +++ b/src/main/python/server.py @@ -284,10 +284,16 @@ def get_pulse_search(): @app.route('/get_phaseogram', methods=['POST']) def get_phaseogram(): + + binary_params= None + if "binary_params" in request.json: + binary_params = request.json['binary_params'] + return DaveEndpoint.get_phaseogram(request.json['filename'], request.json['bck_filename'], request.json['gti_filename'], UPLOADS_TARGET, request.json['filters'], request.json['axis'], float(request.json['dt']), - float(request.json['f']), int(request.json['nph']), int(request.json['nt'])) + float(request.json['f']), int(request.json['nph']), int(request.json['nt']), + float(request.json['fdot']), float(request.json['fddot']), binary_params) # Receives a message from client and send it to all subscribers diff --git a/src/main/python/utils/dave_endpoint.py b/src/main/python/utils/dave_endpoint.py index 22a23e2..ac75b97 100644 --- a/src/main/python/utils/dave_endpoint.py +++ b/src/main/python/utils/dave_endpoint.py @@ -826,7 +826,8 @@ def get_pulse_search(src_filename, bck_filename, gti_filename, target, def get_phaseogram(src_filename, bck_filename, gti_filename, target, - filters, axis, dt, f, nph, nt): + filters, axis, dt, f, nph, nt, fdot=0, fddot=0, + binary_parameters=None): src_destination = get_destination(src_filename, target) if not src_destination: @@ -853,9 +854,12 @@ def get_phaseogram(src_filename, bck_filename, gti_filename, target, logging.debug("get_phaseogram: f %s" % f) logging.debug("get_phaseogram: nph %s" % nph) logging.debug("get_phaseogram: nt %s" % nt) + logging.debug("get_phaseogram: fdot %s" % fdot) + logging.debug("get_phaseogram: fddot %s" % fddot) + logging.debug("get_phaseogram: binary_parameters %s" % binary_parameters) data = DaveEngine.get_phaseogram(src_destination, bck_destination, gti_destination, - filters, axis, dt, f, nph, nt) + filters, axis, dt, f, nph, nt, fdot, fddot, binary_parameters) logging.debug("get_phaseogram: Finish!") diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index 121dc2b..c1a5f74 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -590,7 +590,7 @@ def get_power_density_spectrum(src_destination, bck_destination, gti_destination logging.error(ExHelper.getException('get_power_density_spectrum')) help_msg = "" if len(freq) == 0 and pds_type != 'Sng': - help_msg = " Try with PDSType: Single." + help_msg = " Try with PDSType: Single or a smaller segment length." warnmsg = [ExHelper.getWarnMsg() + help_msg] # Preapares the result @@ -845,7 +845,7 @@ def get_cross_spectrum(src_destination1, bck_destination1, gti_destination1, fil logging.error(ExHelper.getException('get_cross_spectrum')) help_msg = "" if len(freq) == 0 and xds_type != 'Sng': - help_msg = " Try with PDSType: Single." + help_msg = " Try with PDSType: Single a smaller segment length." warnmsg = [ExHelper.getWarnMsg() + help_msg] # Preapares the result @@ -1647,6 +1647,9 @@ def get_pulse_search(src_destination, bck_destination, gti_destination, filters, # Gets time data time_data = np.array(ds.tables[axis[0]["table"]].columns[axis[0]["column"]].values) + tseg = np.median(np.diff(time_data)) + logging.debug("tseg: " + str(tseg)) + # We will search for pulsations over a range # of frequencies around the known pulsation period. @@ -1697,7 +1700,7 @@ def get_pulse_search(src_destination, bck_destination, gti_destination, filters, # @param: nt: Number of time bins. # def get_phaseogram(src_destination, bck_destination, gti_destination, filters, axis, - dt, f, nph, nt): + dt, f, nph, nt, fdot=0, fddot=0, binary_parameters=None): phaseogr = [] phases = [] times = [] @@ -1721,9 +1724,33 @@ def get_phaseogram(src_destination, bck_destination, gti_destination, filters, a if DsHelper.is_lightcurve_dataset(ds): weights = np.array(ds.tables["RATE"].columns["RATE"].values) - # Calculate the phaseogram plot data + # Prepares the phaseogram parameters time_data = np.array(ds.tables[axis[0]["table"]].columns[axis[0]["column"]].values) - phaseogr, phases, times, additional_info = phaseogram(time_data, f, nph=nph, nt=nt, weights=weights) + + pepoch = None + if len(ds.tables["GTI"].columns["START"].values) > 0: + pepoch = ds.tables["GTI"].columns["START"].values[0] + + delay_times = 0 + orbital_period = time_data[-1] - time_data[0] + asini = 0 + t0 = pepoch + prev_t0 = 0 + if not binary_parameters is None: + if binary_parameters[0] > 0: + orbital_period=binary_parameters[0] + if binary_parameters[1] > 0: + asini=binary_parameters[1] + if binary_parameters[2] > 0: + t0=binary_parameters[2] + delay_times = asini * np.sin(2 * np.pi * (time_data - t0) / orbital_period) + + corrected_times = time_data - delay_times + + # Calculate the phaseogram plot data + phaseogr, phases, times, additional_info = phaseogram(corrected_times, f, nph=nph, nt=nt, + fdot=fdot, fddot=fddot, plot=False, + pepoch=pepoch, weights=weights) phaseogr = np.transpose(phaseogr) # Calculates the profile plot data @@ -1736,6 +1763,7 @@ def get_phaseogram(src_destination, bck_destination, gti_destination, filters, a err_low, err_high = poisson_conf_interval(mean_profile, interval='frequentist-confidence', sigma=1) error_dist = [err_low, err_high] + except: logging.error(ExHelper.getException('get_phaseogram')) return common_error(ExHelper.getWarnMsg()) diff --git a/src/main/resources/static/scripts/config.js b/src/main/resources/static/scripts/config.js index 787d5a4..7fec2af 100644 --- a/src/main/resources/static/scripts/config.js +++ b/src/main/resources/static/scripts/config.js @@ -68,6 +68,7 @@ CONFIG = { BASELINE_COLOR: '#DD3333', MEANFLUX_COLOR: '#3333DD', CANDIDATE_FREQ_COLOR: '#DD3333', - AGN_COLORS: ['#20b378', '#6fb320', '#cc8d10', '#cc2610', '#cc10a6'] + AGN_COLORS: ['#20b378', '#6fb320', '#cc8d10', '#cc2610', '#cc10a6'], + PHASEOGRAM_LINE_COLOR: '#dddddd' } } diff --git a/src/main/resources/static/scripts/master_page.js b/src/main/resources/static/scripts/master_page.js index d44c739..3c835ae 100644 --- a/src/main/resources/static/scripts/master_page.js +++ b/src/main/resources/static/scripts/master_page.js @@ -187,7 +187,7 @@ function hideWaitingDialogDelayed (delay) { function uncaugthError(errorMsg) { if (!errorMsg.toLowerCase().includes("invalid or unexpected token")){ - logErr(errorMsg + ", line: " + lineNumber); + logErr(errorMsg); } return false; } diff --git a/src/main/resources/static/scripts/plots/freqRangePlot.js b/src/main/resources/static/scripts/plots/freqRangePlot.js new file mode 100644 index 0000000..bff5709 --- /dev/null +++ b/src/main/resources/static/scripts/plots/freqRangePlot.js @@ -0,0 +1,94 @@ +//Frequency range selector plot + +function FreqRangePlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlotReadyFn, toolbar, cssClass, switchable, projectConfig, plotStyle) { + + var currentObj = this; + plotConfig.freq_range = [-1, -1]; + plotConfig.default_freq_range = [-1, -1]; + plotConfig.selected_freq_range = [-1, -1]; + + PDSPlot.call(this, id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlotReadyFn, toolbar, cssClass, switchable, projectConfig); + + this.plotStyle = !isNull(plotStyle) ? plotStyle : null; + this.ls_opts = {}; + this.ls_opts.samples_per_peak = { default:5, min:1, max: 100}; //Samples per peak for LombScargle method + this.ls_opts.nyquist_factor = { default:1, min:1, max: 100}; //The nyquist factor for LombScargle method + + this.plotConfig.xAxisType = "linear"; + this.plotConfig.yAxisType = "log"; + this.plotConfig.plotType = "X"; + this.plotConfig.ls_norm = "standard"; + this.plotConfig.samples_per_peak = this.ls_opts.samples_per_peak.default; + this.plotConfig.nyquist_factor = this.ls_opts.nyquist_factor.default; + + this.getDefaultFreqRange = function (){ + if (this.plotConfig.default_freq_range[0] < 0 + && !isNull(this.data) && this.data.length >= 4) { + var minMax = minMax2DArray(this.data[0].values); + this.plotConfig.default_freq_range = [ minMax.min, minMax.max ]; + } + return this.plotConfig.default_freq_range; + } + + this.mustPropagateAxisFilter = function (axis) { + return axis == 0; + } + + this.getPlotlyConfig = function (data) { + + var plotDefaultConfig = this.getDefaultPlotlyConfig(); + + var plotlyConfig = get_plotdiv_lightcurve(data[0].values, data[1].values, + [], isNull(data[1].error_values) ? [] : data[1].error_values, [], + this.getLabel(0), + this.getLabel(1), + this.getTitle(), + plotDefaultConfig); + + var freq_range = this.getDefaultFreqRange(); + if (freq_range[0] >= 0 + && this.plotConfig.selected_freq_range[0] >= 0) { + plotlyConfig.layout.shapes = getShapesFromWti ([[freq_range[0], this.plotConfig.selected_freq_range[0]], + [this.plotConfig.selected_freq_range[1], freq_range[1]]], + plotDefaultConfig.WTI_FILLCOLOR, + plotDefaultConfig.WTI_OPACITY); + } + + plotlyConfig = this.addExtraDataConfig(plotlyConfig, plotDefaultConfig); + plotlyConfig = this.prepareAxis(plotlyConfig); + + if (this.plotConfig.plotType == "X*Y") { + plotlyConfig.layout.yaxis.titlefont = $.extend(true, {}, plotlyConfig.layout.yaxis.titlefont); //Avoid change text size of all plots + plotlyConfig.layout.yaxis.titlefont.size *= 0.75; + } + + return plotlyConfig; + } + + this.onBinSizeChanged = function () { + currentObj.plotConfig.default_freq_range= [-1, -1]; + currentObj.plotConfig.dt = currentObj.binSelector.value; + var tab = getTabForSelector(currentObj.id); + if (!isNull(tab)){ + tab.onBinSizeChanged(currentObj.binSelector.value); + } + } + + this.getLabel = function (axis) { + if (axis == this.XYLabelAxis){ + var yLabel = this.plotConfig.styles.labels[this.XYLabelAxis]; + if (this.plotConfig.plotType == "X*Y" && + (isNull(this.plotConfig.styles.XYLabelIsCustom) + || !this.plotConfig.styles.XYLabelIsCustom)) { + yLabel += " x " + this.plotConfig.styles.labels[0]; + } + return yLabel; + } else { + return this.plotConfig.styles.labels[axis]; + } + } + + log ("new FreqRangePlot id: " + this.id); + + return this; +} diff --git a/src/main/resources/static/scripts/plots/pdsPlot.js b/src/main/resources/static/scripts/plots/pdsPlot.js index 89b5a62..a67db2e 100644 --- a/src/main/resources/static/scripts/plots/pdsPlot.js +++ b/src/main/resources/static/scripts/plots/pdsPlot.js @@ -366,7 +366,7 @@ function PDSPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot this.getPlotlyConfig = function (data) { - var plotDefaultConfig = currentObj.getDefaultPlotlyConfig(); + var plotDefaultConfig = this.getDefaultPlotlyConfig(); var plotlyConfig = get_plotdiv_lightcurve(data[0].values, data[1].values, [], isNull(data[1].error_values) ? [] : data[1].error_values, [], diff --git a/src/main/resources/static/scripts/plots/phPlot.js b/src/main/resources/static/scripts/plots/phPlot.js index 187dc7f..1efe62d 100644 --- a/src/main/resources/static/scripts/plots/phPlot.js +++ b/src/main/resources/static/scripts/plots/phPlot.js @@ -7,19 +7,31 @@ function PhPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlotR Plot.call(this, id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlotReadyFn, toolbar, cssClass, switchable); this.ph_opts = {}; - this.ph_opts.nph = { default:32, min:1, max: 256}; //Number of phase bins of the phaseogram - this.ph_opts.nt = { default:64, min:1, max: 512}; //Number of time bins of the phaseogram + this.ph_opts.nph = { default:64, min:1, max: 256}; //Number of phase bins of the phaseogram + this.ph_opts.nt = { default:128, min:1, max: 512}; //Number of time bins of the phaseogram this.plotConfig.f = 0; this.plotConfig.nph = this.ph_opts.nph.default; this.plotConfig.nt = this.ph_opts.nt.default; + this.plotConfig.fdot = 0; + this.plotConfig.fddot = 0; + this.plotConfig.binary_params = null; + //this.plotConfig.binary_params = [0, 0, 0]; // [orbital_period, asini, t0] this.plotConfig.colorScale = $.extend(true, {}, this.getDefaultPlotlyConfig().DEFAULT_COLORSCALE); + this.plotConfig.tmp_df = 0; + this.plotConfig.tmp_fdot = 0; + this.plotConfig.tmp_fddot = 0; + this.plotConfig.tmp_binary_params = null; + + this.showLines = false; + this.btnFullScreen.remove(); this.btnLoad.remove(); this.getPlotlyConfig = function (data) { + var plotDefaultConfig = currentObj.getDefaultPlotlyConfig(); var plotlyConfig = get_plotdiv_dynamical_spectrum(data[1].values, data[2].values, data[0].values, @@ -31,9 +43,74 @@ function PhPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlotR currentObj.getDefaultPlotlyConfig()); plotlyConfig.data[0].type = "heatmap"; + //Calculates and plots the lines + if (currentObj.showLines && data[2].values.length > 0){ + var pepoch = data[2].values[0]; + var orbital_period = !isNull(currentObj.plotConfig.tmp_binary_params) ? currentObj.plotConfig.tmp_binary_params[0] : 1; + if (Math.abs(orbital_period) < 0.00001) { + orbital_period = 0.00001; + } + var asini = !isNull(currentObj.plotConfig.tmp_binary_params) ? currentObj.plotConfig.tmp_binary_params[1] : 0; + var t0 = !isNull(currentObj.plotConfig.tmp_binary_params) ? currentObj.plotConfig.tmp_binary_params[2] : 0; + + var prev_orbital_period = !isNull(currentObj.plotConfig.binary_params) ? currentObj.plotConfig.binary_params[0] : 1; + var prev_asini = !isNull(currentObj.plotConfig.binary_params) ? currentObj.plotConfig.binary_params[1] : 0; + var prev_t0 = !isNull(currentObj.plotConfig.binary_params) ? currentObj.plotConfig.binary_params[2] : 0; + + for (ph0 = 0.0; ph0 <= 2.0; ph0 += 0.5) { + var xData = []; + var delay0 = null; + for (j = 0; j < data[2].values.length; j++) { + var delay = null; + if (isNull(currentObj.plotConfig.tmp_binary_params)) { + var t = data[2].values[j] - pepoch; + delay = (t * currentObj.plotConfig.tmp_df) + + (0.5 * Math.pow(t, 2) * currentObj.plotConfig.tmp_fdot) + + (1/6 * Math.pow(t, 3) * currentObj.plotConfig.tmp_fddot); + } else { + var new_value = asini * Math.sin(2 * Math.PI * (data[2].values[j] - t0) / orbital_period) + var old_value = prev_asini * Math.sin(2 * Math.PI * (data[2].values[j] - prev_t0) / prev_orbital_period) + delay = (new_value - old_value) * currentObj.plotConfig.f + } + if (isNull(delay0)){ + delay0 = delay; + } + xData.push(ph0 + delay - delay0); + } + plotlyConfig.data.push(getLine (xData, data[2].values, plotDefaultConfig.PHASEOGRAM_LINE_COLOR, 1)); + } + + //Fixes xaxis range + plotlyConfig.layout.xaxis.range = [0.0, 2.0]; + } + return plotlyConfig; } + this.applySliders = function (){ + if (isNull(this.plotConfig.tmp_binary_params)){ + this.plotConfig.f -= this.plotConfig.tmp_df; + this.plotConfig.fdot -= this.plotConfig.tmp_fdot; + this.plotConfig.fddot -= this.plotConfig.tmp_fddot; + } else { + this.plotConfig.binary_params = this.plotConfig.tmp_binary_params; + } + } + + this.resetFrequecy = function (freq) { + this.plotConfig.f = freq; + this.plotConfig.fdot = 0; + this.plotConfig.fddot = 0; + this.plotConfig.binary_params = null; + } + + this.resetTempValues = function () { + this.plotConfig.tmp_df = 0; + this.plotConfig.tmp_fdot = 0; + this.plotConfig.tmp_fddot = 0; + this.plotConfig.tmp_binary_params = null; + } + this.getCoordsFromPlotlyHoverEvent = function (){ return null; } diff --git a/src/main/resources/static/scripts/plots/plotWithSettings.js b/src/main/resources/static/scripts/plots/plotWithSettings.js index f6801ec..39ac303 100644 --- a/src/main/resources/static/scripts/plots/plotWithSettings.js +++ b/src/main/resources/static/scripts/plots/plotWithSettings.js @@ -215,7 +215,7 @@ function PlotWithSettings(id, plotConfig, getDataFromServerFn, onFiltersChangedF //Adds bin size selector to plot var tab = getTabForSelector(currentObj.id); - if (!isNull(tab) && !isNull(tab.toolPanel.binSelector)){ + if (!isNull(tab)){ //&& !isNull(tab.toolPanel.binSelector) var enabled = !isNull(this.binSelector) && this.binSelector.enabled; var binSize = (enabled) ? this.plotConfig.dt : tab.projectConfig.binSize; @@ -250,8 +250,8 @@ function PlotWithSettings(id, plotConfig, getDataFromServerFn, onFiltersChangedF this.binSelector = new BinSelector(this.id + "_binSelector", "Bin Size (" + tab.projectConfig.timeUnit + "):", - tab.projectConfig.minBinSize, - tab.projectConfig.maxBinSize, + binSelectorConfig.minBinSize, + binSelectorConfig.maxBinSize, binSelectorConfig.step, binSize, this.onBinSizeChanged, diff --git a/src/main/resources/static/scripts/projectConfig.js b/src/main/resources/static/scripts/projectConfig.js index 3364f50..54c1e69 100644 --- a/src/main/resources/static/scripts/projectConfig.js +++ b/src/main/resources/static/scripts/projectConfig.js @@ -165,6 +165,7 @@ function ProjectConfig(){ for (i in projectConfigs) { this.totalDuration = (this.totalDuration != 0) ? Math.min(this.totalDuration, projectConfigs[i].totalDuration) : projectConfigs[i].totalDuration; this.minBinSize = (this.minBinSize != 0) ? Math.max(this.minBinSize, projectConfigs[i].minBinSize) : projectConfigs[i].minBinSize; + this.maxBinSize = (this.maxBinSize != 0) ? Math.max(this.maxBinSize, projectConfigs[i].maxBinSize) : projectConfigs[i].maxBinSize; this.binSize = (this.binSize != 0) ? Math.max(this.binSize, projectConfigs[i].binSize) : projectConfigs[i].binSize; this.avgSegmentSize = (this.avgSegmentSize != 0) ? Math.min(this.avgSegmentSize, projectConfigs[i].avgSegmentSize) : projectConfigs[i].avgSegmentSize; this.maxSegmentSize = (this.maxSegmentSize != 0) ? Math.min(this.maxSegmentSize, projectConfigs[i].maxSegmentSize) * 0.95 : projectConfigs[i].maxSegmentSize * 0.95; diff --git a/src/main/resources/static/scripts/selectors/binSelector.js b/src/main/resources/static/scripts/selectors/binSelector.js index 8a2fbb1..1768cd1 100644 --- a/src/main/resources/static/scripts/selectors/binSelector.js +++ b/src/main/resources/static/scripts/selectors/binSelector.js @@ -9,6 +9,7 @@ function BinSelector(id, title, fromValue, toValue, step, initValue, onSelectorV this.fromValue = fromValue; this.toValue = toValue; this.value = initValue; + this.initValue = initValue; this.step = step; this.type = (!isNull(type) && (type == "log")) ? type : "linear"; // Type: linear or log this.precision = !isNull(precision) ? precision : CONFIG.DEFAULT_NUMBER_DECIMALS; diff --git a/src/main/resources/static/scripts/tabPanels/phTabpanel.js b/src/main/resources/static/scripts/tabPanels/phTabpanel.js index 62cd779..b1a63e6 100644 --- a/src/main/resources/static/scripts/tabPanels/phTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/phTabpanel.js @@ -58,8 +58,8 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel this.createPlots = function () { - //Adds Long-Term variability Plot to outputPanel - this.pgPlot = new PgPlot( + //Adds FreqRangePlot Plot to outputPanel + this.freqRangePlot = new FreqRangePlot( this.id + "_pg_" + (new Date()).getTime(), $.extend(true, $.extend(true, {}, plotConfig), { styles: { type: "ligthcurve", @@ -72,18 +72,27 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel function (filters) { //onFiltersChangedFromPlot currentObj.freqRangeSelector.setValues( filters[0].from, filters[0].to ); + currentObj.freqRangePlot.plotConfig.selected_freq_range = [ filters[0].from, filters[0].to ]; + currentObj.freqRangePlot.redrawDiffered(); }, - function (comesFromLombScargle) { - //On PgPlot Plot Ready - if (!isNull(currentObj.pgPlot.data) - && currentObj.pgPlot.data[0].values.length > 0){ + function () { + //On FreqRangePlot Plot Ready + if (!isNull(currentObj.freqRangePlot.data) + && currentObj.freqRangePlot.data[0].values.length > 0){ currentObj.outputPanel.onPlotReady(); if (isNull(currentObj.freqRangeSelector)){ //We already know the freq range, so create controls currentObj.addControls(); + } else { + //Else update freqRangeSelector + var freqRange = currentObj.freqRangePlot.getDefaultFreqRange(); + currentObj.freqRangeSelector.setMinMaxValues(freqRange[0], freqRange[1]); } + } else if (!isNull(currentObj.freqRangePlot.data) + && currentObj.freqRangePlot.data[3].values.length > 0) { + currentObj.freqRangePlot.showWarn(currentObj.freqRangePlot.data[3].values[0]); } else { - currentObj.pgPlot.showWarn("Wrong PDS data"); + currentObj.freqRangePlot.showWarn("Wrong PDS data"); } }, null, @@ -92,7 +101,7 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel this.projectConfig, !isNull(plotStyle) ? $.extend(true, {}, plotStyle) : null ); - this.addPlot(this.pgPlot, false); + this.addPlot(this.freqRangePlot, false); //Adds Pulse Search Plot to outputPanel this.psPlot = new PulseSearchPlot( @@ -157,7 +166,14 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel this.addPlot(this.phPlot, false); //Request plot data after all plots were added - this.pgPlot.onDatasetValuesChanged(this.outputPanel.getFilters()); + this.freqRangePlot.onDatasetValuesChanged(this.outputPanel.getFilters()); + } + + this.onBinSizeChanged = function (dt) { + currentObj.projectConfig.binSize = dt; + currentObj.psPlot.plotConfig.dt = dt; + currentObj.prPlot.plotConfig.dt = dt; + currentObj.phPlot.plotConfig.dt = dt; } this.addControls = function(){ @@ -166,7 +182,7 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel var $pulseSearchContainer = getSectionContainer(this.pulseSearchSection); //Adds frequency range selector - var freqRange = this.pgPlot.getDefaultFreqRange(); + var freqRange = this.freqRangePlot.getDefaultFreqRange(); this.freqRangeSelector = new sliderSelector(this.id + "_FreqRange", "Frequency Range (Hz):", { table:"EVENTS", column:"FREQ", source: "frequency" }, @@ -175,6 +191,10 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel null, function( event, ui ) { currentObj.freqRangeSelector.setValues( ui.values[ 0 ], ui.values[ 1 ], "slider"); + currentObj.freqRangePlot.plotConfig.selected_freq_range = [ ui.values[ 0 ], ui.values[ 1 ]]; + setTimeout( function () { + currentObj.freqRangePlot.redrawDiffered(); + }, 120); }, null, getStepSizeFromRange(freqRange[1] - freqRange[0], 100)); @@ -250,7 +270,8 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel restoreBtn.click(function () { if (!isNull(currentObj.candidateFrequency)){ currentObj.freqSelector.setValues(currentObj.candidateFrequency); - currentObj.phPlot.plotConfig.f = currentObj.candidateFrequency; + currentObj.phPlot.resetFrequecy(currentObj.candidateFrequency); + currentObj.createPhaseogramSliders(); currentObj.getPhaseogramFromServer(); } }); @@ -267,6 +288,8 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel $phaseogramContainer.append($phaseogramAdv); this.toolPanel.$html.find(".fileSelectorsContainer").append($phaseogram); + + this.createPhaseogramSliders(); } this.onPulseSearchClick = function() { @@ -281,6 +304,7 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel this.onFreqSelectorValuesChanged = function(){ currentObj.phPlot.plotConfig.f = currentObj.freqSelector.value; + currentObj.createPhaseogramSliders(); if (!isNull(currentObj.freqSelectorTimeOutId)){ clearTimeout(currentObj.freqSelectorTimeOutId); } @@ -289,6 +313,243 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel }, 350); } + this.createPhaseogramSliders = function () { + + //Prepares containers + var $phaseogramContainer = getSectionContainer(this.toolPanel.$html.find(".phaseogram")); + $phaseogramContainer.find(".phSlidersContainer").remove(); + var $phSliders = getSection ("Pulse adjustment", "phSlidersContainer", + currentObj.phPlot.showLines, + function ( enabled ) { + currentObj.phPlot.showLines = enabled; + if (enabled) { + currentObj.phPlot.redrawDiffered(); + } else { + currentObj.phPlot.resetFrequecy(currentObj.candidateFrequency); + currentObj.createPhaseogramSliders(); + currentObj.getPhaseogramFromServer(); + } + }); + $phaseogramContainer.append($phSliders); + var $phSlidersContainer = getSectionContainer($phSliders); + + var sliderPrecision = 3; + + //Resets plot temp values + this.phPlot.resetTempValues(); + + //Creates Pulse search mode radios on Pulse Search Advanced container + var $adjModeRadiosCont = getRadioControl(this.id, + "Mode", + "adjMode", + [ + { id:"pder", label:"Period derivatives", value:"per_der"}, + { id:"orbm", label:"Orbital motion", value:"orbital_motion"} + ], + this.phSlidersMode, + function( value ) { + currentObj.onPhSlidersModeChanged(value); + currentObj.restorePhSliders(); + }); + $phSlidersContainer.append($adjModeRadiosCont); + + //Df slider + var delta_df_start = 4 / this.projectConfig.getTimeRange(); + this.df_order_of_mag = Math.floor(Math.log10(delta_df_start)); + var delta_df = delta_df_start / Math.pow(10, this.df_order_of_mag); + this.dfSelector = new BinSelector(this.id + "_dfSelector", + "Delta freq x$10^" + this.df_order_of_mag, + -delta_df, delta_df, Math.pow(10, -sliderPrecision), currentObj.phPlot.plotConfig.tmp_df, + this.onDfSelectorValuesChanged, + function( event, ui ) { + currentObj.dfSelector.setValues( ui.values[ 0 ], "slider"); + currentObj.onDfSelectorValuesChanged(); + }); + this.dfSelector.precision = sliderPrecision; + this.dfSelector.inputChanged = function ( event ) { + currentObj.dfSelector.setValues( getInputFloatValue(currentObj.dfSelector.fromInput, currentObj.phPlot.plotConfig.tmp_df) ); + currentObj.onDfSelectorValuesChanged(); + }; + $phSlidersContainer.append(this.dfSelector.$html); + + //Fdot slider + var delta_dfdot_start = 8 / Math.pow(this.projectConfig.getTimeRange(), 2); + this.dfdot_order_of_mag = Math.floor(Math.log10(delta_dfdot_start)); + var delta_dfdot = delta_dfdot_start / Math.pow(10, this.dfdot_order_of_mag); + this.fdotSelector = new BinSelector(this.id + "_fdotSelector", + "Delta fdot x$10^" + this.dfdot_order_of_mag, + -delta_dfdot, delta_dfdot, Math.pow(10, -sliderPrecision), currentObj.phPlot.plotConfig.tmp_fdot, + this.onFdotSelectorValuesChanged, + function( event, ui ) { + currentObj.fdotSelector.setValues( ui.values[ 0 ], "slider"); + currentObj.onFdotSelectorValuesChanged(); + }); + this.fdotSelector.precision = sliderPrecision; + this.fdotSelector.inputChanged = function ( event ) { + currentObj.fdotSelector.setValues( getInputFloatValue(currentObj.fdotSelector.fromInput, currentObj.phPlot.plotConfig.tmp_fdot) ); + currentObj.onFdotSelectorValuesChanged(); + }; + $phSlidersContainer.append(this.fdotSelector.$html); + + //Fddot slider + var delta_dfddot_start = 16 / Math.pow(this.projectConfig.getTimeRange(), 3); + this.dfddot_order_of_mag = Math.floor(Math.log10(delta_dfddot_start)); + var delta_dfddot = delta_dfddot_start / Math.pow(10, this.dfddot_order_of_mag); + this.fddotSelector = new BinSelector(this.id + "_fddotSelector", + "Delta fddot x$10^" + this.dfddot_order_of_mag, + -delta_dfddot, delta_dfddot, Math.pow(10, -sliderPrecision), currentObj.phPlot.plotConfig.tmp_fddot, + this.onFddotSelectorValuesChanged, + function( event, ui ) { + currentObj.fddotSelector.setValues( ui.values[ 0 ], "slider"); + currentObj.onFddotSelectorValuesChanged(); + }); + this.fddotSelector.precision = sliderPrecision; + this.fddotSelector.inputChanged = function ( event ) { + currentObj.fddotSelector.setValues( getInputFloatValue(currentObj.fddotSelector.fromInput, currentObj.phPlot.plotConfig.tmp_fddot) ); + currentObj.onFddotSelectorValuesChanged(); + }; + $phSlidersContainer.append(this.fddotSelector.$html); + + //Orbital Period slider + var delta_period = this.projectConfig.getTimeRange() * 5; + var orbital_period = !isNull(currentObj.phPlot.plotConfig.binary_params) ? + currentObj.phPlot.plotConfig.binary_params[0] : + this.projectConfig.getTimeRange() * 0.99; + this.orbPerSelector = new BinSelector(this.id + "_orbPerSelector", + "Orb. Per. (s)", + Math.max(this.projectConfig.getTimeRange() - delta_period), + this.projectConfig.getTimeRange() + delta_period, + this.projectConfig.getTimeRange() / 500, + orbital_period, + this.onOrbPerSelectorValuesChanged, + function( event, ui ) { + currentObj.orbPerSelector.setValues( ui.values[ 0 ], "slider"); + currentObj.onOrbPerSelectorValuesChanged(); + }); + this.orbPerSelector.precision = CONFIG.MAX_TIME_RESOLUTION_DECIMALS; + this.orbPerSelector.inputChanged = function ( event ) { + currentObj.orbPerSelector.setValues( getInputFloatValue(currentObj.orbPerSelector.fromInput, currentObj.phPlot.plotConfig.tmp_binary_params[0]) ); + currentObj.onOrbPerSelectorValuesChanged(); + }; + $phSlidersContainer.append(this.orbPerSelector.$html); + + //Asini slider + var delta_asini = 5 / currentObj.phPlot.plotConfig.f; + var min_asini = 1 / Math.pow(10, CONFIG.MAX_TIME_RESOLUTION_DECIMALS); + var asini = !isNull(currentObj.phPlot.plotConfig.binary_params) ? currentObj.phPlot.plotConfig.binary_params[1] : min_asini * 500; + this.asiniSelector = new BinSelector(this.id + "_asiniSelector", + "a sin i / c (l-sec)", + min_asini, asini + delta_asini, (asini + delta_asini) / 500, asini, + this.onAsiniSelectorValuesChanged, + function( event, ui ) { + currentObj.asiniSelector.setValues( ui.values[ 0 ], "slider"); + currentObj.onAsiniSelectorValuesChanged(); + }); + this.asiniSelector.precision = CONFIG.MAX_TIME_RESOLUTION_DECIMALS; + this.asiniSelector.inputChanged = function ( event ) { + currentObj.asiniSelector.setValues( getInputFloatValue(currentObj.asiniSelector.fromInput, currentObj.phPlot.plotConfig.tmp_binary_params[1]) ); + currentObj.onAsiniSelectorValuesChanged(); + }; + $phSlidersContainer.append(this.asiniSelector.$html); + + //Asini slider + var delta_t0 = delta_period; + var t0 = !isNull(currentObj.phPlot.plotConfig.binary_params) ? currentObj.phPlot.plotConfig.binary_params[2] : 0; + this.t0Selector = new BinSelector(this.id + "_t0Selector", + "T0 (MET)", + t0 - delta_t0, t0 + delta_t0, (delta_t0 * 2) / 500, t0, + this.onT0SelectorValuesChanged, + function( event, ui ) { + currentObj.t0Selector.setValues( ui.values[ 0 ], "slider"); + currentObj.onT0SelectorValuesChanged(); + }); + this.t0Selector.precision = CONFIG.DEFAULT_NUMBER_DECIMALS; + this.t0Selector.inputChanged = function ( event ) { + currentObj.t0Selector.setValues( getInputFloatValue(currentObj.t0Selector.fromInput, currentObj.phPlot.plotConfig.tmp_binary_params[2]) ); + currentObj.onT0SelectorValuesChanged(); + }; + $phSlidersContainer.append(this.t0Selector.$html); + + //Adds the Recalculate button + var recalculateBtn = $(''); + recalculateBtn.click(function () { + currentObj.phPlot.applySliders(); + currentObj.createPhaseogramSliders(); + currentObj.getPhaseogramFromServer(); + currentObj.addInfoPanel(); + }); + $phSlidersContainer.append(recalculateBtn); + + //Adds the Restore sliders button + var restorePhBtn = $(''); + restorePhBtn.click(function () { + currentObj.restorePhSliders(); + }); + $phSlidersContainer.append(restorePhBtn); + + //Sets selectors visibilities + this.onPhSlidersModeChanged(this.phSlidersMode); + + //Removes infoPanel if exists + this.outputPanel.$body.find(".infoPanel").remove(); + } + + this.onPhSlidersModeChanged = function(mode) { + this.phSlidersMode = mode; + + setVisibility(this.dfSelector.$html, mode=="per_der"); + setVisibility(this.fdotSelector.$html, mode=="per_der"); + setVisibility(this.fddotSelector.$html, mode=="per_der"); + + setVisibility(this.orbPerSelector.$html, mode=="orbital_motion"); + setVisibility(this.asiniSelector.$html, mode=="orbital_motion"); + setVisibility(this.t0Selector.$html, mode=="orbital_motion"); + + if (mode=="per_der"){ + this.phPlot.resetTempValues(); + } else { + this.phPlot.plotConfig.tmp_binary_params = [ currentObj.orbPerSelector.initValue, + currentObj.asiniSelector.initValue, + currentObj.t0Selector.initValue ]; + } + } + + this.onDfSelectorValuesChanged = function(){ + currentObj.phPlot.plotConfig.tmp_df = currentObj.dfSelector.value * Math.pow(10, currentObj.dfdot_order_of_mag); + currentObj.phPlot.redrawDiffered(); + } + + this.onFdotSelectorValuesChanged = function(){ + currentObj.phPlot.plotConfig.tmp_fdot = currentObj.fdotSelector.value * Math.pow(10, currentObj.df_order_of_mag); + currentObj.phPlot.redrawDiffered(); + } + + this.onFddotSelectorValuesChanged = function(){ + currentObj.phPlot.plotConfig.tmp_fddot = currentObj.fddotSelector.value * Math.pow(10, currentObj.dfdot_order_of_mag); + currentObj.phPlot.redrawDiffered(); + } + + this.onOrbPerSelectorValuesChanged = function(){ + currentObj.phPlot.plotConfig.tmp_binary_params[0] = currentObj.orbPerSelector.value; + currentObj.phPlot.redrawDiffered(); + } + + this.onAsiniSelectorValuesChanged = function(){ + currentObj.phPlot.plotConfig.tmp_binary_params[1] = currentObj.asiniSelector.value; + currentObj.phPlot.redrawDiffered(); + } + + this.onT0SelectorValuesChanged = function(){ + currentObj.phPlot.plotConfig.tmp_binary_params[2] = currentObj.t0Selector.value; + currentObj.phPlot.redrawDiffered(); + } + + this.restorePhSliders = function () { + this.phPlot.resetFrequecy(this.candidateFrequency); + this.createPhaseogramSliders(); + this.getPhaseogramFromServer(); + } + this.onPHTexboxesChanged = function(event){ if ($(event.target).hasClass("inputNPH")){ currentObj.phPlot.plotConfig.nph = getInputIntValueCropped(currentObj.toolPanel.$html.find(".inputNPH"), currentObj.phPlot.plotConfig.nph, currentObj.phPlot.ph_opts.nph.min, currentObj.phPlot.ph_opts.nph.max); @@ -307,7 +568,7 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel } this.onCandidateFrequenciesFound = function () { - if (currentObj.psPlot.candidateFreqs.length > 0) { + if (!isNull(currentObj.psPlot.candidateFreqs) && currentObj.psPlot.candidateFreqs.length > 0) { //If we have candidate frequency we can continue plotting the plofile and phaseogram //Fill candidate frequencies selector @@ -334,8 +595,8 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel setVisibility(currentObj.toolPanel.$html.find(".phaseogram"), true); //Minimize Pulse Search Plots - if (currentObj.pgPlot.$html.hasClass("fullWidth")) { - currentObj.pgPlot.btnFullScreen.click(); + if (currentObj.freqRangePlot.$html.hasClass("fullWidth")) { + currentObj.freqRangePlot.btnFullScreen.click(); } if (currentObj.psPlot.$html.hasClass("fullWidth")) { currentObj.psPlot.btnFullScreen.click(); @@ -416,11 +677,34 @@ function PHTabPanel (id, classSelector, navItemClass, service, navBarList, panel }; + this.addInfoPanel = function () { + this.outputPanel.$body.find(".infoPanel").remove(); + this.infoPanel = new InfoPanel("infoPanel", "Pulse adjustment parameters", null, null, null); + this.infoPanel.redraw = function() { + + if (currentObj.phSlidersMode == "per_der"){ + content = " Frequency: " + currentObj.phPlot.plotConfig.f.toFixed(6) + " Hz" + + " Delta fdot: " + currentObj.phPlot.plotConfig.fdot.toFixed(9) + "" + + " Delta fddot: " + currentObj.phPlot.plotConfig.fddot.toFixed(9) + ""; + } else { + content = " PB (s): " + currentObj.phPlot.plotConfig.binary_params[0].toFixed(6) + " (" + (currentObj.phPlot.plotConfig.binary_params[0] / 86400).toFixed(6) + " d)" + + " A1 (l-s): " + currentObj.phPlot.plotConfig.binary_params[1].toFixed(6) + "" + + " T0 (MET): " + currentObj.phPlot.plotConfig.binary_params[2].toFixed(6) + ""; + } + + this.container.html(content); + } + this.infoPanel.redraw(); + this.outputPanel.$body.append(this.infoPanel.$html); + } + //Set the selected plot configs this.plotConfig = plotConfig; this.pulseSearchAdvEnabled = false; this.phaseogramAdvEnabled = false; + this.phSlidersTimeout = 25; + this.phSlidersMode = "per_der"; this.setTitle("Phaseogram"); diff --git a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js index 0ff401f..0544d68 100644 --- a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js @@ -876,7 +876,7 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel async.waterfall([ function(callback) { if (!isNull(tabConfig.plotDefaultConfig)){ - currentObj.plotDefaultConfig = $.extend(true, {}, tabConfig.plotDefaultConfig); + currentObj.plotDefaultConfig = $.extend(true, CONFIG.PLOT_CONFIG, tabConfig.plotDefaultConfig); } callback(); }, diff --git a/src/main/resources/static/scripts/tabPanels/xsTabpanel.js b/src/main/resources/static/scripts/tabPanels/xsTabpanel.js index 6a39713..1c42250 100644 --- a/src/main/resources/static/scripts/tabPanels/xsTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/xsTabpanel.js @@ -158,6 +158,10 @@ function XSTabPanel (id, classSelector, navItemClass, service, navBarList, panel false, this.projectConfig ); + xsPlot.onBinSizeChanged = function () { + this.plotConfig.dt1 = this.binSelector.value; + this.plotConfig.dt2 = this.binSelector.value; + }; this.xsPlotIdx = this.outputPanel.plots.length; this.addPlot(xsPlot, false); diff --git a/src/main/resources/static/scripts/toolpanel.js b/src/main/resources/static/scripts/toolpanel.js index cdf3e2f..2e79538 100644 --- a/src/main/resources/static/scripts/toolpanel.js +++ b/src/main/resources/static/scripts/toolpanel.js @@ -324,7 +324,7 @@ function ToolPanel (id, function (selector) { //Notifies that time range has changed if (!isNull(currentObj.tabPanel)){ - currentObj.tabPanel.onTimeRangeChanged(Math.max ((selector.toValue - selector.fromValue) * 0.95, selector.step)); + currentObj.tabPanel.onTimeRangeChanged(Math.max ((selector.toValue - selector.fromValue), selector.step)); } }, this.selectors_array, diff --git a/src/main/resources/templates/includes/output_panel.html b/src/main/resources/templates/includes/output_panel.html index 5c8bab7..ae74fa3 100644 --- a/src/main/resources/templates/includes/output_panel.html +++ b/src/main/resources/templates/includes/output_panel.html @@ -28,6 +28,7 @@ + From 2642c2b3070448d5e3b6629c36f8c68c882ead50 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Mon, 13 Nov 2017 14:12:36 +0100 Subject: [PATCH 05/14] DAVE-348: RMF file cant be loaded for NuStar files --- src/main/python/server.py | 2 +- src/main/python/utils/dave_endpoint.py | 5 +++-- src/main/python/utils/dave_engine.py | 9 ++++---- .../resources/static/scripts/projectConfig.js | 7 +++++++ src/main/resources/static/scripts/schema.js | 13 ++++++++++++ src/main/resources/static/scripts/service.js | 6 ++++-- .../static/scripts/tabPanels/wfTabpanel.js | 2 +- .../resources/static/scripts/toolpanel.js | 21 +++++++++++++------ 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/main/python/server.py b/src/main/python/server.py index 15d5853..208c1c2 100644 --- a/src/main/python/server.py +++ b/src/main/python/server.py @@ -101,7 +101,7 @@ def append_file_to_dataset(): @app.route('/apply_rmf_file_to_dataset', methods=['GET']) def apply_rmf_file_to_dataset(): - return DaveEndpoint.apply_rmf_file_to_dataset(request.args['filename'], request.args['rmf_filename'], UPLOADS_TARGET) + return DaveEndpoint.apply_rmf_file_to_dataset(request.args['filename'], request.args['rmf_filename'], request.args['column'], UPLOADS_TARGET) @app.route('/get_plot_data', methods=['POST']) diff --git a/src/main/python/utils/dave_endpoint.py b/src/main/python/utils/dave_endpoint.py index ac75b97..6889379 100644 --- a/src/main/python/utils/dave_endpoint.py +++ b/src/main/python/utils/dave_endpoint.py @@ -121,8 +121,9 @@ def append_file_to_dataset(filename, nextfile, target): # Creates a new column E with Enery data on dataset # @param: filename: filename or dataset cache key # @param: rmf_filename: rmf file to apply +# @param: column: column to use for the conversion: PHA, or PI for NuSTAR # -def apply_rmf_file_to_dataset(filename, rmf_filename, target): +def apply_rmf_file_to_dataset(filename, rmf_filename, column, target): destination = get_destination(filename, target) if not destination: return common_error("Invalid file or cache key") @@ -134,7 +135,7 @@ def apply_rmf_file_to_dataset(filename, rmf_filename, target): if not FileUtils.is_valid_file(rmf_destination): return common_error("Invalid RMF file") - result = DaveEngine.apply_rmf_file_to_dataset(destination, rmf_destination) + result = DaveEngine.apply_rmf_file_to_dataset(destination, rmf_destination, column) return json.dumps(result) diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index c1a5f74..bff09a2 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -116,8 +116,9 @@ def append_file_to_dataset(destination, next_destination): # # @param: destination: file destination or dataset cache key # @param: rmf_destination: file destination of file to apply +# @param: column: column to use for the conversion: PHA, or PI for NuSTAR # -def apply_rmf_file_to_dataset(destination, rmf_destination): +def apply_rmf_file_to_dataset(destination, rmf_destination, column): try: dataset, cache_key = DaveReader.get_file_dataset(destination) if DsHelper.is_events_dataset(dataset): @@ -127,11 +128,11 @@ def apply_rmf_file_to_dataset(destination, rmf_destination): events_table = dataset.tables["EVENTS"] rmf_table = rmf_dataset.tables["EBOUNDS"] - if "PHA" not in events_table.columns: - logging.warn('apply_rmf_file_to_dataset: PHA column not found!') + if column not in events_table.columns: + logging.warn('apply_rmf_file_to_dataset: ' + str(column) + ' column not found!') return False - pha_data = events_table.columns["PHA"].values + pha_data = events_table.columns[column].values e_avg_data = dict((channel, (min + max)/2) for channel, min, max in zip(rmf_table.columns["CHANNEL"].values, rmf_table.columns["E_MIN"].values, diff --git a/src/main/resources/static/scripts/projectConfig.js b/src/main/resources/static/scripts/projectConfig.js index 54c1e69..3a267e2 100644 --- a/src/main/resources/static/scripts/projectConfig.js +++ b/src/main/resources/static/scripts/projectConfig.js @@ -197,6 +197,13 @@ function ProjectConfig(){ } } + this.getCalibrationColumn = function () { + if (this.hasSchema()){ + return this.schema.getCalibrationColumn(); + } + return "PHA"; + } + this.getConfig = function () { var config = $.extend( {}, this ); config.selectorFilenames = Object.assign({}, this.selectorFilenames); diff --git a/src/main/resources/static/scripts/schema.js b/src/main/resources/static/scripts/schema.js index 8615ab5..11c4155 100644 --- a/src/main/resources/static/scripts/schema.js +++ b/src/main/resources/static/scripts/schema.js @@ -174,6 +174,19 @@ function Schema(schema){ return this.getTotalDuration() * CONFIG.TIMERANGE_MULTIPLIER; } + this.getCalibrationColumn = function () { + if (this.hasHeader()){ + var tableHeader = this.getHeader(); + if (!isNull(tableHeader["TELESCOP"])) { + var telescop = tableHeader["TELESCOP"].trim().toLowerCase(); + if (telescop == "nustar") { + return "PI"; + } + } + } + return "PHA"; + } + return this; } diff --git a/src/main/resources/static/scripts/service.js b/src/main/resources/static/scripts/service.js index 38b9f1e..a9a3508 100644 --- a/src/main/resources/static/scripts/service.js +++ b/src/main/resources/static/scripts/service.js @@ -50,8 +50,10 @@ function Service (base_url) { errorFn); }; - this.apply_rmf_file_to_dataset = function ( filename, rmf_filename, fn ) { - $.get( thisService.base_url + "/apply_rmf_file_to_dataset", { filename: filename, rmf_filename: rmf_filename } ) + this.apply_rmf_file_to_dataset = function ( filename, rmf_filename, column, fn ) { + $.get( thisService.base_url + "/apply_rmf_file_to_dataset", { filename: filename, + rmf_filename: rmf_filename, + column: column } ) .done(fn) .fail(fn); }; diff --git a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js index 0544d68..341e217 100644 --- a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js @@ -87,7 +87,7 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel currentObj.service.get_dataset_schema(currentObj.projectConfig.gtiFilename, currentObj.onGtiSchemaChanged, currentObj.onSchemaError, !isNull(callback) ? { callback: callback } : null ); } else if ((selectorKey == "RMF") && currentObj.projectConfig.hasSchema()) { waitingDialog.show('Applying RMF: ' + getFilename(filenames[0])); - currentObj.service.apply_rmf_file_to_dataset(currentObj.projectConfig.filename, currentObj.projectConfig.rmfFilename, function (res) { currentObj.onRmfApplied(res, callback); } ); + currentObj.service.apply_rmf_file_to_dataset(currentObj.projectConfig.filename, currentObj.projectConfig.rmfFilename, currentObj.projectConfig.getCalibrationColumn(), function (res) { currentObj.onRmfApplied(res, callback); } ); } } else if (filenames.length > 1){ diff --git a/src/main/resources/static/scripts/toolpanel.js b/src/main/resources/static/scripts/toolpanel.js index 2e79538..87915d0 100644 --- a/src/main/resources/static/scripts/toolpanel.js +++ b/src/main/resources/static/scripts/toolpanel.js @@ -238,15 +238,16 @@ function ToolPanel (id, //Sets RMF fileSelector message depending on PHA column var rmfMessage = ""; - if (!projectConfig.schema.hasColumn("PHA")){ - //PHA Column doesn't exist, show we can't apply RMF file - rmfMessage = "PHA column not found in SRC file"; - } else if (projectConfig.schema.getTable()["PHA"].min_value >= projectConfig.schema.getTable()["PHA"].max_value){ + var calibrationColumn = projectConfig.getCalibrationColumn(); + if (!projectConfig.schema.hasColumn(calibrationColumn)){ + //calibrationColumn Column doesn't exist, show we can't apply RMF file + rmfMessage = calibrationColumn + " column not found in SRC file"; + } else if (projectConfig.schema.getTable()[calibrationColumn].min_value >= projectConfig.schema.getTable()[calibrationColumn].max_value){ //PHA Column is empty, show we can't apply RMF file - rmfMessage = "PHA column is empty in SRC file"; + rmfMessage = calibrationColumn + " column is empty in SRC file"; } - if (rmfMessage != ""){ + if ((rmfMessage != "") || (calibrationColumn == "PI")){ //If hasen't PHA column then remove PI from excludedFilters excludedFilters = excludedFilters.filter(function(column) { return column != "PI"; }); } @@ -380,6 +381,14 @@ function ToolPanel (id, //Adds color selectors, PHA filters this.createColorSelectors (pha_column); + + } else if (projectConfig.getCalibrationColumn() == "PI"){ + //If NuSTAR and show must upload RMF file for set energy ranges: + this.$html.find(".selectorsContainer").append('
' + + '

Energy range filter:

' + + '
'); + this.onColorFilterTypeChanged("E"); // If no rmffile yet, upload rmf will be shown. + this.$html.find(".colorSelectorsContainer").removeClass("hidden"); } //Sets initial filters to ToolPanel From 5e586437e79b1e31eed9981cd67872f249c920dc Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 15 Nov 2017 17:59:32 +0100 Subject: [PATCH 06/14] RMF file cant be loaded for NuStar file, Support to channel column from config.js --- src/main/resources/static/scripts/config.js | 6 ++ .../resources/static/scripts/projectConfig.js | 6 +- src/main/resources/static/scripts/schema.js | 10 ++- .../static/scripts/tabPanels/wfTabpanel.js | 16 ++-- .../resources/static/scripts/toolpanel.js | 86 +++++++++---------- 5 files changed, 67 insertions(+), 57 deletions(-) diff --git a/src/main/resources/static/scripts/config.js b/src/main/resources/static/scripts/config.js index 7fec2af..ca82f5e 100644 --- a/src/main/resources/static/scripts/config.js +++ b/src/main/resources/static/scripts/config.js @@ -28,6 +28,12 @@ CONFIG = { EVENTS_STRING: 'EVENTS,XTE_SE,XTE_SA', //Supported EVENTS HDU names GTI_STRING: 'GTI,STDGTI,STDGTI04,STDGTI04-1,SRC_GTIS,BKG_GTIS', //Supported GTI HDU names FRACEXP_LIMIT: 0.5, // Minimum exposure fraction allowed + CHANNEL_COLUMNS: [ { TELESCOP: "XMM", COLUMN: "PHA"}, + { TELESCOP: "RXTE", COLUMN: "PI"}, + { TELESCOP: "SWIFT", COLUMN: "PHA"}, + { TELESCOP: "CHANDRA", COLUMN: "PI"}, + { TELESCOP: "NuSTAR", COLUMN: "PI"} ], //Sets the channel column for each telescop, Supported columns: "PI", "PHA" + DEFAULT_CHANNEL_COLUMN: "PI", PLOT_CONFIG: { diff --git a/src/main/resources/static/scripts/projectConfig.js b/src/main/resources/static/scripts/projectConfig.js index 3a267e2..4b5f56d 100644 --- a/src/main/resources/static/scripts/projectConfig.js +++ b/src/main/resources/static/scripts/projectConfig.js @@ -197,11 +197,11 @@ function ProjectConfig(){ } } - this.getCalibrationColumn = function () { + this.getChannelColumn = function () { if (this.hasSchema()){ - return this.schema.getCalibrationColumn(); + return this.schema.getChannelColumn(); } - return "PHA"; + return CONFIG.DEFAULT_CHANNEL_COLUMN; } this.getConfig = function () { diff --git a/src/main/resources/static/scripts/schema.js b/src/main/resources/static/scripts/schema.js index 11c4155..b56bfb5 100644 --- a/src/main/resources/static/scripts/schema.js +++ b/src/main/resources/static/scripts/schema.js @@ -174,17 +174,19 @@ function Schema(schema){ return this.getTotalDuration() * CONFIG.TIMERANGE_MULTIPLIER; } - this.getCalibrationColumn = function () { + this.getChannelColumn = function () { + if (this.hasHeader()){ var tableHeader = this.getHeader(); if (!isNull(tableHeader["TELESCOP"])) { var telescop = tableHeader["TELESCOP"].trim().toLowerCase(); - if (telescop == "nustar") { - return "PI"; + var channel_colums = CONFIG.CHANNEL_COLUMNS.filter(function(channel_colum) { return channel_colum.TELESCOP.trim().toLowerCase() == telescop; }); + if (channel_colums.length > 0) { + return channel_colums[0].COLUMN; } } } - return "PHA"; + return CONFIG.DEFAULT_CHANNEL_COLUMN; } return this; diff --git a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js index 341e217..3f60e21 100644 --- a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js @@ -56,12 +56,14 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel } this.getPageName = function () { - if (!this.projectConfig.hasSchema()) { - return "LoadPage"; - } else if (this.projectConfig.schema.isEventsFile()){ - return "EventsFilePage"; - } else if (this.projectConfig.schema.isLightCurveFile()){ - return "LightcurveFilePage"; + if (!isNull(this.projectConfig)){ + if (!this.projectConfig.hasSchema()) { + return "LoadPage"; + } else if (this.projectConfig.schema.isEventsFile()){ + return "EventsFilePage"; + } else if (this.projectConfig.schema.isLightCurveFile()){ + return "LightcurveFilePage"; + } } return "WrongPage2"; @@ -87,7 +89,7 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel currentObj.service.get_dataset_schema(currentObj.projectConfig.gtiFilename, currentObj.onGtiSchemaChanged, currentObj.onSchemaError, !isNull(callback) ? { callback: callback } : null ); } else if ((selectorKey == "RMF") && currentObj.projectConfig.hasSchema()) { waitingDialog.show('Applying RMF: ' + getFilename(filenames[0])); - currentObj.service.apply_rmf_file_to_dataset(currentObj.projectConfig.filename, currentObj.projectConfig.rmfFilename, currentObj.projectConfig.getCalibrationColumn(), function (res) { currentObj.onRmfApplied(res, callback); } ); + currentObj.service.apply_rmf_file_to_dataset(currentObj.projectConfig.filename, currentObj.projectConfig.rmfFilename, currentObj.projectConfig.getChannelColumn(), function (res) { currentObj.onRmfApplied(res, callback); } ); } } else if (filenames.length > 1){ diff --git a/src/main/resources/static/scripts/toolpanel.js b/src/main/resources/static/scripts/toolpanel.js index 87915d0..64e4b5a 100644 --- a/src/main/resources/static/scripts/toolpanel.js +++ b/src/main/resources/static/scripts/toolpanel.js @@ -44,6 +44,7 @@ function ToolPanel (id, this.file_selectors_ids_array = []; this.file_selectors_array = []; this.selectors_array = []; + this.channelColumn = "PHA"; this.replaceColumn = "PHA"; this.tabPanel = isNull(tabPanel) ? null : tabPanel; @@ -236,19 +237,19 @@ function ToolPanel (id, this.showEventsSelectors(); - //Sets RMF fileSelector message depending on PHA column + //Sets RMF fileSelector message depending on channel column var rmfMessage = ""; - var calibrationColumn = projectConfig.getCalibrationColumn(); - if (!projectConfig.schema.hasColumn(calibrationColumn)){ - //calibrationColumn Column doesn't exist, show we can't apply RMF file - rmfMessage = calibrationColumn + " column not found in SRC file"; - } else if (projectConfig.schema.getTable()[calibrationColumn].min_value >= projectConfig.schema.getTable()[calibrationColumn].max_value){ - //PHA Column is empty, show we can't apply RMF file - rmfMessage = calibrationColumn + " column is empty in SRC file"; + this.channelColumn = projectConfig.getChannelColumn(); + if (!projectConfig.schema.hasColumn(this.channelColumn)){ + //channelColumn Column doesn't exist, show we can't apply RMF file + rmfMessage = this.channelColumn + " column not found in Event file"; + } else if (projectConfig.schema.getTable()[this.channelColumn].min_value >= projectConfig.schema.getTable()[this.channelColumn].max_value){ + //channelColumn is empty, show we can't apply RMF file + rmfMessage = this.channelColumn + " column is empty in Event file"; } - if ((rmfMessage != "") || (calibrationColumn == "PI")){ - //If hasen't PHA column then remove PI from excludedFilters + if ((rmfMessage != "") || (this.channelColumn == "PI")){ + //Remove PI from excludedFilters if there is rmfMessage or channel column is PI excludedFilters = excludedFilters.filter(function(column) { return column != "PI"; }); } this.rmfFileSelector.disable(rmfMessage); @@ -283,7 +284,7 @@ function ToolPanel (id, this.$html.find(".selectorsContainer").append(binDiv); } - var pha_column = null; + var channel_column_data = null; //Adds the rest of selectors from dataset columns for (tableName in projectConfig.schema.contents) { @@ -308,8 +309,8 @@ function ToolPanel (id, //Sets the slider precision var precision = CONFIG.DEFAULT_NUMBER_DECIMALS; - if (tableName == "EVENTS" && columnName == "PHA") { - pha_column = column; + if (tableName == "EVENTS" && columnName == projectConfig.getChannelColumn()) { + channel_column_data = column; precision = 0; } else if (columnName == CONFIG.TIME_COLUMN){ precision = CONFIG.MAX_TIME_RESOLUTION_DECIMALS; @@ -357,14 +358,14 @@ function ToolPanel (id, } } - if (pha_column != null){ + if (channel_column_data != null){ - // Creates colors filter type (PHA by default or ENERGY with RMF file upload requisite) + // Creates colors filter type (channelColumn by default or ENERGY with RMF file upload requisite) this.colorFilterTypeRadios = $('
' + '

Energy range filter type:

' + '
' + - '' + - '' + + '' + + '' + '' + '' + '
' + @@ -379,16 +380,15 @@ function ToolPanel (id, gaTracker.sendEvent("LoadPage", "colorFilterTypeRadios_" + this.value, currentObj.id); }); - //Adds color selectors, PHA filters - this.createColorSelectors (pha_column); + //Adds color selectors, Channel filters + this.createColorSelectors (channel_column_data); + } else { + // Shows can't find channel column in file + this.colorFilterTypeRadios = $('
' + + '

Energy range filter:
No channel column ( ' + this.channelColumn + ' ) found in Event file
' + + '
'); - } else if (projectConfig.getCalibrationColumn() == "PI"){ - //If NuSTAR and show must upload RMF file for set energy ranges: - this.$html.find(".selectorsContainer").append('
' + - '

Energy range filter:

' + - '
'); - this.onColorFilterTypeChanged("E"); // If no rmffile yet, upload rmf will be shown. - this.$html.find(".colorSelectorsContainer").removeClass("hidden"); + this.$html.find(".selectorsContainer").append(this.colorFilterTypeRadios); } //Sets initial filters to ToolPanel @@ -405,14 +405,14 @@ function ToolPanel (id, var selectorKey = "Color_" + selectorName; var filterData = { table:"EVENTS", column:selectorKey, source:"ColorSelector", replaceColumn: column.id }; var selector = new sliderSelector(this.id + "_selector_" + selectorKey + "_" + column.id, - ((column.id == "PHA") ? "Channel" : "Energy") + " range " + selectorName + ":", + ((column.id == this.channelColumn) ? "Channel" : "Energy") + " range " + selectorName + ":", filterData, column.min_value, column.max_value, this.onSelectorValuesChanged, this.selectors_array); var min_value = column.min_value + (increment * i); var max_value = min_value + increment; - if (column.id == "PHA") { + if (column.id == this.channelColumn) { selector.precision = 0; } else { selector.setFixedStep(CONFIG.ENERGY_FILTER_STEP); @@ -481,7 +481,7 @@ function ToolPanel (id, this.setColorFilterRadios = function (column) { var colorFilterTypeRadios = this.$html.find(".colorFilterType").find("input"); - colorFilterTypeRadios.filter('[value=PHA]').prop('checked', column == "PHA").checkboxradio('refresh'); + colorFilterTypeRadios.filter('[value=' + this.channelColumn + ']').prop('checked', column == this.channelColumn).checkboxradio('refresh'); colorFilterTypeRadios.filter('[value=E]').prop('checked', column == "E").checkboxradio('refresh'); } @@ -498,13 +498,13 @@ function ToolPanel (id, && filters[f].source == 'ColorSelector') { //Sets Energy or Channels filters visible var selectorsContainer = currentObj.$html.find(".colorSelectorsContainer"); - var showPHA = (currentObj.tabPanel.projectConfig.rmfFilename == "") || (filters[f].replaceColumn == "PHA"); - setVisibility(selectorsContainer.find(".colorSelectors_PHA"), showPHA); - setVisibility(selectorsContainer.find(".colorSelectors_E"), !showPHA); - if (showPHA) { - sliderSelectors_setFiltersEnabled (currentObj.selectors_array, "ColorSelector", "PHA"); - currentObj.setColorFilterRadios("PHA"); - currentObj.replaceColumn = "PHA"; + var showChannel = (currentObj.tabPanel.projectConfig.rmfFilename == "") || (filters[f].replaceColumn == currentObj.channelColumn); + setVisibility(selectorsContainer.find(".colorSelectors_" + currentObj.channelColumn), showChannel); + setVisibility(selectorsContainer.find(".colorSelectors_E"), !showChannel); + if (showChannel) { + sliderSelectors_setFiltersEnabled (currentObj.selectors_array, "ColorSelector", currentObj.channelColumn); + currentObj.setColorFilterRadios(currentObj.channelColumn); + currentObj.replaceColumn = currentObj.channelColumn; } else { sliderSelectors_setFiltersEnabled (currentObj.selectors_array, "ColorSelector", "E"); currentObj.setColorFilterRadios("E"); @@ -552,7 +552,7 @@ function ToolPanel (id, //Sets energy values to Energy Selectors from Pha selector values var e_Selectors = sliderSelectors_getSelectors(currentObj.selectors_array, "ColorSelector", "E"); - var pha_Selectors = sliderSelectors_getSelectors(currentObj.selectors_array, "ColorSelector", "PHA"); + var pha_Selectors = sliderSelectors_getSelectors(currentObj.selectors_array, "ColorSelector", currentObj.channelColumn); for (i in pha_Selectors) { var phaSelector = pha_Selectors[i]; for (i in e_Selectors) { @@ -573,12 +573,12 @@ function ToolPanel (id, currentObj.onSelectorValuesChanged(); } } else { - //Show PHA color selectors - sliderSelectors_setFiltersEnabled (currentObj.selectors_array, "ColorSelector", "PHA"); + //Show Channel color selectors + sliderSelectors_setFiltersEnabled (currentObj.selectors_array, "ColorSelector", currentObj.channelColumn); - //Sets pha values to PHA Selectors from Energy selector values + //Sets values to Channel Selectors from Energy selector values var e_Selectors = sliderSelectors_getSelectors(currentObj.selectors_array, "ColorSelector", "E"); - var pha_Selectors = sliderSelectors_getSelectors(currentObj.selectors_array, "ColorSelector", "PHA"); + var pha_Selectors = sliderSelectors_getSelectors(currentObj.selectors_array, "ColorSelector", currentObj.channelColumn); for (i in pha_Selectors) { var phaSelector = pha_Selectors[i]; for (i in e_Selectors) { @@ -594,8 +594,8 @@ function ToolPanel (id, } } - selectorsContainer.find(".colorSelectors_PHA").show(); - currentObj.replaceColumn = "PHA"; + selectorsContainer.find(".colorSelectors_" + currentObj.channelColumn).show(); + currentObj.replaceColumn = currentObj.channelColumn; currentObj.onSelectorValuesChanged(); } } From 9b8832bab81b2f12f4e3a6471eb5bc49845ba757 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 15 Nov 2017 18:48:58 +0100 Subject: [PATCH 07/14] DAVE-355: Multifile concatenation not works, and some JS bug fixing --- src/main/python/utils/dave_engine.py | 2 +- src/main/python/utils/dave_reader.py | 2 +- src/main/resources/static/scripts/master_page.js | 3 ++- src/main/resources/static/scripts/toolpanel.js | 13 +++++++------ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index bff09a2..7dc9f9f 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -92,7 +92,7 @@ def append_file_to_dataset(destination, next_destination): new_dataset = dataset.clone() new_hdutable = DsHelper.get_hdutable_from_dataset(new_dataset) next_hdutable = DsHelper.get_hdutable_from_dataset(next_dataset) - new_hdutable = new_hdutable.join(next_hdutable) + new_dataset.tables[new_hdutable.id] = new_hdutable.join(next_hdutable) new_dataset.tables["GTI"] = DsHelper.join_gti_tables(new_dataset.tables["GTI"], next_dataset.tables["GTI"]) # DsCache.remove(destination) # Removes previous cached dataset for prev key diff --git a/src/main/python/utils/dave_reader.py b/src/main/python/utils/dave_reader.py index 2b48208..9a2f029 100644 --- a/src/main/python/utils/dave_reader.py +++ b/src/main/python/utils/dave_reader.py @@ -285,7 +285,7 @@ def get_lightcurve_fits_dataset_with_stingray(destination, hdulist, hduname='RAT # Stores the events_start_time in time column extra dataset.tables[hduname].columns[column].set_extra("TSTART", events_start_time) - logging.debug("Read Lightcurve fits with stingray file successfully: " + str(destination) + ", tstart: " + str(events_start_time) + ", rate: " + str(lcurve["counts"])) + logging.debug("Read Lightcurve fits with stingray file successfully: " + str(destination) + ", tstart: " + str(events_start_time) + ", rate: " + str(len(lcurve["counts"]))) return dataset diff --git a/src/main/resources/static/scripts/master_page.js b/src/main/resources/static/scripts/master_page.js index 3c835ae..ccb22cd 100644 --- a/src/main/resources/static/scripts/master_page.js +++ b/src/main/resources/static/scripts/master_page.js @@ -186,7 +186,8 @@ function hideWaitingDialogDelayed (delay) { } function uncaugthError(errorMsg) { - if (!errorMsg.toLowerCase().includes("invalid or unexpected token")){ + if (!errorMsg.toLowerCase().includes("invalid or unexpected token") + && !errorMsg.toLowerCase().includes("missing ) after argument list")){ logErr(errorMsg); } return false; diff --git a/src/main/resources/static/scripts/toolpanel.js b/src/main/resources/static/scripts/toolpanel.js index 64e4b5a..62e0728 100644 --- a/src/main/resources/static/scripts/toolpanel.js +++ b/src/main/resources/static/scripts/toolpanel.js @@ -382,13 +382,14 @@ function ToolPanel (id, //Adds color selectors, Channel filters this.createColorSelectors (channel_column_data); - } else { - // Shows can't find channel column in file - this.colorFilterTypeRadios = $('
' + - '

Energy range filter:
No channel column ( ' + this.channelColumn + ' ) found in Event file
' + - '
'); - this.$html.find(".selectorsContainer").append(this.colorFilterTypeRadios); + } else if (projectConfig.schema.isEventsFile()){ + // Shows can't find channel column in Event file + var colorFilterTypeMsg = $('
' + + '

Energy range filter:
No channel column ( ' + this.channelColumn + ' ) found in Event file
' + + '
'); + + this.$html.find(".selectorsContainer").append(colorFilterTypeMsg); } //Sets initial filters to ToolPanel From 6f7a369055be503a9f9f6caf25e954c3c2585fe6 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 15 Nov 2017 18:53:33 +0100 Subject: [PATCH 08/14] DAVE-349: Little text change in general setting --- .../resources/static/scripts/tabPanels/settingsTabpanel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js b/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js index f6632a1..bd8c64d 100644 --- a/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js @@ -50,7 +50,7 @@ function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, '
' + '' + '' + - '

Settings changed here only applies to new tabs. You can save the workspace for reusing this settings later, or edit config.js file to update the default settings.

' + + '

Settings changed here only applies to new tabs. You can save the workspace to reuse this settings later, or edit config.js file to update the default settings.

' + '


'); var $mainSettings = this.$container.find(".mainSettings"); @@ -173,7 +173,7 @@ function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, "

© 2016 Timelab Technologies Ltd.

" + "

DAVE Version: " + version + "

"); - gaTracker.sendEvent("GeneralSettings", "btnAboutDave", currentObj.id); + gaTracker.sendEvent("GeneralSettings", "btnAboutDave", currentObj.id); }); log("SettingsTabPanel ready! id: " + this.id); From 12a80acb2372f7487922cbe424b748bcf303dce5 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 15 Nov 2017 19:16:52 +0100 Subject: [PATCH 09/14] DAVE-353: Plots goes down to page bottom if screen size is reduced --- src/main/js/electron/main.js | 2 ++ src/main/resources/static/styles/master_page.css | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/main/js/electron/main.js b/src/main/js/electron/main.js index a3f6c88..342bc87 100644 --- a/src/main/js/electron/main.js +++ b/src/main/js/electron/main.js @@ -14,6 +14,8 @@ let mainWindow, windowParams = { width:1200, height: 700, + minHeight: 300, + minWidth: 768, icon: "resources/resources/static/img/icon.png" }; var retryInterval = 0.5 * 1000; diff --git a/src/main/resources/static/styles/master_page.css b/src/main/resources/static/styles/master_page.css index 0bb136c..5cf5145 100644 --- a/src/main/resources/static/styles/master_page.css +++ b/src/main/resources/static/styles/master_page.css @@ -10,6 +10,10 @@ html,body,.container { margin: 0; } +body { + min-width: 1090px; +} + h2 { font-size: 18px; } @@ -133,6 +137,7 @@ ul#right-navbar li { padding-left: 15px; padding-bottom: 60px; background-color: #ffffff; + min-width: 720px; } .daveContainer .columnDivider From e5b76767621d8a794e4eb3ef0be0aa6f6cb706f7 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 15 Nov 2017 20:08:12 +0100 Subject: [PATCH 10/14] DAVE-354: Once MultiFile not supported msg is shown Choose file not works, and added channel column selector to general settings --- .../static/scripts/selectors/fileSelector.js | 1 + .../scripts/tabPanels/settingsTabpanel.js | 45 +++++++++++++++---- .../resources/static/styles/master_page.css | 10 ++++- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/main/resources/static/scripts/selectors/fileSelector.js b/src/main/resources/static/scripts/selectors/fileSelector.js index b949ee4..dcbc761 100644 --- a/src/main/resources/static/scripts/selectors/fileSelector.js +++ b/src/main/resources/static/scripts/selectors/fileSelector.js @@ -235,6 +235,7 @@ function fileSelector(id, label, selectorKey, uploadFn, onFileChangedFn) { } } + this.setMultiFileEnabled(this.multiFileEnabled); this.onUploadSuccess(); log ("new fileSelector id: " + id + ", label: " + label + ", inputId: " + this.uploadInputId); diff --git a/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js b/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js index bd8c64d..5b63cd0 100644 --- a/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/settingsTabpanel.js @@ -55,7 +55,7 @@ function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, var $mainSettings = this.$container.find(".mainSettings"); var $segmSettings = this.$container.find(".segmSettings"); - var $advSettingss = this.$container.find(".advSettings"); + var $advSettings = this.$container.find(".advSettings"); /* Shows the auto BinSize or time filtering choice $mainSettings.append(getRadioControl(currentObj.id, @@ -111,29 +111,58 @@ function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, "Default segment size: TotalTime /", CONFIG.DEFAULT_SEGMENT_DIVIDER, 1, 100, function(value, input) { CONFIG.DEFAULT_SEGMENT_DIVIDER = value; updateServerConfig(); })); - $advSettingss.append(getTextBox ("TIME_COLUMN_" + this.id, "inputTIME_COLUMN", + $advSettings.append(getTextBox ("TIME_COLUMN_" + this.id, "inputTIME_COLUMN", "Time column name on HDU", CONFIG.TIME_COLUMN, function(value, input) { CONFIG.TIME_COLUMN = value; updateServerConfig(); })); - $advSettingss.append(getTextBox ("EVENTS_STRING_" + this.id, "inputEVENTS_STRING width80", + $advSettings.append(getRadioControl(currentObj.id, + "Default channel column name on HDU", + "defaultChannelColumn", + [ + { id:"pi", label:"PI", value:"PI" }, + { id:"pha", label:"PHA", value:"PHA" } + ], + CONFIG.DEFAULT_CHANNEL_COLUMN, + function(value, id) { + CONFIG.DEFAULT_CHANNEL_COLUMN = value; + updateServerConfig(); + }, + "smallTextStyle")); + + + $advSettings.append('Telescops configuration '); + $advSettings.find(".btnTelescopConfig").click(function () { + + var msg = ""; + for (var i = 0; i < CONFIG.CHANNEL_COLUMNS.length; i++){ + msg += "

" + CONFIG.CHANNEL_COLUMNS[i].TELESCOP + " -> " + CONFIG.CHANNEL_COLUMNS[i].COLUMN + "

"; + } + msg += '

You can change this settings in config.js file to update the default channel column and the channel column per each telescop.

' + + showMsg("Telescops configuration", msg); + + gaTracker.sendEvent("GeneralSettings", "btnTelescopConfig", currentObj.id); + }); + + $advSettings.append(getTextBox ("EVENTS_STRING_" + this.id, "inputEVENTS_STRING width80", "HDU names supported as EVENT tables (separated by commas without spaces)", CONFIG.EVENTS_STRING, function(value, input) { CONFIG.EVENTS_STRING = value; updateServerConfig(); })); - $advSettingss.append(getTextBox ("GTI_STRING_" + this.id, "inputGTI_STRING width80", + $advSettings.append(getTextBox ("GTI_STRING_" + this.id, "inputGTI_STRING width80", "HDU names supported as GTI tables (separated by commas without spaces)", CONFIG.GTI_STRING, function(value, input) { CONFIG.GTI_STRING = value; updateServerConfig(); })); - $advSettingss.append(getBooleanBox ("Avoid set background light curve if it is already subtracted", + $advSettings.append(getBooleanBox ("Avoid set background light curve if it is already subtracted", "chkDENY_BCK_IF_SUBS", CONFIG.DENY_BCK_IF_SUBS, function(enabled) { CONFIG.DENY_BCK_IF_SUBS = enabled; updateServerConfig(); })); - $advSettingss.append(getBooleanBox ("Show server logs on GUI Log tab", + $advSettings.append(getBooleanBox ("Show server logs on GUI Log tab", "chkLOG_TO_SERVER_ENABLED", CONFIG.LOG_TO_SERVER_ENABLED, function(enabled) { CONFIG.LOG_TO_SERVER_ENABLED = enabled; updateServerConfig(); })); //Add the server log level radio buttons // PYTHON SERVER LOG LEVEL -> ALL = -1, DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3, NONE = 4 - $advSettingss.append(getRadioControl(currentObj.id, + $advSettings.append(getRadioControl(currentObj.id, "Server logging level", "serverLogLevel", [ @@ -161,7 +190,7 @@ function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, }, 2000); }); }); - $advSettingss.append($btnClearCache); + $advSettings.append($btnClearCache); this.$container.find(".btnAboutDave").click(function () { diff --git a/src/main/resources/static/styles/master_page.css b/src/main/resources/static/styles/master_page.css index 5cf5145..bf7cf0c 100644 --- a/src/main/resources/static/styles/master_page.css +++ b/src/main/resources/static/styles/master_page.css @@ -673,12 +673,14 @@ input.wrongValue { { color: rgb(245, 243, 243); font-size: 1.5em; + margin-top: 0px; } .TabPanel.Settings h3 { color: #e68f4d; clear: both; + margin-top: 0px; } .floatRight { @@ -752,7 +754,7 @@ input.wrongValue { padding-left: 12px; } -.serverLogLevel h3 { +.serverLogLevel h3, .defaultChannelColumn h3 { color: #9d9d9d !important; } @@ -827,3 +829,9 @@ p.allPlots { fieldset.ui-controlgroup.ui-controlgroup-horizontal.ui-helper-clearfix input { display: none; } + +.btnTelescopConfig { + float: right; + margin-top: -26px; + margin-right: 230px; +} From 8bd2fd0ab531984ed31d7be5de08434d7786fcef Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 15 Nov 2017 20:39:33 +0100 Subject: [PATCH 11/14] DAVE-356: If RMF file is loaded twice two Energy Filters are shown --- .../resources/static/scripts/toolpanel.js | 73 ++++++++++++------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/src/main/resources/static/scripts/toolpanel.js b/src/main/resources/static/scripts/toolpanel.js index 62e0728..0bf77cc 100644 --- a/src/main/resources/static/scripts/toolpanel.js +++ b/src/main/resources/static/scripts/toolpanel.js @@ -400,46 +400,69 @@ function ToolPanel (id, var selectorNames = ["A", "B", "C", "D"]; var increment = (column.max_value - column.min_value) * (1 / selectorNames.length); var container = $("
"); + var mustAppend = false; for (i in selectorNames) { var selectorName = selectorNames[i]; var selectorKey = "Color_" + selectorName; - var filterData = { table:"EVENTS", column:selectorKey, source:"ColorSelector", replaceColumn: column.id }; - var selector = new sliderSelector(this.id + "_selector_" + selectorKey + "_" + column.id, - ((column.id == this.channelColumn) ? "Channel" : "Energy") + " range " + selectorName + ":", - filterData, - column.min_value, column.max_value, - this.onSelectorValuesChanged, - this.selectors_array); + var sliderId = this.id + "_selector_" + selectorKey + "_" + column.id; var min_value = column.min_value + (increment * i); var max_value = min_value + increment; - if (column.id == this.channelColumn) { - selector.precision = 0; + var selector = sliderSelectors_getSelector(this.selectors_array, sliderId); + + if (isNull(selector)) { + //Creates new selector + mustAppend = true; + var filterData = { table:"EVENTS", column:selectorKey, source:"ColorSelector", replaceColumn: column.id }; + selector = new sliderSelector(sliderId, + ((column.id == this.channelColumn) ? "Channel" : "Energy") + " range " + selectorName + ":", + filterData, + column.min_value, column.max_value, + this.onSelectorValuesChanged, + this.selectors_array); + if (column.id == this.channelColumn) { + selector.precision = 0; + } else { + selector.setFixedStep(CONFIG.ENERGY_FILTER_STEP); + } + selector.setValues (min_value, max_value); + selector.setEnabled (true); + container.append(selector.$html); + } else { - selector.setFixedStep(CONFIG.ENERGY_FILTER_STEP); + //Udpate selector min and max values + selector.setMinMaxValues(column.min_value, column.max_value); + selector.setValues (min_value, max_value); } - selector.setValues (min_value, max_value); - selector.setEnabled (true); - container.append(selector.$html); } - this.$html.find(".colorSelectorsContainer").append(container); - this.$html.find(".colorSelectorsContainer").removeClass("hidden"); + if (mustAppend){ + this.$html.find(".colorSelectorsContainer").append(container); + this.$html.find(".colorSelectorsContainer").removeClass("hidden"); + } } this.onRmfDatasetUploaded = function ( schema ) { if (schema.isEventsFile()) { var column = schema.getTable()["E"]; if (!isNull(column)){ - //Adds Energy general filter - var selector = new sliderSelector(this.id + "_Energy", - "Energy (keV):", - { table:"EVENTS", column:"E" }, - column.min_value, column.max_value, - this.onSelectorValuesChanged, - this.selectors_array); - selector.setFixedStep(CONFIG.ENERGY_FILTER_STEP); - selector.$html.insertAfter("." + this.id + "_TIME"); + var energySliderId = this.id + "_Energy"; + var selector = sliderSelectors_getSelector(this.selectors_array, energySliderId); + if (isNull(selector)) { + //Adds energy general filter selector + selector = new sliderSelector(energySliderId, + "Energy (keV):", + { table:"EVENTS", column:"E" }, + column.min_value, column.max_value, + this.onSelectorValuesChanged, + this.selectors_array); + selector.setFixedStep(CONFIG.ENERGY_FILTER_STEP); + selector.$html.insertAfter("." + this.id + "_TIME"); + } else { + + //Udpate energy selector min and max values + selector.setMinMaxValues(column.min_value, column.max_value); + } //Prepares Energy color filters this.createColorSelectors(column); @@ -465,7 +488,7 @@ function ToolPanel (id, } else { - //Udpated rate slider min and max values + //Udpate rate slider min and max values var rateSelector = sliderSelectors_getSelector(currentObj.selectors_array, rateSliderId); if (!isNull(rateSelector)) { var newMinRate = Math.min(rateSelector.initFromValue, minRate); From b427e081b471581e0b3b83bce18fdf9cf1271f29 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Wed, 29 Nov 2017 01:15:17 +0100 Subject: [PATCH 12/14] Added RMS vs CountRate Plot --- src/main/python/server.py | 3 +- src/main/python/utils/dave_endpoint.py | 5 +-- src/main/python/utils/dave_engine.py | 25 ++++++++++++--- .../scripts/outputPanels/wfOutputPanel.js | 32 +++++++++++++------ .../resources/static/scripts/plots/rmsPlot.js | 3 +- .../static/scripts/tabPanels/wfTabpanel.js | 18 +++++++---- 6 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/main/python/server.py b/src/main/python/server.py index 208c1c2..cafc18e 100644 --- a/src/main/python/server.py +++ b/src/main/python/server.py @@ -199,7 +199,8 @@ def get_rms_spectrum(): request.json['filters'], request.json['axis'], float(request.json['dt']), float(request.json['nsegm']), float(request.json['segment_size']), request.json['norm'], request.json['type'], float(request.json['df']), - request.json['freq_range'], request.json['energy_range'], int(request.json['n_bands'])) + request.json['freq_range'], request.json['energy_range'], + int(request.json['n_bands']), request.json['x_type']) @app.route('/get_plot_data_from_models', methods=['POST']) diff --git a/src/main/python/utils/dave_endpoint.py b/src/main/python/utils/dave_endpoint.py index 6889379..b61482f 100644 --- a/src/main/python/utils/dave_endpoint.py +++ b/src/main/python/utils/dave_endpoint.py @@ -532,7 +532,7 @@ def get_phase_lag_spectrum(src_filename, bck_filename, gti_filename, target, def get_rms_spectrum(src_filename, bck_filename, gti_filename, target, filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands): + freq_range, energy_range, n_bands, x_type): src_destination = get_destination(src_filename, target) if not src_destination: return common_error("Invalid file or cache key for source data") @@ -563,10 +563,11 @@ def get_rms_spectrum(src_filename, bck_filename, gti_filename, target, logging.debug("get_rms_spectrum: freq_range %s" % freq_range) logging.debug("get_rms_spectrum: energy_range %s" % energy_range) logging.debug("get_rms_spectrum: n_bands %s" % n_bands) + logging.debug("get_rms_spectrum: x_type %s" % x_type) data = DaveEngine.get_rms_spectrum(src_destination, bck_destination, gti_destination, filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands) + freq_range, energy_range, n_bands, x_type) logging.debug("get_rms_spectrum: Finish!") diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index 7dc9f9f..d498371 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -1103,11 +1103,12 @@ def get_phase_lag_spectrum(src_destination, bck_destination, gti_destination, # @param: energy_range: A tuple with minimum and maximum values of the # range of energy, send [-1, -1] for use all energies # @param: n_bands: The number of bands to split the refence band +# @param: x_type: Defines de values for x_axis data, "energy" by default or "countrate" # def get_rms_spectrum(src_destination, bck_destination, gti_destination, filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands): - energy_arr = [] + freq_range, energy_range, n_bands, x_type): + xaxis_arr = [] rms_arr =[] rms_err_arr = [] duration = [] @@ -1128,6 +1129,9 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, if segm_size == 0: segm_size = None + if x_type not in ['energy', 'countrate']: + x_type = "energy" + # Prepares GTI if passed base_gti = load_gti_from_destination (gti_destination) @@ -1163,7 +1167,10 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, energy_low = min_energy + (i * energy_step) energy_high = energy_low + energy_step - energy_arr.extend([(energy_low + energy_high) / 2]) + + if x_type == "energy": + xaxis_arr.extend([(energy_low + energy_high) / 2]) + rms, rms_err = 0, 0 try: @@ -1178,6 +1185,9 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, lc = evt_list.to_lc(dt) if lc: + if x_type == "countrate": + xaxis_arr.extend([lc.meanrate]) + gti = base_gti if not gti: gti = lc.gti @@ -1233,6 +1243,13 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, rms_arr.extend([rms]) rms_err_arr.extend([rms_err]) + # If x_type is countrate we need to sort values + if x_type == "countrate": + sorted_idx = np.argsort(xaxis_arr) + xaxis_arr = np.array(xaxis_arr)[sorted_idx] + rms_arr = np.array(rms_arr)[sorted_idx] + rms_err_arr = np.array(rms_err_arr)[sorted_idx] + else: logging.warn('get_rms_spectrum: E column not found!') warnmsg = ['E column not found'] @@ -1248,7 +1265,7 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, warnmsg = [ExHelper.getWarnMsg()] # Preapares the result - result = push_to_results_array([], energy_arr) + result = push_to_results_array([], xaxis_arr) result = push_to_results_array_with_errors(result, rms_arr, rms_err_arr) result = push_to_results_array(result, duration) result = push_to_results_array(result, warnmsg) diff --git a/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js b/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js index aa65250..4c60fd9 100644 --- a/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js +++ b/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js @@ -580,7 +580,7 @@ function WfOutputPanel (id, classSelector, container, service, onFiltersChangedF gti_filename: projectConfig.gtiFilename, styles:{ type: "2d", labels: ["Energy(keV)", "Covariance"], - title: "Covariance Spectrum" } + title: "Covariance spectrum" } }, this.service.request_covariance_spectrum, this.onFiltersChangedFromPlot, @@ -595,21 +595,31 @@ function WfOutputPanel (id, classSelector, container, service, onFiltersChangedF if (this.waitingPlotType != "covariance") { covarianceSpectrumPlot.hide(); } this.appendPlot(covarianceSpectrumPlot, true); - var rmsPlot = this.getRMSPlot ( projectConfig, + var rmsEnergyPlot = this.getRMSPlot ( projectConfig, projectConfig.filename, projectConfig.bckFilename, projectConfig.gtiFilename, - "EVENTS", "PHA", "fullWidth", "RMS vs Energy" ) - this.plots.push(rmsPlot); - projectConfig.addPlotId(rmsPlot.id, "RMF"); - if (this.waitingPlotType != "rms") { rmsPlot.hide(); } - this.appendPlot(rmsPlot, true); + "EVENTS", "PHA", "fullWidth", "RMS vs Energy", null, "energy"); + this.plots.push(rmsEnergyPlot); + projectConfig.addPlotId(rmsEnergyPlot.id, "RMF"); + if (this.waitingPlotType != "rmsEnergy") { rmsEnergyPlot.hide(); } + this.appendPlot(rmsEnergyPlot, true); + + var rmsCountRatePlot = this.getRMSPlot ( projectConfig, + projectConfig.filename, + projectConfig.bckFilename, + projectConfig.gtiFilename, + "EVENTS", "PHA", "fullWidth", "RMS vs Count Rate", null, "countrate"); + this.plots.push(rmsCountRatePlot); + projectConfig.addPlotId(rmsCountRatePlot.id, "RMF"); + if (this.waitingPlotType != "rmsCountRate") { rmsCountRatePlot.hide(); } + this.appendPlot(rmsCountRatePlot, true); var phaseLagPlot = this.getPhaseLagPlot ( projectConfig, projectConfig.filename, projectConfig.bckFilename, projectConfig.gtiFilename, - "EVENTS", "PHA", "fullWidth", "Phase lag vs Energy" ) + "EVENTS", "PHA", "fullWidth", "Phase lag vs Energy"); this.plots.push(phaseLagPlot); projectConfig.addPlotId(phaseLagPlot.id, "RMF"); if (this.waitingPlotType != "phaseLag") { phaseLagPlot.hide(); } @@ -672,7 +682,7 @@ function WfOutputPanel (id, classSelector, container, service, onFiltersChangedF } this.getRMSPlot = function ( projectConfig, filename, bck_filename, gti_filename, tableName, columnName, - cssClass, title, mandatoryFilters ) { + cssClass, title, mandatoryFilters, x_axis_type ) { log("getRMSPlot: filename: " + filename ); return new RmsPlot( @@ -683,11 +693,13 @@ function WfOutputPanel (id, classSelector, container, service, onFiltersChangedF bck_filename: bck_filename, gti_filename: gti_filename, styles: { type: "ligthcurve", - labels: ["Energy(keV)", "RMS"], + labels: [ (x_axis_type != "countrate") ? "Energy(keV)" : "Count Rate (c/s)", + "RMS"], title: title }, axis: [ { table: tableName, column:CONFIG.TIME_COLUMN }, { table: tableName, column:columnName } ], mandatoryFilters: mandatoryFilters, + x_axis_type: x_axis_type }, this.service.request_rms_spectrum, this.onFiltersChangedFromPlot, diff --git a/src/main/resources/static/scripts/plots/rmsPlot.js b/src/main/resources/static/scripts/plots/rmsPlot.js index 51f0e59..b071a06 100644 --- a/src/main/resources/static/scripts/plots/rmsPlot.js +++ b/src/main/resources/static/scripts/plots/rmsPlot.js @@ -5,6 +5,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot plotConfig.freq_range = [-1, -1]; plotConfig.energy_range = [-1, -1]; plotConfig.default_energy_range = [-1, -1]; + plotConfig.x_type = (plotConfig.x_axis_type != "countrate") ? "energy" : "countrate"; this.freq_range_title = "RMS Frequency Range (Hz):"; @@ -53,7 +54,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot this.getLabel = function (axis) { return this.plotConfig.styles.labels[axis]; } - + log ("new RmsPlot id: " + this.id); return this; diff --git a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js index 3f60e21..7630ce6 100644 --- a/src/main/resources/static/scripts/tabPanels/wfTabpanel.js +++ b/src/main/resources/static/scripts/tabPanels/wfTabpanel.js @@ -288,7 +288,8 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel currentObj.outputPanel.addRmfPlots(currentObj.projectConfig); //Hides upload RMF buttons from Analyze tab - currentObj.toolPanel.$html.find(".rmsBtn").remove(); + currentObj.toolPanel.$html.find(".rmsEnergyBtn").remove(); + currentObj.toolPanel.$html.find(".rmsCountRateBtn").remove(); currentObj.toolPanel.$html.find(".covarianceBtn").remove(); currentObj.toolPanel.$html.find(".phaseLagBtn").remove(); @@ -444,12 +445,17 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel function () { currentObj.showUploadRMFDialog("covariance") }, timingPlotsButtons); - timingPlotsButtons = currentObj.addButtonToArray("RMS spectrum", - "rmsBtn", - function () { currentObj.showUploadRMFDialog("rms") }, + timingPlotsButtons = currentObj.addButtonToArray("RMS vs Energy", + "rmsEnergyBtn", + function () { currentObj.showUploadRMFDialog("rmsEnergy") }, timingPlotsButtons); - timingPlotsButtons = currentObj.addButtonToArray("Phase Lag spectrum", + timingPlotsButtons = currentObj.addButtonToArray("RMS vs Count Rate", + "rmsCountRateBtn", + function () { currentObj.showUploadRMFDialog("rmsCountRate") }, + timingPlotsButtons); + + timingPlotsButtons = currentObj.addButtonToArray("Phase lag vs Energy", "phaseLagBtn", function () { currentObj.showUploadRMFDialog("phaseLag") }, timingPlotsButtons); @@ -716,7 +722,7 @@ function WfTabPanel (id, classSelector, navItemClass, service, navBarList, panel //Show upload RMF file var $uploadRMFDialog = $('
' + '
' + - '

RMF file is requiered for "Covariance spectrum", "RMS spectrum" and "Phase lag spectrum"

' + + '

RMF file is requiered for "Covariance spectrum", "RMS vs Energy", "RMS vs Count Rate" and "Phase lag spectrum"

' + '
' + '
'); From 566eaf2437427ad23e68fd89834645e0abd921de Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Thu, 30 Nov 2017 00:38:56 +0100 Subject: [PATCH 13/14] Created method rms_vs_counrate for RMS_vs_CountRate plot --- src/main/python/server.py | 13 +- src/main/python/utils/dave_endpoint.py | 48 +++- src/main/python/utils/dave_engine.py | 208 ++++++++++++++++-- .../scripts/outputPanels/wfOutputPanel.js | 10 +- .../resources/static/scripts/plots/rmsPlot.js | 7 +- src/main/resources/static/scripts/service.js | 4 + 6 files changed, 258 insertions(+), 32 deletions(-) diff --git a/src/main/python/server.py b/src/main/python/server.py index cafc18e..eb7c97a 100644 --- a/src/main/python/server.py +++ b/src/main/python/server.py @@ -199,8 +199,17 @@ def get_rms_spectrum(): request.json['filters'], request.json['axis'], float(request.json['dt']), float(request.json['nsegm']), float(request.json['segment_size']), request.json['norm'], request.json['type'], float(request.json['df']), - request.json['freq_range'], request.json['energy_range'], - int(request.json['n_bands']), request.json['x_type']) + request.json['freq_range'], request.json['energy_range'], int(request.json['n_bands'])) + + +@app.route('/get_rms_vs_countrate', methods=['POST']) +def get_rms_vs_countrate(): + return DaveEndpoint.get_rms_vs_countrate(request.json['filename'], + request.json['bck_filename'], request.json['gti_filename'], UPLOADS_TARGET, + request.json['filters'], request.json['axis'], float(request.json['dt']), + float(request.json['nsegm']), float(request.json['segment_size']), + request.json['norm'], request.json['type'], float(request.json['df']), + request.json['freq_range'], request.json['energy_range'], int(request.json['n_bands'])) @app.route('/get_plot_data_from_models', methods=['POST']) diff --git a/src/main/python/utils/dave_endpoint.py b/src/main/python/utils/dave_endpoint.py index b61482f..82bf29e 100644 --- a/src/main/python/utils/dave_endpoint.py +++ b/src/main/python/utils/dave_endpoint.py @@ -532,7 +532,7 @@ def get_phase_lag_spectrum(src_filename, bck_filename, gti_filename, target, def get_rms_spectrum(src_filename, bck_filename, gti_filename, target, filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands, x_type): + freq_range, energy_range, n_bands): src_destination = get_destination(src_filename, target) if not src_destination: return common_error("Invalid file or cache key for source data") @@ -563,17 +563,59 @@ def get_rms_spectrum(src_filename, bck_filename, gti_filename, target, logging.debug("get_rms_spectrum: freq_range %s" % freq_range) logging.debug("get_rms_spectrum: energy_range %s" % energy_range) logging.debug("get_rms_spectrum: n_bands %s" % n_bands) - logging.debug("get_rms_spectrum: x_type %s" % x_type) data = DaveEngine.get_rms_spectrum(src_destination, bck_destination, gti_destination, filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands, x_type) + freq_range, energy_range, n_bands) logging.debug("get_rms_spectrum: Finish!") return json.dumps(data, cls=NPEncoder) +def get_rms_vs_countrate(src_filename, bck_filename, gti_filename, target, + filters, axis, dt, nsegm, segm_size, norm, pds_type, df, + freq_range, energy_range, n_bands): + src_destination = get_destination(src_filename, target) + if not src_destination: + return common_error("Invalid file or cache key for source data") + + bck_destination = "" + if bck_filename: + bck_destination = get_destination(bck_filename, target) + if not bck_destination: + return common_error("Invalid file or cache key for backgrund data") + + gti_destination = "" + if gti_filename: + gti_destination = get_destination(gti_filename, target) + if not gti_destination: + return common_error("Invalid file or cache key for gti data") + + logging.debug("get_rms_vs_countrate src: %s" % src_filename) + logging.debug("get_rms_vs_countrate bck: %s" % bck_filename) + logging.debug("get_rms_vs_countrate gti: %s" % gti_filename) + logging.debug("get_rms_vs_countrate: filters %s" % filters) + logging.debug("get_rms_vs_countrate: axis %s" % axis) + logging.debug("get_rms_vs_countrate: dt %s" % dt) + logging.debug("get_rms_vs_countrate: nsegm %f" % nsegm) + logging.debug("get_rms_vs_countrate: segm_size %f" % segm_size) + logging.debug("get_rms_vs_countrate: norm %s" % norm) + logging.debug("get_rms_vs_countrate: type %s" % pds_type) + logging.debug("get_rms_vs_countrate: df %s" % df) + logging.debug("get_rms_vs_countrate: freq_range %s" % freq_range) + logging.debug("get_rms_vs_countrate: energy_range %s" % energy_range) + logging.debug("get_rms_vs_countrate: n_bands %s" % n_bands) + + data = DaveEngine.get_rms_vs_countrate(src_destination, bck_destination, gti_destination, + filters, axis, dt, nsegm, segm_size, norm, pds_type, df, + freq_range, energy_range, n_bands) + + logging.debug("get_rms_vs_countrate: Finish!") + + return json.dumps(data, cls=NPEncoder) + + def get_plot_data_from_models(models, x_values): logging.debug("get_plot_data_from_models models: %s" % models) diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index d498371..9fa32aa 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -1103,12 +1103,11 @@ def get_phase_lag_spectrum(src_destination, bck_destination, gti_destination, # @param: energy_range: A tuple with minimum and maximum values of the # range of energy, send [-1, -1] for use all energies # @param: n_bands: The number of bands to split the refence band -# @param: x_type: Defines de values for x_axis data, "energy" by default or "countrate" # def get_rms_spectrum(src_destination, bck_destination, gti_destination, filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands, x_type): - xaxis_arr = [] + freq_range, energy_range, n_bands): + energy_arr = [] rms_arr =[] rms_err_arr = [] duration = [] @@ -1129,9 +1128,6 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, if segm_size == 0: segm_size = None - if x_type not in ['energy', 'countrate']: - x_type = "energy" - # Prepares GTI if passed base_gti = load_gti_from_destination (gti_destination) @@ -1168,8 +1164,7 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, energy_low = min_energy + (i * energy_step) energy_high = energy_low + energy_step - if x_type == "energy": - xaxis_arr.extend([(energy_low + energy_high) / 2]) + energy_arr.extend([(energy_low + energy_high) / 2]) rms, rms_err = 0, 0 @@ -1185,9 +1180,6 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, lc = evt_list.to_lc(dt) if lc: - if x_type == "countrate": - xaxis_arr.extend([lc.meanrate]) - gti = base_gti if not gti: gti = lc.gti @@ -1242,14 +1234,6 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, rms_arr.extend([rms]) rms_err_arr.extend([rms_err]) - - # If x_type is countrate we need to sort values - if x_type == "countrate": - sorted_idx = np.argsort(xaxis_arr) - xaxis_arr = np.array(xaxis_arr)[sorted_idx] - rms_arr = np.array(rms_arr)[sorted_idx] - rms_err_arr = np.array(rms_err_arr)[sorted_idx] - else: logging.warn('get_rms_spectrum: E column not found!') warnmsg = ['E column not found'] @@ -1265,7 +1249,191 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, warnmsg = [ExHelper.getWarnMsg()] # Preapares the result - result = push_to_results_array([], xaxis_arr) + result = push_to_results_array([], energy_arr) + result = push_to_results_array_with_errors(result, rms_arr, rms_err_arr) + result = push_to_results_array(result, duration) + result = push_to_results_array(result, warnmsg) + result = push_to_results_array(result, freq_min_max) + return result + + +# get_rms_vs_countrate: +# Returns the energy values and its correlated rms and rms errors +# +# @param: src_destination: source file destination +# @param: bck_destination: background file destination, is optional +# @param: gti_destination: gti file destination, is optional +# @param: filters: array with the filters to apply +# [{ table = "EVENTS", column = "Time", from=0, to=10 }, ... ] +# @param: axis: array with the column names to use in ploting +# [{ table = "EVENTS", column = "TIME" }, +# { table = "EVENTS", column = "PHA" } ] +# @param: dt: The time resolution of the events. +# @param: nsegm: The number of segments for splitting the lightcurve +# @param: segm_size: The segment length for split the lightcurve +# @param: norm: The normalization of the (real part of the) power spectrum. +# @param: pds_type: Type of PDS to use, single or averaged. +# @param: df: If not 0 is the frequency rebining value +# @param: freq_range: A tuple with minimum and maximum values of the +# range of frequency, send [-1, -1] for use all frequencies +# @param: energy_range: A tuple with minimum and maximum values of the +# range of energy, send [-1, -1] for use all energies +# +def get_rms_vs_countrate(src_destination, bck_destination, gti_destination, + filters, axis, dt, nsegm, segm_size, norm, pds_type, df, + freq_range, energy_range, n_bands): + countrate_arr = [] + rms_arr =[] + rms_err_arr = [] + duration = [] + warnmsg = [] + freq_min_max = [-1, -1] + + try: + + if len(axis) != 2: + return common_error("Wrong number of axis") + + if norm not in ['frac', 'abs', 'leahy', 'none']: + return common_error("Wrong normalization") + + if pds_type not in ['Sng', 'Avg']: + return common_error("Wrong power density spectrum type") + + if segm_size == 0: + segm_size = None + + # Prepares GTI if passed + base_gti = load_gti_from_destination (gti_destination) + + filters = FltHelper.get_filters_clean_color_filters(filters) + + filtered_ds = get_filtered_dataset(src_destination, filters, gti_destination) + + if DsHelper.is_events_dataset(filtered_ds): + events_table = filtered_ds.tables["EVENTS"] + if len(events_table.columns[CONFIG.TIME_COLUMN].values) > 0: + min_time = events_table.columns[CONFIG.TIME_COLUMN].values[0] + max_time = events_table.columns[CONFIG.TIME_COLUMN].values[len(events_table.columns[CONFIG.TIME_COLUMN].values) - 1] + duration = [(max_time - min_time)] + + if "E" in events_table.columns: + + event_list = np.column_stack((events_table.columns[CONFIG.TIME_COLUMN].values, + events_table.columns["E"].values)) + + if energy_range[0] < 0: + min_energy = min(event_list[:,1]) + else: + min_energy = energy_range[0] + + if energy_range[1] >= min_energy: + max_energy = energy_range[1] - min_energy + else: + max_energy = max(event_list[:,1]) - min_energy + + event_list = event_list[ (max_energy>event_list[:,1]) & (event_list[:,1]>min_energy) ] + + time_step = duration[0] / n_bands + + for i in range(n_bands): + + time_low = min_energy + (i * time_step) + time_high = time_low + time_step + + try: + filtered_event_list = event_list[ (time_high>event_list[:,0]) & (event_list[:,0]>time_low) ] + if (len(filtered_event_list) > 0): + + evt_list = EventList(filtered_event_list[:,0], pi=filtered_event_list[:,1]) + if evt_list and evt_list.ncounts > 1: + + if (evt_list.time[evt_list.ncounts - 1] - evt_list.time[0]) >= dt: + + lc = evt_list.to_lc(dt) + if lc: + + rms, rms_err = 0, 0 + + gti = base_gti + if not gti: + gti = lc.gti + + if segm_size > lc.tseg: + segm_size = lc.tseg + logging.warn("get_rms_vs_countrate: Time range: " + str(time_low) + " to " + str(time_high) + ", segmsize bigger than lc.duration, lc.duration applied instead.") + + pds = None + if pds_type == 'Sng': + pds = Powerspectrum(lc, norm=norm, gti=gti) + else: + pds = AveragedPowerspectrum(lc=lc, segment_size=segm_size, norm=norm, gti=gti) + + if pds: + + if df > 0: + pds = pds.rebin(df=df) + + #pds = rebin_spectrum_if_necessary(pds) + + if len(pds.freq): + if freq_range[0] < 0: + freq_low = min(pds.freq) + else: + freq_low = freq_range[0] + + if freq_min_max[0] >= 0: + freq_min_max[0] = min([freq_min_max[0], freq_low]) + else: + freq_min_max[0] = freq_low + + if freq_range[1] < 0: + freq_high = max(pds.freq) + else: + freq_high = freq_range[1] + freq_min_max[1] = max([freq_min_max[1], freq_high]) + + rms, rms_err = pds.compute_rms(freq_low, freq_high) + else: + logging.warn("get_rms_vs_countrate: can't create power density spectrum. Time range: " + str(time_low) + " to " + str(time_high)) + + countrate_arr.extend([lc.meanrate]) + rms_arr.extend([rms]) + rms_err_arr.extend([rms_err]) + + else: + logging.warn("get_rms_vs_countrate: can't create lightcurve. Time range: " + str(time_low) + " to " + str(time_high)) + else: + logging.warn("get_rms_vs_countrate: can't create lightcurve. Not enougth duration. Time range: " + str(time_low) + " to " + str(time_high)) + else: + logging.warn("get_rms_vs_countrate: can't create eventlist or counts are 0. Time range: " + str(time_low) + " to " + str(time_high) + ", counts: " + str(len(filtered_event_list))) + else: + logging.warn("get_rms_vs_countrate: Time range: " + str(time_low) + " to " + str(time_high) + " has no events") + except: + logging.warn(ExHelper.getException('get_rms_vs_countrate: Time range: ' + str(time_low) + ' to ' + str(time_high))) + + # If x_type is countrate we need to sort values + sorted_idx = np.argsort(countrate_arr) + countrate_arr = np.array(countrate_arr)[sorted_idx] + rms_arr = np.array(rms_arr)[sorted_idx] + rms_err_arr = np.array(rms_err_arr)[sorted_idx] + + else: + logging.warn('get_rms_vs_countrate: E column not found!') + warnmsg = ['E column not found'] + else: + logging.warn('get_rms_vs_countrate: No events data!') + warnmsg = ['No events data'] + else: + logging.warn('get_rms_vs_countrate: Wrong dataset type!') + warnmsg = ['Wrong dataset type'] + + except: + logging.error(ExHelper.getException('get_rms_vs_countrate')) + warnmsg = [ExHelper.getWarnMsg()] + + # Preapares the result + result = push_to_results_array([], countrate_arr) result = push_to_results_array_with_errors(result, rms_arr, rms_err_arr) result = push_to_results_array(result, duration) result = push_to_results_array(result, warnmsg) diff --git a/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js b/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js index 4c60fd9..1d16be0 100644 --- a/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js +++ b/src/main/resources/static/scripts/outputPanels/wfOutputPanel.js @@ -686,14 +686,16 @@ function WfOutputPanel (id, classSelector, container, service, onFiltersChangedF log("getRMSPlot: filename: " + filename ); return new RmsPlot( - this.generatePlotId("rms_" + filename), + this.generatePlotId("rms_" + x_axis_type + "_" + filename), { selectorKey: "SRC", filename: filename, bck_filename: bck_filename, gti_filename: gti_filename, styles: { type: "ligthcurve", - labels: [ (x_axis_type != "countrate") ? "Energy(keV)" : "Count Rate (c/s)", + labels: [ (x_axis_type != "countrate") ? + "Energy(keV)" : + "Count Rate (c/s)", "RMS"], title: title }, axis: [ { table: tableName, column:CONFIG.TIME_COLUMN }, @@ -701,7 +703,9 @@ function WfOutputPanel (id, classSelector, container, service, onFiltersChangedF mandatoryFilters: mandatoryFilters, x_axis_type: x_axis_type }, - this.service.request_rms_spectrum, + (x_axis_type != "countrate") ? + this.service.request_rms_spectrum : + this.service.request_rms_vs_countrate, this.onFiltersChangedFromPlot, this.onPlotReady, getTabForSelector(this.id).$html.find(".TimingPlot").find(".sectionContainer"), diff --git a/src/main/resources/static/scripts/plots/rmsPlot.js b/src/main/resources/static/scripts/plots/rmsPlot.js index b071a06..9e5f964 100644 --- a/src/main/resources/static/scripts/plots/rmsPlot.js +++ b/src/main/resources/static/scripts/plots/rmsPlot.js @@ -5,9 +5,8 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot plotConfig.freq_range = [-1, -1]; plotConfig.energy_range = [-1, -1]; plotConfig.default_energy_range = [-1, -1]; - plotConfig.x_type = (plotConfig.x_axis_type != "countrate") ? "energy" : "countrate"; - this.freq_range_title = "RMS Frequency Range (Hz):"; + this.freq_range_title = (plotConfig.x_axis_type != "countrate") ? "RMS Frequency Range (Hz):" : "Frequency Range (Hz):"; if (projectConfig.schema.isEventsFile()) { var column = projectConfig.schema.getTable()["E"]; @@ -16,7 +15,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot //Adds Reference Band filter plotConfig.energy_range = [column.min_value, column.max_value]; plotConfig.default_energy_range = [column.min_value, column.max_value]; - plotConfig.n_bands = Math.floor(column.max_value - column.min_value); + plotConfig.n_bands = (plotConfig.x_axis_type != "countrate") ? Math.floor(column.max_value - column.min_value) : 20; } else { log("RmsPlot error, plot" + currentObj.id + ", NO ENERGY COLUMN ON SCHEMA"); @@ -48,7 +47,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot this.addEnergyRangeControlToSetting("Energy range (keV)", ".rightCol"); //Adds number of point control of rms plot - this.addNumberOfBandsControlToSettings("Nº Energy Segments", ".rightCol"); + this.addNumberOfBandsControlToSettings((plotConfig.x_axis_type != "countrate") ? "Nº Energy Segments" : "Nº Time Segments", ".rightCol"); } this.getLabel = function (axis) { diff --git a/src/main/resources/static/scripts/service.js b/src/main/resources/static/scripts/service.js index a9a3508..0a0e8cf 100644 --- a/src/main/resources/static/scripts/service.js +++ b/src/main/resources/static/scripts/service.js @@ -129,6 +129,10 @@ function Service (base_url) { return thisService.make_ajax_call("get_rms_spectrum", data, fn); }; + this.request_rms_vs_countrate = function ( data, fn ) { + return thisService.make_ajax_call("get_rms_vs_countrate", data, fn); + }; + this.request_plot_data_from_models = function ( data, fn ) { return thisService.make_ajax_call("get_plot_data_from_models", data, fn); }; From 9ece7a16828511aa85deaadd5747ac432a52f5f1 Mon Sep 17 00:00:00 2001 From: Ricardo Valles Blanco Date: Fri, 1 Dec 2017 01:07:35 +0100 Subject: [PATCH 14/14] Fix wrong approach for RMS vs CountRate plot --- src/main/python/server.py | 5 +-- src/main/python/utils/dave_endpoint.py | 10 +---- src/main/python/utils/dave_engine.py | 40 ++++--------------- .../static/scripts/plots/plotWithSettings.js | 6 ++- .../resources/static/scripts/plots/rmsPlot.js | 21 ++++++++-- 5 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/main/python/server.py b/src/main/python/server.py index eb7c97a..36c22b1 100644 --- a/src/main/python/server.py +++ b/src/main/python/server.py @@ -207,9 +207,8 @@ def get_rms_vs_countrate(): return DaveEndpoint.get_rms_vs_countrate(request.json['filename'], request.json['bck_filename'], request.json['gti_filename'], UPLOADS_TARGET, request.json['filters'], request.json['axis'], float(request.json['dt']), - float(request.json['nsegm']), float(request.json['segment_size']), - request.json['norm'], request.json['type'], float(request.json['df']), - request.json['freq_range'], request.json['energy_range'], int(request.json['n_bands'])) + int(request.json['n_bands']), float(request.json['df']), + request.json['freq_range'], request.json['energy_range']) @app.route('/get_plot_data_from_models', methods=['POST']) diff --git a/src/main/python/utils/dave_endpoint.py b/src/main/python/utils/dave_endpoint.py index 82bf29e..9813dc4 100644 --- a/src/main/python/utils/dave_endpoint.py +++ b/src/main/python/utils/dave_endpoint.py @@ -574,8 +574,7 @@ def get_rms_spectrum(src_filename, bck_filename, gti_filename, target, def get_rms_vs_countrate(src_filename, bck_filename, gti_filename, target, - filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands): + filters, axis, dt, nsegm, df, freq_range, energy_range): src_destination = get_destination(src_filename, target) if not src_destination: return common_error("Invalid file or cache key for source data") @@ -599,17 +598,12 @@ def get_rms_vs_countrate(src_filename, bck_filename, gti_filename, target, logging.debug("get_rms_vs_countrate: axis %s" % axis) logging.debug("get_rms_vs_countrate: dt %s" % dt) logging.debug("get_rms_vs_countrate: nsegm %f" % nsegm) - logging.debug("get_rms_vs_countrate: segm_size %f" % segm_size) - logging.debug("get_rms_vs_countrate: norm %s" % norm) - logging.debug("get_rms_vs_countrate: type %s" % pds_type) logging.debug("get_rms_vs_countrate: df %s" % df) logging.debug("get_rms_vs_countrate: freq_range %s" % freq_range) logging.debug("get_rms_vs_countrate: energy_range %s" % energy_range) - logging.debug("get_rms_vs_countrate: n_bands %s" % n_bands) data = DaveEngine.get_rms_vs_countrate(src_destination, bck_destination, gti_destination, - filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands) + filters, axis, dt, nsegm, df, freq_range, energy_range) logging.debug("get_rms_vs_countrate: Finish!") diff --git a/src/main/python/utils/dave_engine.py b/src/main/python/utils/dave_engine.py index 9fa32aa..f4147ee 100644 --- a/src/main/python/utils/dave_engine.py +++ b/src/main/python/utils/dave_engine.py @@ -1119,7 +1119,7 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, if len(axis) != 2: return common_error("Wrong number of axis") - if norm not in ['frac', 'abs', 'leahy', 'none']: + if norm not in ['frac', 'leahy']: return common_error("Wrong normalization") if pds_type not in ['Sng', 'Avg']: @@ -1178,7 +1178,7 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, if (evt_list.time[evt_list.ncounts - 1] - evt_list.time[0]) >= dt: lc = evt_list.to_lc(dt) - if lc: + if lc and np.sqrt(lc.meancounts * lc.meancounts) > 0: gti = base_gti if not gti: @@ -1222,7 +1222,7 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, else: logging.warn("get_rms_spectrum: can't create power density spectrum. Energy range: " + str(energy_low) + " to " + str(energy_high)) else: - logging.warn("get_rms_spectrum: can't create lightcurve. Energy range: " + str(energy_low) + " to " + str(energy_high)) + logging.warn("get_rms_spectrum: can't create lightcurve or is invalid. Energy range: " + str(energy_low) + " to " + str(energy_high)) else: logging.warn("get_rms_spectrum: can't create lightcurve. Not enougth duration. Energy range: " + str(energy_low) + " to " + str(energy_high)) else: @@ -1270,9 +1270,6 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, # { table = "EVENTS", column = "PHA" } ] # @param: dt: The time resolution of the events. # @param: nsegm: The number of segments for splitting the lightcurve -# @param: segm_size: The segment length for split the lightcurve -# @param: norm: The normalization of the (real part of the) power spectrum. -# @param: pds_type: Type of PDS to use, single or averaged. # @param: df: If not 0 is the frequency rebining value # @param: freq_range: A tuple with minimum and maximum values of the # range of frequency, send [-1, -1] for use all frequencies @@ -1280,8 +1277,7 @@ def get_rms_spectrum(src_destination, bck_destination, gti_destination, # range of energy, send [-1, -1] for use all energies # def get_rms_vs_countrate(src_destination, bck_destination, gti_destination, - filters, axis, dt, nsegm, segm_size, norm, pds_type, df, - freq_range, energy_range, n_bands): + filters, axis, dt, nsegm, df, freq_range, energy_range): countrate_arr = [] rms_arr =[] rms_err_arr = [] @@ -1294,15 +1290,6 @@ def get_rms_vs_countrate(src_destination, bck_destination, gti_destination, if len(axis) != 2: return common_error("Wrong number of axis") - if norm not in ['frac', 'abs', 'leahy', 'none']: - return common_error("Wrong normalization") - - if pds_type not in ['Sng', 'Avg']: - return common_error("Wrong power density spectrum type") - - if segm_size == 0: - segm_size = None - # Prepares GTI if passed base_gti = load_gti_from_destination (gti_destination) @@ -1334,9 +1321,9 @@ def get_rms_vs_countrate(src_destination, bck_destination, gti_destination, event_list = event_list[ (max_energy>event_list[:,1]) & (event_list[:,1]>min_energy) ] - time_step = duration[0] / n_bands + time_step = duration[0] / nsegm - for i in range(n_bands): + for i in range(nsegm): time_low = min_energy + (i * time_step) time_high = time_low + time_step @@ -1351,7 +1338,7 @@ def get_rms_vs_countrate(src_destination, bck_destination, gti_destination, if (evt_list.time[evt_list.ncounts - 1] - evt_list.time[0]) >= dt: lc = evt_list.to_lc(dt) - if lc: + if lc and np.sqrt(lc.meancounts * lc.meancounts) > 0: rms, rms_err = 0, 0 @@ -1359,23 +1346,12 @@ def get_rms_vs_countrate(src_destination, bck_destination, gti_destination, if not gti: gti = lc.gti - if segm_size > lc.tseg: - segm_size = lc.tseg - logging.warn("get_rms_vs_countrate: Time range: " + str(time_low) + " to " + str(time_high) + ", segmsize bigger than lc.duration, lc.duration applied instead.") - - pds = None - if pds_type == 'Sng': - pds = Powerspectrum(lc, norm=norm, gti=gti) - else: - pds = AveragedPowerspectrum(lc=lc, segment_size=segm_size, norm=norm, gti=gti) - + pds = Powerspectrum(lc, norm='frac', gti=gti) if pds: if df > 0: pds = pds.rebin(df=df) - #pds = rebin_spectrum_if_necessary(pds) - if len(pds.freq): if freq_range[0] < 0: freq_low = min(pds.freq) diff --git a/src/main/resources/static/scripts/plots/plotWithSettings.js b/src/main/resources/static/scripts/plots/plotWithSettings.js index 39ac303..c2b938f 100644 --- a/src/main/resources/static/scripts/plots/plotWithSettings.js +++ b/src/main/resources/static/scripts/plots/plotWithSettings.js @@ -166,8 +166,10 @@ function PlotWithSettings(id, plotConfig, getDataFromServerFn, onFiltersChangedF //Adds energy range selector this.onEnergyRangeValuesChanged = function() { - currentObj.plotConfig.n_bands = Math.max.apply(Math, [1, Math.floor(currentObj.energyRangeSelector.toValue - currentObj.energyRangeSelector.fromValue)]); - currentObj.settingsPanel.find(".inputNBands").val(currentObj.plotConfig.n_bands); + if (plotConfig.x_axis_type != "countrate"){ + currentObj.plotConfig.n_bands = Math.max.apply(Math, [1, Math.floor(currentObj.energyRangeSelector.toValue - currentObj.energyRangeSelector.fromValue)]); + currentObj.settingsPanel.find(".inputNBands").val(currentObj.plotConfig.n_bands); + } currentObj.plotConfig.energy_range = [currentObj.energyRangeSelector.fromValue, currentObj.energyRangeSelector.toValue]; } diff --git a/src/main/resources/static/scripts/plots/rmsPlot.js b/src/main/resources/static/scripts/plots/rmsPlot.js index 9e5f964..c093f7a 100644 --- a/src/main/resources/static/scripts/plots/rmsPlot.js +++ b/src/main/resources/static/scripts/plots/rmsPlot.js @@ -1,7 +1,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlotReadyFn, toolbar, cssClass, switchable, projectConfig) { var currentObj = this; - plotConfig.n_bands = 10; + plotConfig.n_bands = 25; plotConfig.freq_range = [-1, -1]; plotConfig.energy_range = [-1, -1]; plotConfig.default_energy_range = [-1, -1]; @@ -15,7 +15,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot //Adds Reference Band filter plotConfig.energy_range = [column.min_value, column.max_value]; plotConfig.default_energy_range = [column.min_value, column.max_value]; - plotConfig.n_bands = (plotConfig.x_axis_type != "countrate") ? Math.floor(column.max_value - column.min_value) : 20; + plotConfig.n_bands = (plotConfig.x_axis_type != "countrate") ? Math.min(Math.floor(column.max_value - column.min_value), 25) : 25; } else { log("RmsPlot error, plot" + currentObj.id + ", NO ENERGY COLUMN ON SCHEMA"); @@ -29,6 +29,13 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot this.plotConfig.xAxisType = "linear"; this.plotConfig.yAxisType = "linear"; this.plotConfig.plotType = "X"; + this.plotConfig.norm = "frac"; + this.plotConfig.type = "Sng"; + + if (plotConfig.x_axis_type == "countrate"){ + this.plotConfig.nsegm = 0; + this.plotConfig.segment_size = 0; + } this.onSettingsCreated = function(){ @@ -37,6 +44,7 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot this.xAxisRadios.hide(); this.yAxisRadios.hide(); this.plotTypeRadios.hide(); + this.normRadios.hide(); //Adds frequency range selector this.addFrequencyRangeSelector(this.freq_range_title, @@ -47,7 +55,14 @@ function RmsPlot(id, plotConfig, getDataFromServerFn, onFiltersChangedFn, onPlot this.addEnergyRangeControlToSetting("Energy range (keV)", ".rightCol"); //Adds number of point control of rms plot - this.addNumberOfBandsControlToSettings((plotConfig.x_axis_type != "countrate") ? "Nº Energy Segments" : "Nº Time Segments", ".rightCol"); + if (plotConfig.x_axis_type != "countrate"){ + this.addNumberOfBandsControlToSettings("Nº Energy Segments", ".rightCol"); + } else { + this.typeRadios.hide(); + this.segmSelector.$html.hide(); + this.rebinSelector.$html.hide(); + this.addNumberOfBandsControlToSettings("Nº Time Segments", ".leftCol"); + } } this.getLabel = function (axis) {