//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This is an incredibly rudimentary function used to modify landslide raster // It takes a few rasters from the //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDSoilHydroRaster::NaiveLandslide(LSDRaster& FilledElevation, int initiationPixels, int MinPixels, float landslide_thickness) { // Get a flow info object // set no flux boundary conditions vector<string> boundary_conditions(4); boundary_conditions[0] = "No"; boundary_conditions[1] = "no flux"; boundary_conditions[2] = "no flux"; boundary_conditions[3] = "No flux"; // some values from the rasters float local_elev; float local_mask; // get a flow info object LSDFlowInfo FlowInfo(boundary_conditions,FilledElevation); // get the contributing pixels LSDIndexRaster ContributingPixels = FlowInfo.write_NContributingNodes_to_LSDIndexRaster(); vector<int> sources = FlowInfo.get_sources_index_threshold(ContributingPixels, initiationPixels); // get a value vector for the landslides vector<float> landslide_thicknesses; for (int i = 0; i< int(sources.size()); i++) { landslide_thicknesses.push_back(landslide_thickness); } // get the mask LSDRaster Mask = FlowInfo.get_upslope_node_mask(sources,landslide_thicknesses); // now set all points that have elevation data but not landslide data to // the value of the landslide thickness, removing data that is below the minium // pixel area for (int row = 0; row<NRows; row++) { for (int col = 0; col<NCols; col++) { local_elev = FilledElevation.get_data_element(row,col); local_mask = Mask.get_data_element(row,col); RasterData[row][col] = local_mask; // Turn nodata points into 0s if( local_mask == NoDataValue) { RasterData[row][col] = 0.0; } // remove data where there is no topographic information if( local_elev == NoDataValue) { RasterData[row][col] = NoDataValue; } } } }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // Calculate w, a hyrdological index, used in the factor of safety equation. // Call with the ratio of recharge to transmissivity. // SWDG 13/6/16 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= LSDSoilHydroRaster LSDSoilHydroRaster::Calculate_w(LSDRaster& Slope, LSDRaster& DrainageArea){ Array2D<float> w(NRows, NCols, NoDataValue); for (int i = 1; i < NRows - 1; ++i){ for (int j = 1; j < NCols - 1; ++j){ if (RasterData[i][j] != NoDataValue){ float value = RasterData[i][j] * (DrainageArea.get_data_element(i,j)/sin(Slope.get_data_element(i,j))); if (value < 1.0){ w[i][j] = value; } else{ w[i][j] = 1.0; } } } } LSDSoilHydroRaster output(NRows,NCols,XMinimum,YMinimum,DataResolution,NoDataValue,w,GeoReferencingStrings); return output; }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This prints a chi map to csv with an area threshold in m^2 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDChiTools::chi_map_to_csv(LSDFlowInfo& FlowInfo, string chi_map_fname, float A_0, float m_over_n, float area_threshold) { ofstream chi_map_csv_out; chi_map_csv_out.open(chi_map_fname.c_str()); chi_map_csv_out.precision(9); float chi_coord; double latitude,longitude; LSDCoordinateConverterLLandUTM Converter; chi_map_csv_out << "latitude,longitude,chi" << endl; LSDRaster Chi = FlowInfo.get_upslope_chi_from_all_baselevel_nodes(m_over_n, A_0, area_threshold); float NDV = Chi.get_NoDataValue(); for(int row = 0; row<NRows; row++) { for(int col = 0; col<NCols; col++) { chi_coord = Chi.get_data_element(row,col); if (chi_coord != NDV) { get_lat_and_long_locations(row, col, latitude, longitude, Converter); chi_map_csv_out << latitude << "," << longitude << "," << chi_coord << endl; } } } chi_map_csv_out.close(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=---=-=-=-=-=-=-=-=-=-=-=-=- // This function prints a chan file for assimilation into the chi analysis, // but in this cases uses a discharge rather than a drainage area // // the file format is // channel_number node_index node_on_reciever row column flow_dist elevation drainage_area // // SMM 07/05/2015 // //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= void LSDIndexChannelTree::print_LSDChannels_for_chi_network_ingestion(LSDFlowInfo& FlowInfo, LSDRaster& Elevation_Raster, LSDRaster& FlowDistance, string fname, LSDRaster& Discharge) { if (organization_switch != 1) { cout << "LSDIndexChannelTree you can't run LSDIndexChannelTree::retrieve_LSDChannels_from_tree" << endl; cout << "with this channel organization, organization switch: " << organization_switch << endl; exit(EXIT_FAILURE); } // open the outfile ofstream channelfile_out; channelfile_out.open(fname.c_str()); channelfile_out.precision(10); float m_over_n = 0.5; float A_0 = 1; // get the vector of channels vector<LSDChannel> vector_of_channels = retrieve_LSDChannels_from_tree(m_over_n, A_0, FlowInfo,Elevation_Raster); int n_channels = vector_of_channels.size(); int n_nodes_in_channel; int node,row,col; float elev,chi,drain_area,flow_dist,this_discharge; // first print out some data about the dem channelfile_out << get_NRows() << endl; channelfile_out << get_NCols() << endl; channelfile_out << get_XMinimum() << endl; channelfile_out << get_YMinimum() << endl; channelfile_out << get_DataResolution() << endl; channelfile_out << get_NoDataValue() << endl; //loop through the channels for (int i = 0; i< n_channels; i++) { // get the number of nodes in the channel n_nodes_in_channel =IndexChannelVector[i].get_n_nodes_in_channel(); // now loop through the channel, printing out the data. for(int ch_node= 0; ch_node<n_nodes_in_channel; ch_node++) { IndexChannelVector[i].get_node_row_col_in_channel(ch_node, node, row, col); vector_of_channels[i].retrieve_node_information(ch_node, elev, chi, drain_area); flow_dist = FlowDistance.get_data_element(row,col); this_discharge = Discharge.get_data_element(row,col); // print data to file channelfile_out << i << " " << receiver_channel[i] << " " << node_on_receiver_channel[i] << " " << node << " " << row << " " << col << " " << flow_dist << " " << " " << elev << " " << this_discharge << endl; } } channelfile_out.close(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=---=-=-=-=-=-=-=-=-=-=-=-=- // Same as above but also reports the discharge // // SMM 06/05/2015 // //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDIndexChannelTree::convert_chan_file_for_ArcMap_ingestion(string fname, LSDRaster& DrainageArea, LSDRaster& Discharge) { // open the outfile ifstream channelfile_in; channelfile_in.open(fname.c_str()); unsigned dot = fname.find_last_of("."); string prefix = fname.substr(0,dot); //string suffix = str.substr(dot); string insert = "_for_Arc.csv"; string outfname = prefix+insert; cout << "the Arc channel filename is: " << outfname << endl; ofstream ArcChan_out; ArcChan_out.open(outfname.c_str()); ArcChan_out.precision(10); // print the first line of the arcchan. This is going to be comma seperated! ArcChan_out << "id,x,y,channel,reciever_channel,node_on_reciever_channel,node,row,col,flow_distance_m,elevation_m,drainage_area_m2,discharge_m2_times_precipunits" << endl; // now go throught the file, collecting the data int id,ch,rc,norc,n,r,c; float fd,elev,da; float x,y; float xll; float yll; float datares; float ndv; int nrows; int ncols; float this_discharge; float this_da; // read in the first lines with DEM information channelfile_in >> nrows >> ncols >> xll >> yll >> datares >> ndv; id = 0; // now loop through the file, calculating x and y locations as you go while(channelfile_in >> ch >> rc >> norc >> n >> r >> c >> fd >> elev >> da) { id++; x = xll + float(c)*datares + 0.5*datares; y = yll + float(nrows-r)*datares - 0.5*datares; // this is because the DEM starts from the top corner this_discharge = Discharge.get_data_element(r,c); this_da = DrainageArea.get_data_element(r,c); ArcChan_out << id << "," << x << "," << y << "," << ch << "," << rc << "," << norc << "," << n << "," << r << "," << c << "," << fd << "," << elev << "," << this_da << "," << this_discharge << endl; } channelfile_in.close(); ArcChan_out.close(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // Create function that takes the dimensions and georeferencing of a raster // but then sets all data to value, setting the NoDataValues to // the NoData of the raster //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDSoilHydroRaster::create(LSDRaster& OtherRaster, float value) { NRows = OtherRaster.get_NRows(); NCols = OtherRaster.get_NCols(); XMinimum = OtherRaster.get_XMinimum(); YMinimum = OtherRaster.get_YMinimum(); DataResolution = OtherRaster.get_DataResolution(); NoDataValue = OtherRaster.get_NoDataValue(); GeoReferencingStrings = OtherRaster.get_GeoReferencingStrings(); // set the raster data to be a certain value Array2D<float> data(NRows,NCols,NoDataValue); for (int row = 0; row <NRows; row++) { for (int col = 0; col<NCols; col++) { if (OtherRaster.get_data_element(row,col) != NoDataValue) { data[row][col] = value; //cout << value << endl; } } } RasterData = data.copy(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // Calculate the the sinmap Stability Index (SI). // This is a wrapper around a lightly modified port of the original sinmap 2.0 implementation. // call with any SoilHydroRaster, it's values are used for identification of NoDataValues. // // SWDG 15/6/16 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= LSDSoilHydroRaster LSDSoilHydroRaster::Calculate_sinmap_SI(LSDRaster Slope, LSDRaster DrainageArea, LSDSoilHydroRaster lo_C, LSDSoilHydroRaster hi_C, LSDSoilHydroRaster lo_phi, LSDSoilHydroRaster hi_phi, LSDSoilHydroRaster lo_RoverT, LSDSoilHydroRaster hi_RoverT, LSDSoilHydroRaster lo_r, LSDSoilHydroRaster hi_r, LSDSoilHydroRaster lo_FS, LSDSoilHydroRaster hi_FS){ Array2D<float> SI(NRows, NCols, NoDataValue); for (int i = 1; i < NRows - 1; ++i){ for (int j = 1; j < NCols - 1; ++j){ if (RasterData[i][j] != NoDataValue){ SI[i][j] = StabilityIndex(Slope.get_data_element(i, j), DrainageArea.get_data_element(i, j), lo_C.get_data_element(i, j), hi_C.get_data_element(i, j), lo_phi.get_data_element(i, j), hi_phi.get_data_element(i, j), lo_RoverT.get_data_element(i, j), hi_RoverT.get_data_element(i, j), lo_r.get_data_element(i, j), hi_r.get_data_element(i, j), lo_FS.get_data_element(i, j), hi_FS.get_data_element(i, j)); } } } LSDSoilHydroRaster output(NRows,NCols,XMinimum,YMinimum,DataResolution,NoDataValue,SI,GeoReferencingStrings); return output; }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // Create function that just copies a raster into the hydro raster //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDSoilHydroRaster::create(LSDRaster& OtherRaster) { NRows = OtherRaster.get_NRows(); NCols = OtherRaster.get_NCols(); XMinimum = OtherRaster.get_XMinimum(); YMinimum = OtherRaster.get_YMinimum(); DataResolution = OtherRaster.get_DataResolution(); NoDataValue = OtherRaster.get_NoDataValue(); GeoReferencingStrings = OtherRaster.get_GeoReferencingStrings(); RasterData = OtherRaster.get_RasterData(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // Creates an LSDChiTools from an LSDRaster //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDChiTools::create(LSDRaster& ThisRaster) { NRows = ThisRaster.get_NRows(); NCols = ThisRaster.get_NCols(); XMinimum = ThisRaster.get_XMinimum(); YMinimum = ThisRaster.get_YMinimum(); DataResolution = ThisRaster.get_DataResolution(); NoDataValue = ThisRaster.get_NoDataValue(); GeoReferencingStrings = ThisRaster.get_GeoReferencingStrings(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // // Create function that reads from a raster // //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDRasterInfo::create(LSDRaster& Raster) { ///Number of rows. NRows = Raster.get_NRows(); NCols = Raster.get_NCols(); XMinimum = Raster.get_XMinimum(); YMinimum = Raster.get_YMinimum(); DataResolution = Raster.get_DataResolution(); NoDataValue = Raster.get_NoDataValue(); GeoReferencingStrings = Raster.get_GeoReferencingStrings(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This function calculates a snow thickenss (effective, in g cm^-2 for cosmogenic // applications) based on a bilinear model such as that of P Kirchner: http://escholarship.org/uc/item/9zn1c1mk#page-8 // The paper is here: http://www.hydrol-earth-syst-sci.net/18/4261/2014/hess-18-4261-2014.html // This paper also agrees withy this general trend: // http://www.the-cryosphere.net/8/2381/2014/tc-8-2381-2014.pdf //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDSoilHydroRaster::SetSnowEffDepthBilinear(float SlopeAscend, float SlopeDescend, float PeakElevation, float PeakSnowpack, LSDRaster& Elevation) { float LocalElevation; float ascendEffDepth; float descendEffDepth; float thisEffDepth = 0; for (int row = 0; row <NRows; row++) { for (int col = 0; col<NCols; col++) { if (RasterData[row][col] != NoDataValue) { LocalElevation = Elevation.get_data_element(row,col); if (LocalElevation != NoDataValue) { // get the effective depth on both the ascending and descending limb ascendEffDepth = SlopeAscend*(LocalElevation-PeakElevation)+PeakSnowpack; descendEffDepth = SlopeDescend*(LocalElevation-PeakElevation)+PeakSnowpack; // the correct depth is the lesser of the two if (ascendEffDepth < descendEffDepth) { thisEffDepth = ascendEffDepth; } else { thisEffDepth = descendEffDepth; } // if the depth is less than zero, then set to zero if(thisEffDepth <0) { thisEffDepth = 0; } RasterData[row][col] = thisEffDepth; } else // if there ins't any elevation data, set the snow data to NoData { RasterData[row][col] = NoDataValue; } } } } }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This prints a chi map to csv with an area threshold in m^2. You feed it the chi map //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDChiTools::chi_map_to_csv(LSDFlowInfo& FlowInfo, string chi_map_fname, LSDRaster& chi_coord) { ofstream chi_map_csv_out; chi_map_csv_out.open(chi_map_fname.c_str()); float this_chi_coord; double latitude,longitude; LSDCoordinateConverterLLandUTM Converter; chi_map_csv_out << "latitude,longitude,chi" << endl; float NDV = chi_coord.get_NoDataValue(); for(int row = 0; row<NRows; row++) { for(int col = 0; col<NCols; col++) { this_chi_coord = chi_coord.get_data_element(row,col); if (this_chi_coord != NDV) { get_lat_and_long_locations(row, col, latitude, longitude, Converter); chi_map_csv_out.precision(9); chi_map_csv_out << latitude << "," << longitude << ","; chi_map_csv_out.precision(5); chi_map_csv_out << this_chi_coord << endl; } } } chi_map_csv_out.close(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This function calculates a snow thickenss (effective, in g cm^-2 for cosmogenic // applications) based on a richard's equsion sigmoidal growth model // It was propoesd to represent peak SWE so we cruedly apply it to average annual SWE // see // http://onlinelibrary.wiley.com/doi/10.1002/2015GL063413/epdf //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDSoilHydroRaster::SetSnowEffDepthRichards(float MaximumEffDepth, float MaximumSlope, float v, float lambda, LSDRaster& Elevation) { // Don't let V be less than or equal to zero if (v <= 0) { v = 0.001; } // some variables to speed up compuation float exp_term; float thisEffDepth = 0; float elev_mulitplier = (MaximumSlope/MaximumEffDepth)*pow((1+v),1+(1/v)); float LocalElevation; for (int row = 0; row <NRows; row++) { for (int col = 0; col<NCols; col++) { if (RasterData[row][col] != NoDataValue) { LocalElevation = Elevation.get_data_element(row,col); if (LocalElevation != NoDataValue) { // get the effective depth using the richards sigmoidal gorth function exp_term = 1+v*exp(elev_mulitplier*(lambda-LocalElevation)); thisEffDepth = MaximumEffDepth*pow(exp_term,-(1/v)); // if the depth is less than zero, then set to zero if(thisEffDepth <0) { thisEffDepth = 0; } // update the data RasterData[row][col] = thisEffDepth; } else // if there ins't any elevation data, set the snow data to NoData { RasterData[row][col] = NoDataValue; } } } } }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // Calculate the factor of safety using the sinmap definition. // Call with the dimensionless cohesion (C) raster. // SWDG 13/6/16 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= LSDSoilHydroRaster LSDSoilHydroRaster::Calculate_sinmap_Fs(LSDRaster& Slope, LSDSoilHydroRaster& w, LSDSoilHydroRaster& r, LSDSoilHydroRaster& phi){ Array2D<float> Fs(NRows, NCols, NoDataValue); for (int i = 1; i < NRows - 1; ++i){ for (int j = 1; j < NCols - 1; ++j){ if (RasterData[i][j] != NoDataValue){ Fs[i][j] = ( RasterData[i][j] + cos(Slope.get_data_element(i,j)) * (1.0-w.get_data_element(i,j)*r.get_data_element(i,j)) * tan(phi.get_data_element(i,j)) ) / sin(Slope.get_data_element(i,j)); } } } LSDSoilHydroRaster output(NRows,NCols,XMinimum,YMinimum,DataResolution,NoDataValue,Fs,GeoReferencingStrings); return output; }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // Calculate h, the soil depth normal to the slope, used in the factor of safety equation. // Call with the soil thickness raster. // SWDG 13/6/16 //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= LSDSoilHydroRaster LSDSoilHydroRaster::Calculate_h(LSDRaster& Slope){ Array2D<float> h(NRows, NCols, NoDataValue); for (int i = 1; i < NRows - 1; ++i){ for (int j = 1; j < NCols - 1; ++j){ if (RasterData[i][j] != NoDataValue){ h[i][j] = RasterData[i][j] * cos(Slope.get_data_element(i,j)); } } } LSDSoilHydroRaster output(NRows,NCols,XMinimum,YMinimum,DataResolution,NoDataValue,h,GeoReferencingStrings); return output; }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // this function prints chi values. It is used on the channel tree when channels are organized by links // (that is organization switch == 0 // // SMM 01/09/2012 // //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= void LSDIndexChannelTree::print_chi_vs_elevation_from_channel_tree(LSDRaster& Elevation, LSDFlowInfo& FlowInfo, LSDJunctionNetwork& ChannelNetwork, float m_over_n, float A_0, string chi_vs_elev_fname) { if(organization_switch != 0) { cout << "LSDIndexChannelTree you can't run LSDIndexChannelTree::print_chi_vs_elevation_from_channel_tree with this channel organization" << endl; exit(EXIT_FAILURE); } int n_channels = IndexChannelVector.size(); int n_nodes_in_link,current_node_index; vector< vector<float> > chi_vectors = calculate_chi_from_channel_tree(FlowInfo, ChannelNetwork, m_over_n, A_0); // the chi iterator vector< vector<float> >::iterator chi_iter; chi_iter = chi_vectors.begin(); float current_chi; float current_elev; int curr_row,curr_col; ofstream chi_elev_out; chi_elev_out.open(chi_vs_elev_fname.c_str()); for (int i = 0; i<n_channels; i++) { n_nodes_in_link = IndexChannelVector[i].get_n_nodes_in_channel(); for (int this_node = 0; this_node<n_nodes_in_link; this_node++) { current_node_index = IndexChannelVector[i].get_node_in_channel(this_node); current_chi = (*chi_iter)[this_node]; FlowInfo.retrieve_current_row_and_col(current_node_index,curr_row,curr_col); current_elev = Elevation.get_data_element(curr_row,curr_col); //cout << "current_node: " << current_node_index << " and chi: " << current_chi << endl; //chi_elev_out << current_chi << " " << current_elev << endl; } chi_iter++; } chi_elev_out.close(); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=---=-=-=-=-=-=-=-=-=-=-=-=- // this function prints chi and elevation, along with flow distance and the // number of the tributary it all goes to one file // // the file format is // channel_number node_index row column flow_dist chi elevation drainage_area // // SMM 01/09/2012 // //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDIndexChannelTree::print_LSDChannels_from_tree(float m_over_n, float A_0, LSDFlowInfo& FlowInfo, LSDRaster& Elevation_Raster, LSDRaster& FlowDistance, string fname) { if (organization_switch != 1) { cout << "LSDIndexChannelTree you can't run LSDIndexChannelTree::retrieve_LSDChannels_from_tree" << endl; cout << "with this channel organization, organization switch: " << organization_switch << endl; exit(EXIT_FAILURE); } // open the outfile ofstream channelfile_out; channelfile_out.open(fname.c_str()); // get the vector of channels vector<LSDChannel> vector_of_channels = retrieve_LSDChannels_from_tree(m_over_n, A_0, FlowInfo,Elevation_Raster); int n_channels = vector_of_channels.size(); int n_nodes_in_channel; int node,row,col; float elev,chi,drain_area,flow_dist; //loop through the channels for (int i = 0; i< n_channels; i++) { // get the number of nodes in the channel n_nodes_in_channel =IndexChannelVector[i].get_n_nodes_in_channel(); // now loop through the channel, printing out the data. for(int ch_node= 0; ch_node<n_nodes_in_channel; ch_node++) { IndexChannelVector[i].get_node_row_col_in_channel(ch_node, node, row, col); vector_of_channels[i].retrieve_node_information(ch_node, elev, chi, drain_area); flow_dist = FlowDistance.get_data_element(row,col); // print data to file channelfile_out << i << " " << node << " " << row << " " << col << " " << flow_dist << " " << chi << " " << elev << " " << drain_area << endl; } } channelfile_out.close(); }
int main(int nNumberofArgs, char *argv[]) { //Test for correct input arguments if (nNumberofArgs!=5) { cout << "FATAL ERROR: wrong number of inputs. The program needs the path (with trailing slash), the filename prefix, the DEM file format, the window size in spatial units."; exit(EXIT_FAILURE); } //get input args string path = argv[1]; string Prefix = argv[2]; string DEM_Format = argv[3]; int WindowSize = atoi(argv[4]); //surface fitting vector<int> raster_selection; raster_selection.push_back(0); raster_selection.push_back(1); //slope raster_selection.push_back(0); raster_selection.push_back(1); //curvature //set up a writer to write the output data ofstream WriteData; //create an output filename based on the dem name stringstream ss; ss << path << Prefix << "_ChtResData.txt"; WriteData.open(ss.str().c_str()); //write headers WriteData << "resoulution 2pc 25pc median mean 75pc 98pc minimum maximum" << endl; //array of resolutions to load int Resolutions[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // vectors to hold the stats about the fitted surface vector<float> Curv_vec; //set boundary conditions vector<string> BoundaryConditions(4, "No Flux"); for (int a = 0; a < 10; ++a){ cout << "Processing DEM " << a+1 << " of " << "10" << endl; //load the DEM //build the string of the filename to load stringstream ss2; ss2 << path << Prefix << "_" << Resolutions[a] << "_DEM"; LSDRaster DEM(ss2.str(), DEM_Format); //Fill float MinSlope = 0.0001; LSDRaster FilledDEM = DEM.fill(MinSlope); int CurrentWindowSize = WindowSize; vector<LSDRaster> Surfaces = FilledDEM.calculate_polyfit_surface_metrics(CurrentWindowSize, raster_selection); // get a flow info object LSDFlowInfo FlowInfo(BoundaryConditions,FilledDEM); //get stream net from channel heads vector<int> sources = FlowInfo.Ingest_Channel_Heads((path+Prefix+"_CH"), "csv", 2); LSDJunctionNetwork ChanNetwork(sources, FlowInfo); // extract hilltops LSDRaster hilltops = ChanNetwork.ExtractRidges(FlowInfo); LSDRaster Hilltops = ChanNetwork.ExtractHilltops(hilltops, Surfaces[1], 0.4); //get hilltop curvature using filter to remove positive curvatures LSDRaster cht_raster = FilledDEM.get_hilltop_curvature(Surfaces[3], Hilltops); LSDRaster CHT = FilledDEM.remove_positive_hilltop_curvature(cht_raster); //go through the landscape and get every curvature value into a 1D vector Curv_vec = Flatten_Without_Nodata(CHT.get_RasterData(), CHT.get_NoDataValue()); stringstream ss3; ss3 << path << Prefix << "_" << Resolutions[a] << "_Hist_CHT.txt"; print_histogram(Curv_vec, 0.01, ss3.str()); vector<float> Boxplot = BoxPlot(Curv_vec); //write the values to the output file WriteData << Resolutions[a] << " " << Boxplot[0] << " " << Boxplot[1] << " " << Boxplot[2] << " " << Boxplot[3] << " " << Boxplot[4] << " " << Boxplot[5] << " " << Boxplot[6] << " " << Boxplot[7]; WriteData << endl; } WriteData.close(); }
int main (int nNumberofArgs,char *argv[]) { //Test for correct input arguments if (nNumberofArgs!=7) { cout << "FATAL ERROR: wrong number of inputs. The program needs the path (with trailing slash), the filename prefix, the DEM file format, the window radius, "; cout << "basin order, and a switch to write rasters if desired." << endl; exit(EXIT_SUCCESS); } //load input arguments string Path = argv[1]; string Prefix = argv[2]; string DEM_Format = argv[3]; float window_radius = atof(argv[4]); //6 int BasinOrder = atoi(argv[5]); //2 int WriteRasters = atoi(argv[6]); //0 (do not write rasters) or 1 (write rasters) //set up writers to write the output data stringstream ssLH; stringstream ssR; ssLH << Path << Prefix << "_LHResData_variable.txt"; ssR << Path << Prefix << "_RResData_variable.txt"; ofstream WriteLHData; WriteLHData.open(ssLH.str().c_str()); ofstream WriteRData; WriteRData.open(ssR.str().c_str()); //write headers WriteLHData << "resolution 2pc 25pc median mean 75pc 98pc minimum maximum" << endl; WriteRData << "resolution 2pc 25pc median mean 75pc 98pc minimum maximum" << endl; //set boundary conditions vector<string> BoundaryConditions(4, "No Flux"); //array of resolutions to load int Resolutions[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; for (int a = 0; a < 19; ++a){ cout << "Processing DEM " << a+1 << " of " << "19" << endl; //create an output filename based on the dem name and the resolution stringstream ss; ss << Path << Prefix << "_" << Resolutions[a]; string Filename = ss.str(); //load dem LSDRaster DEM((Filename + "_DEM"), DEM_Format); stringstream ssa; ssa << Path << Prefix << "_" << Resolutions[a] << "_variable"; string Filename_variable = ssa.str(); //Fill float MinSlope = 0.0001; LSDRaster FilledDEM = DEM.fill(MinSlope); //surface fitting vector<int> raster_selection; raster_selection.push_back(0); raster_selection.push_back(1); //slope raster_selection.push_back(1); //aspect raster_selection.push_back(1); //curvature raster_selection.push_back(1); //plan curvature raster_selection.push_back(0); raster_selection.push_back(0); raster_selection.push_back(0); int CurrentWindowSize = window_radius; vector<LSDRaster> Surfaces = FilledDEM.calculate_polyfit_surface_metrics(CurrentWindowSize, raster_selection); LSDRaster slope = Surfaces[1]; LSDRaster aspect = Surfaces[2]; cout << "\nGetting drainage network and basins\n" << endl; // get a flow info object LSDFlowInfo FlowInfo(BoundaryConditions,FilledDEM); //get stream net from channel heads stringstream ss_ch; ss_ch << Path << "Pelletier/" << Prefix << "_" << Resolutions[a] << "_CH"; vector<int> sources = FlowInfo.Ingest_Channel_Heads(ss_ch.str(), "bil"); LSDJunctionNetwork ChanNetwork(sources, FlowInfo); LSDIndexRaster StreamNetwork = ChanNetwork.StreamOrderArray_to_LSDIndexRaster(); //Extract basins based on input stream order vector< int > basin_junctions = ChanNetwork.ExtractBasinJunctionOrder(BasinOrder, FlowInfo); LSDIndexRaster Basin_Raster = ChanNetwork.extract_basins_from_junction_vector(basin_junctions, FlowInfo); cout << "\nExtracting hilltops and hilltop curvature" << endl; // extract hilltops - no critical slope filtering is performed here LSDRaster hilltops = ChanNetwork.ExtractRidges(FlowInfo); //get hilltop curvature using filter to remove positive curvatures LSDRaster cht_raster = FilledDEM.get_hilltop_curvature(Surfaces[3], hilltops); LSDRaster CHT = FilledDEM.remove_positive_hilltop_curvature(cht_raster); cout << "Starting hilltop flow routing\n" << endl; // these params do not need changed during normal use of the HFR algorithm bool print_paths_switch = false; int thinning = 1; string trace_path = ""; bool basin_filter_switch = false; vector<int> Target_Basin_Vector; //run HFR vector< Array2D<float> > HFR_Arrays = FlowInfo.HilltopFlowRouting(FilledDEM, hilltops, slope, StreamNetwork, aspect, Filename_variable, Basin_Raster, Surfaces[4], print_paths_switch, thinning, trace_path, basin_filter_switch, Target_Basin_Vector); LSDRaster HFR_LH = hilltops.LSDRasterTemplate(HFR_Arrays[1]); LSDRaster relief = hilltops.LSDRasterTemplate(HFR_Arrays[3]); //Filter Relief and LH data to remove any values < 2 pixels, as in Grieve et al (2015) LSDRaster LH1 = HFR_LH.RemoveBelow(2.0*Resolutions[a]); LSDRaster Relief1 = relief.RemoveBelow(2.0*Resolutions[a]); //Filter Relief and LH data to remove any values > 10000 //These are created due to using 1m channel heads on low res data, and inadvertantly //sampling nodata values, which gives us massive relief values LSDRaster LH = LH1.RemoveAbove(10000); LSDRaster Relief = Relief1.RemoveAbove(10000); //go through the lh raster and get every value into a 1D vector vector<float> LH_vec = Flatten_Without_Nodata(LH.get_RasterData(), LH.get_NoDataValue()); vector<float> Boxplot = BoxPlot(LH_vec); //write the values to the output file WriteLHData << Resolutions[a] << " " << Boxplot[0] << " " << Boxplot[1] << " " << Boxplot[2] << " " << Boxplot[3] << " " << Boxplot[4] << " " << Boxplot[5] << " " << Boxplot[6] << " " << Boxplot[7]; WriteLHData << endl; stringstream ss3; ss3 << Path << Prefix << "_" << Resolutions[a] << "_Hist_LH_variable.txt"; print_histogram(LH_vec, 1, ss3.str()); //go through the relief raster and get every value into a 1D vector vector<float> R_vec = Flatten_Without_Nodata(Relief.get_RasterData(), Relief.get_NoDataValue()); vector<float> Boxplot_R = BoxPlot(R_vec); //write the values to the output file WriteRData << Resolutions[a] << " " << Boxplot_R[0] << " " << Boxplot_R[1] << " " << Boxplot_R[2] << " " << Boxplot_R[3] << " " << Boxplot_R[4] << " " << Boxplot_R[5] << " " << Boxplot_R[6] << " " << Boxplot_R[7]; WriteRData << endl; stringstream ss4; ss4 << Path << Prefix << "_" << Resolutions[a] << "_Hist_R_variable.txt"; print_histogram(R_vec, 1, ss4.str()); //if the user requests the rasters to be written, write the rasters if (WriteRasters == 1){ cout << "Writing Rasters\n" << endl; Surfaces[1].write_raster((Filename + "_Slope_variable"), DEM_Format); CHT.write_raster((Filename + "_CHT_variable"), DEM_Format); LH.write_raster((Filename + "_HFR_LH_variable"), DEM_Format); Relief.write_raster((Filename + "_Relief_variable"), DEM_Format); } } WriteLHData.close(); WriteRData.close(); }
int main (int nNumberofArgs,char *argv[]) { //Test for correct input arguments if (nNumberofArgs!=7) { cout << "FATAL ERROR: wrong number of inputs. The program needs the path (with trailing slash), the filename prefix, window radius, "; cout << "basin order, a switch to use or exclude floodplains and a switch to write rasters if desired." << endl; exit(EXIT_SUCCESS); } //load input arguments string path = argv[1]; string filename = argv[2]; float window_radius = atof(argv[3]); //6 int BasinOrder = atoi(argv[4]); //2 int FloodplainSwitch = atoi(argv[5]); int WriteRasters = atoi(argv[6]); //0 (do not write rasters) or 1 (write rasters) //set boundary conditions vector<string> BoundaryConditions(4, "No Flux"); //load dem LSDRaster DEM((path+filename+"_dem"), "flt"); //Fill float MinSlope = 0.0001; LSDRaster FilledDEM = DEM.fill(MinSlope); //surface fitting vector<int> raster_selection; raster_selection.push_back(0); raster_selection.push_back(1); //slope raster_selection.push_back(1); //aspect raster_selection.push_back(1); //curvature raster_selection.push_back(1); //plan curvature raster_selection.push_back(0); raster_selection.push_back(0); raster_selection.push_back(0); vector<LSDRaster> Surfaces = FilledDEM.calculate_polyfit_surface_metrics(window_radius, raster_selection); LSDRaster slope = Surfaces[1]; LSDRaster aspect = Surfaces[2]; cout << "\nGetting drainage network and basins\n" << endl; // get a flow info object LSDFlowInfo FlowInfo(BoundaryConditions,FilledDEM); //get stream net from channel heads vector<int> sources = FlowInfo.Ingest_Channel_Heads((path+filename+"_dem_CH"), "flt"); //swap to csv? LSDJunctionNetwork ChanNetwork(sources, FlowInfo); LSDIndexRaster StreamNetwork = ChanNetwork.StreamOrderArray_to_LSDIndexRaster(); //load floodplain and merge with the channel network if required, otherwise the //floodplain mask will only contain the channel data LSDIndexRaster ChannelAndFloodplain; if (FloodplainSwitch == 1){ LSDIndexRaster Floodplains((path+filename+"_FloodPlain"), "flt"); ChannelAndFloodplain = StreamNetwork.MergeChannelWithFloodplain(Floodplains); } else{ ChannelAndFloodplain = StreamNetwork; } //Extract basins based on input stream order vector< int > basin_junctions = ChanNetwork.ExtractBasinJunctionOrder(BasinOrder, FlowInfo); LSDIndexRaster Basin_Raster = ChanNetwork.extract_basins_from_junction_vector(basin_junctions, FlowInfo); cout << "\nExtracting hilltops and hilltop curvature" << endl; // extract hilltops - no critical slope filtering is performed here LSDRaster hilltops = ChanNetwork.ExtractRidges(FlowInfo); //get hilltop curvature using filter to remove positive curvatures LSDRaster cht_raster = FilledDEM.get_hilltop_curvature(Surfaces[3], hilltops); LSDRaster CHT = FilledDEM.remove_positive_hilltop_curvature(cht_raster); //get d infinity flowdirection and flow area Array2D<float> dinf = FilledDEM.D_inf_FlowDir(); LSDRaster dinf_rast = FilledDEM.LSDRasterTemplate(dinf); LSDRaster DinfArea = FilledDEM.D_inf_units(); cout << "Starting hilltop flow routing\n" << endl; //start of Hilltop flow routing string prefix = (path+filename+"_dreich_"); //set a path to write the hillslope length data to, based on the input path and filename given by the user // these params do not need changed during normal use of the HFR algorithm bool print_paths_switch = false; int thinning = 1; string trace_path = ""; bool basin_filter_switch = false; vector<int> Target_Basin_Vector; //run HFR vector< Array2D<float> > HFR_Arrays = FlowInfo.HilltopFlowRouting(FilledDEM, hilltops, slope, ChannelAndFloodplain, aspect, prefix, Basin_Raster, Surfaces[4], print_paths_switch, thinning, trace_path, basin_filter_switch, Target_Basin_Vector); LSDRaster HFR_LH = hilltops.LSDRasterTemplate(HFR_Arrays[1]); LSDRaster HFR_Slope = hilltops.LSDRasterTemplate(HFR_Arrays[2]); LSDRaster relief = hilltops.LSDRasterTemplate(HFR_Arrays[3]); //end of HFR //create lsdbasin objects in a loop over each junction number vector< LSDBasin > Basins; //slope area plotting parameters - these defaults are usually fine float log_bin_width = 0.1; int SplineResolution = 10000; int bin_threshold = 0; float CriticalSlope = 1.2; //this needs modified to generate proper E*R* data cout << "\nCreating each LSDBasin" << endl; //loop over each basin, generating an LSDBasin object which contains that basin's measurements for (int w = 0; w < int(basin_junctions.size()); ++w){ cout << (w+1) << " / " << basin_junctions.size() << endl; LSDBasin Basin(basin_junctions[w], FlowInfo, ChanNetwork); Basin.set_FlowLength(StreamNetwork, FlowInfo); Basin.set_DrainageDensity(); Basin.set_all_HillslopeLengths(FlowInfo, HFR_LH, slope, DinfArea, log_bin_width, SplineResolution, bin_threshold); Basin.set_SlopeMean(FlowInfo, slope); Basin.set_AspectMean(FlowInfo, aspect); Basin.set_ElevationMean(FlowInfo, FilledDEM); Basin.set_ReliefMean(FlowInfo, relief); Basin.set_CHTMean(FlowInfo, CHT); Basin.set_EStar_RStar(CriticalSlope); Basins.push_back(Basin); } //create a filestream to write the output data // use the input arguments to generate a path and filename for the output file ofstream WriteData; stringstream ss; ss << path << filename << "_dreich_PaperData.txt"; WriteData.open(ss.str().c_str()); //write headers WriteData << "BasinID HFR_mean HFR_median HFR_stddev HFR_stderr HFR_Nvalues HFR_range HFR_min HFR_max SA_binned_LH SA_Spline_LH LH_Density Area Basin_Slope_mean Basin_Slope_median Basin_Slope_stddev Basin_Slope_stderr Basin_Slope_Nvalues Basin_Slope_range Basin_Slope_min Basin_Slope_max Basin_elev_mean Basin_elev_median Basin_elev_stddev Basin_elev_stderr Basin_elev_Nvalues Basin_elev_Range Basin_elev_min Basin_elev_max Aspect_mean CHT_mean CHT_median CHT_stddev CHT_stderr CHT_Nvalues CHT_range CHT_min CHT_max EStar RStar HT_Slope_mean HT_Slope_median HT_Slope_stddev HT_Slope_stderr HT_Slope_Nvalues HT_Slope_range HT_Slope_min HT_Slope_max HT_relief_mean HT_relief_median HT_relief_stddev HT_relief_stderr HT_relief_Nvalues HT_relief_range HT_relief_min HT_relief_max" << endl; cout << "\nWriting data to file\n" << endl; //write all data to the opened file, ensuring that there are data points to be written in each basin for (int q = 0; q < int(Basins.size()); ++q){ // only work where we have data points if (Basins[q].CalculateNumDataPoints(FlowInfo, HFR_LH) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, slope) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, FilledDEM) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, CHT) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, HFR_Slope) != 0 && Basins[q].CalculateNumDataPoints(FlowInfo, relief) != 0){ // BasinID WriteData << Basins[q].get_Junction()<< " "; //HFR WriteData << Basins[q].get_HillslopeLength_HFR() << " " << Basins[q].CalculateBasinMedian(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinStdError(FlowInfo, HFR_LH) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinRange(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinMin(FlowInfo, HFR_LH) << " " << Basins[q].CalculateBasinMax(FlowInfo, HFR_LH)<< " "; //SA_Bins WriteData << Basins[q].get_HillslopeLength_Binned()<< " "; //SA_Spline WriteData << Basins[q].get_HillslopeLength_Spline()<< " "; //Density WriteData << Basins[q].get_HillslopeLength_Density()<< " "; //Area WriteData << Basins[q].get_Area()<< " "; //Slope_Basin WriteData << Basins[q].get_SlopeMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, slope) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, slope) << " " << Basins[q].CalculateBasinStdError(FlowInfo, slope) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, slope) << " " << Basins[q].CalculateBasinRange(FlowInfo, slope) << " " << Basins[q].CalculateBasinMin(FlowInfo, slope) << " " << Basins[q].CalculateBasinMax(FlowInfo, slope)<< " "; //Elev_Basin WriteData << Basins[q].get_ElevationMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinStdError(FlowInfo, FilledDEM) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinRange(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinMin(FlowInfo, FilledDEM) << " " << Basins[q].CalculateBasinMax(FlowInfo, FilledDEM)<< " "; //Aspect_Basin WriteData << Basins[q].get_AspectMean()<< " "; //CHT WriteData << Basins[q].get_CHTMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, CHT) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, CHT) << " " << Basins[q].CalculateBasinStdError(FlowInfo, CHT) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, CHT) << " " << Basins[q].CalculateBasinRange(FlowInfo, CHT) << " " << Basins[q].CalculateBasinMin(FlowInfo, CHT) << " " << Basins[q].CalculateBasinMax(FlowInfo, CHT) << " "; //EStar WriteData << Basins[q].get_EStar()<< " "; //RStar WriteData << Basins[q].get_RStar()<< " "; //Slope_mean WriteData << Basins[q].CalculateBasinMean(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinMedian(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinStdError(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinRange(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinMin(FlowInfo, HFR_Slope) << " " << Basins[q].CalculateBasinMax(FlowInfo, HFR_Slope)<< " "; //Relief_mean WriteData << Basins[q].get_ReliefMean() << " " << Basins[q].CalculateBasinMedian(FlowInfo, relief) << " " << Basins[q].CalculateBasinStdDev(FlowInfo, relief) << " " << Basins[q].CalculateBasinStdError(FlowInfo, relief) << " " << Basins[q].CalculateNumDataPoints(FlowInfo, relief) << " " << Basins[q].CalculateBasinRange(FlowInfo, relief) << " " << Basins[q].CalculateBasinMin(FlowInfo, relief) << " " << Basins[q].CalculateBasinMax(FlowInfo, relief)<< "\n"; } } // close the output file WriteData.close(); //if the user requests the raster to be written, write the rasters if (WriteRasters == 1){ cout << "Writing Rasters\n" << endl; // FilledDEM.write_raster((path+filename+"_Fill"), "flt"); Surfaces[1].write_raster((path+filename+"_dreich_Slope"),"flt"); //Surfaces[2].write_raster((path+filename+"_Aspect"),"flt"); //Surfaces[3].write_raster((path+filename+"_Curvature"),"flt"); //StreamNetwork.write_raster((path+filename+"_STNET"), "flt"); //Basin_Raster.write_raster((path+filename+"_Basins"), "flt"); CHT.write_raster((path+filename+"_dreich_CHT"),"flt"); HFR_LH.write_raster((path+filename+"_dreich_HFR_LH"),"flt"); HFR_Slope.write_raster((path+filename+"_dreich_HFR_SLP"),"flt"); relief.write_raster((path+filename+"_dreich_Relief"),"flt"); //perform a hillshade //LSDRaster Hillshade = FilledDEM.hillshade(45.0,315.0,1.0); //Hillshade.write_raster((path+filename+"_HS"),"flt"); } }
int main (int nNumberofArgs,char *argv[]) { //Test for correct input arguments if (nNumberofArgs!=3) { cout << "FATAL ERROR: wrong number inputs. The program needs the path name and the file name" << endl; exit(EXIT_SUCCESS); } string path_name = argv[1]; // make sure there is a slash on the end of the file string lchar = path_name.substr(path_name.length()-2,1); string slash = "/"; if (lchar != slash) { cout << "You forgot the frontslash at the end of the path. Appending." << endl; path_name = path_name+slash; } string f_name = argv[2]; cout << "\nYou are running the write junctions driver." << endl <<"IMPORTANT: this has been updated to load an ENVI DEM, whith extension .bil" << endl <<"You can convert your DEM to this file format using gdal_translate, with -of ENVI" << endl <<"See documentation at: http://www.geos.ed.ac.uk/~smudd/LSDTT_docs/html/gdal_notes.html" << endl << endl; cout << "The path is: " << path_name << " and the filename is: " << f_name << endl; string full_name = path_name+f_name; ifstream file_info_in; file_info_in.open(full_name.c_str()); if( file_info_in.fail() ) { cout << "\nFATAL ERROR: the header file \"" << full_name << "\" doesn't exist" << endl; exit(EXIT_FAILURE); } string DEM_name; string fill_ext = "_fill"; file_info_in >> DEM_name; int junction_number; float pruning_threshold; int threshold; float A_0; int minimum_segment_length; float sigma; float start_movern; float d_movern; float Minimum_Slope; int n_movern; int target_nodes; int n_iterations; float fraction_dchi_for_variation; float vertical_interval; float horizontal_interval; float area_thin_frac; int target_skip; file_info_in >> Minimum_Slope >> threshold >> junction_number >> pruning_threshold >> A_0 >> minimum_segment_length >> sigma >> start_movern >> d_movern >> n_movern >> target_nodes >> n_iterations >> fraction_dchi_for_variation >> vertical_interval >> horizontal_interval >> area_thin_frac >> target_skip; cout << "Paramters of this run: " << endl << "junction number: " << junction_number << endl << "pruning_threshold: " << pruning_threshold << endl << "threshold: " << threshold << endl << "A_0: " << A_0 << endl << "minimum_segment_length: " << minimum_segment_length << endl << "sigma: " << sigma << endl << "start_movern " << start_movern << endl << "d_movern: " << d_movern << endl << "n_movern: " << n_movern << endl << "target_nodes: " << target_nodes << endl << "n_iterarions: " << n_iterations << endl << "fraction_dchi_for_variation: " << fraction_dchi_for_variation << endl << "vertical interval: " << vertical_interval << endl << "horizontal interval: " << horizontal_interval << endl << "area thinning fraction for SA analysis: " << area_thin_frac << endl << "target_skip is: " << target_skip << endl; cout << "=================================================================" << endl << "You are also loading a precipitation raster to get the discharge" << endl << "The precipitation raster should: " << endl << "1) Have units of m/yr" << endl << "Have the same prefix as the DEM, but will have the extension _PRECIP"<< endl << "For example, if the DEM is my_DEM.bil, the precip file will be" << endl << "my_DEM_precip.bil" << endl << "=================================================================" << endl; string jn_name = itoa(junction_number); string uscore = "_"; jn_name = uscore+jn_name; file_info_in.close(); string DEM_f_name = path_name+DEM_name+fill_ext; string DEM_bil_extension = "bil"; string precip_ext = "_PRECIP"; string Precip_f_name = path_name+DEM_name+precip_ext; // set no flux boundary conditions vector<string> boundary_conditions(4); boundary_conditions[0] = "No"; boundary_conditions[1] = "no flux"; boundary_conditions[2] = "no flux"; boundary_conditions[3] = "No flux"; // load the filled DEM LSDRaster filled_topo_test((path_name+DEM_name+fill_ext), DEM_bil_extension); // get a flow info object LSDFlowInfo FlowInfo(boundary_conditions,filled_topo_test); // calcualte the distance from outlet LSDRaster DistanceFromOutlet = FlowInfo.distance_from_outlet(); LSDIndexRaster ContributingPixels = FlowInfo.write_NContributingNodes_to_LSDIndexRaster(); // calculate the discharge // note: not discharge yet, need to multiply by cell area LSDRaster VolumePrecipitation(Precip_f_name, DEM_bil_extension); float dx = VolumePrecipitation.get_DataResolution(); // volume precipitation per time precipitation times the cell areas VolumePrecipitation.raster_multiplier(dx*dx); // discharge accumulates this precipitation LSDRaster Discharge = FlowInfo.upslope_variable_accumulator(VolumePrecipitation); string Q_ext = "_Q"; string Q_f_name = path_name+DEM_name+Q_ext; Discharge.write_raster(Q_f_name,DEM_bil_extension); // get the sources vector<int> sources; sources = FlowInfo.get_sources_index_threshold(ContributingPixels, threshold); // now get the junction network LSDJunctionNetwork ChanNetwork(sources, FlowInfo); // now get a junction and look for the longest channel upstream cout << "creating main stem" << endl; LSDIndexChannel main_stem = ChanNetwork.generate_longest_index_channel_in_basin(junction_number, FlowInfo, DistanceFromOutlet); cout << "got main stem channel, with n_nodes " << main_stem.get_n_nodes_in_channel() << endl; string Basin_name = "_basin"; LSDIndexRaster BasinArray = ChanNetwork.extract_basin_from_junction(junction_number,junction_number,FlowInfo); BasinArray.write_raster((path_name+DEM_name+Basin_name+jn_name),DEM_bil_extension); // now get the best fit m over n for all the tributaries int organization_switch = 1; int pruning_switch = 1; LSDIndexChannelTree ChannelTree(FlowInfo, ChanNetwork, junction_number, organization_switch, DistanceFromOutlet, pruning_switch, pruning_threshold); LSDRaster DrainageArea = FlowInfo.write_DrainageArea_to_LSDRaster(); // print a file that can be ingested by the chi fitting algorithm string Chan_fname = "_ChanNet"; string Chan_ext = ".chan"; string Chan_for_chi_ingestion_fname = path_name+DEM_name+Chan_fname+jn_name+Chan_ext; ChannelTree.print_LSDChannels_for_chi_network_ingestion(FlowInfo, filled_topo_test, DistanceFromOutlet, Chan_for_chi_ingestion_fname, Discharge); ChannelTree.convert_chan_file_for_ArcMap_ingestion(Chan_for_chi_ingestion_fname,DrainageArea,Discharge); }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This function is a much more rudimentary version that mimics the // channel steepness caluclations. // chi needs tobe calculated outside of the function //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDChiTools::chi_map_automator_rudimentary(LSDFlowInfo& FlowInfo, vector<int> source_nodes, vector<int> outlet_nodes, LSDRaster& Elevation, LSDRaster& FlowDistance, LSDRaster& DrainageArea, LSDRaster& chi_coordinate, int regression_nodes) { // the data is stored in maps, for easier testing if a node has been // visited. // You might consider having these as data elements in the object so you don't // have to pass them map<int,float> gradient_data_map; map<int,float> intercept_data_map; map<int,float> R2_data_map; map<int,float> chi_coordinate_data_map; map<int,float> elevation_data_map; map<int,float> flow_distance_map; map<int,float> area_map; vector<int> node_order; // check if the number of nodes are odd .If not add 1 if (regression_nodes % 2 == 0) { cout << "Hello user. You need an odd number of regression nodes." << endl; regression_nodes = regression_nodes+1; cout << " Changing your regression nodes to " << regression_nodes << endl; } // now get the midpoint int mp_nodes = (regression_nodes-1)/2; //cout << "The number of mp nodes is: " << mp_nodes << endl; // these keep track of the beginning and ending nodes of a given channel int channel_start_node; int channel_end_node; float channel_end_elevation; // vectors for holding the chi elevation data vector<float> chi_vec; vector<float> elev_vec; vector<float> empty_vec; // these are extracted from the channel segments using linear regression float intercept,gradient,R_squared; //float this_chi; //float this_elev; int this_mp_node; int this_end_node; int this_start_node; // these are for getting information out of the FlowInfo object int row,col, this_node; int r_node, r_row,r_col; // reciever row and column. // The way this works is that it starts at the top of a channel. It then works // its way down and find the node that is the midpoint and the node that is the // end point. The midpoint node is where the data will be recorded. // It then puts the data from the start node to the end node into a vector // and performs a linear regression of this vector. The regression data from these // vectors are recorded at the nodes. // We then want to cover all the nodes with data so what happens if some nodes // do not become midpoints? // We could start at the top and get the first midpoint. // From there we can work our way down checking if the top of the regression segment // is more than one node down from the end point... // get the number of channels int n_channels = int(source_nodes.size()); // now loop through the channels for(int chan = 0; chan<n_channels; chan++) { channel_start_node = source_nodes[chan]; channel_end_node = outlet_nodes[chan]; // Get the elevation of the end node as a secondary check of the ending of the channel // segment FlowInfo.retrieve_current_row_and_col(channel_end_node,row,col); channel_end_elevation = Elevation.get_data_element(row,col); // reset the flag for ending the channel bool is_end_of_channel = false; // set the segment start node to the channel start node this_start_node = channel_start_node; // now retrieve the midpoint node this_node = channel_start_node; for(int n = 0; n<mp_nodes; n++) { FlowInfo.retrieve_receiver_information(this_node,r_node,r_row,r_col); this_node = r_node; } this_mp_node = this_node; this_node = r_node; // now go down one step FlowInfo.retrieve_receiver_information(this_node,r_node,r_row,r_col); this_node = r_node; // now get the end node for(int n = 0; n<mp_nodes; n++) { FlowInfo.retrieve_receiver_information(this_node,r_node,r_row,r_col); this_node = r_node; } this_end_node = this_node; //================================================ // This loop is for bug checking //this_node = this_start_node; //do //{ // // get the elevation and chi vectors by following the flow // cout << "This node is: " << this_node << endl; // FlowInfo.retrieve_current_row_and_col(this_node,row,col); // FlowInfo.retrieve_receiver_information(this_node,r_node,r_row,r_col); // this_node = r_node; //} //while(this_node != this_end_node); // //cout << "And the midpoint node was: " << this_mp_node << endl; //================================================ // we search down the channel, collecting linear regressions at the // midpoint of the intervals while (not is_end_of_channel) { // get a vector of chi and elevation from the start node to the end node chi_vec = empty_vec; elev_vec = empty_vec; // copy the data elements into the vecotrs. This is a little stupid // because one might just use a deque to pop the first element // and push the last, but the linear regression takes vectors, // not deques so you would have to copy the deque element-wise anyway // If you wanted, you could speed this up by implementing a linear regression // of deques, but that will need to wait for another day. this_node = this_start_node; do { // get the elevation and chi vectors by following the flow FlowInfo.retrieve_current_row_and_col(this_node,row,col); chi_vec.push_back(chi_coordinate.get_data_element(row,col)); elev_vec.push_back(Elevation.get_data_element(row,col)); FlowInfo.retrieve_receiver_information(this_node,r_node,r_row,r_col); this_node = r_node; } while(this_node != this_end_node); // do a linear regression on the segment least_squares_linear_regression(chi_vec,elev_vec, intercept, gradient, R_squared); // now add the intercept and gradient data to the correct node // only take data that has not been calculated before // The channels are in order of descending length so data from // longer channels take precidence. if (gradient_data_map.find(this_mp_node) == gradient_data_map.end() ) { FlowInfo.retrieve_current_row_and_col(this_mp_node,row,col); gradient_data_map[this_mp_node] = gradient; intercept_data_map[this_mp_node] = intercept; R2_data_map[this_mp_node] = R_squared; chi_coordinate_data_map[this_mp_node] = chi_coordinate.get_data_element(row,col); elevation_data_map[this_mp_node] = Elevation.get_data_element(row,col); flow_distance_map[this_mp_node] = FlowDistance.get_data_element(row,col); area_map[this_mp_node] = DrainageArea.get_data_element(row,col); node_order.push_back(this_mp_node); } else { is_end_of_channel = true; } // now move all the nodes down one FlowInfo.retrieve_receiver_information(this_start_node,r_node,r_row,r_col); this_start_node = r_node; FlowInfo.retrieve_receiver_information(this_mp_node,r_node,r_row,r_col); this_mp_node = r_node; FlowInfo.retrieve_receiver_information(this_end_node,r_node,r_row,r_col); this_end_node = r_node; // check if we are at the end of the channel if (this_end_node == channel_end_node) { is_end_of_channel = true; } // also check if the end node is lower elevation than the end node, // just to try and stop the channel passing the end node FlowInfo.retrieve_current_row_and_col(this_end_node,row,col); if (channel_end_elevation > Elevation.get_data_element(row,col)) { is_end_of_channel = true; } } // This finishes the regression segment loop } // This finishes the channel and resets channel start and end nodes // set the data objects M_chi_data_map = gradient_data_map; b_chi_data_map = intercept_data_map; elev_data_map = elevation_data_map; chi_data_map = chi_coordinate_data_map; flow_distance_data_map = flow_distance_map; drainage_area_data_map = area_map; node_sequence = node_order; }
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // This function is for calculating segments from all sources in a DEM // The sources and their outlets are supplied by the source and outlet nodes // vectors. These are generated from the LSDJunctionNetwork function // get_overlapping_channels //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- void LSDChiTools::chi_map_automator(LSDFlowInfo& FlowInfo, vector<int> source_nodes, vector<int> outlet_nodes, LSDRaster& Elevation, LSDRaster& FlowDistance, LSDRaster& DrainageArea, LSDRaster& chi_coordinate, int target_nodes, int n_iterations, int skip, int minimum_segment_length, float sigma) { // IMPORTANT THESE PARAMETERS ARE NOT USED BECAUSE CHI IS CALUCALTED SEPARATELY // However we need to give something to pass to the Monte carlo functions // even through they are not used (they are inherited) float A_0 = 1; float m_over_n = 0.5; // These elements access the chi data vector< vector<float> > chi_m_means; vector< vector<float> > chi_b_means; vector< vector<float> > chi_coordinates; vector< vector<int> > chi_node_indices; // these are for the individual channels vector<float> these_chi_m_means; vector<float> these_chi_b_means; vector<float> these_chi_coordinates; vector<int> these_chi_node_indices; // these are maps that will store the data map<int,float> m_means_map; map<int,float> b_means_map; map<int,float> chi_coord_map; map<int,float> elev_map; map<int,float> area_map; map<int,float> flow_distance_map; vector<int> node_sequence_vec; // these are for working with the FlowInfo object int this_node,row,col; // get the number of channels int n_channels = int(source_nodes.size()); for(int chan = 0; chan<n_channels; chan++) { cout << "Sampling channel " << chan+1 << " of " << n_channels << endl; // get this particualr channel (it is a chi network with only one channel) LSDChiNetwork ThisChiChannel(FlowInfo, source_nodes[chan], outlet_nodes[chan], Elevation, FlowDistance, DrainageArea,chi_coordinate); // split the channel //cout << "Splitting channels" << endl; ThisChiChannel.split_all_channels(A_0, m_over_n, n_iterations, skip, target_nodes, minimum_segment_length, sigma); // monte carlo sample all channels //cout << "Entering the monte carlo sampling" << endl; ThisChiChannel.monte_carlo_sample_river_network_for_best_fit_after_breaks(A_0, m_over_n, n_iterations, skip, minimum_segment_length, sigma); // okay the ChiNetwork has all the data about the m vales at this stage. // Get these vales and print them to a raster chi_m_means = ThisChiChannel.get_m_means(); chi_b_means = ThisChiChannel.get_b_means(); chi_coordinates = ThisChiChannel.get_chis(); chi_node_indices = ThisChiChannel.get_node_indices(); // now get the number of channels. This should be 1! int n_channels = int(chi_m_means.size()); if (n_channels != 1) { cout << "Whoa there, I am trying to make a chi map but something seems to have gone wrong with the channel extraction." << endl; cout << "I should only have one channel per look but I have " << n_channels << " channels." << endl; } // now get the m_means out these_chi_m_means = chi_m_means[0]; these_chi_b_means = chi_b_means[0]; these_chi_coordinates = chi_coordinates[0]; these_chi_node_indices = chi_node_indices[0]; //cout << "I have " << these_chi_m_means.size() << " nodes." << endl; int n_nodes_in_channel = int(these_chi_m_means.size()); for (int node = 0; node< n_nodes_in_channel; node++) { this_node = these_chi_node_indices[node]; //cout << "This node is " << this_node << endl; // only take the nodes that have not been found if (m_means_map.find(this_node) == m_means_map.end() ) { FlowInfo.retrieve_current_row_and_col(this_node,row,col); //cout << "This is a new node; " << this_node << endl; m_means_map[this_node] = these_chi_m_means[node]; b_means_map[this_node] = these_chi_b_means[node]; chi_coord_map[this_node] = these_chi_coordinates[node]; elev_map[this_node] = Elevation.get_data_element(row,col); area_map[this_node] = DrainageArea.get_data_element(row,col); flow_distance_map[this_node] = FlowDistance.get_data_element(row,col); node_sequence_vec.push_back(this_node); } else { //cout << "I already have node: " << this_node << endl; } } } // set the opject data members M_chi_data_map =m_means_map; b_chi_data_map = b_means_map; elev_data_map = elev_map; chi_data_map = chi_coord_map; flow_distance_data_map = flow_distance_map; drainage_area_data_map = area_map; node_sequence = node_sequence_vec; }
void LSDSoilHydroRaster::create(LSDRaster& DEM, LSDRaster& OtherRaster, int min_max) { NRows = OtherRaster.get_NRows(); NCols = OtherRaster.get_NCols(); XMinimum = OtherRaster.get_XMinimum(); YMinimum = OtherRaster.get_YMinimum(); DataResolution = OtherRaster.get_DataResolution(); NoDataValue = OtherRaster.get_NoDataValue(); GeoReferencingStrings = OtherRaster.get_GeoReferencingStrings(); // set the raster data to be a certain value Array2D<float> data(NRows,NCols,NoDataValue); float min_max_val = NoDataValue; if (min_max == 0){ // get the minimum value of OtherRaster Array2D<float> tmp = OtherRaster.get_RasterData(); min_max_val = Get_Minimum(tmp, NoDataValue); } else if (min_max == 1){ // get the maximum value of OtherRaster Array2D<float> tmp = OtherRaster.get_RasterData(); min_max_val = Get_Maximum(tmp, NoDataValue); } // for each cell, if there is no paramter data but there is topo, fill in the data with the minimum/maximum value // otherwise, just keep the minimum value. for (int i = 0; i < NRows; ++i){ for (int j = 0; j < NCols; ++j){ if (DEM.get_data_element(i, j) != NoDataValue && OtherRaster.get_data_element(i,j) == NoDataValue){ data[i][j] = min_max_val; } else if (DEM.get_data_element(i, j) != NoDataValue && OtherRaster.get_data_element(i, j) != NoDataValue){ data[i][j] = OtherRaster.get_data_element(i,j); } } } RasterData = data.copy(); }
int main (int nNumberofArgs,char *argv[]) { // the driver version string driver_version = "Driver_version: 0.01"; // some paramters //Test for correct input arguments if (nNumberofArgs!=5) { cout << endl; cout << "=====================================================================" << endl; cout << "|| Welcome to the Topographic Shielding tool! ||" << endl; cout << "|| This program is used to calculate topographic shielding_driver ||" << endl; cout << "|| rasters following the method of Codilean (2006). ||" << endl; cout << "=====================================================================" << endl; cout << "This program requires four inputs: " << endl; cout << "* First the path to the DEM files." << endl; cout << " The path must have a slash at the end." << endl; cout << " (Either \\ or / depending on your operating system.)" << endl; cout << "* Second the prefix of the DEM (that is, without the .bil)." << endl; cout << " For example if you DEM is Ladakh.bil, you should enter Ladakh" << endl; cout << " (Note that the DEM should be in *.bil format)" << endl; cout << "* Third the increment in azimuth (in degrees) over which you" << endl; cout << " want shielding calculated. Recommended values is 5" << endl; cout << "* Fourth the increment in inclination (in degrees) over which you" << endl; cout << " want shielding calculated. Recommended values is 5" << endl; cout << "=====================================================================" << endl; cout << "For more documentation, see readme and online documentation" << endl; cout << "=====================================================================" << endl; cout << endl; exit(EXIT_SUCCESS); } cout << endl; cout << "===============================================================" << endl; cout << "Welcome to the Topographic Shielding tool" << endl; cout << "This software was developed at the University of Edinburgh," << endl; cout << "by the Land Surface Dynamics group. For questions email" << endl; cout << "simon.m.mudd _at_ ed.ac.uk" << endl; cout << "This software is released under a GNU public license." << endl; cout << "You are using " << driver_version << endl; cout << "================================================================" << endl; cout << "++IMPORTANT++ The DEM must be an ENVI bil format file" << endl; cout << "ENVI bil files are required because, unlike asc or flt files, " << endl; cout << "they use georeferencing information." << endl; cout << "For more information about changing DEM formatting, see: " << endl; cout << "http://lsdtopotools.github.io/LSDTT_book/#_gdal_2" << endl; cout << "================================================================" << endl; //Assign values from input arguments string path_name = argv[1]; string file_name = argv[2]; string azimuth_str = argv[3]; string inclination_str = argv[4]; //Set the DEM filename file_name = path_name+file_name; //Convert the angle increments to integers int azimuth_step = atoi(azimuth_str.c_str()); int inclination_step = atoi(inclination_str.c_str()); // check the parameter values check_azimuth_and_inclination(azimuth_step,inclination_step); //load dem LSDRaster DEM(file_name, "bil"); //launch toposhielding LSDRaster TopoShielding = DEM.TopographicShielding(azimuth_step,inclination_step); TopoShielding.write_raster(file_name+"_TopoShield","bil"); cout << "Done!" << endl << endl; }