Create EPW files for arbitrary dates potentially spanning multiple years

Hi all.

I’m creating EPW files from real weather data.

I’ve been successfully creating files for one year periods using Ladybug. It came in pretty handy, so thanks for that already.

Now I’d like to create files with arbitrary bounds, potentially spanning several years.

This should be possible with E+:

I’m wondering if Ladybug allows this.

I saw there’s a years property (plural) in EPW but I couldn’t find where it used.

I also saw that years 2016 and 2017 are hardcoded in Date and in the resulting epw file.

Is it possible to generate files this those bounds:

  • 1/ 2012/06/22 -> 2012/09/17 (less than a year)
  • 2/ 2012/06/22 -> 2013/01/18 (less than a year, spanning multiple years)
  • 3/ 2012/06/22 -> 2013/09/17 (more than a year)


We want to calibrate models with real measured and weather data, so ideally I’d like to have the real dates so that the weeks in the simulation match the real weeks.


I’ve been digging a bit further and I think I found answers already.

I read (can’t find the source anymore) that the year in the timestamps is not used so it doesn’t matter that 2016 and 2017 are hardcoded. My point is to ensure simulation calendars will match actual weeks, but there must be another mechanism for this, although I’m confused whether or not this should be addresses by the weather file.

It seems LadyBug can generate files spanning across two years with a max length of one year. So I can simulate a complete heating season (say October to March in northern hemisphere), but not two successive years. While this might be a limitation, it might not be that bad in our case.

However, I’m building the EPW files from real data using from_missing_values which creates Jan-01 -> Dec-31 periods by calling AnalysisPeriod with only is_leap_year as argument. I guess I’ll have to adapt from_missing_values to create arbitrary periods (with the limitation discussed above).

Yes, it’s possible with E+ but it’s intentionally not possible with Ladybug Tools. The value that Ladybug Tools gains by dealing with timeseries data in units of a year (or smaller) is just too great for us to change the Ladybug Tools data structures. EnergyPlus can do it because it’s an engine and it’s primarily concerned with running simulations. It doesn’t have to worry as much about the aftermath of how you analyze, visualize, manage, and usefully interpret the simulation results. But it’s just not worth the sacrifice of analysis capabilities we would have to make in Ladybug Tools to support something like this. We can support leap years (that’s why you have both 2016 and 2017 hard-coded there) but Ladybug Tools data is always in units of a year or smaller.

From another perspective, the ability to simulate a multi-year EPW is also not all that useful to design decisions. I know that the EnergyPlus developers added it primary for validation/calibration purposes and I know this is what you are doing here. But, 99% of the simulations that people run with Ladybug Tools don’t need the results to perfectly match real-world measurements for the first week of January.

In fact, if someone were running a multi-year simulation to inform design decisions, it’s probably more useful to generate a few EPWs (one for each year) and then run a few EnergyPlus simulations for each of the years. At least with that approach, you can run the EnergyPlus simulations in parallel, which could save a lot of time. And, at the end of the simulation, you get results in chunks of a year, which are much easier to manage, analyze, and visualize.

For these few cases where you really need those first few days of the simulation to match reality within a few percent, I don’t think it’s that much to ask you to write your own script that stiches together the annual EPWs that you export from Ladybug. Hopefully, the Ladybug Tools SDK already gets you 90% of the way towards making your own EPWs and writing the “stitching script” to run at the end is not that much of an extra effort. FYI, you can still overwrite the years of the exported EPW by setting the values of the years data collection on the EPW object . So this should get you those starting EPWs in the format you want and it really is a matter of just stitching files together.

Hi Chris. Thank you very much for this answer.

I understand that design choice. I’ve been discussing this with our engineers and in fact, this might be more of a theoretical issue. We might have to deal with multi-year simulations but then, as you say, it’s nice already if Ladybug gets us close and we only have a few steps remaining to stitch the files together.

Moving on with Ladybug, I’ve been trying to extend my “one year weather data -> EPW file” tool to manage shorter periods and I’m almost done except I just stumbled upon an exception which seem to mean explicitly that only full year periods can be exported to EPW files.

Can you please clarify whether Ladybug can export files shorter than a full year?

I’ve been overriding EPW.from_missing_values to allow it to create shorter periods (still with full days):

def from_missing_values(
    st_month=1, st_day=1, end_month=12, end_day=31,
    timestep=1, is_leap_year=False
    # Initialize the class with all data missing
    epw_obj = cls(None)
    epw_obj._is_leap_year = is_leap_year
    epw_obj._location = Location()

    # create an analysis period
    analysis_period = AnalysisPeriod(
        st_month=st_month, st_day=st_day,
        end_month=end_month, end_day=end_day,
        timestep=timestep, is_leap_year=is_leap_year

Then I got this length error exception while writing the EPW file.

I managed to override to_file_string to reuse the analysis period created in from_missing_values rather than creating an annual analysis period here:

After this, I could output an EPW file, but there is still at least one thing wrong with the generated file as DATA_PERIODS is hard-coded as well:

(New user, can only add two links… Perhaps the forum could accept a regex whitelist including github links.)

data_str = 'DATA PERIODS,1,1,Data,Sunday, 1/ 1,12/31\n'
return [loc_str, des_str, week_str, grnd_st, leap_str, c_str1, c_str2, data_str]

I could also override headers property, or, easier and dirtier, patch its output from the to_file_string method I’m already overriding, but at this point I’m wondering if I’m on the right track.

Looks like I found at least two occurrences of that explicitly don’t support periods shorter than a full year.

Is this really a feature that is meant to be supported?


Another thing that seems wrong is the first value being pushed to the end position:

# if the first value is at 1AM, move first item to end position

I find it strange to do even on full years because it may introduce a step while the data may be meant to be more or less continuous. For instance, midnight air temperature on two successive new year’s eve may be very different so this move may send a -5°C just after a -5°C, introducing a 10°C step. This must have been discussed already, and I don’t mean to reopen the discussion. I guess the effect of the change has been deemed minimal and this is better than having an hour shift all along.

Anyway, this seems even more wrong if the year is incomplete, as the last value may match the next to last even less. But again, perhaps this is insignificant.

My initial point still stands. From what I gathered, the case of an analysis period shorter than a full year is not supported.

I could share the modifications I made to get it to work, but it wouldn’t be a readily mergeable PR as it breaks a few things in