diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 850fae6adeeb3b95e23118c6222a4341b41d2da4..0936cd9873a4a4b260c7db2fbe2f3e13123263ff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -447,7 +447,8 @@ deploy-tmss-test: - ssh $LOFAR_USER@$LOFAR_TARGET "docker pull ${CI_NEXUS_REGISTRY_LOCATION}/tmss_django:$CI_COMMIT_SHORT_SHA" - ssh $LOFAR_USER@$LOFAR_TARGET "docker tag ${CI_NEXUS_REGISTRY_LOCATION}/tmss_django:$CI_COMMIT_SHORT_SHA nexus.cep4.control.lofar:18080/tmss_django:latest" - ssh $LOFAR_USER@$LOFAR_TARGET "docker tag ${CI_NEXUS_REGISTRY_LOCATION}/tmss_django:$CI_COMMIT_SHORT_SHA tmss_django:latest" - #- ssh $LOFAR_USER@head.cep4.control.lofar "/data/home/lofarsys/tmss_clean_commissioning_data.sh || true" + - ssh $LOFAR_USER@$LOFAR_TARGET 'docker run --rm -u root -v tmss_staticfiles:/opt/lofar/staticfiles tmss_django:latest bash -c "source lofarinit.sh; bin/tmss_manage_django collectstatic --no-input"' + - ssh $LOFAR_USER@$LOFAR_TARGET 'docker run --rm --env-file /localhome/lofarsys/.lofar/.lofar_env_test tmss_django:latest bash -c "source lofarinit.sh; bin/tmss_manage_django migrate"' - ssh $LOFAR_USER@$LOFAR_TARGET "supervisorctl -u $SUPERVISOR_USER -p $SUPERVISOR_PASSWORD start TMSS:*" needs: - job: dockerize_TMSS @@ -648,6 +649,8 @@ deploy-tmss-prod: - ssh $LOFAR_USER@$LOFAR_TARGET "docker pull ${CI_NEXUS_REGISTRY_LOCATION}/tmss_django:$CI_COMMIT_SHORT_SHA" - ssh $LOFAR_USER@$LOFAR_TARGET "docker tag ${CI_NEXUS_REGISTRY_LOCATION}/tmss_django:$CI_COMMIT_SHORT_SHA nexus.cep4.control.lofar:18080/tmss_django:latest" - ssh $LOFAR_USER@$LOFAR_TARGET "docker tag ${CI_NEXUS_REGISTRY_LOCATION}/tmss_django:$CI_COMMIT_SHORT_SHA tmss_django:latest" + - ssh $LOFAR_USER@$LOFAR_TARGET 'docker run --rm -u root -v tmss_staticfiles:/opt/lofar/staticfiles tmss_django:latest bash -c "source lofarinit.sh; bin/tmss_manage_django collectstatic --no-input"' + - ssh $LOFAR_USER@$LOFAR_TARGET 'docker run --rm --env-file /localhome/lofarsys/.lofar/.lofar_env_test tmss_django:latest bash -c "source lofarinit.sh; bin/tmss_manage_django migrate"' - ssh $LOFAR_USER@$LOFAR_TARGET "supervisorctl -u $SUPERVISOR_USER -p $SUPERVISOR_PASSWORD start TMSS:*" environment: name: production diff --git a/LTA/sip/lib/siplib.py b/LTA/sip/lib/siplib.py index a4f9faf5867c93e730a709c2328d8a7f71487188..af6c39adf031d466fdcbb4c8d7e4e06ca46ee3c3 100644 --- a/LTA/sip/lib/siplib.py +++ b/LTA/sip/lib/siplib.py @@ -1071,7 +1071,7 @@ class ProcessMap(): for rel in relations: __relations.append(rel._get_pyxb_processrelation(suppress_warning=True)) self.process_map = dict(processIdentifier=identifier._get_pyxb_identifier(suppress_warning=True), - observationId=observation_identifier._get_pyxb_identifier(suppress_warning=True), + observationId=observation_identifier._get_pyxb_identifier(suppress_warning=True), relations=__relations, strategyName=strategyname, strategyDescription=strategydescription, startTime=starttime, duration=duration) diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc index cfa73e2eb20d8b67b2b01a770bebab79b4b00475..b1a3291432c4bab42e94be7b2ef657c857bb15aa 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc @@ -797,7 +797,7 @@ void MACScheduler::_updatePlannedList() if (!upcomingSubTasks.empty()) { LOG_DEBUG(formatString("TMSSCheck:First planned observation (%s) is at %s", - upcomingSubTasks[0]["url"].asCString(), upcomingSubTasks[0]["scheduled_process_start_time"].asCString())); + upcomingSubTasks[0]["url"].asCString(), upcomingSubTasks[0]["scheduled_on_sky_start_time"].asCString())); } // make a copy of the current prepared observations (= observations shown in the navigator in the 'future' @@ -913,7 +913,7 @@ void MACScheduler::_updatePlannedList() // construct name and timings info for observation string obsName(observationName(subtask_id)); - ptime start_time = time_from_string(subtask["scheduled_process_start_time"].asString().replace(10, 1, " ")); + ptime start_time = time_from_string(subtask["scheduled_on_sky_start_time"].asString().replace(10, 1, " ")); ptime modTime = time_from_string(subtask["updated_at"].asString().replace(10, 1, " ")); // remove obs from backup of the planned-list (it is in the list again) diff --git a/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc b/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc index c1d7f1bb912c82a8d901097f0aaf0f4d04817f92..b0d0e6e2c0fd4220230c40d76e61720cfbc3581c 100644 --- a/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc +++ b/MAC/APL/MainCU/src/MACScheduler/TMSSBridge.cc @@ -83,7 +83,7 @@ Json::Value TMSSBridge::getSubTasksStartingInThreeMinutes() ptime upper_limit = from_time_t(now+3*60); //TODO: make exact query as in SAS/OTDB/sql/getTreeGroup_func.sql with OR'd states and exact timewindow - string queryStr = "/api/subtask/?state__value=scheduled&scheduled_process_start_time__gt=" + to_iso_extended_string(lower_limit) + "&scheduled_process_start_time__lt=" + to_iso_extended_string(upper_limit) + "&ordering=scheduled_process_start_time"; + string queryStr = "/api/subtask/?state__value=scheduled&scheduled_on_sky_start_time__gt=" + to_iso_extended_string(lower_limit) + "&scheduled_on_sky_start_time__lt=" + to_iso_extended_string(upper_limit) + "&ordering=scheduled_on_sky_start_time"; Json::Value result; if(httpGETAsJson(queryStr, result)) @@ -95,7 +95,7 @@ Json::Value TMSSBridge::getActiveSubTasks() { ptime now = from_time_t(time(0)); //TODO: make exact query as in SAS/OTDB/sql/getTreeGroup_func.sql with OR'd states and exact timewindow - string queryStr = "/api/subtask/?state__value=started&scheduled_process_start_time__lt=" + to_iso_extended_string(now) + "&scheduled_process_stop_time__gt=" + to_iso_extended_string(now) + "&ordering=scheduled_process_start_time"; + string queryStr = "/api/subtask/?state__value=started&scheduled_on_sky_start_time__lt=" + to_iso_extended_string(now) + "&scheduled_on_sky_stop_time__gt=" + to_iso_extended_string(now) + "&ordering=scheduled_on_sky_start_time"; Json::Value result; if(httpGETAsJson(queryStr, result)) @@ -107,7 +107,7 @@ Json::Value TMSSBridge::getFinishingSubTasks() { ptime justnow = from_time_t(time(0)-3*60); //TODO: make exact query as in SAS/OTDB/sql/getTreeGroup_func.sql with OR'd states and exact timewindow - string queryStr = "/api/subtask/?state__value=finishing&scheduled_process_stop_time__gt=" + to_iso_extended_string(justnow) + "&ordering=scheduled_process_start_time"; + string queryStr = "/api/subtask/?state__value=finishing&scheduled_on_sky_stop_time__gt=" + to_iso_extended_string(justnow) + "&ordering=scheduled_on_sky_start_time"; Json::Value result; if(httpGETAsJson(queryStr, result)) @@ -161,7 +161,7 @@ std::size_t callback(const char* in, // Need to check response status code of http (200) // Inspired by https://gist.github.com/connormanning/41efa6075515019e499c // Example: -// httpQuery("/api/subtask/?scheduled_process_start_time__lt=2020-03-04T12:03:00") +// httpQuery("/api/subtask/?scheduled_on_sky_start_time__lt=2020-03-04T12:03:00") // results in a json string output // bool TMSSBridge::httpQuery(const string& target, string &result, const string& query_method, const string& data) diff --git a/SAS/TMSS/backend/src/remakemigrations.py b/SAS/TMSS/backend/src/remakemigrations.py index feb80bbb50063f5618e83c3f11b08ad5a497c486..ceb04af2b7220d8f40cc0ebb7c75d17b8edd48dd 100755 --- a/SAS/TMSS/backend/src/remakemigrations.py +++ b/SAS/TMSS/backend/src/remakemigrations.py @@ -130,6 +130,7 @@ class Migration(migrations.Migration): IF OLD.specifications_doc <> NEW.specifications_doc OR OLD.name <> NEW.name OR OLD.description <> NEW.description OR + OLD.short_description <> NEW.short_description OR OLD.specifications_template_id <> NEW.specifications_template_id OR OLD.scheduling_unit_blueprint_id <> NEW.scheduling_unit_blueprint_id THEN RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE BLUEPRINT FIELD'; diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/sip.py b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/sip.py index 1621708ea605b50ec04c29091c057eabb5252df5..f299db6d2fb0a7e8464777a3e71650281ee1bc30 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/sip.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/sip.py @@ -78,7 +78,7 @@ def get_siplib_stations_list(subtask): return siplib_station_list -def get_siplib_identifier(sipid_obj: SIPidentifier, context_str="") -> siplib.Identifier: +def get_siplib_identifier(sipid_obj: SIPidentifier, context_str="", name:str=None) -> siplib.Identifier: """ Retrieve an Identifier object. Get the unique_identifier and source of the given sip object and covert that to a siblib object @@ -98,7 +98,7 @@ def get_siplib_identifier(sipid_obj: SIPidentifier, context_str="") -> siplib.Id ltasip.IdentifierType( source=source, identifier=unique_id, - name=None, + name=name, label=None), suppress_warning=True) return identifier @@ -133,7 +133,7 @@ def create_sip_representation_for_subtask(subtask: Subtask): :return: A siplib.Observation object or one of the various siplib pipeline object flavors """ # determine common properties - subtask_sip_identifier = get_siplib_identifier(subtask.global_identifier, "Subtask id=%s" % subtask.id) + subtask_sip_identifier = get_siplib_identifier(subtask.global_identifier, "Subtask id=%s" % subtask.id, name=subtask.task_blueprint.short_description) name = str(subtask.id) process_map = siplib.ProcessMap(strategyname=subtask.specifications_template.name, strategydescription=subtask.specifications_template.description, diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py index bfd95c9f273df7aaf63d3ba8c5b1c41d75bec30d..5d19ced6b7659cc33e41585611baf168cc7aeac1 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.9 on 2021-09-27 14:27 +# Generated by Django 3.0.9 on 2021-10-05 17:32 from django.conf import settings import django.contrib.auth.models diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0002_populate.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0002_populate.py index c1ef378f9059ec3f0dea83cc6270fb555189d323..8c9cb85cebe6990cf3b0ac2af2e117bd4b62ab84 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0002_populate.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0002_populate.py @@ -9,6 +9,7 @@ from django.db import migrations from lofar.sas.tmss.tmss.tmssapp.populate import * class Migration(migrations.Migration): + dependencies = [ ('tmssapp', '0001_initial'), ] diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0003_taskblueprint_shortdescription.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0003_taskblueprint_shortdescription.py new file mode 100644 index 0000000000000000000000000000000000000000..c00080d12019c8b7c494f045f26ed521420eaa92 --- /dev/null +++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0003_taskblueprint_shortdescription.py @@ -0,0 +1,50 @@ +# Generated by Django 3.0.9 on 2021-10-07 09:17 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tmssapp', '0002_populate'), + ] + + operations = [ + migrations.AddField( + model_name='taskblueprint', + name='short_description', + field=models.CharField(blank=True, default='', help_text='A short description of this task, usually the name of the target and abbreviated task type.', max_length=32), + ), + migrations.AddField( + model_name='taskdraft', + name='short_description', + field=models.CharField(blank=True, default='', help_text='A short description of this task, usually the name of the target and abbreviated task type.', max_length=32), + ), + migrations.AlterField( + model_name='project', + name='project_state', + field=models.ForeignKey(default='opened', help_text='The state this project is in.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.ProjectState'), + ), + migrations.RunSQL('''CREATE OR REPLACE FUNCTION tmssapp_block_task_blueprint_immutable_fields_update() + RETURNS trigger AS + $BODY$ + BEGIN + IF OLD.specifications_doc <> NEW.specifications_doc OR + OLD.name <> NEW.name OR + OLD.description <> NEW.description OR + OLD.short_description <> NEW.short_description OR + OLD.specifications_template_id <> NEW.specifications_template_id OR + OLD.scheduling_unit_blueprint_id <> NEW.scheduling_unit_blueprint_id THEN + RAISE EXCEPTION 'ILLEGAL UPDATE OF IMMUTABLE BLUEPRINT FIELD'; + END IF; + RETURN NEW; + END; + $BODY$ + LANGUAGE plpgsql VOLATILE; + DROP TRIGGER IF EXISTS tmssapp_block_task_blueprint_immutable_fields_update ON tmssapp_TaskBlueprint ; + CREATE TRIGGER tmssapp_block_task_blueprint_immutable_fields_update + BEFORE UPDATE ON tmssapp_TaskBlueprint + FOR EACH ROW EXECUTE PROCEDURE tmssapp_block_task_blueprint_immutable_fields_update(); + ''') + ] diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py index 85e8a589c36b5ca66723fbbd1f8212543f0752d1..35417a7499018cba594f373058455b8cb2434349 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py @@ -983,6 +983,7 @@ class SchedulingUnitBlueprint(ProjectPropertyMixin, TemplateSchemaMixin, NamedCo class TaskDraft(NamedCommon, TemplateSchemaMixin, ProjectPropertyMixin): + short_description = CharField(max_length=32, help_text='A short description of this task, usually the name of the target and abbreviated task type.', blank=True, default="") specifications_doc = JSONField(help_text='Specifications for this task.') scheduling_unit_draft = ForeignKey('SchedulingUnitDraft', related_name='task_drafts', on_delete=CASCADE, help_text='Scheduling Unit draft to which this task draft belongs.') specifications_template = ForeignKey('TaskTemplate', on_delete=CASCADE, help_text='Schema used for specifications_doc.') # todo: 'schema'? @@ -1123,6 +1124,7 @@ class TaskBlueprint(ProjectPropertyMixin, TemplateSchemaMixin, NamedCommon): SCHEDULED = "scheduled" SCHEDULABLE = "schedulable" + short_description = CharField(max_length=32, help_text='A short description of this task, usually the name of the target and abbreviated task type.', blank=True, default="") specifications_doc = JSONField(help_text='Schedulings for this task (IMMUTABLE).') specifications_template = ForeignKey('TaskTemplate', on_delete=CASCADE, help_text='Schema used for specifications_doc (IMMUTABLE).') draft = ForeignKey('TaskDraft', related_name='task_blueprints', null=True, on_delete=SET_NULL, help_text='TaskDraft from which this TaskBlueprint was created. If the TaskDraft is deleted the we loose this reference, which is ok.') diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/reservations.py b/SAS/TMSS/backend/src/tmss/tmssapp/reservations.py index 25909b98bab8c01e7340d1b32caa69ffa86dd307..18b76eb7592c88e6fbbeab02512c56bbc5ff6a03 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/reservations.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/reservations.py @@ -6,7 +6,7 @@ def get_active_station_reservations_in_timewindow(lower_bound, upper_bound): Retrieve a list of all active stations reservations, which are reserved between a timewindow """ lst_active_station_reservations = [] - if upper_bound is None: + if upper_bound is not None: queryset = models.Reservation.objects.filter(start_time__lt=upper_bound) else: queryset = models.Reservation.objects.all() diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/HBA-single-beam-observation-scheduling-unit-observation-strategy.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/HBA-single-beam-observation-scheduling-unit-observation-strategy.json index ad73745d513793c040b6f8cf53dc78f2f5081a56..9f7ce85e09e7d63412220fb0e5ae1d1caa03225a 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/HBA-single-beam-observation-scheduling-unit-observation-strategy.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/HBA-single-beam-observation-scheduling-unit-observation-strategy.json @@ -22,13 +22,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -116,13 +110,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -147,13 +135,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LBA-survey-observation-scheduling-unit-observation-strategy.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LBA-survey-observation-scheduling-unit-observation-strategy.json index 5e6ebb9d68a2b2f650cf0ace496a75bf0d6cfdf2..b609badce605465e2acd871383f4cb235e1d9ad1 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LBA-survey-observation-scheduling-unit-observation-strategy.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LBA-survey-observation-scheduling-unit-observation-strategy.json @@ -514,13 +514,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -542,13 +536,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -570,13 +558,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -598,13 +580,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LoTSS-observation-scheduling-unit-observation-strategy.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LoTSS-observation-scheduling-unit-observation-strategy.json index 04e23c8cb95281e7633cc7e9a12bdb1b044e87bf..3fc1514896e0901425a11f4b1637a5043a45164a 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LoTSS-observation-scheduling-unit-observation-strategy.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/LoTSS-observation-scheduling-unit-observation-strategy.json @@ -22,13 +22,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -53,13 +47,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -643,13 +631,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 @@ -674,13 +656,7 @@ "autocorrelations":true }, "demix":{ - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps":10, "ignore_target":false, "frequency_steps":64 diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/UC1-scheduling-unit-observation-strategy.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/UC1-scheduling-unit-observation-strategy.json index e7655c9202c304138cbeec89f80f85216257a20e..b2fa516e2b915a27f25d9dc05cb4abaff7c16b47 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/UC1-scheduling-unit-observation-strategy.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/UC1-scheduling-unit-observation-strategy.json @@ -25,13 +25,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 @@ -120,13 +114,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 @@ -149,13 +137,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 @@ -193,13 +175,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/common_schema_template-affectedhardware-1.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/common_schema_template-affectedhardware-1.json new file mode 100644 index 0000000000000000000000000000000000000000..9fbfe91589c654d77324518acd9ef163b46046d7 --- /dev/null +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/common_schema_template-affectedhardware-1.json @@ -0,0 +1,31 @@ +{ + "$id": "http://tmss.lofar.org/api/schemas/commonschematemplate/affectedhardware/1#", + "$schema": "http://json-schema.org/draft-06/schema#", + "title": "affectedhardware", + "description": "This schema defines the hardware that was affected by a system event.", + "version": 1, + "type": "object", + "properties": { + "stations": { + "title": "Stations", + "description": "List of stations", + "$ref": "http://tmss.lofar.org/api/schemas/commonschematemplate/stations/1#/definitions/station_list", + "default": [] + }, + "clusters": { + "title": "Clusters", + "description": "List of affected clusters", + "type": "array", + "additionalItems": false, + "uniqueItems": true, + "default": [], + "items": { + "type": "string", + "title": "Cluster", + "default": "CEP4", + "enum": [ "COBALT2", "CEP4", "DragNet" ] + } + } + }, + "required": [] +} diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/responsive_telescope_HBA_LoTSS-scheduling_unit_observation-strategy-1.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/responsive_telescope_HBA_LoTSS-scheduling_unit_observation-strategy-1.json index aded1dbe41f84d85b9331afb95d858e5a9e5b805..6384fa54aac12fc9674551cdceb00b93ee7fe6a6 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/responsive_telescope_HBA_LoTSS-scheduling_unit_observation-strategy-1.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/responsive_telescope_HBA_LoTSS-scheduling_unit_observation-strategy-1.json @@ -16,13 +16,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 @@ -379,13 +373,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 @@ -562,4 +550,4 @@ } }, "scheduling_constraints_template": "constraints" -} \ No newline at end of file +} diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/scheduling_unit_template-scheduling_unit-1.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/scheduling_unit_template-scheduling_unit-1.json index 466d87bc2b7d5f65437a5db64279f09778d08465..073f13b8f3e522bcc2e38d51f152a534fc98e1c6 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/scheduling_unit_template-scheduling_unit-1.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/scheduling_unit_template-scheduling_unit-1.json @@ -17,10 +17,17 @@ "additionalProperties": false, "default": {}, "properties": { + "short description": { + "type": "string", + "title": "Short Description", + "default": "", + "description": "A short description of this task, usually the name of the target/source and abbreviated task type" + }, "description": { "type": "string", "title": "Description", - "default": "" + "default": "", + "description": "A long(er) description of this task" }, "tags": { "type": "array", diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/short-observation-pipeline-ingest-scheduling-unit-observation-strategy.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/short-observation-pipeline-ingest-scheduling-unit-observation-strategy.json index d6a5fabba170d6592c2a40f89c182a152300e5da..09942c4310d010053b3159a80f5f88ecbac69e7e 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/short-observation-pipeline-ingest-scheduling-unit-observation-strategy.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/short-observation-pipeline-ingest-scheduling-unit-observation-strategy.json @@ -58,13 +58,7 @@ "autocorrelations": true }, "demix": { - "sources":{ - "CasA":"auto", - "CygA":"auto", - "HerA":"auto", - "TauA":"auto", - "VirA":"auto", - "HydraA":"auto" }, + "sources": [], "time_steps": 10, "ignore_target": false, "frequency_steps": 64 diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/task_template-preprocessing_pipeline-1.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/task_template-preprocessing_pipeline-1.json index 430818d9644a75160ed78498160aa3cbd44f4cba..81b6a537a92c6d485d3b8024e2655533c74b4221 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/task_template-preprocessing_pipeline-1.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/task_template-preprocessing_pipeline-1.json @@ -70,51 +70,23 @@ "required": [], "properties": { "sources": { - "type": "object", - "title": "Sources", - "default": { - "CasA": "no", - "CygA": "no", - "HerA": "no", - "TauA": "no", - "VirA": "no", - "HydraA": "no" - }, - "required": [ - "CasA", - "CygA", - "HerA", - "HydraA", - "TauA", - "VirA" - ], - "properties": { - "CasA": { - "$ref": "http://scu199.control.lofar:8008/api/schemas/commonschematemplate/pipeline/1#/definitions/demix_strategy", - "title": "CasA" - }, - "CygA": { - "$ref": "http://scu199.control.lofar:8008/api/schemas/commonschematemplate/pipeline/1#/definitions/demix_strategy", - "title": "CygA" - }, - "HerA": { - "$ref": "http://scu199.control.lofar:8008/api/schemas/commonschematemplate/pipeline/1#/definitions/demix_strategy", - "title": "HerA" - }, - "TauA": { - "$ref": "http://scu199.control.lofar:8008/api/schemas/commonschematemplate/pipeline/1#/definitions/demix_strategy", - "title": "TauA" - }, - "VirA": { - "$ref": "http://scu199.control.lofar:8008/api/schemas/commonschematemplate/pipeline/1#/definitions/demix_strategy", - "title": "VirA" - }, - "HydraA": { - "$ref": "http://scu199.control.lofar:8008/api/schemas/commonschematemplate/pipeline/1#/definitions/demix_strategy", - "title": "HyrdraA" - } - }, - "additionalProperties": false + "type": "array", + "minItems": 0, + "maxItems": 2, + "uniqueItems": true, + "additionalItems": false, + "items": { + "type": "string", + "default": "CasA", + "enum": [ + "CasA", + "CygA", + "HerA", + "HydraA", + "TauA", + "VirA" + ] + } }, "time_steps": { "type": "integer", diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/templates.json b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/templates.json index 136fe7ab2e55c2f47bfc4d0d0cb603658e768bca..3ad4146d854b1c1bab7343c59a868c8cbb53a3b8 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/schemas/templates.json +++ b/SAS/TMSS/backend/src/tmss/tmssapp/schemas/templates.json @@ -31,6 +31,10 @@ "file_name": "common_schema_template-triggers-1.json", "template": "common_schema_template" }, + { + "file_name": "common_schema_template-affectedhardware-1.json", + "template": "common_schema_template" + }, { "file_name": "dataproduct_specifications_template-SAP-1.json", "template": "dataproduct_specifications_template" diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py index ce2d4c74b035198d660acfa6293cf772a453a9fa..9e79c6d55e3537e7f3257051b88f330df8095123 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py @@ -2095,8 +2095,8 @@ def _generate_subtask_specs_from_preprocessing_task_specs(preprocessing_task_spe subtask_specs['demixer']["demix_frequency_steps"] = preprocessing_task_specs['demix']['frequency_steps'] subtask_specs['demixer']["demix_time_steps"] = preprocessing_task_specs['demix']['time_steps'] subtask_specs['demixer']["ignore_target"] = preprocessing_task_specs['demix']['ignore_target'] - subtask_specs['demixer']["demix_always"] = [source for source,strategy in preprocessing_task_specs['demix']['sources'].items() if strategy == "yes"] - subtask_specs['demixer']["demix_if_needed"] = [source for source,strategy in preprocessing_task_specs['demix']['sources'].items() if strategy == "auto"] + subtask_specs['demixer']["demix_always"] = preprocessing_task_specs['demix']['sources'] + subtask_specs['demixer']["demix_if_needed"] = [] # flagging if preprocessing_task_specs["flag"]["rfi_strategy"] != 'none': diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py index 090bf84731519e91e1e31a25e46b5c0192768bd5..e365caec1b6d878fa2d0eec7d311306aebbabcc1 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py @@ -144,6 +144,7 @@ def copy_task_draft(task_draft: models.TaskDraft, including_relations: bool=Fals with transaction.atomic(): task_draft_copy = models.TaskDraft.objects.create(name="%s (Copy)" % (task_draft.name,), description="%s (Copy from task_draft id=%s)" % (task_draft.description, task_draft.id), + short_description=task_draft.short_description, specifications_doc=task_draft.specifications_doc, scheduling_unit_draft=task_draft.scheduling_unit_draft, specifications_template=task_draft.specifications_template) @@ -174,6 +175,7 @@ def copy_task_blueprint_to_task_draft(task_blueprint: models.TaskBlueprint, incl with transaction.atomic(): task_draft_copy = models.TaskDraft.objects.create(name="%s (Copy)" % (task_blueprint.name,), description="%s (Copy from task_blueprint id=%s)" % (task_blueprint.description, task_blueprint.id), + short_description=task_blueprint.short_description, specifications_doc=task_blueprint.specifications_doc, scheduling_unit_draft=task_blueprint.scheduling_unit_blueprint.draft, specifications_template=task_blueprint.specifications_template) @@ -244,6 +246,7 @@ def update_task_graph_from_specifications_doc(scheduling_unit_draft: models.Sche try: task_draft = scheduling_unit_draft.task_drafts.get(name=task_name) task_draft.description = task_definition.get("description", "") + task_draft.short_description = task_definition.get("short description", "") task_draft.specifications_doc = task_specifications_doc task_draft.specifications_template = task_template task_draft.save() @@ -253,6 +256,7 @@ def update_task_graph_from_specifications_doc(scheduling_unit_draft: models.Sche except models.TaskDraft.DoesNotExist: task_draft = models.TaskDraft.objects.create(name=task_name, description=task_definition.get("description", ""), + short_description=task_definition.get("short description", ""), scheduling_unit_draft=scheduling_unit_draft, specifications_doc = task_specifications_doc, specifications_template=task_template) @@ -332,6 +336,7 @@ def create_task_blueprint_from_task_draft(task_draft: models.TaskDraft) -> model task_blueprint.save() except TaskBlueprint.DoesNotExist: task_blueprint = TaskBlueprint.objects.create(description=task_draft.description, + short_description=task_draft.short_description, name=task_draft.name, draft=task_draft, scheduling_unit_blueprint=scheduling_unit_blueprint, diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py index 55651cf119fd0d25f5f2dc3010c085cd822dda6a..eecfea0ab5133fbca074cb3d41f43eeb8a915e8f 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py @@ -127,19 +127,36 @@ class SubTaskFilter(property_filters.PropertyFilterSet): id_max = filters.NumberFilter(field_name='id', lookup_expr='lte') state = filters.ModelMultipleChoiceFilter(field_name='state', queryset=models.SubtaskState.objects.all()) name = filters.CharFilter(field_name='task_blueprint__scheduling_unit_blueprint__name', lookup_expr='icontains') # todo: correct name? - on_sky_start_time__lt = property_filters.PropertyDateTimeFilter(field_name='on_sky_start_time', lookup_expr='lt') - on_sky_start_time__gt = property_filters.PropertyDateTimeFilter(field_name='on_sky_start_time', lookup_expr='gt') - process_start_time__lt = property_filters.PropertyDateTimeFilter(field_name='process_start_time', lookup_expr='lt') - process_stop_time__gt = property_filters.PropertyDateTimeFilter(field_name='process_start_time', lookup_expr='gt') + on_sky_start_time__lt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_start_time', lookup_expr='lt') + on_sky_start_time__gt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_start_time', lookup_expr='gt') + on_sky_stop_time__lt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_stop_time', lookup_expr='lt') + on_sky_stop_time__gt = property_filters.PropertyIsoDateTimeFilter(field_name='on_sky_stop_time', lookup_expr='gt') + process_start_time__lt = property_filters.PropertyIsoDateTimeFilter(field_name='process_start_time', lookup_expr='lt') + process_start_time__gt = property_filters.PropertyIsoDateTimeFilter(field_name='process_start_time', lookup_expr='gt') + process_stop_time__lt = property_filters.PropertyIsoDateTimeFilter(field_name='process_stop_time', lookup_expr='lt') + process_stop_time__gt = property_filters.PropertyIsoDateTimeFilter(field_name='process_stop_time', lookup_expr='gt') + scheduled_on_sky_start_time__lt = filters.IsoDateTimeFilter(field_name='scheduled_on_sky_start_time', lookup_expr='lt') + scheduled_on_sky_start_time__gt = filters.IsoDateTimeFilter(field_name='scheduled_on_sky_start_time', lookup_expr='gt') + scheduled_on_sky_stop_time__lt = filters.IsoDateTimeFilter(field_name='scheduled_on_sky_stop_time', lookup_expr='lt') + scheduled_on_sky_stop_time__gt = filters.IsoDateTimeFilter(field_name='scheduled_on_sky_stop_time', lookup_expr='gt') + actual_on_sky_start_time__lt = filters.IsoDateTimeFilter(field_name='actual_on_sky_start_time', lookup_expr='lt') + actual_on_sky_start_time__gt = filters.IsoDateTimeFilter(field_name='actual_on_sky_start_time', lookup_expr='gt') + actual_on_sky_stop_time__lt = filters.IsoDateTimeFilter(field_name='actual_on_sky_stop_time', lookup_expr='lt') + actual_on_sky_stop_time__gt = filters.IsoDateTimeFilter(field_name='actual_on_sky_stop_time', lookup_expr='gt') + scheduled_process_start_time__lt = filters.IsoDateTimeFilter(field_name='scheduled_process_start_time', lookup_expr='lt') + scheduled_process_start_time__gt = filters.IsoDateTimeFilter(field_name='scheduled_process_start_time', lookup_expr='gt') + scheduled_process_stop_time__lt = filters.IsoDateTimeFilter(field_name='scheduled_process_stop_time', lookup_expr='lt') + scheduled_process_stop_time__gt = filters.IsoDateTimeFilter(field_name='scheduled_process_stop_time', lookup_expr='gt') + actual_process_start_time__lt = filters.IsoDateTimeFilter(field_name='actual_process_start_time', lookup_expr='lt') + actual_process_start_time__gt = filters.IsoDateTimeFilter(field_name='actual_process_start_time', lookup_expr='gt') + actual_process_stop_time__lt = filters.IsoDateTimeFilter(field_name='actual_process_stop_time', lookup_expr='lt') + actual_process_stop_time__gt = filters.IsoDateTimeFilter(field_name='actual_process_stop_time', lookup_expr='gt') + class Meta: model = Subtask fields = { 'state__value': ['exact'], - 'scheduled_on_sky_start_time': ['lt', 'gt'], - 'scheduled_on_sky_stop_time': ['lt', 'gt'], - 'actual_on_sky_start_time': ['lt', 'gt'], - 'actual_on_sky_stop_time': ['lt', 'gt'], 'cluster__name': ['exact', 'icontains'], } filter_overrides = FILTER_OVERRIDES diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py index feee484b5062de0644160451fd8e738d74a438b0..30e8211d7bc2047a4884980a1c839360620c2302 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py @@ -87,9 +87,7 @@ class SchedulingUnitObservingStrategyTemplateViewSet(LOFARViewSet): Parameter(name='name', required=False, type='string', in_='query', description="The name for the newly created scheduling_unit"), Parameter(name='description', required=False, type='string', in_='query', - description="The description for the newly created scheduling_unit"), - Parameter(name='specifications_doc_overrides', required=False, type='dict', in_='body', - description="a JSON dict containing the override values for the parameters in the template") + description="The description for the newly created scheduling_unit") ]) @action(methods=['post'], detail=True) def create_scheduling_unit(self, request, pk=None): @@ -675,8 +673,8 @@ class SchedulingUnitDraftViewSet(LOFARViewSet): @swagger_auto_schema(responses={201: 'The new copied SchedulingUnitDraft', 403: 'forbidden'}, operation_description="Copy this SchedulingUnitDraft", - manual_parameters=[Parameter(name='scheduling_set_id', required=False, type='integer', in_='body', - description="the id of the scheduling_set which will be the parent of the newly created scheduling_unit") ] ) + request_body=openapi.Schema(type=openapi.TYPE_INTEGER, + description="the id of the scheduling_set which will be the parent of the newly created scheduling_unit")) @action(methods=['post'], detail=True, url_name="copy", name="Copy") def copy(self, request, pk=None): scheduling_unit_draft = get_object_or_404(models.SchedulingUnitDraft, pk=pk) diff --git a/SAS/TMSS/backend/src/tmss/workflowapp/serializers/schedulingunitflow.py b/SAS/TMSS/backend/src/tmss/workflowapp/serializers/schedulingunitflow.py index 891e06e0512fccb64ddd3ec40de155eb3b29bfd7..6095fc889fcfe237b01b510af439b7d5db83e7f1 100644 --- a/SAS/TMSS/backend/src/tmss/workflowapp/serializers/schedulingunitflow.py +++ b/SAS/TMSS/backend/src/tmss/workflowapp/serializers/schedulingunitflow.py @@ -1,4 +1,4 @@ -from rest_framework.serializers import ModelSerializer +from rest_framework.serializers import CharField, EmailField, ModelSerializer from lofar.sas.tmss.tmss.workflowapp import models from django.views import generic @@ -34,6 +34,8 @@ class SchedulingUnitProcessSerializer(ModelSerializer): fields = '__all__' class SchedulingUnitTaskSerializer(ModelSerializer): + owner_email = EmailField(source='owner.email', read_only=True, default=None) + owner_username = CharField(source='owner.username', read_only=True, default=None) class Meta: model = models.SchedulingUnitTask fields = '__all__' diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js index 0c7dbf406e06e62cb638cd85ba50ae05b4ba834d..9d081a10cc2562ee31f8a6ef4ce7089bada529c5 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js @@ -461,8 +461,8 @@ class SchedulingUnitList extends Component{ if (!this.props.project || (this.props.project && this.props.project === scheduleunit.scheduling_set.project.name)) { scheduleunit['status'] = null; scheduleunit['workflowStatus'] = null; - scheduleunit['observation_strategy_template_name'] = scheduleunit.observation_strategy_template.name; - scheduleunit['observation_strategy_template_description'] = scheduleunit.observation_strategy_template.description; + scheduleunit['observation_strategy_template_name'] = scheduleunit.observation_strategy_template?scheduleunit.observation_strategy_template.name:null; + scheduleunit['observation_strategy_template_description'] = scheduleunit.observation_strategy_template?scheduleunit.observation_strategy_template.description:null; scheduleunit['draft'] = this.getLinksList(scheduleunit.scheduling_unit_blueprints_ids, 'blueprint'); scheduleunit['task_content'] = this.getTaskTypeGroupCounts(scheduleunit['task_drafts']); scheduleunit['station_group'] = this.getStationGroup(scheduleunit).counts; @@ -535,9 +535,9 @@ class SchedulingUnitList extends Component{ scheduleunit.type= 'Blueprint'; scheduleunit['actionpath'] ='/schedulingunit/view/blueprint/'+scheduleunit.id; scheduleunit['task_content'] = this.getTaskTypeGroupCounts(scheduleunit['task_blueprints']); - scheduleunit['observation_strategy_template_name'] = scheduleunit.draft? scheduleunit.draft.observation_strategy_template.name : ''; - scheduleunit['observation_strategy_template_description'] = scheduleunit.draft? scheduleunit.draft.observation_strategy_template.description : ''; - scheduleunit['observation_strategy_template_id'] = scheduleunit.draft? scheduleunit.draft.observation_strategy_template.id : ''; + scheduleunit['observation_strategy_template_name'] = scheduleunit.draft.observation_strategy_template? scheduleunit.draft.observation_strategy_template.name : ''; + scheduleunit['observation_strategy_template_description'] = scheduleunit.draft.observation_strategy_template? scheduleunit.draft.observation_strategy_template.description : ''; + scheduleunit['observation_strategy_template_id'] = scheduleunit.draft.observation_strategy_template? scheduleunit.draft.observation_strategy_template.id : ''; scheduleunit['station_group'] = this.getStationGroup(scheduleunit).counts; scheduleunit['draft'] = this.getLinksList([scheduleunit.draft_id], 'draft'); //key 'drafts' used in filters, so use after process or change variable while fetching scheduleunit.canSelect = true; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js index 06e70a43112ca8b439f985db0d940cd1175f2d45..5a78ea520739ea9faa89a8180fa05225dbaf9181 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/edit.js @@ -49,6 +49,7 @@ export class EditSchedulingUnit extends Component { observStrategy: {}, // Selected strategy to create SU paramsSchema: null, // JSON Schema to be generated from strategy template to pass to JSOn editor constraintSchema:null, + tasksToUpdate: {}, validEditor: false, // For JSON editor validation validFields: {}, // For Form Validation observStrategyVisible: false, @@ -95,65 +96,70 @@ export class EditSchedulingUnit extends Component { */ async changeStrategy (strategyId) { const observStrategy = _.find(this.observStrategies, {'id': strategyId}); - let station_group = []; - let tasksToUpdate = {}; - const tasks = observStrategy.template.tasks; - const parameters = observStrategy.template.parameters; - let paramsOutput = {}; - let schema = { type: 'object', additionalProperties: false, - properties: {}, definitions:{} - }; - let bandPassFilter = null; - const $strategyRefs = await $RefParser.resolve(observStrategy.template); - // TODo: This schema reference resolving code has to be moved to common file and needs to rework - for (const param of parameters) { - // TODO: make parameter handling more generic, instead of task specific. - if (!param.refs[0].startsWith("#/tasks/")) { continue; } + if (observStrategy) { + let station_group = []; + let tasksToUpdate = {}; + const tasks = observStrategy.template.tasks; + const parameters = observStrategy.template.parameters; + let paramsOutput = {}; + let schema = { type: 'object', additionalProperties: false, + properties: {}, definitions:{} + }; + let bandPassFilter = null; + const $strategyRefs = await $RefParser.resolve(observStrategy.template); + // TODo: This schema reference resolving code has to be moved to common file and needs to rework + for (const param of parameters) { + // TODO: make parameter handling more generic, instead of task specific. + if (!param.refs[0].startsWith("#/tasks/")) { continue; } - let taskPaths = param.refs[0].split("/"); - const taskName = taskPaths[2]; - taskPaths = taskPaths.slice(4, taskPaths.length); - const task = tasks[taskName]; - const taskDraft = this.state.taskDrafts.find(taskD => taskD.name === taskName); - if (taskDraft) { - task.specifications_doc = taskDraft.specifications_doc; - } - if (task) { - tasksToUpdate[taskName] = taskName; - const taskTemplate = _.find(this.taskTemplates, {'name': task['specifications_template']['name']}); - if (taskTemplate.type_value==='observation' && task.specifications_doc.station_groups) { - station_group = task.specifications_doc.station_groups; - } - // Get the default Bandpass filter and pass to the editor to for frequency calculation from subband list - if (taskTemplate.type_value === 'observation' && task.specifications_doc.filter) { - bandPassFilter = task.specifications_doc.filter; - } else if (taskTemplate.type_value === 'observation' && taskTemplate.schema.properties.filter) { - bandPassFilter = taskTemplate.schema.properties.filter.default; + let taskPaths = param.refs[0].split("/"); + const taskName = taskPaths[2]; + taskPaths = taskPaths.slice(4, taskPaths.length); + const task = tasks[taskName]; + const taskDraft = this.state.taskDrafts.find(taskD => taskD.name === taskName); + if (taskDraft) { + task.specifications_doc = taskDraft.specifications_doc; } - let taskTemplateSchema = this.taskTemplateSchemas[task['specifications_template']['name']]; - if (!taskTemplateSchema) { - taskTemplateSchema = _.find(this.taskTemplates, {'name': task['specifications_template']['name']}).schema; - taskTemplateSchema = await UtilService.resolveSchema(_.cloneDeep(taskTemplateSchema)); - this.taskTemplateSchemas[task['specifications_template']['name']] = taskTemplateSchema; - } - schema.definitions = {...schema.definitions, ...taskTemplateSchema.definitions}; - taskPaths.reverse(); - const paramProp = await ParserUtility.getParamProperty($strategyRefs, taskPaths, taskTemplateSchema, param); - schema.properties[param.name] = _.cloneDeep(paramProp); - if (schema.properties[param.name]) { - schema.properties[param.name].title = param.name; - schema.properties[param.name].default = $strategyRefs.get(param.refs[0]); - paramsOutput[param.name] = schema.properties[param.name].default; + if (task) { + tasksToUpdate[taskName] = taskName; + const taskTemplate = _.find(this.taskTemplates, {'name': task['specifications_template']['name']}); + if (taskTemplate.type_value==='observation' && task.specifications_doc.station_groups) { + station_group = task.specifications_doc.station_groups; + } + // Get the default Bandpass filter and pass to the editor to for frequency calculation from subband list + if (taskTemplate.type_value === 'observation' && task.specifications_doc.filter) { + bandPassFilter = task.specifications_doc.filter; + } else if (taskTemplate.type_value === 'observation' && taskTemplate.schema.properties.filter) { + bandPassFilter = taskTemplate.schema.properties.filter.default; + } + let taskTemplateSchema = this.taskTemplateSchemas[task['specifications_template']['name']]; + if (!taskTemplateSchema) { + taskTemplateSchema = _.find(this.taskTemplates, {'name': task['specifications_template']['name']}).schema; + taskTemplateSchema = await UtilService.resolveSchema(_.cloneDeep(taskTemplateSchema)); + this.taskTemplateSchemas[task['specifications_template']['name']] = taskTemplateSchema; + } + schema.definitions = {...schema.definitions, ...taskTemplateSchema.definitions}; + taskPaths.reverse(); + const paramProp = await ParserUtility.getParamProperty($strategyRefs, taskPaths, taskTemplateSchema, param); + schema.properties[param.name] = _.cloneDeep(paramProp); + if (schema.properties[param.name]) { + schema.properties[param.name].title = param.name; + schema.properties[param.name].default = $strategyRefs.get(param.refs[0]); + paramsOutput[param.name] = schema.properties[param.name].default; + } } } - } - this.setState({observStrategy: observStrategy, paramsSchema: schema, paramsOutput: paramsOutput, - bandPassFilter:bandPassFilter, tasksToUpdate: tasksToUpdate}); - // this.setState({observStrategy: observStrategy, paramsSchema: _.cloneDeep(schema), paramsOutput: paramsOutput, stationGroup: station_group, isDirty: true}); + this.setState({observStrategy: observStrategy, paramsSchema: schema, paramsOutput: paramsOutput, + bandPassFilter:bandPassFilter, tasksToUpdate: tasksToUpdate}); + // this.setState({observStrategy: observStrategy, paramsSchema: _.cloneDeep(schema), paramsOutput: paramsOutput, stationGroup: station_group, isDirty: true}); - // Function called to clear the JSON Editor fields and reload with new schema - if (this.state.editorFunction) { - this.state.editorFunction(); + // Function called to clear the JSON Editor fields and reload with new schema + if (this.state.editorFunction) { + this.state.editorFunction(); + } + } else { + this.setState({observStrategy: null}); + this.setEditorOutput(null, []); } } @@ -181,13 +187,11 @@ export class EditSchedulingUnit extends Component { responses[4].project = this.schedulingSets.find(i => i.id === responses[4].scheduling_set_id).project_id; this.setState({ schedulingUnit: responses[4], taskDrafts: responses[5].data.results, observStrategyVisible: responses[4].observation_strategy_template_id?true:false }); - if (responses[4].observation_strategy_template_id) { - this.changeStrategy(responses[4].observation_strategy_template_id); - const targetObservation = responses[5].data.results.find(task => {return task.template.type_value === 'observation' && task.specifications_doc.station_groups?true:false}); - this.setState({ - stationGroup: targetObservation?targetObservation.specifications_doc.station_groups:[] - }); - } + this.changeStrategy(responses[4].observation_strategy_template_id); + const targetObservation = responses[5].data.results.find(task => {return task.template.type_value === 'observation' && task.specifications_doc.station_groups?true:false}); + this.setState({ + stationGroup: targetObservation?targetObservation.specifications_doc.station_groups:[] + }); if (this.state.schedulingUnit.project) { const projectSchedSets = _.filter(this.schedulingSets, {'project_id': this.state.schedulingUnit.project}); this.setState({isLoading: false, schedulingSets: projectSchedSets}); @@ -336,75 +340,74 @@ export class EditSchedulingUnit extends Component { * Function to create Scheduling unit */ async saveSchedulingUnit() { - if (this.state.schedulingUnit.observation_strategy_template_id) { - const constStrategy = _.cloneDeep(this.state.constraintParamsOutput); - if (constStrategy.scheduler === 'online') { - // For deleting property - delete constStrategy.time.at; - } - if (!constStrategy.time.after) { - delete constStrategy.time.after; + const constStrategy = _.cloneDeep(this.state.constraintParamsOutput); + if (constStrategy.scheduler === 'online') { + // For deleting property + delete constStrategy.time.at; } - if (!constStrategy.time.before) { - delete constStrategy.time.before; - } - for (let type in constStrategy.time) { - if (constStrategy.time[type] && constStrategy.time[type].length) { - if (typeof constStrategy.time[type] === 'string') { - constStrategy.time[type] = `${moment(constStrategy.time[type]).format("YYYY-MM-DDTHH:mm:ss.SSSSS", { trim: false })}Z`; - } else { - constStrategy.time[type].forEach(time => { - for (let key in time) { - time[key] = `${moment(time[key] ).format("YYYY-MM-DDTHH:mm:ss.SSSSS", { trim: false })}Z`; - } - - }) - } + if (!constStrategy.time.after) { + delete constStrategy.time.after; + } + if (!constStrategy.time.before) { + delete constStrategy.time.before; + } + for (let type in constStrategy.time) { + if (constStrategy.time[type] && constStrategy.time[type].length) { + if (typeof constStrategy.time[type] === 'string') { + constStrategy.time[type] = `${moment(constStrategy.time[type]).format("YYYY-MM-DDTHH:mm:ss.SSSSS", { trim: false })}Z`; + } else { + constStrategy.time[type].forEach(time => { + for (let key in time) { + time[key] = `${moment(time[key] ).format("YYYY-MM-DDTHH:mm:ss.SSSSS", { trim: false })}Z`; + } + + }) } } - /* for (let type in constStrategy.sky.transit_offset) { - constStrategy.sky.transit_offset[type] = constStrategy.sky.transit_offset[type] * 60; - }*/ - UnitConversion.degreeToRadians(constStrategy.sky); - let observStrategy = _.cloneDeep(this.state.observStrategy); + } + /* for (let type in constStrategy.sky.transit_offset) { + constStrategy.sky.transit_offset[type] = constStrategy.sky.transit_offset[type] * 60; + }*/ + UnitConversion.degreeToRadians(constStrategy.sky); + let observStrategy = null; + if (this.state.observStrategy) { + observStrategy = _.cloneDeep(this.state.observStrategy); const $refs = await $RefParser.resolve(observStrategy.template); observStrategy.template.parameters.forEach(async(param, index) => { $refs.set(observStrategy.template.parameters[index]['refs'][0], this.state.paramsOutput[param.name]); }); - const schUnit = { ...this.state.schedulingUnit }; - schUnit.scheduling_constraints_doc = constStrategy; - //station - const station_groups = []; - (this.state.selectedStations || []).forEach(key => { - let station_group = {}; - const stations = this.state[key] ? this.state[key].stations : []; - const max_nr_missing = parseInt(this.state[key] ? (this.state[key].missing_StationFields || 0) : 0); - station_group = { - stations, - max_nr_missing - }; - station_groups.push(station_group); - }); - this.state.customSelectedStations.forEach(station => { - station_groups.push({ - stations: station.stations, - max_nr_missing: parseInt(station.max_nr_missing) - }); - }); - let schedulingUnit = this.state.schedulingUnit; - schUnit.priority_rank = schUnit.priority_rank === ''?0:schUnit.priority_rank.toFixed(4); - schedulingUnit = await ScheduleService.updateSUDraftFromObservStrategy(observStrategy,schUnit,this.state.taskDrafts, this.state.tasksToUpdate, station_groups); - if (!schedulingUnit.error) { - this.growl.show({severity: 'success', summary: 'Success', detail: 'Scheduling Unit and Tasks updated successfully!'}); - this.props.history.push({ - pathname: `/schedulingunit/view/draft/${this.props.match.params.id}`, - }); - } else { - this.growl.show({severity: 'error', summary: 'Error Occured', detail: schedulingUnit.message || 'Unable to Update Scheduling Unit/Tasks'}); - } - } else { - this.growl.show({severity: 'error', summary: 'Error Occured', detail: 'Template Missing.'}); } + const schUnit = { ...this.state.schedulingUnit }; + schUnit.scheduling_constraints_doc = constStrategy; + //station + const station_groups = []; + (this.state.selectedStations || []).forEach(key => { + let station_group = {}; + const stations = this.state[key] ? this.state[key].stations : []; + const max_nr_missing = parseInt(this.state[key] ? (this.state[key].missing_StationFields || 0) : 0); + station_group = { + stations, + max_nr_missing + }; + station_groups.push(station_group); + }); + this.state.customSelectedStations.forEach(station => { + station_groups.push({ + stations: station.stations, + max_nr_missing: parseInt(station.max_nr_missing) + }); + }); + let schedulingUnit = this.state.schedulingUnit; + schUnit.priority_rank = schUnit.priority_rank === ''?0:schUnit.priority_rank.toFixed(4); + schedulingUnit = await ScheduleService.updateSUDraftFromObservStrategy(observStrategy,schUnit,this.state.taskDrafts, this.state.tasksToUpdate, station_groups); + if (!schedulingUnit.error) { + this.growl.show({severity: 'success', summary: 'Success', detail: 'Scheduling Unit and Tasks updated successfully!'}); + this.props.history.push({ + pathname: `/schedulingunit/view/draft/${this.props.match.params.id}`, + }); + } else { + this.growl.show({severity: 'error', summary: 'Error Occured', detail: schedulingUnit.message || 'Unable to Update Scheduling Unit/Tasks'}); + } this.setState({isDirty: false}); publish('edit-dirty', false); @@ -594,9 +597,10 @@ export class EditSchedulingUnit extends Component { {this.state.observStrategy? this.state.observStrategy.description : "Select Observation Strategy"} </label> </div> + <div className="col-lg-1 col-md-1 col-sm-12"></div> </> } - <div className="col-lg-1 col-md-1 col-sm-12"></div> + <label htmlFor="project" className="col-lg-2 col-md-2 col-sm-12">Prevent Automatic Deletion</label> <div className="col-lg-3 col-md-3 col-sm-12" data-testid="project" > <Checkbox inputId="trigger" role="trigger" diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js index db19a4c08514316b44cf1fa50a3343be27a11731..acfc903326428e02b389d04247d1652e9c75e723 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js @@ -315,7 +315,7 @@ export class TimelineView extends Component { suBlueprint.duration = UnitConverter.getSecsToHHmmss(suBlueprint.duration); suBlueprint.workflowStatus = this.timelineCommonUtils.getWorkflowStatus(suBlueprint); suBlueprint.task_content = ""; - suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template.name; + suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template?suBlueprint.draft.observation_strategy_template.name:null; suBlueprint.tasks = suBlueprint.task_blueprints; suBlueprint.stationGroupCount = this.timelineCommonUtils.getSUStationGroupCount(suBlueprint).counts; for (let task of suBlueprint.tasks) { @@ -1156,7 +1156,7 @@ export class TimelineView extends Component { suBlueprint.duration = UnitConverter.getSecsToHHmmss(suBlueprint.duration); suBlueprint.workflowStatus = this.timelineCommonUtils.getWorkflowStatus(suBlueprint); suBlueprint.task_content = ""; - suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template.name; + suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template?suBlueprint.draft.observation_strategy_template.name:null; suBlueprint.tasks = suBlueprint.task_blueprints; suBlueprint.stationGroupCount = this.timelineCommonUtils.getSUStationGroupCount(suBlueprint).counts; _.remove(suBlueprints, function (suB) { return suB.id === id }); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js index 5c97d3c7250de69c2b59bbc4280cf328aa871eac..ab192791713e44f92548559c48a891b558bbf9ac 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js @@ -261,7 +261,7 @@ export class WeekTimelineView extends Component { suBlueprint.duration = UnitConverter.getSecsToHHmmss(suBlueprint.duration); suBlueprint.workflowStatus = this.timelineCommonUtils.getWorkflowStatus(suBlueprint); suBlueprint.task_content = ""; - suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template.name; + suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template?suBlueprint.draft.observation_strategy_template.name:null; suBlueprint.tasks = suBlueprint.task_blueprints; suBlueprint.stationGroupCount = this.timelineCommonUtils.getSUStationGroupCount(suBlueprint).counts; // Add Subtask Id as control id for task if subtask is primary. Also add antenna_set & band prpoerties to the task object. @@ -752,7 +752,7 @@ export class WeekTimelineView extends Component { suBlueprint.duration = UnitConverter.getSecsToHHmmss(suBlueprint.duration); suBlueprint.workflowStatus = this.timelineCommonUtils.getWorkflowStatus(suBlueprint); suBlueprint.task_content = ""; - suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template.name; + suBlueprint.observ_template_name = suBlueprint.draft.observation_strategy_template?suBlueprint.draft.observation_strategy_template.name:null; suBlueprint.tasks = suBlueprint.task_blueprints; suBlueprint.stationGroupCount = this.timelineCommonUtils.getSUStationGroupCount(suBlueprint).counts; // Add Subtask Id as control id for task if subtask type us control. Also add antenna_set & band prpoerties to the task object.