def extract_cell_field_data(self, cell_shell_optimization=False): """ Extracts basic information about cell field :return: """ cell_type_array = vtk.vtkIntArray() cell_type_array.SetName("celltype") cell_type_array_int_addr = extract_address_int_from_vtk_object( cell_type_array) # Also get the CellId cell_id = vtk.vtkLongArray() cell_id.SetName("cellid") cell_id_int_addr = extract_address_int_from_vtk_object(cell_id) used_cell_types_list = self.field_extractor.fillCellFieldData3D( cell_type_array_int_addr, cell_id_int_addr, cell_shell_optimization) ret_val = { 'cell_type_array': cell_type_array, 'cell_id_array': cell_id, 'used_cell_types': used_cell_types_list } return ret_val
def _render_trial(self, trial_idx): """ Main routine to perform rendering for a trial from batch run :param trial_idx: index of trial :return: None """ print('CallableCC3DRenderer rendering trial {}'.format(trial_idx)) self.load_trial_results(trial_idx) if self.cml_results_reader is None: print('No results loaded.') return ss_dir = self.scm.get_screenshot_dir_name() if not os.path.isdir(ss_dir): os.mkdir(ss_dir) file_list = self.cml_results_reader.ldsFileList for file_number, file_name in enumerate(file_list): self.cml_results_reader.read_simulation_data_non_blocking(file_number) sim_data_int_addr = extract_address_int_from_vtk_object(self.cml_results_reader.simulationData) mcs = self.cml_results_reader.extract_mcs_number_from_file_name(file_name) self.gd.field_extractor.setSimulationData(sim_data_int_addr) gd_manipulator = self._get_rendering_manipulator(trial_idx, mcs) if gd_manipulator is not None: gd_manipulator(self.gd) sc_manipulator = self._get_screenshot_manipulator(trial_idx, mcs) if sc_manipulator is not None: sc_manipulator(self.scm) print('...{}'.format(mcs)) self.output_screenshots(mcs)
def get_results_min_max(self, trial_idx): """ Gets minimum and maximum over all simulation time for all available results :return: {dict} range per available field """ min_max_dict = dict() self.load_trial_results(trial_idx) if self.cml_results_reader is None: print('No results loaded for trial {}.'.format(trial_idx)) return None file_list = self.cml_results_reader.ldsFileList for file_number, file_name in enumerate(file_list): self.cml_results_reader.read_simulation_data_non_blocking(file_number) sim_data_int_addr = extract_address_int_from_vtk_object(self.cml_results_reader.simulationData) self.gd.field_extractor.setSimulationData(sim_data_int_addr) for field_name, screenshot_data in self.scm.screenshotDataDict.items(): min_max = self._get_field_min_max(screenshot_data) if min_max is not None: if field_name not in min_max_dict.keys(): min_max_dict[field_name] = min_max else: if min_max[0] < min_max_dict[field_name][0]: min_max_dict[field_name][0] = min_max[0] if min_max[1] > min_max_dict[field_name][1]: min_max_dict[field_name][1] = min_max[1] return min_max_dict
def read_simulation_data_non_blocking(self, file_number: int) -> bool: """ reads content of the serialized file :param file_number: {int} :return: {bool} flag whether read was successful or not """ # this flag is used to prevent calling draw function self.newFileBeingLoaded = True # when new data is read from hard drive if file_number >= len(self.ldsFileList): return False fileName = self.ldsFileList[file_number] self.simulationDataReader = vtk.vtkStructuredPointsReader() self.currentFileName = os.path.join(self.ldsDir, fileName) print('self.currentFileName=', self.currentFileName) extracted_mcs = self.extract_mcs_number_from_file_name( file_name=self.currentFileName) if extracted_mcs < 0: extracted_mcs = file_number self.simulationDataReader.SetFileName(self.currentFileName) # print "path= ", os.path.join(self.ldsDir,fileName) data_reader_int_addr = extract_address_int_from_vtk_object( vtkObj=self.simulationDataReader) # swig wrapper on top of vtkStructuredPointsReader.Update() - releases GIL, # hence can be used in multithreaded program that does not block GUI self.__ui.fieldExtractor.readVtkStructuredPointsData( data_reader_int_addr) # # # self.simulationDataReader.Update() # does not erlease GIL - VTK ISSUE - # cannot be used in multithreaded program - blocks GUI self.simulationData = self.simulationDataReader.GetOutput() self.fieldDimPrevious = self.fieldDim # self.fieldDimPrevious=CompuCell.Dim3D() dim_from_vtk = self.simulationData.GetDimensions() self.fieldDim = CompuCell.Dim3D(dim_from_vtk[0], dim_from_vtk[1], dim_from_vtk[2]) self.currentStep = extracted_mcs # # # self.currentStep = self.frequency * _i # this is how we set CMS for CML reading before self.setCurrentStep(self.currentStep) self.newFileBeingLoaded = False return True
def extract_cell_field_data(self): """ Extracts basic information about cell field :return: """ cellType = vtk.vtkIntArray() cellType.SetName("celltype") cellTypeIntAddr = extract_address_int_from_vtk_object(cellType) # Also get the CellId cellId = vtk.vtkLongArray() cellId.SetName("cellid") cellIdIntAddr = extract_address_int_from_vtk_object(cellId) usedCellTypesList = self.field_extractor.fillCellFieldData3D(cellTypeIntAddr, cellIdIntAddr) ret_val = { 'cell_type_array': cellType, 'cell_id_array': cellId, 'used_cell_types': usedCellTypesList } return ret_val
def read_simulation_data(self, file_number: int) -> (bool, int): """ reads content of the serialized file :param file_number: {int} :return: {(bool, int)} flag whether read was successful or not, extracted mcs """ # By this point, either field extractor is set, or parent has cml field extractor if self.field_extractor is None: assert hasattr(self._parent, 'fieldExtractor') or hasattr(self._parent, 'field_extractor') if hasattr(self._parent, 'field_extractor'): _a = 'field_extractor' else: _a = 'fieldExtractor' self.field_extractor = getattr(self._parent, _a) assert isinstance(self.field_extractor, PlayerPython.FieldExtractorCML) # when new data is read from hard drive if file_number >= len(self.ldsFileList): return False, -1 fileName = self.ldsFileList[file_number] self.simulationDataReader = vtk.vtkStructuredPointsReader() self.currentFileName = os.path.join(self.ldsDir, fileName) print('self.currentFileName=', self.currentFileName) extracted_mcs = self.extract_mcs_number_from_file_name(file_name=self.currentFileName) if extracted_mcs < 0: extracted_mcs = file_number self.simulationDataReader.SetFileName(self.currentFileName) data_reader_int_addr = extract_address_int_from_vtk_object(vtkObj=self.simulationDataReader) # swig wrapper on top of vtkStructuredPointsReader.Update() - releases GIL, # hence can be used in multithreaded program that does not block GUI self.field_extractor.readVtkStructuredPointsData(data_reader_int_addr) # # # self.simulationDataReader.Update() # does not erlease GIL - VTK ISSUE - # limited use in multithreaded program - blocks GUI self.simulationData = self.simulationDataReader.GetOutput() self.fieldDimPrevious = self.fieldDim dim_from_vtk = self.simulationData.GetDimensions() self.fieldDim = CompuCell.Dim3D(dim_from_vtk[0], dim_from_vtk[1], dim_from_vtk[2]) return True, extracted_mcs
def _get_field_min_max(self, screenshot_data): """ Gets minimum and maximum of field described in screenshot data; returns None if unavailable :param screenshot_data: screenshot data for a field :return: minimum and maximum """ field_name = screenshot_data.plotData[0] fieldType = screenshot_data.plotData[1] plane = screenshot_data.projection planePos = screenshot_data.projectionPosition con_array = vtk.vtkDoubleArray() con_array.SetName("concentration") con_array_int_addr = extract_address_int_from_vtk_object(vtkObj=con_array) field_type = fieldType.lower() if field_type == 'confield': fill_successful = self.gd.field_extractor.fillConFieldData2D(con_array_int_addr, field_name, plane, planePos) elif field_type == 'scalarfield': fill_successful = self.gd.field_extractor.fillScalarFieldData2D(con_array_int_addr, field_name, plane, planePos) elif field_type == 'scalarfieldcelllevel': fill_successful = self.gd.field_extractor.fillScalarFieldCellLevelData2D(con_array_int_addr, field_name, plane, planePos) else: return None if not fill_successful: return None con_array_range = con_array.GetRange() min_max = [con_array_range[0], con_array_range[1]] return min_max
def render_step(self, mcs: int) -> bool: """ Executes screenshot rendering for a simulation step :param mcs: simulation step :return: {bool} True if rendering succeeded """ if mcs not in self.available_mcs: print(f'Step {mcs} not available') return False file_number = self.available_mcs.index(mcs) self.cml_results_reader.read_simulation_data(file_number) sim_data_int_addr = extract_address_int_from_vtk_object( self.cml_results_reader.simulationData) self.generic_drawer.field_extractor.setSimulationData( sim_data_int_addr) if self.render_manipulator is not None: self.render_manipulator(self.screenshot_manager, self.generic_drawer, mcs) return True
def init_vector_field_actors(self, actor_specs, drawing_params=None): """ initializes vector field actors for cartesian lattice :param actor_specs: {ActorSpecs} :param drawing_params: {DrawingParameters} :return: None """ actors_dict = actor_specs.actors_dict field_dim = self.currentDrawingParameters.bsd.fieldDim field_name = drawing_params.fieldName field_type = drawing_params.fieldType.lower() scene_metadata = drawing_params.screenshot_data.metadata mdata = MetadataHandler(mdata=scene_metadata) dim = [field_dim.x, field_dim.y, field_dim.z] vector_grid = vtk.vtkUnstructuredGrid() points = vtk.vtkPoints() vectors = vtk.vtkFloatArray() vectors.SetNumberOfComponents(3) vectors.SetName("visVectors") points_int_addr = extract_address_int_from_vtk_object(vtkObj=points) vectors_int_addr = extract_address_int_from_vtk_object(vtkObj=vectors) fill_successful = False hex_flag = False if self.is_lattice_hex(drawing_params=drawing_params): hex_flag = True if field_type == 'vectorfield': fill_successful = self.field_extractor.fillVectorFieldData2DHex( points_int_addr, vectors_int_addr, field_name, self.currentDrawingParameters.plane, self.currentDrawingParameters.planePos) elif field_type == 'vectorfieldcelllevel': fill_successful = self.field_extractor.fillVectorFieldCellLevelData2DHex( points_int_addr, vectors_int_addr, field_name, self.currentDrawingParameters.plane, self.currentDrawingParameters.planePos) else: if field_type == 'vectorfield': fill_successful = self.field_extractor.fillVectorFieldData2D( points_int_addr, vectors_int_addr, field_name, self.currentDrawingParameters.plane, self.currentDrawingParameters.planePos) elif field_type == 'vectorfieldcelllevel': fill_successful = self.field_extractor.fillVectorFieldCellLevelData2D( points_int_addr, vectors_int_addr, field_name, self.currentDrawingParameters.plane, self.currentDrawingParameters.planePos) if not fill_successful: return vector_grid.SetPoints(points) vector_grid.GetPointData().SetVectors(vectors) cone = vtk.vtkConeSource() cone.SetResolution(5) cone.SetHeight(2) cone.SetRadius(0.5) # cone.SetRadius(4) range_array = vectors.GetRange(-1) min_magnitude = range_array[0] max_magnitude = range_array[1] min_max_dict = self.get_min_max_metadata(scene_metadata=scene_metadata, field_name=field_name) min_range_fixed = min_max_dict['MinRangeFixed'] max_range_fixed = min_max_dict['MaxRangeFixed'] min_range = min_max_dict['MinRange'] max_range = min_max_dict['MaxRange'] # Note! should really avoid doing a getSetting with each step to speed up the rendering; # only update when changed in Prefs if min_range_fixed: min_magnitude = min_range if max_range_fixed: max_magnitude = max_range glyphs = vtk.vtkGlyph3D() if VTK_MAJOR_VERSION >= 6: glyphs.SetInputData(vector_grid) else: glyphs.SetInput(vector_grid) glyphs.SetSourceConnection(cone.GetOutputPort()) # glyphs.SetScaleModeToScaleByVector() # glyphs.SetColorModeToColorByVector() # scaling arrows here ArrowLength indicates scaling factor not actual length # glyphs.SetScaleFactor(Configuration.getSetting("ArrowLength")) vector_field_actor = actors_dict['vector_field_actor'] # scaling factor for an arrow - ArrowLength indicates scaling factor not actual length arrowScalingFactor = mdata.get('ArrowLength', default=1.0) if mdata.get('FixedArrowColorOn', default=False): glyphs.SetScaleModeToScaleByVector() dataScalingFactor = max(abs(min_magnitude), abs(max_magnitude)) if dataScalingFactor == 0.0: # in this case we are plotting 0 vectors and in this case data scaling factor will be set to 1 dataScalingFactor = 1.0 glyphs.SetScaleFactor(arrowScalingFactor / dataScalingFactor) # coloring arrows arrow_color = to_vtk_rgb(mdata.get('ArrowColor', data_type='color')) vector_field_actor.GetProperty().SetColor(arrow_color) else: glyphs.SetColorModeToColorByVector() glyphs.SetScaleFactor(arrowScalingFactor) self.glyphsMapper.SetInputConnection(glyphs.GetOutputPort()) self.glyphsMapper.SetLookupTable(self.scalarLUT) self.glyphsMapper.SetScalarRange([min_magnitude, max_magnitude]) vector_field_actor.SetMapper(self.glyphsMapper) self.init_min_max_actor( min_max_actor=actors_dict['min_max_text_actor'], range_array=range_array) if hex_flag: vector_field_actor.SetScale(self.xScaleHex, self.yScaleHex, self.zScaleHex)
def init_concentration_field_actors(self, actor_specs, drawing_params=None): """ initializes concentration field actors :param actor_specs: :param drawing_params: :return: None """ actors_dict = actor_specs.actors_dict field_dim = self.currentDrawingParameters.bsd.fieldDim # dim_order = self.dimOrder(self.currentDrawingParameters.plane) # dim = self.planeMapper(dim_order, (field_dim.x, field_dim.y, field_dim.z))# [fieldDim.x, fieldDim.y, fieldDim.z] dim = [field_dim.x, field_dim.y, field_dim.z] field_name = drawing_params.fieldName scene_metadata = drawing_params.screenshot_data.metadata mdata = MetadataHandler(mdata=scene_metadata) try: isovalues = mdata.get('ScalarIsoValues', default=[]) isovalues = list([float(x) for x in isovalues]) except: print('Could not process isovalue list ') isovalues = [] try: numIsos = mdata.get('NumberOfContourLines', default=3) except: print('could not process NumberOfContourLines setting') numIsos = 0 hex_flag = False lattice_type_str = self.get_lattice_type_str() if lattice_type_str.lower() == 'hexagonal': hex_flag = True types_invisible = PlayerPython.vectorint() for type_label in drawing_params.screenshot_data.invisible_types: types_invisible.append(int(type_label)) # self.isovalStr = Configuration.getSetting("ScalarIsoValues", field_name) # if type(self.isovalStr) == QVariant: # self.isovalStr = str(self.isovalStr.toString()) # else: # self.isovalStr = str(self.isovalStr) con_array = vtk.vtkDoubleArray() con_array.SetName("concentration") con_array_int_addr = extract_address_int_from_vtk_object( vtkObj=con_array) cell_type_con = vtk.vtkIntArray() cell_type_con.SetName("concelltype") cell_type_con_int_addr = extract_address_int_from_vtk_object( vtkObj=cell_type_con) field_type = drawing_params.fieldType.lower() if field_type == 'confield': fill_successful = self.field_extractor.fillConFieldData3D( con_array_int_addr, cell_type_con_int_addr, field_name, types_invisible) elif field_type == 'scalarfield': fill_successful = self.field_extractor.fillScalarFieldData3D( con_array_int_addr, cell_type_con_int_addr, field_name, types_invisible) elif field_type == 'scalarfieldcelllevel': fill_successful = self.field_extractor.fillScalarFieldCellLevelData3D( con_array_int_addr, cell_type_con_int_addr, field_name, types_invisible) if not fill_successful: return range_array = con_array.GetRange() min_con = range_array[0] max_con = range_array[1] field_max = range_array[1] # print MODULENAME, ' initScalarFieldDataActors(): min,maxCon=',self.minCon,self.maxCon min_max_dict = self.get_min_max_metadata(scene_metadata=scene_metadata, field_name=field_name) min_range_fixed = min_max_dict['MinRangeFixed'] max_range_fixed = min_max_dict['MaxRangeFixed'] min_range = min_max_dict['MinRange'] max_range = min_max_dict['MaxRange'] # Note! should really avoid doing a getSetting with each step to speed up the rendering; # only update when changed in Prefs if min_range_fixed: min_con = min_range if max_range_fixed: max_con = max_range uGrid = vtk.vtkStructuredPoints() uGrid.SetDimensions( dim[0] + 2, dim[1] + 2, dim[2] + 2 ) # only add 2 if we're filling in an extra boundary (rf. FieldExtractor.cpp) # uGrid.SetDimensions(self.dim[0],self.dim[1],self.dim[2]) # uGrid.GetPointData().SetScalars(self.cellTypeCon) # cellType scalar field uGrid.GetPointData().SetScalars(con_array) # uGrid.GetPointData().AddArray(self.conArray) # additional scalar field voi = vtk.vtkExtractVOI() ## voi.SetInputConnection(uGrid.GetOutputPort()) # voi.SetInput(uGrid.GetOutput()) if VTK_MAJOR_VERSION >= 6: voi.SetInputData(uGrid) else: voi.SetInput(uGrid) voi.SetVOI(1, dim[0] - 1, 1, dim[1] - 1, 1, dim[2] - 1) # crop out the artificial boundary layer that we created isoContour = vtk.vtkContourFilter() # skinExtractorColor = vtk.vtkDiscreteMarchingCubes() # skinExtractorColor = vtk.vtkMarchingCubes() # isoContour.SetInput(uGrid) isoContour.SetInputConnection(voi.GetOutputPort()) isoNum = 0 for isoNum, isoVal in enumerate(isovalues): try: isoContour.SetValue(isoNum, isoVal) except: print( MODULENAME, ' initScalarFieldDataActors(): cannot convert to float: ', self.isovalStr[idx]) if isoNum > 0: isoNum += 1 delIso = (max_con - min_con) / (numIsos + 1 ) # exclude the min,max for isovalues isoVal = min_con + delIso for idx in range(numIsos): isoContour.SetValue(isoNum, isoVal) isoNum += 1 isoVal += delIso # UGLY hack to NOT display anything since our attempt to RemoveActor (below) don't seem to work if isoNum == 0: isoVal = field_max + 1.0 # go just outside valid range isoContour.SetValue(isoNum, isoVal) # concLut = vtk.vtkLookupTable() # concLut.SetTableRange(conc_vol.GetScalarRange()) # concLut.SetTableRange([self.minCon,self.maxCon]) self.scalarLUT.SetTableRange([min_con, max_con]) # concLut.SetNumberOfColors(256) # concLut.Build() # concLut.SetTableValue(39,0,0,0,0) # skinColorMapper = vtk.vtkPolyDataMapper() # skinColorMapper.SetInputConnection(skinNormals.GetOutputPort()) # self.conMapper.SetInputConnection(skinExtractorColor.GetOutputPort()) self.conMapper.SetInputConnection(isoContour.GetOutputPort()) self.conMapper.ScalarVisibilityOn() self.conMapper.SetLookupTable(self.scalarLUT) # # # print " this is conc_vol.GetScalarRange()=",conc_vol.GetScalarRange() # self.conMapper.SetScalarRange(conc_vol.GetScalarRange()) self.conMapper.SetScalarRange([min_con, max_con]) # self.conMapper.SetScalarRange(0,1500) # rwh - what does this do? # self.conMapper.SetScalarModeToUsePointFieldData() # self.conMapper.ColorByArrayComponent("concentration",0) # print MODULENAME,"initScalarFieldDataActors(): Plotting 3D Scalar field" # self.conMapper = vtk.vtkPolyDataMapper() # self.conActor = vtk.vtkActor() concentration_actor = actors_dict['concentration_actor'] concentration_actor.SetMapper(self.conMapper) self.init_min_max_actor( min_max_actor=actors_dict['min_max_text_actor'], range_array=range_array) if hex_flag: concentration_actor.SetScale(self.xScaleHex, self.yScaleHex, self.zScaleHex) if actor_specs.metadata is None: actor_specs.metadata = {'mapper': self.conMapper} else: actor_specs.metadata['mapper'] = self.conMapper if mdata.get('LegendEnable', default=False): self.init_legend_actors(actor_specs=actor_specs, drawing_params=drawing_params)