Finding x value at 10% of max y value, after the max

I am trying to find the x value at 90% of my max y value, after the peak. Below is something I have tried using other MATLAB Answers and recieved an error message for (probably because I am not modifying them correctly). I am also attaching a figure of my curves. In my code I am only looking at the first blue curve. It looks like I should get a value around 41 (mm). If I leave out the "*(9/10)", I get 39 which is just the peak, but I need to get to 90% of the peak. Please let me know if you could help! Thank you in advance!
"Depth" is my x data and "SeventyMeV" is my y data.
[TenthmaxYValue, indexAtMaxY] = max(SeventyMeV)*(9/10);
xValueAtMaxYValue = Depth(indexAtMaxY(1))

Answers (2)

ICR
ICR on 15 Nov 2020
Edited: ICR on 15 Nov 2020
% Find the max value for your data
maxVal = max(SeventyMeV);
maxVal90 = round(maxVal)*(9/10); % if you have enough datapoints remove round.
% Orelse you can use round or floor whichever suits you
[row,col] = find(SeventyMeV == maxVal90);
valAt90 = SeventyMeV(row(2)); % this will be your value of 90% after the peak
depthAt90 = depth(row);

6 Comments

Thank you for helping, unfortunately MATLAB is giving an error on the "valAt90" line. It says the "Index exceeds matrix dimensions". Your suggestion seems to make logical sense, not sure what the issue is.
Also, should the [row, col] line be "==maxVal90" or should it just be "==maxVal"?
Best,
Brett
My bad. Here is the correct one
% Find the max value for your data
maxVal = max(SeventyMeV);
maxVal90 = round(maxVal*(9/10)); % if you have enough datapoints remove round.
% Orelse you can use round or floor whichever suits you
[row,col] = find(SeventyMeV == maxVal90);
valAt90 = SeventyMeV(row(2)); % this will be your value of 90% after the peak
depthAt90 = depth(row);
I appreciate your help, but it is still throwing an error on the "valAt90" line. I will look into what Star Strider said as well. Thank you!
Very odd, still saying the same thing. Also I changed the depth to Depth at the very end. Please let me know what you think.
It could be coz the maxVal90 is not present in your seventyMeV.

Sign in to comment.

It would be necessary to have a sample of your data to write specific code, so I will simply describe the procedure.
First, use findpeaks to find the peak values.
Second, use the ‘locs’ index values (second output of findpeaks) to determine the indices of the peaks.
Third, for each peak, use interp1 to interpolate the value you want, something such as:
v90(k) = interp1(y(locs(k)+[0 1]), x(locs(k)+[0 1]), 0.9*y(pks(k)), 'linear','extrap')
for each peak for k = 1:numel(locs).
I cannot figure out a way to simulate the missing data, so I am labeling this UNTESTED CODE. It should work, however it may need to be tweaked to work with your data.

6 Comments

I am looking into this now, thank you, Star Strider!
Here is my code, I edited what you provided to fit my x and y data, but am getting an error code:
Error using griddedInterpolant
Interpolation requires at least two sample points in each dimension.
Error in interp1 (line 150)
F = griddedInterpolant(X,V,method);
Error in Braggs (line 76)
v90(k) = interp1(SeventyMeV(locs(k)+[0 1]), Depth(locs(k)+[0 1]), 0.9*SeventyMeV(pk90(k)),
'linear','extrap')
[pk90,locs] = findpeaks(SeventyMeV,Depth);
k = 1:numel(locs);
v90(k) = interp1(SeventyMeV(locs(k)+[0 1]), Depth(locs(k)+[0 1]), 0.9 ...
*SeventyMeV(pk90(k)), 'linear','extrap')
Please let me know what you think!
This is the problem of not having a sample of your data to work with.
Try this:
x = 1:15; % Create Data
y = rand(1,numel(x)); % Create Data
[pks,locs] = findpeaks(y); % Peaks & Location Indices
for k = 1:numel(locs)
v90(k) = interp1(y(locs(k)+[0 1]), x(locs(k)+[0 1]), 0.9*y(locs(k)), 'linear') % X-Values At 90% After PEak
end
figure
plot(x,y)
hold on
plot(x(locs), y(locs), '^r')
plot(v90, 0.9*y(locs), 'pg')
hold off
legend('Simulated Data', 'Peaks', '90% After Peak')
That works with my simulated data.
Hey, Star Strider, this seems to be working for only some of my data sets. I wonder if it is because I am working with discrete values and I can't grab the values that aren't there. I am assuming the interpolate function should take care of that, but it only seems to be working for some of the data sets. Some of them say NaN, and others throw an error. Is there a way that instead of simply using the plot() function, I can use a functin that will trace all of my points so that every x has a y value? Then I can use your suggestion? Let me know! I appreciate your help thus far!
Again, this is a problem of not having your data to work with.
Solve the NaN probllems by adding 'extrap' to the interp1 call:
v90(k) = interp1(y(locs(k)+[0 1]), x(locs(k)+[0 1]), 0.9*y(locs(k)), 'linear','extrap') % X-Values At 90% After Peak
This may result in ‘interesting’ extrapolated values!
Another option (with or without 'extrap') is:
v90(k) = interp1(y(locs(k)+[0:2]), x(locs(k)+[0:2]), 0.9*y(locs(k)), 'linear') % X-Values At 90% After Peak
However without at least a sample of your data, I’m just left to guess as to what the probllems could be.
I leave it to you to experiment with these options.

Sign in to comment.

Asked:

on 15 Nov 2020

Commented:

on 15 Nov 2020

Community Treasure Hunt

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

Start Hunting!