• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RAMP-project / RAMP / 9364900772

04 Jun 2024 09:46AM UTC coverage: 77.375%. First build
9364900772

Pull #150

github

web-flow
Merge df93fb41e into 8b66734bb
Pull Request #150: Release v0.5.2

285 of 316 new or added lines in 17 files covered. (90.19%)

1409 of 1821 relevant lines covered (77.38%)

0.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.32
/ramp/cli.py
1
import argparse
1✔
2
import datetime
1✔
3
import os.path
1✔
4

5
import pandas as pd
1✔
6
import numpy as np
1✔
7
from ramp.ramp_run import run_usecase
1✔
8

9
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
1✔
10

11
parser = argparse.ArgumentParser(
1✔
12
    prog="ramp",
13
    description="Execute RAMP code",
14
    epilog="To convert '.py' input files into '.xlsx' input files use the command 'ramp_convert'",
15
)
16
parser.add_argument(
1✔
17
    "-i",
18
    dest="fname_path",
19
    nargs="+",
20
    type=str,
21
    help="Path to the (.xlsx/.py) input files (including filename). Must be provided",
22
)
23
parser.add_argument(
1✔
24
    "-o",
25
    dest="ofname_path",
26
    nargs="+",
27
    type=str,
28
    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')}",
29
)
30
parser.add_argument(
1✔
31
    "-n",
32
    dest="num_days",
33
    nargs="+",
34
    type=int,
35
    help="Number of daily profiles to be generated",
36
)
37

38
parser.add_argument(
1✔
39
    "-y",
40
    dest="years",
41
    nargs="+",
42
    type=int,
43
    help="Years for which one should generate demand profiles",
44
)
45

46
parser.add_argument(
1✔
47
    "--start-date",
48
    dest="date_start",
49
    type=datetime.date.fromisoformat,
50
    help="Date of start in YYYY-MM-DD format",
51
)
52

53
parser.add_argument(
1✔
54
    "--end-date",
55
    dest="date_end",
56
    type=datetime.date.fromisoformat,
57
    help="Date of end in YYYY-MM-DD format",
58
)
59

60
parser.add_argument(
1✔
61
    "--ext",
62
    dest="extension",
63
    type=str,
64
    help="Format of input files for monthly variability (only used in combination with -y option and when -i path is a directory)",
65
    default="xlsx",
66
)
67

68
parser.add_argument(
1✔
69
    "-p",
70
    dest="parallel",
71
    default=False,
72
    const=True,
73
    nargs="?",
74
    type=bool,
75
    help="Whether or not the simulation uses parallel processing",
76
)
77

78

79
def main():
1✔
80
    args = vars(parser.parse_args())
1✔
81
    fnames = args["fname_path"]
1✔
82
    ofnames = args["ofname_path"]
1✔
83
    num_days = args["num_days"]
1✔
84
    # Define which input files should be considered and run.
85
    date_start = args["date_start"]
1✔
86
    date_end = args["date_end"]
1✔
87
    ext = args["extension"]
1✔
88
    parallel_processing = args["parallel"]
1✔
89

90
    years = args["years"]
1✔
91

92
    if num_days is None:
1✔
93
        if date_start is None:
1✔
94
            if date_end is not None:
1✔
95
                date_start = datetime.date(date_end.year, 1, 1)
1✔
96
                # logging.info
97
                print(
1✔
98
                    f"You did not provide a start date, this is chosen automatically for you: {date_start}"
99
                )
100

101
        else:
102
            if date_end is None:
1✔
103
                date_end = datetime.date(date_start.year, 12, 31)
1✔
104
                # logging.info
105
                print(
1✔
106
                    f"You did not provide an end date, this is chosen automatically for you: {date_end}"
107
                )
108

109
    month_files = False
1✔
110

111
    if years is not None:
1✔
112
        if date_start is not None or date_end is not None:
1✔
113
            raise ValueError(
1✔
114
                "You cannot use the option -y in combinaison with --date-start and/or --date-end"
115
            )
116
        else:
117
            date_start = datetime.date(years[0], 1, 1)
1✔
118
            date_end = datetime.date(years[-1], 12, 31)
1✔
119
        if len(years) == 1 and fnames is not None:
1✔
120
            # This special combination (option -y with only 1 year and option -i with a directory as parameter)
121
            # Triggers the special mode "one input file per month"
122
            if os.path.isdir(fnames[0]):
1✔
123
                dir_path = fnames[0]
