Skip to content

Commit 4a10c81

Browse files
ndg63276gfrnMark Williams
authored
Merge pre-release/2025-R1.1 into master (#899)
* LIMS-1540 - Remove references to summary pages/DB (#860) * LIMS-1564 - Remove unused dependencies (#868) * LIMS-1066: Autofill UDC visit on dispatch form (#881) * LIMS-1528: Fix sorting on old summary page (#883) * LIMS-1554: Add 'State' column to proposals list page (#865) --------- Co-authored-by: Guilherme Francisco <guilherme.de-freitas@diamond.ac.uk> Co-authored-by: Mark Williams <mark.williams@diamond.ac.uk>
1 parent 3684b32 commit 4a10c81

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+443
-22743
lines changed

api/config_sample.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@
1313
$isb = array('user' => 'user', 'pass' => 'pass', 'db' => 'localhost/ispyb');
1414
$dbtype = 'mysql';
1515

16-
# Summary Database credentials
17-
######### DELETE if not using connection.
18-
$summarydbconfig = array('user' => 'user', 'pass' => 'pass', 'db' => 'localhost/ispyb');
19-
$ifsummary = true;
20-
2116
# Encoded JWT key, used to sign and check validaty of jwt tokens
2217
# - Create one of these using /api/authenticate/key
2318
# This can be changed to invalidate all currently active tokens
@@ -302,6 +297,8 @@
302297
# Beamlines on which to scale the gridplot to 1024
303298
$scale_grid = array('i24');
304299

300+
# URL for instructions for closed proposals
301+
$closed_proposal_link = '';
305302

306303
# These map proposal types to their proposalcode
307304
# - If these are not defined for a proposal type, the api then uses bl_types below

api/index.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ function setupApplication($mode): Slim
7070
global $motd, $authentication_type, $cas_url, $cas_sso, $sso_url, $package_description,
7171
$facility_courier_countries, $facility_courier_countries_nde, $facility_courier_countries_link,
7272
$dhl_enable, $scale_grid, $scale_grid_end_date, $preset_proposal, $timezone,
73-
$valid_components, $enabled_container_types, $ifsummary, $synchweb_version, $redirects,
73+
$valid_components, $enabled_container_types, $synchweb_version, $redirects,
7474
$shipping_service_app_url, $use_shipping_service_redirect, $use_shipping_service_redirect_incoming_shipments,
75-
$dials_rest_url_rings;
75+
$dials_rest_url_rings, $closed_proposal_link;
7676
$app->contentType('application/json');
7777
$options = $app->container['options'];
7878
$app->response()->body(json_encode(array(
@@ -92,10 +92,10 @@ function setupApplication($mode): Slim
9292
'timezone' => $timezone,
9393
'valid_components' => $valid_components,
9494
'enabled_container_types' => $enabled_container_types,
95-
'ifsummary' => $ifsummary,
9695
'synchweb_version' => $synchweb_version,
9796
'shipping_service_app_url' => $use_shipping_service_redirect || $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null,
9897
'shipping_service_app_url_incoming' => $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null,
98+
'closed_proposal_link' => $closed_proposal_link,
9999
'dials_rest_url_rings' => $dials_rest_url_rings,
100100
'redirects' => $redirects
101101
)));
@@ -112,13 +112,6 @@ function setupDependencyInjectionContainer($app)
112112
return $db;
113113
});
114114

115-
$app->container->singleton('dbsummary', function () use ($app): DatabaseParent {
116-
$dbFactory = new DatabaseFactory(new DatabaseConnectionFactory());
117-
$db = $dbFactory->get("summary");
118-
$db->set_app($app);
119-
return $db;
120-
});
121-
122115
$app->container->singleton('authData', function () use ($app) {
123116
return new AuthenticationData($app->container['db']);
124117
});

