Skip to content

Commit

Permalink
New types of pulsed measurements, fixed STDP plot bug
Browse files Browse the repository at this point in the history
  • Loading branch information
cantudo committed Jan 24, 2023
1 parent e6b4a9e commit 331fcca
Show file tree
Hide file tree
Showing 31 changed files with 1,570 additions and 556 deletions.
67 changes: 61 additions & 6 deletions backend/src/b1500/measure/pulsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,29 @@ fn init_pulsed_voltage_waveform(

pub type PulseTrainCollection = Vec<PulseTrain>;

/// Notes:
/// _____ _____ _____ ------------> v_high
/// | | | | | |
/// | | | | | |
/// | |_____| |_____| |_____ -------> v_low
/// |<------->| cycle_time
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PulseTrain {
/// The number of pulses the train has
pub n_pulses: usize,
/// The duty cycle of the pulses, that is the proportion of the cycle time
/// that the pulse is active (at v_high).
pub duty_cycle: f64,
/// The cycle time, that is the time that it takes to complete a cycle,
/// one v_high, one v_low. (seconds)
pub cycle_time: f64,
/// Active voltage of the pulses, see notes above. (Volts)
pub v_high: f64,
/// Low voltage of the pulses, see notes above. (Volts)
pub v_low: f64,
/// Initial waiting delay, in seconds. (seconds)
pub delay: f64
}

fn wgfmu_add_pulse_train<T: WgfmuDriver>(
Expand Down Expand Up @@ -122,6 +137,26 @@ fn wgfmu_add_pulse_train<T: WgfmuDriver>(
pulse_train.duty_cycle,
);

if pulse_train.delay != 0.0 {
let wait_wf: VoltageWaveForm = vec![VoltageWaveFormPoint { voltage: 0.0, dtime: pulse_train.delay * 1.001 }];
let delay_pattern = format!("{}_delay", pattern);
wgfmu.create_pattern(delay_pattern.as_str(), 0.0)?;
add_waveform(wgfmu, &wait_wf, delay_pattern.as_str())?;
wgfmu.add_sequence(CHANNEL2, delay_pattern.as_str(), 1)?;
// eventEndTime = time + interval * (points - 1) + average
let points = 80.0;
let interval = (pulse_train.delay - *avg_time) / (points - 1.0);
wgfmu.set_measure_event(
delay_pattern.as_str(),
"event_delay",
0.0,
points as i32,
interval,
*avg_time,
MeasureEventMode::MeasureEventDataAveraged,
)?;
}

if !noise {
add_waveform(wgfmu, &waveform, pattern)?;
wgfmu.add_sequence(CHANNEL2, pattern, pulse_train.n_pulses)?;
Expand Down Expand Up @@ -166,10 +201,10 @@ fn wgfmu_add_pulse_train<T: WgfmuDriver>(
)?;

// Sampling margin
let pattern_margin = format!("{}_margin", pattern);
wgfmu.create_pattern(pattern_margin.as_str(), 0.0)?;
wgfmu.add_vector(pattern_margin.as_str(), pulse_train.cycle_time, 0.0)?;
wgfmu.add_sequence(CHANNEL2, "v1_margin", 1)?;
// let pattern_margin = format!("{}_margin", pattern);
// wgfmu.create_pattern(pattern_margin.as_str(), 0.0)?;
// wgfmu.add_vector(pattern_margin.as_str(), pulse_train.delay, 0.0)?;
// wgfmu.add_sequence(CHANNEL2, pattern_margin.as_str(), 1)?;
} else {
// let total_measure_time = measure_totaltime_high + measure_totaltime_low;

Expand Down Expand Up @@ -210,6 +245,26 @@ fn wgfmu_add_pulse_train<T: WgfmuDriver>(
{
let v2 = format!("{}_v2", pattern);

if pulse_train.delay != 0.0 {
let wait_wf: VoltageWaveForm = vec![VoltageWaveFormPoint { voltage: 0.0, dtime: pulse_train.delay * 1.001 }];
let delay_pattern = format!("{}_delay", v2);
wgfmu.create_pattern(delay_pattern.as_str(), 0.0)?;
add_waveform(wgfmu, &wait_wf, delay_pattern.as_str())?;
wgfmu.add_sequence(CHANNEL1, delay_pattern.as_str(), 1)?;
// eventEndTime = time + interval * (points - 1) + average
let points = 80.0;
let interval = (pulse_train.delay - *avg_time) / (points - 1.0);
wgfmu.set_measure_event(
delay_pattern.as_str(),
"event_delay_v2",
0.0,
points as i32,
interval,
*avg_time,
MeasureEventMode::MeasureEventDataAveraged,
)?;
}

if !noise {
let total_time = pulse_train.cycle_time + 2e-8;

Expand All @@ -218,7 +273,7 @@ fn wgfmu_add_pulse_train<T: WgfmuDriver>(
// End at 0
wgfmu.set_vector(v2.as_str(), total_time, 0.0)?;

wgfmu.add_sequence(CHANNEL1, "v2", pulse_train.n_pulses)?;
wgfmu.add_sequence(CHANNEL1, v2.as_str(), pulse_train.n_pulses)?;

wgfmu.set_measure_event(
v2.as_str(),
Expand Down Expand Up @@ -247,7 +302,7 @@ fn wgfmu_add_pulse_train<T: WgfmuDriver>(
// End at 0
wgfmu.set_vector(v2.as_str(), total_time * (pulse_train.n_pulses as f64), 0.0)?;

wgfmu.add_sequence(CHANNEL1, "v2", 1)?;
wgfmu.add_sequence(CHANNEL1, v2.as_str(), 1)?;

let total_points =
(n_rep * (unique_pulses * (n_points_low as usize + n_points_high as usize))) as i32;
Expand Down
2 changes: 1 addition & 1 deletion backend/src/b1500/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub fn add_noisy_waveform<D: WgfmuDriver>(
n_points
];

// We llok at two adjacent points and linearly interpolate between them
// We look at two adjacent points and linearly interpolate between them
let mut current_index = 0; // Index of the of the first of the two points we are looking at in the provided waveform
let mut current_time = 0.0; // Absolute time of the first of the two points we are looking at in the provided waveform
for (idx, &time) in final_time_points[..n_points - 1].iter().enumerate() {
Expand Down
1 change: 1 addition & 0 deletions backend/src/www/measurements/pulse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub async fn pulse_measurement(
cycle_time: params.cycle_time,
v_high: params.v_high,
v_low: params.v_low,
delay: 0.0
},
params.n_points_high,
params.n_points_low,
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/Graph/plots/stdpCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ export function getParameters(data: StdpCollectionMeasurement, dimensions: Dimen
let auxDataConductanceRatio =
data.collection.map(meas => (meas.stdpMeasurement.conductance - data.baseConductance) / data.baseConductance)


let auxDataDelay = data.collection.map(w => w.delay)

console.log({auxDataConductanceRatio})

let finalData: StdpPoint[] = []
auxDataConductanceRatio.forEach((r, i) => finalData.push({delay: auxDataDelay[i], conductanceRatio: r}))

let delayScaling = getScaling<number>(auxDataDelay, 's', (d) => d)
// let conductanceScaling = getScaling<number>(auxDataConductance, 'S', (d) => d)
console.log({sfactor: delayScaling.scalingFactor})

let xExtentDelay: [number, number] = [0, 0]
let aux = d3.extent([...auxDataDelay.map(d => -d), ...auxDataDelay], d => d * delayScaling.scalingFactor)
Expand All @@ -52,8 +54,9 @@ export function getParameters(data: StdpCollectionMeasurement, dimensions: Dimen

let yExtentConductanceRatio: [number, number] = [0, 0]
aux = d3.extent([...auxDataConductanceRatio.map(c => -c), ...auxDataConductanceRatio], d => d)
console.log({aux})
aux[0] != undefined && aux[1] != undefined && (yExtentConductanceRatio = aux)
if (yExtentConductanceRatio[0] + yExtentConductanceRatio[1] == 0) {
if (Math.abs(yExtentConductanceRatio[0]) + Math.abs(yExtentConductanceRatio[1]) == 0) {
yExtentConductanceRatio = [-1, 1]
}

Expand Down
57 changes: 57 additions & 0 deletions frontend/src/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Children } from "react"

interface Props {
children: React.ReactNode
}

export default function Modal(props: Props) {
return (
<>
<div
className="modal fade fixed top-0 left-0 hidden w-full h-full outline-none overflow-x-hidden overflow-y-auto"
id="exampleModalCenter"
tabIndex={-1}
aria-labelledby="exampleModalCenterTitle"
aria-modal="true"
role="dialog"
>
<div className="modal-dialog modal-dialog-centered relative w-auto pointer-events-none">
<div className="modal-content border-none shadow-lg relative flex flex-col w-full pointer-events-auto bg-white bg-clip-padding rounded-md outline-none text-current">
<div className="modal-header flex flex-shrink-0 items-center justify-between p-4 border-b border-gray-200 rounded-t-md">
<h5
className="text-xl font-medium leading-normal text-gray-800"
id="exampleModalScrollableLabel"
>
Modal title
</h5>
<button
type="button"
className="btn-close box-content w-4 h-4 p-1 text-black border-none rounded-none opacity-50 focus:shadow-none focus:outline-none focus:opacity-100 hover:text-black hover:opacity-75 hover:no-underline"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body relative p-4">
<p>This is a vertically centered modal.</p>
</div>
<div className="modal-footer flex flex-shrink-0 flex-wrap items-center justify-end p-4 border-t border-gray-200 rounded-b-md">
<button
type="button"
className="inline-block px-6 py-2.5 bg-purple-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-purple-700 hover:shadow-lg focus:bg-purple-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-purple-800 active:shadow-lg transition duration-150 ease-in-out"
data-bs-dismiss="modal"
>
Close
</button>
<button
type="button"
className="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out ml-1"
>
Save changes
</button>
</div>
</div>
</div>
</div>
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { boolean } from "mathjs"
import { useState } from "react"
import { HiLockClosed, HiLockOpen } from "react-icons/hi"
import { Slider, Number } from "../../../../../components/Input"
import { useAppDispatch, useAppSelector } from "../../../../../store/hooks"
import { EpscControls as EpscControlsInterface } from "../../types"
import {
selectEpscParams,
setEpscParamsField,
setMultiPulseParamsField as setParamsField,
updateState,
} from "./collectionControlsSlice"

type ValidateInterface = {
[k in keyof EpscControlsInterface]: boolean
}

export default function EpscControls() {
const dispatch = useAppDispatch()
const params = useAppSelector(selectEpscParams)

const [valid, setValid] = useState<ValidateInterface>({
frequencies: true,
interTrainsTime: true,
spikeTime: true,
}) // wether or not this settings are valid

const [samplingPointsTied, setSamplingPointsTied] = useState(true)

const onValidateCurry = (id: keyof EpscControlsInterface) => {
return (isValid: boolean) => setValid({ ...valid, [id]: isValid })
}

return (
<>
<div className="py-4 w-full border-b border-solid border-neutral-600">
<Number
label="Inter trains time"
onChange={(value) => {
dispatch(setEpscParamsField({ val: value, key: "interTrainsTime" }))
}}
value={params.interTrainsTime}
onValidate={onValidateCurry("interTrainsTime")}
type={{
type: "sci",
unit: "s",
}}
min={0}
/>
</div>
<div className="py-4 w-full">
<Number
label="Spike time"
onChange={(value) => {
dispatch(setEpscParamsField({ val: value, key: "spikeTime" }))
}}
value={params.spikeTime}
onValidate={onValidateCurry("spikeTime")}
type={{
type: "sci",
unit: "s",
}}
min={0}
/>
</div>
</>
)
}
Loading

0 comments on commit 331fcca

Please sign in to comment.