1✔
124
                fnames = [
1✔
125
                    os.path.join(dir_path, f)
126
                    for f in os.listdir(fnames[0])
127
                    if f.endswith(ext)
128
                ]
129
                fnames.sort(key=lambda f: int("".join(filter(str.isdigit, f))))
1✔
130

131
                if len(fnames) == 12:
1✔
132
                    print(
1✔
133
                        "The following input files were found and will be used in this exact order for month inputs"
134
                    )
135
                    print("\n".join(fnames))
1✔
136
                    month_files = True
1✔
137
                    year = years[0]
1✔
138
                else:
139
                    raise ValueError(
1✔
140
                        f"You want to simulate a whole year, yet the folder {dir_path} only contains {len(fnames)} out of the 12 monthes required"
141
                    )
142
            else:
143
                print("You selected a single year but the input path is not a folder.")
×
144

145
    if ofnames is None:
1✔
146
        ofnames = [None]
1✔
147

148
    if fnames is None:
1✔
149
        print("Please provide path to input file with option -i, \n\n")
×
150
    else:
151
        if num_days is not None:
1✔
152
            if len(num_days) == 1:
1✔
153
                num_days = num_days * len(fnames)
1✔
154
            else:
155
                if len(num_days) != len(fnames):
×
156
                    raise ValueError(
×
157
                        "The number of profiles parameters  should match the number of input files provided"
158
                    )
159
        else:
160
            num_days = [None] * len(fnames)
1✔
161

162
        if month_files is False:
1✔
163
            if len(ofnames) == 1:
1✔
164
                ofnames = ofnames * len(fnames)
1✔
165
            elif len(fnames) != len(ofnames):
×
166
                raise ValueError(
×
167
                    f"The number of output file paths({len(ofnames)}) should match the number of input files paths ({len(fnames)})"
168
                )
169

170
            for i, fname in enumerate(fnames):
1✔
171
                run_usecase(
1✔
172
                    fname=fname,
173
                    ofname=ofnames[i],
174
                    num_days=num_days[i],
175
                    date_start=date_start,
176
                    date_end=date_end,
177
                    plot=True,
178
                    parallel=parallel_processing,
179
                )
180
        else:
181
            year_profile = []
1✔
182
            for i, fname in enumerate(fnames):
1✔
183
                month_start = datetime.date(year, i + 1, 1)
1✔
184
                month_end = datetime.date(
1✔
185
                    year, i + 1, pd.Period(month_start, freq="D").days_in_month
186
                )
187
                month_profiles = run_usecase(
1✔
188
                    fname=fname,
189
                    ofname=None,
190
                    num_days=num_days[i],
191
                    date_start=month_start,
192
                    date_end=month_end,
193
                    plot=False,
194
                    parallel=parallel_processing,
195
                )
196
                month_profiles = month_profiles.reshape(
1✔
197
                    1, 1440 * month_profiles.shape[0]
198
                ).squeeze()
199
                year_profile.append(month_profiles)
1✔
200

201
            # Create a dataFrame to save the year profile with timestamps every minutes
202
            series_frame = pd.DataFrame(
1✔
203
                np.hstack(year_profile),
204
                index=pd.date_range(
205
                    start=f"{year}-1-1", end=f"{year}-12-31 23:59", freq="min"
206
                ),
207
            )
208
            # Save to minute and hour resolution
209
            if len(ofnames) == 1:
1✔
210
                ofname = ofnames[0]
1✔
211
            else:
NEW
212
                ofname = None
×
213

214
            if ofname is None:
1✔
215
                ofname = os.path.abspath(os.path.curdir)
1✔
216

217
            if not os.path.exists(ofname):
1✔
NEW
218
                os.mkdir(ofname)
×
219

220
            series_frame.to_csv(
1✔
221
                os.path.join(ofname, "yearly_profile_min_resolution.csv")
222
            )
223
            resampled = pd.DataFrame()
1✔
224

225
            resampled["mean"] = series_frame.resample("h").mean()
1✔
226
            resampled["max"] = series_frame.resample("h").max()
1✔
227
            resampled["min"] = series_frame.resample("h").min()
1✔
228
            # TODO add more columns with other resampled functions (do this in Jupyter)
229
            resampled.to_csv(
1✔
230
                os.path.join(ofname, "yearly_profile_hourly_resolution.csv")
231
            )
232
            print(
1✔
233
                f"Results of the yearly RAMP simulation with seasonality are located in the folder {ofname}"
234
            )
235

236

237
if __name__ == "__main__":
1✔
238
    main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc