Skip to content
2 changes: 2 additions & 0 deletions script-gen-manager/src/instr_metadata/mpsu50_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ impl Mpsu50Metadata {

base.add_range("source.limiti".to_string(), 0.01, 5.1);

base.add_range("source.step_to_sweep_delay".to_string(), 0.0, 100.0);

// Add region maps
// when pulse mode is off
let exclude_i = NumberLimit::new(-10.0e-9, 10.0e-9, false, None);
Expand Down
2 changes: 2 additions & 0 deletions script-gen-manager/src/instr_metadata/msmu60_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ impl Msmu60Metadata {
base.add_range("source.limiti".to_string(), -1e-8, 1.515);
base.add_range("source.limitv".to_string(), -0.02, 60.6);

base.add_range("source.step_to_sweep_delay".to_string(), 0.0, 100.0);

// Add region maps
// when pulse mode is off
let exclude_v = Some(NumberLimit::new(-0.01, 0.01, false, None));
Expand Down
10 changes: 10 additions & 0 deletions script-gen-manager/src/model/sweep_data/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ impl ParameterFloat {
unit,
}
}

pub fn limit(&mut self, min: f64, max: f64) {
if self.value >= min && self.value <= max {
return;
} else if self.value < min {
self.value = min
} else {
self.value = max
}
}
}

