Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/locations_tutorial_snippet.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/locations_tutorial_snippet.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/locations_tutorial_snippet.rst (revision 3529) @@ -0,0 +1,112 @@ +Creating Location class from locations.csv code snippet +------------------------------------------------------- + +.. code-block:: python + + import dampythoninterface as dpi + import pandas as pd + + def get_zone_type(csv_zone_type: str): + dictionary = { + "NoZones": dpi.ZoneTypeClass.NoZones, + "ZoneAreas": dpi.ZoneTypeClass.ZoneAreas, + "ForbiddenZones": dpi.ZoneTypeClass.ForbiddenZones, + } + return dictionary[csv_zone_type] + + + def read_locations_csv(location_csv_name: str, scenario_csv_name: str): + # read csv file using pandas + location_csv = pd.read_csv(location_csv_name, delimiter=";") + scenario_csv = pd.read_csv(scenario_csv_name, delimiter=";") + merged_csv = pd.merge(location_csv, scenario_csv, on="location_id") + # initialize profile list that will be used for the dam input + locations_list = [] + # Loop through all unique profile names of the csv + for index, row in merged_csv.iterrows(): + # initialize DesignScenario + design_scenario = dpi.DesignScenario( + Id=str(index), + PolderLevel=row["polderlevel"], + HeadPl2=row["head_pl2"], + HeadPl3=row["head_pl3"], + PlLineOffsetBelowDikeTopAtRiver=row["PLLineOffsetBelowDikeTopAtRiver"], + PlLineOffsetBelowDikeTopAtPolder=row["PLLineOffsetBelowDikeTopAtPolder"], + PlLineOffsetBelowShoulderBaseInside=row[ + "PLLineOffsetBelowShoulderBaseInside" + ], + PlLineOffsetBelowDikeToeAtPolder=row["PLLIneOffsetBelowDikeToeAtPolder"], + RiverLevel=row["water_height"], + RiverLevelLow=row["water_height_low"], + DikeTableHeight=row["dike_table_height"], + RequiredSafetyFactorStabilityInnerSlope=row[ + "safety_factor_stability_inner_slope" + ], + RequiredSafetyFactorStabilityOuterSlope=row[ + "safety_factor_stability_outer_slope" + ], + UpliftCriterionPiping=row["uplift_criterion_piping"], + UpliftCriterionStability=row["uplift_criterion_stability"], + RequiredSafetyFactorPiping=row["safety_factor_piping"], + ) + # initialize design options class + design_options = dpi.DesignOptions( + ShoulderEmbankmentMaterial=row["ophoogmateriaalberm"], + StabilityShoulderGrowSlope=row["StabilityShoulderGrowSlope"], + StabilityShoulderGrowDeltaX=row["StabilityShoulderGrowDeltaX"], + StabilitySlopeAdaptionDeltaX=row["StabilitySlopeAdaptionDeltaX"], + NewDikeTopWidth=row["NewDikeTopWidth"], + NewDikeSlopeInside=row["NewDikeSlopeInside"], + NewDikeSlopeOutside=row["NewDikeSlopeOutside"], + NewShoulderTopSlope=row["NewShoulderTopSlope"], + NewShoulderBaseSlope=row["NewShoulderBaseSlope"], + NewMaxHeightShoulderAsFraction=row["NewMaxHeightShoulderAsFraction"], + NewMinDistanceDikeToeStartDitch=row["NewMinDistanceDikeToeStartDitch"], + UseNewDitchDefinition=row["UseNewDitchDefinition"], + NewWidthDitchBottom=row["NewWidthDitchBottom"], + NewDepthDitch=row["NewDepthDitch"], + NewSlopeAngleDitch=row["NewSlopeAngleDitch"], + RedesignDikeHeight=0, + RedesignDikeShoulder=0, + SlopeAdaptionStartCotangent=1, + SlopeAdaptionEndCotangent=1, + SlopeAdaptionStepCotangent=1, + StabilityDesignMethod=dpi.StabilityDesignMethodType.OptimizedSlopeAndShoulderAdaption, + ) + # Initialize stability options + stability_options = dpi.StabilityOptions( + MinimumCircleDepth=row["minimal_circle_depth"], + TrafficLoad=row["trafficload"], + ZoneType=get_zone_type(row["ZoneType"]), + ) + # initialize waternet options + waternet_options = dpi.WaternetOptions( + DampingFactorPl3=row["dempingsfactor_pl3"], + DampingFactorPl4=row["dempingsfactor_pl4"], + PhreaticLineCreationMethod=row["PLLineCreationMethod"], + PenetrationLength=0, + SlopeDampingFactor=1, + IntrusionVerticalWaterPressure=dpi.IntrusionVerticalWaterPressureType.Standard, + DikeSoilScenario=dpi.DikeSoilScenarioType.ClayDikeOnClay, + ) + # initialize location class + location = dpi.Location( + XSoilGeometry2DOrigin=row["x_soilgeometry2D_origin"], + SurfaceLineName=row["surfaceline_id"], + SegmentName=row["segment_id"], + DikeEmbankmentMaterial=row["ophoogmateriaaldijk"], + Name=row["location_id"], + DesignOptions=design_options, + DesignScenarios=[design_scenario], + StabilityOptions=stability_options, + WaternetOptions=waternet_options, + ) + locations_list.append(location) + return locations_list + + if __name__ == "__main__": + # read location csv + locations = read_locations_csv( + "locations.csv", + "scenarios.csv", + ) \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/locations.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/locations.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/locations.csv (revision 3529) @@ -0,0 +1,2 @@ +location_id;surfaceline_id;segment_id;geo_x;geo_y;x_soilgeometry2D_origin;polderlevel;head_pl2;head_pl3;ophoogmateriaaldijk;ophoogmateriaalberm;dempingsfactor_pl3;dempingsfactor_pl4;PLLineCreationMethod;PLLineOffsetBelowDikeTopAtRiver;PLLineOffsetBelowDikeTopAtPolder;PLLineOffsetBelowShoulderBaseInside;PLLIneOffsetBelowDikeToeAtPolder;StabilityShoulderGrowSlope;StabilityShoulderGrowDeltaX;StabilitySlopeAdaptionDeltaX;minimal_circle_depth;trafficload;UseNewDikeTopWidth;NewDikeTopWidth;UseNewDikeSlopeInside;NewDikeSlopeInside;UseNewDikeSlopeOutside;NewDikeSlopeOutside;UseNewShoulderTopSlope;NewShoulderTopSlope;UseNewShoulderBaseSlope;NewShoulderBaseSlope;UseNewMaxHeightShoulderAsFraction;NewMaxHeightShoulderAsFraction;UseNewMinDistanceDikeToeStartDitch;NewMinDistanceDikeToeStartDitch;UseNewDitchDefinition;NewWidthDitchBottom;NewDepthDitch;NewSlopeAngleDitch;ZoneType +Profiel 1;Profiel 1;1;275793.299;584533.586;0;0;0;3.6;Ophoogmateriaal_dijk;Ophoogmateriaal_berm;0;0;ExpertKnowledgeRRD;0.5;1;0;0;0.33;1;1;1.5;13.3;FALSE;3;FALSE;0.33;FALSE;0.33;FALSE;0.05;FALSE;0.333;FALSE;0.5;FALSE;5;FALSE;1;1;1;NoZones Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial.rst (revision 3529) @@ -0,0 +1,27 @@ +Tutorial: Setting up a DAM project from pre-existing csv files +============================================================== + + +.. include:: tutorial_sections/segment_csv_tutorial.rst + +The full code snippet for reading the segment.csv can be found in :doc:`this document. ` + +.. include:: tutorial_sections/surface_lines_csv_tutorial.rst + +The full code snippet for reading the csvs can be found in :doc:`this document. ` + +.. include:: tutorial_sections/soil_profile_1d_csv_tutorial.rst + +The full code snippet for reading the csvs can be found in :doc:`this document. ` + +.. include:: tutorial_sections/locations_csv_tutorial.rst + +The full code snippet for reading the csvs can be found in :doc:`this document. ` + +.. include:: tutorial_sections/soil_materials_tutorial.rst + +The full code snippet for reading the csvs can be found in :doc:`this document. ` + +.. include:: tutorial_sections/setting_up_dam_input_and_executing.rst + +The full code snippet :doc:`this document. ` \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/characteristicpoints.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/characteristicpoints.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/characteristicpoints.csv (revision 3529) @@ -0,0 +1,2 @@ +LOCATIONID;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Insteek geul;Y_Insteek geul;Z_Insteek geul;X_Teen geul;Y_Teen geul;Z_Teen geul;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts +Profiel 1;100.000;0.000;0.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;35.000;0.000;0.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;23.000;0.000;4.000;23.000;0.000;4.000;20.500;0.000;4.000;19.000;0.000;4.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;10.000;0.000;1.000;-1.000;-1.000;-1.000;-1.000;-1.000;-1.000;0.000;0.000;1.000 Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/segments.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/segments.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/segments.csv (revision 3529) @@ -0,0 +1,3 @@ +segment_id;soilprofile_id;probability;calculation_type +1;soilprofile_01;1;Piping +1;soilprofile_01;1;Stability Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/locations_csv_tutorial.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/locations_csv_tutorial.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/locations_csv_tutorial.rst (revision 3529) @@ -0,0 +1,134 @@ +Creating Location class from locations.csv +------------------------------------------ + +To create the list of :py:class:`dampythoninterface.location.Location` which can later be inputted in the DamInput a function read_locations_csv is created. +Two csv files are given as input, the locations.csv and the scenarios.csv. +Firstly, these two files are read and merged based on the location_id csv column. + + +.. code-block:: python + + import dampythoninterface as dpi + import pandas as pd + + # read csv file using pandas + location_csv = pd.read_csv(location_csv_name, delimiter=";") + scenario_csv = pd.read_csv(scenario_csv_name, delimiter=";") + merged_csv = pd.merge(location_csv, scenario_csv, on="location_id") + +Then each row is read from the csv file. + +.. code-block:: python + + # initialize location list that will be used for the dam input + locations_list = [] + # Loop through all unique profile names of the csv + for index, row in merged_csv.iterrows(): + +The :py:class:`dampythoninterface.location.DesignScenario` class is initialized. In this case there is only one design scenario. + + + .. code-block:: python + + # initialize DesignScenario + design_scenario = dpi.DesignScenario( + Id=str(index), + PolderLevel=row["polderlevel"], + HeadPl2=row["head_pl2"], + HeadPl3=row["head_pl3"], + PlLineOffsetBelowDikeTopAtRiver=row["PLLineOffsetBelowDikeTopAtRiver"], + PlLineOffsetBelowDikeTopAtPolder=row["PLLineOffsetBelowDikeTopAtPolder"], + PlLineOffsetBelowShoulderBaseInside=row[ + "PLLineOffsetBelowShoulderBaseInside" + ], + PlLineOffsetBelowDikeToeAtPolder=row["PLLIneOffsetBelowDikeToeAtPolder"], + RiverLevel=row["water_height"], + RiverLevelLow=row["water_height_low"], + DikeTableHeight=row["dike_table_height"], + RequiredSafetyFactorStabilityInnerSlope=row[ + "safety_factor_stability_inner_slope" + ], + RequiredSafetyFactorStabilityOuterSlope=row[ + "safety_factor_stability_outer_slope" + ], + UpliftCriterionPiping=row["uplift_criterion_piping"], + UpliftCriterionStability=row["uplift_criterion_stability"], + RequiredSafetyFactorPiping=row["safety_factor_piping"], + ) + +The :py:class:`dampythoninterface.location.DesignOptions` class is initialized. + + .. code-block:: python + + # initialize design options class + design_options = dpi.DesignOptions( + ShoulderEmbankmentMaterial=row["ophoogmateriaalberm"], + StabilityShoulderGrowSlope=row["StabilityShoulderGrowSlope"], + StabilityShoulderGrowDeltaX=row["StabilityShoulderGrowDeltaX"], + StabilitySlopeAdaptionDeltaX=row["StabilitySlopeAdaptionDeltaX"], + NewDikeTopWidth=row["NewDikeTopWidth"], + NewDikeSlopeInside=row["NewDikeSlopeInside"], + NewDikeSlopeOutside=row["NewDikeSlopeOutside"], + NewShoulderTopSlope=row["NewShoulderTopSlope"], + NewShoulderBaseSlope=row["NewShoulderBaseSlope"], + NewMaxHeightShoulderAsFraction=row["NewMaxHeightShoulderAsFraction"], + NewMinDistanceDikeToeStartDitch=row["NewMinDistanceDikeToeStartDitch"], + UseNewDitchDefinition=row["UseNewDitchDefinition"], + NewWidthDitchBottom=row["NewWidthDitchBottom"], + NewDepthDitch=row["NewDepthDitch"], + NewSlopeAngleDitch=row["NewSlopeAngleDitch"], + RedesignDikeHeight=0, + RedesignDikeShoulder=0, + SlopeAdaptionStartCotangent=1, + SlopeAdaptionEndCotangent=1, + SlopeAdaptionStepCotangent=1, + StabilityDesignMethod=dpi.StabilityDesignMethodType.OptimizedSlopeAndShoulderAdaption, + ) + +The :py:class:`dampythoninterface.location.StabilityOptions` class is initialized. + + .. code-block:: python + + # Initialize stability options + stability_options = dpi.StabilityOptions( + MinimumCircleDepth=row["minimal_circle_depth"], + TrafficLoad=row["trafficload"], + ZoneType=get_zone_type(row["ZoneType"]), + ) + +The :py:class:`dampythoninterface.location.WaternetOptions` class is initialized. + + .. code-block:: python + + waternet_options = dpi.WaternetOptions( + DampingFactorPl3=row["dempingsfactor_pl3"], + DampingFactorPl4=row["dempingsfactor_pl4"], + PhreaticLineCreationMethod=row["PLLineCreationMethod"], + PenetrationLength=0, + SlopeDampingFactor=1, + IntrusionVerticalWaterPressure=dpi.IntrusionVerticalWaterPressureType.Standard, + DikeSoilScenario=dpi.DikeSoilScenarioType.ClayDikeOnClay, + ) + +Finally, the :py:class:`dampythoninterface.location.Location` class is initialized with all the inputs that were defined in the code snippets above. + + .. code-block:: python + + # initialize location class + location = dpi.Location( + XSoilGeometry2DOrigin=row["x_soilgeometry2D_origin"], + SurfaceLineName=row["surfaceline_id"], + SegmentName=row["segment_id"], + DikeEmbankmentMaterial=row["ophoogmateriaaldijk"], + Name=row["location_id"], + DesignOptions=design_options, + DesignScenarios=[design_scenario], + StabilityOptions=stability_options, + WaternetOptions=waternet_options, + ) + +The location is appended to the list of locations + + .. code-block:: python + + locations_list.append(location) \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.mdb =================================================================== diff -u Binary files differ Index: DamClients/DamPythonInterface/trunk/doc/source/index.rst =================================================================== diff -u -r3475 -r3529 --- DamClients/DamPythonInterface/trunk/doc/source/index.rst (.../index.rst) (revision 3475) +++ DamClients/DamPythonInterface/trunk/doc/source/index.rst (.../index.rst) (revision 3529) @@ -9,6 +9,9 @@ DamPythonInterface is a Python package to generate input for the DAM engine basically bypassing the DAM UI. Release v\ |version|. +Tutorial +-------- +The tutorial can be found in :doc:`this document. ` The total interface documentation --------------------------------- @@ -21,7 +24,6 @@ dev/input - Indices and tables ================== Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_profile_1d_csv_tutorial.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_profile_1d_csv_tutorial.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_profile_1d_csv_tutorial.rst (revision 3529) @@ -0,0 +1,56 @@ +Creating profiles class from soilprofiles.csv file +-------------------------------------------------- + +To read the soilprofiles.csv the user can create a function that will create a list of +:py:class:`dampythoninterface.soilprofile1D.SoilProfile1D` class. + +The profile csv is read using the pandas module + +.. code-block:: python + + import pandas as pd + # read csv file using pandas + profile_csv = pd.read_csv(file_name, delimiter=";") + +Then a loop is created that goes through all unique profile ids. +A list of all 1D layers for a certain profile is initialized. + +.. code-block:: python + + list_of_1D_layers = [] + +Then a second loop is created that loops all csv rows with a certain profile id. +A :py:class:`dampythoninterface.soilprofile1D.Layer1D` class is initialized for each row. +This is append to the list of the 1D layers. + +.. code-block:: python + + for csv_row in profile_csv[profile_csv["soilprofile_id"] == profile_id].index: + list_of_1D_layers.append( + dpi.Layer1D( + **{ + "Name": profile_csv["soil_name"][csv_row], + "SoilName": profile_csv["soil_name"][csv_row], + "TopLevel": profile_csv["top_level"][csv_row], + "IsAquifer": False, + "WaterpressureInterpolationModel": dpi.WaterpressureInterpolationModelType.Automatic, + } + ) + ) + +The created list can be inputted in the profile list. +That will be later used as dam input. +Therefore, :py:class:`dampythoninterface.soilprofile1D.SoilProfile1D` class is initialized. +Note that the input of BottomLevel is hardcoded by the user and not extracted from a csv file. + +.. code-block:: python + + # create profile and append it to the profile list + profile_list.append( + dpi.SoilProfile1D( + Name=str(profile_id), + BottomLevel=-30, + Layers1D=list_of_1D_layers, + ) + ) + return profile_list \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/segment_tutorial_snippet.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/segment_tutorial_snippet.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/segment_tutorial_snippet.rst (revision 3529) @@ -0,0 +1,50 @@ +Creating Segment class from segments.csv code snippet +----------------------------------------------------- + +.. code-block:: python + + import dampythoninterface as dpi + import pandas as pd + + + def get_failure_mechanism(soil_profile: str): + output_dictionary = { + "All": dpi.SegmentFailureMechanismTypeClass.All, + "Stability": dpi.SegmentFailureMechanismTypeClass.Stability, + "Piping": dpi.SegmentFailureMechanismTypeClass.Piping, + "Liquefaction": dpi.SegmentFailureMechanismTypeClass.Liquefaction, + } + return output_dictionary[soil_profile] + + + if __name__ == "__main__": + # read csv file using pandas + segment_csv = pd.read_csv( + "segments.csv", delimiter=";" + ) + # initialize segment list that will be used for the dam input + segments_list = [] + # Loop through all unique segment names of the csv + for segment_id in segment_csv["segment_id"].unique(): + # loop through all different probabilities and create a list of the SoilGeometryProbabilityElement + list_of_probability_elements = [] + for csv_row in segment_csv[segment_csv["segment_id"] == segment_id].index: + list_of_probability_elements.append( + dpi.SoilGeometryProbabilityElement( + **{ + "SoilProfileName": segment_csv["soilprofile_id"][csv_row], + "SoilProfileType": dpi.SoilProfileTypeClass.ProfileType1D, + "Probability": segment_csv["probability"][csv_row], + "SegmentFailureMechanismType": get_failure_mechanism( + segment_csv["calculation_type"][csv_row] + ), + } + ) + ) + # create segment and append it to the segment list + segments_list.append( + Segment( + Name=str(segment_id), + SoilGeometryProbability=list_of_probability_elements, + ) + ) Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/full_tutorial_snippet.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/full_tutorial_snippet.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/full_tutorial_snippet.rst (revision 3529) @@ -0,0 +1,355 @@ +Tutorial code snippet +--------------------- + + +.. code-block:: python + + import dampythoninterface as dpi + + import pandas as pd + from pathlib import Path + + def get_failure_mechanism(soil_profile: str): + import dampythoninterface as dpi + + output_dictionary = { + "All": dpi.SegmentFailureMechanismTypeClass.All, + "Stability": dpi.SegmentFailureMechanismTypeClass.Stability, + "Piping": dpi.SegmentFailureMechanismTypeClass.Piping, + "Liquefaction": dpi.SegmentFailureMechanismTypeClass.Liquefaction, + } + return output_dictionary[soil_profile] + + + def read_segment_csv_file(file_name: str): + # read csv file using pandas + segment_csv = pd.read_csv(file_name, delimiter=";") + # initialize segment list that will be used for the dam input + segments_list = [] + # Loop through all unique segment names of the csv + for segment_id in segment_csv["segment_id"].unique(): + # loop through all different probabilities and create a list of the SoilGeometryProbabilityElement + list_of_probability_elements = [] + for csv_row in segment_csv[segment_csv["segment_id"] == segment_id].index: + list_of_probability_elements.append( + dpi.SoilGeometryProbabilityElement( + **{ + "SoilProfileName": segment_csv["soilprofile_id"][csv_row], + "SoilProfileType": dpi.SoilProfileTypeClass.ProfileType1D, + "Probability": segment_csv["probability"][csv_row], + "SegmentFailureMechanismType": get_failure_mechanism( + segment_csv["calculation_type"][csv_row] + ), + } + ) + ) + # create segment and append it to the segment list + segments_list.append( + dpi.Segment( + Name=str(segment_id), + SoilGeometryProbability=list_of_probability_elements, + ) + ) + return segments_list + + + def read_surface_lines_csv(file_name: str): + # read csv file using pandas + surface_lines_csv = pd.read_csv(file_name, delimiter=";", index_col=False) + surface_lines = {} + # loop though all locations + for location_id in surface_lines_csv["LOCATIONID"]: + # get row of one of the locations + row_csv = surface_lines_csv[surface_lines_csv["LOCATIONID"] == location_id] + row_csv = row_csv.values[0][1:] + # reshape row so that each point is separated + row_csv = row_csv.reshape((-1, 3)) + # create list of points all values all values have a none type + surface_lines[location_id] = [] + for point in row_csv: + # check if point is defined or if it is nan + if not (str(point[0]) == "nan") or not (str(point[-1]) == "nan"): + surface_lines[location_id].append( + dpi.Point(X=point[0], Z=point[-1], PointType=dpi.PointTypeEnum.NONE) + ) + return surface_lines + + + def get_characteristic_point_type(point_type: str): + output_dictionary = { + "Maaiveld buitenwaarts": dpi.PointTypeEnum.SurfaceLevelOutside, + "Teen dijk buitenwaarts": dpi.PointTypeEnum.DikeToeAtRiver, + "Kruin buitenberm": dpi.PointTypeEnum.ShoulderTopOutside, + "Insteek buitenberm": dpi.PointTypeEnum.ShoulderBaseOutside, + "Kruin buitentalud": dpi.PointTypeEnum.DikeTopAtRiver, + "referentielijn": dpi.PointTypeEnum.DikeLine, + "Verkeersbelasting kant buitenwaarts": dpi.PointTypeEnum.TrafficLoadOutside, + "Verkeersbelasting kant binnenwaarts": dpi.PointTypeEnum.TrafficLoadInside, + "Kruin binnentalud": dpi.PointTypeEnum.DikeTopAtPolder, + "Insteek binnenberm": dpi.PointTypeEnum.ShoulderBaseInside, + "Kruin binnenberm": dpi.PointTypeEnum.ShoulderTopInside, + "Teen dijk binnenwaarts": dpi.PointTypeEnum.DikeToeAtPolder, + "Insteek sloot dijkzijde": dpi.PointTypeEnum.DitchDikeSide, + "Slootbodem dijkzijde": dpi.PointTypeEnum.BottomDitchDikeSide, + "Slootbodem polderzijde": dpi.PointTypeEnum.BottomDitchPolderSide, + "Insteek sloot polderzijde": dpi.PointTypeEnum.DitchPolderSide, + "Maaiveld binnenwaarts": dpi.PointTypeEnum.SurfaceLevelInside, + } + return output_dictionary.get(point_type, dpi.PointTypeEnum.NONE) + + + def read_characteristic_points(file_name: str): + # read csv file using pandas + characteristic_points_csv = pd.read_csv(file_name, delimiter=";") + column_groups = [ + char_type_point.split("_")[-1] + for char_type_point in characteristic_points_csv.columns[1:] + ] + # remove duplicates + column_groups = list(dict.fromkeys(column_groups)) + characteristic_points_results = {} + # loop though all locations + for characteristic_points in characteristic_points_csv["LOCATIONID"]: + row_csv = characteristic_points_csv[ + characteristic_points_csv["LOCATIONID"] == characteristic_points + ] + characteristic_points_results[characteristic_points] = [] + for characteristic_point_type in column_groups: + # get relevant columns + relevant_columns = [ + char_type_point + for char_type_point in characteristic_points_csv.columns + if characteristic_point_type in char_type_point + ] + char_point = row_csv[relevant_columns] + if not (char_point.isin([-1]).sum().sum() == 3): + characteristic_points_results[characteristic_points].append( + Point( + X=list(char_point["X_" + characteristic_point_type])[0], + Z=list(char_point["Z_" + characteristic_point_type])[0], + PointType=get_characteristic_point_type( + characteristic_point_type + ), + ) + ) + return characteristic_points_results + + + def get_X(d): + return d.X + + + def read_profile(file_name: str): + # read csv file using pandas + profile_csv = pd.read_csv(file_name, delimiter=";") + # initialize profile list that will be used for the dam input + profile_list = [] + # Loop through all unique profile names of the csv + for profile_id in profile_csv["soilprofile_id"].unique(): + list_of_1D_layers = [] + for csv_row in profile_csv[profile_csv["soilprofile_id"] == profile_id].index: + list_of_1D_layers.append( + dpi.Layer1D( + **{ + "Name": profile_csv["soil_name"][csv_row], + "SoilName": profile_csv["soil_name"][csv_row], + "TopLevel": profile_csv["top_level"][csv_row], + "IsAquifer": False, + "WaterpressureInterpolationModel": dpi.WaterpressureInterpolationModelType.Automatic, + } + ) + ) + # create profile and append it to the profile list + profile_list.append( + dpi.SoilProfile1D( + Name=str(profile_id), + BottomLevel=-30, + Layers1D=list_of_1D_layers, + ) + ) + return profile_list + + + def get_zone_type(csv_zone_type: str): + dictionary = { + "NoZones": dpi.ZoneTypeClass.NoZones, + "ZoneAreas": dpi.ZoneTypeClass.ZoneAreas, + "ForbiddenZones": dpi.ZoneTypeClass.ForbiddenZones, + } + return dictionary[csv_zone_type] + + + def read_locations_csv(location_csv_name: str, scenario_csv_name: str): + # read csv file using pandas + location_csv = pd.read_csv(location_csv_name, delimiter=";") + scenario_csv = pd.read_csv(scenario_csv_name, delimiter=";") + merged_csv = pd.merge(location_csv, scenario_csv, on="location_id") + # initialize location list that will be used for the dam input + locations_list = [] + # Loop through all unique profile names of the csv + for index, row in merged_csv.iterrows(): + # initialize DesignScenario + design_scenario = dpi.DesignScenario( + Id=str(index), + PolderLevel=row["polderlevel"], + HeadPl2=row["head_pl2"], + HeadPl3=row["head_pl3"], + PlLineOffsetBelowDikeTopAtRiver=row["PLLineOffsetBelowDikeTopAtRiver"], + PlLineOffsetBelowDikeTopAtPolder=row["PLLineOffsetBelowDikeTopAtPolder"], + PlLineOffsetBelowShoulderBaseInside=row[ + "PLLineOffsetBelowShoulderBaseInside" + ], + PlLineOffsetBelowDikeToeAtPolder=row["PLLIneOffsetBelowDikeToeAtPolder"], + RiverLevel=row["water_height"], + RiverLevelLow=row["water_height_low"], + DikeTableHeight=row["dike_table_height"], + RequiredSafetyFactorStabilityInnerSlope=row[ + "safety_factor_stability_inner_slope" + ], + RequiredSafetyFactorStabilityOuterSlope=row[ + "safety_factor_stability_outer_slope" + ], + UpliftCriterionPiping=row["uplift_criterion_piping"], + UpliftCriterionStability=row["uplift_criterion_stability"], + RequiredSafetyFactorPiping=row["safety_factor_piping"], + ) + # initialize design options class + design_options = dpi.DesignOptions( + ShoulderEmbankmentMaterial=row["ophoogmateriaalberm"], + StabilityShoulderGrowSlope=row["StabilityShoulderGrowSlope"], + StabilityShoulderGrowDeltaX=row["StabilityShoulderGrowDeltaX"], + StabilitySlopeAdaptionDeltaX=row["StabilitySlopeAdaptionDeltaX"], + NewDikeTopWidth=row["NewDikeTopWidth"], + NewDikeSlopeInside=row["NewDikeSlopeInside"], + NewDikeSlopeOutside=row["NewDikeSlopeOutside"], + NewShoulderTopSlope=row["NewShoulderTopSlope"], + NewShoulderBaseSlope=row["NewShoulderBaseSlope"], + NewMaxHeightShoulderAsFraction=row["NewMaxHeightShoulderAsFraction"], + NewMinDistanceDikeToeStartDitch=row["NewMinDistanceDikeToeStartDitch"], + UseNewDitchDefinition=row["UseNewDitchDefinition"], + NewWidthDitchBottom=row["NewWidthDitchBottom"], + NewDepthDitch=row["NewDepthDitch"], + NewSlopeAngleDitch=row["NewSlopeAngleDitch"], + RedesignDikeHeight=0, + RedesignDikeShoulder=0, + SlopeAdaptionStartCotangent=1, + SlopeAdaptionEndCotangent=1, + SlopeAdaptionStepCotangent=1, + StabilityDesignMethod=dpi.StabilityDesignMethodType.OptimizedSlopeAndShoulderAdaption, + ) + # Initialize stability options + stability_options = dpi.StabilityOptions( + MinimumCircleDepth=row["minimal_circle_depth"], + TrafficLoad=row["trafficload"], + ZoneType=get_zone_type(row["ZoneType"]), + ) + # initialize waternet options + waternet_options = dpi.WaternetOptions( + DampingFactorPl3=row["dempingsfactor_pl3"], + DampingFactorPl4=row["dempingsfactor_pl4"], + PhreaticLineCreationMethod=row["PLLineCreationMethod"], + PenetrationLength=0, + SlopeDampingFactor=1, + IntrusionVerticalWaterPressure=dpi.IntrusionVerticalWaterPressureType.Standard, + DikeSoilScenario=dpi.DikeSoilScenarioType.ClayDikeOnClay, + ) + # initialize location class + location = dpi.Location( + XSoilGeometry2DOrigin=row["x_soilgeometry2D_origin"], + SurfaceLineName=row["surfaceline_id"], + SegmentName=row["segment_id"], + DikeEmbankmentMaterial=row["ophoogmateriaaldijk"], + Name=row["location_id"], + DesignOptions=design_options, + DesignScenarios=[design_scenario], + StabilityOptions=stability_options, + WaternetOptions=waternet_options, + ) + locations_list.append(location) + return locations_list + + + def read_soilmaterials_csv(soilmaterials_csv_name: str): + # read csv file using pandas + soils_csv = pd.read_csv(soilmaterials_csv_name, delimiter=";") + # initialize soil list that will be used for the dam input + soils_list = [] + # Loop through all unique soil names of the csv + for index, row in soils_csv.iterrows(): + soil = dpi.Soil( + Name=row["Name"], + BelowPhreaticLevel=row["Saturatedunitweight"], + AbovePhreaticLevel=row["Unsaturatedunitweight"], + Cohesion=row["Cohesion"], + FrictionAngle=row["Frictionangle"], + DiameterD70=row["DiameterD70"], + PermeabKx=row["PermeabilityX"], + ShearStrengthModel=dpi.ShearStrengthModelType.CPhi, + StrengthIncreaseExponent=row["Strengthincreaseexp(m)"], + RatioCuPc=row["RatioSu/Pc"], + ) + soils_list.append(soil) + return soils_list + + + @pytest.mark.acceptance + def test_tutorial_read_csv_files(): + segments_list = read_segment_csv_file( + "trunk\\src\\tests\\test_data\\csvfiles\\segments.csv" + ) + surface_lines = read_surface_lines_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\surfacelines.csv" + ) + characteristic_points = read_characteristic_points( + "trunk\\src\\tests\\test_data\\csvfiles\\characteristicpoints.csv" + ) + # merge the two dictionaries to create surface line + for key, value in surface_lines.items(): + surface_lines[key] += characteristic_points.get(key, []) + # sort points based on X coordinate + surface_lines[key].sort(key=get_X) + # all the points of the surface lines are merged so the surface lines list can be created + surface_lines_dam_input = [] + for location, points in surface_lines.items(): + surface_lines_dam_input.append(dpi.SurfaceLine(Name=location, Points=points)) + # the soil profile should also be created + # In this case only 1D segments will be inputted + profiles = read_profile("trunk\\src\\tests\\test_data\\csvfiles\\soilprofiles.csv") + # read location csv + locations = read_locations_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\locations.csv", + "trunk\\src\\tests\\test_data\\csvfiles\\scenarios.csv", + ) + # read soil materials csv + soils = read_soilmaterials_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\soilmaterials.csv" + ) + # create stability parameters + stability_parameter = dpi.StabilityParameters( + SearchMethod=dpi.SearchMethodType.Calculationgrid, + GridDetermination=dpi.GridDeterminationType.Automatic, + BishopTangentLinesDefinition=dpi.BishopTangentLinesDefinitionType.OnBoundaryLines, + ) + # create dam input + dam_input = dpi.DamInput( + SurfaceLines=surface_lines_dam_input, + Soils=soils, + SoilProfiles1D=profiles, + Segments=segments_list, + Locations=locations, + FailureMechanismSystemType=dpi.FailureMechanismSystem.StabilityInside, + StabilityModelType=dpi.StabilityType.UpliftVan, + ProjectPath=Path(""), + StabilityParameters=stability_parameter, + ) + + xml_dam_input = Path( + TestUtils.get_output_test_data_dir(""), "InputTutorialFile.xml" + ) + dam_input.ExportToXml(xml_file=xml_dam_input) + xml_dam_output = Path( + TestUtils.get_output_test_data_dir(""), "OutputTutorialxml.xml" + ) + result_code = dam_input.execute( + xml_input_file=xml_dam_input, xml_output_file=xml_dam_output + ) \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_materials_code_snippet.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_materials_code_snippet.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_materials_code_snippet.rst (revision 3529) @@ -0,0 +1,32 @@ +Creating Soil class from soilmaterials.csv code snippet +------------------------------------------------------- + +.. code-block:: python + + def read_soilmaterials_csv(soilmaterials_csv_name: str): + # read csv file using pandas + soils_csv = pd.read_csv(soilmaterials_csv_name, delimiter=";") + # initialize soil list that will be used for the dam input + soils_list = [] + # Loop through all unique soil names of the csv + for index, row in soils_csv.iterrows(): + soil = dpi.Soil( + Name=row["Name"], + BelowPhreaticLevel=row["Saturatedunitweight"], + AbovePhreaticLevel=row["Unsaturatedunitweight"], + Cohesion=row["Cohesion"], + FrictionAngle=row["Frictionangle"], + DiameterD70=row["DiameterD70"], + PermeabKx=row["PermeabilityX"], + ShearStrengthModel=dpi.ShearStrengthModelType.CPhi, + StrengthIncreaseExponent=row["Strengthincreaseexp(m)"], + RatioCuPc=row["RatioSu/Pc"], + ) + soils_list.append(soil) + return soils_list + + if __name__ == "__main__": + # read soil materials csv + soils = read_soilmaterials_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\soilmaterials.csv" + ) Index: DamClients/DamPythonInterface/trunk/doc/source/conf.py =================================================================== diff -u -r3483 -r3529 --- DamClients/DamPythonInterface/trunk/doc/source/conf.py (.../conf.py) (revision 3483) +++ DamClients/DamPythonInterface/trunk/doc/source/conf.py (.../conf.py) (revision 3529) @@ -57,7 +57,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ["sphinx.ext.autodoc"] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.intersphinx"] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.mds =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.mds (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.mds (revision 3529) @@ -0,0 +1,25 @@ +[Frame] +ProjectId=- +AnnexNum=- +DrawnBy=- +DateStamp=- +UseCurrentDate=1 + +[Page] +PagePrintAxes01=0 +PageOrientation01=1 +PageMarginLeft01=10 +PageMarginRight01=30 +PageMarginTop01=10 +PageMarginBottom01=10 +PageWidth01=210 +PageHeight01=297 +PagePrintAxes02=0 +PageOrientation02=0 +PageMarginLeft02=30 +PageMarginRight02=10 +PageMarginTop02=10 +PageMarginBottom02=10 +PageWidth02=210 +PageHeight02=297 + Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilprofiles.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilprofiles.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilprofiles.csv (revision 3529) @@ -0,0 +1,5 @@ +soilprofile_id;top_level;soil_name +soilprofile_01;10;Dijkmateriaal +soilprofile_01;0;Deklaag_klei +soilprofile_01;-2;wl_zand1 +soilprofile_01;-10;wl_zand4 Index: DamClients/DamPythonInterface/trunk/src/tests/test_dampythonframework.py =================================================================== diff -u -r3495 -r3529 --- DamClients/DamPythonInterface/trunk/src/tests/test_dampythonframework.py (.../test_dampythonframework.py) (revision 3495) +++ DamClients/DamPythonInterface/trunk/src/tests/test_dampythonframework.py (.../test_dampythonframework.py) (revision 3529) @@ -19,23 +19,377 @@ # Stichting Deltares and remain full property of Stichting Deltares at all times. # All rights reserved. - +from trunk.src.dampythoninterface.location import Location +from trunk.src.dampythoninterface.soil import Soil +from trunk.src.dampythoninterface.surface_line import Point from dampythoninterface import __version__ -import dampythoninterface +import dampythoninterface as dpi +from .utils import TestUtils +import pandas as pd +from pathlib import Path import pytest -@pytest.mark.acceptance -def test_version(): - assert __version__ == "0.1.0" +class TestDamPythonInterface: + @pytest.mark.acceptance + def test_version(self): + assert __version__ == "0.1.0" + @pytest.mark.unittest + def test_imports(self): + assert dpi.surface_line + assert dpi.segment + assert dpi.soil + assert dpi.stability_parameters + assert dpi.soilprofile1D + assert dpi.input -@pytest.mark.unittest -def test_imports(): - assert dampythoninterface.surface_line - assert dampythoninterface.segment - assert dampythoninterface.soil - assert dampythoninterface.stability_parameters - assert dampythoninterface.soilprofile1D - assert dampythoninterface.input + +class TestTutorial: + def get_failure_mechanism(self, soil_profile: str): + import dampythoninterface as dpi + + output_dictionary = { + "All": dpi.SegmentFailureMechanismTypeClass.All, + "Stability": dpi.SegmentFailureMechanismTypeClass.Stability, + "Piping": dpi.SegmentFailureMechanismTypeClass.Piping, + "Liquefaction": dpi.SegmentFailureMechanismTypeClass.Liquefaction, + } + return output_dictionary[soil_profile] + + def read_segment_csv_file(self, file_name: str): + # read csv file using pandas + segment_csv = pd.read_csv(file_name, delimiter=";") + # initialize segment list that will be used for the dam input + segments_list = [] + # Loop through all unique segment names of the csv + for segment_id in segment_csv["segment_id"].unique(): + # loop through all different probabilities and create a list of the SoilGeometryProbabilityElement + list_of_probability_elements = [] + for csv_row in segment_csv[segment_csv["segment_id"] == segment_id].index: + list_of_probability_elements.append( + dpi.SoilGeometryProbabilityElement( + **{ + "SoilProfileName": segment_csv["soilprofile_id"][csv_row], + "SoilProfileType": dpi.SoilProfileTypeClass.ProfileType1D, + "Probability": segment_csv["probability"][csv_row], + "SegmentFailureMechanismType": self.get_failure_mechanism( + segment_csv["calculation_type"][csv_row] + ), + } + ) + ) + # create segment and append it to the segment list + segments_list.append( + dpi.Segment( + Name=str(segment_id), + SoilGeometryProbability=list_of_probability_elements, + ) + ) + return segments_list + + def read_surface_lines_csv(self, file_name: str): + # read csv file using pandas + surface_lines_csv = pd.read_csv(file_name, delimiter=";", index_col=False) + surface_lines = {} + # loop though all locations + for location_id in surface_lines_csv["LOCATIONID"]: + # get row of one of the locations + row_csv = surface_lines_csv[surface_lines_csv["LOCATIONID"] == location_id] + row_csv = row_csv.values[0][1:] + # reshape row so that each point is separated + row_csv = row_csv.reshape((-1, 3)) + # create list of points all values all values have a none type + surface_lines[location_id] = [] + for point in row_csv: + # check if point is defined or if it is nan + if not (str(point[0]) == "nan") or not (str(point[-1]) == "nan"): + surface_lines[location_id].append( + dpi.Point( + X=point[0], Z=point[-1], PointType=dpi.PointTypeEnum.NONE + ) + ) + return surface_lines + + def get_characteristic_point_type(self, point_type: str): + output_dictionary = { + "Maaiveld buitenwaarts": dpi.PointTypeEnum.SurfaceLevelOutside, + "Teen dijk buitenwaarts": dpi.PointTypeEnum.DikeToeAtRiver, + "Kruin buitenberm": dpi.PointTypeEnum.ShoulderTopOutside, + "Insteek buitenberm": dpi.PointTypeEnum.ShoulderBaseOutside, + "Kruin buitentalud": dpi.PointTypeEnum.DikeTopAtRiver, + "referentielijn": dpi.PointTypeEnum.DikeLine, + "Verkeersbelasting kant buitenwaarts": dpi.PointTypeEnum.TrafficLoadOutside, + "Verkeersbelasting kant binnenwaarts": dpi.PointTypeEnum.TrafficLoadInside, + "Kruin binnentalud": dpi.PointTypeEnum.DikeTopAtPolder, + "Insteek binnenberm": dpi.PointTypeEnum.ShoulderBaseInside, + "Kruin binnenberm": dpi.PointTypeEnum.ShoulderTopInside, + "Teen dijk binnenwaarts": dpi.PointTypeEnum.DikeToeAtPolder, + "Insteek sloot dijkzijde": dpi.PointTypeEnum.DitchDikeSide, + "Slootbodem dijkzijde": dpi.PointTypeEnum.BottomDitchDikeSide, + "Slootbodem polderzijde": dpi.PointTypeEnum.BottomDitchPolderSide, + "Insteek sloot polderzijde": dpi.PointTypeEnum.DitchPolderSide, + "Maaiveld binnenwaarts": dpi.PointTypeEnum.SurfaceLevelInside, + } + return output_dictionary.get(point_type, dpi.PointTypeEnum.NONE) + + def read_characteristic_points(self, file_name: str): + # read csv file using pandas + characteristic_points_csv = pd.read_csv(file_name, delimiter=";") + column_groups = [ + char_type_point.split("_")[-1] + for char_type_point in characteristic_points_csv.columns[1:] + ] + # remove duplicates + column_groups = list(dict.fromkeys(column_groups)) + characteristic_points_results = {} + # loop though all locations + for characteristic_points in characteristic_points_csv["LOCATIONID"]: + row_csv = characteristic_points_csv[ + characteristic_points_csv["LOCATIONID"] == characteristic_points + ] + characteristic_points_results[characteristic_points] = [] + for characteristic_point_type in column_groups: + # get relevant columns + relevant_columns = [ + char_type_point + for char_type_point in characteristic_points_csv.columns + if characteristic_point_type in char_type_point + ] + char_point = row_csv[relevant_columns] + if not (char_point.isin([-1]).sum().sum() == 3): + characteristic_points_results[characteristic_points].append( + Point( + X=list(char_point["X_" + characteristic_point_type])[0], + Z=list(char_point["Z_" + characteristic_point_type])[0], + PointType=self.get_characteristic_point_type( + characteristic_point_type + ), + ) + ) + return characteristic_points_results + + def get_X(self, d): + return d.X + + def read_profile(self, file_name: str): + # read csv file using pandas + profile_csv = pd.read_csv(file_name, delimiter=";") + # initialize profile list that will be used for the dam input + profile_list = [] + # Loop through all unique profile names of the csv + for profile_id in profile_csv["soilprofile_id"].unique(): + list_of_1D_layers = [] + for csv_row in profile_csv[ + profile_csv["soilprofile_id"] == profile_id + ].index: + list_of_1D_layers.append( + dpi.Layer1D( + **{ + "Name": profile_csv["soil_name"][csv_row], + "SoilName": profile_csv["soil_name"][csv_row], + "TopLevel": profile_csv["top_level"][csv_row], + "IsAquifer": False, + "WaterpressureInterpolationModel": dpi.WaterpressureInterpolationModelType.Automatic, + } + ) + ) + # create profile and append it to the profile list + profile_list.append( + dpi.SoilProfile1D( + Name=str(profile_id), + BottomLevel=-30, + Layers1D=list_of_1D_layers, + ) + ) + return profile_list + + def get_zone_type(self, csv_zone_type: str): + dictionary = { + "NoZones": dpi.ZoneTypeClass.NoZones, + "ZoneAreas": dpi.ZoneTypeClass.ZoneAreas, + "ForbiddenZones": dpi.ZoneTypeClass.ForbiddenZones, + } + return dictionary[csv_zone_type] + + def read_locations_csv(self, location_csv_name: str, scenario_csv_name: str): + # read csv file using pandas + location_csv = pd.read_csv(location_csv_name, delimiter=";") + scenario_csv = pd.read_csv(scenario_csv_name, delimiter=";") + merged_csv = pd.merge(location_csv, scenario_csv, on="location_id") + # initialize location list that will be used for the dam input + locations_list = [] + # Loop through all unique profile names of the csv + for index, row in merged_csv.iterrows(): + # initialize DesignScenario + design_scenario = dpi.DesignScenario( + Id=str(index), + PolderLevel=row["polderlevel"], + HeadPl2=row["head_pl2"], + HeadPl3=row["head_pl3"], + PlLineOffsetBelowDikeTopAtRiver=row["PLLineOffsetBelowDikeTopAtRiver"], + PlLineOffsetBelowDikeTopAtPolder=row[ + "PLLineOffsetBelowDikeTopAtPolder" + ], + PlLineOffsetBelowShoulderBaseInside=row[ + "PLLineOffsetBelowShoulderBaseInside" + ], + PlLineOffsetBelowDikeToeAtPolder=row[ + "PLLIneOffsetBelowDikeToeAtPolder" + ], + RiverLevel=row["water_height"], + RiverLevelLow=row["water_height_low"], + DikeTableHeight=row["dike_table_height"], + RequiredSafetyFactorStabilityInnerSlope=row[ + "safety_factor_stability_inner_slope" + ], + RequiredSafetyFactorStabilityOuterSlope=row[ + "safety_factor_stability_outer_slope" + ], + UpliftCriterionPiping=row["uplift_criterion_piping"], + UpliftCriterionStability=row["uplift_criterion_stability"], + RequiredSafetyFactorPiping=row["safety_factor_piping"], + ) + # initialize design options class + design_options = dpi.DesignOptions( + ShoulderEmbankmentMaterial=row["ophoogmateriaalberm"], + StabilityShoulderGrowSlope=row["StabilityShoulderGrowSlope"], + StabilityShoulderGrowDeltaX=row["StabilityShoulderGrowDeltaX"], + StabilitySlopeAdaptionDeltaX=row["StabilitySlopeAdaptionDeltaX"], + NewDikeTopWidth=row["NewDikeTopWidth"], + NewDikeSlopeInside=row["NewDikeSlopeInside"], + NewDikeSlopeOutside=row["NewDikeSlopeOutside"], + NewShoulderTopSlope=row["NewShoulderTopSlope"], + NewShoulderBaseSlope=row["NewShoulderBaseSlope"], + NewMaxHeightShoulderAsFraction=row["NewMaxHeightShoulderAsFraction"], + NewMinDistanceDikeToeStartDitch=row["NewMinDistanceDikeToeStartDitch"], + UseNewDitchDefinition=row["UseNewDitchDefinition"], + NewWidthDitchBottom=row["NewWidthDitchBottom"], + NewDepthDitch=row["NewDepthDitch"], + NewSlopeAngleDitch=row["NewSlopeAngleDitch"], + RedesignDikeHeight=0, + RedesignDikeShoulder=0, + SlopeAdaptionStartCotangent=1, + SlopeAdaptionEndCotangent=1, + SlopeAdaptionStepCotangent=1, + StabilityDesignMethod=dpi.StabilityDesignMethodType.OptimizedSlopeAndShoulderAdaption, + ) + # Initialize stability options + stability_options = dpi.StabilityOptions( + MinimumCircleDepth=row["minimal_circle_depth"], + TrafficLoad=row["trafficload"], + ZoneType=self.get_zone_type(row["ZoneType"]), + ) + # initialize waternet options + waternet_options = dpi.WaternetOptions( + DampingFactorPl3=row["dempingsfactor_pl3"], + DampingFactorPl4=row["dempingsfactor_pl4"], + PhreaticLineCreationMethod=row["PLLineCreationMethod"], + PenetrationLength=0, + SlopeDampingFactor=1, + IntrusionVerticalWaterPressure=dpi.IntrusionVerticalWaterPressureType.Standard, + DikeSoilScenario=dpi.DikeSoilScenarioType.ClayDikeOnClay, + ) + # initialize location class + location = dpi.Location( + XSoilGeometry2DOrigin=row["x_soilgeometry2D_origin"], + SurfaceLineName=row["surfaceline_id"], + SegmentName=row["segment_id"], + DikeEmbankmentMaterial=row["ophoogmateriaaldijk"], + Name=row["location_id"], + DesignOptions=design_options, + DesignScenarios=[design_scenario], + StabilityOptions=stability_options, + WaternetOptions=waternet_options, + ) + locations_list.append(location) + return locations_list + + def read_soilmaterials_csv(self, soilmaterials_csv_name: str): + # read csv file using pandas + soils_csv = pd.read_csv(soilmaterials_csv_name, delimiter=";") + # initialize soil list that will be used for the dam input + soils_list = [] + # Loop through all unique soil names of the csv + for index, row in soils_csv.iterrows(): + soil = dpi.Soil( + Name=row["Name"], + BelowPhreaticLevel=row["Saturatedunitweight"], + AbovePhreaticLevel=row["Unsaturatedunitweight"], + Cohesion=row["Cohesion"], + FrictionAngle=row["Frictionangle"], + DiameterD70=row["DiameterD70"], + PermeabKx=row["PermeabilityX"], + ShearStrengthModel=dpi.ShearStrengthModelType.CPhi, + StrengthIncreaseExponent=row["Strengthincreaseexp(m)"], + RatioCuPc=row["RatioSu/Pc"], + ) + soils_list.append(soil) + return soils_list + + @pytest.mark.acceptance + def test_tutorial_read_csv_files(self): + segments_list = self.read_segment_csv_file( + "trunk\\src\\tests\\test_data\\csvfiles\\segments.csv" + ) + surface_lines = self.read_surface_lines_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\surfacelines.csv" + ) + characteristic_points = self.read_characteristic_points( + "trunk\\src\\tests\\test_data\\csvfiles\\characteristicpoints.csv" + ) + # merge the two dictionaries to create surface line + for key, value in surface_lines.items(): + surface_lines[key] += characteristic_points.get(key, []) + # sort points based on X coordinate + surface_lines[key].sort(key=self.get_X) + # all the points of the surface lines are merged so the surface lines list can be created + surface_lines_dam_input = [] + for location, points in surface_lines.items(): + surface_lines_dam_input.append( + dpi.SurfaceLine(Name=location, Points=points) + ) + # the soil profile should also be created + # In this case only 1D segments will be inputted + profiles = self.read_profile( + "trunk\\src\\tests\\test_data\\csvfiles\\soilprofiles.csv" + ) + # read location csv + locations = self.read_locations_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\locations.csv", + "trunk\\src\\tests\\test_data\\csvfiles\\scenarios.csv", + ) + # read soil materials csv + soils = self.read_soilmaterials_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\soilmaterials.csv" + ) + # create stability parameters + stability_parameter = dpi.StabilityParameters( + SearchMethod=dpi.SearchMethodType.Calculationgrid, + GridDetermination=dpi.GridDeterminationType.Automatic, + BishopTangentLinesDefinition=dpi.BishopTangentLinesDefinitionType.OnBoundaryLines, + ) + # create dam input + dam_input = dpi.DamInput( + SurfaceLines=surface_lines_dam_input, + Soils=soils, + SoilProfiles1D=profiles, + Segments=segments_list, + Locations=locations, + FailureMechanismSystemType=dpi.FailureMechanismSystem.StabilityInside, + StabilityModelType=dpi.StabilityType.UpliftVan, + ProjectPath=Path(""), + StabilityParameters=stability_parameter, + ) + + xml_dam_input = Path( + TestUtils.get_output_test_data_dir(""), "InputTutorialFile.xml" + ) + dam_input.ExportToXml(xml_file=xml_dam_input) + xml_dam_output = Path( + TestUtils.get_output_test_data_dir(""), "OutputTutorialxml.xml" + ) + result_code = dam_input.execute( + xml_input_file=xml_dam_input, xml_output_file=xml_dam_output + ) Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_profile_1d_coders_snippet.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_profile_1d_coders_snippet.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_profile_1d_coders_snippet.rst (revision 3529) @@ -0,0 +1,41 @@ +Creating profiles class from soilprofiles.csv file code snippet +--------------------------------------------------------------- + +.. code-block:: python + + import dampythoninterface as dpi + import pandas as pd + + def read_profile(file_name: str): + # read csv file using pandas + profile_csv = pd.read_csv(file_name, delimiter=";") + # initialize profile list that will be used for the dam input + profile_list = [] + # Loop through all unique profile names of the csv + for profile_id in profile_csv["soilprofile_id"].unique(): + list_of_1D_layers = [] + for csv_row in profile_csv[profile_csv["soilprofile_id"] == profile_id].index: + list_of_1D_layers.append( + dpi.Layer1D( + **{ + "Name": profile_csv["soil_name"][csv_row], + "SoilName": profile_csv["soil_name"][csv_row], + "TopLevel": profile_csv["top_level"][csv_row], + "IsAquifer": False, + "WaterpressureInterpolationModel": dpi.WaterpressureInterpolationModelType.Automatic, + } + ) + ) + # create profile and append it to the profile list + profile_list.append( + dpi.SoilProfile1D( + Name=str(profile_id), + BottomLevel=-30, + Layers1D=list_of_1D_layers, + ) + ) + return profile_list + + if __name__ == "__main__": + # In this case only 1D segments will be inputted + profiles = read_profile("soilprofiles.csv") Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/surface_lines_csv_tutorial.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/surface_lines_csv_tutorial.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/surface_lines_csv_tutorial.rst (revision 3529) @@ -0,0 +1,185 @@ +Creating Surface Line class by reading surfacelines.csv and characteristicpoints.csv +------------------------------------------------------------------------------------ + +In this section the user will read the surfacelines.csv and characteristicpoints.csv +and combine them to create a list of Surface Lines to input in the dam input. +In this case two different functions are created the read_surface_lines_csv and +read_characteristic_points_csv. + +The read_surface_lines_csv has as input the location of the surfacelines.csv. +First the surfacelines.csv is read using the pandas modules. + +.. code-block:: python + + import pandas as pd + # read csv file using pandas + surface_lines_csv = pd.read_csv(file_name, delimiter=";") + +An empty dictionary is initialized that will be filled with the points contained in the surfacelines.csv. + +.. code-block:: python + + surface_lines = {} + +Then a loop is defined that loops through each different location contained in the csv. +The row that is defined for each location is extracted. +Finally the row is reshaped so that every point is separated. + +.. code-block:: python + + # loop though all locations + for location_id in surface_lines_csv["LOCATIONID"]: + # get row of one of the locations + row_csv = surface_lines_csv[surface_lines_csv["LOCATIONID"] == location_id] + row_csv = row_csv.values[0][1:] + # reshape row so that each point is separated + row_csv = row_csv.reshape((-1, 3)) + +Finally, for each point location a list is initialized with the intention of appending +all points in that certain location. +Note that point that with a NaN value are not included. +Also these points are not given a certain characteristic point type and therefore the +enum type NONE is used from the :py:class:`dampythoninterface.surface_line.PointTypeEnum`. + +.. code-block:: python + + # create list of points all values all values have a none type + surface_lines[location_id] = [] + for point in row_csv: + # check if point is defined or if it is nan + if not (str(point[0]) == "nan") or not (str(point[-1]) == "nan"): + surface_lines[location_id].append( + dpi.Point(X=point[0], Z=point[-1], PointType=dpi.PointTypeEnum.NONE)) + +Finally, the created function read_surface_lines_csv, returns a dictionary of location ids. +Each location id is assigned a certain point list. + +.. code-block:: python + + return surface_lines + +After defining the surface line read function the read_characteristic_points function is defined. +The first step is to establish a relationship between the columns of the characteristicpoints.csv +and the :py:class:`dampythoninterface.surface_line.PointTypeEnum` class. To do that a simple function is created +were a helper dictionary is used to retrieve the enum value from the :py:class:`dampythoninterface.surface_line.PointTypeEnum` class. +The code is appended below + +.. code-block:: python + + def get_characteristic_point_type(point_type: str): + output_dictionary = { + "Maaiveld buitenwaarts": dpi.PointTypeEnum.SurfaceLevelOutside, + "Teen dijk buitenwaarts": dpi.PointTypeEnum.DikeToeAtRiver, + "Kruin buitenberm": dpi.PointTypeEnum.ShoulderTopOutside, + "Insteek buitenberm": dpi.PointTypeEnum.ShoulderBaseOutside, + "Kruin buitentalud": dpi.PointTypeEnum.DikeTopAtRiver, + "referentielijn": dpi.PointTypeEnum.DikeLine, + "Verkeersbelasting kant buitenwaarts": dpi.PointTypeEnum.TrafficLoadOutside, + "Verkeersbelasting kant binnenwaarts": dpi.PointTypeEnum.TrafficLoadInside, + "Kruin binnentalud": dpi.PointTypeEnum.DikeTopAtPolder, + "Insteek binnenberm": dpi.PointTypeEnum.ShoulderBaseInside, + "Kruin binnenberm": dpi.PointTypeEnum.ShoulderTopInside, + "Teen dijk binnenwaarts": dpi.PointTypeEnum.DikeToeAtPolder, + "Insteek sloot dijkzijde": dpi.PointTypeEnum.DitchDikeSide, + "Slootbodem dijkzijde": dpi.PointTypeEnum.BottomDitchDikeSide, + "Slootbodem polderzijde": dpi.PointTypeEnum.BottomDitchPolderSide, + "Insteek sloot polderzijde": dpi.PointTypeEnum.DitchPolderSide, + "Maaiveld binnenwaarts": dpi.PointTypeEnum.SurfaceLevelInside, + } + return output_dictionary.get(point_type, dpi.PointTypeEnum.NONE) + +Then the read_characteristic_points is defined. +First, the csv file is read using the pandas module. + +.. code-block:: python + + import pandas as pd + # read csv file using pandas + characteristic_points_csv = pd.read_csv(file_name, delimiter=";") + +Then the column titles are extracted from the csv files and duplicate values are removed. + +.. code-block:: python + + column_groups = [ + char_type_point.split("_")[-1] + for char_type_point in characteristic_points_csv.columns[1:] + ] + # remove duplicates + column_groups = list(dict.fromkeys(column_groups)) + +An empty dictionary is initialized that will be filled with the points contained in the characteristicpoints.csv. + +.. code-block:: python + + characteristic_points_results = {} + +Then a loop is defined that loops through each different location contained in the csv. +The row that is defined for each location is extracted. + +.. code-block:: python + + # loop though all locations + for characteristic_points in characteristic_points_csv["LOCATIONID"]: + row_csv = characteristic_points_csv[ + characteristic_points_csv["LOCATIONID"] == characteristic_points + ] + +Then all characteristic points can be extracted. +A loop is defined that will loop through all types of characteristic points. +For each characteristic point type all relevant columns are extracted. +This is actually a list of the X, Y and Z coordinate of a location. + + +.. code-block:: python + + characteristic_points_results[characteristic_points] = [] + for characteristic_point_type in column_groups: + # get relevant columns + relevant_columns = [ + char_type_point + for char_type_point in characteristic_points_csv.columns + if characteristic_point_type in char_type_point + ] + +These columns are extracted from the row of the csv file and appended as a point +to the dictionary of characteristic points. +Points that have -1 coordinates are not included in the in the list of characteristic points. + +.. code-block:: python + + char_point = row_csv[relevant_columns] + if not (char_point.isin([-1]).sum().sum() == 3): + characteristic_points_results[characteristic_points].append( + Point( + X=list(char_point["X_" + characteristic_point_type])[0], + Z=list(char_point["Z_" + characteristic_point_type])[0], + PointType=get_characteristic_point_type(characteristic_point_type), + ) + ) + +Finally, the created function read_characteristic_points, returns a dictionary of location ids. +Each location id is assigned a certain point list. + +.. code-block:: python + + return surface_lines + +The final step includes combining the points of the locations found in the two different csv files. +Note that the points need to be inputted in an ascending order. +This is done as it can be seen in the following code snippet + +.. code-block:: python + + def get_X(d): + return d.X + + # merge the two dictionaries to create surface line + for key, value in surface_lines.items(): + surface_lines[key] += characteristic_points.get(key, []) + # sort points based on X coordinate + surface_lines[key].sort(key=get_X) + # all the points of the surface lines are merged so the surface lines list can be created + surface_lines_dam_input = [] + for location, points in surface_lines.items(): + surface_lines_dam_input.append(dpi.SurfaceLine(Name=location, Points=points)) \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/soilmaterials.csv (revision 3529) @@ -0,0 +1,10 @@ +Name;Soiltype;Saturatedunitweight;Unsaturatedunitweight;Cohesion;Frictionangle;DiameterD70;PermeabilityX;Shearstrengthmodel;Strengthincreaseexp(m);RatioSu/Pc;UsePOP;POP +Dijkmateriaal;Clay;17;17;0.5;22;200;0;C phi;0.7;0.22;CheckUnchecked;10 +Deklaag_klei;Clay;16;16;0.5;22;200;0.001;C phi;0.7;0.22;CheckUnchecked;10 +wl_zand1;Sand;19;18;0;32;210;0.001;C phi;0.7;0.22;CheckUnchecked;10 +Ophoogmateriaal_dijk;Clay;17;17;0.5;22;200;0;C phi;0.7;0.22;CheckUnchecked;10 +Ophoogmateriaal_berm;Sand;19;18;0.5;22;200;0;C phi;0.7;0.22;CheckUnchecked;10 +wl_zand2;Sand;19;18;0;32;215;0.001;C phi;0.7;0.22;CheckUnchecked;10 +wl_zand3;Sand;19;18;0;32;220;0.001;C phi;0.7;0.22;CheckUnchecked;10 +wl_zand4;Sand;19;18;0;32;225;0.001;C phi;0.7;0.22;CheckUnchecked;10 +wl_zand5;Sand;19;18;0;32;230;0.001;C phi;0.7;0.22;CheckUnchecked;10 Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/scenarios.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/scenarios.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/scenarios.csv (revision 3529) @@ -0,0 +1,3 @@ +location_id;location_scenario_id;water_height;water_height_low;dike_table_height;safety_factor_stability_inner_slope;safety_factor_stability_outer_slope;uplift_criterion_piping;uplift_criterion_stability;safety_factor_piping +Profiel 1;1;3.8;2.5;4;1.22;1.16;1.2;1.2;1.2 + Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/surface_lines_snippet.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/surface_lines_snippet.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/surface_lines_snippet.rst (revision 3529) @@ -0,0 +1,108 @@ +Creating Surface Line class by reading surfacelines.csv and characteristicpoints.csv from code snippet +------------------------------------------------------------------------------------------------------ + +.. code-block:: python + + import dampythoninterface as dpi + import pandas as pd + + def read_surface_lines_csv(file_name: str): + # read csv file using pandas + surface_lines_csv = pd.read_csv(file_name, delimiter=";", index_col=False) + surface_lines = {} + # loop though all locations + for location_id in surface_lines_csv["LOCATIONID"]: + # get row of one of the locations + row_csv = surface_lines_csv[surface_lines_csv["LOCATIONID"] == location_id] + row_csv = row_csv.values[0][1:] + # reshape row so that each point is separated + row_csv = row_csv.reshape((-1, 3)) + # create list of points all values all values have a none type + surface_lines[location_id] = [] + for point in row_csv: + # check if point is defined or if it is nan + if not (str(point[0]) == "nan") or not (str(point[-1]) == "nan"): + surface_lines[location_id].append( + dpi.Point(X=point[0], Z=point[-1], PointType=dpi.PointTypeEnum.NONE) + ) + return surface_lines + + + def get_characteristic_point_type(point_type: str): + output_dictionary = { + "Maaiveld buitenwaarts": dpi.PointTypeEnum.SurfaceLevelOutside, + "Teen dijk buitenwaarts": dpi.PointTypeEnum.DikeToeAtRiver, + "Kruin buitenberm": dpi.PointTypeEnum.ShoulderTopOutside, + "Insteek buitenberm": dpi.PointTypeEnum.ShoulderBaseOutside, + "Kruin buitentalud": dpi.PointTypeEnum.DikeTopAtRiver, + "referentielijn": dpi.PointTypeEnum.DikeLine, + "Verkeersbelasting kant buitenwaarts": dpi.PointTypeEnum.TrafficLoadOutside, + "Verkeersbelasting kant binnenwaarts": dpi.PointTypeEnum.TrafficLoadInside, + "Kruin binnentalud": dpi.PointTypeEnum.DikeTopAtPolder, + "Insteek binnenberm": dpi.PointTypeEnum.ShoulderBaseInside, + "Kruin binnenberm": dpi.PointTypeEnum.ShoulderTopInside, + "Teen dijk binnenwaarts": dpi.PointTypeEnum.DikeToeAtPolder, + "Insteek sloot dijkzijde": dpi.PointTypeEnum.DitchDikeSide, + "Slootbodem dijkzijde": dpi.PointTypeEnum.BottomDitchDikeSide, + "Slootbodem polderzijde": dpi.PointTypeEnum.BottomDitchPolderSide, + "Insteek sloot polderzijde": dpi.PointTypeEnum.DitchPolderSide, + "Maaiveld binnenwaarts": dpi.PointTypeEnum.SurfaceLevelInside, + } + return output_dictionary.get(point_type, dpi.PointTypeEnum.NONE) + + + def read_characteristic_points(file_name: str): + # read csv file using pandas + characteristic_points_csv = pd.read_csv(file_name, delimiter=";") + column_groups = [ + char_type_point.split("_")[-1] + for char_type_point in characteristic_points_csv.columns[1:] + ] + # remove duplicates + column_groups = list(dict.fromkeys(column_groups)) + characteristic_points_results = {} + # loop though all locations + for characteristic_points in characteristic_points_csv["LOCATIONID"]: + row_csv = characteristic_points_csv[ + characteristic_points_csv["LOCATIONID"] == characteristic_points + ] + characteristic_points_results[characteristic_points] = [] + for characteristic_point_type in column_groups: + # get relevant columns + relevant_columns = [ + char_type_point + for char_type_point in characteristic_points_csv.columns + if characteristic_point_type in char_type_point + ] + char_point = row_csv[relevant_columns] + if not (char_point.isin([-1]).sum().sum() == 3): + characteristic_points_results[characteristic_points].append( + Point( + X=list(char_point["X_" + characteristic_point_type])[0], + Z=list(char_point["Z_" + characteristic_point_type])[0], + PointType=get_characteristic_point_type( + characteristic_point_type + ), + ) + ) + return characteristic_points_results + + def get_X(d): + return d.X + + if __name__ == "__main__": + surface_lines = read_surface_lines_csv( + "trunk\\src\\tests\\test_data\\csvfiles\\surfacelines.csv" + ) + characteristic_points = read_characteristic_points( + "trunk\\src\\tests\\test_data\\csvfiles\\characteristicpoints.csv" + ) + # merge the two dictionaries to create surface line + for key, value in surface_lines.items(): + surface_lines[key] += characteristic_points.get(key, []) + # sort points based on X coordinate + surface_lines[key].sort(key=get_X) + # all the points of the surface lines are merged so the surface lines list can be created + surface_lines_dam_input = [] + for location, points in surface_lines.items(): + surface_lines_dam_input.append(dpi.SurfaceLine(Name=location, Points=points)) \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/surfacelines.csv =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/surfacelines.csv (revision 0) +++ DamClients/DamPythonInterface/trunk/src/tests/test_data/csvfiles/surfacelines.csv (revision 3529) @@ -0,0 +1,2 @@ +LOCATIONID;X1;Y1;Z1;.....;Xn;Yn;Zn;(Profiel); +Profiel 1;0.000;0.000;1.000;10.000;0.000;1.000;19.000;0.000;4.000;20.500;0.000;4.000;23.000;0.000;4.000;35.000;0.000;0.000;100.000;0.000;0.000; Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_materials_tutorial.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_materials_tutorial.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/soil_materials_tutorial.rst (revision 3529) @@ -0,0 +1,7 @@ +Creating Soil class from soilmaterials.csv +------------------------------------------ + +To create a list of :py:class:`dampythoninterface.soil.Soil` class list that can later be inputted in the dam input a read_soilmaterials_csv function is created. +This function takes as input the location od the soilmaterials csv file which is exported from the DamUI. +The csv id read using pandas. And values of each row are used as inputs if the soil class. +The reader is referred directly to the code snippet referred below. Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/segment_csv_tutorial.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/segment_csv_tutorial.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/segment_csv_tutorial.rst (revision 3529) @@ -0,0 +1,87 @@ +Creating Segment class from segments.csv +---------------------------------------- +In this example the segments.csv is imported by using pandas. +The user can follow the following example to get the result of a list of Segments which can be later used as input of the DAM model. + +In the segments.csv it can be seen that the calculation_type is given by string value. +For example "Stability" or "Piping". The first step to read the csv successfully is for the user +to create a function that will transform this string input to the correct enumeration class +:py:class:`dampythoninterface.segment.SegmentFailureMechanismTypeClass`. The following code snippet +shows how + +.. code-block:: python + + def get_failure_mechanism(soil_profile): + import dampythoninterface as dpi + + output_dictionary = { + "All": dpi.SegmentFailureMechanismTypeClass.All, + "Stability": dpi.SegmentFailureMechanismTypeClass.Stability, + "Piping": dpi.SegmentFailureMechanismTypeClass.Piping, + "Liquefaction": dpi.SegmentFailureMechanismTypeClass.Liquefaction, + } + return output_dictionary[soil_profile] + +Then the user can read the csv file using pandas. + +.. code-block:: python + + import pandas as pd + # read csv file using pandas + segment_csv = pd.read_csv("segments.csv", delimiter=";") + +There are several ways to extract the values from the csv file. +In this case the user loops through unique id segments. +The second loop of the code lets the user loop through all the different rows of the csv +file that have the same segment_id. For each segment a new list of probabilities is +created. + +.. code-block:: python + + import dampythoninterface as dpi + # initialize segment list that will be used for the dam input + segments_list = [] + # Loop through all unique segment names of the csv + for segment_id in segment_csv["segment_id"].unique(): + # loop through all different probabilities and create a list of the SoilGeometryProbabilityElement + list_of_probability_elements = [] + for csv_row in segment_csv[segment_csv["segment_id"] == segment_id].index: + +In the second loop, a dictionary of the values that are contained in a certain row of the csv +is created. + +.. code-block:: python + + dictionary_probability_element = { + "SoilProfileName": segment_csv["soilprofile_id"][csv_row], + "SoilProfileType": dpi.SoilProfileTypeClass.ProfileType1D, + "Probability": segment_csv["probability"][csv_row], + "SegmentFailureMechanismType": get_failure_mechanism( + segment_csv["calculation_type"][csv_row] + ), + } + + +This dictionary can be used to initialize class :py:class:`dampythoninterface.segment.SoilGeometryProbabilityElement`, +which can be directly appended to the list_of_probability_elements of the segment + +.. code-block:: python + + list_of_probability_elements.append( + dpi.SoilGeometryProbabilityElement( + **dictionary_probability_element + ) + ) + +After running the second loop the :py:class:`dampythoninterface.segment.Segment` class is initiazed +and appended to the segments list. + +.. code-block:: python + + # create segment and append it to the segment list + segments_list.append( + Segment( + Name=str(segment_id), + SoilGeometryProbability=list_of_probability_elements, + ) + ) \ No newline at end of file Index: DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/setting_up_dam_input_and_executing.rst =================================================================== diff -u --- DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/setting_up_dam_input_and_executing.rst (revision 0) +++ DamClients/DamPythonInterface/trunk/doc/source/tutorial_sections/setting_up_dam_input_and_executing.rst (revision 3529) @@ -0,0 +1,52 @@ +Setting up the input class and executing the calculation +-------------------------------------------------------- + +Finally the user cab set up the more general settings of the +:py:class:`dampythoninterface.stability_parameters.StabilityParameters` class. +An example is shown in the following code snippet. + +.. code-block:: python + + # create stability parameters + stability_parameter = dpi.StabilityParameters( + SearchMethod=dpi.SearchMethodType.Calculationgrid, + GridDetermination=dpi.GridDeterminationType.Automatic, + BishopTangentLinesDefinition=dpi.BishopTangentLinesDefinitionType.OnBoundaryLines, + ) + +The :py:class:`dampythoninterface.input.DamInput` class can then be defined as follows. + +.. code-block:: python + + # create dam input + dam_input = dpi.DamInput( + SurfaceLines=surface_lines_dam_input, + Soils=soils, + SoilProfiles1D=profiles, + Segments=segments_list, + Locations=locations, + FailureMechanismSystemType=dpi.FailureMechanismSystem.StabilityInside, + StabilityModelType=dpi.StabilityType.UpliftVan, + ProjectPath=Path(""), + StabilityParameters=stability_parameter, + ) + +The input xml path is defined and the xml is exported. + +.. code-block:: python + + xml_dam_input = Path( + TestUtils.get_output_test_data_dir(""), "InputTutorialFile.xml" + ) + dam_input.ExportToXml(xml_file=xml_dam_input) + +Finally, the user can define an output file location and name and execute a DAM calculation + +.. code-block:: python + + xml_dam_output = Path( + TestUtils.get_output_test_data_dir(""), "OutputTutorialxml.xml" + ) + result_code = dam_input.execute( + xml_input_file=xml_dam_input, xml_output_file=xml_dam_output + ) \ No newline at end of file