22from ast import literal_eval
33from collections import defaultdict
44import copy
5+ from ctypes import c_int32 , c_char_p
56import hashlib
67import itertools
78import pickle
1718
1819from . import __version__
1920from .statepointmodel import StatePointModel
20- from .plot_colors import random_rgb , reset_seed
21+ from .plot_colors import random_rgb
2122
2223ID , NAME , COLOR , COLORLABEL , MASK , HIGHLIGHT = range (6 )
2324
@@ -170,9 +171,6 @@ def __init__(self, use_settings_pkl, model_path):
170171 self .appliedScores = ()
171172 self .appliedNuclides = ()
172173
173- # reset random number seed for consistent
174- # coloring when reloading a model
175- reset_seed ()
176174 self .previousViews = []
177175 self .subsequentViews = []
178176
@@ -333,11 +331,11 @@ def makePlot(self):
333331 # generate colors if not present
334332 for cell_id , cell in cv .cells .items ():
335333 if cell .color is None :
336- cell . color = random_rgb ()
334+ cv . cells . set_color ( cell_id , random_rgb () )
337335
338336 for mat_id , mat in cv .materials .items ():
339337 if mat .color is None :
340- mat . color = random_rgb ()
338+ cv . material . set_color ( mat_id , random_rgb () )
341339
342340 # construct image data
343341 domain [_OVERLAP ] = DomainView (_OVERLAP , "Overlap" , cv .overlap_color )
@@ -999,8 +997,9 @@ def __init__(self, origin=(0, 0, 0), width=10, height=10, restore_view=None,
999997 self .materials = restore_view .materials
1000998 self .selectedTally = restore_view .selectedTally
1001999 else :
1002- self .cells = self .getDomains ('cell' )
1003- self .materials = self .getDomains ('material' )
1000+ rng = np .random .RandomState (10 )
1001+ self .cells = self .getDomains ('cell' , rng )
1002+ self .materials = self .getDomains ('material' , rng )
10041003 self .selectedTally = None
10051004
10061005 def __getattr__ (self , name ):
@@ -1025,7 +1024,7 @@ def __hash__(self):
10251024 return hash (self .__dict__ .__str__ () + self .__str__ ())
10261025
10271026 @staticmethod
1028- def getDomains (domain_type ):
1027+ def getDomains (domain_type , rng ):
10291028 """ Return dictionary of domain settings.
10301029
10311030 Retrieve cell or material ID numbers and names from .xml files
@@ -1046,26 +1045,39 @@ def getDomains(domain_type):
10461045 raise ValueError ("Domain type, {}, requested is neither "
10471046 "'cell' nor 'material'." .format (domain_type ))
10481047
1049- lib_domain = None
1048+ # Get number of domains, functions for ID/name, and dictionary for defaults
10501049 if domain_type == 'cell' :
1051- lib_domain = openmc .lib .cells
1050+ num_domain = len (openmc .lib .cells )
1051+ get_id = openmc .lib .core ._dll .openmc_cell_get_id
1052+ get_name = openmc .lib .core ._dll .openmc_cell_get_name
10521053 elif domain_type == 'material' :
1053- lib_domain = openmc .lib .materials
1054-
1055- domains = {}
1056- for domain , domain_obj in lib_domain .items ():
1057- name = domain_obj .name
1058- domains [domain ] = DomainView (domain , name , random_rgb ())
1054+ num_domain = len (openmc .lib .materials )
1055+ get_id = openmc .lib .core ._dll .openmc_material_get_id
1056+ get_name = openmc .lib .core ._dll .openmc_material_get_name
1057+
1058+ # Sample default colors for each domain
1059+ colors = rng .randint (256 , size = (num_domain , 3 ))
1060+
1061+ domain_id_c = c_int32 ()
1062+ name_c = c_char_p ()
1063+ defaults = {}
1064+ for i , color in enumerate (colors ):
1065+ # Get ID and name for each domain
1066+ get_id (i , domain_id_c )
1067+ get_name (i , name_c )
1068+ domain_id = domain_id_c .value
1069+ name = name_c .value .decode ()
1070+
1071+ # Create default domain view for this domain
1072+ defaults [domain_id ] = DomainView (domain_id , name , color )
10591073
10601074 # always add void to a material domain at the end
10611075 if domain_type == 'material' :
10621076 void_id = _VOID_REGION
1063- domains [void_id ] = DomainView (void_id , "VOID" ,
1064- (255 , 255 , 255 ),
1065- False ,
1066- False )
1077+ defaults [void_id ] = DomainView (void_id , "VOID" , (255 , 255 , 255 ),
1078+ False , False )
10671079
1068- return domains
1080+ return DomainViewDict ( defaults )
10691081
10701082 def adopt_plotbase (self , view ):
10711083 """
@@ -1085,6 +1097,50 @@ def adopt_plotbase(self, view):
10851097 self .basis = view .basis
10861098
10871099
1100+ class DomainViewDict (dict ):
1101+ """Dictionary of domain ID to DomainView objects with shared defaults
1102+
1103+ When the active/current view changes in the plotter, this dictionary gets
1104+ deepcopied. To avoid the dictionary being huge for models with lots of
1105+ cells/materials, defaults are stored separately and the key/value pairs in
1106+ this dictionary represent modifications to the default pairs. When an item
1107+ is looked up, if there is no locally modified version we pull the value from
1108+ the defaults dictionary.
1109+
1110+ """
1111+ def __init__ (self , defaults : dict ):
1112+ self .defaults = defaults
1113+
1114+ def __getitem__ (self , key ) -> DomainView :
1115+ if key in self :
1116+ return super ().__getitem__ (key )
1117+ else :
1118+ # If key is not present, pull it from the defaults
1119+ return self .defaults [key ]
1120+
1121+ def __deepcopy__ (self , memo ):
1122+ cls = self .__class__
1123+ obj = cls .__new__ (cls )
1124+ memo [id (self )] = obj
1125+ for key , value in self .items ():
1126+ obj [key ] = copy .deepcopy (value )
1127+ # Shallow copy the defaults dictionary
1128+ obj .defaults = self .defaults
1129+ return obj
1130+
1131+ def set_color (self , key : int , color ):
1132+ domain = self [key ]
1133+ self [key ] = DomainView (domain .id , domain .name , color , domain .masked , domain .highlight )
1134+
1135+ def set_masked (self , key : int , masked : bool ):
1136+ domain = self [key ]
1137+ self [key ] = DomainView (domain .id , domain .name , domain .color , masked , domain .highlight )
1138+
1139+ def set_highlight (self , key : int , highlight : bool ):
1140+ domain = self [key ]
1141+ self [key ] = DomainView (domain .id , domain .name , domain .color , domain .masked , highlight )
1142+
1143+
10881144class DomainView :
10891145 """Represents view settings for OpenMC cell or material.
10901146
0 commit comments