### Finding knickpoints in river profiles

Posted on Updated on

Did you know that TopoToolbox has a function to identify knickpoints in river profiles? Well, if you don’t know, now you know.

The function is called knickpointfinder. It uses an algorithm that adjusts a strictly concave upward profile to the actual profile. Offsets between the actual and the concave upward profile occur where the actual profile has convexities. Relaxing the concavity constraint where offsets attain a maximum will adjust the concave profile to the actual profile. knickpointfinder adjusts the profile iteratively until offsets fall below a specified tolerance value. Look at the animation below which probably explains more than a thousand words.

Using knickpointfinder is easy. Just see the function help to run the example whose results are shown above.

Let us know how well knickpointfinder suits your needs. Note that this algorithm is not yet published, so please give credits to our TopoToolbox paper if you are using this algorithm in your work.

## 37 thoughts on “Finding knickpoints in river profiles”

Toni Kroos said:
July 8, 2018 at 3:16 pm

I recently gained some free time, so I decided to learn TopoToolbox. What is the knickpointfinder output variable dz? I understand it is some measure of the vertical offset of the knickpoint, but how is it measured? I want to scale the tolerance properly. A tolerance of 20 [m?] (10 m DEM) led to 1000+ knickpoints (maybe more noise than signal).

wschwanghart responded:
July 8, 2018 at 7:54 pm

Hi. I’ll try to explain that soon and in more detail in a future post. knickpointfinder fits a strictly concave upward profile to the elevation profile with the constraint that the fitted curve runs below the actual profile. dz is the maximum vertical distance between the actual and the modelled profile. knickpointfinder identifies these locations iteratively. If there is one with dz >= tol, then knickpointfinder will relax the curvature constraint, so that the fitted profile obtains a sharp convex knick. The thus obtained profile is then the input for the next iteration. This procedure is repeated until there are only vertical distances dz < tol.

Hope this helps.
Cheers, W

Ivan Rojas said:
July 14, 2018 at 1:30 pm

Hello,
I am Ivan Rojas, student of master program water resources, in Chle. I am currently conducting an investigation to identify changes in the morphometry of the channels generated by tectonic processes, identifying knickpoints in river profiles. This tool that presents would be very useful in my research and I would like to know more about it, and even try it in my current research.
Thanks!

wschwanghart responded:
July 15, 2018 at 1:27 pm

Hi Ivan. Thanks for your note. I’ll try to provide some more information soon here on this blog.
Cheers, Wolfgang

Neha joshi said:
August 31, 2018 at 5:20 am

Hello
I am Neha Joshi, working as a Senior research fellow from India.I currently used the knickpointfinder using the above link. I successfully did that, but I want to plot the locations of knickpoints (which are shown over longitudinal profile) over DEM. Please guide me with the MATLAB codes for plotting knickpoint posistion over DEM.
Thanks!

wschwanghart responded:
September 12, 2018 at 1:44 pm

Dear Joshi, take a look at the second output of knickpointfinder. The structure array kp contains two elements, kp.x and kp.y. scatter(kp.x,kp.y) does the job.
Best, Wolfgang

Neha joshi said:
September 28, 2018 at 4:53 am

Hello
thanks a lot for your response. Now I could successfully plot the required points

Julieta Carolina Nóbile said:
October 9, 2018 at 5:25 pm

I find the tool very useful and straightforward, could you please give me some advice to plot the knickpoints above a DEM but with circles sizes that reflect also the offset between the actual profile and the strictly upward concave profile? I used to plot:

imageschs(DEM,[],’colormap’,’landcolor’,…
‘colorbar’,true,…
‘colorbarylabel’,’Elevation’)

hold on
scatter(kp.x,kp.y)
hold off

thanks!!!

wschwanghart responded:
October 9, 2018 at 8:34 pm

Hi Julieta, scatter takes several input arguments.
`scatter(kp.x,kp.y,kp.dz)`
would change the size of the bubbles.
`scatter(kp.x,kp.y,20,kp.dz,'filled')`
would change their bubbles.
Best, Wolfgang

Julieta Carolina Nóbile said:
October 11, 2018 at 5:28 pm

Thanks, Wolfgang, I will try that. I finally plotted it with scatter(kp.x,kp.y, kp.dz, ‘MarkerFaceColor’,’r’)
How can I save the kp results or export this data (structure array) to shapefile or table?

Yousef21 said:
November 4, 2018 at 11:44 pm

Error in STREAMobj/modify (line 96)
p = InputParser;

Error in Ornekolsun (line 10)
S = modify(S,’distance’,10000)

I have with this problem, Could you help me ?

wschwanghart responded:
November 5, 2018 at 8:51 am

Dear Yousef21, STREAMobj/modify usually doesn’t return an error. Please provide the code that would enable me to understand the error message.
Best, Wolfgang

Yousef21 said:
November 5, 2018 at 10:56 am

