Using thresholds obtained earlier in the study

So I’m using a QUEST handler, and I’ve obtained 75, 50 and 25% detection thresholds. They are saved as such:
threshold_50
threshold_25
threshold_75

I want to use these threshold values later in the study to change the volume of an audio stimulus. I have multiple trials in a block and the volume needs to vary between the 3 thresholds and 0 volume. I have created a conditions file and a column (GVolume), that includes: threshold_50, threshold_25, threshold_75 and 0. And have set the volume of my audio stimuli to GVolume.

The problem is it is recognising the value as a string not a float. All the thresholds are a float. I was just wondering if there were anyway to use my obtained values from the QUEST to set the volume of my stimuli?

You could try adding float(threshold_50) etc. in the later components.

To confirm – you are writing your thresholds to a CSV file and then reading that back in?

Is there a reason why it needs to be a float and not an int? It’ll probably be easier to just save them as integers and use them that way. Otherwise, float() should work.

It just depends what format the volume setting is in. For PTB sound it looks like volume is a float between 0 and 1, so you’ll need to 1) have it as a float and 2) convert it to a value between 0 and 1.

If float() does not work and it’s recognizing them as strings specifically, eval() will also work, though whether you get a float or an int will depend on whether there is a decimal. That said, if you need to convert it to a value between 0 and 1 anyway, it’ll get turned into a float at that point.

No I created the cvs before - I was unsure how to set the trial order when creating a new file. I think I’ve fixed it. I’ve used the column name GVolume and added code to convert it to the threshold value and then used GVolume2 as my volume of my audio component:
if GVolume == ‘threshold_50’:
GVolume2 = threshold_50
elif GVolume == ‘threshold_25’:
GVolume2 = threshold_25
elif GVolume == ‘threshold_75’:
GVolume2 = threshold_75
elif GVolume == ‘0’:
GVolume2 = 0
else:
GVolume2 = 0

In a completely unrelated problem (which I might start a new thread for). When I use a keyboard response, after so many trials a brief noise (almost like a bounce/ping sound), when a key is pressed appears. Any suggestions why?

What version of PsychoPy are you using? It sounds like your key presses are being sent to Builder as well as being registered by the experiment. I think this was fixed in 2024.2.3 or 2024.2.4.

I’m using 2024.2.4 - it only starts happening after about 20 trials. I’ve used previous version and never had that problem - I switched to 2024.2.4 as the QUEST handler has been working a lot smoother for me.

Thanks for all the help. It works locally. But now I’m trying to run the study on Pavlovia and I’m having trouble using the values. I get ‘value is not finite’. Even though I’ve set the values to 4 decimel places (this is after the thresholding routine). I’ve tried changing the code (removing let - I saw on another thread that var could be the problem).
Basically I’m trying to obtain thresholds from my Quest - I’ll later use these values as volumes.
Post-threshold routine code:
// Function to calculate quantiles (after the loop finishes)
function calculateQuantiles(x_data, y_data) {
// Sort the data based on intensity values (x_data)
let sortedData = x_data.map((x, i) => ({ x: x, y: y_data[i] }));
sortedData.sort((a, b) => a.x - b.x); // Sort by x (intensity)

// Get sorted x values
let sortedX = sortedData.map(d => d.x);

// Calculate quantiles
let threshold_50 = calculatePercentile(sortedX, 50);
let threshold_25 = calculatePercentile(sortedX, 25);
let threshold_75 = calculatePercentile(sortedX, 75);

// Round thresholds to 4 decimal places and ensure they remain numbers
let threshold_dict = {
    "threshold_50": Number(threshold_50.toFixed(4)),
    "threshold_25": Number(threshold_25.toFixed(4)),
    "threshold_75": Number(threshold_75.toFixed(4))
};

// Print values to console
console.log("Thresholds calculated:");
console.log("50% threshold:", threshold_dict["threshold_50"]);
console.log("25% threshold:", threshold_dict["threshold_25"]);
console.log("75% threshold:", threshold_dict["threshold_75"]);

return threshold_dict;

}

// Declare global variables to store thresholds
let threshold_50, threshold_25, threshold_75;

// Function to calculate quantiles (after the loop finishes)
function calculateQuantiles(x_data, y_data) {
// Sort the data based on intensity values (x_data)
let sortedData = x_data.map((x, i) => ({ x: x, y: y_data[i] }));
sortedData.sort((a, b) => a.x - b.x); // Sort by x (intensity)

// Get sorted x values
let sortedX = sortedData.map(d => d.x);

// Calculate quantiles
threshold_50 = calculatePercentile(sortedX, 50);
threshold_25 = calculatePercentile(sortedX, 25);
threshold_75 = calculatePercentile(sortedX, 75);

// Round thresholds to 4 decimal places and ensure they remain numbers
threshold_50 = Number(threshold_50.toFixed(4));
threshold_25 = Number(threshold_25.toFixed(4));
threshold_75 = Number(threshold_75.toFixed(4));

// Print values to console
console.log("Thresholds calculated:");
console.log("50% threshold:", threshold_50);
console.log("25% threshold:", threshold_25);
console.log("75% threshold:", threshold_75);

}

// Function to calculate the nth percentile
function calculatePercentile(sortedData, percentile) {
let index = Math.floor(percentile / 100 * (sortedData.length - 1));
return sortedData[index];
}

// At the end of your loop or experiment, no need to use ‘let’ for global variables
calculateQuantiles(x_data, y_data);

// Print final values to console again (for clarity)
console.log(“Final Thresholds:”);
console.log(“50% threshold:”, threshold_50);
console.log(“25% threshold:”, threshold_25);
console.log(“75% threshold:”, threshold_75);

Then later in the study I have a conditions file with a column GVolume which includes values e.g., threshold_75. I then use this code to make sure it converts to the values obtained and use $GVolume2 as my variable in my audio file (this has worked for python).
if (GVolume === “threshold_50”) {
GVolume2 = threshold_50;
} else if (GVolume === “threshold_25”) {
GVolume2 = threshold_25;
} else if (GVolume === “threshold_75”) {
GVolume2 = threshold_75;
} else if (GVolume === “0”) {
GVolume2 = 0;
} else {
GVolume2 = threshold_75; // Default value if no condition matches
}

// Print values for debugging
console.log(“Trial 1”, TrialLoop.thisTrialN + 1, “GVolume:”, GVolume);
console.log(“Volume:”, GVolume2);

I tried using the values directly (GVolume) from the condition file and it didn’t work either.

Link to study:

Another unrelated Q - I use a sound file throughout my study. It initially sounds fine but as it goes through the experiment it seems to change? Any idea why.

Any help would be much appreciated! I’ve been going in circles all day

I’ve tried using: isFinite(x);
}

but that doesn’t work. Any help would be appreciated.

Solved it - the isFinite did work.
The function needed to be moved to the before experiment rather than begin experiment to ensure it was loaded.

1 Like