How to run daylight radiance simulation with HB Python/CLI packages with .hbjson file as input

Hi all,
In the recent version of HB-radiance, I noticed a .hbjson file generated after running the simulation.
My question is whether(and if yes, how) could one use the .hbjson file directly for daylight simulation in the CLI/Python environment.
A reference to an example/documentation would be appreciated!

Thanks in advance!

Hi @Fimano,

Check this post. Let me know if you have any questions.

2 Likes

Thanks for your response and sorry for my late comment.

I have a few specific questions about the annual simulation,
I would like to calculate the following values from a given .hbjson file: DA,cDA,sDA,UDI,ASE, and hourly illuminance across the grid.

Reading this post, one of the ways to do this, I think is to use the lbt-recipe (annual_daylight). I do this by running the following lines of code:

from honeybee.model import Model
from honeybee.room import Room
from honeybee.config import folders as hb_folders
from lbt_recipes.recipe import Recipe
def annual():
    wea = r"epws/USA_KY_London-Corbin-Magee.Field.724243_TMY3.epw"   
    
    # Create a model for simulation
    room = Room.from_box('simulated_room', 5, 10, 3)
    south_face = room[3]
    south_face.apertures_by_ratio(0.4, 0.01)
    model = Model('simulated_test_model', [room])
    model.properties.radiance.sensor_grids = \
        [room.properties.radiance.generate_sensor_grid(1, offset=0.8)]

    # pass the model to the recipe
    recipe = Recipe('annual_daylight')
    recipe.input_value_by_name('model', model)
    recipe.input_value_by_name('wea', wea)

    project_folder = recipe.run(settings='--workers 11', debug_folder='debug_folder')
    # radiation = recipe.output_value_by_name('cumulative-radiation', project_folder)
    # return radiation
annual()

This seems to be working, but when I want to calculate/view the results I don’t know which function to use, I see the “recipe.output_value_by_name” function but from the documentation, I do not know what are the valid inputs for it. can you please help me figure this out?
also if you know of example python programs like this somewhere else for similar purposes can you please refer me to it? (something like hydrashare?)

You can see the inputs here. E.g.,

results = recipe.output_value_by_name('results', project_folder)
udi = recipe.output_value_by_name('udi', project_folder)

DA, cDA, and UDI are calculated by default. If you want to change the thresholds for these, you can modify the defaults by changing the threshold input value.

You can use honeybee-radiance-postprocess for other metrics (and DA, cDA and UDI as well if you want to redo the calculation).

from honeybee_radiance_postprocess.results import Results
...
results_output = recipe.output_value_by_name('results', project_folder)
results = Results(results_output)
ase, hours_above, grids_info = results.annual_sunlight_exposure()
sda, grids_info = results.spatial_daylight_autonomy()

For hourly illuminance there is a method to get illuminance for a single point-in-time.

from ladybug.dt import DateTime
...
hoy = DateTime(3, 21, 12)
pit_values, grids_info = results.point_in_time(hoy)

But the use of this method probably depends on what you want exactly from “hourly illuminance across the grid”.

1 Like

This is a great reply @mikkel,
Thanks a lot.

by the “hourly luminance across the grid”, I mean the total illuminance in a full year.

Hi @Fimano,

If that is just the summed illuminance, then something like this should work.

import numpy as np
from honeybee_radiance_postprocess.util import filter_array
...
grids_info = results._filter_grids(grids_filter='*')
total_illuminance = []
for grid_info in grids_info:
    array = results._array_from_states(grid_info)
    array_total = array.sum(axis=1)
    # use the line below instead if you want to filter by the schedule you used when
    # instantiating the Results class
    # array_filter = np.apply_along_axis(filter_array, 1, array, mask=results.occ_mask)
    total_illuminance.append(array_total)
2 Likes

Dear @mikkel,
Thanks a lot for your response.

There two other question I would like to ask,
1- I want to manually create .hbjson files, or manipulate them, by defining and changing different objects within the model.
for this, I need to efficiently visualize the 3D hbjson while working on it.
Can you suggest a function capable of doing so?

2- I have setup the following code, but the results are all zero. the .hbjson I used is from a model I created in grasshopper where the results are not zero. Am I doing some part of it wrongly? I have attached the file I use.

from honeybee.model import Model
from honeybee.room import Room
from honeybee.config import folders as hb_folders
from lbt_recipes.recipe import Recipe
from honeybee_radiance_postprocess.results import Results
import pathlib as PL
import honeybee.model as hb_model

#def annual():
# weather file
wea = "BEL_BRU_Brussels.Natl.AP.064510_TMYx.2004-2018.wea
[ReturnedZero.zip|attachment](upload://ilf6qaBOPdzTXQ9A6QAMuptbuZC.zip) (59.4 KB)
"   

# Create a model for simulation
model= hb_model.Model.from_hbjson("unnamed_e7336249.hbjson")

# pass the model to the recipe
recipe = Recipe('annual-irradiance')
recipe.input_value_by_name('model', model)
recipe.input_value_by_name('wea', wea)

#Run the simulation
project_folder = recipe.run(debug_folder='debug_folder') #Path to the project folder containing the recipe results.
results_output = recipe.output_value_by_name('results', project_folder)
results = Results(PL.Path(results_output[0]).parent.resolve())

# annual metrics
ase, hours_above, grid_info = results.annual_sunlight_exposure() #ASE
sda, grids_info = results.spatial_daylight_autonomy() #SDA
udi, grids_info = results.useful_daylight_illuminance() #UDI
udi_lower, grids_info = results.useful_daylight_illuminance_lower() #UDI_lower
udi_upper, grids_info = results.useful_daylight_illuminance_upper() #UDI_upper

ReturnedZero.zip (59.4 KB)

Thank you,
F

The annual-irradiance recipe doesn’t have any outputs for useful_daylight_illuminance or any of those other outputs. Did you mean to run annual-daylight instead?

You can use honeybee-vtk. Look at this example for showing a model in a web browser. Be aware that you have to use Python 3.7.x.

1 Like

@mikkel, thank you for your suggestion on honeybee-vtk, it is indeed a very good solution for my problem!

@chris, you are right, I should run the annual_daylight recipe. However, even after this revision of my code, I get the same output, an array of zeros for all the grid nodes.

Are you able to share the results folder from the simulation?

Sure!
You can download it here.
Sorry the size was more than the 1.4MB limit, I had to upload it elsewhere!

The log file gives an error. It can’t find the prepare-multiphase CLI command in honeybee-radiance. Perhaps the version of honeybee-radiance used is not updated.

I did run the recipe with your model though, and it also shows zero arrays, however, it seems like there are no apertures in the model.

1 Like

Hi @mikkel,
Thanks for your response.
I updated the python libraries, and repeated the experiment, by creating a simple box in rhino, and performing the annual simulation, which went well and the results are as expected.
I use the output .hbjson to repeat the simulation in the Python environment, and the following problems happen:

1- The results are again all zeros.
2- Close to your observation, a very crucial property of my model, the transmittance of the window, does not exist in the .hbjson, I cannot find it by searching the file here.

I uploaded the simulation folder here and the GH pipeline is the following, I could not send the definition because of a problem I face for saving Rhino/GH files on my machine currently.

Hi @Fimano,

If it works in Grasshopper you likely have an older version of annual-daylight running in Grasshopper.

I found the issue in honeybee-radiance-postprocess. If you create the glazing as an Aperture instead of Face it should work, however, with the latest version of honeybee-radiance-postprocess it works with a Face as well. Can yo try to update honeybee-radiance-postprocess / lbt-recipes and run it again?