api/src/Database/DatabaseConnectionFactory.php

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class DatabaseConnectionFactory
99
public function get($databaseType)
1010
{
1111
global $isb;
12-
global $summarydbconfig;
1312

1413
if (!$databaseType) {
1514
error_log('Database type variable, dbtype, is not specified in config.php - defaulting to MySql.');
@@ -25,16 +24,6 @@ public function get($databaseType)
2524
$conn = new \mysqli($host, $isb['user'], $isb['pass'], $dbn, $port);
2625
$conn->set_charset("utf8mb4");
2726
}
28-
elseif ($databaseType == 'PureMySQL') {
29-
$port = array_key_exists('port', $summarydbconfig) ? $summarydbconfig['port'] : null;
30-
if (!$port) {
31-
$port = ini_get("mysqli.default_port");
32-
}
33-
list($host, $dbn) = explode('/', $summarydbconfig['db']);
34-
$conn = new \mysqli($host, $summarydbconfig['user'], $summarydbconfig['pass'], $dbn, $port);
35-
$conn->set_charset("utf8mb4");
36-
}
37-
3827

3928
if ($conn == null) {
4029
Utils::returnError("Database Configuration Error", "Database connection for type '$databaseType' does not exist.");

api/src/Database/DatabaseFactory.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ class DatabaseFactory
1010
// Key is lower case representation of class name.
1111
public $database_types = array(
1212
'mysql' => ["dbClassName" =>'MySQL', "dataConnectionName" => 'MySQL'],
13-
'summary' => ["dbClassName" =>'PureMySQL', "dataConnectionName" => 'PureMySQL']
1413
);
1514

1615
function __construct($databaseConnectionFactory)

api/src/Page/Processing.php

Lines changed: 204 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class Processing extends Page {
99
public static $dispatch = array(
1010
array('/:id', 'get', '_results'),
11+
array('/visit/:visit', 'get', '_results_for_visit'),
1112
array('/status', 'post', '_statuses'),
1213

1314
array('/messages/status', 'post', '_ap_message_status'),
@@ -34,7 +35,15 @@ class Processing extends Page {
3435
'map' => '\d+',
3536
'n' => '\d+',
3637
'sampleGroupId' => '\d+',
37-
'resultCount' => '\d+'
38+
'resultCount' => '\d+',
39+
'pipeline' => '[\w\s\+]+',
40+
'spacegroup' => '(\w|\s|\-|\/)+',
41+
'resolution' => '[\d\.]+',
42+
'completeness' => '[\d\.]+',
43+
'anomcompleteness' => '[\d\.]+',
44+
'rmeas' => '[\d\.]+',
45+
'cchalf' => '[\d\.]+',
46+
'ccanom' => '[\d\.]+',
3847
);
3948

4049
/**
@@ -47,6 +56,8 @@ class Processing extends Page {
4756
0 => 3,
4857
);
4958

59+
const EVTOA = 12398.4198;
60+
5061
function _map_status($status) {
5162
foreach ($this->status_mapping as $state => $value) {
5263
if ($status == $state) {
@@ -238,6 +249,198 @@ function _statuses() {
238249
$this->_output($out);
239250
}
240251

252+
function _results_for_visit() {
253+
if (!($this->has_arg('visit'))) {
254+
$this->_error('No visit specified');
255+
}
256+
$pattern = '/([A-z]+)(\d+)-(\d+)/';
257+
preg_match($pattern, $this->arg('visit'), $matches);
258+
if (!sizeof($matches))
259+
$this->_error('No such visit');
260+
261+
$info = $this->db->pq("SELECT s.sessionid FROM blsession s INNER JOIN proposal p ON (p.proposalid = s.proposalid) WHERE p.proposalcode=:1 AND p.proposalnumber=:2 AND s.visit_number=:3", array($matches[1], $matches[2], $matches[3]));
262+
263+
if (!sizeof($info)) {
264+
$this->_error('No such visit');
265+
}
266+
267+
$args = array($info[0]['SESSIONID']);
268+
269+
$where = 'dc.sessionid=:1 AND dc.overlap = 0 AND dc.axisrange > 0 AND dc.numberOfImages > 150 AND app.processingstatus = 1';
270+
271+
if ($this->has_arg('pipeline')) {
272+
$st = sizeof($args);
273+
$where .= " AND app.processingprograms = :" . ($st + 1);
274+
array_push($args, $this->arg('pipeline'));
275+
}
276+
277+
if ($this->has_arg('spacegroup')) {
278+
$st = sizeof($args);
279+
$where .= " AND REPLACE(ap.spacegroup,' ','') = :" . ($st + 1);
280+
array_push($args, $this->arg('spacegroup'));
281+
}
282+
283+
if ($this->has_arg('resolution')) {
284+
$st = sizeof($args);
285+
$where .= " AND apssover.resolutionlimithigh <= :" . ($st + 1);
286+
array_push($args, $this->arg('resolution'));
287+
}
288+
289+
if ($this->has_arg('completeness')) {
290+
$st = sizeof($args);
291+
$where .= " AND apssover.completeness >= :" . ($st + 1);
292+
array_push($args, $this->arg('completeness'));
293+
}
294+
295+
if ($this->has_arg('anomcompleteness')) {
296+
$st = sizeof($args);
297+
$where .= " AND apssover.anomalousCompleteness >= :" . ($st + 1);
298+
array_push($args, $this->arg('anomcompleteness'));
299+
}
300+
301+
if ($this->has_arg('rmeas')) {
302+
$st = sizeof($args);
303+
$where .= " AND apssinner.rmeasalliplusiminus <= :" . ($st + 1);
304+
array_push($args, $this->arg('rmeas'));
305+
}
306+
307+
if ($this->has_arg('cchalf')) {
308+
$st = sizeof($args);
309+
$where .= " AND apssouter.cchalf >= :" . ($st + 1);
310+
array_push($args, $this->arg('cchalf'));
311+
}
312+
313+
if ($this->has_arg('ccanom')) {
314+
$st = sizeof($args);
315+
$where .= " AND apssinner.ccanomalous >= :" . ($st + 1);
316+
array_push($args, $this->arg('ccanom'));
317+
}
318+
319+
if ($this->has_arg('s')) {
320+
$st = sizeof($args);
321+
$where .= " AND (CONCAT(dc.imageprefix,'_',dc.datacollectionnumber) LIKE CONCAT('%',:" . ($st + 1) . ",'%') OR smp.name LIKE CONCAT('%',:" . ($st + 2) . ",'%'))";
322+
array_push($args, $this->arg('s'));
323+
array_push($args, $this->arg('s'));
324+
}
325+
326+
$start = 0;
327+
$pp = $this->has_arg('per_page') ? $this->arg('per_page') : 15;
328+
329+
if ($this->has_arg('page')) {
330+
$pg = $this->arg('page') - 1;
331+
$start = $pg * $pp;
332+
}
333+
334+
$order = 'id DESC';
335+
336+
if ($this->has_arg('sort_by')) {
337+
$cols = array(
338+
'PREFIX' => 'prefix', 'SAMPLE' => 'sample',
339+
'ENERGY' => 'energy', 'RESOLUTION' => 'resolution', 'CELL' => 'cell_a',
340+
'RES' => 'overallrhigh', 'INNERRMEAS' => 'innerrmeas',
341+
'COMPLETENESS' => 'overallcompleteness', 'ANOMCOMPLETENESS' => 'anomoverallcompleteness',
342+
'INNERCCANOM' => 'innerccanom', 'OUTERCCHALF' => 'outercchalf',
343+
'SG' => 'sg', 'PIPELINE' => 'pipeline'
344+
);
345+
$dir = $this->has_arg('order') ? ($this->arg('order') == 'asc' ? 'ASC' : 'DESC') : 'ASC';
346+
if (array_key_exists($this->arg('sort_by'), $cols))
347+
$order = $cols[$this->arg('sort_by')] . ' ' . $dir;
348+
}
349+
350+
$jobs = $this->db->pq(
351+
"SELECT dc.datacollectionid as id,
352+
CONCAT(dc.imageprefix, '_', dc.datacollectionnumber) as prefix,
353+
".self::EVTOA."/dc.wavelength as energy,
354+
dc.resolution,
355+
smp.name as sample,
356+
smp.blsampleid,
357+
app.processingprograms as pipeline,
358+
app.autoprocprogramid as aid,
359+
REPLACE(ap.spacegroup,' ','') as sg,
360+
ap.refinedcell_a as cell_a,
361+
ap.refinedcell_b as cell_b,
362+
ap.refinedcell_c as cell_c,
363+
ap.refinedcell_alpha as cell_al,
364+
ap.refinedcell_beta as cell_be,
365+
ap.refinedcell_gamma as cell_ga,
366+
apssover.resolutionlimithigh as overallrhigh,
367+
apssover.resolutionlimitlow as overallrlow,
368+
apssinner.resolutionlimithigh as innerrhigh,
369+
apssinner.resolutionlimitlow as innerrlow,
370+
apssouter.resolutionlimithigh as outerrhigh,
371+
apssouter.resolutionlimitlow as outerrlow,
372+
apssover.completeness as overallcompleteness,
373+
apssinner.completeness as innercompleteness,
374+
apssouter.completeness as outercompleteness,
375+
apssover.anomalouscompleteness as anomoverallcompleteness,
376+
apssinner.anomalouscompleteness as anominnercompleteness,
377+
apssouter.anomalouscompleteness as anomoutercompleteness,
378+
apssinner.rmeasalliplusiminus as innerrmeas,
379+
apssouter.cchalf as outercchalf,
380+
apssinner.ccanomalous as innerccanom
381+
FROM datacollection dc
382+
LEFT OUTER JOIN blsample smp ON dc.blsampleid = smp.blsampleid
383+
INNER JOIN processingjob pj ON dc.datacollectionid = pj.datacollectionid
384+
INNER JOIN autoprocprogram app ON pj.processingjobid = app.processingjobid
385+
INNER JOIN autoproc ap ON app.autoprocprogramid=ap.autoprocprogramid
386+
INNER JOIN autoprocscaling aps ON ap.autoprocid = aps.autoprocid
387+
INNER JOIN autoprocscalingstatistics apssover ON aps.autoprocscalingid = apssover.autoprocscalingid AND apssover.scalingStatisticsType='overall'
388+
INNER JOIN autoprocscalingstatistics apssinner ON aps.autoprocscalingid = apssinner.autoprocscalingid AND apssinner.scalingStatisticsType='innerShell'
389+
INNER JOIN autoprocscalingstatistics apssouter ON aps.autoprocscalingid = apssouter.autoprocscalingid AND apssouter.scalingStatisticsType='outerShell'
390+
WHERE $where
391+
ORDER BY $order",
392+
$args
393+
);
394+
395+
// Only take one processing job per data collection id
396+
$data = array();
397+
$dcids = array();
398+
foreach ($jobs as $job) {
399+
$dcid = $job['ID'];
400+
if (!(in_array($dcid, $dcids))) {
401+
array_push($data, $job);
402+
array_push($dcids, $dcid);
403+
}
404+
}
405+
406+
// Strip down data to only the page needed
407+
$tot = sizeof($data);
408+
$data = array_slice($data, $start, $pp);
409+
410+
// Add classes to highlight fields in red/yellow/green
411+
foreach ($data as &$d) {
412+
foreach (array('OVERALL', 'INNER', 'OUTER') as $s) {
413+
$c = $d[$s.'COMPLETENESS'];
414+
$d[$s.'COMPLETENESSCLASS'] = $c > 95 ? 'active' : ($c > 80 ? 'minor' : 'inactive');
415+
$c = $d['ANOM'.$s.'COMPLETENESS'];
416+
$d['ANOM'.$s.'COMPLETENESSCLASS'] = $c > 95 ? 'active' : ($c > 80 ? 'minor' : 'inactive');
417+
}
418+
}
419+
420+
// Set number of decimal places
421+
$nf = array(
422+
0 => array('ENERGY'),
423+
2 => array(
424+
'RESOLUTION', 'INNERRMEAS', 'OUTERCCHALF', 'INNERCCANOM',
425+
'CELL_A', 'CELL_B', 'CELL_C', 'CELL_AL', 'CELL_BE', 'CELL_GA',
426+
'OVERALLRHIGH', 'OVERALLRLOW', 'INNERRHIGH', 'INNERRLOW', 'OUTERRHIGH', 'OUTERRLOW',
427+
'OVERALLCOMPLETENESS', 'INNERCOMPLETENESS', 'OUTERCOMPLETENESS',
428+
'ANOMOVERALLCOMPLETENESS', 'ANOMINNERCOMPLETENESS', 'ANOMOUTERCOMPLETENESS'
429+
)
430+
);
431+
432+
foreach ($nf as $nff => $cols) {
433+
foreach ($cols as $c) {
434+
foreach ($data as &$d) {
435+
$d[$c] = number_format($d[$c], $nff);
436+
}
437+
}
438+
}
439+
440+
$this->_output(array('total' => $tot, 'data' => $data));
441+
442+
}
443+
241444
/**
242445
* Auto processing results
243446
* (Integration results only)

api/src/Page/Proposal.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ function _get_proposals($id = null)
206206
$order = 'p.proposalid DESC';
207207

208208
if ($this->has_arg('sort_by')) {
209-
$cols = array('ST' => 'p.bltimestamp', 'PROPOSALCODE' => 'p.proposalcode', 'PROPOSALNUMBER' => 'p.proposalnumber', 'VCOUNT' => 'vcount', 'TITLE' => 'lower(p.title)');
209+
$cols = array('ST' => 'p.bltimestamp', 'PROPOSALCODE' => 'p.proposalcode', 'PROPOSALNUMBER' => 'p.proposalnumber', 'VCOUNT' => 'vcount', 'TITLE' => 'lower(p.title)', 'STATE' => 'p.state');
210210
$dir = $this->has_arg('order') ? ($this->arg('order') == 'asc' ? 'ASC' : 'DESC') : 'ASC';
211211
if (array_key_exists($this->arg('sort_by'), $cols))
212212
$order = $cols[$this->arg('sort_by')] . ' ' . $dir;

api/src/Page/Shipment.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,12 +1642,24 @@ function _get_dewars()
16421642
$order = $cols[$this->arg('sort_by')] . ' ' . $dir;
16431643
}
16441644

1645-
$dewars = $this->db->paginate("SELECT CONCAT(p.proposalcode, p.proposalnumber) as prop, CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number) as firstexperiment, r.labcontactid, se.beamlineoperator as localcontact, se.beamlinename, TO_CHAR(se.startdate, 'HH24:MI DD-MM-YYYY') as firstexperimentst, d.firstexperimentid, s.shippingid, s.shippingname, d.facilitycode, count(c.containerid) as ccount, (case when se.visit_number > 0 then (CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number)) else '' end) as exp, d.code, d.barcode, d.storagelocation, d.dewarstatus, d.dewarid, d.trackingnumbertosynchrotron, d.trackingnumberfromsynchrotron, d.externalShippingIdFromSynchrotron, s.deliveryagent_agentname, d.weight, d.deliveryagent_barcode, GROUP_CONCAT(c.code SEPARATOR ', ') as containers, s.sendinglabcontactid, s.returnlabcontactid, pe.givenname, pe.familyname, s.safetylevel as shippingsafetylevel
1646-
FROM dewar d
1647-
LEFT OUTER JOIN container c ON c.dewarid = d.dewarid
1648-
INNER JOIN shipping s ON d.shippingid = s.shippingid
1649-
INNER JOIN proposal p ON p.proposalid = s.proposalid
1650-
LEFT OUTER JOIN blsession se ON d.firstexperimentid = se.sessionid
1645+
$dewars = $this->db->paginate("SELECT
1646+
CONCAT(p.proposalcode, p.proposalnumber) as prop,
1647+
CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number) as firstexperiment,
1648+
CONCAT(p.proposalcode, p.proposalnumber, '-', se2.visit_number) as udcfirstexperiment,
1649+
r.labcontactid, se.beamlineoperator as localcontact, se.beamlinename,
1650+
TO_CHAR(se.startdate, 'HH24:MI DD-MM-YYYY') as firstexperimentst, d.firstexperimentid,
1651+
s.shippingid, s.shippingname, d.facilitycode, count(c.containerid) as ccount,
1652+
(case when se.visit_number > 0 then (CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number)) else '' end) as exp,
1653+
d.code, d.barcode, d.storagelocation, d.dewarstatus, d.dewarid,
1654+
d.trackingnumbertosynchrotron, d.trackingnumberfromsynchrotron, d.externalShippingIdFromSynchrotron,
1655+
s.deliveryagent_agentname, d.weight, d.deliveryagent_barcode, GROUP_CONCAT(c.code SEPARATOR ', ') as containers,
1656+
s.sendinglabcontactid, s.returnlabcontactid, pe.givenname, pe.familyname, s.safetylevel as shippingsafetylevel
1657+
FROM dewar d
1658+
LEFT OUTER JOIN container c ON c.dewarid = d.dewarid
1659+
INNER JOIN shipping s ON d.shippingid = s.shippingid
1660+
INNER JOIN proposal p ON p.proposalid = s.proposalid
1661+
LEFT OUTER JOIN blsession se ON d.firstexperimentid = se.sessionid
1662+
LEFT OUTER JOIN blsession se2 ON c.sessionid = se2.sessionid
16511663
LEFT OUTER JOIN dewarregistry r ON r.facilitycode = d.facilitycode
16521664
LEFT OUTER JOIN labcontact lc ON s.sendinglabcontactid = lc.labcontactid
16531665
LEFT OUTER JOIN person pe ON lc.personid = pe.personid

0 commit comments

Comments
 (0)