diff --git a/api/config_sample.php b/api/config_sample.php index 97d9fc85d..9be9cf64f 100644 --- a/api/config_sample.php +++ b/api/config_sample.php @@ -406,6 +406,34 @@ $dials_rest_jwt = ""; $dials_rest_url_rings = false; + # Upstream reprocessing pipelines, by beamline type + $upstream_reprocessing_pipelines = array( + 'sm' => array( + array('NAME' => 'Xia2 DIALS', 'VALUE' => 'xia2-dials'), + array('NAME' => 'Xia2 DIALS aimless', 'VALUE' => 'xia2-dials-aimless'), + ), + 'default' => array( + array('NAME' => 'Xia2 DIALS', 'VALUE' => 'xia2-dials'), + array('NAME' => 'Xia2 3dii', 'VALUE' => 'xia2-3dii'), + array('NAME' => 'Fast DP', 'VALUE' => 'fast_dp'), + array('NAME' => 'autoPROC', 'VALUE' => 'autoPROC'), + ), + ); + + # Downstream reprocessing pipelines, by beamline type + $downstream_reprocessing_pipelines = array( + 'sm' => array( + array('NAME' => 'shelxt', 'VALUE' => 'trigger-shelxt'), + ), + 'default' => array( + array('NAME' => 'Dimple', 'VALUE' => 'trigger-dimple'), + array('NAME' => 'Fast EP', 'VALUE' => 'trigger-fastep'), + array('NAME' => 'Big EP', 'VALUE' => 'trigger-bigep'), + array('NAME' => 'MrBUMP', 'VALUE' => 'trigger-mrbump'), + ), + ); + + # Add a button to upload file to CCP4 cloud #$ccp4_cloud_upload_url = 'https://data.cloud.ccp4.ac.uk/api/data/<%=USERNAME%>/<%=FACILITYNAME%>/<%=IMAGEPREFIX%>_<%=DATACOLLECTIONNUMBER%>/upload'; ?> diff --git a/api/index.php b/api/index.php index 60d180f74..a16c214de 100644 --- a/api/index.php +++ b/api/index.php @@ -73,8 +73,8 @@ function setupApplication($mode): Slim $valid_components, $enabled_container_types, $synchweb_version, $redirects, $shipping_service_app_url, $use_shipping_service_redirect, $use_shipping_service_redirect_incoming_shipments, $dials_rest_url_rings, $closed_proposal_link, $ccp4_cloud_upload_url, - $only_staff_can_assign, $industrial_prop_codes, $prop_codes_data_deleted, $container_types_with_parents, - $bl_capacity; + $only_staff_can_assign, $industrial_prop_codes, $upstream_reprocessing_pipelines, $downstream_reprocessing_pipelines, + $prop_codes_data_deleted, $container_types_with_parents, $bl_capacity; $app->contentType('application/json'); $options = $app->container['options']; $app->response()->body(json_encode(array( @@ -97,16 +97,18 @@ function setupApplication($mode): Slim 'valid_components' => $valid_components, 'enabled_container_types' => $enabled_container_types, 'synchweb_version' => $synchweb_version, + 'redirects' => $redirects, 'shipping_service_app_url' => $use_shipping_service_redirect || $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null, 'shipping_service_app_url_incoming' => $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null, - 'closed_proposal_link' => $closed_proposal_link, 'dials_rest_url_rings' => $dials_rest_url_rings, + 'closed_proposal_link' => $closed_proposal_link, 'ccp4_cloud_upload_url' => $ccp4_cloud_upload_url, - 'redirects' => $redirects, 'only_staff_can_assign' => $only_staff_can_assign, - 'container_types_with_parents' => $container_types_with_parents, 'industrial_prop_codes' => $industrial_prop_codes, + 'upstream_reprocessing_pipelines' => $upstream_reprocessing_pipelines, + 'downstream_reprocessing_pipelines' => $downstream_reprocessing_pipelines, 'prop_codes_data_deleted' => $prop_codes_data_deleted ?? array(), + 'container_types_with_parents' => $container_types_with_parents, 'bl_capacity' => $bl_capacity, ))); }); diff --git a/api/src/Page/Sample.php b/api/src/Page/Sample.php index 24b57298d..69b58bfbe 100644 --- a/api/src/Page/Sample.php +++ b/api/src/Page/Sample.php @@ -17,8 +17,8 @@ class Sample extends Page 's' => '\w+', 'prop' => '\w+\d+', 'term' => '\w+', - 'pid' => '\d+', - 'sid' => '\d+', + 'pid' => '-?\d+', + 'sid' => '-?\d+', 'ssid' => '\d+', 'cid' => '\d+', 'crid' => '\d+', diff --git a/client/src/js/modules/dc/views/downstreamreprocess.js b/client/src/js/modules/dc/views/downstreamreprocess.js index 4154a2c68..1ea5f86d7 100644 --- a/client/src/js/modules/dc/views/downstreamreprocess.js +++ b/client/src/js/modules/dc/views/downstreamreprocess.js @@ -100,6 +100,10 @@ define(['backbone', 'marionette', 'views/dialog', this.model.set('PIPELINENAME', this.ui.pipeline.find('option:selected').text()) var btns = this.buttons var warning = '' + if (!this.model.get('PIPELINENAME')) { + warning = ' No pipelines available' + btns = this.disabledButtons + } if (['MrBUMP', 'Dimple'].includes(this.model.get('PIPELINENAME')) && this.type.includes('autoPROC')) { warning = ' Cannot rerun ' + this.model.get('PIPELINENAME') + ' on ' + this.type + ' results' btns = this.disabledButtons @@ -112,7 +116,7 @@ define(['backbone', 'marionette', 'views/dialog', warning = ' Cannot run Dimple as no PDBs defined' btns = this.disabledButtons } - if (this.model.get('PIPELINENAME') === 'MrBUMP' && this.model.get('HASSEQ') === 'No') { + if (this.model.get('PIPELINENAME') === 'MrBUMP' && (this.model.get('HASSEQ') === 'No' || !this.model.get('HASSEQ'))) { warning = ' Cannot run MrBUMP as no sequence defined' btns = this.disabledButtons } @@ -120,7 +124,7 @@ define(['backbone', 'marionette', 'views/dialog', warning = ' Cannot run Fast EP as no anomalous scatterer defined' btns = this.disabledButtons } - if (this.model.get('PIPELINENAME') === 'Big EP' && this.model.get('HASSEQ') === 'No') { + if (this.model.get('PIPELINENAME') === 'Big EP' && (this.model.get('HASSEQ') === 'No' || !this.model.get('HASSEQ'))) { warning = ' Cannot run Big EP as no sequence defined' btns = this.disabledButtons } @@ -155,7 +159,7 @@ define(['backbone', 'marionette', 'views/dialog', initialize: function(options) { - this.proteins = new Proteins(null, { queryParams: { sid: options.model.get('BLSAMPLEID') } }) + this.proteins = new Proteins(null, { queryParams: { sid: options.model.get('BLSAMPLEID') || -1 } }) this._ready = this.proteins.fetch() this._ready.done(this.doOnReady.bind(this)) this.scalingid = options.scalingid @@ -169,24 +173,23 @@ define(['backbone', 'marionette', 'views/dialog', }, onRender: function() { - - this.pipelines = new Pipelines([ - { NAME: 'Dimple', VALUE: 'trigger-dimple' }, - { NAME: 'Fast EP', VALUE: 'trigger-fastep' }, - { NAME: 'Big EP', VALUE: 'trigger-bigep' }, - { NAME: 'MrBUMP', VALUE: 'trigger-mrbump' }, - ]) - - this.ui.pipeline.html(this.pipelines.opts()) + const dspls = app.options.get('downstream_reprocessing_pipelines') + if (dspls) { + const pls = dspls[app.type] ?? dspls['default']; + this.pipelines = new Pipelines(pls) + this.ui.pipeline.html(this.pipelines.opts()) + } }, - + doOnReady: function() { var protein = this.proteins.at(0) - var self = this - _.each(['ACRONYM','PROTEINID','HASSEQ','PDBS','ANOMALOUSSCATTERER'], function(k) { - self.model.set(k, protein.get(k)) - }) - this.pdbs = new PDBs(null, { pid: this.model.get('PROTEINID') }) + if (protein) { + var self = this + _.each(['ACRONYM','PROTEINID','HASSEQ','PDBS','ANOMALOUSSCATTERER'], function(k) { + self.model.set(k, protein.get(k)) + }) + } + this.pdbs = new PDBs(null, { pid: this.model.get('PROTEINID') || -1 }) this.pdbs.fetch().done(this.updatePipeline.bind(this)) this.collection = new IDDataCollections() if (this.model) { diff --git a/client/src/js/modules/dc/views/reprocess2.js b/client/src/js/modules/dc/views/reprocess2.js index 5ebd0f8dd..6ee085e9a 100644 --- a/client/src/js/modules/dc/views/reprocess2.js +++ b/client/src/js/modules/dc/views/reprocess2.js @@ -102,7 +102,7 @@ define(['backbone', 'marionette', 'views/dialog', selectAll: function(e) { - e.preventDefault() + if (e) e.preventDefault() var si = parseInt(this.model.get('SI')) var ni = parseInt(this.model.get('NUMIMG')) @@ -148,6 +148,20 @@ define(['backbone', 'marionette', 'views/dialog', this.$el.find('div input[type="text"]').css('width', '50px') this.ui.pipeline.html(this.getOption('pipelines').opts()) this.model.set('PIPELINE', this.ui.pipeline.val()) + + // check .distl element has been created before selecting all + const callback = (mutationList, observer) => { + for (const mutation of mutationList) { + for (const node of mutation.addedNodes) { + if (node.nodeType === Node.ELEMENT_NODE && node.querySelector('.distl')) { + this.selectAll() + observer.disconnect() + } + } + } + } + const observer = new MutationObserver(callback) + observer.observe(document.getElementById("dialog"), { childList: true, subtree: true }) }, toggleSG: function(e) { @@ -247,6 +261,12 @@ define(['backbone', 'marionette', 'views/dialog', sm: 'input[name=sm]', indexingMethod: 'select[name=method]', absorptionLevel: 'select[name=absorption_level]', + a: 'input[name=a]', + b: 'input[name=b]', + c: 'input[name=c]', + al: 'input[name=alpha]', + be: 'input[name=beta]', + ga: 'input[name=gamma]', }, buttons: { @@ -259,6 +279,7 @@ define(['backbone', 'marionette', 'views/dialog', 'click a.opt': 'toggleOpts', 'click @ui.ind': 'toggleIndividual', 'change @ui.pipeline': 'updatePipeline', + 'change @ui.indexingMethod': 'updateIndexingMethod', 'click a.multicrystal': 'closeDialog', }, @@ -276,11 +297,40 @@ define(['backbone', 'marionette', 'views/dialog', } }, + updateIndexingMethod: function() { + if (this.ui.indexingMethod.val() == 'real_space_grid_search') { + const st = this.ui.ind.is(':checked') + if (st) { + let eachHasCell = true + this.distlview.children.each(function(v) { + if (!v.ui.a.val() || !v.ui.b.val() || !v.ui.c.val() || + !v.ui.al.val() || !v.ui.be.val() || !v.ui.ga.val()) { + v.ui.cell.show() + eachHasCell = false + } + }) + if (!eachHasCell) { + app.alert({ message: 'Real Space Grid Search requires unit cell to be populated' }) + this.ui.indexingMethod.val('') + } + } else { + if (!this.ui.a.val() || !this.ui.b.val() || !this.ui.c.val() || + !this.ui.al.val() || !this.ui.be.val() || !this.ui.ga.val()) { + app.alert({ message: 'Real Space Grid Search requires unit cell to be populated' }) + this.ui.indexingMethod.val('') + this.ui.cell.show() + } + } + } + }, + toggleIndividual: function(e) { - var st = this.ui.ind.is(':checked') + const st = this.ui.ind.is(':checked') st ? this.ui.mul.hide() : this.ui.mul.show() + if (st) this.ui.cell.hide() this.distlview.children.each(function(v) { v.setInd(st) + if (!st) v.ui.cell.hide() }) }, @@ -309,7 +359,7 @@ define(['backbone', 'marionette', 'views/dialog', var s = this.collection.where({ selected: true }) if (!s.length) { - app.alert({ message: 'Please selected some data sets to integrate' }) + app.alert({ message: 'Please select some data sets to integrate' }) return } @@ -530,18 +580,16 @@ define(['backbone', 'marionette', 'views/dialog', }, onRender: function() { - this.ui.opts.hide() + if (app.type != 'sm') this.ui.opts.hide() this.ui.cell.hide() - this.$el.find('span input[type="text"]').css('width', '50px') - - this.pipelines = new Pipelines([ - { NAME: 'Xia2 DIALS', VALUE: 'xia2-dials' }, - { NAME: 'Xia2 3dii', VALUE: 'xia2-3dii' }, - { NAME: 'Fast DP', VALUE: 'fast_dp' }, - { NAME: 'autoPROC', VALUE: 'autoPROC' }, - ]) + this.$el.find('span input[type="text"]').css('width', '55px') - this.ui.pipeline.html(this.pipelines.opts()) + const uspls = app.options.get('upstream_reprocessing_pipelines') + if (uspls) { + const pls = uspls[app.type] ?? uspls['default']; + this.pipelines = new Pipelines(pls) + this.ui.pipeline.html(this.pipelines.opts()) + } this.indexingMethods = new IndexingMethods([ { NAME: '-', VALUE: '' }, @@ -578,6 +626,7 @@ define(['backbone', 'marionette', 'views/dialog', var nm = model.clone() nm.set('CID', this.collection.length+1) this.collection.add(nm) + this.toggleIndividual() }, setCell: function(view, ap) { diff --git a/client/src/js/modules/types/sm/dc/dc.js b/client/src/js/modules/types/sm/dc/dc.js index 61d76f666..f14e77098 100644 --- a/client/src/js/modules/types/sm/dc/dc.js +++ b/client/src/js/modules/types/sm/dc/dc.js @@ -7,9 +7,7 @@ define([ return DCItemView.extend({ apStatusItem: APStatusItem, template: Template, - setProcessingVars: function() {}, - }) }) diff --git a/client/src/js/templates/dc/reprocess.html b/client/src/js/templates/dc/reprocess.html index fdf575bb7..38f964cbf 100644 --- a/client/src/js/templates/dc/reprocess.html +++ b/client/src/js/templates/dc/reprocess.html @@ -11,8 +11,8 @@ | Pipeline : - High Res : Å - Low Res : Å | + High Res : Å + Low Res : Å | Space Group / Cell diff --git a/client/src/js/templates/dc/reprocess_dc.html b/client/src/js/templates/dc/reprocess_dc.html index f24b2cd57..35fc73955 100644 --- a/client/src/js/templates/dc/reprocess_dc.html +++ b/client/src/js/templates/dc/reprocess_dc.html @@ -7,8 +7,8 @@

Pipeline - High Res Å - Low Res Å | + High Res Å + Low Res Å | Space Group / Cell
diff --git a/client/src/js/templates/mc/datacollections.html b/client/src/js/templates/mc/datacollections.html index 7fa8058c3..9af214cb3 100644 --- a/client/src/js/templates/mc/datacollections.html +++ b/client/src/js/templates/mc/datacollections.html @@ -29,8 +29,8 @@

Data Collections for <%-VISIT%>

- - + + Integrate Xia2 Options