diff --git a/CHANGELOG.md b/CHANGELOG.md index e55c7bdc..4ec54f31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,17 @@ Release History =============== -0.4.1 (dev) +0.4.2 (dev) ------------------ **|fixed|** installation options have been debugged and the documentation updated accordingly **|fixed|** automated download of example applications via the `download_example` functions now includes previously missing .csv files +0.4.1 (2023-10-XX) +------------------ + +**|hotfix|** added option `-o` to the terminal command line interface to enable the user to provide output path to save ramp results. This option is also accessible to python users using `ofname` argument of the `ramp/ramp_run.py::run_usecase` or the `ramp/post_process/post_process.py::export_series` functions. 0.4.0 (2023-02-17) ------------------ diff --git a/README.rst b/README.rst index d0011fab..17f558cb 100644 --- a/README.rst +++ b/README.rst @@ -148,7 +148,11 @@ need to run the ``ramp`` command with the option ``-i``: ramp -i -If you already know how many profile you want to simulate, you can indicate it with the + +.. note:: You can input several files, separated from each others by a single blank space + +If you already know +how many profile you want to simulate you can indicate it with the ``-n`` option: .. code-block:: bash @@ -160,7 +164,16 @@ providing a ``.xlsx`` input file with the ``-i`` option, this will then be equivalent to running ``python ramp_run.py`` from the ``ramp`` folder without being prompted for the number of profile within the console. -Other options are documented in the helper of `ramp`, which you access with the ``-h`` option + +If you want to save ramp results to a custom file, you can provide it with the option `-o` + +.. code-block:: bash + + ramp -i -o + +.. note:: You can provide a number of output files, separated from each others by a single blank space, matching the number of input files. + +Other options are documented in the help of `ramp`, which you access with the ``-h`` option .. code-block:: bash diff --git a/ramp/_version.py b/ramp/_version.py index 4ec40078..0bf3b7d6 100644 --- a/ramp/_version.py +++ b/ramp/_version.py @@ -1,2 +1,2 @@ -__version__ = "0.4.0" +__version__ = "0.4.1" diff --git a/ramp/cli.py b/ramp/cli.py index e8899d26..f5f3b4b1 100644 --- a/ramp/cli.py +++ b/ramp/cli.py @@ -19,6 +19,13 @@ type=str, help="path to the (xlsx) input files (including filename). If not provided, then legacy .py input files will be fetched", ) +parser.add_argument( + "-o", + dest="ofname_path", + nargs="+", + type=str, + help=f"path to the csv output files (including filename). If not provided, default output will be provided in {os.path.join(BASE_PATH, 'results')}", +) parser.add_argument( "-n", dest="num_profiles", @@ -72,6 +79,7 @@ def main(): args = vars(parser.parse_args()) fnames = args["fname_path"] + ofnames = args["ofname_path"] num_profiles = args["num_profiles"] # Define which input files should be considered and run. date_start = args["date_start"] @@ -120,6 +128,9 @@ def main(): else: days = None + if ofnames is None: + ofnames = [None] + if fnames is None: print("Please provide path to input file with option -i, \n\nDefault to old version of RAMP input files\n") # Files are specified as numbers in a list (e.g. [1,2] will consider input_file_1.py and input_file_2.py) @@ -135,8 +146,20 @@ def main(): else: num_profiles = [None] * len(input_files_to_run) + if len(ofnames) == 1: + ofnames = ofnames * len(input_files_to_run) + elif len(input_files_to_run) != len(ofnames): + raise ValueError( + f"The number of output file paths({len(ofnames)}) should match the number of input files paths ({len(input_files_to_run)})" + ) + for i, j in enumerate(input_files_to_run): - run_usecase(j=j, num_profiles=num_profiles[i], parallel=parallel_processing) + run_usecase( + j=j, + ofname=ofnames[i], + num_profiles=num_profiles[i], + parallel=parallel_processing, + ) else: if num_profiles is not None: if len(num_profiles) == 1: @@ -173,10 +196,23 @@ def main(): #TODO add more columns with other resampled functions (do this in Jupyter) resampled.to_csv(os.path.join(BASE_PATH, 'yearly_profile_hourly_resolution.csv')) else: + if len(ofnames) == 1: + ofnames = ofnames * len(fnames) + elif len(fnames) != len(ofnames): + raise ValueError( + f"The number of output file paths({len(ofnames)}) should match the number of input files paths ({len(fnames)})" + ) + for i, fname in enumerate(fnames): - run_usecase(fname=fname, num_profiles=num_profiles[i], days=days, parallel=parallel_processing) + run_usecase( + fname=fname, + ofname=ofnames[i], + num_profiles=num_profiles[i], + days=days, + parallel=parallel_processing, + ) if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/ramp/post_process/post_process.py b/ramp/post_process/post_process.py index a3dee56e..a7e98b20 100644 --- a/ramp/post_process/post_process.py +++ b/ramp/post_process/post_process.py @@ -68,9 +68,25 @@ def Profile_series_plot(stoch_profiles_series): # Export Profiles -def export_series(stoch_profiles_series, j=None, fname=None): +def export_series(stoch_profiles_series, j=None, fname=None, ofname=None): series_frame = pd.DataFrame(stoch_profiles_series) - if j is not None: - series_frame.to_csv(os.path.join(BASE_PATH, 'results', 'output_file_%d.csv' % (j))) - if fname is not None: - series_frame.to_csv(os.path.join(BASE_PATH, 'results', f'output_file_{os.path.split(fname)[-1]}.csv')) + path_to_write = None + if ofname is not None: + path_to_write = ofname + else: + if j is not None: + path_to_write = os.path.join( + BASE_PATH, "results", "output_file_%d.csv" % (j) + ) + if fname is not None: + path_to_write = os.path.join( + BASE_PATH, + "results", + f'output_file_{os.path.split(fname)[-1].replace(".", "_")}.csv', + ) + + if path_to_write is not None: + print(f"Writing RAMP results to {path_to_write}") + series_frame.to_csv(path_to_write) + else: + print("No path to a file was provided to write the results") diff --git a/ramp/ramp_run.py b/ramp/ramp_run.py index 953d91ad..96a8773a 100644 --- a/ramp/ramp_run.py +++ b/ramp/ramp_run.py @@ -39,7 +39,8 @@ from post_process import post_process as pp -def run_usecase(j=None, fname=None, num_profiles=None, days=None, plot=True, parallel=False): +def run_usecase(j=None, fname=None, ofname=None, num_profiles=None, days=None, plot=True, parallel=False): + # Calls the stochastic process and saves the result in a list of stochastic profiles if days is None: Profiles_list = stochastic_process(j=j, fname=fname, num_profiles=num_profiles, day_type=yearly_pattern(), parallel=parallel) @@ -48,7 +49,7 @@ def run_usecase(j=None, fname=None, num_profiles=None, days=None, plot=True, par Profiles_avg, Profiles_list_kW, Profiles_series = pp.Profile_formatting(Profiles_list) pp.Profile_series_plot(Profiles_series) # by default, profiles are plotted as a series - pp.export_series(Profiles_series, j, fname) + pp.export_series(Profiles_series, j, fname, ofname) if len(Profiles_list) > 1: # if more than one daily profile is generated, also cloud plots are shown pp.Profile_cloud_plot(Profiles_list, Profiles_avg) @@ -67,7 +68,7 @@ def run_usecase(j=None, fname=None, num_profiles=None, days=None, plot=True, par Profiles_avg, Profiles_list_kW, Profiles_series = pp.Profile_formatting(Profiles_list) pp.Profile_series_plot(Profiles_series) # by default, profiles are plotted as a series - pp.export_series(Profiles_series, j, fname) + pp.export_series(Profiles_series, j, fname, ofname) if len(Profiles_list) > 1: # if more than one daily profile is generated, also cloud plots are shown pp.Profile_cloud_plot(Profiles_list, Profiles_avg)