-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathLSDJunctionNetwork.hpp
More file actions
1921 lines (1711 loc) · 92.3 KB
/
Copy pathLSDJunctionNetwork.hpp
File metadata and controls
1921 lines (1711 loc) · 92.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// LSDJunctionNetwork
// Land Surface Dynamics ChannelNetwork
//
// An object within the University
// of Edinburgh Land Surface Dynamics group topographic toolbox
// for organizing channel routing under the Fastscape algorithm
// (see Braun and Willett, Geomorphology 2013, v180, p 170-179)
// It uses the algorithm to create channel junction networks
// that can be searched for network connectivity
//
//
// Developed by:
// Simon M. Mudd
// Martin D. Hurst
// David T. Milodowski
// Stuart W.D. Grieve
// Declan A. Valters
// Fiona Clubb
//
// Copyright (C) 2013 Simon M. Mudd 2013
//
// Developer can be contacted by simon.m.mudd _at_ ed.ac.uk
//
// Simon Mudd
// University of Edinburgh
// School of GeoSciences
// Drummond Street
// Edinburgh, EH8 9XP
// Scotland
// United Kingdom
//
// This program is free software;
// you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;
// without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the
// GNU General Public License along with this program;
// if not, write to:
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA 02110-1301
// USA
//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
/** @file LSDJunctionNetwork.hpp
@author Simon M. Mudd, University of Edinburgh
@author David Milodowski, University of Edinburgh
@author Martin D. Hurst, British Geological Survey
@author Stuart W. D. Grieve, University of Edinburgh
@author Fiona Clubb, University of Edinburgh
@version Version 0.0.1
@brief Object to create a channel network from an LSDFlowInfo object.
@details This object is built around Braun and Willett's fastscape algorithm and
contains a number of analysis tools built around drainage networks.
@date 30/08/2012
*/
#ifndef LSDJunctionNetwork_H
#define LSDJunctionNetwork_H
#include <vector>
#include <string>
#include <map>
#include "TNT/tnt.h"
#include "LSDFlowInfo.hpp"
#include "LSDRaster.hpp"
#include "LSDIndexChannel.hpp"
#include "LSDChannel.hpp"
#include "LSDStatsTools.hpp"
#include "LSDShapeTools.hpp"
using namespace std;
using namespace TNT;
///@brief Object to create a channel network from an LSDFlowInfo object.
class LSDJunctionNetwork
{
public:
/// @brief This defines a channel network, is empty
/// @author SMM
/// @date 30/07/14
LSDJunctionNetwork() { create(); }
/// @brief This defines a channel network based on a FlowInfo object and a list of source nodes.
/// @param FlowInfo LSDFlowInfo object.
/// @param Sources vector of source nodes.
/// @author SMM
/// @date 01/09/12
LSDJunctionNetwork(vector<int> Sources, LSDFlowInfo& FlowInfo)
{ create(Sources, FlowInfo); }
/// @brief Assignment operator.
LSDJunctionNetwork& operator=(const LSDJunctionNetwork& LSDR);
/// @brief this function gets the UTM_zone and a boolean that is true if
/// the map is in the northern hemisphere
/// @param UTM_zone the UTM zone. Replaced in function.
/// @param is_North a boolean that is true if the DEM is in the northern hemisphere.
/// replaced in function
/// @author SMM
/// @date 22/12/2014
void get_UTM_information(int& UTM_zone, bool& is_North);
/// @brief this gets the x and y location of a node at row and column
/// @param row the row of the node
/// @param col the column of the node
/// @param x_loc the x location (Northing) of the node
/// @param y_loc the y location (Easting) of the node
/// @author SMM
/// @date 22/12/2014
void get_x_and_y_locations(int row, int col, double& x_loc, double& y_loc);
/// @brief this gets the x and y location of a node at row and column
/// @param row the row of the node
/// @param col the column of the node
/// @param x_loc the x location (Northing) of the node
/// @param y_loc the y location (Easting) of the node
/// @author SMM
/// @date 22/12/2014
void get_x_and_y_locations(int row, int col, float& x_loc, float& y_loc);
/// @brief a function to get the lat and long of a node in the raster
/// @detail Assumes WGS84 ellipsiod
/// @param row the row of the node
/// @param col the col of the node
/// @param lat the latitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param long the longitude of the node (in decimal degrees, replaced by function)
/// Note: this is a double, because a float does not have sufficient precision
/// relative to a UTM location (which is in metres)
/// @param Converter a converter object (from LSDShapeTools)
/// @author SMM
/// @date 22/12/2014
void get_lat_and_long_locations(int row, int col, double& lat,
double& longitude, LSDCoordinateConverterLLandUTM Converter);
/// @brief This takes latitude and longitude (in WGS 84) and converts to vectors
/// of easting and northing in UTM
/// @param latitude a vector of latitudes in UTM84
/// @param longitude a vector of longitudes in WGS84
/// @param UTME The easting coordinate (is overwritten)
/// @param UTMN The northing coordinate (is overwritten)
/// @author SMM
/// @date 13/02/2017
void get_x_and_y_from_latlong(vector<float> latitude, vector<float> longitude,
vector<float>& UTME,vector<float>& UTMN);
///@brief Recursive add_to_stack routine to build the junction tree, from Braun and Willett (2012)
///equations 12 and 13.
///@param lm_index Integer
///@param j_index Integer
///@param bl_node Integer
/// @author SMM
/// @date 01/09/12
void add_to_stack(int lm_index, int& j_index, int bl_node);
// this returns all the upstream junction of a junction_number_outlet
/// @brief This returns all the upstream junction of a junction_number_outlet.
/// @param junction_number_outlet Integer of junction of interest.
/// @return integer vector containing all the junction numbers upslope
/// of the chosen junction.
/// @author SMM
/// @date 01/09/12
vector<int> get_upslope_junctions(int junction_number_outlet);
/// @brief This finds all the junctions that are source junctions upslope of a
/// given junction
/// @param junction_number_outlet The junction number of the outlet
/// @return source_junctions a vector of junction numbers: these are the sources
/// @author SMM
/// @date 18/05/2016
vector<int> get_all_source_junctions_of_an_outlet_junction(int junction_number_outlet);
/// @brief This finds all the nodes that are source nodes upslope of a
/// given junction
/// @param junction_number_outlet The junction number of the outlet
/// @return source_nodes a vector of node numbers: these are the sources
/// the nodes are node indices from the FlowInof object
/// @author SMM
/// @date 19/05/2016
vector<int> get_all_source_nodes_of_an_outlet_junction(int junction_number_outlet);
/// @brief this function gets a list of the junction indices of the donors to a particular junction
/// @detail IMPORTANT: this has only retained the string "node" to keep equivalence
/// with the FlowInfo object. It takes junctions and returns junctions!!
/// Also note that base level nodes have themselves as a donor
/// @param node this is the nodeindex of the node for which you want to find the donors
/// @return a vector of the donor nodes
/// @author SMM
/// @date 15/06/2015
vector<int> get_donor_nodes(int node);
/// @brief This function maps a junction onto the indexing of the upslope junction list.
///
/// @details If you get an upslope junction list the indexing starts at the furthest downslope
/// junction. All of the junction pointing refers to the master junction list however.
/// @param upslope_junctions Vector of upslope junctions of interest.
/// @param junction Integer of junction of interest.
/// @return Vector of mapped junctions.
/// @author SMM
/// @date 01/09/12
int map_junction_to_upslope_junction_list(vector<int> upslope_junctions, int junction);
// functions for finding specific basins
/// @brief This function returns the maximum stream order in the DEM.
/// @return Maximum stream order as an integer.
/// @author SMM
/// @date 01/09/12
int get_maximum_stream_order();
/// @brief This function returns the number of streams of a given stream order
/// @param FlowInfo LSDFlowInfo object
/// @param stream_order Stream order of interest
/// @return integer with number of streams.
/// @author FJC
/// @date 15/03/16
int get_number_of_streams(LSDFlowInfo& FlowInfo, int stream_order);
/// @brief This calculates the junction angles based on a number of junctions
/// @param JunctionList a list of junctions
/// @param FlowInfo an LSDFlowInfo object
/// @return A vector of junction angles
/// @author SMM
/// @date 21/04/2017
map<int, vector<float> > calculate_junction_angles(vector<int> JunctionList, LSDFlowInfo& FlowInfo);
/// @brief This function gets the mean and standard error of every junction angle
/// upslope of a given junction
/// @param target_junction The target junction
/// @param FlowInfo an LSDFlowInfo object
/// @return A vector of that has the mean and the standard error of the upslope junction angles
/// @author SMM
/// @date 23/04/2017
vector<float> calculate_junction_angle_statistics_upstream_of_junction(int target_junction, LSDFlowInfo& FlowInfo);
/// @brief Overloaded function similar to above but removes any junctions not greater than
/// threshold SO
/// @param target_junction The target junction
/// @param FlowInfo an LSDFlowInfo object
/// @param threshold_SO threshold stream order to keep junctions (greater than this)
/// @return A vector of that has the stats of the upslope junction angles
/// @author FJC
/// @date 08/03/18
vector<float> calculate_junction_angle_statistics_upstream_of_junction(int target_junction, LSDFlowInfo& FlowInfo, int threshold_SO);
/// @brief This takes the junction angle statistics for all basins of a given order
/// @param FlowInfo the LSDFlowInfo object
/// @param BasinOrder the basin order of interest
/// @param junction_list a vector of ints holding the junctions of interest
/// is replaced in the function
/// @param junction_angle_averages Average junction angles
/// is replaced in the function
/// @param junction_angle_stder a vector junction angle standard errors
/// is replaced in the function
/// @param N_junctions a vector of ints holding the numer of junctions in each larger basin
/// is replaced in the function
/// @author SMM
/// @date 24/04/2017
void calculate_junction_angle_statistics_for_order(LSDFlowInfo& FlowInfo, int BasinOrder,
vector<int>& junction_list,
vector<float>& junction_angle_averages,
vector<float>& junction_angle_stderr,
vector<int>& N_junctions);
/// @brief This function takes a vector of basin junctions and prints statistics of all the junctions
/// upstream of each basin junction to a CSV. The statstics are separated by stream order.
/// @param JunctionList list of basin junctions
/// @param FlowInfo LSDFlowInfo object
/// @param csv_outname name of output csv
/// @author FJC
/// @date 08/03/18
void print_junction_angles_from_basin_list(vector<int> JunctionList, LSDFlowInfo& FlowInfo, string csv_outname);
/// @brief This prints the junction angles to a csv file
/// @param JunctionList The list of junctions to analyze. If this is an empty vector,
/// the code analyses all junctions in the DEM
/// @param FlowInfo The LSDFlowInfo object
/// @param csv_name The name of the file. Needs full path and csv extension
/// @author SMM
/// @date 23/04/2017
void print_junction_angles_to_csv(vector<int> JunctionList, LSDFlowInfo& FlowInfo,
string csv_name);
/// @brief This gets the junction number of a given node.
/// @param Node
/// @param FlowInfo Flow Info object
/// @return JunctionNumber
/// @author FC
/// @date 31/10/13
int get_Junction_of_Node(int Node, LSDFlowInfo& FlowInfo);
/// @brief This gets the junction number all the sources
/// @param FlowInfo Flow Info object
/// @return A vector of junctions from all the sources
/// @author SMM
/// @date 08/05/15
vector<int> get_Junctions_of_Sources(LSDFlowInfo& FlowInfo);
/// @brief returns the penultimate node of the stream link below given junction
/// @param upstream junction of desired stream link
/// @param FlowInfo object
/// @return node index (for FlowInfo) of penultimate node in stream link
/// @author DTM
/// @date 04/06/14
int get_penultimate_node_from_stream_link(int upstream_junction, LSDFlowInfo& FlowInfo);
// this prints the link array to raster
/// @brief This sends the StreamOrderArray to a LSDIndexRaster.
/// @return LSDIndexRaster of StreamOrderArray.
/// @author SMM
/// @date 01/09/12
LSDIndexRaster StreamOrderArray_to_LSDIndexRaster();
/// @brief Method to flatten an te stream order array and place the non NDV values in a csv file.
/// @detail Each value is placed on its own line, so that it can be read more quickly in python etc.
/// It includes the lat long coordinates in CSV, in WGS84 coordinate system EPSG:4326
/// @param FileName_prefix The prefix of the file to write, if no path is included it will write to the current directory.
/// The csv extension is added automatically.
/// @author SMM
/// @date 12/11/16
void StreamOrderArray_to_WGS84CSV(string FileName);
/// @brief This prints a stream network to a csv in WGS84
/// @detail This function prints a network that is ordered by sources, channels
/// have stream orders and junction numbers attached
/// param FlowInfo the flow info object which translates node indices to actual points
/// @param FileName_prefix The prefix of the file to write, if no path is included it will write to the current directory.
/// The csv extension is added automatically.
/// @author SMM
/// @date 14/11/16
void PrintChannelNetworkToCSV(LSDFlowInfo& flowinfo, string fname_prefix);
/// @brief This sends the JunctionArray to a LSDIndexRaster.
/// @return LSDIndexRaster of JunctionArray.
/// @author SMM
/// @date 01/09/12
LSDIndexRaster JunctionArray_to_LSDIndexRaster();
/// @brief This sends the JunctionIndexArray to a LSDIndexRaster.
/// @return LSDIndexRaster of JunctionIndexArray.
/// @author SMM
/// @date 01/09/12
LSDIndexRaster JunctionIndexArray_to_LSDIndexRaster();
/// @brief Turns the StreamOrderArray into a binary rastser where 1 is channel and 0 is hillslope.
/// @return Binary LSDIndexRaster of the channel network.
/// @author SMM
/// @date 01/09/12
LSDIndexRaster StreamOrderArray_to_BinaryNetwork_LSDIndexRaster();
/// @brief This gets the largest donor junction to the baselevel nodes so that you can
/// automate basin selection. (e.g. for use with chi analysis)
///
/// @details This function returns a integer vector containing the junction number of the largest
/// donor catchment (i.e. donor junction with greatest drainage area) upslope of each
/// baselevel node. These can then be used as the starting locations for performing chi
/// analysis.
///
/// IMPORTANT: the junctions always point downstream since they can have one and only
/// one receiver. However, for a basin of given order, this starts just upstream of the
/// confluence to the next basin order. So the basin <b>INCLUDES</b> the channel flowing
/// downstream to the penultamite node.
/// @return Integer vector containing the junction number of the largest donor catchment.
/// @author MDH
/// @date 19/6/13
vector<int> get_BaseLevel_DonorJunctions();
/// @brief This function takes a list of junctions and then prunes
/// junctions based whether they drain from the edge. This attempts to
/// remove junctions that are through-flowing and thus do not have the
/// correct drainage area
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 16/05/16
vector<int> Prune_Junctions_Edge(vector<int>& BaseLevelJunctions_Initial,LSDFlowInfo& FlowInfo);
/// @brief This function takes a list of junctions and then prunes
/// junctions based whether they drain from the edge. This attempts to
/// remove junctions that are through-flowing and thus do not have the
/// correct drainage area
/// @detail Only gets the donor of the baselelve donor to ignore the nodes
/// near the outlet, which often intersect nodata in cut DEMs
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param TestRaster A raster that is just used to look for nodata
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 29/05/17
vector<int> Prune_Junctions_Edge_Ignore_Outlet_Reach(vector<int>& BaseLevelJunctions_Initial,
LSDFlowInfo& FlowInfo, LSDRaster& TestRaster);
/// @brief This function looks through all baselevel nodes and then
/// looks for the largest basin that is not influenced by the edge.
/// It returns a vector of these junctions.
/// @detail Note that it only returns one basin per baselevel node at most
/// so might not do a great job of space filling.
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param TestRaster A raster that is just used to look for nodata
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 21/06/17
vector<int> Prune_To_Largest_Complete_Basins(vector<int>& BaseLevelJunctions_Initial,
LSDFlowInfo& FlowInfo, LSDRaster& TestRaster,
LSDIndexRaster& FlowAcc);
/// @brief This function removes basins that fall outside a contributing pixel
/// Window
/// @param Junctions_Initial a vector of integers containg an inital
/// list of junctions
/// @param FlowInfo The LSDFlowInfo object
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @param lower_limit The minimum number of contributing pixels
/// @param upper_limit The maximum number of contributing pixels
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 26/06/17
vector<int> Prune_Junctions_By_Contributing_Pixel_Window(vector<int>& Junctions_Initial,
LSDFlowInfo& FlowInfo, LSDIndexRaster& FlowAcc,
int lower_limit, int upper_limit);
/// @brief This function removes basins that fall outside a contributing pixel
/// Window, those that are bounded by nodata, and those that
/// are nested. A rather intensive pruning process that hopeuflly results
/// in a number of basins that are a similar size
/// @detail This doesn't just look for baselevel junctions: it goes through
/// all junctions in the DEM. Warning: computationally expensive!
/// @param FlowInfo The LSDFlowInfo object
/// @param TestRaster A raster that is just used to look for nodata
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @param lower_limit The minimum number of contributing pixels
/// @param upper_limit The maximum number of contributing pixels
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 26/06/17
vector<int> Prune_Junctions_By_Contributing_Pixel_Window_Remove_Nested_And_Nodata(LSDFlowInfo& FlowInfo,
LSDRaster& TestRaster, LSDIndexRaster& FlowAcc,
int lower_limit, int upper_limit);
/// @brief This function removes basins that are nested within any other
/// basin in the list
/// @param Junctions_Initial a vector of integers containg an inital
/// list of junctions
/// @param FlowInfo The LSDFlowInfo object
/// @param TestRaster A raster that is just used to look for nodata
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 26/06/17
vector<int> Prune_Junctions_If_Nested(vector<int>& Junctions_Initial,
LSDFlowInfo& FlowInfo, LSDIndexRaster& FlowAcc);
/// @brief This function takes a list of junctions and then prunes
/// junctions based on their number of contributing pixels
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @param Threshold The minimum number of accumulated pixels needed to keep
/// a base level node.
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 16/05/16
vector<int> Prune_Junctions_Area(vector<int>& BaseLevelJunctions_Initial,LSDFlowInfo& FlowInfo,
LSDIndexRaster& FlowAcc, int Threshold);
/// @brief This function takes a list of junctions retains ONLY the larges bains
/// The junction is returned as an int vector so that it can be passed to other functions
/// requiring junction lists.
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 03/06/16
vector<int> Prune_Junctions_Largest(vector<int>& BaseLevelJunctions_Initial,LSDFlowInfo& FlowInfo,
LSDIndexRaster& FlowAcc);
/// @brief This function takes a list of junctions retains ONLY the junctions
/// that have an outlet elevation greater or less than the threshold elevation
/// Selection of greater or lower is determined by bool keep_junctions_below_threshold
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param Elev an LSDRaster of elevation
/// @param threshold_elevation the threshold elevation to kepp
/// @param keep_junctions_below_threshold if true keep junctions below threshold
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 18/01/18
vector<int> Prune_Junctions_Threshold_Elevation(vector<int>& BaseLevelJunctions_Initial,
LSDFlowInfo& FlowInfo, LSDRaster& Elev,
float threshold_elevation, bool keep_junctions_below_threshold);
/// @brief This function takes a list of junctions retains ONLY the junctions
/// that have an outlet elevation with an elevation window
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param Elev an LSDRaster of elevation
/// @param lower_threshold the lower threshold elevation
/// @param upper_threshold the lower threshold elevation
/// @return a pruned list of base level nodes
/// @author SMM
/// @date 19/01/18
vector<int> Prune_Junctions_Elevation_Window(vector<int>& BaseLevelJunctions_Initial,
LSDFlowInfo& FlowInfo, LSDRaster& Elev,
float lower_threshold, float upper_threshold);
/// @brief You give this a list of junction numbers and it returns the
/// number of upslope pixels
/// @param BaseLevelJunctions_Initial a vector of integers containg an inital
/// list of base level nodes
/// @param FlowInfo The LSDFlowInfo object
/// @param FlowAcc an LSDIndexRaster with the number of pixels for flow accumulation
/// @param Threshold The minimum number of accumulated pixels needed to keep
/// a base level node.
/// @return a vector with the N contributing pixels for the junctions specified
/// @author SMM
/// @date 21/06/17
vector<int> get_contributing_pixels_from_specified_junctions(vector<int>& JunctionList,
LSDFlowInfo& FlowInfo, LSDIndexRaster& FlowAcc);
/// @brief Get Junction number at a location.
/// @param row Integer row index.
/// @param col Integer column index.
/// @return Junction number at location row,col.
/// @author SMM
/// @date 01/09/12
int retrieve_junction_number_at_row_and_column(int row,int col)
{ return JunctionIndexArray[ row ][ col ]; }
/// @brief Function for printing out the longest channel upstream of a point.
/// @param outlet_junction
/// @param FInfo LSDFlowInfo object.
/// @param dist_code
/// @param dist_from_outlet
/// @author SMM
/// @date 01/09/12
void print_longest_channel(int outlet_junction, LSDFlowInfo& FInfo, LSDIndexRaster& dist_code,
LSDRaster& dist_from_outlet);
/// @brief Prints the information about the junctions to file.
/// @param filename Output filename to be appended with '.txt'.
/// @author SMM
/// @date 01/09/12
void print_junction_info_vectors(string filename);
/// @brief This generates an LSDChannelIndex object given a junction.
///
/// @details NOTE: junctions start at the upstream end of the channel section.
/// @param start_junction Junction to extract the channel from.
/// @param FlowInfo LSDFlowInfo object.
/// @return The channel for the given junction.
/// @author SMM
/// @date 01/09/12
LSDIndexChannel generate_link_index_channel_from_junction(int start_junction,LSDFlowInfo& FlowInfo);
/// @brief This function extracts the longest channel originating from a junction number
/// outlet_junction.
/// @param outlet_junction Outlet of junction.
/// @param FInfo LSDFlowInfo object.
/// @param dist_from_outlet Distance from outlet junction.
/// @return LSDIndexRaster of the longest channel.
/// @author SMM
/// @date 01/09/12
LSDIndexChannel generate_longest_index_channel_from_junction(int outlet_junction,LSDFlowInfo& FInfo,LSDRaster& dist_from_outlet);
// this generates the longest channel in a basin. The basin starts where a channel of
// some order intersects with a channel of higher order. So the bain includes the
// basin junction, but also the channel flowing downstream from this basin
// junction
// It starts from the node of the reciever junction, so if one were to extract
// the basin from this node one would get a basin that starts one node upstream from
// the lowest node in this
/// @brief This generates the longest channel in a basin.
///
/// @details The basin starts where a channel of some order intersects with a
/// channel of higher order. So the bain includes the basin junction, but also
/// the channel flowing downstream from this basin junction. It starts from the
/// node of the reciever junction, so if one were to extract the basin from
/// this node one would get a basin that starts one node upstream from the lowest node in this.
/// @param basin_junction
/// @param FInfo LSDFlowInfo object.
/// @param dist_from_outlet
/// @return LSDIndexRaster of the longest channel.
/// @author SMM
/// @date 01/09/12
LSDIndexChannel generate_longest_index_channel_in_basin(int basin_junction, LSDFlowInfo& FInfo,
LSDRaster& dist_from_outlet);
/// @brief This generates the upstream source nodes from a vector of basin junctions
///
/// @details The basin starts where a channel of some order intersects with a
/// channel of higher order. So the bain includes the basin junction, but also
/// the channel flowing downstream from this basin junction. It starts from the
/// node of the reciever junction, so if one were to extract the basin from
/// this node one would get a basin that starts one node upstream from the lowest node in this.
/// @param basin_junction
/// @param FInfo LSDFlowInfo object.
/// @param dist_from_outlet
/// @return LSDIndexRaster of the longest channel.
/// @author FJC
/// @date 21/03/17
vector<int> get_basin_sources_from_outlet_vector(vector<int> basin_junctions, LSDFlowInfo& FlowInfo,
LSDRaster& dist_from_outlet);
/// @brief This extracts the junction numbers, in a vector of integers, of all basins of a
/// given order.
///
/// @details For basins, the basin includes nodes downstream of the basinJunction,
/// until the penulatmite node in this downstream channel.
///
/// IMPORTANT: the junctions always point downstream since they can have one and only
/// one receiver. However, for a basin of given order, this starts just upstream of the
/// confluence to the next basin order. So the basin <b>INCLUDES</b> the channel flowing
/// downstream to the penultamite node.
/// @param BasinOrder Integer of the basin order.
/// @param FlowInfo LSDFlowInfo object.
/// @return Vector of junctions of basins of given order.
/// @author SMM
/// @date 01/09/12
vector<int> extract_basins_order_outlet_junctions(int BasinOrder, LSDFlowInfo& FlowInfo);
// this function gets the outlet node of a list of basins, contined within the
// BasinOutletJunctions parameter. The basin outlet node is _DOWNSTREAM_ from
// the outlet junction, it is the penultamite node of the channel index.
/// @brief this function gets the outlet node of a list of basins.
///
/// @details The basin outlet node is _DOWNSTREAM_ from the outlet junction,
/// it is the penultamite node of the channel index.
/// @param BasinOutletJunctions
/// @param FlowInfo LSDFlowInfo object.
/// @return Vector of outlet nodes of basins.
/// @author SMM
/// @date 01/09/12
vector<int> extract_basins_order_outlet_nodes(vector<int>& BasinOutletJunctions, LSDFlowInfo& FlowInfo);
/// @brief This function gets tributaries along a continous channel.
///
/// @details What it does is goes down the index channel looking at the JunctionIndexArray
/// to see if there is a junction. If it hits a junction then all the contributing junction
/// it overwrites two vectors: \n
/// tributary_junctions, which lists all junctions whose reciever is the main
/// stem and nodes_on_main_stem_of_tributaries, which are the njodes on the
/// main_stem LSDIndexChannel where the tributaries intersect the main stem
/// this second vector is used to calcualte the chi values of the downstream node
/// of the tributaries.
/// @param MainStem LSDIndexChannel of the main stem.
/// @param FlowInfo LSDFlowInfo object.
/// @param tributary_junctions
/// @param nodes_on_main_stem_of_tributaries
/// @author SMM
/// @date 01/09/12
void extract_tributary_junctions_to_main_stem(LSDIndexChannel& MainStem, LSDFlowInfo& FlowInfo,
vector<int>& tributary_junctions,
vector<int>& nodes_on_main_stem_of_tributaries);
/// @brief this function gets the tributary junctions upstream of the starting_junction based on
/// pruning criteria.
///
/// @details This function extracts tributaries juncions to the main stem of the
/// channel, then selects a sample based on various criteria set by an integer
/// called pruning switch \n\n
/// pruning_switch == 0 channels are only added if they exceed a threshold drainage area \n
/// pruning_switch == 1 channels are only added if the ratio between them
/// and the mainstem exceeds a certain value (pruning_threshold)\n
/// pruning_switch == 2 channels are only added if the ratio between them
/// and the area of the mainstem _at the junction_ exceeds a certain value\n
/// pruning_switch == 3 channels are only added if the channel order is >= threshold.
/// @param FlowInfo LSDFlowInfo object.
/// @param ChannelNetwork LSDJunctionNetwork object.
/// @param starting_junction
/// @param DistanceFromOutlet LSDIndexRaster of outlet distances.
/// @param pruning_switch
/// @param pruning_threshold
/// @return Pruned tributary junctions.
/// @author DTM
/// @date 30/04/2013
vector<int> get_pruned_tributaries_from_main_stem(LSDFlowInfo& FlowInfo, LSDJunctionNetwork& ChannelNetwork,
int starting_junction, LSDRaster& DistanceFromOutlet,
int pruning_switch, float pruning_threshold);
/// @brief This function extracts basin nodes according to their accumulated drainage area.
/// @param Threshold Threshold drainage area.
/// @param FlowInfo LSDFlowInfo object.
/// @return Vector of basin nodes.
/// @author DTM
/// @date 07/05/2013
vector<int> extract_basin_nodes_by_drainage_area(float DrainageAreaThreshold, LSDFlowInfo& FlowInfo);
/// @brief This function extracts nodes where the basins of both tributaries are greater
/// than a certain drainage area threshold. Moves downstream from sources to baselevel so that
/// nested catchments will be selected
/// @param FlowInfo LSDFlowInfo object.
/// @param DrainageAreaThreshold Threshold drainage area.
/// @return Vector of basin nodes. These are the nodes just upstream of the outlet junction at
/// the confluence of the basins.
/// @author FJC
/// @date 10/01/17
vector<int> extract_basin_nodes_above_drainage_area_threshold(LSDFlowInfo& FlowInfo, float DrainageAreaThreshold);
/// @brief This function checks all of the basin nodes to check if they fall within a mask
/// (input raster). If they fall within the mask raster then the first node upstream
/// not in the mask is selected.
/// @param basin_nodes vector of basin nodes
/// @param FlowInfo LSDFlowInfo object
/// @param MaskRaster raster to use as mask
/// @return vector with the modified basin nodes
/// @author FJC
/// @date 31/01/17
vector<int> modify_basin_nodes_from_mask(vector<int> basin_nodes, LSDFlowInfo& FlowInfo, LSDRaster& MaskRaster);
/// @brief This function extracts basin junctions from a list of basin outlet nodes.
/// @param basin_nodes list of basin outlet nodes
/// @param FlowInfo LSDFlowInfo object
/// @return vector of basin junctions
/// @author FJC
/// @date 15/01/2014
vector<int> extract_basin_junctions_from_nodes(vector<int> basin_nodes, LSDFlowInfo& FlowInfo);
/// @brief This function gets the node indices of outlets of basins of a certain order
///
/// @details IMPORTANT: The junctions always point downstream since they can have one and only
/// one receiver. However, for a basin of given order, this starts just upstream of the
/// confluence to the next basin order. So the basin <b>INCLUDES</b> the channel flowing
/// downstream to the penultamite node.
///
/// @param basin_junction Junction of basin to be extracted.
/// @param basin_reference_number Reference number for printing to the IndexRaster.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of extracted basin.
/// @author SMM
/// @date 01/09/12
LSDIndexRaster extract_basin_from_junction(int basin_junction, int basin_reference_number, LSDFlowInfo& FlowInfo);
/// @brief This function converts a list of sources used to generate the initial channel network
/// into a list of junction indexes of channel heads which can be used to extract hollows.
/// @param Sources A vector of source nodes that correspond to channel heads.
/// @param FlowInfo LSDFlowInfo object.
/// @return A vector of junction indexes for each channel head.
/// @author SWDG
/// @date 05/12/13
vector<int> Get_Channel_Head_Junctions(vector<int> Sources, LSDFlowInfo& FlowInfo);
/// @brief This function extracts a single hollow from a given channel head junction.
///
/// @details The junction index of channel heads can be extracted using LSDJunctionNetwork.Get_Channel_Head_Junctions.
/// @param CH_junction Junction index to extract.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of the extracted hollow, coded with junction number.
/// @author SWDG
/// @date 05/12/13
LSDIndexRaster extract_hollow(int CH_junction, LSDFlowInfo& FlowInfo);
/// @brief This function extracts a series of hollows from a vector of channel head junctions.
///
/// @details The junction index of channel heads can be extracted using LSDJunctionNetwork.Get_Channel_Head_Junctions.
/// @param CH_junctions Vector of juntions to extract.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of the extracted hollows, coded with junction numbers.
/// @author SWDG
/// @date 05/12/13
LSDIndexRaster extract_hollow(vector<int> CH_junctions, LSDFlowInfo& FlowInfo);
/// @brief This function gets the an LSDIndexRaster of basins draining from a vector of junctions.
///
/// @details IMPORTANT: The junctions always point downstream since they can have one and only
/// one receiver. However, for a basin of given order, this starts just upstream of the
/// confluence to the next basin order. So the basin <b>INCLUDES</b> the channel flowing
/// downstream to the penultamite node.
///
/// @param basin_junctions Vector of junction numbers of basins to be extracted.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of extracted basin.
/// @author SMM
/// @date 01/09/12
LSDIndexRaster extract_basins_from_junction_vector(vector<int> basin_junctions, LSDFlowInfo& FlowInfo);
/// @brief This function gets an LSDIndexRaster of basins draining from a vector of junctions.
///
/// @details IMPORTANT: The junctions always point downstream since they can have one and only
/// one receiver. However, for a basin of given order, this starts just upstream of the
/// confluence to the next basin order. So the basin <b>INCLUDES</b> the channel flowing
/// downstream to the penultamite node.
/// UPDATED so that if basins are nested, they don't overwrite each other - basins are
/// sorted by the number of contributing pixels, and the smaller basins are written
/// first.
///
/// @param basin_junctions Vector of junction numbers of basins to be extracted.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of extracted basin.
/// @author FJC
/// @date 10/01/17
LSDIndexRaster extract_basins_from_junction_vector_nested(vector<int> basin_junctions, LSDFlowInfo& FlowInfo);
/// @brief This function gets the an LSDIndexRaster of basins draining from a vector of junctions.
/// @details IThis is a highly rudimentary version, which just collects
/// all the upslope nodes.
/// @param basin_junctions Vector of junction numbers of basins to be extracted.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of extracted basin.
/// @author SMM
/// @date 08/05/15
LSDIndexRaster extract_basins_from_junctions_rudimentary(vector<int> junctions, LSDFlowInfo& FlowInfo);
/// @brief Basin extraction - extracts all drainage basins of specified stream order.
/// @param BasinOrder Integer basin order to extract.
/// @param FlowInfo LSDFlowInfo object.
/// @return LSDIndexRaster of extracted basins.
/// @author DTM
/// @date 17/10/2012
LSDIndexRaster ExtractBasinsOrder(int BasinOrder, LSDFlowInfo& FlowInfo);
/// @brief This function extracts the juctions of all non-beheaded drainage basins of a given order, n.
/// @param BasinOrder Integer basin order to extract.
/// @param FlowInfo LSDFlowInfo object.
/// @return Vector of junction indexes.
/// @author SWDG
/// @date 24/10/2013
vector<int> ExtractBasinJunctionOrder(int BasinOrder, LSDFlowInfo& FlowInfo);
/// @brief This function extracts the juctions of all non-beheaded drainage basins of a given order, n.
/// Like the previous version but in this case includes basins at the edge (abutting nodata)
/// @param BasinOrder Integer basin order to extract.
/// @param FlowInfo LSDFlowInfo object.
/// @return Vector of junction indexes.
/// @author SMM
/// @date 29/04/2017
vector<int> ExtractBasinJunctionOrderKeepEdgeBasins(int BasinOrder, LSDFlowInfo& FlowInfo);
/// @brief Get farthest upslope hilltops.
///
/// @details This function looks at all the source junctions in a network
/// upstream of a given junction and returns the node index of the
/// hilltop node that is the farthest upstream from the source junction
/// @param JunctionNumber the junction number upstream of which you want to search for sources
/// @param FlowInfo the flow info object
/// @param FlowDistance distance upslope
/// @return vector<int> a vector of node indices to the ridge nodes that are farthest upslope
/// of the sources
/// @author SMM
/// @date 26/09/2013
vector<int> FindFarthestUpslopeHilltopsFromSources(int JunctionNumber, LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance);
/// @brief This function generates LSDChannels that run from the hilltops above
/// all the sources of the junction JunctionNumber
/// @author SMM
/// @date 26/09/2013
int GetChannelHeadsChiMethodFromNode(int NodeNumber,
int MinSegLength, float A_0, float m_over_n,
LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance, LSDRaster& ElevationRaster);
/// @brief This function generates LSDChannels that run from the hilltops above
/// all the sources from the valley network down to a specified number of downstream junctions below
/// the sources
/// @author FJC
/// @date 10/09/15
int GetChannelHeadsChiMethodFromSourceNode(int NodeNumber,
int MinSegLength, float A_0, float m_over_n,
LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance, LSDRaster& ElevationRaster, int NJunctions);
/// @brief This function generates LSDChannels that run from the hilltops above
/// all the sources from the valley network down to a specified number of downstream junctions below
/// the sources and writes the profile to csv
/// @author FJC
/// @date 23/12/16
void write_valley_hilltop_chi_profiles_to_csv(vector<int> sources, float A_0, float m_over_n, LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance, LSDRaster& ElevationRaster, int NJunctions, string output_path, string DEM_ID);
/// @brief This function generates an LSDIndexRaster of the channel that runs from
/// the hilltop above the furthest upslope source of the junction JunctionNumber
/// @param BasinOrder
/// @param MinSegLength
/// @param A_0
/// @param m_over_n
/// @param FlowInfo
/// @param FlowDistance
/// @param ElevationRaster
/// @return LSDIndexRaster with channel
/// @author FJC
/// @date 21/08/15
LSDIndexRaster GetChannelfromDreich(int NodeNumber, int MinSegLength, float A_0, float m_over_n,
LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance, LSDRaster& ElevationRaster, string path_name, int NJunctions);
/// @brief This function returns all potential channel heads in a DEM. It looks for
/// channel heads organized by a basin order which is fed to the code
/// The basin order just determines how far downstream the algorithm looks for the 'fluvial'
/// section.
/// It returns a vector<int> of nodeindices where the channel heads are
/// @return vector<int> a vector of node_indices of potential channel heads
/// @author SMM
/// @date 26/09/2013
// vector<int> GetChannelHeadsChiMethodBasinOrder(int BasinOrder,
// int MinSegLength, float A_0, float m_over_n,
// LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance,
// LSDRaster& ElevationRaster);
/// @brief This function returns all potential channel heads in a DEM. It looks for
/// channel heads based on the outlet junctions of the valleys (which are identified by looking
/// for portions of the landscape with 10 or more nodes with a high curvature that are linked)
/// @param ValleyJunctions
/// @param MinSegLength
/// @param A_0
/// @param m_over_n
/// @param FlowInfo
/// @param FlowDistance
/// @param ElevationRaster
/// @return vector<int> a vector of node_indices of potential channel heads
/// @author FC
/// @date 31/10/2013
vector<int> GetChannelHeadsChiMethodFromValleys(vector<int> ValleyNodes,
int MinSegLength, float A_0, float m_over_n,
LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance,
LSDRaster& ElevationRaster);
/// @brief This function returns all potential channel heads in a DEM. It looks for
/// channel heads based on the valley source nodes identified as concave parts of the landscape
/// @param ValleyJunctions
/// @param MinSegLength
/// @param A_0
/// @param m_over_n
/// @param FlowInfo
/// @param FlowDistance
/// @param ElevationRaster
/// @param NJunctions number of downstream junctions to run the channel profiles from
/// @return vector<int> a vector of node_indices of potential channel heads
/// @author FC
/// @date 10/09/15
vector<int> GetChannelHeadsChiMethodFromSources(vector<int> ValleySources,
int MinSegLength, float A_0, float m_over_n,
LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance,
LSDRaster& ElevationRaster, int NJunctions);
/// @brief This function returns all channels in the DEM that the DrEICH algorithm uses for segiment fitting.
/// It looks for channels based on the outlet junctions of valleys.
/// It returns a LSDIndexRaster with the channels.
/// @param ValleyNodes
/// @param MinSegLength
/// @param A_0
/// @param m_over_n
/// @param FlowInfo
/// @param FlowDistance
/// @param ElevationRaster
/// @return LSDIndexRaster with all channels
/// @author FJC
/// @date 21/08/15
LSDIndexRaster GetChannelsDreich(vector<int> ValleySources, int MinSegLength, float A_0, float m_over_n,
LSDFlowInfo& FlowInfo, LSDRaster& FlowDistance, LSDRaster& ElevationRaster, string path_name, int NJunctions);
/// @brief This function returns a 2D array containing the locations of all pixels identified
/// as being part of the channel using chi profiles. It calculates the chi and elevation value
/// of every pixel upstream of the given junction, then bins this data and calculates the pixels
/// in the 95th percentile of each bin. Any pixels above the 95th percentile are considered part
/// of the channel, and any below are considered to be hillslopes. This is the first part of the
/// channel head prediction using chi profiles.
/// @param JunctionNumber
/// @param A_0
/// @param m_over_n
/// @param bin_width
/// @param FlowInfo Flow Info object
/// @param ElevationRaster
/// @return Array2D<float> with channel pixels
/// @author FC
/// @date 01/10/2013
Array2D<int> GetChannelHeadsChiMethodAllPixels(int JunctionNumber,