Updating standered deviation values for a live process.

8 vues (au cours des 30 derniers jours)
Phoebe
Phoebe le 31 Juil 2025
Modifié(e) : Aryan le 5 Août 2025
I am writing a script that plots live data as it is being aquired. The script takes a 100 measurments and averages those into a single shot value. This shot value is then recorded and plotted. 100 more measurments are taken and another shot is aquired which is plotted along side the first shot. What is actually being plotted is every shot subtracted off from the mean of all shots aquired, so the 0 y location and standered deviation of each shot with respect to the mean of all shots changes with every new run. I am struggaling to get the standered deviations to update properly. I was using (end+1) to add aditional values onto an array but this does not go back and recalculate std values for prevous shots. Let me know what you guys think and if there is a better way to do this.
Here is my code:
%Calculates Vectors
x1 = BPM_3156_x;
Unrecognized function or variable 'BPM_3156_x'.
x2 = BPM_3218_x;
xp = (x2-M11.*x1)./M12;
y1 = BPM_3156_y;
y2 = BPM_3218_y;
yp = (y2-M33.*y1)./M34;
%BPM positions array for z and x (and y) positions
z_BPM = [z_3156, z_3218];
x_BPM = [x1, x1 + xp * diff(z_BPM)];
y_BPM = [y1, y1 + yp * diff(z_BPM)];
%NOTE: did not transpose matrix (like in origional) because wrong
%shape for interpolation
% Interpolate x and y positions over the specific z range
x = interp1(z_BPM, x_BPM(ind_analyse, :)', z);
y = interp1(z_BPM, y_BPM(ind_analyse, :)', z);
xp = xp(ind_analyse);
yp = yp(ind_analyse);
% Calculate mean values
xmean_i = mean(x,"omitnan")*1000; % um
ymean_i = mean(y,"omitnan")*1000; % um
xpmean_i = mean(xp,"omitnan")*1000; % urad
ypmean_i = mean(yp,"omitnan")*1000; % urad
TMITmean_i = mean(BPM_2445_TMIT);
% Save the scaled values for plotting
xmean(end+1) = xmean_i;
ymean(end+1) = ymean_i;
xpmean(end+1) = xpmean_i;
ypmean(end+1) = ypmean_i;
TMITmean(end+1) = TMITmean_i;
E0_BPM_plot(end+1) = E0_BPM_plot_i;
%mean of all shots
xmean_allshots = mean(xmean);
ymean_allshots = mean(ymean);
xpmean_allshots = mean(xpmean);
ypmean_allshots = mean(ypmean);
TMITmean_allshots = mean(TMITmean);
%deviation from mean (ie, x-x0 ir y-y0)
x_deviation = xmean - xmean_allshots;
y_deviation = ymean - ymean_allshots;
xp_deviation = xpmean - xpmean_allshots;
yp_deviation = ypmean - ypmean_allshots;
TMIT_deviation = TMITmean - TMITmean_allshots;
% Store STD vals
%{
xn = length(xmean);
yn = length(ymean);
xpn = length(xpmean);
ypn = length(ypmean);
TMITn = length(TMITmean);
x_std_i = sqrt((sum(xmean-xmean_allshots)^2)/xn-1);
xp_std_i = sqrt((sum(xpmean-xpmean_allshots)^2)/xpn-1);
y_std_i = sqrt((sum(ymean-ymean_allshots)^2)/yn-1);
yp_std_i = sqrt((sum(ypmean-ypmean_allshots)^2)/ypn-1);
TMIT_std_i = sqrt((sum(TMITmean-TMITmean_allshots)^2)/TMITn-1);
x_std(end+1) = x_std_i;
xp_std(end+1) = x_std_i;
y_std(end+1) = y_std_i;
yp_std(end+1) = yp_std_i;
TMIT_std(end+1) = TMIT_std_i;
%store std values
x_std_i = std(xmean);
y_std_i = std(ymean);
xp_std_i = std(xpmean);
yp_std_i = std(ypmean);
TMIT_std_i = std(TMITmean);
%save for plotting
x_std(end+1) = x_std_i;
y_std(end+1) = y_std_i;
xp_std(end+1) = xp_std_i;
yp_std(end+1) = yp_std_i;
TMIT_std(end+1) = TMIT_std_i;
%}
x_std_val_i = sqrt(sum((xmean - xmean_allshots).^2) / (length(xmean)-1));
x_std(end+1) = x_std_val_i;
%force matrices to have the same diemstions)
x_deviation = x_deviation(:);
y_deviation = y_deviation(:);
xp_deviation = xp_deviation(:);
yp_deviation = yp_deviation(:);
BPM_2445_TMIT = BPM_2445_TMIT(ind_analyse);
%figures
figure(1)
%x-x0 plot
subplot(3,2,1)
errorbar(E0_BPM_plot, x_deviation, x_std, 'o', 'MarkerFaceColor', 'b')
scatter(E0_BPM_plot,x_deviation,'filled')
xlabel('Slice Energy [GeV]')
ylabel('x-x_0 \mu m')
%xp-xp0 plot
subplot(3,2,2)
scatter(E0_BPM_plot,xp_deviation,'filled')
xlabel('Slice Energy [GeV]')
ylabel('x'' - x_0'' \mu m')
%y-y0 plot
subplot(3,2,3)
scatter(E0_BPM_plot,y_deviation,'filled')
xlabel('Slice Energy [GeV]')
ylabel('y-y_0 [\mu m]')
%yp-yp0 plot
subplot(3,2,4)
scatter(E0_BPM_plot,yp_deviation,'filled')
xlabel('Slice Energy [GeV]')
ylabel('y'' - y_0'' \mu m')
%BPM 2445 TMIT plot
subplot(3,2,5)
scatter(E0_BPM_plot,TMIT_deviation,'filled')
xlabel('Slice Energy [GeV]')
ylabel('Transmitted')
  1 commentaire
dpb
dpb le 1 Août 2025
Your code doesn't show how data are being acquired; is it in lots of 100 hundred values, vectors, arrays, ...?
You would have much better success to use arrays and indexing rather than all the separately named variables, then calculations could be done in a vectorized form using the abilities of MATLAB. Passing those arrays to functions inside the looping construct that returns the data would also greatly simplify the code structure.
In "I was using (end+1) to add aditional values onto an array but this does not go back and recalculate std values for prevous shots" it isn't clear why you would need to "recalculate previous shots"; those data aren't going to have changed so those previously computed std values will be the same and already saved -- unless you mean you want to be calculating a moving std or other measure instead?
Also in the above, using (end+1) to add elements is very inefficient as it requires reallocation of the array every pass. This may not be terribly bad in extra computing time for small arrays or if the number of loops is few, but is bad practice in general. Instead, preallocate the result arrays to some expected size first and then increment an index into them and store the values there. Test for the process running enough times to fill up the array; if/when does, then you can reallocate another chunk onto the existing array and continue; this is much more efficient.
But, the big thing is to factorize the calculations into a generic subroutine and pass the incoming data into it as arrays, thus eliminating the need for all the many separately-named variables.
Providing an overall description of the actual set up and the expected result would aid in folks here being able to help you refactor the code rather than trying to guess from incomplete code snippet.

Connectez-vous pour commenter.

Réponse acceptée

Aryan
Aryan le 5 Août 2025
Modifié(e) : Aryan le 5 Août 2025
Hi,
I understand that you want to display the deviation from the mean and the running standard deviation for each shot.
The core issue is that your current approach for storing the standard deviation, such as x_std(end+1) = x_std_val_i;, only appends the most recent value rather than recalculating the standard deviation for all previous shots. This do not accurately represent the running statistics of your data.
To address this, use MATLAB's built-in "std" function in conjunction with "arrayfun" to compute the running standard deviation up to each shot.
This ensures that each value of "x_std" reflects the standard deviation of all shots up to that point.
x_std = arrayfun(@(i) std(xmean(1:i), "omitnan"), 1:length(xmean));
Apply the same logic to your other variables ("ymean", "xpmean", "ypmean", "TMITmean"). This will create arrays ("x_std", "y_std", etc.) that contain the running standard deviation up to each shot.
Kindly refer to the following MathWorks documentation links for better understanding the functions used above:
Hope it helps!

Plus de réponses (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by