Cannot find an exact (case-sensitive) match for ‘InputParser’

The closest match is: inputParser in C:\Program
Files\MATLAB\R2013a\toolbox\matlab\lang\@inputParser\inputParser.m

Error in STREAMobj/modify (line 96)
p = InputParser;

Error in Yusuf2 (line 8)
S = modify(S,’distance’,10000);

Error in STREAMobj/modify (line 96) This one sir,

Yousef21 said:
November 5, 2018 at 10:55 am

Cannot find an exact (case-sensitive) match for ‘InputParser’

The closest match is: inputParser in C:\Program
Files\MATLAB\R2013a\toolbox\matlab\lang\@inputParser\inputParser.m

Error in STREAMobj/modify (line 96)
p = InputParser;

Error in Yusuf2 (line 8)
S = modify(S,’distance’,10000);

Error in STREAMobj/modify (line 96) This one sir,

wschwanghart responded:
November 5, 2018 at 1:04 pm

In addition, if you run MATLAB R2013a, you will certainly face other errors, too. Consider updating MATLAB.
Cheers, W

Yousef21 said:
November 5, 2018 at 5:36 pm

Thank you very much. I will use Topotoolbox in my master thesis. And I want to generate Chi maps. İf I have some questions, Can I ask you ? Can you help me ?

Simone Racano said:
February 24, 2019 at 7:14 pm

Hi Wolfgang,
how can I export knickpoints as a shapefile?

Ivan Rojas said:
February 25, 2019 at 1:54 am

Hello Simone and Yousef21,
I had the same difficulty converting the knickpoints in shapefile format. However, the problem is the creation of a structure that can be used to export the variable. I present the code that I applied:
After creating Knickpoints with Knickpointfinder, adjust this code:

% Generating SHP Kinckpoints
nr_Kp = numel(kp.n); knickpoint = [];
for i=1:kp.n
knickpoint(i).Geometry = deal(‘Point’);
knickpoint(i).id = i;
knickpoint(i).X = kp.x(i);
knickpoint(i).Y = kp.y(i);
knickpoint(i).distan = kp.distance(i);
knickpoint(i).z = kp.z(i);
knickpoint(i).IXgrid = kp.IXgrid(i);
knickpoint(i).order = kp.order(i);
knickpoint(i).dz = kp.dz(i);

``````fprintf('%u/%u\n',i,nr_Kp)
``````

end

Finally, export the knickpoint variable with shapewrite
I hope the solution will work for them, it worked for me.
regards

Ivan Rojas said:
February 25, 2019 at 2:11 am

Again the code, greetings

nr_Kp = numel(kp.n); knickpoint = [];
for i = 1:kp.n
knickpoint(i).Geometry = deal(‘Point’);
knickpoint(i).id = i;
knickpoint(i).X = kp.x(i);
knickpoint(i).Y = kp.y(i);
knickpoint(i).distan = kp.distance(i);
knickpoint(i).z = kp.z(i);
knickpoint(i).IXgrid = kp.IXgrid(i);
knickpoint(i).order = kp.order(i);
knickpoint(i).dz = kp.dz(i);

``````fprintf('%u/%u\n',i,nr_Kp)
``````

end

Allan López Saborío said:
February 26, 2019 at 12:15 am

Hi Ivan, I get this message:
knickpoint(i).Geometry = deal(‘Point’);

Error: The input character is not valid in MATLAB statements or expressions.

Ivan Rojas said:
February 26, 2019 at 1:58 am

Hello Allan López,
In the following code I will present the code for a DEM as an example, it works for me. Try entering your DEM and the destination path to save the file. I hope it works equally for you.
Regards, Ivan.

DEM = GRIDobj(‘C:\example.tif’);
FD = FLOWobj(DEM,’preprocess’,’carve’);
S = STREAMobj(FD,’minarea’,1000);
S = klargestconncomps(S);
zs = quantcarve(S,DEM,.5,’split’,false);
figure
[zk,kp] = knickpointfinder(S,zs,’split’,false,’plot’,true,’tol’,20);
hold on
scatter(kp.distance,kp.z,kp.dz,’sk’,’MarkerFaceColor’,’r’)
hold off

%% Generating SHP Kinckpoints
nr_Kp = numel(kp.n); kinck = [];
for i=1:kp.n
kinck(i).Geometry = deal(‘Point’);
kinck(i).id = i;
kinck(i).X = kp.x(i);
kinck(i).Y = kp.y(i);
kinck(i).distan = kp.distance(i);
kinck(i).z = kp.z(i);
kinck(i).IXgrid = kp.IXgrid(i);
kinck(i).order = kp.order(i);
kinck(i).dz = kp.dz(i);

``````fprintf('%u/%u\n',i,nr_Kp)
``````

end

%% Export knickpoints to shapefiles

shapewrite(kinck,’dir_Knick’); % insert the destination address in ‘dir_Knick’

