From 8ff7659fc5d41b379fb2643634fe59e65092ef6e Mon Sep 17 00:00:00 2001 From: Luke Simons <luke.simons@epfl.ch> Date: Thu, 24 Apr 2025 12:03:34 +0200 Subject: [PATCH 1/5] Added get_mds_node_info.m and tcv_get_ids_dataset_description.m --- .../tcv_get_ids_dataset_description.m | 90 +++++++++++++++++++ matlab/get_mds_node_info.m | 44 +++++++++ 2 files changed, 134 insertions(+) create mode 100644 matlab/TCV_IMAS/tcv_get_ids_dataset_description.m create mode 100644 matlab/get_mds_node_info.m diff --git a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m new file mode 100644 index 00000000..8b49ae50 --- /dev/null +++ b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m @@ -0,0 +1,90 @@ +function [ids_dataset_description,ids_dataset_description_description] = ... + tcv_get_ids_dataset_description(shot, ids_dataset_description_empty, gdat_params,varargin) +% +% [ids_dataset_description,ids_dataset_description_description] = ... +% tcv_get_ids_dataset_description(shot, ids_dataset_description_empty,varargin); +% +% Get the TCV IMAS dataset_description data +% +% ids_dataset_description_empty should at least be the empty dataset_description ids structure +% in input +% +% gdat_params: gdat_data.gdat_params to get all params passed from original +% call, in particular error_bar options +% +% Date: 24/04/25 +% Author: L. Simons + +% Initialise structure with default ids_properties +% shot=70777; gdat_params=[]; varargin={}; +% aa=gdat([],'ids','source','dataset_description'); ids_dataset_description_empty=aa.dataset_description; +if exist('gdat_params') + [ids_dataset_description, ~] = tcv_ids_headpart(shot, ids_dataset_description_empty, ... + 'dataset_description','homogeneous_time',1,'gdat_params',gdat_params, ... + varargin{:}); +else + [ids_dataset_description, ~] = tcv_ids_headpart(shot,ids_dataset_description_empty,'dataset_description','homogeneous_time',0,varargin{:}); +end + +ids_dataset_description_description = struct(); + +% homogenous_time=2 , only static and constant information +ids_dataset_description.ids_properties.homogeneous_time=2; + +% Get username +username = getenv('USERNAME'); % Works on Windows +if isempty(username) + username = getenv('USER'); % Works on Unix/Linux/Mac +end + +% Define uri +backend='mdsplus'; +run=1; +imas_version_number=getenv('IMAS_VERSION'); +version=num2str(imas_version_number(1)); +uri = sprintf('imas:%s?user=%s;shot=%d;run=%d;database=%s;version=%s', ... + backend, username, shot, run, database,version); +ids_dataset_description.uri=uri; + +% Define type +% FIXME: Not sure what the condition should be here... To be discussed +if strcmp(gdat_params.data_request,'ids') + ids_dataset_description.type.name='experimental'; + ids_dataset_description.type.index=1; + ids_dataset_description.type.description='Data coming from an experiment'; +else + ids_dataset_description.type.name='simulation'; + ids_dataset_description.type.index=2; + ids_dataset_description.type.description='Data coming from a simulation'; +end + +% Define data_entry +ids_dataset_description.machine='tcv'; +ids_dataset_description.pulse=shot; + +% Attempt to fill information about pulse time +% FIXME: How to get pulse_time_end? Simply = pulse_time_begin + X seconds? +[pulse_time_begin,pulse_time_begin_epoch]= ... + get_mds_node_info('\VSYSTEM:TIMERS.VALUES',shot); +ids_dataset_description.pulse_time_begin=pulse_time_begin; +ids_dataset_description.pulse_time_begin_epoch.seconds=pulse_time_begin_epoch; +ids_dataset_description.pulse_time_begin_epoch.nanoseconds=pulse_time_begin_epoch.*1e9; +% ids_dataset_description.pulse_time_end_epoch.seconds= +% ids_dataset_description.pulse_time_end_epoch.nanoseconds= +% ids_dataset_description.pulse_processing_time_begin=node_time + + +%% Simulation metadata +% FIXME: How do we hope to get this information? +% ids_dataset_description.simulation.comment_before=? +% ids_dataset_description.simulation.comment_after=? +% ids_dataset_description.simulation.time_begin=? +% ids_dataset_description.simulation.time_step=? +% ids_dataset_description.simulation.time_end=? +% ids_dataset_description.simulation.time_restart=? +% ids_dataset_description.simulation.time_current=? +% ids_dataset_description.simulation.time_begun=? +% ids_dataset_description.simulation.time_ended=? +% ids_dataset_description.simulation.time_workflow=? + +end diff --git a/matlab/get_mds_node_info.m b/matlab/get_mds_node_info.m new file mode 100644 index 00000000..6c0ecc1c --- /dev/null +++ b/matlab/get_mds_node_info.m @@ -0,0 +1,44 @@ +function [node_time, node_epoch_time, node_owner] = get_mds_node_info(node_str, shot) +%GET_MDS_NODE_INFO Retrieves insertion time and owner of a node in MDSplus +% +% [node_time, node_owner] = GET_MDS_NODE_INFO(node_str, shot) +% Inputs: +% node_str - String path to the MDSplus node +% (e.g. '\\RESULTS::CXRS_001:TI') +% shot - Shot number to open +% +% Outputs: +% node_time - Time the node data was inserted +% node_owner - (Optional) Owner info of the node + + % Open the shot + mdsopen('tcv_shot',shot); + + try + % Time inserted + tdi_time = sprintf('times(getnci("%s","TIME_INSERTED"))', node_str); + mds_node_time = mdsvalue(tdi_time); + % Convert the timestamp (returned as a string) to MATLAB datetime + dt = datetime(mds_node_time, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SSSSSS', 'TimeZone', 'UTC'); + % Format it to ISO 8601 with Zulu (UTC) time + time_str = datestr(dt, 'yyyy-mm-ddTHH:MM:SS'); + node_time = [time_str 'Z']; + % Convert to Unix Epoch time (seconds since Jan 1, 1970 UTC) + node_epoch_time = posixtime(datetime(mds_node_time, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SSSSSS', 'TimeZone', 'UTC')); + + + % Owner + tdi_owner = sprintf('owner_ascii("%s")', node_str); + node_owner = mdsvalue(tdi_owner); + + catch + warning('Failed to read time of node, returning empty strings..'); + node_time=''; + node_owner=''; + mdsclose; + end + + % Always close MDS connection + mdsclose; + +end \ No newline at end of file -- GitLab From d106e4b8d29580c35f629ec0a5a6a0968300b135 Mon Sep 17 00:00:00 2001 From: Luke Simons <luke.simons@epfl.ch> Date: Fri, 25 Apr 2025 10:45:44 +0200 Subject: [PATCH 2/5] Changed comments. Added calculation for epoch time in ns --- .../tcv_get_ids_dataset_description.m | 4 ++-- matlab/get_mds_node_info.m | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m index 8b49ae50..3efe0d0d 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m +++ b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m @@ -64,11 +64,11 @@ ids_dataset_description.pulse=shot; % Attempt to fill information about pulse time % FIXME: How to get pulse_time_end? Simply = pulse_time_begin + X seconds? -[pulse_time_begin,pulse_time_begin_epoch]= ... +[pulse_time_begin,pulse_time_begin_epoch,pulse_time_begin_epoch_ns]= ... get_mds_node_info('\VSYSTEM:TIMERS.VALUES',shot); ids_dataset_description.pulse_time_begin=pulse_time_begin; ids_dataset_description.pulse_time_begin_epoch.seconds=pulse_time_begin_epoch; -ids_dataset_description.pulse_time_begin_epoch.nanoseconds=pulse_time_begin_epoch.*1e9; +ids_dataset_description.pulse_time_begin_epoch.nanoseconds=pulse_time_begin_epoch_ns; % ids_dataset_description.pulse_time_end_epoch.seconds= % ids_dataset_description.pulse_time_end_epoch.nanoseconds= % ids_dataset_description.pulse_processing_time_begin=node_time diff --git a/matlab/get_mds_node_info.m b/matlab/get_mds_node_info.m index 6c0ecc1c..b832deb3 100644 --- a/matlab/get_mds_node_info.m +++ b/matlab/get_mds_node_info.m @@ -1,15 +1,20 @@ -function [node_time, node_epoch_time, node_owner] = get_mds_node_info(node_str, shot) -%GET_MDS_NODE_INFO Retrieves insertion time and owner of a node in MDSplus +function [node_time, node_epoch_time, node_epoch_time_ns, node_owner] = get_mds_node_info(node_str, shot) +% [node_time, node_epoch_time, node_owner] = +% get_mds_node_info(node_str, shot) +% +% Retrieves insertion time and owner of a node in MDSplus % -% [node_time, node_owner] = GET_MDS_NODE_INFO(node_str, shot) % Inputs: -% node_str - String path to the MDSplus node +% node_str - String, path to the MDSplus node % (e.g. '\\RESULTS::CXRS_001:TI') -% shot - Shot number to open +% shot - Numeric, Shot number to open % % Outputs: -% node_time - Time the node data was inserted -% node_owner - (Optional) Owner info of the node +% node_time - Numeric, Time the node data was inserted +% node_owner - String, (Optional) Owner info of the node +% +% Date: 20/09/24 +% Author: L. Simons % Open the shot mdsopen('tcv_shot',shot); @@ -25,7 +30,7 @@ function [node_time, node_epoch_time, node_owner] = get_mds_node_info(node_str, node_time = [time_str 'Z']; % Convert to Unix Epoch time (seconds since Jan 1, 1970 UTC) node_epoch_time = posixtime(datetime(mds_node_time, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SSSSSS', 'TimeZone', 'UTC')); - + node_epoch_time_ns=mod(second(dt),1)*1e9; % Owner tdi_owner = sprintf('owner_ascii("%s")', node_str); -- GitLab From be2864f69f95663a5f2276c68d0d9a6c6b452c6f Mon Sep 17 00:00:00 2001 From: Luke Simons <luke.simons@epfl.ch> Date: Thu, 24 Apr 2025 12:03:34 +0200 Subject: [PATCH 3/5] Added get_mds_node_info.m and tcv_get_ids_dataset_description.m --- .../tcv_get_ids_dataset_description.m | 90 +++++++++++++++++++ matlab/get_mds_node_info.m | 44 +++++++++ 2 files changed, 134 insertions(+) create mode 100644 matlab/TCV_IMAS/tcv_get_ids_dataset_description.m create mode 100644 matlab/get_mds_node_info.m diff --git a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m new file mode 100644 index 00000000..8b49ae50 --- /dev/null +++ b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m @@ -0,0 +1,90 @@ +function [ids_dataset_description,ids_dataset_description_description] = ... + tcv_get_ids_dataset_description(shot, ids_dataset_description_empty, gdat_params,varargin) +% +% [ids_dataset_description,ids_dataset_description_description] = ... +% tcv_get_ids_dataset_description(shot, ids_dataset_description_empty,varargin); +% +% Get the TCV IMAS dataset_description data +% +% ids_dataset_description_empty should at least be the empty dataset_description ids structure +% in input +% +% gdat_params: gdat_data.gdat_params to get all params passed from original +% call, in particular error_bar options +% +% Date: 24/04/25 +% Author: L. Simons + +% Initialise structure with default ids_properties +% shot=70777; gdat_params=[]; varargin={}; +% aa=gdat([],'ids','source','dataset_description'); ids_dataset_description_empty=aa.dataset_description; +if exist('gdat_params') + [ids_dataset_description, ~] = tcv_ids_headpart(shot, ids_dataset_description_empty, ... + 'dataset_description','homogeneous_time',1,'gdat_params',gdat_params, ... + varargin{:}); +else + [ids_dataset_description, ~] = tcv_ids_headpart(shot,ids_dataset_description_empty,'dataset_description','homogeneous_time',0,varargin{:}); +end + +ids_dataset_description_description = struct(); + +% homogenous_time=2 , only static and constant information +ids_dataset_description.ids_properties.homogeneous_time=2; + +% Get username +username = getenv('USERNAME'); % Works on Windows +if isempty(username) + username = getenv('USER'); % Works on Unix/Linux/Mac +end + +% Define uri +backend='mdsplus'; +run=1; +imas_version_number=getenv('IMAS_VERSION'); +version=num2str(imas_version_number(1)); +uri = sprintf('imas:%s?user=%s;shot=%d;run=%d;database=%s;version=%s', ... + backend, username, shot, run, database,version); +ids_dataset_description.uri=uri; + +% Define type +% FIXME: Not sure what the condition should be here... To be discussed +if strcmp(gdat_params.data_request,'ids') + ids_dataset_description.type.name='experimental'; + ids_dataset_description.type.index=1; + ids_dataset_description.type.description='Data coming from an experiment'; +else + ids_dataset_description.type.name='simulation'; + ids_dataset_description.type.index=2; + ids_dataset_description.type.description='Data coming from a simulation'; +end + +% Define data_entry +ids_dataset_description.machine='tcv'; +ids_dataset_description.pulse=shot; + +% Attempt to fill information about pulse time +% FIXME: How to get pulse_time_end? Simply = pulse_time_begin + X seconds? +[pulse_time_begin,pulse_time_begin_epoch]= ... + get_mds_node_info('\VSYSTEM:TIMERS.VALUES',shot); +ids_dataset_description.pulse_time_begin=pulse_time_begin; +ids_dataset_description.pulse_time_begin_epoch.seconds=pulse_time_begin_epoch; +ids_dataset_description.pulse_time_begin_epoch.nanoseconds=pulse_time_begin_epoch.*1e9; +% ids_dataset_description.pulse_time_end_epoch.seconds= +% ids_dataset_description.pulse_time_end_epoch.nanoseconds= +% ids_dataset_description.pulse_processing_time_begin=node_time + + +%% Simulation metadata +% FIXME: How do we hope to get this information? +% ids_dataset_description.simulation.comment_before=? +% ids_dataset_description.simulation.comment_after=? +% ids_dataset_description.simulation.time_begin=? +% ids_dataset_description.simulation.time_step=? +% ids_dataset_description.simulation.time_end=? +% ids_dataset_description.simulation.time_restart=? +% ids_dataset_description.simulation.time_current=? +% ids_dataset_description.simulation.time_begun=? +% ids_dataset_description.simulation.time_ended=? +% ids_dataset_description.simulation.time_workflow=? + +end diff --git a/matlab/get_mds_node_info.m b/matlab/get_mds_node_info.m new file mode 100644 index 00000000..6c0ecc1c --- /dev/null +++ b/matlab/get_mds_node_info.m @@ -0,0 +1,44 @@ +function [node_time, node_epoch_time, node_owner] = get_mds_node_info(node_str, shot) +%GET_MDS_NODE_INFO Retrieves insertion time and owner of a node in MDSplus +% +% [node_time, node_owner] = GET_MDS_NODE_INFO(node_str, shot) +% Inputs: +% node_str - String path to the MDSplus node +% (e.g. '\\RESULTS::CXRS_001:TI') +% shot - Shot number to open +% +% Outputs: +% node_time - Time the node data was inserted +% node_owner - (Optional) Owner info of the node + + % Open the shot + mdsopen('tcv_shot',shot); + + try + % Time inserted + tdi_time = sprintf('times(getnci("%s","TIME_INSERTED"))', node_str); + mds_node_time = mdsvalue(tdi_time); + % Convert the timestamp (returned as a string) to MATLAB datetime + dt = datetime(mds_node_time, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SSSSSS', 'TimeZone', 'UTC'); + % Format it to ISO 8601 with Zulu (UTC) time + time_str = datestr(dt, 'yyyy-mm-ddTHH:MM:SS'); + node_time = [time_str 'Z']; + % Convert to Unix Epoch time (seconds since Jan 1, 1970 UTC) + node_epoch_time = posixtime(datetime(mds_node_time, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SSSSSS', 'TimeZone', 'UTC')); + + + % Owner + tdi_owner = sprintf('owner_ascii("%s")', node_str); + node_owner = mdsvalue(tdi_owner); + + catch + warning('Failed to read time of node, returning empty strings..'); + node_time=''; + node_owner=''; + mdsclose; + end + + % Always close MDS connection + mdsclose; + +end \ No newline at end of file -- GitLab From 7847aacd7f245ca68f40b614747104a9ab38235d Mon Sep 17 00:00:00 2001 From: Luke Simons <luke.simons@epfl.ch> Date: Fri, 25 Apr 2025 10:45:44 +0200 Subject: [PATCH 4/5] Changed comments. Added calculation for epoch time in ns --- .../tcv_get_ids_dataset_description.m | 4 ++-- matlab/get_mds_node_info.m | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m index 8b49ae50..3efe0d0d 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m +++ b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m @@ -64,11 +64,11 @@ ids_dataset_description.pulse=shot; % Attempt to fill information about pulse time % FIXME: How to get pulse_time_end? Simply = pulse_time_begin + X seconds? -[pulse_time_begin,pulse_time_begin_epoch]= ... +[pulse_time_begin,pulse_time_begin_epoch,pulse_time_begin_epoch_ns]= ... get_mds_node_info('\VSYSTEM:TIMERS.VALUES',shot); ids_dataset_description.pulse_time_begin=pulse_time_begin; ids_dataset_description.pulse_time_begin_epoch.seconds=pulse_time_begin_epoch; -ids_dataset_description.pulse_time_begin_epoch.nanoseconds=pulse_time_begin_epoch.*1e9; +ids_dataset_description.pulse_time_begin_epoch.nanoseconds=pulse_time_begin_epoch_ns; % ids_dataset_description.pulse_time_end_epoch.seconds= % ids_dataset_description.pulse_time_end_epoch.nanoseconds= % ids_dataset_description.pulse_processing_time_begin=node_time diff --git a/matlab/get_mds_node_info.m b/matlab/get_mds_node_info.m index 6c0ecc1c..b832deb3 100644 --- a/matlab/get_mds_node_info.m +++ b/matlab/get_mds_node_info.m @@ -1,15 +1,20 @@ -function [node_time, node_epoch_time, node_owner] = get_mds_node_info(node_str, shot) -%GET_MDS_NODE_INFO Retrieves insertion time and owner of a node in MDSplus +function [node_time, node_epoch_time, node_epoch_time_ns, node_owner] = get_mds_node_info(node_str, shot) +% [node_time, node_epoch_time, node_owner] = +% get_mds_node_info(node_str, shot) +% +% Retrieves insertion time and owner of a node in MDSplus % -% [node_time, node_owner] = GET_MDS_NODE_INFO(node_str, shot) % Inputs: -% node_str - String path to the MDSplus node +% node_str - String, path to the MDSplus node % (e.g. '\\RESULTS::CXRS_001:TI') -% shot - Shot number to open +% shot - Numeric, Shot number to open % % Outputs: -% node_time - Time the node data was inserted -% node_owner - (Optional) Owner info of the node +% node_time - Numeric, Time the node data was inserted +% node_owner - String, (Optional) Owner info of the node +% +% Date: 20/09/24 +% Author: L. Simons % Open the shot mdsopen('tcv_shot',shot); @@ -25,7 +30,7 @@ function [node_time, node_epoch_time, node_owner] = get_mds_node_info(node_str, node_time = [time_str 'Z']; % Convert to Unix Epoch time (seconds since Jan 1, 1970 UTC) node_epoch_time = posixtime(datetime(mds_node_time, 'InputFormat', 'dd-MMM-yyyy HH:mm:ss.SSSSSS', 'TimeZone', 'UTC')); - + node_epoch_time_ns=mod(second(dt),1)*1e9; % Owner tdi_owner = sprintf('owner_ascii("%s")', node_str); -- GitLab From 4d3c10132fcc3271518f3f951c92183491de05d1 Mon Sep 17 00:00:00 2001 From: Luke Simons <luke.simons@epfl.ch> Date: Tue, 24 Jun 2025 11:46:55 +0200 Subject: [PATCH 5/5] Added additional argument for backend. Default value of mdsplus --- matlab/TCV_IMAS/tcv_get_ids_dataset_description.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m index 3efe0d0d..456b9bb4 100644 --- a/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m +++ b/matlab/TCV_IMAS/tcv_get_ids_dataset_description.m @@ -1,5 +1,5 @@ function [ids_dataset_description,ids_dataset_description_description] = ... - tcv_get_ids_dataset_description(shot, ids_dataset_description_empty, gdat_params,varargin) + tcv_get_ids_dataset_description(shot, ids_dataset_description_empty, gdat_params, backend, varargin) % % [ids_dataset_description,ids_dataset_description_description] = ... % tcv_get_ids_dataset_description(shot, ids_dataset_description_empty,varargin); @@ -38,7 +38,11 @@ if isempty(username) end % Define uri -backend='mdsplus'; + +if isempty(backend) + backend='mdsplus'; +end + run=1; imas_version_number=getenv('IMAS_VERSION'); version=num2str(imas_version_number(1)); -- GitLab