diff --git a/kic-script-gen/src/back_end/data_model.rs b/kic-script-gen/src/back_end/data_model.rs index 9a5f7e3..1a61c79 100644 --- a/kic-script-gen/src/back_end/data_model.rs +++ b/kic-script-gen/src/back_end/data_model.rs @@ -154,6 +154,8 @@ impl DataModel { // remove unused and invalid channels sweep_model.sweep_config.remove_unused_invalid_channels(); + sweep_model.sweep_config.evaluate(); + self.sweep_model = sweep_model.clone(); self.serialize_sweep_model( &sweep_model, diff --git a/script-gen-manager/src/instr_metadata/base_metadata.rs b/script-gen-manager/src/instr_metadata/base_metadata.rs index 48176b9..aaac93a 100644 --- a/script-gen-manager/src/instr_metadata/base_metadata.rs +++ b/script-gen-manager/src/instr_metadata/base_metadata.rs @@ -57,6 +57,8 @@ impl BaseMetadata { pub const RATE_NORMAL: &'static str = "Normal"; pub const RATE_FAST: &'static str = "Fast"; + pub const UNDEFINED: &'static str = "UNDEFINED"; + pub const UNIT_VOLTS: &'static str = "V"; pub const UNIT_AMPERES: &'static str = "A"; pub const UNIT_SECONDS: &'static str = "s"; @@ -79,8 +81,8 @@ impl BaseMetadata { ], ); - names.insert("sense=Two-wire", "SENSE_LOCAL"); - names.insert("sense=Four-wire", "SENSE_REMOTE"); + names.insert("sense=Two-wire", "SENSE_2WIRE"); + names.insert("sense=Four-wire", "SENSE_4WIRE"); BaseMetadata { options, diff --git a/script-gen-manager/src/instr_metadata/msmu60_metadata.rs b/script-gen-manager/src/instr_metadata/msmu60_metadata.rs index 389dee9..fa7217d 100644 --- a/script-gen-manager/src/instr_metadata/msmu60_metadata.rs +++ b/script-gen-manager/src/instr_metadata/msmu60_metadata.rs @@ -1,6 +1,5 @@ use crate::model::{ - chan_data::region_map::RegionMapMetadata, - sweep_data::{number_limit::NumberLimit, parameters::ParameterFloat}, + chan_data::region_map::RegionMapMetadata, sweep_data::number_limit::NumberLimit, }; use super::base_metadata::{BaseMetadata, Metadata}; diff --git a/script-gen-manager/src/model/chan_data/start_stop_channel.rs b/script-gen-manager/src/model/chan_data/start_stop_channel.rs index 81c6106..7c23546 100644 --- a/script-gen-manager/src/model/chan_data/start_stop_channel.rs +++ b/script-gen-manager/src/model/chan_data/start_stop_channel.rs @@ -1,5 +1,3 @@ -use core::num; - use serde::{Deserialize, Serialize}; use super::default_channel::CommonChanAttributes; diff --git a/script-gen-manager/src/script_component/sweep.rs b/script-gen-manager/src/script_component/sweep.rs index e9ae175..b4b4b45 100644 --- a/script-gen-manager/src/script_component/sweep.rs +++ b/script-gen-manager/src/script_component/sweep.rs @@ -1,10 +1,14 @@ use std::{any::Any, collections::HashMap}; use crate::{ + device::DeviceType, instr_metadata::base_metadata::BaseMetadata, model::{ chan_data::channel_range::ChannelRange, - sweep_data::{parameters::ParameterFloat, sweep_config::SweepConfig}, + sweep_data::{ + parameters::{ParameterFloat, ParameterString}, + sweep_config::SweepConfig, + }, }, }; @@ -79,9 +83,9 @@ impl SweepModel { } } - fn define_bias_channels(&mut self, sweep_config: &SweepConfig) { + fn define_bias_channels(&mut self, bias_config: &SweepConfig) { let mut index = 1; - for bias_channel in sweep_config.bias_channels.iter() { + for bias_channel in bias_config.bias_channels.iter() { let instr_name = format!("bias{index}"); self.attributes.bias_names.push(instr_name.clone()); @@ -106,29 +110,32 @@ impl SweepModel { ); self.val_replacement_map.insert( - instr_name.clone() + ":SFUNCTION", + instr_name.clone() + ":MODEL-TYPE", bias_channel .common_chan_attributes - .source_function - .value - .to_lowercase() - .clone(), - ); - self.val_replacement_map.insert( - instr_name.clone() + ":SRANGE", - self.format_range(bias_channel.common_chan_attributes.source_range.clone()), + .device + .device_type + .to_string(), ); - self.val_replacement_map.insert( - instr_name.clone() + ":MFUNCTION", - bias_channel - .common_chan_attributes - .meas_function - .value - .to_lowercase() - .clone(), + let val = self + .get_function_value(&bias_channel.common_chan_attributes.source_function) + .clone(); + self.val_replacement_map + .insert(instr_name.clone() + ":SFUNCTION", val); + + self.set_source_range( + bias_channel.common_chan_attributes.source_range.clone(), + &instr_name, ); + let val = self + .get_function_value(&bias_channel.common_chan_attributes.meas_function) + .clone(); + + self.val_replacement_map + .insert(instr_name.clone() + ":MFUNCTION", val); + //sense mode exists only for SMU if let Some(sense_mode) = &bias_channel.common_chan_attributes.sense_mode { let sense_mode_key = format!("sense={}", sense_mode.value); @@ -136,13 +143,14 @@ impl SweepModel { .common_chan_attributes .get_name_for(&sense_mode_key) { - self.val_replacement_map.insert( - instr_name.clone() + ":SENSE", - String::from(sense_mode_value), - ); - } else { - //TODO: error handling for sense mode value not found + self.val_replacement_map + .insert(instr_name.clone() + ":SENSE", sense_mode_value.to_owned()); } + } else { + self.val_replacement_map.insert( + instr_name.clone() + ":SENSE", + BaseMetadata::UNDEFINED.to_string(), + ); } //source_limitv exists only for SMU @@ -182,9 +190,33 @@ impl SweepModel { } } - fn define_step_channels(&mut self, sweep_config: &SweepConfig) { + fn set_source_range(&mut self, channel_range: ChannelRange, instr_name: &String) { + let mut val = self.format_range(channel_range.clone()); + + if channel_range.is_range_auto() { + val = "CONSTANTS.AUTO".to_string(); + } + + self.val_replacement_map + .insert(instr_name.clone() + ":SRANGE", val); + } + + //Returns the value used in the script + fn get_function_value(&mut self, source_function: &ParameterString) -> String { + if source_function.value.to_lowercase() == BaseMetadata::FUNCTION_VOLTAGE.to_lowercase() { + "FUNC_DC_VOLTAGE".to_string() + } else if source_function.value.to_lowercase() + == BaseMetadata::FUNCTION_CURRENT.to_lowercase() + { + "FUNC_DC_CURRENT".to_string() + } else { + "FUNC_DC_IV_COMBINED".to_string() + } + } + + fn define_step_channels(&mut self, step_config: &SweepConfig) { let mut index = 1; - for step_channel in sweep_config.step_channels.iter() { + for step_channel in step_config.step_channels.iter() { let instr_name = format!("step{index}"); self.attributes.step_names.push(instr_name.clone()); @@ -221,35 +253,53 @@ impl SweepModel { ); self.val_replacement_map.insert( - instr_name.clone() + ":SFUNCTION", + instr_name.clone() + ":MODEL-TYPE", step_channel .start_stop_channel .common_chan_attributes - .source_function - .value - .to_lowercase() - .clone(), + .device + .device_type + .to_string(), ); - self.val_replacement_map.insert( - instr_name.clone() + ":SRANGE", - self.format_range( - step_channel + + let val = self + .get_function_value( + &step_channel .start_stop_channel .common_chan_attributes - .source_range - .clone(), - ), - ); + .source_function, + ) + .clone(); + self.val_replacement_map + .insert(instr_name.clone() + ":SFUNCTION", val); - self.val_replacement_map.insert( - instr_name.clone() + ":MFUNCTION", + self.set_source_range( step_channel .start_stop_channel .common_chan_attributes - .meas_function - .value - .to_lowercase() + .source_range .clone(), + &instr_name, + ); + + let val = self + .get_function_value( + &step_channel + .start_stop_channel + .common_chan_attributes + .meas_function, + ) + .clone(); + self.val_replacement_map + .insert(instr_name.clone() + ":MFUNCTION", val); + + self.val_replacement_map.insert( + instr_name.clone() + ":MODE", + if step_config.step_global_parameters.list_step { + "LIST".to_string() + } else { + step_channel.start_stop_channel.style.value.clone() + }, ); //sense mode exists only for SMU @@ -264,13 +314,14 @@ impl SweepModel { .common_chan_attributes .get_name_for(&sense_mode_key) { - self.val_replacement_map.insert( - instr_name.clone() + ":SENSE", - String::from(sense_mode_value), - ); - } else { - //TODO: error handling for sense mode value not found + self.val_replacement_map + .insert(instr_name.clone() + ":SENSE", sense_mode_value.to_owned()); } + } else { + self.val_replacement_map.insert( + instr_name.clone() + ":SENSE", + BaseMetadata::UNDEFINED.to_string(), + ); } //source_limitv exists only for SMU @@ -312,17 +363,17 @@ impl SweepModel { ); self.process_list( - sweep_config.step_global_parameters.list_step, + step_config.step_global_parameters.list_step, &step_channel.start_stop_channel.list, instr_name, - sweep_config.step_global_parameters.step_points.value as usize, + step_config.step_global_parameters.step_points.value as usize, ); index += 1; } let step_count = if !self.attributes.step_names.is_empty() { - sweep_config + step_config .step_global_parameters .step_points .value @@ -332,12 +383,7 @@ impl SweepModel { }; let step_to_sweep_delay = if !self.attributes.step_names.is_empty() { - self.format( - sweep_config - .step_global_parameters - .step_to_sweep_delay - .value, - ) + self.format(step_config.step_global_parameters.step_to_sweep_delay.value) } else { String::from("0") }; @@ -420,37 +466,54 @@ impl SweepModel { ); self.val_replacement_map.insert( - instr_name.clone() + ":SFUNCTION", + instr_name.clone() + ":MODEL-TYPE", sweep_channel .start_stop_channel .common_chan_attributes - .source_function - .value - .to_lowercase() - .clone(), + .device + .device_type + .to_string(), ); - self.val_replacement_map.insert( - instr_name.clone() + ":SRANGE", - self.format_range( - sweep_channel + + let val = self + .get_function_value( + &sweep_channel .start_stop_channel .common_chan_attributes - .source_range - .clone(), - ), - ); + .source_function, + ) + .clone(); + self.val_replacement_map + .insert(instr_name.clone() + ":SFUNCTION", val); - self.val_replacement_map.insert( - instr_name.clone() + ":MFUNCTION", + self.set_source_range( sweep_channel .start_stop_channel .common_chan_attributes - .meas_function - .value - .to_lowercase() + .source_range .clone(), + &instr_name, ); + let val = self + .get_function_value( + &sweep_channel + .start_stop_channel + .common_chan_attributes + .meas_function, + ) + .clone(); + self.val_replacement_map + .insert(instr_name.clone() + ":MFUNCTION", val); + + self.val_replacement_map.insert( + instr_name.clone() + ":MODE", + if sweep_config.sweep_global_parameters.list_sweep { + "LIST".to_string() + } else { + sweep_channel.start_stop_channel.style.value.clone() + }, + ); //sense mode exists only for SMU if let Some(sense_mode) = &sweep_channel .start_stop_channel @@ -463,13 +526,14 @@ impl SweepModel { .common_chan_attributes .get_name_for(&sense_mode_key) { - self.val_replacement_map.insert( - instr_name.clone() + ":SENSE", - String::from(sense_mode_value), - ); - } else { - //TODO: error handling for sense mode value not found + self.val_replacement_map + .insert(instr_name.clone() + ":SENSE", sense_mode_value.to_owned()); } + } else { + self.val_replacement_map.insert( + instr_name.clone() + ":SENSE", + BaseMetadata::UNDEFINED.to_string(), + ); } //source_limitv exists only for SMU diff --git a/script-gen-ui/src/app/components/main-sweep/main-sweep.component.scss b/script-gen-ui/src/app/components/main-sweep/main-sweep.component.scss index dbff548..a613556 100644 --- a/script-gen-ui/src/app/components/main-sweep/main-sweep.component.scss +++ b/script-gen-ui/src/app/components/main-sweep/main-sweep.component.scss @@ -241,11 +241,14 @@ display: flex; justify-content: space-between; color: var(--vscode-editor-foreground); - // border: 1px solid var(--vscode-editorWidget-border); border-radius: 10px; - padding-left: 1px; - padding-right: 1px; - padding-top: 7px; + padding: 7px 10px; + background-color: var(--vscode-editor-background); + position: sticky; + top: 0; + z-index: 100; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + margin-bottom: 10px; } .timing { diff --git a/xml-handler/src/resources/sweep/MP5000Sweep.xml b/xml-handler/src/resources/sweep/MP5000Sweep.xml index ebf3b98..1831c5a 100644 --- a/xml-handler/src/resources/sweep/MP5000Sweep.xml +++ b/xml-handler/src/resources/sweep/MP5000Sweep.xml @@ -42,6 +42,7 @@ --#region Util CONSTANTS = { + UNDEFINED = nil, AUTO = "AUTO", localnode = 0, SENSE_2WIRE = 0, @@ -82,9 +83,9 @@ ---@class Source ---@field values ScalarValue | LogValues | LinearValues | ListValues The value or values to source - ---@field range number | `CONSTANTS.AUTO` The range to use, or Auto + ---@field range number | "AUTO" The range to use, or Auto ---@field limiti number The current limit - ---@field limitv number The voltage limit + ---@field limitv number | nil The voltage limit ---@field delay number The time to delay before sourcing ---@field func `self.slot.smu.FUNC_DC_VOLTAGE` | `self.slot.smu.FUNC_DC_CURRENT` @@ -325,7 +326,7 @@ self.channel.source.levelv = self.source.values.scalar elseif self.source.func == CONSTANTS.FUNC_DC_CURRENT then self.channel.source.func = self.slot.smu.FUNC_DC_CURRENT - self.channel.trigger.source.leveli = self.source.values.scalar + self.channel.source.leveli = self.source.values.scalar end elseif self.source.values.list ~= nil then if self.source.func == CONSTANTS.FUNC_DC_VOLTAGE then @@ -741,8 +742,7 @@ ---@param self Device config = function(self) UTILITY.init_slot_event_ids(self.slot, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }) - -- Sense setting -- - self.channel.sense = self.sense + local event_id = UTILITY.get_slot_event_id(self.slot) if event_id then @@ -1274,16 +1274,16 @@ local errorTag = "[{error}]" - local numberOfSteps = 10 - local numberOfSweeps = 10 + local numberOfSteps = %STEP-COUNT% + local numberOfSweeps = %SWEEP-POINTS% - local stepToSweepDelay = 0 + local stepToSweepDelay = %STEP-TO-SWEEP-DELAY% - local nplc = 1 + local nplc = %NPLC% - local source_delay = 0 - local measure_delay = nil - local measure_count = 1 + local source_delay = %SOURCE-DELAY% + local measure_delay = %MEASURE-DELAY% + local measure_count = %MEASURE-COUNT% @@ -1301,6 +1301,7 @@ %SLOT-IDX% %CHANNEL-IDX% %MODEL% + %MODEL-TYPE% %SFUNCTION% %SRANGE% %BIAS% @@ -1331,32 +1332,32 @@ buffers = { - current + FUNC_DC_CURRENT { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_CURRENT }, - voltage + FUNC_DC_VOLTAGE { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_VOLTAGE }, - current,voltage + FUNC_DC_IV_COMBINED { - buffer = %NODE%.slot[%BIAS-DEVICE:SLOT-IDX%].smu[%BIAS-DEVICE:CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%BIAS-DEVICE:SLOT-IDX%].%MODEL-TYPE%[%BIAS-DEVICE:CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_CURRENT }, { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer2, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer2, type = CONSTANTS.FUNC_DC_VOLTAGE }, @@ -1375,6 +1376,7 @@ %SLOT-IDX% %CHANNEL-IDX% %MODEL% + %MODEL-TYPE% %SFUNCTION% %SRANGE% %START% @@ -1384,6 +1386,7 @@ %SENSE% %LIMITI% %LIMITV% + %MODE% UTILITY.insert(nodes.steps, UTILITY.makestep({ node_idx = %NODE-IDX%, @@ -1434,32 +1437,32 @@ buffers = { - current + FUNC_DC_CURRENT { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_CURRENT }, - voltage + FUNC_DC_VOLTAGE { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_VOLTAGE }, - current,voltage + FUNC_DC_IV_COMBINED { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_CURRENT }, { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer2, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer2, type = CONSTANTS.FUNC_DC_VOLTAGE }, @@ -1478,6 +1481,7 @@ %SLOT-IDX% %CHANNEL-IDX% %MODEL% + %MODEL-TYPE% %SFUNCTION% %SRANGE% %START% @@ -1487,13 +1491,14 @@ %SENSE% %LIMITI% %LIMITV% + %MODE% UTILITY.insert(nodes.sweeps, UTILITY.makesweep({ node_idx = %NODE-IDX%, slot_idx = %SLOT-IDX%, channel_idx = %CHANNEL-IDX%, model = "%MODEL%", - sense = CONSTANTS.%SENSE, -- must be SENSE_2WIRE or SENSE_4WIRE + sense = CONSTANTS.%SENSE%, -- must be SENSE_2WIRE or SENSE_4WIRE source = { @@ -1533,36 +1538,36 @@ nplc = nplc, count = measure_count, delay = measure_delay, - func = CONSTANTS["%MFUNCTION%"], -- must be FUNC_DC_VOLTAGE, FUNC_DC_CURRENT, or FUNC_DC_IV_COMBINED + func = CONSTANTS.%MFUNCTION%, -- must be FUNC_DC_VOLTAGE, FUNC_DC_CURRENT, or FUNC_DC_IV_COMBINED buffers = { - current + FUNC_DC_CURRENT { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_CURRENT }, - voltage + FUNC_DC_VOLTAGE { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_VOLTAGE }, - current,voltage + FUNC_DC_IV_COMBINED { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer1, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer1, type = CONSTANTS.FUNC_DC_CURRENT }, { - buffer = %NODE%.slot[%SLOT-IDX%].smu[%CHANNEL-IDX%].defbuffer2, + buffer = %NODE%.slot[%SLOT-IDX%].%MODEL-TYPE%[%CHANNEL-IDX%].defbuffer2, type = CONSTANTS.FUNC_DC_VOLTAGE }, diff --git a/xml-handler/src/snippet/mod.rs b/xml-handler/src/snippet/mod.rs index 208d5de..1086b30 100644 --- a/xml-handler/src/snippet/mod.rs +++ b/xml-handler/src/snippet/mod.rs @@ -1,8 +1,7 @@ use std::{ any::Any, collections::HashMap, - fs::File, - io::{self, BufRead, Cursor, Write}, + io::{self, BufRead, Cursor}, }; use quick_xml::{events::Event, name::QName, Reader};