Allan López Saborío said:
February 26, 2019 at 3:36 am

Not yet. Please, send me your email, to share my DEM with you and find out what my mistake is. good night

wschwanghart responded:
February 26, 2019 at 9:20 am

Hi Allan and Ivan,
thanks Ivan to show your code. Here is some minor edits:

```%% Generating SHP Kinckpoints
kinck = struct();
for i=1:numel(kp.x);
kinck(i).Geometry = ‘Point’;
kinck(i).id = i;
kinck(i).X = kp.x(i);
kinck(i).Y = kp.y(i);
kinck(i).distan = kp.distance(i);
kinck(i).z = kp.z(i);
kinck(i).IXgrid = kp.IXgrid(i);
kinck(i).order = kp.order(i);
kinck(i).dz = kp.dz(i);
end
```

There are probably more elegant ways to do this. Hopefully, I’ll find to write a function or blog entry on this soon. It seems a problem that many face when working with knickpointfinder.

Cheers, Wolfgang

Allan López Saborío said:
February 27, 2019 at 5:16 pm

Hi Ivan and Wolfgang !. You both were right, the symbol in ‘Point´ was responsible so I wrote it again. Excuse me for this primitive question because of my limited Matlab knowledge: How to transform the saved kinck in the workspace into a SHP ?

Ivan Rojas said:
February 27, 2019 at 5:33 pm

Hello Allan,
The code for convert the variable Knick in shapefile is:

```shapewrite(kinck,’dir_Knick’); % insert the destination address in ‘dir_Knick’
```

Regards, Ivan

Allan López Saborío said:
February 27, 2019 at 7:09 pm

Dear Ivan, the “receipt” to plot the KPs is working fine. I will be very busy the next weeks. Everyone Have a nice evening !. Muchas Gracias=Vielen dank= Thank you very much

Allan López Saborío said:
February 27, 2019 at 5:26 pm

It would be superb to import the XYZ points produced by Wolfgans’s KINCK into the tiny Mappingtool

Allan López Saborío said:
February 27, 2019 at 5:30 pm

I mean the MAPPINGAPP

wschwanghart responded:
February 28, 2019 at 9:10 am

Good idea. That little tool should have some import capabilities. I’ll write it on my todo list.

Allan López Saborío said:
February 27, 2019 at 5:30 pm

Does TTB support PALSAR and SENTINEL DEMs ?. Or it is only limited by hardware capabilities ?

Ivan Rojas said:
February 26, 2019 at 12:30 pm

Hello Wolfgang and Allan
Thanks Wolfgang of the adjusts of the code. it is simpler than what I had elaborated. A curious question: As I write I make comments where I can insert the code in a box, as you present them? I tried several times to attach the code, but in the comment I just put a line in a box, seeing the code very messy

I think the Allan’s error should in the code paste. When I paste the code for study the changes realized for Wolfgang, the symbol ‘ caused the error. The solution, rewrite this symbols. I made this correction and it worked well.
If the code still does not work, send me the DEM to my email extensionforestal@gmail.com. Although very soon Wolfgang will make the required adjustments. He is very attentive and will solve this situation quickly to all users.
Regards, Ivan

Simone Racano said:
February 27, 2019 at 1:30 pm

Thanks everybody for the help, the community of topotoolbox is great.
I have one last question, in topotoolbox the script streamproj is very useful to extrapolate old river baselevels, but it works only for one stream. It’s possible make a projection also considering more streams and the knickpoints extracted with knickpointfinder?

wschwanghart responded:
February 28, 2019 at 9:09 am

HI Simone, I will need to take a close look at streamproj because it has been a while since I last used this function. Maybe you will need to iterate through all knickpoints…

Simone Racano said:
February 28, 2019 at 9:32 am

Ho Wolfgang,
Yes the idea is find an envelope curve that reconstruct old river profiles giving also knickpoints of different stream segments for a selected basin

Manish Pandey said:
May 29, 2019 at 5:59 am

Hi Wolfgang,
The code you have posted, “%% Generating SHP Kinckpoints
kinck = struct();
for i=1:numel(kp.x);
kinck(i).Geometry = ‘Point’;
kinck(i).id = i;
kinck(i).X = kp.x(i);
kinck(i).Y = kp.y(i);
kinck(i).distan = kp.distance(i);
kinck(i).z = kp.z(i);
kinck(i).IXgrid = kp.IXgrid(i);
kinck(i).order = kp.order(i);
kinck(i).dz = kp.dz(i);
end
shapewrite(kinck,’C:\Users\ManishGeoscience\Documents\MATLAB\Tools\topotoolbox-master’);”
runs on my computer but when I browse the directory (‘C:\Users\ManishGeoscience\Documents\MATLAB\Tools\topotoolbox-master), there is no file with the name kinck.shp.
I don’t understand where does this file go.