diff --git a/.gitignore b/.gitignore
index 5bf21e1c9..809a02e39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,6 @@ css/custom.css
# file marking a development version
.hrm_devel_version
+
+# Composer's vendor folder
+/vendor/
diff --git a/README.md b/README.md
index b57353ced..fd6916568 100644
--- a/README.md
+++ b/README.md
@@ -6,3 +6,35 @@ The Huygens Remote Manager is an open-source, efficient, multi-user web-based in
For more information please see:
* [HRM project website](http://huygens-rm.org/)
* [HRM documentation on ReadTheDocs.org](http://huygens-remote-manager.readthedocs.org/en/latest/)
+ * [HRM API](http://api.huygens-rm.org/html/index.html)
+
+Download and install dependences for development
+------------------------------------------------
+
+In the console, run:
+
+```bash
+$ cd $HRM_ROOT
+$ ./setup/setup_devel.sh
+```
+
+This will update composer, and download and install all third-party libraries used for development. Please notice that the the development dependencies are way more than those needed for release (see below).
+
+Package an HRM release
+----------------------
+
+In the console, run:
+
+```bash
+$ cd $HRM_ROOT
+$ ./setup/package_release.sh workdir archive_name
+```
+
+This will update composer, download and install all third-party libraries necessary for the release version of HRM, and then package everything into a zip file ready for distribution.
+
+Example:
+
+```bash
+$ cd $HRM_ROOT
+$ ./setup/package_release.sh /tmp ~/hrm_3.4.0.zip
+```
diff --git a/aberration_correction.php b/aberration_correction.php
index c99d73232..c1d7b63d0 100644
--- a/aberration_correction.php
+++ b/aberration_correction.php
@@ -2,12 +2,18 @@
// This file is part of the Huygens Remote Manager
// Copyright and license notice: see license.txt
-require_once("./inc/User.inc.php");
-require_once("./inc/Parameter.inc.php");
-require_once("./inc/Setting.inc.php");
-require_once("./inc/Util.inc.php");
-require_once("./inc/System.inc.php");
-require_once("./inc/wiki_help.inc.php");
+use hrm\DatabaseConnection;
+use hrm\Nav;
+use hrm\param\AberrationCorrectionMode;
+use hrm\param\AdvancedCorrectionOptions;
+use hrm\param\base\Parameter;
+use hrm\param\CoverslipRelativePosition;
+use hrm\param\ImageFileFormat;
+use hrm\param\PerformAberrationCorrection;
+use hrm\param\PSFGenerationDepth;
+
+require_once dirname(__FILE__) . '/inc/bootstrap.php';
+
/* *****************************************************************************
*
@@ -18,7 +24,8 @@
session_start();
if (!isset($_SESSION['user']) || !$_SESSION['user']->isLoggedIn()) {
- header("Location: " . "login.php"); exit();
+ header("Location: " . "login.php");
+ exit();
}
$message = "";
@@ -31,11 +38,12 @@
/* In this page, all parameters are required! */
$parameterNames = $_SESSION['setting']->correctionParameterNames();
$db = new DatabaseConnection();
-foreach ( $parameterNames as $name ) {
- $parameter = $_SESSION['setting']->parameter( $name );
- $confidenceLevel = $db->getParameterConfidenceLevel( '', $name );
- $parameter->setConfidenceLevel( $confidenceLevel );
- $_SESSION['setting']->set( $parameter );
+foreach ($parameterNames as $name) {
+ /** @var Parameter $parameter */
+ $parameter = $_SESSION['setting']->parameter($name);
+ $confidenceLevel = $db->getParameterConfidenceLevel('', $name);
+ $parameter->setConfidenceLevel($confidenceLevel);
+ $_SESSION['setting']->set($parameter);
}
/* *****************************************************************************
@@ -44,14 +52,15 @@
*
**************************************************************************** */
-if ( $_SESSION['setting']->checkPostedAberrationCorrectionParameters( $_POST ) ) {
- $saved = $_SESSION['setting']->save();
- $message = $_SESSION['setting']->message();
- if ($saved) {
- header("Location: select_parameter_settings.php" ); exit();
- }
+if ($_SESSION['setting']->checkPostedAberrationCorrectionParameters($_POST)) {
+ $saved = $_SESSION['setting']->save();
+ $message = $_SESSION['setting']->message();
+ if ($saved) {
+ header("Location: select_parameter_settings.php");
+ exit();
+ }
} else {
- $message = $_SESSION['setting']->message();
+ $message = $_SESSION['setting']->message();
}
@@ -61,9 +70,9 @@
*
**************************************************************************** */
-if ( $_SESSION['setting']->isSted() || $_SESSION['setting']->isSted3D()) {
+if ($_SESSION['setting']->isSted() || $_SESSION['setting']->isSted3D()) {
$back = "sted_parameters.php";
-} else if ( $_SESSION['setting']->isSpim()) {
+} else if ($_SESSION['setting']->isSpim()) {
$back = "spim_parameters.php";
} else {
$back = "capturing_parameter.php";
@@ -76,24 +85,24 @@
**************************************************************************** */
// Javascript includes
-$script = array( "settings.js", "quickhelp/help.js",
- "quickhelp/aberrationCorrectionHelp.js" );
+$script = array("settings.js", "quickhelp/help.js",
+ "quickhelp/aberrationCorrectionHelp.js");
include("header.inc.php");
?>
-
-
+
+
Go back to previous page.
-
+
Abort editing and go back to the image parameters selection page.
All changes will be lost!
-
+
Save and return to the image parameters selection page.
@@ -101,28 +110,28 @@
-
[ name(); ?> ]
+
[ name(); ?> ]
name()));
?>
-
+
-
Spherical aberration correction
+
Spherical aberration correction
-
-
+
-
+
-
+
-
Quick help
+
Quick help
-
+
The main cause of spherical aberration is a mismatch between
the refractive index of the lens immersion medium and specimen
embedding medium and causes the PSF to become asymmetric at
depths of already a few µm. SA is especially harmful for
widefield microscope deconvolution. The HRM can correct for SA
automatically, but in case of very large refractive index
- mismatches some artifacts can be generated. Advanced parameters
+ mismatches some artifacts can be generated. Advanced parameters
allow for fine-tuning of the correction.
");
- $("#update").on("click", function() {
+ updateDiv.on("click", function () {
openWindow("http://huygens-rm.org/home/?q=node/4");
});
- $("#update").show();
- return;
+ updateDiv.show();
+
}
)
}
// Hide the "update" div in the beginning
- $(document).ready(function() {
+ $(document).ready(function () {
$("#update").hide();
});
@@ -510,21 +548,23 @@ function checkForUpdates() {
?>
// Update job information
- $(document).ready(function() {
+ $(document).ready(function () {
// Fill in the information about jobs in the queue as soon as the
// page is ready
update();
// Set up timer for the repeated update
- var interval = window.setInterval(function() { update(); }, 5000);
+ window.setInterval(function () {
+ update();
+ }, 5000);
// Function that queries the server via an Ajax call
function update() {
ajaxGetNumberOfUserJobsInQueue(
- 'jobsInQueue',
- '
See all jobs. You have ',
- ' in the queue.
');
+ 'jobsInQueue',
+ '
See all jobs. You have ',
+ ' in the queue.
');
}
});
diff --git a/image_format.php b/image_format.php
index a0beb8158..9db1ce4f6 100644
--- a/image_format.php
+++ b/image_format.php
@@ -2,11 +2,14 @@
// This file is part of the Huygens Remote Manager
// Copyright and license notice: see license.txt
-require_once("./inc/User.inc.php");
-require_once("./inc/Parameter.inc.php");
-require_once("./inc/Setting.inc.php");
-require_once("./inc/System.inc.php");
-require_once("./inc/wiki_help.inc.php");
+use hrm\DatabaseConnection;
+use hrm\Nav;
+use hrm\param\base\Parameter;
+use hrm\setting\ParameterSetting;
+use hrm\Util;
+
+require_once dirname(__FILE__) . '/inc/bootstrap.php';
+
/* *****************************************************************************
*
@@ -16,16 +19,18 @@
session_start();
-if ( !isset( $_SESSION[ 'user' ] ) || !$_SESSION[ 'user' ]->isLoggedIn() ) {
- header("Location: " . "login.php"); exit();
+if (!isset($_SESSION['user']) || !$_SESSION['user']->isLoggedIn()) {
+ header("Location: " . "login.php");
+ exit();
}
if (isset($_GET['home'])) {
- header("Location: " . "home.php"); exit();
+ header("Location: " . "home.php");
+ exit();
}
-if ( !isset( $_SESSION[ 'setting' ] ) ) {
- $_SESSION['setting'] = new ParameterSetting();
+if (!isset($_SESSION['setting'])) {
+ $_SESSION['setting'] = new ParameterSetting();
}
$message = "";
@@ -42,11 +47,11 @@
*/
$parameterNames = $_SESSION['setting']->imageParameterNames();
$db = new DatabaseConnection();
-foreach ( $parameterNames as $name ) {
- $parameter = $_SESSION['setting']->parameter( $name );
- $confidenceLevel = $db->getParameterConfidenceLevel( '', $name );
- $parameter->setConfidenceLevel( $confidenceLevel );
- $_SESSION['setting']->set( $parameter );
+foreach ($parameterNames as $name) {
+ $parameter = $_SESSION['setting']->parameter($name);
+ $confidenceLevel = $db->getParameterConfidenceLevel('', $name);
+ $parameter->setConfidenceLevel($confidenceLevel);
+ $_SESSION['setting']->set($parameter);
}
/* *****************************************************************************
@@ -55,17 +60,18 @@
*
**************************************************************************** */
-if ( $_SESSION[ 'setting' ]->checkPostedImageParameters( $_POST ) ) {
+if ($_SESSION['setting']->checkPostedImageParameters($_POST)) {
- // Now we force all variable channel parameters to have the correct number
- // of channels
- $_SESSION[ 'setting' ]->setNumberOfChannels(
- $_SESSION[ 'setting']->numberOfChannels( ) );
+ // Now we force all variable channel parameters to have the correct number
+ // of channels
+ $_SESSION['setting']->setNumberOfChannels(
+ $_SESSION['setting']->numberOfChannels());
- // Continue to the next page
- header("Location: " . "microscope_parameter.php"); exit();
+ // Continue to the next page
+ header("Location: " . "microscope_parameter.php");
+ exit();
} else {
- $message = $_SESSION['setting']->message();
+ $message = $_SESSION['setting']->message();
}
/* *****************************************************************************
@@ -75,289 +81,295 @@
**************************************************************************** */
// Javascript includes
-$script = array( "settings.js", "quickhelp/help.js", "quickhelp/imageFormat.js");
+$script = array("settings.js", "quickhelp/help.js", "quickhelp/imageFormat.js");
include("header.inc.php");
?>
-
-
+
+
Abort editing and go back to the image parameters selection page.
All changes will be lost!
-
+
Continue to next page.
-
+
Here you are asked to define the number of channels in your
- data and whether you want to use a theoretical PSF or a
- measured PSF you distilled with the Huygens Software.
-
+
+
Here you are asked to define the number of channels in your
+ data and whether you want to use a theoretical PSF or a
+ measured PSF you distilled with the Huygens Software.
connection = ADONewConnection($db_type);
- $this->connection->Connect($db_host, $db_user, $db_password, $db_name);
-
- // Set the parameter name dictionary
- $this-> parameterNameDictionary = array(
- "CCDCaptorSizeX" => "sampleSizesX", // In HRM there is no distinction between x and y pixel size
- "ZStepSize" => "sampleSizesZ",
- "TimeInterval" => "sampleSizesT",
- "PinholeSize" => "pinhole",
- "NumberOfChannels" => "chanCnt",
- "PinholeSpacing" => "pinholeSpacing",
- "ExcitationWavelength" => "lambdaEx",
- "EmissionWavelength" => "lambdaEm",
- "MicroscopeType" => "mType",
- "NumericalAperture" => "NA",
- "ObjectiveType" => "RILens",
- "SampleMedium" => "RIMedia",
- "unused1" => "iFacePrim", // PSFGenerationDepth?
- "unused2" => "iFaceScnd",
- "unused3" => "imagingDir",
- "unused4" => "objQuality",
- "unused5" => "photonCnt",
- "unused6" => "exBeamFill",
- "StedDepletionMode" => "stedMode",
- "StedWavelength" => "stedLambda",
- "StedSaturationFactor" => "stedSatFact",
- "StedImmunity" => "stedImmunity",
- "Sted3D" => "sted3D");
- }
-
- /*!
- \brief Checks whether a connection to the DB is possible
- \return true if the connection is possible, false otherwise
- */
- public function isReachable() {
- global $db_type;
- global $db_host;
- global $db_name;
- global $db_user;
- global $db_password;
- $connection = ADONewConnection($db_type);
- $result = $connection->Connect($db_host, $db_user, $db_password, $db_name);
- return $result;
- }
-
- /*!
- \brief Returns the type of the database (mysql, ...)
- \return type of the database (e.g. postgresql)
- */
- public function type() {
- global $db_type;
- return $db_type;
- }
-
- /*!
- \brief Attempts to get the version of the underlying database
- \return version of the database (e.g. 2.2.14)
- */
- public function version() {
- try {
- $query = "SELECT version( );";
- $version = $this->queryLastValue($query);
- } catch (Exception $e) {
- $version = "Could not get version information.";
- }
- return $version;
- }
-
- /*!
- \brief Returns the database host name
- \return name of the database host
- */
- public function host() {
- global $db_host;
- return $db_host;
- }
-
- /*!
- \brief Returns the database name
- \return name of the database
- */
- public function name() {
- global $db_name;
- return $db_name;
- }
-
- /*!
- \brief Returns the name of the database user
- \return name of the database user
- */
- public function user() {
- global $db_user;
- return $db_user;
- }
-
- /*!
- \brief Returns the password of the database user
- \return password of the database user
- */
- public function password() {
- global $db_password;
- return $db_password;
- }
-
- /*!
- \brief Returns the ADOConnection object
- \return the connection object
- */
- public function connection() {
- return $this->connection;
- }
-
- /*!
- \brief Executes an SQL query
- \param $query SQL query
- \return query object
- */
- public function execute($query) {
- $connection = $this->connection();
- $result = $connection->Execute($query);
- return $result;
- }
-
- /*!
- \brief Executes an SQL query and returns the results
- \param $queryString SQL query
- \return result of the query (array)
- */
- public function query($queryString) {
- $connection = $this->connection();
- $resultSet = $connection->Execute($queryString);
- if (!$resultSet) {
- return False;
- }
- $rows = $resultSet->GetRows();
- return $rows;
- }
-
- /*!
- \brief Executes an SQL query and returns the last row of the results
- \param $queryString SQL query
- \return last row of the result of the query (array)
- */
- public function queryLastRow($queryString) {
- $rows = $this->query($queryString);
- if (!$rows) return False;
- $result = end($rows);
- return $result;
- }
-
- /*!
- \brief Executes an SQL query and returns the value in the last column of
- the last row of the results
- \param $queryString SQL query
- \return value of the last column of the last row of the result of the query
- */
- public function queryLastValue($queryString) {
- $rows = $this->queryLastRow($queryString);
- if (!$rows) return False;
- $result = end($rows);
- return $result;
- }
-
- /*!
- \brief Adds a new user to the database (all parameters are expected
- to be already validated!
- \param $username The name of the user
- \param $password Password (plain)
- \param $email E-mail address
- \param $group Research group
- \param $status Status or ID
- \return $success True if success; false otherwise
- */
- public function addNewUser($username, $password, $email, $group, $status) {
- $query = "INSERT INTO username (name, password, email, research_group, status) ".
- "VALUES ('".$username."', ".
- "'".md5($password)."', ".
- "'".$email."', ".
- "'".$group."', ".
- "'".$status."')";
- $result = $this->execute($query);
- if ( $result ) {
- $query = "UPDATE username SET creation_date = CURRENT_TIMESTAMP WHERE name = '". $username . "'";
- $result = $this->execute($query);
- }
- if ( $result ) {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Updates an existing user in the database (all parameters are
- expected to be already validated!)
-
- Only the password can be changed for the admin user. For a normal user,
- e-mail address, group and password can be updated.
-
- \param $isadmin True if the user is the HRM admin
- \param $username The name of the user
- \param $password Password (plain)
- \param $email E-mail address
- \param $group Research group
- \return $success True if success; false otherwise
- */
- public function updateExistingUser( $isadmin, $username, $password, $email = "", $group = "" ) {
- // The admin user does not have a group and stores his password in the
- // configuration files. The only variable is the password.
- if ( $isadmin === True ) {
- $query = "UPDATE username SET password = '".md5($password)."' " .
- "WHERE name = '".$username."';";
- } else {
- $query = "UPDATE username SET email ='".$email."', " .
- "research_group ='".$group."', ".
- "password = '".md5($password)."' " .
- "WHERE name = '".$username."';";
- }
- $result = $this->execute($query);
- if ( $result ) {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Updates an existing user in the database (all parameters are
- expected to be already validated!)
-
- The last access time will be updated as well.
-
- \param $username The name of the user (used to query)
- \param $email E-mail address
- \param $group Research group
-
- \return $success True if success; false otherwise
- */
- public function updateUserNoPassword($username, $email, $group) {
-
- if ($email == "" || $group=="") {
- report("User data update: e-mail and group cannot be empty! " .
- "No changes to the database!", 0);
- return false;
- }
-
- // Build query
- $query = "UPDATE username SET email ='" . $email . "', " .
- "research_group ='" . $group . "' " .
- "WHERE name = '" . $username . "';";
-
- $result = $this->execute($query);
- if ( $result ) {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Updates the status of an existing user in the database (username
- is expected to be already validated!
- \param $username The name of the user
- \param $status One of 'd', 'a', ...
- \return $success True if success; false otherwise
- */
- public function updateUserStatus($username, $status) {
- $query = "UPDATE username SET status = '".$status."' WHERE name = '".$username."'";
- $result = $this->execute($query);
- if ( $result ) {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Updates the status of all non-admin users in the database
- \param $status One of 'd', 'a', ...
- \return $success True if success; false otherwise
- */
- public function updateAllUsersStatus($status) {
- $query = "UPDATE username SET status = '".$status."' WHERE name NOT LIKE 'admin'";
- $result = $this->execute($query);
- if ( $result ) {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Deletes an user and all data from the database (username is
- expected to be already validated!
- \param $username One of 'd', 'a', ...
- \return $success True if success; false otherwise
- */
- public function deleteUser($username) {
- if ( $username == 'admin' ) {
- return false;
- }
- $query = "DELETE FROM username WHERE name = '".$username."'";
- $result = $this->execute($query);
- if ($result) {
- // delete user's settings
- $query = "DELETE FROM parameter WHERE owner = '".$username."'";
- $this->execute($query);
- $query = "DELETE FROM parameter_setting WHERE owner = '".$username."'";
- $this->execute($query);
- $query = "DELETE FROM task_parameter WHERE owner = '".$username."'";
- $this->execute($query);
- $query = "DELETE FROM task_setting WHERE owner = '".$username."'";
- $this->execute($query);
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Returns the password of a given user name
- \param $name Name of the user
- \return password for the requested user
- */
- public function passwordQueryString($name) {
- $string = "select password from username where name='" . $name . "'";
- return $string;
- }
-
- /*!
- \brief Returns the e-mail address of a given user name
- \param $username Name of the user
- \return e-mail address for the requested user
- */
- public function emailAddress($username) {
- $query = "select email from username where name = '" . $username . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Saves the parameter values of the setting object into the database.
- If the setting already exists, the old values are overwritten,
- otherwise a new setting is created
- \param $settings Settings object to be saved
- \return true if saving was successful, false otherwise
- */
- public function saveParameterSettings($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- $settingTable = $settings->table();
- $table = $settings->parameterTable();
- if ($settings->isDefault())
- $standard = "t";
- else
- $standard = "f";
- $result = True;
- if (!$this->existsSetting($settings)) {
- $query = "insert into $settingTable values ('" . $user."', '";
- $query .= $name . "', '" .$standard . "')";
- $result = $result && $this->execute($query);
- }
- $existsAlready = $this->existsParametersFor($settings);
-
- foreach ($settings->parameterNames() as $parameterName) {
- $parameter = $settings->parameter($parameterName);
- $parameterValue = $parameter->internalValue();
-
- if (is_array($parameterValue)) {
- /*! Before, # was used as a separator, but the first element
- with index zero was always NULL because channels started
- their indexing at one. To keep backwards compatibility with
- the database, we use # now as a channel marker, and even the
- first channel has a # in front of its value "/" separator is
- used to mark range values for signal to noise ratio.
- */
-
- /*!
- \todo Currently there are not longer "range values" (values
- separated by /). In the future they will be reintroduced.
- We leave the code in place.
- */
- if (is_array($parameterValue[0])) {
- $maxChanCnt = $this->getMaxChanCnt();
- for ($i = 0; $i < $maxChanCnt; $i++) {
- if ($parameterValue[$i] != null) {
- $parameterValue[$i] =
- implode("/", array_filter($parameterValue[$i]));
- }
- }
- }
- $parameterValue = "#".implode("#", $parameterValue);
- }
-
- if (!$existsAlready) {
- $query = "INSERT INTO $table VALUES ('" . $user . "', '";
- $query .= $name . "', '" . $parameterName . "', '";
- $query .= $parameterValue . "')";
- } else {
- /* Check that the parameter itself exists. */
- $query = "SELECT name FROM $table WHERE owner='" . $user;
- $query .= "' AND setting='" . $name;
- $query .= "' AND name='" . $parameterName . "' LIMIT 1";
- $newValue = $this->queryLastValue($query);
-
- if ( $newValue != NULL ) {
- $query = "UPDATE $table SET value = '" . $parameterValue;
- $query .= "' WHERE owner='" . $user;
- $query .= "' AND setting='" . $name;
- $query .= "' AND name='" . $parameterName . "'";
- } else {
- $query = "INSERT INTO $table VALUES ('" . $user;
- $query .= "', '" . $name . "', '" . $parameterName;
- $query .= "', '" . $parameterValue . "')";
- }
- }
-
- // Accumulate the successes (or failures) of the queries. If a query
- // fails, the return of $this->execute() will be === false; otherwise
- // it is an ADORecordSet.
- $result &= ($this->execute($query) !== false);
- }
-
-
- return $result;
- }
-
- /*!
- \brief Saves the parameter values of the setting object into the database.
- If the setting already exists, the old values are overwritten,
- otherwise a new setting is created
- \param $settings Settings object to be saved
- \param $isShare Boolean (default = False): True if the setting is to
- be saved to the share table, False if it is a standard
- save.
- \return true if saving was successful, false otherwise
-*/
- public function saveSharedParameterSettings($settings, $targetUserName) {
- $owner = $settings->owner();
- $original_user = $owner->name();
- $name = $settings->name();
- $new_owner = new User();
- $new_owner->setName($targetUserName);
- $settings->setOwner($new_owner);
- $settingTable = $settings->sharedTable();
- $table = $settings->sharedParameterTable();
- $result = True;
- if (!$this->existsSharedSetting($settings)) {
- $query = "insert into $settingTable " .
- "(owner, previous_owner, sharing_date, name) values " .
- "('$targetUserName', '$original_user', CURRENT_TIMESTAMP, '$name')";
- $result = $result && $this->execute($query);
- }
-
- if (!$result) {
- return False;
- }
-
- // Get the Id
- $query = "select id from $settingTable where " .
- "owner='$targetUserName' " .
- "AND previous_owner='$original_user' " .
- "AND name='$name'";
- $id = $this->queryLastValue($query);
- if (! $id) {
- return False;
- }
-
- // Get the parameter names
- $parameterNames = $settings->parameterNames();
-
- // Add the parameters
- foreach ($parameterNames as $parameterName) {
-
- $parameter = $settings->parameter($parameterName);
- $parameterValue = $parameter->internalValue();
-
- if (is_array($parameterValue)) {
- // Before, # was used as a separator, but the first element with
- // index zero was always NULL because channels started their indexing
- // at one. To keep backwards compatibility with the database, we use
- // # now as a channel marker, and even the first channel has a # in
- // front of its value.
- // "/" separator is used to mark range values for signal to noise ratio
-
-
- // Special treatment for the PSF parameter.
- if ($parameter->name() == "PSF") {
-
- // Create hard links and update paths to the PSF files
- // to point to the hard-links.
- $fileServer = new Fileserver($original_user);
- $parameterValue = $fileServer->createHardLinksToSharedPSFs(
- $parameterValue, $targetUserName);
-
- }
-
- /*!
- \todo Currently there are not longer "range values" (values
- separated by /). In the future they will be reintroduced.
- We leave the code in place.
- */
- if (is_array($parameterValue[0])) {
- $maxChanCnt = $this->getMaxChanCnt();
- for ($i = 0; $i < $maxChanCnt; $i++) {
- if ($parameterValue[$i] != null) {
- $parameterValue[$i] = implode("/", array_filter($parameterValue[$i]));
- }
- }
- }
- $parameterValue = "#".implode("#", $parameterValue);
- }
-
- $query = "insert into $table " .
- "(setting_id, owner, setting, name, value) " .
- "values ('$id', '$targetUserName', '$name', " .
- "'$parameterName', '$parameterValue')";
- $result = $result && $this->execute($query);
- }
-
- return $result;
- }
-
- /*!
- \brief Loads the parameter values for a setting and returns a copy of
- the setting with the loaded parameter values. If a value starts
- with # it is considered to be an array with the first value at
- the index 0
- \param $settings Setting object to be loaded
- \return $settings object with loaded values
- */
- public function loadParameterSettings($settings) {
- $user = $settings->owner();
- $user = $user->name();
- $name = $settings->name();
- $table = $settings->parameterTable();
-
- foreach ($settings->parameterNames() as $parameterName) {
- $parameter = $settings->parameter($parameterName);
- $query = "SELECT value FROM $table WHERE owner='" . $user;
- $query .= "' AND setting='" . $name . "' AND name='";
- $query .= $parameterName . "'";
-
- $newValue = $this->queryLastValue($query);
-
- if ($newValue == NULL) {
-
- // See if the Parameter has a usable default
- $newValue = $parameter->defaultValue( );
- if ($newValue == NULL) {
- continue;
- }
- }
-
-
- if ($newValue{0} == '#') {
- switch($parameterName) {
- case "ExcitationWavelength":
- case "EmissionWavelength":
- case "PinholeSize":
- case "PinholeSpacing":
- case "SignalNoiseRatio":
- case "BackgroundOffsetPercent":
- case "ChromaticAberration":
- case "StedDepletionMode":
- case "StedWavelength":
- case "StedSaturationFactor":
- case "StedImmunity":
- case "Sted3D":
- case "SpimExcMode":
- case "SpimGaussWidth":
- case "SpimCenterOffset":
- case "SpimFocusOffset":
- case "SpimNA":
- case "SpimFill":
- case "SpimDir":
- case "ColocChannel":
- case "ColocThreshold":
- case "ColocCoefficient":
- /* Extract and continue to explode. */
- $newValue = substr($newValue,1);
- default:
- $newValues = explode("#", $newValue);
- }
-
- if (strcmp( $parameterName, "PSF" ) != 0
- && strpos($newValue, "/")) {
- $newValue = array();
- for ($i = 0; $i < count($newValues); $i++) {
- if (strpos($newValues[$i], "/")) {
- $newValue[] = explode("/", $newValues[$i]);
- }
- else {
- $newValue[] = array($newValues[$i]);
- }
- }
- }
- else {
- $newValue = $newValues;
- }
- }
-
- $parameter->setValue($newValue);
- $settings->set($parameter);
- }
-
- return $settings;
- }
-
- /*!
- \brief Loads the parameter values for a setting and returns a copy of
- the setting with the loaded parameter values. If a value starts
- with # it is considered to be an array with the first value at
- the index 0
- \param $id Setting id
- \param $id Setting id
- \return $settings object with loaded values
- */
- public function loadSharedParameterSettings($id, $type) {
-
- // Get the correct objects
- switch ($type) {
-
- case "parameter":
-
- $settingTable = ParameterSetting::sharedTable();
- $table = ParameterSetting::sharedParameterTable();
- $settings = new ParameterSetting();
- break;
-
- case "task":
-
- $settingTable = TaskSetting::sharedTable();
- $table = TaskSetting::sharedParameterTable();
- $settings = new TaskSetting();
- break;
-
- case "analysis":
-
- $settingTable = AnalysisSetting::sharedTable();
- $table = AnalysisSetting::sharedParameterTable();
- $settings = new AnalysisSetting();
- break;
-
- default:
-
- throw new Exception("bad value for type!");
- }
-
- // Get the setting info
- $query = "select * from $settingTable where id=$id;";
- $response = $this->queryLastRow($query);
- if (!$response) {
- return NULL;
- }
-
- // Fill the setting
- $settings->setName($response["name"]);
- $user = new User();
- $user->setName($response["owner"]);
- $settings->setOwner($user);
-
- // Load from shared table
- foreach ($settings->parameterNames() as $parameterName) {
- $parameter = $settings->parameter($parameterName);
- $query = "select value from $table where setting_id=$id and name='$parameterName'";
- $newValue = $this->queryLastValue($query);
- if ($newValue == NULL) {
- // See if the Parameter has a usable default
- $newValue = $parameter->defaultValue( );
- if ($newValue == NULL) {
- continue;
- }
- }
- if ($newValue{0}=='#') {
- switch($parameterName) {
- case "ExcitationWavelength":
- case "EmissionWavelength":
- case "SignalNoiseRatio":
- case "BackgroundOffsetPercent":
- case "ChromaticAberration":
- /* Extract and continue to explode. */
- $newValue = substr($newValue,1);
- default:
- $newValues = explode("#", $newValue);
- }
-
- if (strcmp( $parameterName, "PSF" ) != 0 && strpos($newValue, "/")) {
- $newValue = array();
- for ($i = 0; $i < count($newValues); $i++) {
- //$val = explode("/", $newValues[$i]);
- //$range = array(NULL, NULL, NULL, NULL);
- //for ($j = 0; $j < count($val); $j++) {
- // $range[$j] = $val[$j];
- //}
- //$newValue[] = $range;
- /*!
- \todo Currently there are not longer "range values" (values
- separated by /). In the future they will be reintroduced.
- We leave the code in place.
- */
- if (strpos($newValues[$i], "/")) {
- $newValue[] = explode("/", $newValues[$i]);
- }
- else {
- $newValue[] = array($newValues[$i]);
- }
- }
- }
- else {
- $newValue = $newValues;
- }
- }
- //$shiftedNewValue = array(1 => NULL, 2 => NULL, 3 => NULL, 4 => NULL, 5 => NULL);
- //if (is_array($newValue)) {
- // // start array at 1
- // for ($i = 1; $i <= count($newValue); $i++) {
- // $shiftedNewValue[$i] = $newValue[$i - 1];
- // }
- //}
- //else $shiftedNewValue = $newValue;
- $parameter->setValue($newValue);
- $settings->set($parameter);
- }
- return $settings;
- }
-
- /*!
- \brief Returns the list of shared templates with the given user.
- \param $username Name of the user for whom to query for shared templates
- \param $table Shared table to query
- \return list of shared jobs
- */
- public function getTemplatesSharedWith($username, $table) {
- $query = "SELECT * FROM $table WHERE owner='$username'";
- $result = $this->query($query);
- return $result;
- }
-
- /*!
- \brief Returns the list of shared templates by the given user.
- \param $username Name of the user for whom to query for shared templates
- \param $table Shared table to query
- \return list of shared jobs
- */
- public function getTemplatesSharedBy($username, $table) {
- $query = "SELECT * FROM $table WHERE previous_owner='$username'";
- $result = $this->query($query);
- return $result;
- }
-
- /*!
- \brief Copies the relevant rows from shared- to user- tables.
- \param $id ID of the setting to be copied
- \param $sourceSettingTable Setting table to copy from
- \param $sourceParameterTable Parameter table to copy from
- \param $destSettingTable Setting table to copy to
- \param $destParameterTable Parameter table to copy to
- \return True if copying was successful; false otherwise.
- */
- public function copySharedTemplate($id, $sourceSettingTable,
- $sourceParameterTable, $destSettingTable, $destParameterTable) {
-
- // Get the name of the previous owner (the one sharing the setting).
- $query = "select previous_owner, owner, name from $sourceSettingTable where id=$id";
- $rows = $this->queryLastRow($query);
- if (False === $rows) {
- return False;
- }
- $previous_owner = $rows["previous_owner"];
- $owner = $rows["owner"];
- $setting_name = $rows["name"];
-
- // Compose the new name of the setting
- $out_setting_name = $previous_owner . "_" . $setting_name;
-
- // Check if a setting with this name already exists in the target tables
- $query = "select name from $destSettingTable where " .
- "name='$out_setting_name' and owner='$owner'";
- if ($this->queryLastValue($query)) {
-
- // The setting already exists; we try adding numerical indices
- $n = 1; $original_out_setting_name = $out_setting_name;
- while (1) {
-
- $test_name = $original_out_setting_name . "_" . $n++;
- $query = "select name from $destSettingTable where name='$test_name' and owner='$owner'";
- if (! $this->queryLastValue($query)) {
- $out_setting_name = $test_name;
- break;
- }
- }
-
- }
-
- // Get all rows from source table for given setting id
- $query = "select * from $sourceParameterTable where setting_id=$id";
- $rows = $this->query($query);
- if (count($rows) == 0) {
- return False;
- }
-
- // Now add the rows to the destination table
- $ok = True;
- $record = array();
- $this->connection->BeginTrans();
- foreach ($rows as $row) {
- $record["owner"] = $row["owner"];
- $record["setting"] = $out_setting_name;
- $record["name"] = $row["name"];
-
- // PSF files must be processed differently
- if ($record["name"] == "PSF") {
-
- // Instantiate a Fileserver object for the target user
- $fileserver = new Fileserver($owner);
-
- // Get the array of PSF names
- $values = $row["value"];
- if ($values[0] == "#") {
- $values = substr($values, 1);
- }
- $psfFiles = explode('#', $values);
-
- // Create hard-links to the target user folder
- $newPSFFiles = $fileserver->createHardLinksFromSharedPSFs(
- $psfFiles, $owner, $previous_owner);
-
- // Update the entries for the database
- $record["value"] = "#" . implode('#', $newPSFFiles);
-
- } else {
-
- $record["value"] = $row["value"];
-
- }
-
- $insertSQL = $this->connection->GetInsertSQL($destParameterTable,
- $record);
- $status = $this->connection->Execute($insertSQL);
- $ok &= !(false === $status);
- if (! $ok) {
- break;
- }
- }
-
- // If everything went okay, we commit the transaction; otherwise we roll
- // back
- if ($ok) {
- $this->connection->CommitTrans();
- } else {
- $this->connection->RollbackTrans();
- return False;
- }
-
- // Now add the setting to the setting table
- $query = "select * from $sourceSettingTable where id=$id";
- $rows = $this->query($query);
- if (count($rows) != 1) {
- return False;
- }
-
- $ok = True;
- $this->connection->BeginTrans();
- $record = array();
- $row = $rows[0];
- $record["owner"] = $row["owner"];
- $record["name"] = $out_setting_name;
- $record["standard"] = 'f';
- $insertSQL = $this->connection->GetInsertSQL($destSettingTable,
- $record);
- $status = $this->connection->Execute($insertSQL);
- $ok &= !(false === $status);
-
- if ($ok) {
- $this->connection->CommitTrans();
- } else {
- $this->connection->RollbackTrans();
- return False;
- }
-
- // Now we can delete the records from the source tables. Even if it
- // if it fails we do not roll back, since the parameters were copied
- // successfully.
-
- // Delete setting entry
- $query = "delete from $sourceSettingTable where id=$id";
- $status = $this->connection->Execute($query);
- if (false === $status) {
- return False;
- }
-
- // Delete parameter entries
- $query = "delete from $sourceParameterTable where setting_id=$id";
- $status = $this->connection->Execute($query);
- if (false === $status) {
- return False;
- }
-
- return True;
- }
-
- /*!
- \brief Delete the relevant rows from the shared tables.
- \param $id ID of the setting to be deleted
- \param $sourceSettingTable Setting table to copy from
- \param $sourceParameterTable Parameter table to copy from
- \return True if deleting was successful; false otherwise.
- */
- public function deleteSharedTemplate($id, $sourceSettingTable,
- $sourceParameterTable) {
-
- // Initialize success
- $ok = True;
-
- // Delete shared PSF files if any exist
- if ($sourceParameterTable == "shared_parameter") {
- $query = "select value from $sourceParameterTable where setting_id=$id and name='PSF'";
- $psfFiles = $this->queryLastValue($query);
- if (NULL != $psfFiles && $psfFiles != "#####") {
- if ($psfFiles[0] == "#") {
- $psfFiles = substr($psfFiles, 1);
- }
-
- // Extract PSF file paths from the string
- $psfFiles = explode("#", $psfFiles);
-
- // Delete them
- Fileserver::deleteSharedFSPFilesFromBuffer($psfFiles);
- }
- }
-
- // Delete setting entry
- $query = "delete from $sourceSettingTable where id=$id";
- $status = $this->connection->Execute($query);
- $ok &= !(false === $status);
-
- // Delete parameter entries
- $query = "delete from $sourceParameterTable where setting_id=$id";
- $status = $this->connection->Execute($query);
- $ok &= !(false === $status);
-
- return $ok;
- }
-
- /*!
- \brief Updates the default entry in the database according to the default
- value in the setting
- \param $settings Settings object to be used to update the default
- \return query result
- */
- public function updateDefault($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- if ($settings->isDefault())
- $standard = "t";
- else
- $standard = "f";
- $table = $settings->table();
- $query = "update $table set standard = '" . $standard . "' where owner='" . $user . "' and name='" . $name . "'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Deletes the setting and all its parameter values from the database
- \param $settings Settings object to be used to delete all entries from
- the database
- \return true if the setting and all parameters were deleted from the
- database; false otherwise
- */
- public function deleteSetting($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- $result = True;
- $table = $settings->parameterTable();
- $query = "delete from $table where owner='" . $user . "' and setting='" . $name ."'";
- $result = $result && $this->execute($query);
- if (!$result) {
- return FALSE;
- }
- $table = $settings->table();
- $query = "delete from $table where owner='" . $user . "' and name='" . $name ."'";
- $result = $result && $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Checks whether parameters are already stored for a given setting
- \param $settings Settings object to be used to check for existance in
- the database
- \return true if the parameters exist in the database; false otherwise
- */
- public function existsParametersFor($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- $table = $settings->parameterTable();
- $query = "select name from $table where owner='" . $user . "' and setting='" . $name ."' LIMIT 1";
- $result = True;
- if (!$this->queryLastValue($query)) {
- $result = False;
- }
- return $result;
- }
-
- /*!
- \brief Checks whether parameters are already stored for a given shared
- setting
- \param $settings Settings object to be used to check for existence in
- the database
- \return true if the parameters exist in the database; false otherwise
- */
- public function existsSharedParametersFor($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- $table = $settings->sharedParameterTable();
- $query = "select name from $table where owner='" . $user . "' and setting='" . $name ."' LIMIT 1";
- $result = True;
- if (!$this->queryLastValue($query)) {
- $result = False;
- }
- return $result;
- }
-
- /*!
- \brief Checks whether settings exist in the database for a given owner
- \param $settings Settings object to be used to check for existance in
- the database (the name of the owner must be set in the
- settings)
- \return true if the settings exist in the database; false otherwise
- */
- public function existsSetting($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- $table = $settings->table();
- $query = "select standard from $table where owner='" . $user . "' and name='" . $name ."' LIMIT 1";
- $result = True;
- if (!$this->queryLastValue($query)) {
- $result = False;
- }
- return $result;
- }
-
- /*!
- \brief Checks whether settings exist in the database for a given owner
- \param $settings Settings object to be used to check for existence in
- the database (the name of the owner must be set in the
- settings)
- \return true if the settings exist in the database; false otherwise
- */
- public function existsSharedSetting($settings) {
- $owner = $settings->owner();
- $user = $owner->name();
- $name = $settings->name();
- $table = $settings->sharedTable();
- $query = "select standard from $table where owner='" . $user . "' and name='" . $name ."' LIMIT 1";
- $result = True;
- if (!$this->queryLastValue($query)) {
- $result = False;
- }
- return $result;
- }
-
- /*!
- \brief Adds all files for a given job id and user to the database
- \param $id Job id
- \param $owner Name of the user that owns the job
- \param $files Array of file names
- \return true if the job files could be saved successfully; false otherwise
- */
- public function saveJobFiles($id, $owner, $files, $autoseries) {
- $result = True;
- $username = $owner->name();
- $sqlAutoSeries = "";
- foreach ($files as $file) {
- if (strcasecmp($autoseries, "TRUE") == 0 || strcasecmp($autoseries, "T") == 0) {
- $sqlAutoSeries = "T";
- }
- $query = "insert into job_files values ('" . $id ."', '" . $username ."', '" . addslashes($file) . "', '" . $sqlAutoSeries . "')";
- $result = $result && $this->execute($query);
- }
- return $result;
- }
-
- /*!
- \brief Adds a job for a given job id and user to the database
- \param $id Job id
- \param $username Name of the user that owns the job
- \return query result
- */
- public function queueJob($id, $username) {
- $query = "insert into job_queue (id, username, queued, status) values ('" .$id . "', '" . $username . "', NOW(), 'queued')";
- return $this->execute($query);
- }
-
- /*!
- \brief Assigns priorities to the jobs in the queue
- \return true if assigning priorities was successful
- */
- public function setJobPriorities( ) {
-
- $result = True;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // First we analyze the queue
- //
- ////////////////////////////////////////////////////////////////////////////
-
- // Get the number of users that currently have jobs in the queue
- $users = $this->execute( "SELECT DISTINCT( username ) FROM job_queue;" );
- $row = $this->execute( "SELECT COUNT( DISTINCT( username ) ) FROM job_queue;" )->FetchRow( );
- $numUsers = $row[ 0 ];
-
- // 'Highest' priority (i.e. lowest value) is 0
- $currentPriority = 0;
-
- // First, we make sure to give the highest priorities to paused and
- // broken jobs
- $rs = $this->execute( "SELECT id FROM job_queue WHERE status = 'broken' OR status = 'paused';" );
- if ( $rs ) {
- while ( $row = $rs->FetchRow( ) ) {
-
- // Update the priority for current job id
- $query = "UPDATE job_queue SET priority = " . $currentPriority++ .
- " WHERE id = '" . $row[ 0 ] . "';";
-
- $rs = $this->execute( $query );
- if ( !$rs ) {
- error_log( "Could not update priority for key " . $row[ 0 ] );
- $result = False;
- return $result;
- }
-
- }
- }
-
- // Then, we go through to running jobs
- $rs = $this->execute( "SELECT id FROM job_queue WHERE status = 'started';" );
- if ( $rs ) {
- while ( $row = $rs->FetchRow( ) ) {
-
- // Update the priority for current job id
- $query = "UPDATE job_queue SET priority = " . $currentPriority++ .
- " WHERE id = '" . $row[ 0 ] . "';";
-
- $rs = $this->execute( $query );
- if ( !$rs ) {
- error_log( "Could not update priority for key " . $row[ 0 ] );
- $result = False;
- return $result;
- }
- }
- }
-
- // Then we organize the queued jobs in a way that lets us then assign
- // priorities easily in a second pass
- $numJobsPerUser = array( );
- $userJobs = array( );
- for ( $i = 0; $i < $numUsers; $i++ ) {
- // Get current username
- $row = $users->FetchRow( );
- $username = $row[ 0 ];
- $query = "SELECT id
- FROM job_queue, job_files
- WHERE job_queue.id = job_files.job AND
- job_queue.username = job_files.owner AND
- job_queue.username = '" . $username . "' AND
- status = 'queued'
- ORDER BY job_queue.queued asc, job_files.file asc";
- $rs = $this->execute( $query );
- if ( $rs ) {
- $userJobs[ $i ] = array( );
- $counter = 0;
- while ( $row = $rs->FetchRow( ) ) {
- $userJobs[ $i ][ $counter++ ] = $row[ 0 ];
- }
- $numJobsPerUser[ $i ] = $counter;
- }
- }
-
- // Now we can assign priorities to the queued jobs -- minimum priority is 1
- // above the priorities assigned to all other types of jobs
- $maxNumJobs = max( $numJobsPerUser );
- for ( $j = 0; $j < $maxNumJobs; $j++ ) {
- for ( $i = 0; $i < $numUsers; $i++ ) {
- if ( $j < count( $userJobs[ $i ] ) ) {
- // Update the priority for current job id
- $query = "UPDATE job_queue SET priority = " .
- $currentPriority ." WHERE id = '" .
- $userJobs[ $i ][ $j ] . "';";
-
- $rs = $this->execute( $query );
- if ( !$rs ) {
- error_log( "Could not update priority for key " . $userJobs[ $i ][ $j ] );
- $result = False;
- return $result;
- }
- $currentPriority++;
- }
- }
- }
-
- // We can now return true
- return $result;
- }
-
- /*!
- \brief Logs job information in the statistics table
- \param $job Job object whose information is to be logged in the
- database
- \param $startTime Job start time
- \return void
- */
- public function updateStatistics($job, $startTime) {
-
- $desc = $job->description();
- $parameterSetting = $desc->parameterSetting();
- $taskSetting = $desc->taskSetting();
- $analysisSetting = $desc->analysisSetting();
-
- $stopTime = date("Y-m-d H:i:s");
- $id = $desc->id();
- $user = $desc->owner();
- $owner = $user->name();
- $group = $user->userGroup($owner);
-
- $parameter = $parameterSetting->parameter('ImageFileFormat');
- $inFormat = $parameter->value();
- $parameter = $parameterSetting->parameter('PointSpreadFunction');
- $PSF = $parameter->value();
- $parameter = $parameterSetting->parameter('MicroscopeType');
- $microscope = $parameter->value();
- $parameter = $taskSetting->parameter('OutputFileFormat');
- $outFormat = $parameter->value();
- $parameter = $analysisSetting->parameter('ColocAnalysis');
- $colocAnalysis = $parameter->value();
-
- $query = "insert into statistics values ('" . $id ."', '" . $owner ."', '" .
- $group . "','" . $startTime . "', '" . $stopTime . "', '" . $inFormat .
- "', '" . $outFormat . "', '" . $PSF . "', '" .
- $microscope . "', '" . $colocAnalysis . "')";
-
- $this->execute($query);
-
- }
-
- /*!
- \brief Flattens a multi-dimensional array
- \param $anArray Multi-dimensional array
- \return flattened array
- */
- public function flatten($anArray) {
- $result = array();
- foreach ($anArray as $row) {
- $result[] = end($row);
- }
- return $result;
- }
-
- /*!
- \brief Returns the possible values for a given parameter
- \param $parameter Parameter object
- \return Flattened array of possible values
- */
- public function readPossibleValues($parameter) {
- $name = $parameter->name();
- $query = "select value from possible_values where parameter = '" .$name . "'";
- $answer = $this->query($query);
- $result = $this->flatten($answer);
- return $result;
- }
-
- /*!
- \brief Returns the translated possible values for a given parameter
- \param $parameter Parameter object
- \return Flattened array of translated possible values
- */
- public function readTranslatedPossibleValues($parameter) {
- $name = $parameter->name();
- $query = "select translation from possible_values where parameter = '" .$name . "'";
- $answer = $this->query($query);
- $result = $this->flatten($answer);
- return $result;
- }
-
- /*!
- \brief Returns the translation of current value for a given parameter
- \param $parameterName Name of the Parameter object
- \param $value Value for which a thanslation should be returned
- \return Translated value
- */
- public function translationFor($parameterName, $value) {
- $query = "select translation from possible_values where parameter = '" .$parameterName . "' and value = '" . $value . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Returns the translation of a hucore value
- \param $parameterName Name of the Parameter object
- \param $hucorevalue value name in HuCore
- \return Expected value by HRM
-*/
- public function hucoreTranslation($parameterName, $hucorevalue) {
- $query = "select value from possible_values where parameter = '" .$parameterName . "' and translation = '" . $hucorevalue . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Returns an array of all file extensions
- \return Array of file extensions
- */
- public function allFileExtensions( ) {
- $query = "select distinct extension from file_extension";
- $answer = $this->query($query);
- $result = $this->flatten($answer);
- return $result;
- }
-
- /*!
- \brief Returns an array of all extensions for multi-dataset files
- \return Array of file extensions for multi-dataset files
- */
- public function allMultiFileExtensions( ) {
- $query = "SELECT name FROM file_format, file_extension
- WHERE file_format.name = file_extension.file_format
- AND file_format.ismultifile LIKE 't'";
- $answer = $this->query($query);
- $result = $this->flatten($answer);
- return $result;
- }
-
- /*!
- \brief Returns an array of file extensions associated to a given file format
- \param $imageFormat File format
- \return Array of file extensions
- */
- public function fileExtensions($imageFormat) {
- $query = "select distinct extension from file_extension where file_format = '" . $imageFormat . "'";
- $answer = $this->query($query);
- $result = $this->flatten($answer);
- return $result;
- }
-
- /*!
- \brief Returns all restrictions for a given numerical parameter
- \param $parameter Parameter (object)
- \return Array of restrictions
- */
- public function readNumericalValueRestrictions($parameter) {
- $name = $parameter->name();
- $query = "select min, max, min_included, max_included, standard from boundary_values where parameter = '" .$name . "'";
- $result = $this->queryLastRow($query);
- if ( !$result ) {
- $result = array( null, null, null, null, null );
- }
- return $result;
- }
-
- /*!
- \brief Returns the file formats that fit the conditions expressed by the
- parameters.
- \param $isSingleChannel Set whether the file format must be single
- channel (True), multi channel (False) or if
- it doesn't matter (NULL)
- \param $isVariableChannel Set whether the number of channels must be
- variable (True), fixed (False) or if it
- doesn't matter (NULL)
- \param $isFixedGeometry Set whether the geometry (xyzt) must be fixed
- (True), variable (False) or if it doesn't
- matter (NULL).
- \return array of file formats
- */
- public function fileFormatsWith($isSingleChannel, $isVariableChannel, $isFixedGeometry) {
- $isSingleChannelValue = 'f';
- $isVariableChannelValue = 'f';
- $isFixedGeometryValue ='f';
- if ($isSingleChannel) {
- $isSingleChannelValue = 't';
- }
- if ($isVariableChannel) {
- $isVariableChannelValue = 't';
- }
- if ($isFixedGeometry) {
- $isFixedGeometryValue = 't';
- }
- $conditions = array();
- if ($isSingleChannel!=NULL) {
- $conditions['isSingleChannel'] = $isSingleChannelValue;
- }
- if ($isVariableChannel!=NULL) {
- $conditions['isVariableChannel'] = $isVariableChannelValue;
- }
- if ($isFixedGeometry!=NULL) {
- $conditions['isFixedGeometry'] = $isFixedGeometryValue;
- }
- return $this->retrieveColumnFromTableWhere('name', 'file_format', $conditions);
- }
-
- /*!
- \brief Returns the geometries (XY, XY-time, XYZ, XYZ-time) fit the
- conditions expressed by the parameters
- \param $isThreeDimensional True if 3D
- \param $isTimeSeries True if time-series
- \return array of geometries
- */
- public function geometriesWith($isThreeDimensional, $isTimeSeries) {
- $isThreeDimensionalValue = 'f';
- $isTimeSeriesValue = 'f';
- if ($isThreeDimensional) {
- $isThreeDimensionalValue = 't';
- }
- if ($isTimeSeries) {
- $isTimeSeriesValue = 't';
- }
- $conditions = array();
- if ($isThreeDimensional!=NULL) {
- $conditions['isThreeDimensional'] = $isThreeDimensionalValue;
- }
- if ($isTimeSeries!=NULL) {
- $conditions['isTimeSeries'] = $isTimeSeriesValue;
- }
- return $this->retrieveColumnFromTableWhere("name", "geometry", $conditions);
- }
-
- /*!
- \brief Return all values from the column from the table where the condition
- evaluates to true
- \param $column Name of the column from which the values are taken
- \param $table Name of the table from which the values are taken
- \param $conditions Array of conditions that the result values must fullfil.
- This is an array with column names as indices and
- boolean values as content.
- \return array of values
- */
- public function retrieveColumnFromTableWhere($column, $table, $conditions) {
- $query = "select distinct $column from $table where ";
- foreach ($conditions as $eachName => $eachValue) {
- $query = $query . $eachName . " = '" . $eachValue . "' and ";
- }
- $query = $query . "1 = 1";
- $answer = $this->query($query);
- $result = array();
-
- if ( !empty($answer) ) {
- foreach ($answer as $row) {
- $result[] = end($row);
- }
- }
-
- return $result;
- }
-
- /*!
- \brief Returns the default value for a given parameter
- \param $parameterName Name of the parameter
- \return Default value
- */
- public function defaultValue($parameterName) {
- $query = "SELECT value FROM possible_values WHERE parameter='";
- $query .= $parameterName . "' AND isDefault='t'";
- $result = $this->queryLastValue($query);
- if ($result === False) {
- return NULL;
- }
-
- return $result;
- }
-
- /*!
- \brief Returns the id for next job from the queue, sorted by priority
- \return Job id
- */
- public function getNextIdFromQueue() {
- // For the query we join job_queue and job_files, since we want to sort also by file name
- $query = "SELECT id
- FROM job_queue, job_files
- WHERE job_queue.id = job_files.job AND job_queue.username = job_files.owner
- AND job_queue.status = 'queued'
- ORDER BY job_queue.priority desc, job_queue.status desc, job_files.file desc";
- $result = $this->queryLastValue($query);
- if (!$result) {
- return NULL;
- }
- return $result;
- }
-
- /*!
- \brief Returns all jobs from the queue, both compound and simple,
- ordered by priority
- \return all jobs
- */
- public function getQueueJobs() {
- // Get jobs as they are in the queue, compound or not, without splitting
- // them.
- $query = "SELECT id, username, queued, start, server, process_info, status
- FROM job_queue
- ORDER BY job_queue.priority asc, job_queue.queued asc, job_queue.status asc";
- $result = $this->query($query);
- return $result;
- }
-
- /*!
- \brief Returns all jobs from the queue, both compund and simple,
- and the associated file names, ordered by priority
- \return all jobs
- */
- public function getQueueContents() {
- // For the query we join job_queue and job_files, since we want to sort also by file name
- $query = "SELECT id, username, queued, start, stop, server, process_info, status, file
- FROM job_queue, job_files
- WHERE job_queue.id = job_files.job AND job_queue.username = job_files.owner
- ORDER BY job_queue.priority asc, job_queue.queued asc, job_queue.status asc, job_files.file asc
- LIMIT 100";
- $result = $this->query($query);
- return $result;
- }
-
- /*!
- \brief Returns all jobs from the queue for a given id (that must be
- univocal!)
- \param $id String Id of the job
- \return all jobs for the id
- */
- public function getQueueContentsForId($id) {
- $query = "select id, username, queued, start, server, process_info, status from job_queue where id='" . $id . "'";
- $result = $this->queryLastRow($query); // it is supposed that just one job exists with a given id
- return $result;
- }
-
- /*!
- \brief Returns all file names associated to a job with given id
- \param $id Job id
- \return array of file names
- */
- public function getJobFilesFor($id) {
- $query = "select file from job_files where job = '" . $id . "'";
- $result = $this->query($query);
- $result = $this->flatten($result);
- return $result;
- }
-
- /*!
- \brief Returns the file series mode of a job with given id
- \param $id Job id
- \return true or false
- */
- public function getSeriesModeForId($id) {
- $query = "select autoseries from job_files where job = '" . $id . "'";
- $result = $this->queryLastValue($query);
-
- return $result;
- }
-
- /*!
- \brief Returns the number of jobs currently in the queue for a
- given username
- \param $username Name of the user
- \return number of jobs in queue
- */
- public function getNumberOfQueuedJobsForUser($username) {
- $query = "SELECT COUNT(id) FROM job_queue WHERE username = '" . $username . "';";
- $row = $this->Execute( $query )->FetchRow( );
- return $row[ 0 ];
- }
-
- /*!
- \brief Returns the total number of jobs currently in the queue
- \return total number of jobs in queue
- */
- public function getTotalNumberOfQueuedJobs() {
- $query = "SELECT COUNT(id) FROM job_queue;";
- $row = $this->Execute( $query )->FetchRow( );
- return $row[ 0 ];
- }
-
- /*!
- \brief Returns the name of the user who created the job with given id
- \param $id String id of the job
- \return name of the user
- */
- public function userWhoCreatedJob($id) {
- $query = "select username from job_queue where id = '" . $id . "'";
- $result = $this->queryLastValue($query);
- if (!$result) {
- return NULL;
- }
- return $result;
- }
-
- /*!
- \brief Deletes job with specified ID from all job tables
- \param $id Id of the job
- \return true if success
- */
- public function deleteJobFromTables($id) {
- // TODO: Use foreign keys in the database!
- $result = True;
- $result = $result && $this->execute(
- "delete from job_analysis_parameter where setting='$id'");
- $result = $result && $this->execute(
- "delete from job_analysis_setting where name='$id'");
- $result = $result && $this->execute(
- "delete from job_files where job='$id'");
- $result = $result && $this->execute(
- "delete from job_parameter where setting='$id'");
- $result = $result && $this->execute(
- "delete from job_parameter_setting where name='$id'");
- $result = $result && $this->execute(
- "delete from job_queue where id='$id'");
- $result = $result && $this->execute(
- "delete from job_task_parameter where setting='$id'");
- $result = $result && $this->execute(
- "delete from job_task_setting where name='$id'");
- return $result;
- }
-
- /*!
- \brief Returns the path to hucore on given host
- \param $host String Host name
- \return full path to hucore
- */
- // TODO better management of multiple hosts
- function huscriptPathOn($host) {
- $query = "SELECT huscript_path FROM server where name = '" . $host . "'";
- $result = $this->queryLastValue($query);
- if (!$result) {
- return NULL;
- }
- return $result;
- }
-
- /*!
- \brief Get the name of a free server
- \return name of the server
- */
- public function freeServer() {
- $query = "select name from server where status='free'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Get the status (i.e. free, busy, paused) of server $name
- \param $name Name of the server
- \return status
- */
- public function statusOfServer($name) {
- $query = "select status from server where name='$name'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Checks whether server is busy
- \param $name Name of the server
- \return true if the server is busy, false otherwise
- */
- public function isServerBusy($name) {
- $status = $this->statusOfServer($name);
- $result = ($status == 'busy');
- return $result;
- }
-
- /*!
- \brief Checks whether the switch in the queue manager is 'on'
- \return true if on
- */
- public function isSwitchOn() {
- // Handle some back-compatibility issue
- if ($this->doGlobalVariablesExist()) {
- $query = "SELECT value FROM queuemanager WHERE field = 'switch'";
- $answer = $this->queryLastValue($query);
- $result = True;
- if ($answer == 'off') {
- $result = False;
- report("$query; returned '$answer'", 1);
- notifyRuntimeError("hrmd stopped",
- "$query; returned '$answer'\n\nThe HRM queue manage will stop.");
- }
- }
- else {
- $query = "select switch from queuemanager";
- $answer = $this->queryLastValue($query);
- $result = True;
- if ($answer == 'off') {
- $result = False;
- report("$query; returned '$answer'", 1);
- notifyRuntimeError("hrmd stopped",
- "$query; returned '$answer'\n\nThe HRM queue manage will stop.");
- }
- }
-
- return $result;
- }
-
- /*!
- \brief Gets the status of the queue manager's switch
- \return 'on' or 'off'
- */
- public function getSwitchStatus() {
- if ($this->doGlobalVariablesExist()) {
- $query = "SELECT value FROM queuemanager WHERE field = 'switch'";
- $answer = $this->queryLastValue($query);
- }
- else {
- $query = "select switch from queuemanager";
- $answer = $this->queryLastValue($query);
- }
- return $answer;
- }
-
- /*!
- \brief Sets the status of the queue manager's switch
- \param $status String Either 'on' or 'off'
- \return query result
- */
- public function setSwitchStatus( $status ) {
- $result = $this->execute("UPDATE queuemanager SET value = '". $status ."' WHERE field = 'switch'");
- return $result;
- }
-
- /*!
- \brief Sets the state of the server to 'busy' and the pid for a running job
- \param $name String Server name
- \param $pid String Process identifier associated with a running job
- \return query result
- */
- public function reserveServer($name, $pid) {
- $query = "update server set status='busy', job='$pid' where name='$name'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Sets the state of the server to 'free' and deletes the the pid
- \param $name String Server name
- \param $pid Process identifier associated with a running job (UNUSED!)
- \return query result
- */
- public function resetServer($name, $pid) {
- $query = "update server set status='free', job=NULL where name='$name'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Starts a job
- \param $job Job object
- \return query result
- */
- public function startJob($job) {
- $desc = $job->description();
- $id = $desc->id();
- $server = $job->server();
- $process_info = $job->pid();
- $query = "update job_queue set start=NOW(), server='$server', process_info='$process_info', status='started' where id='" .$id . "'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Get all running jobs
- \return array of Job objects
- */
- public function getRunningJobs() {
- $result = array();
- $query = "select id, process_info, server from job_queue where status = 'started'";
- $rows = $this->query($query);
- if (!$rows) return $result;
-
- foreach ($rows as $row) {
- $desc = new JobDescription();
- $desc->setId($row['id']);
- $desc->load();
- $job = new Job($desc);
- $job->setServer($row['server']);
- $job->setPid($row['process_info']);
- $job->setStatus('started');
- $result[] = $job;
- }
- return $result;
- }
-
- /*!
- \brief Get names of all processing servers (independent of their status)
- \return array of strings
- */
- public function availableServer() {
- $query = "select name from server";
- $result = $this->query($query);
- $result = $this->flatten($result);
- return $result;
- }
-
- /*/!
- \brief Get the starting time of given job object
- \param $job Job object
- \return Start time (String)
- */
- public function startTimeOf( Job $job ) {
- $desc = $job->description();
- $id = $desc->id();
- $query = "select start from job_queue where id = '" .$id . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!---------------------------------------------------------
- \brief Returns a formatted time from a unix timestamp
- \param $timestamp Unix timestamp
- \return formatted time string: YYYY-MM-DD hh:mm:ss
- */
- public function fromUnixTime($timestamp) {
- $query = "select FROM_UNIXTIME($timestamp)";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Pauses a job of given id
- \param $id Job id
- \return query result
- */
- public function pauseJob($id) {
- $query = "update job_queue set status='paused' where id='" . $id . "'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Sets the end time of a job
- \param $id Job id
- \param $date Formatted date: YYYY-MM-DD hh:mm:ss
- \return query result
- */
- public function setJobEndTime($id, $date) {
- $query = "update job_queue set stop='".$date."' where id='" . $id . "'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Changes status of 'paused' jobs to 'queued'
- \return query result
- */
- public function restartPausedJobs() {
- $query = "update job_queue set status='queued' where status='paused'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Marks a job with given id as 'broken' (i.e. to be removed)
- \param $id Job id
- \return query result
- */
- public function markJobAsRemoved($id) {
- $query = "update job_queue set status='broken' where (status='queued' or status='paused') and id='" . $id . "'";
- // $query = "update job_queue set status='broken' where id='" . $id . "'";
- $result = $this->execute($query);
- $query = "update job_queue set status='kill' where status='started' and id='" . $id . "'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Set the server status to free
- \param $server Server name
- \return query result
- */
- public function markServerAsFree($server) {
- $query = "update server set status='free', job=NULL where name='" . $server . "'";
- $result = $this->execute($query);
- return $result;
- }
-
- /*!
- \brief Get all jobs with status 'broken'
- \return array of ids
- */
- public function getMarkedJobIds() {
- $conditions['status'] = 'broken';
- $ids = $this->retrieveColumnFromTableWhere('id', 'job_queue', $conditions);
- return $ids;
- }
-
- /*!
- \brief Get all jobs with status 'kill' to be killed by the Queue Manager
- \return array of ids
- */
- public function getJobIdsToKill() {
- $conditions['status'] = 'kill';
- $ids = $this->retrieveColumnFromTableWhere('id', 'job_queue', $conditions);
- return $ids;
- }
-
- /*!
- \brief Check whether a user exists
- \param $name Name of the user
- \return true if the user exists
- */
- public function checkUser($name) {
- $query = "select status from username where name = '" . $name . "'";
- $result = $this->queryLastValue($query);
- if ($result) $result = true;
- return $result;
- }
-
- /*!
- \brief Get the status of a user
- \param $name Name of the user
- \return status ('a', 'd', ...)
- */
- public function getUserStatus($name) {
- $query = "select status from username where name = '" . $name . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Return the list of known users.
- \param String User name to filter out from the list (optional).
- \return Array of users.
- */
- public function getUserList($name) {
- $query = "select name from username where name != '" . $name . "' " .
- " and name != 'admin';";
- $result = $this->query($query);
- return $result;
- }
-
- /*!
- \brief Get the name of the user who owns a job with given id
- \param $id Job id
- \return name of the user who owns the job
- */
- public function getJobOwner($id) {
- $query = "select username from job_queue where id = '" . $id . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Returns current date and time
- \return formatted date (YYYY-MM-DD hh:mm:ss)
- */
- public function now() {
- $query = "select now()";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Returns the group to which the user belongs
- \param $userName Name of the user
- \return group name
- */
- public function getGroup($userName) {
- $query = "SELECT research_group FROM username WHERE name= '" . $userName . "'";
- $result = $this->queryLastValue($query);
- return $result;
- }
-
- /*!
- \brief Updates the e-mail address of a user
- \param $userName Name of the user
- \param $email E-mail address
- \return query result
- */
- public function updateMail($userName, $email) {
- $cmd = "UPDATE username SET email = '". $email ."' WHERE name = '".$userName."'";
- $result = $this->execute($cmd);
- return $result;
- }
-
- /*!
- \brief Updates the last access date of a user
- \param $userName Name of the user
- \return query result
- */
- public function updateLastAccessDate($userName) {
- $query = "UPDATE username SET last_access_date = CURRENT_TIMESTAMP WHERE name = '". $userName . "'";
- $result = $this->execute($query);
- return $result;
- }
-
-
- /*!
- \brief Gets the maximum number of channels from the database.
- \return The number of channels.
- */
- public function getMaxChanCnt() {
- $query = "SELECT MAX(value) as \"\" FROM possible_values ";
- $query .= "WHERE parameter='NumberOfChannels'";
- $result = trim($this->execute($query));
-
- if (!is_numeric($result)) {
- $result = 5;
- }
-
- return $result;
- }
-
-
- /*!
- \brief Get the list of Setting's for the User
-
- The Parameter values are not loaded.
-
- \return array of Setting's
- */
- public function getSettingList( $username, $table ) {
- $query = "select name, standard from $table where owner ='" . $username . "' order by name";
- return ( $this->query( $query ) );
- }
-
- /*!
- \brief Get the parameter confidence level for given file format
- \param $fileFormat File format for which the Parameter confidence level is queried
- (not strictly necessary for the Parameters with confidence level 'Provide',
- could be set to '' for those)
- \param $parameterName Name of the Paramater the confidence level should be returned
- \return parameter confidence level
- */
- public function getParameterConfidenceLevel( $fileFormat, $parameterName ) {
- // Some Parameters MUST be provided by the user and cannot be overridden
- // by the file metadata
- switch ( $parameterName ) {
- case 'ImageFileFormat' :
- case 'NumberOfChannels' :
- case 'PointSpreadFunction':
- case 'MicroscopeType' :
- case 'CoverslipRelativePosition':
- case 'PerformAberrationCorrection':
- case 'AberrationCorrectionMode':
- case 'AdvancedCorrectionOptions':
- case 'PSF' :
- return "provided";
- case 'Binning':
- case 'IsMultiChannel':
- case 'ObjectiveMagnification':
- case 'CMount':
- case 'TubeFactor':
- case 'AberrationCorrectionNecessary':
- case 'CCDCaptorSize':
- case 'PSFGenerationDepth':
- return "default";
- default:
-
- // For the other Parameters, the $fileFormat must be specified
- if ( ( $fileFormat == '' ) && ( $fileFormat == null ) ) {
- exit( "Error: please specify a file format!" . "\n" );
- }
-
- // The wavelength and voxel size parameters have a common confidence in
- // the HRM but two independent confidences in hucore
- if ( ( $parameterName == "ExcitationWavelength" ) ||
- ( $parameterName == "EmissionWavelength" ) ) {
-
- $confidenceLevelEx = $this->huCoreConfidenceLevel(
- $fileFormat, "ExcitationWavelength" );
- $confidenceLevelEm = $this->huCoreConfidenceLevel(
- $fileFormat, "EmissionWavelength" );
- $confidenceLevel = $this->minConfidenceLevel(
- $confidenceLevelEx, $confidenceLevelEm );
-
- } elseif ( ( $parameterName == "CCDCaptorSizeX" ) ||
- ( $parameterName == "ZStepSize" ) ) {
-
- $confidenceLevelX = $this->huCoreConfidenceLevel(
- $fileFormat, "CCDCaptorSizeX" );
- $confidenceLevelZ = $this->huCoreConfidenceLevel(
- $fileFormat, "ZStepSize" );
- $confidenceLevel = $this->minConfidenceLevel(
- $confidenceLevelX, $confidenceLevelZ );
-
- } else {
-
- $confidenceLevel = $this->huCoreConfidenceLevel(
- $fileFormat, $parameterName );
-
- }
-
- // Return the confidence level
- return $confidenceLevel;
-
- }
-
- }
-
- /*!
- \brief Finds out whether a Huygens module is supported by the license.
- \param $feature The module to find out about. It can use (SQL) wildcards.
- \return Boolean: true if the module is supported by the license.
- */
- public function hasLicense ( $feature ) {
-
- $query = "SELECT feature FROM hucore_license WHERE " .
- "feature LIKE '" . $feature . "' LIMIT 1;";
-
- if ( $this->queryLastValue($query) === FALSE ) {
- return false;
- } else {
- return true;
- }
- }
-
- /*!
- \brief Checks whether Huygens Core has a valid license
- \return true if the license is valid, false otherwise
- */
- public function hucoreHasValidLicense( ) {
-
- // We (ab)use the hasLicense() method
- return ( $this->hasLicense("freeware") == false);
- }
-
- /*!
- \brief Gets the licensed server type for Huygens Core.
- \return one of desktop, small, medium, large, extreme
- */
- public function hucoreServerType() {
-
- $query = "SELECT feature FROM hucore_license WHERE feature LIKE 'server=%';";
- $server = $this->queryLastValue($query);
- if ($server == false) {
- return "no server information";
- }
- return substr($server, 7);
- }
-
- /*!
- \brief Updates the database with the current HuCore license details.
- \param $licDetails A string with the supported license features.
- \return Boolean: true if the license details were successfully saved.
- */
- public function storeLicenseDetails ( $licDetails ) {
-
- $licStored = true;
-
- // Make sure that the hucore_license table exists.
- $tables = $this->connection->MetaTables("TABLES");
- if (!in_array("hucore_license", $tables) ) {
- $msg = "Table hucore_license does not exist! " .
- "Please update the database!";
- report( $msg, 1 ); exit( $msg );
- }
-
- // Empty table: remove existing values from older licenses.
- $query = "DELETE FROM hucore_license";
- $result = $this->execute($query);
-
- if (!$result) {
- report("Could not store license details in the database!\n", 1);
- $licStored = false;
- return $licStored;
- }
-
- // Populate the table with the new license.
- $features = explode(" ", $licDetails);
- foreach ($features as $feature) {
-
- switch( $feature ) {
- case 'desktop':
- case 'small':
- case 'medium':
- case 'large':
- case 'extreme':
- $feature = "server=" . $feature;
- report("Licensed server: $feature", 1);
- default:
- report("Licensed feature: $feature", 1);
- }
-
- $query = "INSERT INTO hucore_license (feature) ".
- "VALUES ('". $feature ."')";
- $result = $this->execute($query);
-
- if (!$result) {
- report("Could not store license feature
- '$feature' in the database!\n", 1);
- $licStored = false;
- break;
- }
- }
-
- return $licStored;
- }
-
- /*!
- \brief Store the confidence levels returned by huCore into the database for faster retrieval
-
- This is a rather low-level function that creates the table if needed.
-
- \param $confidenceLevels Array of confidence levels with file formats as keys
- \return true if storing (or updating) the database was successful, false otherwise
- */
- public function storeConfidenceLevels( $confidenceLevels ) {
-
- // Make sure that the confidence_levels table exists
- $tables = $this->connection->MetaTables("TABLES");
- if (!in_array("confidence_levels", $tables) ) {
- $msg = "Table confidence_levels does not exist! " .
- "Please update the database!";
- report( $msg, 1 ); exit( $msg );
- }
-
- // Get the file formats
- $fileFormats = array_keys( $confidenceLevels );
-
- // Get the keys of the parameter arrays from the first array (the others are the same)
- $parameters = array_keys( $confidenceLevels[ $fileFormats[ 0 ] ] );
-
- // Go over all $confidenceLevels and set the values
- foreach ( $fileFormats as $format ) {
-
- // If the row for current $fileFormat does not exist, INSERT a new
- // row with all parameters, otherwise UPDATE the existing one.
- $query = "SELECT fileFormat FROM confidence_levels WHERE " .
- "fileFormat = '" . $format . "' LIMIT 1;";
-
- if ( $this->queryLastValue($query) === FALSE ) {
-
- // INSERT
- if ( !$this->connection->AutoExecute( "confidence_levels",
- $confidenceLevels[ $format ], "INSERT" ) ) {
- $msg = "Could not insert confidence levels for file format $format!";
- report( $msg, 1 ); exit( $msg );
- }
-
- } else {
-
- // UPDATE
- if ( !$this->connection->AutoExecute( "confidence_levels",
- $confidenceLevels[ $format ], 'UPDATE',
- "fileFormat = '$format'" ) ) {
- $msg = "Could not update confidence levels for file format $format!";
- report( $msg, 1 ); exit( $msg);
- }
-
- }
-
- }
-
- return true;
-
- }
-
- /*!
- \brief Checks whether a user with a given seed exists in the database
-
- If a user requests an account, his username is added to the database with
- a random seed as status.
-
- \return true if a user with given seed exists, false otherwise
- */
- public function existsUserRequestWithSeed($seed) {
- $query = "SELECT status FROM username WHERE status = '" . $seed . "'";
- $value = $this->queryLastValue($query);
- if ($value == false) {
- return false;
- } else {
- return ( $value == $seed );
- }
-
- }
-
-
- public function switchGPUState( $newState ) {
- if ( $newState == "On" ) {
- $value = TRUE;
- } else if ( $newState == "Off" ) {
- $value = FALSE;
- } else {
- return "Impossible to change the GPU configuration. Unknown value.";
- }
-
- $query = "UPDATE global_variables SET value = '". $value ."' " .
- "WHERE name = 'GPUenabled';";
-
- $result = $this->execute($query);
- if ( $result ) {
- return "GPU processing has been turned " .
- strtolower($newState) . ".";
- } else {
- return "Impossible to change the GPU configuration.";
- }
- }
-
- public function getGPUStateAsString( ) {
- $query = "SELECT value FROM global_variables " .
- "WHERE name = 'GPUenabled';";
-
- if ($this->queryLastValue($query)) {
- return "true";
- } else {
- return "false";
- }
- }
-
-
- /*
- PRIVATE FUNCTIONS
- */
-
- /*!
- \brief Return the mapped HuCore file format corresponding to HRM's
- \param $fileFormat HRM's file format
- \return mapped HuCore file format
- */
- private function minConfidenceLevel( $level1, $level2 ) {
- $levels = array( );
- $levels[ 'default' ] = 0;
- $levels[ 'estimated' ] = 1;
- $levels[ 'reported' ] = 2;
- $levels[ 'verified' ] = 3;
- $levels[ 'asIs' ] = 3;
-
- if ( $levels[ $level1 ] <= $levels[ $level2 ] ) {
- return $level1;
- } else {
- return $level2;
- }
-
- }
-
- /*!
- \brief Return the raw HuCore confidence level
- \param $fileFormat HRM's file format
- \param $parameterName Name of the HRM Paramater
- \return HuCore's raw confidence level
- */
- private function huCoreConfidenceLevel( $fileFormat, $parameterName ) {
-
- // Get the mapped file format
- $query = "SELECT hucoreName FROM file_format WHERE name = '" .
- $fileFormat . "' LIMIT 1";
- $hucoreFileFormat = $this->queryLastValue( $query );
- if ( !$hucoreFileFormat ) {
- report( "Could not get the mapped file name for " . $fileFormat ."!", 1 );
- return "default";
- }
-
- // Use the mapped file format to retrieve the
- if (!array_key_exists($parameterName, $this->parameterNameDictionary)) {
- return "default";
- }
- $query = "SELECT " . $this->parameterNameDictionary[ $parameterName ] .
- " FROM confidence_levels WHERE fileFormat = '" . $hucoreFileFormat .
- "' LIMIT 1;";
- $confidenceLevel = $this->queryLastValue( $query );
- if ( !$confidenceLevel ) {
- report( "Could not get the confidence level for " . $fileFormat ."!", 1 );
- return "default";
- }
-
- // return the confidence level
- return $confidenceLevel;
- }
-
- /*!
- \brief Ugly hack to check for old table structure
- \return true if global variables exist
- */
- private function doGlobalVariablesExist() {
- global $db_type;
- global $db_host;
- global $db_name;
- global $db_user;
- global $db_password;
-
- $test = False;
-
- $dsn = $db_type."://".$db_user.":".$db_password."@".$db_host."/".$db_name;
- $db = ADONewConnection($dsn);
- if(!$db)
- return;
- $tables = $db->MetaTables("TABLES");
- if (in_array("global_variables", $tables))
- $test = True;
-
- return $test;
- }
-
-}
-?>
diff --git a/inc/Database.php b/inc/Database.php
new file mode 100644
index 000000000..912f48225
--- /dev/null
+++ b/inc/Database.php
@@ -0,0 +1,2363 @@
+connection = ADONewConnection($db_type);
+ $this->connection->Connect($db_host, $db_user, $db_password, $db_name);
+
+ // Set the parameter name dictionary
+ $this->parameterNameDictionary = array(
+ "CCDCaptorSizeX" => "sampleSizesX", // In HRM there is no distinction between x and y pixel size
+ "ZStepSize" => "sampleSizesZ",
+ "TimeInterval" => "sampleSizesT",
+ "PinholeSize" => "pinhole",
+ "NumberOfChannels" => "chanCnt",
+ "PinholeSpacing" => "pinholeSpacing",
+ "ExcitationWavelength" => "lambdaEx",
+ "EmissionWavelength" => "lambdaEm",
+ "MicroscopeType" => "mType",
+ "NumericalAperture" => "NA",
+ "ObjectiveType" => "RILens",
+ "SampleMedium" => "RIMedia",
+ "unused1" => "iFacePrim", // PSFGenerationDepth?
+ "unused2" => "iFaceScnd",
+ "unused3" => "imagingDir",
+ "unused4" => "objQuality",
+ "unused5" => "photonCnt",
+ "unused6" => "exBeamFill",
+ "StedDepletionMode" => "stedMode",
+ "StedWavelength" => "stedLambda",
+ "StedSaturationFactor" => "stedSatFact",
+ "StedImmunity" => "stedImmunity",
+ "Sted3D" => "sted3D");
+ }
+
+ /**
+ * Checks whether a connection to the DB is possible.
+ * @return boolean True if the connection is possible, false otherwise.
+ */
+ public function isReachable()
+ {
+ global $db_type;
+ global $db_host;
+ global $db_name;
+ global $db_user;
+ global $db_password;
+ /** @var ADODB_mysql|\ADODB_postgres8|\ADODB_postgres9 $connection */
+ $connection = ADONewConnection($db_type);
+ $result = $connection->Connect($db_host, $db_user, $db_password, $db_name);
+ return $result;
+ }
+
+ /**
+ * Returns the type of the database (mysql, postgres)
+ * @return string The type of the database (e.g. mysql, postgres)
+ */
+ public function type()
+ {
+ global $db_type;
+ return $db_type;
+ }
+
+ /**
+ * Attempts to get the version of the underlying database.
+ * @return string Version of the database (e.g. 2.2.14).
+ */
+ public function version()
+ {
+ try {
+ $query = "SELECT version( );";
+ $version = $this->queryLastValue($query);
+ } catch (\Exception $e) {
+ $version = "Could not get version information.";
+ }
+ return $version;
+ }
+
+ /**
+ * Returns the database host name.
+ * @return string Name of the database host.
+ */
+ public function host()
+ {
+ global $db_host;
+ return $db_host;
+ }
+
+ /**
+ * Returns the database name.
+ * @return string Name of the database.
+ */
+ public function name()
+ {
+ global $db_name;
+ return $db_name;
+ }
+
+ /**
+ * Returns the name of the database user.
+ * @return string Name of the database user.
+ */
+ public function user()
+ {
+ global $db_user;
+ return $db_user;
+ }
+
+ /**
+ * Returns the password of the database user.
+ * @return string Password of the database user.
+ */
+ public function password()
+ {
+ global $db_password;
+ return $db_password;
+ }
+
+ /**
+ * Returns the ADOConnection object.
+ * @return \ADORecordSet_mysql|\ADODB_postgres8|\ADODB_postgres9 The connection object.
+ */
+ public function connection()
+ {
+ return $this->connection;
+ }
+
+ /**
+ * Executes an SQL query.
+ * @param string $query SQL query.
+ * @return \ADORecordSet_empty|\ADORecordSet_mysql|False Query result.
+ */
+ public function execute($query)
+ {
+ /** @var ADODB_mysql|\ADODB_postgres8|\ADODB_postgres9 $connection */
+ $connection = $this->connection();
+ $result = $connection->Execute($query);
+ return $result;
+ }
+
+ /**
+ * Executes an SQL query and returns the results.
+ * @param string $queryString SQL query.
+ * @return array|false Result of the query (rows).
+ */
+ public function query($queryString)
+ {
+ $resultSet = $this->connection()->Execute($queryString);
+ if ($resultSet === false) {
+ return False;
+ }
+ /** @var \ADORecordSet $resultSet */
+ $rows = $resultSet->GetRows();
+ return $rows;
+ }
+
+ /**
+ * Executes an SQL query and returns the results.
+ * @param string $sql Prepared SQL query.
+ * @param array $values Array of values for the prepared query.
+ * @return array|false Result of the query (rows).
+ */
+ public function queryPrepared($sql, array $values)
+ {
+ $resultSet = $this->connection()->Execute($sql, $values);
+ if ($resultSet === false) {
+ return False;
+ }
+ /** @var \ADORecordSet $resultSet */
+ $rows = $resultSet->GetRows();
+ return $rows;
+ }
+
+ /**
+ * Executes an SQL query and returns the last row of the results.
+ * @param string $queryString SQL query.
+ * @return array Last row of the result of the query.
+ */
+ public function queryLastRow($queryString)
+ {
+ $rows = $this->query($queryString);
+ if (!$rows) {
+ return False;
+ }
+ $result = end($rows);
+ return $result;
+ }
+
+ /**
+ * Executes an SQL query and returns the value in the last column of the
+ * last row of the results.
+ * @param string $queryString SQL query.
+ * @return string Value of the last column of the last row of the result of
+ * the query.
+ */
+ public function queryLastValue($queryString)
+ {
+ $rows = $this->queryLastRow($queryString);
+ if (!$rows) {
+ return False;
+ }
+ $result = end($rows);
+ return $result;
+ }
+
+ /**
+ * Saves the parameter values of the setting object into the database.
+ *
+ * If the setting already exists, the old values are overwritten, otherwise
+ * a new setting is created.
+ *
+ * @param \hrm\setting\base\Setting $settings Settings object to be saved.
+ * @return bool True if saving was successful, false otherwise.
+ */
+ public function saveParameterSettings(Setting $settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ $settingTable = $settings->table();
+ $table = $settings->parameterTable();
+ if ($settings->isDefault())
+ $standard = "t";
+ else
+ $standard = "f";
+ $result = True;
+ if (!$this->existsSetting($settings)) {
+ $query = "insert into $settingTable values ('$user', '$name'" .
+ ", '$standard')";
+ $result = $result && $this->execute($query);
+ }
+ $existsAlready = $this->existsParametersFor($settings);
+
+ foreach ($settings->parameterNames() as $parameterName) {
+ $parameter = $settings->parameter($parameterName);
+ $parameterValue = $parameter->internalValue();
+
+ if (is_array($parameterValue)) {
+ /*! Before, # was used as a separator, but the first element
+ with index zero was always NULL because channels started
+ their indexing at one. To keep backwards compatibility with
+ the database, we use # now as a channel marker, and even the
+ first channel has a # in front of its value "/" separator is
+ used to mark range values for signal to noise ratio.
+ */
+
+ /*!
+ @todo Currently there are not longer "range values" (values
+ separated by /). In the future they will be reintroduced.
+ We leave the code in place.
+ */
+ if (is_array($parameterValue[0])) {
+ $maxChanCnt = $this->getMaxChanCnt();
+ for ($i = 0; $i < $maxChanCnt; $i++) {
+ if ($parameterValue[$i] != null) {
+ $parameterValue[$i] =
+ implode("/", array_filter($parameterValue[$i]));
+ }
+ }
+ }
+ $parameterValue = "#" . implode("#", $parameterValue);
+ }
+
+ if (!$existsAlready) {
+ $query = "INSERT INTO $table VALUES ('$user', '$name', " .
+ "'$parameterName', '$parameterValue');";
+ } else {
+ /* Check that the parameter itself exists. */
+ $query = "SELECT name FROM $table WHERE owner='$user' AND " .
+ "setting='$name' AND name='$parameterName' LIMIT 1;";
+ $newValue = $this->queryLastValue($query);
+
+ if ($newValue != NULL) {
+ $query = "UPDATE $table SET value = '$parameterValue' " .
+ "WHERE owner='$user' AND setting='$name' " .
+ "AND name='$parameterName';";
+ } else {
+ $query = "INSERT INTO $table VALUES ('$user', '$name', "
+ . "'$parameterName', '$parameterValue');";
+ }
+ }
+
+ // Accumulate the successes (or failures) of the queries. If a query
+ // fails, the return of $this->execute() will be === false; otherwise
+ // it is an ADORecordSet.
+ $result &= ($this->execute($query) !== false);
+ }
+
+
+ return $result;
+ }
+
+ /**
+ * Save the parameter values of the setting object into the shared tables.
+ *
+ * @param Setting $settings Settings object to be saved.
+ * @param string $targetUserName User name of the user that the Setting is
+ * to be shared with.
+ * @return bool True if saving was successful, false otherwise.
+ */
+ public function saveSharedParameterSettings($settings, $targetUserName)
+ {
+ $owner = $settings->owner();
+ $original_user = $owner->name();
+ $name = $settings->name();
+ $new_owner = new UserV2();
+ $new_owner->setName($targetUserName);
+ $settings->setOwner($new_owner);
+ /** @var ParameterSetting|TaskSetting|AnalysisSetting $settings */
+ $settingTable = $settings->sharedTable();
+ $table = $settings->sharedParameterTable();
+ $result = True;
+ if (!$this->existsSharedSetting($settings)) {
+ $query = "insert into $settingTable " .
+ "(owner, previous_owner, sharing_date, name) values " .
+ "('$targetUserName', '$original_user', CURRENT_TIMESTAMP, '$name')";
+ $result = $result && $this->execute($query);
+ }
+
+ if (!$result) {
+ return False;
+ }
+
+ // Get the Id
+ $query = "select id from $settingTable where " .
+ "owner='$targetUserName' AND previous_owner='$original_user' " .
+ "AND name='$name'";
+ $id = $this->queryLastValue($query);
+ if (!$id) {
+ return False;
+ }
+
+ // Get the parameter names
+ $parameterNames = $settings->parameterNames();
+
+ // Add the parameters
+ foreach ($parameterNames as $parameterName) {
+
+ $parameter = $settings->parameter($parameterName);
+ $parameterValue = $parameter->internalValue();
+
+ if (is_array($parameterValue)) {
+ // Before, # was used as a separator, but the first element with
+ // index zero was always NULL because channels started their indexing
+ // at one. To keep backwards compatibility with the database, we use
+ // # now as a channel marker, and even the first channel has a # in
+ // front of its value.
+ // "/" separator is used to mark range values for signal to noise ratio
+
+
+ // Special treatment for the PSF parameter.
+ if ($parameter->name() == "PSF") {
+
+ // Create hard links and update paths to the PSF files
+ // to point to the hard-links.
+ $fileServer = new Fileserver($original_user);
+ $parameterValue = $fileServer->createHardLinksToSharedPSFs(
+ $parameterValue, $targetUserName);
+
+ }
+
+ /*!
+ @todo Currently there are not longer "range values" (values
+ separated by /). In the future they will be reintroduced.
+ We leave the code in place.
+ */
+ if (is_array($parameterValue[0])) {
+ $maxChanCnt = $this->getMaxChanCnt();
+ for ($i = 0; $i < $maxChanCnt; $i++) {
+ if ($parameterValue[$i] != null) {
+ $parameterValue[$i] = implode("/", array_filter($parameterValue[$i]));
+ }
+ }
+ }
+ $parameterValue = "#" . implode("#", $parameterValue);
+ }
+
+ $query = "insert into $table " .
+ "(setting_id, owner, setting, name, value) " .
+ "values ('$id', '$targetUserName', '$name', " .
+ "'$parameterName', '$parameterValue');";
+ $result = $result && $this->execute($query);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Loads the parameter values for a setting and returns a copy of the
+ * setting with the loaded parameter values.
+ *
+ * If a value starts with # it is considered to be an array with the first
+ * value at the index 0.
+ * @param Setting $settings Setting object to be loaded.
+ * @return Setting $settings Setting object with loaded values.
+ * @todo Debug the switch blog (possibly buggy!)
+ */
+ public function loadParameterSettings($settings)
+ {
+ $user = $settings->owner();
+ $user = $user->name();
+ $name = $settings->name();
+ $table = $settings->parameterTable();
+
+ foreach ($settings->parameterNames() as $parameterName) {
+ $parameter = $settings->parameter($parameterName);
+ $query = "SELECT value FROM $table WHERE owner='$user' AND " .
+ "setting='$name' AND name='$parameterName';";
+
+ $newValue = $this->queryLastValue($query);
+
+ if ($newValue == NULL) {
+
+ // See if the Parameter has a usable default
+ $newValue = $parameter->defaultValue();
+ if ($newValue == NULL) {
+ continue;
+ }
+ }
+
+
+ if ($newValue{0} == '#') {
+ switch ($parameterName) {
+ case "ExcitationWavelength":
+ case "EmissionWavelength":
+ case "PinholeSize":
+ case "PinholeSpacing":
+ case "SignalNoiseRatio":
+ case "BackgroundOffsetPercent":
+ case "ChromaticAberration":
+ case "StedDepletionMode":
+ case "StedWavelength":
+ case "StedSaturationFactor":
+ case "StedImmunity":
+ case "Sted3D":
+ case "SpimExcMode":
+ case "SpimGaussWidth":
+ case "SpimCenterOffset":
+ case "SpimFocusOffset":
+ case "SpimNA":
+ case "SpimFill":
+ case "SpimDir":
+ case "ColocChannel":
+ case "ColocThreshold":
+ case "ColocCoefficient":
+ /* Extract and continue to explode. */
+ $newValue = substr($newValue, 1);
+ default:
+ $newValues = explode("#", $newValue);
+ }
+
+ if (strcmp($parameterName, "PSF") != 0
+ && strpos($newValue, "/")
+ ) {
+ $newValue = array();
+ for ($i = 0; $i < count($newValues); $i++) {
+ if (strpos($newValues[$i], "/")) {
+ $newValue[] = explode("/", $newValues[$i]);
+ } else {
+ $newValue[] = array($newValues[$i]);
+ }
+ }
+ } else {
+ $newValue = $newValues;
+ }
+ }
+
+ $parameter->setValue($newValue);
+ $settings->set($parameter);
+ }
+
+ return $settings;
+ }
+
+ /**
+ * Loads the parameter values for a setting fro mthe sharead tabled and
+ * returns it.
+ * @param int $id Setting id.
+ * @param string $type Setting type (one of "parameter", "task", "analysis").
+ * @return Setting object with loaded values.
+ * @throws \Exception
+ * @todo Debug the second switch block (probably buggy!)
+ */
+ public function loadSharedParameterSettings($id, $type)
+ {
+
+ // Get the correct objects
+ switch ($type) {
+
+ case "parameter":
+
+ $settingTable = ParameterSetting::sharedTable();
+ $table = ParameterSetting::sharedParameterTable();
+ $settings = new ParameterSetting();
+ break;
+
+ case "task":
+
+ $settingTable = TaskSetting::sharedTable();
+ $table = TaskSetting::sharedParameterTable();
+ $settings = new TaskSetting();
+ break;
+
+ case "analysis":
+
+ $settingTable = AnalysisSetting::sharedTable();
+ $table = AnalysisSetting::sharedParameterTable();
+ $settings = new AnalysisSetting();
+ break;
+
+ default:
+
+ throw new \Exception("bad value for type!");
+ }
+
+ // Get the setting info
+ $query = "select * from $settingTable where id=$id;";
+ $response = $this->queryLastRow($query);
+ if (!$response) {
+ return NULL;
+ }
+
+ // Fill the setting
+ $settings->setName($response["name"]);
+ $user = new UserV2();
+ $user->setName($response["owner"]);
+ $settings->setOwner($user);
+
+ // Load from shared table
+ foreach ($settings->parameterNames() as $parameterName) {
+ $parameter = $settings->parameter($parameterName);
+ $query = "select value from $table where setting_id=$id and name='$parameterName'";
+ $newValue = $this->queryLastValue($query);
+ if ($newValue == NULL) {
+ // See if the Parameter has a usable default
+ $newValue = $parameter->defaultValue();
+ if ($newValue == NULL) {
+ continue;
+ }
+ }
+ if ($newValue{0} == '#') {
+ switch ($parameterName) {
+ case "ExcitationWavelength":
+ case "EmissionWavelength":
+ case "SignalNoiseRatio":
+ case "BackgroundOffsetPercent":
+ case "ChromaticAberration":
+ /* Extract and continue to explode. */
+ $newValue = substr($newValue, 1);
+ default:
+ $newValues = explode("#", $newValue);
+ }
+
+ if (strcmp($parameterName, "PSF") != 0 && strpos($newValue, "/")) {
+ $newValue = array();
+ for ($i = 0; $i < count($newValues); $i++) {
+ //$val = explode("/", $newValues[$i]);
+ //$range = array(NULL, NULL, NULL, NULL);
+ //for ($j = 0; $j < count($val); $j++) {
+ // $range[$j] = $val[$j];
+ //}
+ //$newValue[] = $range;
+ /*!
+ @todo Currently there are not longer "range values" (values
+ separated by /). In the future they will be reintroduced.
+ We leave the code in place.
+ */
+ if (strpos($newValues[$i], "/")) {
+ $newValue[] = explode("/", $newValues[$i]);
+ } else {
+ $newValue[] = array($newValues[$i]);
+ }
+ }
+ } else {
+ $newValue = $newValues;
+ }
+ }
+ //$shiftedNewValue = array(1 => NULL, 2 => NULL, 3 => NULL, 4 => NULL, 5 => NULL);
+ //if (is_array($newValue)) {
+ // // start array at 1
+ // for ($i = 1; $i <= count($newValue); $i++) {
+ // $shiftedNewValue[$i] = $newValue[$i - 1];
+ // }
+ //}
+ //else $shiftedNewValue = $newValue;
+ $parameter->setValue($newValue);
+ $settings->set($parameter);
+ }
+ return $settings;
+ }
+
+ /**
+ * Returns the list of shared templates with the given user.
+ * @param string $username Name of the user for whom to query for shared
+ * templates.
+ * @param string $table Name of the shared table to query.
+ * @return array List of shared jobs.
+ */
+ public function getTemplatesSharedWith($username, $table)
+ {
+ $query = "SELECT * FROM $table WHERE owner='$username'";
+ $result = $this->query($query);
+ return $result;
+ }
+
+ /**
+ * Returns the list of shared templates by the given user.
+ * @param string $username Name of the user for whom to query for shared
+ * templates.
+ * @param string $table Name of the shared table to query.
+ * @return array List of shared jobs.
+ */
+ public function getTemplatesSharedBy($username, $table)
+ {
+ $query = "SELECT * FROM $table WHERE previous_owner='$username'";
+ $result = $this->query($query);
+ return $result;
+ }
+
+ /**
+ * Copies the relevant rows from shared- to user- tables.
+ * @param int $id ID of the setting to be copied.
+ * @param string $sourceSettingTable Setting table to copy from.
+ * @param string $sourceParameterTable Parameter table to copy from.
+ * @param string $destSettingTable Setting table to copy to.
+ * @param string $destParameterTable Parameter table to copy to.
+ * @return bool True if copying was successful; false otherwise.
+ */
+ public function copySharedTemplate($id, $sourceSettingTable,
+ $sourceParameterTable, $destSettingTable, $destParameterTable)
+ {
+
+ // Get the name of the previous owner (the one sharing the setting).
+ $query = "select previous_owner, owner, name from $sourceSettingTable where id=$id";
+ $rows = $this->queryLastRow($query);
+ if (False === $rows) {
+ return False;
+ }
+ $previous_owner = $rows["previous_owner"];
+ $owner = $rows["owner"];
+ $setting_name = $rows["name"];
+
+ // Compose the new name of the setting
+ $out_setting_name = $previous_owner . "_" . $setting_name;
+
+ // Check if a setting with this name already exists in the target tables
+ $query = "select name from $destSettingTable where " .
+ "name='$out_setting_name' and owner='$owner'";
+ if ($this->queryLastValue($query)) {
+
+ // The setting already exists; we try adding numerical indices
+ $n = 1;
+ $original_out_setting_name = $out_setting_name;
+ while (1) {
+
+ $test_name = $original_out_setting_name . "_" . $n++;
+ $query = "select name from $destSettingTable where name='$test_name' and owner='$owner'";
+ if (!$this->queryLastValue($query)) {
+ $out_setting_name = $test_name;
+ break;
+ }
+ }
+
+ }
+
+ // Get all rows from source table for given setting id
+ $query = "select * from $sourceParameterTable where setting_id=$id";
+ $rows = $this->query($query);
+ if (count($rows) == 0) {
+ return False;
+ }
+
+ // Now add the rows to the destination table
+ $ok = True;
+ $record = array();
+ $this->connection->BeginTrans();
+ foreach ($rows as $row) {
+ $record["owner"] = $row["owner"];
+ $record["setting"] = $out_setting_name;
+ $record["name"] = $row["name"];
+
+ // PSF files must be processed differently
+ if ($record["name"] == "PSF") {
+
+ // Instantiate a Fileserver object for the target user
+ $fileserver = new Fileserver($owner);
+
+ // Get the array of PSF names
+ $values = $row["value"];
+ if ($values[0] == "#") {
+ $values = substr($values, 1);
+ }
+ $psfFiles = explode('#', $values);
+
+ // Create hard-links to the target user folder
+ $newPSFFiles = $fileserver->createHardLinksFromSharedPSFs(
+ $psfFiles, $owner, $previous_owner);
+
+ // Update the entries for the database
+ $record["value"] = "#" . implode('#', $newPSFFiles);
+
+ } else {
+
+ $record["value"] = $row["value"];
+
+ }
+
+ $insertSQL = $this->connection->GetInsertSQL($destParameterTable,
+ $record);
+ $status = $this->connection->Execute($insertSQL);
+ $ok &= !(false === $status);
+ if (!$ok) {
+ break;
+ }
+ }
+
+ // If everything went okay, we commit the transaction; otherwise we roll
+ // back
+ if ($ok) {
+ $this->connection->CommitTrans();
+ } else {
+ $this->connection->RollbackTrans();
+ return False;
+ }
+
+ // Now add the setting to the setting table
+ $query = "select * from $sourceSettingTable where id=$id";
+ $rows = $this->query($query);
+ if (count($rows) != 1) {
+ return False;
+ }
+
+ $ok = True;
+ $this->connection->BeginTrans();
+ $record = array();
+ $row = $rows[0];
+ $record["owner"] = $row["owner"];
+ $record["name"] = $out_setting_name;
+ $record["standard"] = 'f';
+ $insertSQL = $this->connection->GetInsertSQL($destSettingTable,
+ $record);
+ $status = $this->connection->Execute($insertSQL);
+ $ok &= !(false === $status);
+
+ if ($ok) {
+ $this->connection->CommitTrans();
+ } else {
+ $this->connection->RollbackTrans();
+ return False;
+ }
+
+ // Now we can delete the records from the source tables. Even if it
+ // if it fails we do not roll back, since the parameters were copied
+ // successfully.
+
+ // Delete setting entry
+ $query = "delete from $sourceSettingTable where id=$id";
+ $status = $this->connection->Execute($query);
+ if (false === $status) {
+ return False;
+ }
+
+ // Delete parameter entries
+ $query = "delete from $sourceParameterTable where setting_id=$id";
+ $status = $this->connection->Execute($query);
+ if (false === $status) {
+ return False;
+ }
+
+ return True;
+ }
+
+ /**
+ * Delete the relevant rows from the shared tables.
+ * @param int $id ID of the setting to be deleted.
+ * @param string $sourceSettingTable Setting table to copy from.
+ * @param string $sourceParameterTable Parameter table to copy from.
+ * @return bool True if deleting was successful; false otherwise.
+ */
+ public function deleteSharedTemplate($id, $sourceSettingTable,
+ $sourceParameterTable)
+ {
+
+ // Initialize success
+ $ok = True;
+
+ // Delete shared PSF files if any exist
+ if ($sourceParameterTable == "shared_parameter") {
+ $query = "select value from $sourceParameterTable where setting_id=$id and name='PSF'";
+ $psfFiles = $this->queryLastValue($query);
+ if (NULL != $psfFiles && $psfFiles != "#####") {
+ if ($psfFiles[0] == "#") {
+ $psfFiles = substr($psfFiles, 1);
+ }
+
+ // Extract PSF file paths from the string
+ $psfFiles = explode("#", $psfFiles);
+
+ // Delete them
+ Fileserver::deleteSharedFSPFilesFromBuffer($psfFiles);
+ }
+ }
+
+ // Delete setting entry
+ $query = "delete from $sourceSettingTable where id=$id";
+ $status = $this->connection->Execute($query);
+ $ok &= !(false === $status);
+
+ // Delete parameter entries
+ $query = "delete from $sourceParameterTable where setting_id=$id";
+ $status = $this->connection->Execute($query);
+ $ok &= !(false === $status);
+
+ return $ok;
+ }
+
+ /**
+ * Updates the default entry in the database according to the default
+ * value in the setting.
+ * @param Setting $settings Settings object to be used to update the default.
+ * @return array query result.
+ */
+ public function updateDefault($settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ if ($settings->isDefault())
+ $standard = "t";
+ else
+ $standard = "f";
+ $table = $settings->table();
+ $query = "update $table set standard = '$standard' where owner='$user' and name='$name'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Deletes the setting and all its parameter values from the database.
+ * @param Setting $settings Settings object to be used to delete all entries
+ * from the database.
+ * @return bool true if the setting and all parameters were deleted from the
+ * database; false otherwise.
+ */
+ public function deleteSetting($settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ $result = True;
+ $table = $settings->parameterTable();
+ $query = "delete from $table where owner='$user' and setting='$name'";
+ $result = $result && $this->execute($query);
+ if (!$result) {
+ return FALSE;
+ }
+ $table = $settings->table();
+ $query = "delete from $table where owner='$user' and name='$name'";
+ $result = $result && $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Checks whether parameters are already stored for a given setting.
+ * @param Setting $settings Settings object to be used to check for
+ * existence in the database.
+ * @return bool True if the parameters exist in the database; false otherwise.
+ */
+ public function existsParametersFor($settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ $table = $settings->parameterTable();
+ $query = "select name from $table where owner='$user' and setting='$name' LIMIT 1";
+ $result = True;
+ if (!$this->queryLastValue($query)) {
+ $result = False;
+ }
+ return $result;
+ }
+
+ /**
+ * Checks whether parameters are already stored for a given shared setting.
+ * @param ParameterSetting|TaskSetting|AnalysisSetting $settings Settings object to be used to check for existence
+ * in the database.
+ * @return bool True if the parameters exist in the database; false otherwise.
+ */
+ public function existsSharedParametersFor($settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ $table = $settings->sharedParameterTable();
+ $query = "select name from $table where owner='$user' and setting='$name' LIMIT 1";
+ $result = True;
+ if (!$this->queryLastValue($query)) {
+ $result = False;
+ }
+ return $result;
+ }
+
+ /**
+ * Checks whether settings exist in the database for a given owner.
+ *
+ * @param Setting $settings Settings object to be used to check for
+ * existence in the database (the name of the owner must be set in the
+ * settings).
+ * @return bool True if the settings exist in the database; false otherwise.
+ */
+ public function existsSetting(Setting $settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ $table = $settings->table();
+ $query = "select standard from $table where owner='$user' and name='$name' LIMIT 1";
+ $result = True;
+ if (!$this->queryLastValue($query)) {
+ $result = False;
+ }
+ return $result;
+ }
+
+ /**
+ * Checks whether shared settings exist in the database for a given owner.
+ * @param ParameterSetting|TaskSetting|AnalysisSetting $settings $settings Settings object to be used to check for
+ * existence in the database (the name of the owner must be set in the
+ * settings)
+ * @return bool True if the settings exist in the database; false otherwise.
+ */
+ public function existsSharedSetting($settings)
+ {
+ $owner = $settings->owner();
+ $user = $owner->name();
+ $name = $settings->name();
+ $table = $settings->sharedTable();
+ $query = "select standard from $table where owner='$user' and name='$name' LIMIT 1";
+ $result = True;
+ if (!$this->queryLastValue($query)) {
+ $result = False;
+ }
+ return $result;
+ }
+
+ /**
+ * Adds all files for a given job id and user to the database.
+ * @param string $id Job id.
+ * @param string $owner Name of the user that owns the job.
+ * @param array $files Array of file names.
+ * @param bool $autoseries True if the series is to be loaded automatically, false otherwise.
+ * @return bool True if the job files could be saved successfully; false
+ * otherwise.
+ */
+ public function saveJobFiles($id, $owner, $files, $autoseries)
+ {
+ $result = True;
+ /** @var UserV2 $owner */
+ $username = $owner->name();
+ $sqlAutoSeries = "";
+ foreach ($files as $file) {
+ if (strcasecmp($autoseries, "TRUE") == 0 || strcasecmp($autoseries, "T") == 0) {
+ $sqlAutoSeries = "T";
+ }
+ $slashesFile = addslashes($file);
+ $query = "insert into job_files values ('$id', '$username', '$slashesFile', '$sqlAutoSeries')";
+ $result = $result && $this->execute($query);
+ }
+ return $result;
+ }
+
+ /**
+ * Adds a job for a given job id and user to the queue.
+ * @param string $id Job id.
+ * @param string $username Name of the user that owns the job.
+ * @return array Query result.
+ */
+ public function queueJob($id, $username)
+ {
+ $query = "insert into job_queue (id, username, queued, status) values ('$id', '$username', NOW(), 'queued')";
+ return $this->execute($query);
+ }
+
+ /**
+ * Assigns priorities to the jobs in the queue.
+ * @return True if assigning priorities was successful.
+ */
+ public function setJobPriorities()
+ {
+
+ $result = True;
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // First we analyze the queue
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ // Get the number of users that currently have jobs in the queue
+ $users = $this->execute("SELECT DISTINCT( username ) FROM job_queue;");
+ $row = $this->execute("SELECT COUNT( DISTINCT( username ) ) FROM job_queue;")->FetchRow();
+ $numUsers = $row[0];
+
+ // 'Highest' priority (i.e. lowest value) is 0
+ $currentPriority = 0;
+
+ // First, we make sure to give the highest priorities to paused and
+ // broken jobs
+ $rs = $this->execute("SELECT id FROM job_queue WHERE status = 'broken' OR status = 'paused';");
+ if ($rs) {
+ while ($row = $rs->FetchRow()) {
+
+ // Update the priority for current job id
+ $query = "UPDATE job_queue SET priority = " . $currentPriority++ .
+ " WHERE id = '" . $row[0] . "';";
+
+ $rs = $this->execute($query);
+ if (!$rs) {
+ Log::error("Could not update priority for key " . $row[0]);
+ $result = False;
+ return $result;
+ }
+
+ }
+ }
+
+ // Then, we go through to running jobs
+ $rs = $this->execute("SELECT id FROM job_queue WHERE status = 'started';");
+ if ($rs) {
+ while ($row = $rs->FetchRow()) {
+
+ // Update the priority for current job id
+ $query = "UPDATE job_queue SET priority = " . $currentPriority++ .
+ " WHERE id = '" . $row[0] . "';";
+
+ $rs = $this->execute($query);
+ if (!$rs) {
+ Log::error("Could not update priority for key " . $row[0]);
+ $result = False;
+ return $result;
+ }
+ }
+ }
+
+ // Then we organize the queued jobs in a way that lets us then assign
+ // priorities easily in a second pass
+ $numJobsPerUser = array();
+ $userJobs = array();
+ for ($i = 0; $i < $numUsers; $i++) {
+ // Get current username
+ $row = $users->FetchRow();
+ $username = $row[0];
+ $query = "SELECT id
+ FROM job_queue, job_files
+ WHERE job_queue.id = job_files.job AND
+ job_queue.username = job_files.owner AND
+ job_queue.username = '$username' AND
+ status = 'queued'
+ ORDER BY job_queue.queued asc, job_files.file asc";
+ $rs = $this->execute($query);
+ if ($rs) {
+ $userJobs[$i] = array();
+ $counter = 0;
+ while ($row = $rs->FetchRow()) {
+ $userJobs[$i][$counter++] = $row[0];
+ }
+ $numJobsPerUser[$i] = $counter;
+ }
+ }
+
+ // Now we can assign priorities to the queued jobs -- minimum priority is 1
+ // above the priorities assigned to all other types of jobs
+ $maxNumJobs = max($numJobsPerUser);
+ for ($j = 0; $j < $maxNumJobs; $j++) {
+ for ($i = 0; $i < $numUsers; $i++) {
+ if ($j < count($userJobs[$i])) {
+ // Update the priority for current job id
+ $query = "UPDATE job_queue SET priority = " .
+ $currentPriority . " WHERE id = '" .
+ $userJobs[$i][$j] . "';";
+
+ $rs = $this->execute($query);
+ if (!$rs) {
+ Log::error("Could not update priority for key " . $userJobs[$i][$j]);
+ $result = False;
+ return $result;
+ }
+ $currentPriority++;
+ }
+ }
+ }
+
+ // We can now return true
+ return $result;
+ }
+
+ /**
+ * Logs job information in the statistics table.
+ * @param Job $job Job object whose information is to be logged in the
+ * database.
+ * @param string $startTime Job start time.
+ * @return void
+ */
+ public function updateStatistics(Job $job, $startTime)
+ {
+ /** @var JobDescription $desc */
+ $desc = $job->description();
+ $parameterSetting = $desc->parameterSetting();
+ $taskSetting = $desc->taskSetting();
+ $analysisSetting = $desc->analysisSetting();
+
+ $stopTime = date("Y-m-d H:i:s");
+ $id = $desc->id();
+ /** @var UserV2 $user */
+ $user = $desc->owner();
+ $owner = $user->name();
+ $group = $user->group();
+
+ $parameter = $parameterSetting->parameter('ImageFileFormat');
+ $inFormat = $parameter->value();
+ $parameter = $parameterSetting->parameter('PointSpreadFunction');
+ $PSF = $parameter->value();
+ $parameter = $parameterSetting->parameter('MicroscopeType');
+ $microscope = $parameter->value();
+ $parameter = $taskSetting->parameter('OutputFileFormat');
+ $outFormat = $parameter->value();
+ $parameter = $analysisSetting->parameter('ColocAnalysis');
+ $colocAnalysis = $parameter->value();
+
+ $query = "insert into statistics values ('$id', '$owner', '$group', " .
+ "'$startTime', '$stopTime', '$inFormat', '$outFormat', " .
+ "'$PSF', '$microscope', '$colocAnalysis')";
+
+ $this->execute($query);
+
+ }
+
+ /**
+ * Flattens a multi-dimensional array.
+ * @param array $anArray Multi-dimensional array.
+ * @return array Flattened array.
+ */
+ public function flatten($anArray)
+ {
+ $result = array();
+ foreach ($anArray as $row) {
+ $result[] = end($row);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns the possible values for a given parameter.
+ * @param Parameter $parameter Parameter object.
+ * @return array Flattened array of possible values.
+ */
+ public function readPossibleValues($parameter)
+ {
+ $name = $parameter->name();
+ $query = "select value from possible_values where parameter = '$name';";
+ $answer = $this->query($query);
+ $result = $this->flatten($answer);
+ return $result;
+ }
+
+ /**
+ * Returns the translated possible values for a given parameter.
+ * @param Parameter $parameter Parameter object.
+ * @return array Flattened array of translated possible values.
+ */
+ public function readTranslatedPossibleValues($parameter)
+ {
+ $name = $parameter->name();
+ $query = "select translation from possible_values where parameter = '$name';";
+ $answer = $this->query($query);
+ $result = $this->flatten($answer);
+ return $result;
+ }
+
+ /**
+ * Returns the translation of current value for a given parameter.
+ * @param string $parameterName Name of the Parameter object.
+ * @param string $value Value for which a translation should be returned.
+ * @return string Translated value.
+ */
+ public function translationFor($parameterName, $value)
+ {
+ $query = "select translation from possible_values where parameter = '$parameterName' and value = '$value';";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Returns the translation of a hucore value.
+ * @param string $parameterName Name of the Parameter object.
+ * @param string $hucorevalue Value name in HuCore.
+ * @return string Expected value by HRM.
+ */
+ public function hucoreTranslation($parameterName, $hucorevalue)
+ {
+ $query = "select value from possible_values where parameter = '" . $parameterName . "' and translation = '" . $hucorevalue . "'";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Returns an array of all file extensions.
+ * @return array Array of file extensions.
+ */
+ public function allFileExtensions()
+ {
+ $query = "select distinct extension from file_extension";
+ $answer = $this->query($query);
+ $result = $this->flatten($answer);
+ return $result;
+ }
+
+ /**
+ * Returns an array of all extensions for multi-dataset files.
+ * @return array Array of file extensions for multi-dataset files.
+ */
+ public function allMultiFileExtensions()
+ {
+ $query = "SELECT name FROM file_format, file_extension
+ WHERE file_format.name = file_extension.file_format
+ AND file_format.ismultifile LIKE 't'";
+ $answer = $this->query($query);
+ $result = $this->flatten($answer);
+ return $result;
+ }
+
+ /**
+ * Returns an array of file extensions associated to a given file format.
+ * @param string $imageFormat File format.
+ * @return array Array of file extensions.
+ */
+ public function fileExtensions($imageFormat)
+ {
+ $query = "select distinct extension from file_extension where file_format = '$imageFormat';";
+ $answer = $this->query($query);
+ $result = $this->flatten($answer);
+ return $result;
+ }
+
+ /**
+ * Returns all restrictions for a given numerical parameter.
+ * @param Parameter $parameter Parameter (object).
+ * @return array Array of restrictions.
+ */
+ public function readNumericalValueRestrictions(Parameter $parameter)
+ {
+ $name = $parameter->name();
+ $query = "select min, max, min_included, max_included, standard from boundary_values where parameter = '$name';";
+ $result = $this->queryLastRow($query);
+ if (!$result) {
+ $result = array(null, null, null, null, null);
+ }
+ return $result;
+ }
+
+ /**
+ * Returns the file formats that fit the conditions expressed by the
+ * parameters.
+ * @param bool $isSingleChannel Set whether the file format must be single
+ * channel (True), multi channel (False) or if it doesn't matter (NULL).
+ * @param bool $isVariableChannel Set whether the number of channels must be
+ * variable (True), fixed (False) or if it doesn't matter (NULL).
+ * @param bool $isFixedGeometry Set whether the geometry (xyzt) must be fixed
+ * (True), variable (False) or if it doesn't matter (NULL).
+ * @return array Array of file formats.
+ * @todo Check if this method is still used.
+ */
+ public function fileFormatsWith($isSingleChannel, $isVariableChannel, $isFixedGeometry)
+ {
+ $isSingleChannelValue = 'f';
+ $isVariableChannelValue = 'f';
+ $isFixedGeometryValue = 'f';
+ if ($isSingleChannel) {
+ $isSingleChannelValue = 't';
+ }
+ if ($isVariableChannel) {
+ $isVariableChannelValue = 't';
+ }
+ if ($isFixedGeometry) {
+ $isFixedGeometryValue = 't';
+ }
+ $conditions = array();
+ if ($isSingleChannel != NULL) {
+ $conditions['isSingleChannel'] = $isSingleChannelValue;
+ }
+ if ($isVariableChannel != NULL) {
+ $conditions['isVariableChannel'] = $isVariableChannelValue;
+ }
+ if ($isFixedGeometry != NULL) {
+ $conditions['isFixedGeometry'] = $isFixedGeometryValue;
+ }
+ return $this->retrieveColumnFromTableWhere('name', 'file_format', $conditions);
+ }
+
+ /**
+ * Returns the geometries (XY, XY-time, XYZ, XYZ-time) fit the conditions
+ * expressed by the parameters.
+ * @param bool $isThreeDimensional True if 3D.
+ * @param bool $isTimeSeries True if time-series.
+ * @return array Array of geometries.
+ * @todo Check if this method is still used.
+ */
+ public function geometriesWith($isThreeDimensional, $isTimeSeries)
+ {
+ $isThreeDimensionalValue = 'f';
+ $isTimeSeriesValue = 'f';
+ if ($isThreeDimensional) {
+ $isThreeDimensionalValue = 't';
+ }
+ if ($isTimeSeries) {
+ $isTimeSeriesValue = 't';
+ }
+ $conditions = array();
+ if ($isThreeDimensional != NULL) {
+ $conditions['isThreeDimensional'] = $isThreeDimensionalValue;
+ }
+ if ($isTimeSeries != NULL) {
+ $conditions['isTimeSeries'] = $isTimeSeriesValue;
+ }
+ return $this->retrieveColumnFromTableWhere("name", "geometry", $conditions);
+ }
+
+ /**
+ * Return all values from the column from the table where the condition
+ * evaluates to true.
+ * @param string $column Name of the column from which the values are taken
+ * @param string $table Name of the table from which the values are taken
+ * @param array $conditions Array of conditions that the result values must
+ * fulfill. This is an array with column names as indices and boolean values
+ * as content.
+ * @return array Array of values.
+ */
+ public function retrieveColumnFromTableWhere($column, $table, $conditions)
+ {
+ $query = "select distinct $column from $table where ";
+ foreach ($conditions as $eachName => $eachValue) {
+ $query = $query . $eachName . " = '" . $eachValue . "' and ";
+ }
+ $query = $query . "1 = 1";
+ $answer = $this->query($query);
+ $result = array();
+
+ if (!empty($answer)) {
+ foreach ($answer as $row) {
+ $result[] = end($row);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the default value for a given parameter.
+ * @param string $parameterName Name of the parameter.
+ * @return string Default value.
+ */
+ public function defaultValue($parameterName)
+ {
+ $query = "SELECT value FROM possible_values WHERE " .
+ "parameter='$parameterName' AND isDefault='t'";
+ $result = $this->queryLastValue($query);
+ if ($result === False) {
+ return NULL;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the id for next job from the queue, sorted by priority.
+ * @return string Job id.
+ */
+ public function getNextIdFromQueue()
+ {
+ // For the query we join job_queue and job_files, since we want to sort also by file name
+ $query = "SELECT id
+ FROM job_queue, job_files
+ WHERE job_queue.id = job_files.job AND job_queue.username = job_files.owner
+ AND job_queue.status = 'queued'
+ ORDER BY job_queue.priority desc, job_queue.status desc, job_files.file desc;";
+ $result = $this->queryLastValue($query);
+ if (!$result) {
+ return NULL;
+ }
+ return $result;
+ }
+
+ /**
+ * Returns all jobs from the queue, both compound and simple, ordered by
+ * priority.
+ * @return array All jobs.
+ */
+ public function getQueueJobs()
+ {
+ // Get jobs as they are in the queue, compound or not, without splitting
+ // them.
+ $query = "SELECT id, username, queued, start, server, process_info, status
+ FROM job_queue
+ ORDER BY job_queue.priority asc, job_queue.queued asc, job_queue.status asc;";
+ $result = $this->query($query);
+ return $result;
+ }
+
+ /**
+ * Returns all jobs from the queue, both compound and simple, and the
+ * associated file names, ordered by priority.
+ * @return array All jobs.
+ */
+ public function getQueueContents()
+ {
+ // For the query we join job_queue and job_files, since we want to sort also by file name
+ $query = "SELECT id, username, queued, start, stop, server, process_info, status, file
+ FROM job_queue, job_files
+ WHERE job_queue.id = job_files.job AND job_queue.username = job_files.owner
+ ORDER BY job_queue.priority asc, job_queue.queued asc, job_queue.status asc, job_files.file asc
+ LIMIT 100";
+ $result = $this->query($query);
+ return $result;
+ }
+
+ /**
+ * Returns all jobs from the queue for a given id (that must be unique!)
+ * @param string $id Id of the job.
+ * @return array All jobs for the id
+ */
+ public function getQueueContentsForId($id)
+ {
+ $query = "select id, username, queued, start, server, process_info, status from job_queue where id='$id';";
+ $result = $this->queryLastRow($query); // it is supposed that just one job exists with a given id
+ return $result;
+ }
+
+ /**
+ * Returns all file names associated to a job with given id.
+ * @param string $id Job id.
+ * @return array Array of file names.
+ */
+ public function getJobFilesFor($id)
+ {
+ $query = "select file from job_files where job = '" . $id . "'";
+ $result = $this->query($query);
+ $result = $this->flatten($result);
+ return $result;
+ }
+
+ /**
+ * Returns the file series mode of a job with given id.
+ * @param string $id Job id
+ * @return bool True if file series, false otherwise.
+ */
+ public function getSeriesModeForId($id)
+ {
+ $query = "select autoseries from job_files where job = '$id';";
+ $result = $this->queryLastValue($query);
+
+ return $result;
+ }
+
+ /**
+ * Returns the name of the user who created the job with given id.
+ * @param string $id SId of the job.
+ * @return string Name of the user.
+ */
+ public function userWhoCreatedJob($id)
+ {
+ $query = "select username from job_queue where id = '$id';";
+ $result = $this->queryLastValue($query);
+ if (!$result) {
+ return NULL;
+ }
+ return $result;
+ }
+
+ /**
+ * Deletes job with specified ID from all job tables.
+ * @param string $id Id of the job.
+ * @return bool True if success, false otherwise.
+ */
+ public function deleteJobFromTables($id)
+ {
+ // TODO: Use foreign keys in the database!
+ $result = True;
+ $result = $result && $this->execute(
+ "delete from job_analysis_parameter where setting='$id';");
+ $result = $result && $this->execute(
+ "delete from job_analysis_setting where name='$id';");
+ $result = $result && $this->execute(
+ "delete from job_files where job='$id';");
+ $result = $result && $this->execute(
+ "delete from job_parameter where setting='$id';");
+ $result = $result && $this->execute(
+ "delete from job_parameter_setting where name='$id';");
+ $result = $result && $this->execute(
+ "delete from job_queue where id='$id';");
+ $result = $result && $this->execute(
+ "delete from job_task_parameter where setting='$id';");
+ $result = $result && $this->execute(
+ "delete from job_task_setting where name='$id';");
+ return $result;
+ }
+
+ /**
+ * Returns the path to hucore on given host.
+ * @param string $host Host name.
+ * @return string Full path to hucore.
+ * @todo Better management of multiple hosts.
+ */
+ function huscriptPathOn($host)
+ {
+ $query = "SELECT huscript_path FROM server where name = '$host'";
+ $result = $this->queryLastValue($query);
+ if (!$result) {
+ return NULL;
+ }
+ return $result;
+ }
+
+ /**
+ * Get the name of a free server.
+ * @return string Name of the free server.
+ */
+ public function freeServer()
+ {
+ $query = "select name from server where status='free'";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Get the status (i.e. free, busy, paused) of server with given name.
+ * @param string $name Name of the server.
+ * @return string Status (one of 'free', 'busy', or 'paused').
+ */
+ public function statusOfServer($name)
+ {
+ $query = "select status from server where name='$name'";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Checks whether server is busy.
+ * @param string $name Name of the server.
+ * @return bool True if the server is busy, false otherwise
+ */
+ public function isServerBusy($name)
+ {
+ $status = $this->statusOfServer($name);
+ $result = ($status == 'busy');
+ return $result;
+ }
+
+ /**
+ * Checks whether the switch in the queue manager is 'on'.
+ * @return bool True if switch is on, false otherwise.
+ */
+ public function isSwitchOn()
+ {
+ // Handle some back-compatibility issue
+ if ($this->doGlobalVariablesExist()) {
+ $query = "SELECT value FROM queuemanager WHERE field = 'switch'";
+ $answer = $this->queryLastValue($query);
+ $result = True;
+ if ($answer == 'off') {
+ $result = False;
+ Log::warning("$query; returned '$answer'");
+ Util::notifyRuntimeError("hrmd stopped",
+ "$query; returned '$answer'\n\nThe HRM queue manage will stop.");
+ }
+ } else {
+ $query = "select switch from queuemanager";
+ $answer = $this->queryLastValue($query);
+ $result = True;
+ if ($answer == 'off') {
+ $result = False;
+ Log::warning("$query; returned '$answer'");
+ Util::notifyRuntimeError("hrmd stopped",
+ "$query; returned '$answer'\n\nThe HRM queue manage will stop.");
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Gets the status of the queue manager's switch.
+ * @return string 'on' or 'off'
+ */
+ public function getSwitchStatus()
+ {
+ if ($this->doGlobalVariablesExist()) {
+ $query = "SELECT value FROM queuemanager WHERE field = 'switch'";
+ $answer = $this->queryLastValue($query);
+ } else {
+ $query = "select switch from queuemanager";
+ $answer = $this->queryLastValue($query);
+ }
+ return $answer;
+ }
+
+ /**
+ * Sets the status of the queue manager's switch.
+ * @param string $status Either 'on' or 'off'
+ * @return array Query result.
+ */
+ public function setSwitchStatus($status)
+ {
+ $result = $this->execute("UPDATE queuemanager SET value = '$status' WHERE field = 'switch'");
+ return $result;
+ }
+
+ /**
+ * Sets the state of the server to 'busy' and the pid for a running job.
+ * @param string $name Server name.
+ * @param string $pid Process identifier associated with a running job.
+ * @return array Query result.
+ */
+ public function reserveServer($name, $pid)
+ {
+ $query = "update server set status='busy', job='$pid' where name='$name'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Sets the state of the server to 'free' and deletes the the pid.
+ * @param string $name Server name.
+ * @param string $pid Process identifier associated with a running job (UNUSED!).
+ * @return array Query result.
+ */
+ public function resetServer($name, $pid)
+ {
+ $query = "update server set status='free', job=NULL where name='$name'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Starts a job.
+ * @param Job $job Job object.
+ * @return array Query result.
+ */
+ public function startJob(Job $job)
+ {
+ $desc = $job->description();
+ $id = $desc->id();
+ $server = $job->server();
+ $process_info = $job->pid();
+ $query = "update job_queue set start=NOW(), server='$server', process_info='$process_info', status='started' where id='$id'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Get all running jobs.
+ * @return array Array of Job objects.
+ */
+ public function getRunningJobs()
+ {
+ $result = array();
+ $query = "select id, process_info, server from job_queue where status = 'started'";
+ $rows = $this->query($query);
+ if (!$rows) return $result;
+
+ foreach ($rows as $row) {
+ $desc = new JobDescription();
+ $desc->setId($row['id']);
+ $desc->load();
+ $job = new Job($desc);
+ $job->setServer($row['server']);
+ $job->setPid($row['process_info']);
+ $job->setStatus('started');
+ $result[] = $job;
+ }
+ return $result;
+ }
+
+ /**
+ * Get names of all processing servers (independent of their status).
+ * @return array Array of server names.
+ */
+ public function availableServer()
+ {
+ $query = "select name from server";
+ $result = $this->query($query);
+ $result = $this->flatten($result);
+ return $result;
+ }
+
+ /**
+ * Get the starting time of given job object.
+ * @param Job $job Job object.
+ * @return string Start time.
+ */
+ public function startTimeOf(Job $job)
+ {
+ $desc = $job->description();
+ $id = $desc->id();
+ $query = "select start from job_queue where id = '$id';";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Returns a formatted time from a unix timestamp.
+ * @param string $timestamp Unix timestamp.
+ * @return string Formatted time string: YYYY-MM-DD hh:mm:ss.
+ */
+ public function fromUnixTime($timestamp)
+ {
+ $query = "select FROM_UNIXTIME($timestamp)";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Pauses a job of given id.
+ * @param string $id Job id
+ * @return array query result.
+ */
+ public function pauseJob($id)
+ {
+ $query = "update job_queue set status='paused' where id='$id';";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Sets the end time of a job.
+ * @param string $id Job id.
+ * @param string $date Formatted date: YYYY-MM-DD hh:mm:ss.
+ * @return array Query result.
+ */
+ public function setJobEndTime($id, $date)
+ {
+ $query = "update job_queue set stop='$date' where id='$id'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Changes status of 'paused' jobs to 'queued'.
+ * @return array Query result
+ */
+ public function restartPausedJobs()
+ {
+ $query = "update job_queue set status='queued' where status='paused'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Marks a job with given id as 'broken' (i.e. to be removed).
+ * @param string $id Job id.
+ * @return array Query result.
+ */
+ public function markJobAsRemoved($id)
+ {
+ $query = "update job_queue set status='broken' where (status='queued' or status='paused') and id='$id';";
+ // $query = "update job_queue set status='broken' where id='" . $id . "'";
+ $result = $this->execute($query);
+ $query = "update job_queue set status='kill' where status='started' and id='$id';";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Set the server status to free.
+ * @param string $server Server name.
+ * @return array Query result.
+ */
+ public function markServerAsFree($server)
+ {
+ $query = "update server set status='free', job=NULL where name='$server'";
+ $result = $this->execute($query);
+ return $result;
+ }
+
+ /**
+ * Get all jobs with status 'broken'.
+ * @return array Array of ids for broken jobs.
+ */
+ public function getMarkedJobIds()
+ {
+ $conditions['status'] = 'broken';
+ $ids = $this->retrieveColumnFromTableWhere('id', 'job_queue', $conditions);
+ return $ids;
+ }
+
+ /**
+ * Get all jobs with status 'kill' to be killed by the Queue Manager.
+ * @return array Array of ids for jobs to be killed.
+ */
+ public function getJobIdsToKill()
+ {
+ $conditions['status'] = 'kill';
+ $ids = $this->retrieveColumnFromTableWhere('id', 'job_queue', $conditions);
+ return $ids;
+ }
+
+ /**
+ * Return the list of known users (without the administrator).
+ * @param string String User name to filter out from the list (optional).
+ * @return array Filtered array of users.
+ */
+ public function getUserList($name)
+ {
+ $query = "select name from username where name != '$name' " .
+ " and name != 'admin';";
+ $result = $this->query($query);
+ return $result;
+ }
+
+ /**
+ * Get the name of the user who owns a job with given id.
+ * @param string $id Job id.
+ * @return string Name of the user who owns the job.
+ */
+ public function getJobOwner($id)
+ {
+ $query = "select username from job_queue where id = '$id'";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Returns current database (!) date and time.
+ * @return string formatted date (YYYY-MM-DD hh:mm:ss).
+ */
+ public function now()
+ {
+ $query = "select now()";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Returns the group to which the user belongs.
+ * @param string $userName Name of the user
+ * @return string Group name.
+ */
+ public function getGroup($userName)
+ {
+ $query = "SELECT research_group FROM username WHERE name= '$userName'";
+ $result = $this->queryLastValue($query);
+ return $result;
+ }
+
+ /**
+ * Updates the e-mail address of a user.
+ * @param string $userName Name of the user.
+ * @param string $email E-mail address.
+ * @return array Query result.
+ */
+ public function updateMail($userName, $email)
+ {
+ $cmd = "UPDATE username SET email = '$email' WHERE name = '$userName'";
+ $result = $this->execute($cmd);
+ return $result;
+ }
+
+ /**
+ * Gets the maximum number of channels from the database.
+ * @return int The number of channels.
+ */
+ public function getMaxChanCnt()
+ {
+ $query = "SELECT MAX(CAST(value AS unsigned)) as \"\"";
+ $query .= "FROM possible_values WHERE parameter='NumberOfChannels'";
+ $result = trim($this->execute($query));
+
+ if (!is_numeric($result)) {
+ $result = 5;
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * Get the list of settings for the user with given name from the given
+ * settings table.
+ *
+ * The Parameter values are not loaded.
+ * @param string $username Name of the user.
+ * @param string $table Name of the settings table.
+ * @return array Array of settings
+ */
+ public function getSettingList($username, $table)
+ {
+ $query = "select name, standard from $table where owner ='$username' order by name";
+ return ($this->query($query));
+ }
+
+ /**
+ * Get the parameter confidence level for given file format.
+ * @param string $fileFormat File format for which the Parameter confidence
+ * level is queried (not strictly necessary for the Parameters with
+ * confidence level 'Provide', could be set to '' for those).
+ * @param string $parameterName Name of the Parameter the confidence level
+ * should be returned.
+ * @return string Parameter confidence level.
+ */
+ public function getParameterConfidenceLevel($fileFormat, $parameterName)
+ {
+ // Some Parameters MUST be provided by the user and cannot be overridden
+ // by the file metadata
+ switch ($parameterName) {
+ case 'ImageFileFormat' :
+ case 'NumberOfChannels' :
+ case 'PointSpreadFunction':
+ case 'MicroscopeType' :
+ case 'CoverslipRelativePosition':
+ case 'PerformAberrationCorrection':
+ case 'AberrationCorrectionMode':
+ case 'AdvancedCorrectionOptions':
+ case 'PSF' :
+ return "provided";
+ case 'Binning':
+ case 'IsMultiChannel':
+ case 'ObjectiveMagnification':
+ case 'CMount':
+ case 'TubeFactor':
+ case 'AberrationCorrectionNecessary':
+ case 'CCDCaptorSize':
+ case 'PSFGenerationDepth':
+ return "default";
+ default:
+
+ // For the other Parameters, the $fileFormat must be specified
+ if (($fileFormat == '') && ($fileFormat == null)) {
+ exit("Error: please specify a file format!" . "\n");
+ }
+
+ // The wavelength and voxel size parameters have a common
+ // confidence in the HRM but two independent confidences
+ // in hucore
+ if (($parameterName == "ExcitationWavelength") ||
+ ($parameterName == "EmissionWavelength")
+ ) {
+
+ $confidenceLevelEx = $this->huCoreConfidenceLevel(
+ $fileFormat, "ExcitationWavelength");
+ $confidenceLevelEm = $this->huCoreConfidenceLevel(
+ $fileFormat, "EmissionWavelength");
+ $confidenceLevel = $this->minConfidenceLevel(
+ $confidenceLevelEx, $confidenceLevelEm);
+
+ } elseif (($parameterName == "CCDCaptorSizeX") ||
+ ($parameterName == "ZStepSize")
+ ) {
+
+ $confidenceLevelX = $this->huCoreConfidenceLevel(
+ $fileFormat, "CCDCaptorSizeX");
+ $confidenceLevelZ = $this->huCoreConfidenceLevel(
+ $fileFormat, "ZStepSize");
+ $confidenceLevel = $this->minConfidenceLevel(
+ $confidenceLevelX, $confidenceLevelZ);
+
+ } else {
+
+ $confidenceLevel = $this->huCoreConfidenceLevel(
+ $fileFormat, $parameterName);
+
+ }
+
+ // Return the confidence level
+ return $confidenceLevel;
+
+ }
+
+ }
+
+ /**
+ * Finds out whether a Huygens module is supported by the license.
+ * @param string $feature The module to find out about. It can use (SQL)
+ * wildcards.
+ * @return bool True if the module is supported by the license, false
+ * otherwise.
+ */
+ public function hasLicense($feature)
+ {
+
+ $query = "SELECT feature FROM hucore_license WHERE " .
+ "feature LIKE '$feature' LIMIT 1;";
+
+ if ($this->queryLastValue($query) === FALSE) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Checks whether Huygens Core has a valid license.
+ * @return bool True if the license is valid, false otherwise.
+ */
+ public function hucoreHasValidLicense()
+ {
+
+ // We (ab)use the hasLicense() method
+ return ($this->hasLicense("freeware") == false);
+ }
+
+ /**
+ * Gets the licensed server type for Huygens Core.
+ * @return string One of desktop, small, medium, large, extreme.
+ */
+ public function hucoreServerType()
+ {
+
+ $query = "SELECT feature FROM hucore_license WHERE feature LIKE 'server=%';";
+ $server = $this->queryLastValue($query);
+ if ($server == false) {
+ return "no server information";
+ }
+ return substr($server, 7);
+ }
+
+ /**
+ * Updates the database with the current HuCore license details.
+ * @param string $licDetails A string with the supported license features.
+ * @return bool True if the license details were successfully saved, false
+ * otherwise.
+ */
+ public function storeLicenseDetails($licDetails)
+ {
+
+ $licStored = true;
+
+ // Make sure that the hucore_license table exists.
+ $tables = $this->connection->MetaTables("TABLES");
+ if (!in_array("hucore_license", $tables)) {
+ $msg = "Table hucore_license does not exist! " .
+ "Please update the database!";
+ Log::error($msg);
+ exit($msg);
+ }
+
+ // Empty table: remove existing values from older licenses.
+ $query = "DELETE FROM hucore_license";
+ $result = $this->execute($query);
+
+ if (!$result) {
+ Log::error("Could not store license details in the database!\n");
+ $licStored = false;
+ return $licStored;
+ }
+
+ // Populate the table with the new license.
+ $features = explode(" ", $licDetails);
+ foreach ($features as $feature) {
+
+ Log::info("Storing license feature: " . $feature . PHP_EOL);
+
+ switch ($feature) {
+ case 'desktop':
+ case 'small':
+ case 'medium':
+ case 'large':
+ case 'extreme':
+ $feature = "server=" . $feature;
+ Log::info("Licensed server: $feature");
+ break;
+ default:
+ Log::info("Licensed feature: $feature");
+ }
+
+ $query = "INSERT INTO hucore_license (feature) VALUES ('$feature')";
+ $result = $this->execute($query);
+
+ if (!$result) {
+ Log::error("Could not store license feature
+ '$feature' in the database!\n");
+ $licStored = false;
+ break;
+ }
+ }
+
+ return $licStored;
+ }
+
+ /**
+ * Store the confidence levels returned by huCore into the database for
+ * faster retrieval.
+ *
+ * This is a rather low-level function that creates the table if needed.
+ *
+ * @param array $confidenceLevels Array of confidence levels with file
+ * formats as keys.
+ * @return bool True if storing (or updating) the database was successful,
+ * false otherwise.
+ */
+ public function storeConfidenceLevels($confidenceLevels)
+ {
+
+ // Make sure that the confidence_levels table exists
+ $tables = $this->connection->MetaTables("TABLES");
+ if (!in_array("confidence_levels", $tables)) {
+ $msg = "Table confidence_levels does not exist! " .
+ "Please update the database!";
+ Log::error($msg);
+ exit($msg);
+ }
+
+ // Get the file formats
+ $fileFormats = array_keys($confidenceLevels);
+
+ // Go over all $confidenceLevels and set the values
+ foreach ($fileFormats as $format) {
+
+ // If the row for current $fileFormat does not exist, INSERT a new
+ // row with all parameters, otherwise UPDATE the existing one.
+ $query = "SELECT fileFormat FROM confidence_levels WHERE " .
+ "fileFormat = '" . $format . "' LIMIT 1;";
+
+ if ($this->queryLastValue($query) === FALSE) {
+
+ // INSERT
+ if (!$this->connection->AutoExecute("confidence_levels",
+ $confidenceLevels[$format], "INSERT")
+ ) {
+ $msg = "Could not insert confidence levels for file format $format!";
+ Log::error($msg);
+ exit($msg);
+ }
+
+ } else {
+
+ // UPDATE
+ if (!$this->connection->AutoExecute("confidence_levels",
+ $confidenceLevels[$format], 'UPDATE',
+ "fileFormat = '$format'")
+ ) {
+ $msg = "Could not update confidence levels for file format $format!";
+ Log::error($msg);
+ exit($msg);
+ }
+
+ }
+
+ }
+
+ return true;
+
+ }
+
+
+ /**
+ * Get the state of GPU acceleration (as string).
+ * @return string One "true" or "false".
+ */
+ public function getGPUID($server)
+ {
+ $query = "SELECT gpuId FROM server WHERE name = '$server';";
+
+ $result = $this->queryLastValue($query);
+
+ return intval($result);
+ }
+
+
+ /**
+ * Add a server (including GPU info) to the list of processing machines
+ for the queue manager.
+ * @return integer > 0 on failure; 0 on success.
+ */
+ public function addServer($serverName, $huPath, $gpuId)
+ {
+ if (!is_numeric($gpuId)) {
+ return "error: invalid GPU ID";
+ }
+
+ /* This allows for multiple entries for the same machine. */
+ /* The queue manager only looks at the machine name and rejecting
+ anything after the blank. */
+ $server = "$serverName $gpuId";
+
+ $query = "INSERT INTO server VALUES " .
+ "('$server','$huPath','free','NULL','$gpuId')";
+ $result = $this->queryLastValue($query);
+
+ return intval($result);
+ }
+
+
+ /**
+ * Remove a server from the list of processing machines for the queue
+ manager.
+ * @return integer > 0 on failure; 0 on success.
+ */
+ public function removeServer($serverName)
+ {
+ $query = "DELETE FROM server WHERE name='$serverName';";
+ $result = $this->queryLastValue($query);
+
+ return intval($result);
+ }
+
+
+ public function getAllServers($server)
+ {
+ $query = "SELECT * FROM server;";
+
+ $result = $this->query($query);
+
+ return $result;
+ }
+
+
+ /* ------------------------ PRIVATE FUNCTIONS --------------------------- */
+
+ /**
+ * Return the minimum of two confidence levels.
+ *
+ * The order of the levels is as follows:
+ *
+ * 'default' < 'estimated' < 'reported' < 'verified' < 'asIs'.
+ *
+ * @param string $level1 One of 'default', 'estimated', 'reported',
+ * 'verified', 'asIs'.
+ * @param string $level2 One of 'default', 'estimated', 'reported',
+ * 'verified', 'asIs'.
+ * @return string The minimum of the two confidence levels.
+ */
+ private function minConfidenceLevel($level1, $level2)
+ {
+ $levels = array();
+ $levels['default'] = 0;
+ $levels['estimated'] = 1;
+ $levels['reported'] = 2;
+ $levels['verified'] = 3;
+ $levels['asIs'] = 3;
+
+ if ($levels[$level1] <= $levels[$level2]) {
+ return $level1;
+ } else {
+ return $level2;
+ }
+
+ }
+
+ /**
+ * Returns the raw HuCore confidence level.
+ * @param string $fileFormat HRM's file format.
+ * @param string $parameterName Name of the HRM Parameter.
+ * @return string HuCore's raw confidence level.
+ */
+ private function huCoreConfidenceLevel($fileFormat, $parameterName)
+ {
+
+ // Get the mapped file format
+ $query = "SELECT hucoreName FROM file_format WHERE name = '" .
+ $fileFormat . "' LIMIT 1";
+ $hucoreFileFormat = $this->queryLastValue($query);
+ if (!$hucoreFileFormat) {
+ Log::warning("Could not get the mapped file name for " . $fileFormat . "!");
+ return "default";
+ }
+
+ // Use the mapped file format to retrieve the
+ if (!array_key_exists($parameterName, $this->parameterNameDictionary)) {
+ return "default";
+ }
+ $query = "SELECT " . $this->parameterNameDictionary[$parameterName] .
+ " FROM confidence_levels WHERE fileFormat = '" . $hucoreFileFormat .
+ "' LIMIT 1;";
+ $confidenceLevel = $this->queryLastValue($query);
+ if (!$confidenceLevel) {
+ Log::warning("Could not get the confidence level for " . $fileFormat . "!");
+ return "default";
+ }
+
+ // return the confidence level
+ return $confidenceLevel;
+ }
+
+ /**
+ * Ugly hack to check for old table structure.
+ * @return bool True if global variables table exists, false otherwise.
+ */
+ private function doGlobalVariablesExist()
+ {
+ global $db_type;
+ global $db_host;
+ global $db_name;
+ global $db_user;
+ global $db_password;
+
+ $test = False;
+
+ $dsn = $db_type . "://" . $db_user . ":" . $db_password . "@" . $db_host . "/" . $db_name;
+ /** @var ADODB_mysql|\ADODB_postgres8|\ADODB_postgres9 $db */
+ $db = ADONewConnection($dsn);
+ if (!$db)
+ return False;
+ $tables = $db->MetaTables("TABLES");
+ if (in_array("global_variables", $tables))
+ $test = True;
+
+ return $test;
+ }
+
+}
diff --git a/inc/FileBrowser.inc.php b/inc/FileBrowser.php
similarity index 64%
rename from inc/FileBrowser.inc.php
rename to inc/FileBrowser.php
index 04ca7678d..135339028 100644
--- a/inc/FileBrowser.inc.php
+++ b/inc/FileBrowser.php
@@ -1,9 +1,19 @@
getValidArchiveTypesAsString();
- $onClick = "uploadImages('$maxFile', '$maxPost', " .
- "'$validExtensions')";
- $tip = 'Upload a file (or a compressed archive of files) to the ' .
+ $onClick = "uploadImagesAlt()";
+ $tip = 'Upload one or more files (or compressed archives of files) to the ' .
'server';
$name = "upload";
break;
@@ -174,6 +180,7 @@ function fileButton($type) {
"jqTree/tree.jquery.js",
"jquery-ui/jquery-ui-1.9.1.custom.js",
"jquery-ui/jquery.bgiframe-2.1.2.js",
+ "fineuploader/jquery.fine-uploader.js",
"omero.js");
if (!isset($operationResult)) {
@@ -335,6 +342,10 @@ function imageAction (list) {
// The destination folder needs parsing to locate the previews.
$pathAndFile = $pdir . "/" . $file;
preg_match($pattern, $pathAndFile, $matches);
+ if (count($matches) == 0 ) {
+ unset($files[$key]);
+ continue;
+ }
$filePreview = $matches[1] . "/hrm_previews/";
$filePreview .= basename($file) . ".preview_xy.jpg";
@@ -375,7 +386,7 @@ function imageAction (list) {
$flag = " disabled=\"disabled\"";
}
-include("header.inc.php");
+include("header_fb.inc.php");
@@ -389,7 +400,7 @@ function imageAction (list) {
if (isset($top_nav_left)) {
echo $top_nav_left;
} else {
- wiki_link('HuygensRemoteManagerHelpFileManagement');
+ echo(Nav::linkWikiPage('HuygensRemoteManagerHelpFileManagement'));
}
?>
@@ -403,16 +414,16 @@ function imageAction (list) {
// was not the dashboard (home.php) but e.g. the "Select
// images" when creating a new job.
if ( strpos( $referer, 'home.php' ) === False ) {
- include("./inc/nav/back.inc.php");
+ echo(Nav::linkBack($referer));
}
}
if ( $browse_folder == "dest" ) {
- include("./inc/nav/files_raw.inc.html");
+ echo(Nav::linkRawImages());
} else {
- include("./inc/nav/files_results.inc.html");
+ echo(Nav::linkResults());
}
- include("./inc/nav/user.inc.php");
- include("./inc/nav/home.inc.php");
+ echo(Nav::textUser($_SESSION['user']->name()));
+ echo(Nav::linkHome(Util::getThisPageName()));
?>
@@ -449,7 +460,7 @@ function imageAction (list) {
diff --git a/inc/Fileserver.inc.php b/inc/Fileserver.inc.php
deleted file mode 100644
index b661cadab..000000000
--- a/inc/Fileserver.inc.php
+++ /dev/null
@@ -1,3841 +0,0 @@
-username = $name;
- $this->files = NULL;
- $this->selectedFiles = NULL;
- $this->destFiles = NULL;
- $this->imageExtensions = NULL;
-
- // Set the valid image extensions
- $db = new DatabaseConnection();
- $this->validImageExtensions = $db->allFileExtensions();
-
- // Set the multi-image extensions
- $this->multiImageExtensions = $db->allMultiFileExtensions();
-
- // Only valid archive types are those for which decompression commands are
- // specified.
- $this->validArchiveExtensions = array_keys($decompressBin);
- }
-
- /*!
- \brief Checks whether the file area is reachable
- \return true if the file area is reachable
- */
- // FIXME: for most parts, this is not sufficient as it only checks for
- // existence, not for permissions to read/write in these folders!
- public function isReachable() {
- $result = file_exists($this->sourceFolder());
- $result = $result && file_exists($this->destinationFolder());
- return $result;
- }
-
- /*!
- \brief Returns the name of the user
- \return name of the user
- */
- public function username() {
- return $this->username;
- }
-
- /*!
- \brief Returns the absolute path to the user's source image folder. The
- folder may be on the local network
- \return absolute path to the source image folder
- */
- public function sourceFolder() {
- global $image_folder;
- global $image_source;
- $folder = $image_folder . "/" . $this->username . "/" . $image_source;
- return $folder;
- }
-
- /*!
- \brief Returns the absolute path to the user's destination image folder.
- The folder may be on the local network
- \return absolute path to the destination image folder
- */
- public function destinationFolder() {
- global $image_folder;
- global $image_destination;
- $folder = $image_folder . "/" . $this->username . "/" . $image_destination;
- return $folder;
- }
-
- /*!
- \brief Returns the destination image folder from a JobDescription object
- \param $desc JobDescription object
- \return destination image folder with user-generated subfolder
- */
- public function destinationFolderFor($desc) {
- $folder = $this->destinationFolder() . "/" . $desc->relativeSourcePath();
- return $folder;
- }
-
- /*!
- \brief Searches the source folder recursively, stores and also returns the
- list of found files
- \param $extension Extension to be considered to scan the folder. Omit to
- get all files
- \return sorted array of file names
- */
- public function files( $extension = null ) {
- if ( is_null( $extension ) ) {
- if ($this->files == NULL) {
- $this->getFiles();
- }
- return $this->files;
- } else {
- if (!file_exists($this->sourceFolder())) {
- return False;
- }
- $files = $this->listFilesFrom($this->sourceFolder(), "", $extension);
- sort($files);
- $this->files = $files;
- return $files;
- }
- }
-
- /*!
- \brief Extracts the file extension, also if it's a subimage.
- \param $file The file name
- \param $selectedFormat The format selected at the select images stage.
- \return The file extension
- */
- public function checkAgainstFormat($file, $selectedFormat) {
-
- // Both variables as in the 'file_extension' table.
- $fileFormat = false;
- $fileExtension = false;
-
- // Pattern ome.tiff = (\.([^\..]+))*
- // Pattern file extension: = \.([A-Za-z0-9]+)
- // Pattern lif subimages: = (\s\(.*\))*
-
- $pattern = "/(\.([^\..]+))*\.([A-Za-z0-9]+)(\s\(.*\))*$/";
-
- // A first check on the file extension.
- if (preg_match($pattern,$file,$nameDivisions)) {
-
- // Specific to ome-tiff.
- if (isset($nameDivisions[2])) {
- if ($nameDivisions[2] == 'ome') {
- $fileExtension = $nameDivisions[2] . ".";
- }
- }
-
- // Main extension.
- if (isset($nameDivisions[3])) {
- $fileExtension .= $nameDivisions[3];
- }
-
- $fileExtension = strtolower($fileExtension);
- switch ($fileExtension) {
- case 'dv':
- case 'ims':
- case 'lif':
- case 'lsm':
- case 'oif':
- case 'pic':
- case 'r3d':
- case 'stk':
- case 'zvi':
- case 'czi':
- case 'nd2':
- case 'tf2':
- case 'tf8':
- case 'btf':
- $fileFormat = $fileExtension;
- break;
- case 'h5':
- $fileFormat = 'hdf5';
- break;
- case 'tif':
- case 'tiff':
- $fileFormat = 'tiff-generic';
- $fileExtension = "tiff";
- break;
- case 'ome.tif':
- case 'ome.tiff':
- $fileFormat = 'ome-tiff';
- $fileExtension = "ome.tiff";
- break;
- case 'ome':
- $fileFormat = 'ome-xml';
- break;
- case 'ics':
- $fileFormat = 'ics2';
- break;
- default:
- $fileFormat = '';
- $fileExtension = '';
- }
- }
-
- // Control over tiffs: this structure corresponds to Leica tiffs.
- $pattern = "/[^_]+_(T|t|Z|z|CH|ch)[0-9]+\w+\.\w+/";
-
- if (preg_match($pattern,$file,$matches)) {
- if ($fileExtension == 'tiff' || $fileExtension == 'tif') {
- $fileFormat = 'tiff-leica';
- }
- }
-
- // Control over stks: redundant.
- $pattern = "/[^_]+_(T|t)[0-9]+\.\w+/";
-
- if (preg_match($pattern,$file,$matches)) {
- if ($fileExtension == 'stk') {
- $fileFormat = 'stk';
- }
- }
-
- // Control over ics's, no distinction between ics and ics2.
- if ($fileExtension == 'ics') {
- if ($selectedFormat == 'ics' || $selectedFormat == 'ics2') {
- $fileFormat = $selectedFormat;
- }
- }
-
- if ($selectedFormat != '' && $selectedFormat == $fileFormat) {
- return true;
- } else if ($selectedFormat == 'big-tiff' && $fileFormat == 'tf2') {
- return true;
- } else if ($selectedFormat == 'big-tiff' && $fileFormat == 'tf8') {
- return true;
- } else if ($selectedFormat == 'big-tiff' && $fileFormat == 'btf') {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief Searches the source folder recursively and returns all found files
- \param $expandSubInages if true, names of subimages (as in the case of
- lif files) are expanded and returned in the
- list of file names
-
- Please notice that this function DOES NOT STORE THE LIST OF FILES. It
- just returns it!
-
- \return sorted array of file names
- */
- public function listFiles( $expand ) {
- // Store current selections and extensions
- $currentExtensions = $this->imageExtensions;
- $currentFiles = $this->files;
-
- // Process
- $this->setDefaultImageExtensions(array());
- $this->expandSubImages($expand);
- $this->getFiles();
- $files = $this->files();
-
- // Restore the previous selections
- $this->files = $currentFiles;
- $this->imageExtensions = $currentExtensions;
-
- // Return the processed list of files
- return $files;
- }
-
- /*!
- \brief Searches the destination folder recursively and returns all found files
- \param $extension Extension to be considered to scan the folder. Omit to
- get all files
- \return sorted array of file names
- */
- public function destFiles( $extension = null ) {
- if ( is_null( $extension ) ) {
- if ($this->destFiles == NULL) {
- $this->getDestFiles();
- }
- return $this->destFiles;
- } else {
- if (!file_exists($this->destinationFolder())) {
- return False;
- }
- $files = $this->listFilesFrom($this->destinationFolder(), "", $extension);
- sort($files);
- return $files;
- }
- }
-
- /*!
- \brief Return the first file of each series.
- \return The name of the first file of the series.
- */
- public function condenseSeries( ) {
-
- $this->condenseStkSeries();
- $this->condenseTiffLeica();
-
- return $this->files;
- }
-
-
- /*!
- \brief Checks whether a file belongs to a file series.
- \param $file The file to be checked
- \return Boolean: true or false.
- */
- public function isPartOfFileSeries($file) {
-
- $fileExtension = false;
-
- // Pattern file extension: = \.([^\.\s]+)
- // Pattern lif subimages: = [\s\(\)a-zA-Z0-9]*$
- $pattern = "/\.([^\.\s]+)[\s\(\)a-zA-Z0-9]*$/";
-
- // First find the file extension.
- if (preg_match($pattern,$file,$nameDivisions)) {
- $fileExtension = $nameDivisions[1];
- }
-
- switch ( strtolower($fileExtension) ) {
- case 'stk':
- $pattern = "/[^_]+_(T|t)[0-9]+\.\w+/";
- break;
- case 'tiff':
- $pattern = "/\w+[0-9]+\.\w+/";
- break;
- case 'tif':
- $pattern = "/\w+[0-9]+\.\w+/";
- break;
- default:
- return false;
- }
-
- if (preg_match($pattern, $file, $matches)) {
- return true;
- } else {
- return false;
- }
- }
-
- /*!
- \brief A wrapper function to list files of a certain type
- \param $format Extension to be considered to scan the folder.
- \param $isTimeSeries True for time series, false otherwise.
- \return array of file names
- */
- public function filesOfType( $format, $isTimeSeries ) {
-
- if ($format == "ics") {
- $files = $_SESSION['fileserver']->files("ics");
- } else if ($format == "tiff" || $format == "tiff-single") {
- $files = $_SESSION['fileserver']->tiffFiles();
- } else if ($format == "tiff-series") {
- $files = $_SESSION['fileserver']->tiffSeriesFiles();
- } else if ($format == "tiff-leica") {
- $files = $_SESSION['fileserver']->tiffLeicaFiles();
- } else if ($format == "stk") {
- if ($isTimeSeries == true) {
- $files = $_SESSION['fileserver']->stkSeriesFiles();
- } else {
- $files = $_SESSION['fileserver']->stkFiles();
- }
- } else {
- /* The format has already been set in the class, which very badly
- needs to be refactored. By not passing the format again to this
- function we force to list the subimages as well. */
- $files = $_SESSION['fileserver']->files();
- }
-
- return $files;
- }
-
- /*!
- \brief Scans the image source folder recursively and returns all files
- \return sorted array of file names
- */
- public function allFiles() {
- if (!file_exists($this->sourceFolder())) {
- return False;
- }
- $files = $this->listFilesFrom($this->sourceFolder(), "", "");
- sort($files);
- return $files;
- }
-
- /*!
- \brief Convenience method to get TIFF files
- \return array of TIFF file names
- */
- public function tiffFiles() {
- $this->getFiles();
- $this->trimTiff();
- return $this->files;
- }
-
- /*!
- \brief Convenience method to get numbered TIFF series
- \return array of numbered TIFF file names
- */
- public function tiffSeriesFiles() {
- $this->getFiles();
- // TODO refactor
- $this->trimTiffSeries();
- $this->condenseTimeSeries();
- return $this->files;
- }
-
- /*!
- \brief Convenience method to get TIFF series with Leica style numbering
- \return array of Leica TIFF file names
- */
- public function tiffLeicaFiles() {
- $this->getFiles();
- // TODO refactor
- $this->trimTiffLeica();
- $this->condenseTiffLeica();
- return $this->files;
- }
-
- /*!
- \brief Convenience method to get all STK files (also unprocessed time series)
- \return array of STK files with unprocessed time series
- */
- public function stkFiles() {
- $this->getFiles();
- // TODO refactor
-// $this->trimStkSeries();
- return $this->files;
- }
-
- /*!
- \brief Convenience method to get STK time series files (*_t#.stk)
- \return array of STK time series files
- */
- public function stkSeriesFiles() {
- $this->getFiles();
- // TODO refactor
-// $this->trimStk();
- $this->condenseStkSeries();
- return $this->files;
- }
-
- /*!
- \brief Resets the list of source files. Next time the list is accessed
- it will be recreated automatically
- */
- public function resetFiles() {
- $this->files = NULL;
- }
-
- /*!
- \brief Resets the list of destination files. Next time the list is accessed
- it will be recreated automatically
- */
- public function resetDestFiles() {
- $this->destFiles = NULL;
- }
-
- /*!
- \brief Sets a flag to indicate whether multi-experiment image files should
- be expanded in file lists or not
- \param $bool True if multi-image files should be expanded; false otherwise
- */
- public function expandSubImages($bool) {
- $this->expandSubImages = $bool;
- }
-
- /*!
- \brief Returns the list of selected files that will be added to a job
- \return Array of file names
- */
- public function selectedFiles() {
- if ($this->selectedFiles == NULL) {
- $this->selectedFiles = array();
- }
- return $this->selectedFiles;
- }
-
- /*!
- \brief Add files to current selection if they are not already contained
- \param $files Array of file names to be added
- */
- public function addFilesToSelection($files) {
- foreach ($files as $key => $file) {
- $files[$key] = stripslashes($file);
- }
- $selected = $this->selectedFiles();
- $new = array_diff($files, $selected);
- $this->selectedFiles = array_merge($new, $this->selectedFiles);
- sort($this->selectedFiles);
- }
-
- /*!
- \brief Remove all files from current selection
- */
- public function removeAllFilesFromSelection() {
- $this->selectedFiles = NULL;
- }
-
- /*!
- \brief Remove files from current selection (if they are in)
- \param $files Array of file names to be removed
- */
- public function removeFilesFromSelection($files) {
-
- if (!is_array($files)) {
- return;
- }
-
- foreach ($files as $key => $file) {
- $files[$key] = stripslashes($file);
- }
-
- $this->selectedFiles = array_diff($this->selectedFiles, $files);
- }
-
- /*!
- \brief Builds a regular expression to be able to look for files.
- \brief based on ther job id.
- \return The regular expression.
- \TODO A new design and implementation of the file server is necessary.
- */
- public function getFilePattern($fileName) {
-
- // New naming convention: hrmJobid_hrm.extension
- if (!strstr($fileName, '/')) {
- $pattern = "/^([a-z0-9]{13,13})_hrm\.(.*)$/";
- preg_match($pattern,$fileName,$matches);
-
- if (isset($matches) && !empty($matches)) {
- return "*" . $matches[1] . "_hrm.*";
- }
- } else {
- $pattern = "/(.*)\/([a-z0-9]{13,13})_hrm\.(.*)$/";
- preg_match($pattern,$fileName,$matches);
-
- if (isset($matches) && !empty($matches)) {
- return $matches[1] . "/*" . $matches[2] . "_hrm.*";
- }
- }
-
- // Old naming convention: fileName_hrmJobid_hrm.extension
- if (!strstr($fileName, '/')) {
- $pattern = "/(.*)_(.*)_hrm\.(.*)$/";
- preg_match($pattern,$fileName,$matches);
-
- if (isset($matches) && !empty($matches)) {
- return "*" . $matches[2] . "_hrm.*";
- }
- } else {
- $pattern = "/(.*)\/(.*)_(.*)_hrm\.(.*)$/";
- preg_match($pattern,$fileName,$matches);
-
- if (isset($matches) && !empty($matches)) {
- return $matches[1] . "/*" . $matches[3] . "_hrm.*";
- }
- }
- }
-
- /*!
- \brief Packs a series of files to download.
- \param $files Array List of files to be added.
- */
- public function downloadResults($files) {
- global $compressBin, $compressExt, $dlMimeType, $packExcludePath;
-
- // Make sure that the script doesn't timeout before zipping and
- // reading the file to serve is completed.
- set_time_limit(0);
-
- $date = date("Y-m-d_His");
- $zipfile = "/tmp/download_".session_id().$date.$compressExt;
- $command = str_replace("%DEST%",
- $this->destinationFolder(), $compressBin);
- $command .= " ".$zipfile;
-
- foreach ($files as $file) {
- $filePattern = $this->getFilePattern($file);
- $path = str_replace(" ","\ ",$filePattern);
- $preview_path = dirname($path). "/hrm_previews/". basename($filePattern);
- if (!$packExcludePath) {
- $path = $this->destinationFolder()."/".$path;
- $preview_path = $this->destinationFolder()."/".$preview_path;
- }
- $command .= " ".$path." ".$preview_path;
- }
-
- $answer = exec($command , $output, $result);
-
- $size = filesize($zipfile);
- $type = $dlMimeType;
- $dlname = "hrm_results_$date$compressExt";
-
- if ($size) {
- header ("Accept-Ranges: bytes");
- header ("Connection: close");
- header ("Content-Disposition-type: attachment");
- header ("Content-Disposition: attachment; filename=\"$dlname\"");
- header ("Content-Length: $size");
- header ("Content-Type: $type; name=\"$dlname\"");
- ob_clean();
- flush();
- readfile_chunked($zipfile);
- unlink($zipfile);
- return "
OK
";
- } else {
- $error_msg = "No output from command $command.";
- }
- return "Problems with the packaging of the files:" . " $error_msg";
- }
-
- /*!
- \brief Deletes a list of files and all dependent sub-files (e.g. thumbnails
- and so) from a user directory
- \param $files Array of image file names
- \param $dir Folder to consider, one of 'src' or 'dest'
- \return error message in case files could not be deleted.
- */
- public function deleteFiles($files, $dir = "dest" ) {
-
- if ( $dir == "src" ) {
- $pdir = $this->sourceFolder();
- } else {
- $pdir = $this->destinationFolder();
- }
-
- $success = true;
- $nTotFiles = 0;
- foreach ($files as $file) {
- // Update the file counter
- $nTotFiles++;
-
- // Delete all files name like this one, with all different extensions.
- $dirname = dirname($pdir."/".$file);
- $basename = basename($pdir."/".$file);
-
- if ( $dir == "src") {
- $pattern = "/(\.([^\..]+))*\.([A-Za-z0-9]+)(\s\(.*\))*$/";
- preg_match($pattern, $basename, $matches);
-
- $pattern = "/$matches[0]$/";
- $basename = preg_replace($pattern,"\\1.*", $basename);
-
- $path = $dirname . "/" . $basename;
- $path_preview = $dirname . "/hrm_previews/" . $basename;
- } else {
- $filePattern = $this->getFilePattern($basename);
- $path = $dirname . "/" . $filePattern;
- $path_preview = $dirname . "/hrm_previews/" . $filePattern;
- }
-
- $allFiles = glob($path);
- foreach ($allFiles as $f) {
- $success &= unlink($f);
- }
-
- // Clean also the subdirectory hrm_previews
- $allFiles = glob($path_preview);
- foreach ($allFiles as $f) {
- $success &= unlink($f);
- }
- }
-
- if ( $dir == "src" ) {
- $this->resetFiles();
- } else {
- $this->resetDestFiles();
- }
-
- if ( $success == true ) {
- return "";
- } else {
- if ( $nTotFiles > 1 ) {
- return "One or more files could not be deleted!";
- } else {
- return "Could not delete selected file!";
- }
- }
- }
-
- /*!
- \brief Exports a deconvolved image to the OMERO server.
- */
- public function exportToOmero() {
-
- if (!isset($_SESSION['omeroConnection'])) {
- return "Your OMERO connection was interrupted, please try again!";
- }
- // file_put_contents('/tmp/hrm_post.log', var_export($_POST, true));
-
- if (!isset($_POST['selectedFiles'])) {
- return "Please select a deconvolved image to export to OMERO.";
- }
-
- if (!isset($_POST['OmeDatasetId'])
- || empty($_POST['OmeDatasetId'])) {
- return "Please select a destination dataset
- within the OMERO data tree.";
- }
-
- $omeroConnection = $_SESSION['omeroConnection'];
-
- return $omeroConnection->uploadToOMERO($_POST, $this);
- }
-
- /*!
- \brief Imports a raw image from the OMERO server.
- */
- public function importFromOmero() {
-
- if (!isset($_SESSION['omeroConnection'])) {
- return "Your OMERO connection was interrupted, please try again!";
- }
- // file_put_contents('/tmp/hrm_post.log', var_export($_POST, true));
-
- if (!isset($_POST['OmeImages'])
- || empty($_POST['OmeImages'])) {
- return "Please select an image within the OMERO data tree.";
- }
-
- $omeroConnection = $_SESSION['omeroConnection'];
-
- return $omeroConnection->downloadFromOMERO($_POST['OmeImages'], $this);
- }
-
- /*!
- \brief Extracts files from compressed archives
- \param $file Archive name
- \param $type Archive type (zip, tar, tgz...)
- \param $dest Destination path
- \param $okMsg A string to accumulate OK messages
- \param $errMsg A string to accumulate error messages
- \param $subdir An optional subdirectory under $dest to expand the
- files to
- \param $imagesOnly Boolean Apply a filter to delete non-image files after
- extraction
- */
- public function decompressArchive( $file, $type, $dest, &$okMsg, &$errMsg,
- $subdir = "", $imagesOnly = true ) {
-
- global $decompressBin;
-
- if ( $imagesOnly && $subdir == "" ) {
- $errMsg .= "Can't decompress: filtering valid images requires ".
- "expanding the archive to a subdirectory.";
- return;
- }
-
- if ($subdir != "" ) {
- $dest = $dest."/".$subdir;
- @mkdir($dest, 0777);
- }
-
- $command = str_replace("%DEST%", "\"" . $dest . "\"", $decompressBin[$type]).
- " \"$file\"";
-
- $answer = exec($command , $output, $result);
-
- # $okMsg .= "$type $command: $result";
- # foreach ($output as $line) {
- # $okMsg .= "\n $line";
- # }
-
- if ($imagesOnly) {
- $deleted = "";
- $valid = "";
- $this->cleanNonImages($dest, "", $valid, $deleted);
- if ($deleted != "") {
- $errMsg .= " \nThe following files, not being valid images,".
- " were discarded: $deleted";
- }
- if ($valid != "") {
- $okMsg .= " \nThe following images were extracted: ".
- "$valid \n";
- }
- }
-
- return;
-
-
- }
-
- /*!
- \brief Processes the $_FILES array posted when uploading files, moving
- valid one to the specified directory. Compressed files are
- decompressed
- \param $files Array of files to be uploaded.
- \param $dir Destination path, one of 'src' or 'dest'
- \return message with details.
- \see See PHP documentation: POST method uploads
- */
- public function uploadFiles($files, $dir) {
-
- if ( $dir == "src" ) {
- $uploadDir = $this->sourceFolder();
- } else {
- $uploadDir = $this->destinationFolder();
- }
-
- $max = getMaxFileSize() / 1024 / 1024;
- $maxFile = "$max MB";
-
- $ok = "";
- $err = "";
- $okCnt = 0;
-
-
- // This needs some file type validation: only images should be allowed.
- try {
-
- foreach ($files['name'] as $i => $name) {
-
- if ( $name == "" ) {
- // This is also error UPLOAD_ERR_NO_FILE;
- continue;
- }
- $baseName = basename($name);
- $baseName = str_replace(" ","_",$baseName);
- $uploadFile = $uploadDir . "/" . $baseName;
- $bareName = reset(explode('.',$baseName));
- $extension = str_replace($bareName,"",$baseName);
-
- // If the php.ini upload variables are overriden in the HRM
- // config files, PHP does not rise this error.
- if (($files['size'][$i] / 1024 / 1024) > $max) {
- $files['error'][$i] = UPLOAD_ERR_INI_SIZE;
- }
-
- if ($files['error'][$i]) {
- $err .= "Invalid file ".$baseName.": ";
- switch ($files['error'][$i]) {
- case UPLOAD_ERR_INI_SIZE:
- $err .= "larger than $maxFile.";
- break;
- case UPLOAD_ERR_PARTIAL:
- $err .= "file loaded only partially.";
- break;
- case UPLOAD_ERR_NO_TMP_DIR:
- $err .= "missing a temporary folder.";
- break;
- case UPLOAD_ERR_CANT_WRITE:
- $err .= "can't write to disk.";
- break;
- case UPLOAD_ERR_EXTENSION:
- $err .= "upload stopped by extension.";
- break;
-
- }
- $err .=" \n";
- continue;
- }
-
- $type = $this->getCompressedArchiveType($name);
-
- if ( $type != "" ) {
- # If this is a compressed archive, extract its files.
- $subDir = $baseName;
- $zSuffix = 0;
- $zMaxSuffix = 100;
-
- $testExpand = $uploadDir . "/" . $subDir;
-
- while (file_exists($testExpand)) {
- $zSuffix ++;
- $testExpand = $uploadDir . "/" . $bareName .
- "_$zSuffix" . $extension;
- if ($zSuffix > $zMaxSuffix) {
- $err .= "Directory ".$bareName.
- " exists, can't store more ".
- " than $zMaxSuffix versions. \n";
- break;
- }
- }
- if ($zSuffix > $zMaxSuffix) {
- continue;
- }
-
- $okCnt++;
- $ok .= " Processed ".$baseName.". \n";
-
- if ($zSuffix > 0) {
- $subDir = $baseName."_".$zSuffix;
- $ok .= "Extracting files to $subDir. \n";
- }
- $this->decompressArchive($files['tmp_name'][$i], $type,
- $uploadDir, $ok, $err, $subDir, true);
- continue;
-
- }
-
- if (!$this->isValidImage($name, true)) {
- $err .= "Skipped ". $baseName .": ";
- $err .= "unknown image type \n";
- continue;
-
- }
-
- $suffix = 0;
- $maxSuffix = 20;
-
- while (file_exists($uploadFile)) {
- $suffix ++;
- $uploadFile = $uploadDir . "/" . $bareName .
- "_$suffix" . $extension;
- if ($suffix > $maxSuffix) {
- $err .= "File ".$baseName.
- " exists, can't store more than " .
- "$maxSuffix versions.";
- break;
- }
- }
- if ($suffix > $maxSuffix) {
- continue;
- }
-
- if (move_uploaded_file($files['tmp_name'][$i], $uploadFile)) {
- // echo "File is valid, and was successfully uploaded.\n";
- if ($suffix == 0) {
- $ok .= "". $baseName ." uploaded \n";
- } else {
- $ok .= "". $baseName .
- " already exists, uploaded and renamed ".
- "to $bareName" .
- "_$suffix" . $extension . " \n";
- }
- $okCnt++;
- } else {
- $err .= "File ".$baseName." could not be written to its ".
- "final destination. Please make sure that " .
- "directory permissions are correctly set! \n";
- }
- }
- } catch (Exception $e) {
- $err .= "Error uploading files: ".$e->getMessage();
- }
-
- $msg = "
";
- }
-
- if ( $dir == "src" ) {
- $this->resetFiles();
- } else {
- $this->resetDestFiles();
- }
-
- return $msg;
-
- }
-
- /*!
- \brief Returns a list of file extensions for supported images
- \return array of file extensions
- */
- public function imageExtensions() {
- if ($this->imageExtensions == NULL) {
- $this->setDefaultImageExtensions();
- }
- return $this->imageExtensions;
- }
-
- /*!
- \brief Sets the list of image extensions. Files with these extensions
- under the user's source folder will be shown under available
- images. Whenever the image extensions are changed, the files and
- the selected files will be reset. Only exception is when the list
- of image extensions is replaced by itself
- \param $extensions Array of file extensions (strings)
- */
- public function setImageExtensions($extensions) {
- if (implode('', $extensions) != implode('', $this->imageExtensions())) {
- $this->selectedFiles = NULL;
- $this->files = NULL;
- }
- $this->imageExtensions = $extensions;
- }
-
- /*!
- \brief Sets the image extensions from the list of valid image extensions
- */
- public function setDefaultImageExtensions() {
- // new file formats support
- $this->imageExtensions = $this->validImageExtensions;
- }
-
- /*!
- \brief Checks whether the filename extension matches the currently
- selected file format
- \param $filename Filename to be checked
- \return true if the file extension matches the file format, false otherwise
- */
- public function isImage($filename) {
- $ext = $this->getFileNameExtension($filename);
- $ext = strtolower($ext);
- $result = False;
- if (in_array($ext, $this->imageExtensions())) {
- $result = True;
- }
- return $result;
- }
-
- /*!
- \brief Checks whether the file name is of a valid type
- \param $filename The filename to be checked
- \param $alsoExtras: if true, consider also extensions as ids or ids.gz
- \return true if the filename is of a valid type, false otherwise
- */
- public function isValidImage($filename, $alsoExtras = false) {
- $filename = strtolower($filename);
- $ext = $this->getFileNameExtension($filename);
- if ( $ext === "gz" ) {
- // Use two suffixes as extension
- $filename = basename($filename, ".gz");
- $ext = $this->getFileNameExtension($filename) . ".gz";
- }
- $result = False;
- if (in_array($ext, $this->validImageExtensions)) {
- $result = True;
- }
- if ($alsoExtras && (in_array($ext, $this->validImageExtensionsExtras)) ) {
- $result = True;
- }
- return $result;
- }
-
- /*!
- \brief Returns the archive type of a filename, if it is a valid known
- compressed archive.
- \param $filename The filename to be checked
- \return the archive type if the filename is valid archive, "" otherwise
- */
- public function getCompressedArchiveType($filename ) {
-
- if (stristr($filename, ".tar.gz")) {
- // This double extension is a special case.
- return "tar.gz";
- }
- $ext = $this->getFileNameExtension($filename);
- $ext = strtolower($ext);
- $result = "";
- if (in_array($ext, $this->validArchiveExtensions)) {
- $result = $ext;
- }
- return $result;
- }
-
- /*!
- \brief Returns all archive types as string
- \return string containing all archive types
- */
- public function getValidArchiveTypesAsString() {
- $ret = ""; $sep = "";
- foreach ($this->validArchiveExtensions as $ext) {
- $ret .= $sep.".$ext";
- $sep = " ";
- }
- return $ret;
- }
-
- /*!
- \brief When the selected file type is one that can contain subimages
- (like LIF), the already built list of $this->files is extended to
- show all the available subimages. This is done by querying HuCore.
- \param $files Array of file names that have to be inspected for sub-files
- \return updated array of file names with sub-files
- */
- public function getSubImages($files) {
-
- $i = 0;
- $imgList = "";
- foreach ($files as $path) {
- $imgList .= " -img_$i \"$path\"";
- $i ++;
- }
-
- $opt = "-count $i $imgList -dir \"". $this->sourceFolder() ."\"";
-
- $answer = huCoreTools( "reportSubImages", $opt);
-
- if (! $answer ) return;
-
- $lines = count($answer);
-
- $tree = array();
- $new_files = array();
- $cur = NULL;
-
- for ($i = 0; $i < $lines; $i++ ) {
- $key = $answer[$i];
-
- switch ($key) {
- case "BEGIN IMG":
- $i ++;
- $cur = $answer[$i];
- break;
- case "ERROR":
- $i ++;
- echo($answer[$i]);
- case "END IMG":
- $cur = NULL;
- break;
- case "PATH":
- if ($cur) {
- $i ++;
- $tree[$cur]['path'] = $answer[$i];
- }
- break;
- case "COUNT":
- if ($cur) {
- $i ++;
- $tree[$cur]['count'] = $answer[$i];
- }
- break;
- case "TYPE":
- if ($cur) {
- $i ++;
- $tree[$cur]['type'] = $answer[$i];
- }
- break;
- case "SUBIMG":
- if ($cur) {
- $i ++;
- $tree[$cur]['subimg'][] = $answer[$i];
- $new_files[] = $cur ." (". $answer[$i] .")";
- }
- break;
-
- }
- }
-
- return $new_files;
- }
-
- /*!
- \brief Some files like ICS can report their metadata without having to
- open the whole image, which is good e.g. to see the compatibility
- of the selected PSF with the current Parameter Setting.
- This is done by querying HuCore.
- \param $files Array of file paths (relative to the source folder).
- \return N-dimensional array of metadata per file
- */
- public function getMetaDataFromFiles(array $files) {
-
- $i = 0;
- $imgList = "";
-
- foreach ($files as $path) {
- $imgList .= " -img_$i \"$path\"";
- $i ++;
- }
-
- $opt = "-count $i $imgList -dir \"". $this->sourceFolder() ."\"";
- $answer = huCoreTools( "getMetaData", $opt);
- if (! $answer ) return;
-
- $lines = count($answer);
-
- $tree = array();
- $new_files = array();
- $cur = NULL;
- $param = NULL;
-
- for ($i = 0; $i < $lines; $i++ ) {
- $key = $answer[$i];
-
- switch ($key) {
- case "BEGIN IMG":
- $i ++;
- $cur = $answer[$i];
- break;
- case "ERROR":
- $i ++;
- echo($answer[$i]);
- case "END IMG":
- $cur = NULL;
- $param = NULL;
- $len = 1;
- break;
- case "PATH":
- if ($cur) {
- $i ++;
- $tree[$cur]['path'] = $answer[$i];
- }
- break;
- case "LENGTH":
- if ($cur) {
- $i ++;
- $len = $answer[$i];
- }
- break;
- case "DATA":
- if ($cur) {
- $i ++;
- $param= $answer[$i];
- $tree[$cur]['parameters'][] = $param;
- }
- break;
- case "VALUE":
- if ($cur && $param) {
- $i ++;
- // This is always an array even if $len == 1, because in
- // other images this could be a multichannel parameter.
- $tree[$cur][$param][] = $answer[$i];
- }
- break;
-
- }
- }
-
- return $tree;
-
- }
-
- /*!
- \brief Some files like ICS can report their metadata without having to
- open the whole image, which is good e.g. to see the compatibility
- of the selected PSF with the current Parameter Setting.
- This is done by querying HuCore.
- \param $type File type, default is "ics"
- \param $file This can be a file name for the file to be inspected, or
- "all" to inspect all the files of type $type that are in the source
- folder
- \return N-dimensional array of metadata per file
- */
- public function getMetaData( $type = "ics", $file = "all" ) {
-
- $i = 0;
- $imgList = "";
-
- if ( $file == "all" ) {
- $files = $this->files($type);
- } else {
- $files[] = $file;
- }
-
- foreach ($files as $path) {
- $imgList .= " -img_$i \"$path\"";
- $i ++;
- }
-
- $opt = "-count $i $imgList -dir \"". $this->sourceFolder() ."\"";
- $answer = huCoreTools( "getMetaData", $opt);
- if (! $answer ) return;
-
- $lines = count($answer);
-
- $tree = array();
- $new_files = array();
- $cur = NULL;
- $param = NULL;
-
- for ($i = 0; $i < $lines; $i++ ) {
- $key = $answer[$i];
-
- switch ($key) {
- case "BEGIN IMG":
- $i ++;
- $cur = $answer[$i];
- break;
- case "ERROR":
- $i ++;
- echo($answer[$i]);
- case "END IMG":
- $cur = NULL;
- $param = NULL;
- $len = 1;
- break;
- case "PATH":
- if ($cur) {
- $i ++;
- $tree[$cur]['path'] = $answer[$i];
- }
- break;
- case "LENGTH":
- if ($cur) {
- $i ++;
- $len = $answer[$i];
- }
- break;
- case "DATA":
- if ($cur) {
- $i ++;
- $param= $answer[$i];
- $tree[$cur]['parameters'][] = $param;
- }
- break;
- case "VALUE":
- if ($cur && $param) {
- $i ++;
- // This is always an array even if $len == 1, because in
- // other images this could be a multichannel parameter.
- $tree[$cur][$param][] = $answer[$i];
- }
- break;
-
- }
- }
-
- return $tree;
-
- }
-
- /*!
- \brief Generates a html line for a form listing images in the server
- \param $file Image file name
- \param $index (Unused) Index in the file name array
- \param $dir (Unused) Destination directory, one of 'src', or 'dst'
- \param $type (Unused) Type of the image, e.g. 'preview'
- \param $ref (Unused) Default is 0
- \param $data (Unused) Default = 1
- \return the html code for the form
- \todo Check why this function taks 6 parameters and uses only one.
- */
- public function getImageOptionLine ($file, $index, $dir, $type, $ref = 0, $data = 1) {
- $path = explode("/", $file);
- if (count($path) > 2)
- $filename = $path[0] . "/.../" . $path[count($path) - 1];
- else
- $filename = $file;
-
- // Consecutive spaces are collapsed into one space in HTML.
- // Hence ' ' to correct this when the file has more spaces.
- $filename = str_replace(' ',' ',$filename);
-
- return
- " \n";
- }
-
- /*!
- \brief Generates a javascript command to show an image preview.
- \param $file Image file name
- \param $index (Unused) Index in the file name array
- \param $dir (Unused) Destination directory, one of 'src', or 'dst'
- \param $type (Unused) Type of the image, e.g. 'preview'
- \param $ref (Unused) Default is 0
- \param $data (Unused) Default = 1
- \return the javascript code.
- \todo Check why this function taks 6 parameters and uses only one.
- */
- public function getImageAction ($file, $index, $dir, $type, $ref = 0, $data = 1) {
- global $useThumbnails;
- global $genThumbnails;
-
- $path = explode("/", $file);
- if (count($path) > 2)
- $filename = $path[0] . "/.../" . $path[count($path) - 1];
- else
- $filename = $file;
-
-
- $mode = $this->imgPreviewMode($file, $dir, $type) ;
- if ( $ref ) {
- $referer = "?ref=". $_SESSION['referer'];
- } else {
- $referer = "";
- }
-
- // The first comparison mode is the 400x400 pixels preview.
- $compare = $this->imgCompareMode($file, $dir, "400") ;
- if ($compare > 0) { $compare = 400; }
-
- return
- "imgPrev('".rawurlencode($file)."', $mode, ".
- "$genThumbnails, $compare, $index, '$dir', ".
- "'$referer', $data)";
- }
-
- /*!
- \brief Generates a link to retrieve an image thumbnail, which is a jpg
- file saved near the file itself.
- \param $image Image file name
- \param $dir Destination directory, one of 'src' or 'dst'
- \param $type Type of thumbnail, one of 'preview_xy', 'preview_xz',
- 'preview_yz'; default is 'preview_xy'
- \param $escape if true, the code is escaped to be used in Javascript code
- \return an link to securely get the thumbnail.
- */
- public function imgPreview ($image, $dir, $type = "preview_xy", $escape = true ) {
- global $genThumbnails;
-
- if ( $dir == "src" ) {
- $pdir = $this->sourceFolder();
- } else {
- $pdir = $this->destinationFolder();
- }
-
- $dirname = dirname($pdir."/".$image);
- $base = basename($pdir."/".$image);
-
- /* Huygens does not support ":" in names of saved files. */
- $base = str_replace(":", "_", $base);
- $image = str_replace(":", "_", $image);
-
- // The thumbnail is saved in a subdirectory along with the image, and it
- // has a suffix indicating the thumbnail type plus the jpg extension.
- $path = $dirname."/hrm_previews/".$base.".".$type.".jpg";
- $thumb = rawurlencode(stripslashes($image).".".$type.".jpg");
- if (file_exists(stripslashes($path))) {
- $ret = "";
- } else {
- $imgsrc = "";
- // $ret = "
No preview available.
";
- $ret = "$imgsrc No preview available";
- }
-
- if ($escape) {
- return escapeJavaScript($ret);
- } else {
- return $ret;
- }
- }
-
- /*!
- \brief Shows stacks and time series saved as jpeg strips in a css container.
- Inspired by the paperbird code by Rom�n Cort�s:
- \param $file Image file name
- \param $type Type of the strip, one of 'stack.compare', 'tSeries.compare',
- 'preview_yz'; default is 'stack.compare'
- \param $dir Destination directory, one of 'src' or 'dest', default is 'dest'
- \param $frame True to draw a frame, false otherwise
- \param $margin Thickness of the margin around th strip, default is 25
- \return html code to be output to the page
- \see http://www.romancortes.com/blog/css-paper-bird/
- */
- public function viewStrip( $file, $type = "stack.compare", $dir = "dest", $frame = false, $margin = 25 ) {
- global $allowHttpTransfer;
-
- $fileinfo = pathinfo($file);
- $files = $this->findStrip($file, $type, $dir);
-
- if (count($files) != 1 ) {
- echo "";
- return;
- }
- preg_match ("/strip_(.+)x(.+)x(.+)_fr/", $files[0], $match);
-
- $thumb = $fileinfo['dirname']."/" .strstr($files[0],$fileinfo['filename']);
-
- $sx = $match[1];
- $sy = $match[2];
- $width = $sx + $margin * 2;
- $height = $sy + $margin * 2;
- $jump = $height * 400;
- $fCnt = $match[3];
-
- if ( $frame ) {
- // Use this function in two steps: first to create the iframe with
- // the correct width and height, using a link that calls this
- // function again to generate the embedded slicer page.
- echo ' ';
- return;
- }
-
- $borderColor = "#666";
- $textColor = "#bbb";
-
- $img = "file_management.php?getThumbnail=$thumb&dir=$dir";
-
- $file = stripslashes($file);
-
- # $legend = $type. " ". $file;
- $legend = $type;
- if (strlen($legend) > 75) {
- $legend = substr($legend, 0, 70)."...";
- }
-
- echo '
-
-
-
-
- ' . $file . " ". $type. '
-
-
-
-
';
- for ($n = 0; $n < $fCnt; $n++) {
- echo "
";
- echo "
";
- }
-
- echo "
";
- echo "
$legend
";
-
-echo '';
-
-
- }
-
- /*!
- \brief Creates the preview page for the file browser
- \param $file Image file name
- \param $op Operation, one of 'close' or 'home'. Default is "close"
- \param $mode Display mode. One of "MIP", "parameters", "log", "SFP", "stack", "tSeries",
- "history", "remarks". Default is "MIP"
- \param $size Size of the thumbnail. Default is 400
- \return HTML code (whole page)
- */
- public function previewPage ($file , $op = "close", $mode = "MIP", $size = 400) {
- global $allowHttpTransfer;
-
-
- $file = stripslashes($file);
-
- /* All job previews share a common root name and relative path. */
- $this->previewBase = $file;
-
- echo '';
-
- echo '
-
-
-
- HRM - ' . $file . ' - results preview';
- $ico = 'images/hrm_custom.ico';
- if (!file_exists($ico)) {
- $ico = 'images/hrm.ico';
- }
- echo ' ';
- echo '
-
-
-
-
- ';
-
- $custom_css = "css/custom.css";
- if (file_exists($custom_css)) {
- echo ' ' . "\n";
- }
-
-
- echo '
-
-
-
HRM image preview
-
'.$file.'
-
-
';
-
- $pdest = $this->destinationFolder();
- $filePattern = $this->getFilePattern($file);
-
- if (!glob($pdest . "/" . $filePattern)) {
- echo " ";
- echo "Sorry, file $file does not exist any more on the server. ";
- echo " ";
- echo "";
- echo "";
- exit;
- }
-
- $dir = dirname($pdest."/".$file);
- $base = basename($pdest."/".$file);
-
- /* The root name involving the path as well. */
- $prevBase = $dir."/hrm_previews/".$base;
-
- $fileBase = $dir."/".$base;
- $path_info = pathinfo($fileBase);
- $fileBase = $dir."/".$path_info['filename'];
-
- // (Sorted) available views
- //
- // If the file(s) corresponding to a view is missing, no entry will be
- // added to the navigation menu
-
- // MIP comparison
- $path = array();
- $test = $prevBase.".".$size."_xy.jpg";
- if (file_exists($test)) {
- $path['MIP'] = $test;
- }
-
- // This is the text file with the parameter summary (useful to check the
- // runtime parameters that were used if the template was incomplete)
- $filePattern = $this->getFilePattern(basename($file));
- $filePattern = str_replace(".*",".parameters.*",$filePattern);
-
- $paramFile = glob($dir . "/" . $filePattern);
- if (isset($paramFile) && !empty($paramFile)) {
- $path['parameters'] = $paramFile[0];
- }
-
- // Log file (this is the same as the email that is sent to the user)
- $filePattern = $this->getFilePattern(basename($file));
- $filePattern = str_replace(".*",".log.*",$filePattern);
-
- $logFile = glob($dir . "/" . $filePattern);
- if (isset($logFile) && !empty($logFile)) {
- $path['log'] = $logFile[0];
- }
-
- // SFP comparison
- $test = $prevBase.".sfp.jpg";
- if (file_exists($test)) {
- $path['SFP'] = $test;
- }
-
- // Slicer comparison
- $test = $this->findStrip($file, "stack.compare", $pdest);
- if (count($test) == 1) {
- $path['stack'] = $test[0];
- }
- $test = $this->findStrip($file, "tSeries.compare", $pdest);
- if (count($test) == 1) {
- $path['tSeries'] = $test[0];
- }
-
- // Download movie
- $test = $prevBase.".stack.avi";
- if (file_exists($test)) {
- $path['stackMovie'] = $test;
- $movie['stackMovie'] = $file.".stack.avi";
- $msize['stackMovie'] = round(filesize($test) / 1024.0);
- }
- $test = $pdest."/hrm_previews/".$file.".tSeries.avi";
- if (file_exists($test)) {
- $path['tSeriesMovie'] = $test;
- $movie['tSeriesMovie'] = $file.".tSeries.avi";
- $msize['tSeriesMovie'] = round(filesize($test) / 1024.0);
- }
- $test = $pdest."/hrm_previews/".$file.".tSeries.sfp.avi";
- if (file_exists($test)) {
- $path['tSeriesSfpMovie'] = $test;
- $movie['tSeriesSfpMovie'] = $file.".tSeries.sfp.avi";
- $msize['tSeriesSfpMovie'] = round(filesize($test) / 1024.0);
- }
-
- // Colocalization results
- $filePattern = $this->getFilePattern(basename($file));
- $filePattern = str_replace(".*",".coloc.*",$filePattern);
-
- $colocFile = glob($dir . "/" . $filePattern);
- if (isset($colocFile) && !empty($colocFile)) {
- $path['colocalization'] = $colocFile[0];
- }
-
- // Remarks file
- $test = $pdest."/".$file.".remarks.txt";
- if (file_exists($test)) {
- $path['remarks'] = $test;
- }
-
- // Old history filename didn't contain image type extension.
- $test = $fileBase.".history.txt";
- if (file_exists($test)) {
- $path['history'] = $test;
- }
-
- // New filename for history includes the file destination extension.
- $test = $pdest."/".$file.".history.txt";
- if (file_exists($test)) {
- $path['history'] = $test;
- }
-
- // Define some arrays
- $desc = array( 'MIP' => "MIP",
- 'parameters' => "parameters",
- 'log' => "log",
- 'SFP' => "SFP",
- 'stack' => "slicer",
- 'tSeries' => "series",
- 'stackMovie' => "stack movie",
- 'tSeriesMovie' => "series movie",
- 'tSeriesSfpMovie' => "series SFP movie",
- 'colocalization' => "colocalization",
- 'history' => "history",
- 'remarks' => "remarks" );
-
- $tip = array( 'MIP' => "Compare Maximum Intensity Projections",
- 'parameters' => "List the image parameters used (useful to check the runtime parameters that were used if the template was incomplete)",
- 'log' => "See the image restoration log file",
- 'SFP' => "Compare Simulated Fluorescence renderings",
- 'stack' => "Browse along the Z-planes (this could take several seconds)",
- 'tSeries' => "Browse along the time series (this could take several seconds)",
- 'stackMovie' => "Download Z-stack movie",
- 'tSeriesMovie' => "Download time series MIP movie",
- 'tSeriesSfpMovie' => "Download time series SFP movie" ,
- 'colocalization' => "See colocalization results",
- 'history' => "See the image restoration history, the executed Huygens - Tcl commands.",
- 'remarks' => "See the image restoration warnings." );
-
- // Refine some $tips
- if ( isset( $msize['stackMovie'] ) ) {
- $tip['stackMovie'] = "Download Z-stack movie (".$msize['stackMovie']." kB)";
- }
- if ( isset( $msize['tSeriesMovie'] ) ) {
- $tip['tSeriesMovie'] = "Download time series MIP movie (".$msize['tSeriesMovie']." kB)";
- }
- if ( isset( $msize['tSeriesSfpMovie'] ) ) {
- $tip['tSeriesSfpMovie'] = "Download time series SFP movie (".$msize['tSeriesSfpMovie']." kB)";
- }
-
- $link = "file_management.php?compareResult=".rawurlencode($file).
- "&op=$op&mode=";
- $mlink = "file_management.php?getMovie=";
-
- echo "
";
-
- /* There exists a pre-formatted colocalization page created by the
- Queue Manager. That html code cannot just be echo'ed, several
- variables must be inserted before. */
- echo $this->displayColocalization($path["colocalization"]);
- print "
";
- } else {
-
- echo "
\n";
- echo "\n
\n
\n";
-
- echo "
Original
Restored
\n
\n
";
-
- $othumb_0 = rawurlencode($file.".original.".$size."_xy.jpg");
- $rthumb_0 = rawurlencode($file.".".$size."_xy.jpg");
-
- $osfp = rawurlencode($file.".original.sfp.jpg");
- $rsfp = rawurlencode($file.".sfp.jpg");
-
- // YZ slices not shown by now, but here they are:
- $othumb_2 = rawurlencode($file.".original.".$size."_xy.jpg");
- $rthumb_2 = rawurlencode($file.".".$size."_xy.jpg");
-
- if ( $mode == "MIP" ) {
-
- echo "\n
";
-
- echo "\n
";
- } else {
- echo "\n
";
-
- echo "\n
";
- }
-
- echo "\n
";
-
- $othumb_1 = rawurlencode($file.".original.".$size."_xz.jpg");
- $rthumb_1 = $file.".".$size."_xz.jpg";
- $path = $pdest."/hrm_previews/".$rthumb_1;
- $path = stripslashes($path);
- $rthumb_1 = rawurlencode($rthumb_1);
- if ($mode == "MIP" && file_exists($path)) {
- // is a 3D image, so it has a lateral view.
- echo "\n
";
- echo "\n
";
- echo "\n
";
-
- echo "\n
";
- }
-
- echo "\n
\n\n";
-
- }
- echo "
\n";
- echo "";
- echo "
\n";
- include("footer.inc.php");
-
- }
-
- /*!
- \brief Shows original/result previews side by side.
- \param $file Image file name
- \param $size Size of the thumbnail. Default is 400
- \param $op Operation, one of 'close' or 'home'. Default is "close"
- \param $mode Display mode. One of "MIP, "SFP", "stack", "tSeries", "log",
- "history", "remarks". Default is "MIP"
- \return HTML code (whole page)
- */
- public function compareResult( $file, $size = "400", $op = "close", $mode="MIP" ) {
- global $allowHttpTransfer;
-
- $file = stripslashes($file);
-
- $excludeTitle = true;
- include("header.inc.php");
-
- if ( $mode == "MIP" ) {
- $altMode = "SFP";
- } else {
- $altMod = "MIP";
- }
-
- echo "
";
-
- echo "\n\n
Image comparison ($mode)
\n";
-
- $pdest = $this->destinationFolder();
- $filePattern = $this->getFilePattern($file);
-
- if (!glob($pdest . "/" . $filePattern)) {
- echo " ";
- echo "Sorry, file $file does not exist any more on the server. ";
- echo " ";
- echo "";
- echo "";
- exit;
- }
-
- echo "\n
\n
\n";
-
- echo "
Original
Restored
\n
\n
";
-
- $othumb_0 = rawurlencode($file.".original.".$size."_xy.jpg");
- $rthumb_0 = rawurlencode($file.".".$size."_xy.jpg");
-
- $osfp = rawurlencode($file.".original.sfp.jpg");
- $rsfp = rawurlencode($file.".sfp.jpg");
-
- if ( $mode == "MIP" ) {
- $altPath = $pdest."/hrm_previews/".$file.".sfp.jpg";
- } else {
- $altPath = $pdest."/hrm_previews/".$file.".".$size."_xy.jpg";
- }
-
- $altPath = stripslashes($altPath);
- // YZ slices not shown by now, but here they are:
- $othumb_2 = rawurlencode($file.".original.".$size."_xy.jpg");
- $rthumb_2 = rawurlencode($file.".".$size."_xy.jpg");
-
- if ( $mode == "MIP" ) {
-
- echo "\n
";
-
- echo "\n
";
- } else {
- echo "\n
";
-
- echo "\n
";
-
- }
-
- echo "\n
";
-
-
- $othumb_1 = rawurlencode($file.".original.".$size."_xz.jpg");
- $rthumb_1 = $file.".".$size."_xz.jpg";
- $path = $pdest."/hrm_previews/".$rthumb_1;
- $path = stripslashes($path);
- $rthumb_1 = rawurlencode($rthumb_1);
- if ($mode == "MIP" && file_exists($path)) {
- // is a 3D image, so it has a lateral view.
- echo "\n