impl ParameterString {
Expand Down
39 changes: 27 additions & 12 deletions script-gen-manager/src/model/sweep_data/sweep_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::HashMap;

use crate::{
device::Device,
instr_metadata::{base_metadata::Metadata, enum_metadata::MetadataEnum},
model::{
chan_data::{
bias_channel::BiasChannel, step_channel::StepChannel, sweep_channel::SweepChannel,
Expand Down Expand Up @@ -370,9 +371,27 @@ impl SweepConfig {
.sweep_timing_config
.measure_count
.limit(1, 60000);

// Validating Step to Sweep Delay
if !self.step_channels.is_empty() {
let device_metadata = self.step_channels[0]
.start_stop_channel
.common_chan_attributes
.device
.get_metadata();
if let Some((min, max)) =
self.get_range_limits(&device_metadata, "source.step_to_sweep_delay")
{
self.step_global_parameters
.step_to_sweep_delay
.limit(min, max);
}
}

for bias_channel in &mut self.bias_channels {
bias_channel.evaluate();
}

for step_channel in &mut self.step_channels {
step_channel
.start_stop_channel
Expand All @@ -383,18 +402,6 @@ impl SweepConfig {
.start_stop_channel
.evaluate(self.sweep_global_parameters.sweep_points.value as usize);
}

// Check if only bias channels exist and display appropriate message
// if !self.bias_channels.is_empty()
// && self.step_channels.is_empty()
// && self.sweep_channels.is_empty()
// {
// self.status_msg = Some(StatusMsg::new(
// StatusType::Warning,
// String::from("Only bias channels are configured. Please add a step or sweep channel to generate a functional script."),
// ));
// println!("Warning: Only bias channels are configured. Please add a step or sweep channel to generate a functional script.");
// }
}

pub fn update_channel_devices(&mut self) {
Expand Down Expand Up @@ -593,6 +600,14 @@ impl SweepConfig {
}
}

fn get_range_limits(&self, metadata: &MetadataEnum, key: &str) -> Option<(f64, f64)> {
match metadata {
MetadataEnum::Base(base_metadata) => base_metadata.get_range(key),
MetadataEnum::Msmu60(msmu60_metadata) => msmu60_metadata.get_range(key),
MetadataEnum::Mpsu50(mpsu50_metadata) => mpsu50_metadata.get_range(key),
}
}

pub fn reset(&mut self) {
*self = SweepConfig::new();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class PlotStepComponent
backgroundColor: '',
color: '',
};
@Input() color = '';
@Input() color = '';
private mutationObserver: MutationObserver | undefined;
private originalBackgroundColor = '';
activeBackgroundColor = '';
Expand Down Expand Up @@ -95,6 +95,7 @@ export class PlotStepComponent
size: 9,
},
dtick: 1,
range: [0, 10],
// tick0: 0,
showtickprefix: 'none',
showticksuffix: 'all',
Expand Down Expand Up @@ -269,41 +270,88 @@ export class PlotStepComponent
}

private generatePlotData(yData: number[], type: string): void {
if (this.stepPoints) {
if (this.stepPoints && this.stepToSweepDelay) {
const delayTime = this.stepToSweepDelay?.value ?? 0;
const targetLength = Math.max(2, Math.floor(this.plotWidth));
let xData: number[] = [];
let processedYData = [...yData];
let processedXData: number[] = [];

// Handle interpolation first if needed
if (this.stepPoints.value > targetLength) {
if (type == 'LIN') {
const interpolated = PlotUtils.linearInterpolation(
yData,
targetLength
);
xData = interpolated.x;
yData = interpolated.y;
const interpolated = PlotUtils.linearInterpolation(processedYData, targetLength);
processedXData = interpolated.x;
processedYData = interpolated.y;
} else if (type == 'LOG' || type == 'LIST') {
const interpolated = PlotUtils.minMaxInterpolation(
yData,
targetLength
);
xData = interpolated.x;
yData = interpolated.y;
const interpolated = PlotUtils.minMaxInterpolation(processedYData, targetLength);
processedXData = interpolated.x;
processedYData = interpolated.y;
}
} else {
xData = Array.from({ length: this.stepPoints.value }, (_, i) => i)
processedXData = Array.from({ length: this.stepPoints.value }, (_, i) => i)
.concat(this.stepPoints.value)
.flat();
}
this.plotData1.x = xData;
this.plotData1.y = yData;
console.log('Plot data generated:', {
x: this.plotData1.x,
y: this.plotData1.y,
});
this.plotLayout.xaxis.dtick = this.stepPoints.value / 10;

if (delayTime > 0) {
const { x, y } = this.generateDataWithDelay(processedYData, processedXData, delayTime);
this.plotData1.x = x;
this.plotData1.y = y;
} else {
this.generateDataWithoutDelay(processedYData, processedXData);
}

// console.log('Plot data generated:', {
// x: this.plotData1.x,
// y: this.plotData1.y,
// });
// this.plotLayout.xaxis.dtick = (this.stepPoints.value + this.stepToSweepDelay?.value) / 10;
// Update x-axis range to include delay time for each step
// const delayTime = this.stepToSweepDelay?.value ?? 0;
const totalTime = this.stepPoints.value * (1 + delayTime); // Each step now takes (1 + delayTime) units

this.plotLayout.xaxis.dtick = totalTime / 10;
this.plotLayout.xaxis.range = [0, totalTime];
}
}

private generateDataWithDelay(yData: number[], xData: number[], delayTime: number): { x: number[], y: number[] } {
const finalX: number[] = [];
const finalY: number[] = [];
const delayPoints = Math.max(5, Math.floor(delayTime * 10));
const numSteps = yData.length - 1; // Exclude the final repeated point

// Generate data for each step with delay
for (let step = 0; step < numSteps; step++) {
const stepStartTime = step * (1 + delayTime);
const currentYValue = yData[step];

// Add delay period (repeat current y value) at the beginning of each step
for (let d = 0; d < delayPoints; d++) {
finalX.push(stepStartTime + (d * delayTime) / delayPoints);
finalY.push(currentYValue);
}

// Add the actual step point after delay
finalX.push(stepStartTime + delayTime);
finalY.push(currentYValue);
}

// Add final point
if (yData.length > 0) {
const finalStepTime = numSteps * (1 + delayTime);
finalX.push(finalStepTime);
finalY.push(yData[yData.length - 1]);
}

return { x: finalX, y: finalY };
}

private generateDataWithoutDelay(yData: number[], xData: number[]): void {
this.plotData1.x = xData;
this.plotData1.y = yData;
}

private stepListPlot() {
if (this.listStep && this.stepPoints && this.stop) {
const stepValues = this.listStep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export class PlotSweepComponent
list = true;
listSweep: ParameterFloat[] = [];
numSteps: number | undefined;
stepToSweepDelay: ParameterFloat | undefined;

plotUtils = new PlotUtils();

plotLayout = {
Expand Down Expand Up @@ -239,6 +241,7 @@ export class PlotSweepComponent
this.numPoints = this.sweepGlobalParameters?.sweep_points;
this.list = this.sweepGlobalParameters?.list_sweep;
this.numSteps = this.stepGlobalParameters?.step_points.value;
this.stepToSweepDelay = this.stepGlobalParameters?.step_to_sweep_delay;
// this.list = this.sweepGlobalParameters?.list_sweep;
this.listSweep = this.sweepChannel.start_stop_channel.list;

Expand Down Expand Up @@ -295,19 +298,76 @@ export class PlotSweepComponent
if (this.numPoints && this.numSteps) {
const numSteps = this.numSteps;
const numberOfPoints = this.numPoints?.value;
this.plotData1.y = Array.from({ length: numSteps }, () => sweepValues)
.flat()
.concat(sweepValues[sweepValues.length - 1]);

if (xData) {
this.plotData1.x = xData;
const delayTime = this.stepToSweepDelay?.value ?? 0;

if (delayTime > 0) {
const { x, y } = this.generateDataWithDelay(sweepValues, numSteps, numberOfPoints, delayTime, xData);
this.plotData1.x = x;
this.plotData1.y = y;
} else {
this.plotData1.x = Array.from({ length: numSteps }, (_, i) =>
Array.from({ length: numberOfPoints }, (_, j) => i + j / numberOfPoints)
)
.flat()
.concat(numSteps);
this.generateDataWithoutDelay(sweepValues, numSteps, numberOfPoints, xData);
}
}
}

private generateDataWithDelay(
sweepValues: number[],
numSteps: number,
numberOfPoints: number,
delayTime: number,
xData?: number[]
): { x: number[], y: number[] } {
const finalX: number[] = [];
const finalY: number[] = [];
const delayPoints = Math.max(5, Math.floor(delayTime * 10));

// Generate data for each step with delay
for (let step = 0; step < numSteps; step++) {
const stepStartTime = step * (1 + delayTime);

// Add delay period (zeros) at the beginning of each step
for (let d = 0; d < delayPoints; d++) {
finalX.push(stepStartTime + (d * delayTime) / delayPoints);
finalY.push(0);
}

// Add the actual sweep data for this step
for (let j = 0; j < numberOfPoints; j++) {
if (xData) {
const originalIndex = step * numberOfPoints + j;
if (originalIndex < xData.length) {
finalX.push(stepStartTime + delayTime + (j / numberOfPoints));
}
} else {
finalX.push(stepStartTime + delayTime + (j / numberOfPoints));
}
finalY.push(sweepValues[j]);
}
}

// Add final point
if (sweepValues.length > 0) {
const finalStepTime = numSteps * (1 + delayTime);
finalX.push(finalStepTime);
finalY.push(sweepValues[sweepValues.length - 1]);
}

return { x: finalX, y: finalY };
}

private generateDataWithoutDelay(sweepValues: number[], numSteps: number, numberOfPoints: number, xData?: number[]) {
this.plotData1.y = Array.from({ length: numSteps }, () => sweepValues)
.flat()
.concat(sweepValues[sweepValues.length - 1]);

if (xData) {
this.plotData1.x = xData;
} else {
this.plotData1.x = Array.from({ length: numSteps }, (_, i) =>
Array.from({ length: numberOfPoints }, (_, j) => i + j / numberOfPoints)
)
.flat()
.concat(numSteps);
}
}

Expand Down Expand Up @@ -335,8 +395,13 @@ export class PlotSweepComponent
} else {
this.generatePlotDataxy(sweepValues);
}
this.plotLayout.xaxis.dtick = this.numSteps / 10;
this.plotLayout.xaxis.range = [0, this.numSteps];

// Update x-axis range to include delay time for each step
const delayTime = this.stepToSweepDelay?.value ?? 0;
const totalTime = this.numSteps * (1 + delayTime); // Each step now takes (1 + delayTime) units

this.plotLayout.xaxis.dtick = totalTime / 10;
this.plotLayout.xaxis.range = [0, totalTime];
}
}

Expand Down
Loading