class SupplierFormAdmin(ModelFormWidget): MODEL = Supplier #model to manage TITLE = 'Suppliers' #title of the application #formset of the edit form FIELDSETS = [(segment( ('name', 'nif'), ('email', 'contact'), ('country', 'phone'), ), segment('keywords', 'discounts', 'category', ('_category', '_addcategory_btn')))] AUTHORIZED_GROUPS = ['superuser', settings.APP_PROFILE_ORDERS] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._addcategory_btn = ControlButton( '<i class="icon plus" ></i>Category', css='basic mini', field_css='five wide', label_visible=False, default=self.__create_new_category, ) self._category = ControlText('New category', field_css='eleven wide', label_visible=False, visible=False) def __create_new_category(self): if self._category.visible is False: self._category.show() self._addcategory_btn.label = '<i class="icon file outline" ></i>Create' self._addcategory_btn.css = 'blue' else: self._category.hide() self._addcategory_btn.label = '<i class="icon plus" ></i>Category' self._addcategory_btn.css = 'basic mini' if self._category.value: obj, created = Category.objects.get_or_create( name=self._category.value)
class UpdatePublication(BaseWidget): TITLE = 'Search publication' LAYOUT_POSITION = conf.ORQUESTRA_NEW_BIGWINDOW def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) authors = kwargs.get('authors') title = kwargs.get('title') journal_name = kwargs.get('journal_name') doi = kwargs.get('doi') pubdate = kwargs.get('pubdate') pubyear = kwargs.get('pubyear') self.pub_hash = str( (authors, title, journal_name, doi, pubdate, pubyear)) text = f""" <table> <tr> <th style='text-align: right' >Title</th> <td style='padding:5px;padding-left:10px;' colspan='3' >{title}</th> <tr/> <tr> <th style='text-align: right' >Authors</th> <td style='padding:5px;padding-left:10px;' colspan='3' >{authors}</th> <tr/> <tr> <th style='text-align: right' >Journal</th> <td style='padding:5px;padding-left:10px;' >{journal_name}</th> <th style='text-align: right' >Pub date</th> <td style='padding:5px;padding-left:10px;' >{pubdate}</th> <tr/> <tr> <th style='text-align: right' >Year</th> <td style='padding:5px;padding-left:10px;' >{pubyear}</th> <th style='text-align: right' >Doi</th> <td style='padding:5px;padding-left:10px;' >{doi}</th> <tr/> </table> """ self._person = ControlAutoComplete( 'Author', queryset=Person.objects.all().order_by('full_name'), visible=False) self._authoralias = ControlText('Author alias', visible=False) self._addalias = ControlButton('Add alias', default=self.__add_author_alias_evt, visible=False) alias = AuthorAlias.objects.all() self._authors = ControlList( 'Unknown authors', default=[[a] for a in authors.split(';') if not alias.filter(name=a).exists()], horizontal_headers=['Authors alias'], item_selection_changed_event=self.__authors_selection_changed_evt) self._ignorebtn = ControlButton('Ignore this publication', css='red', default=self.__ignore_this_pub_evt, label_visible=False) self._info = ControlLabel(text) self._details = ControlEmptyWidget(parent=self, name='_details', default=PubsList(**kwargs)) self.formset = [ '_ignorebtn', '_info', ('_person', '_authoralias', '_addalias'), '_authors', segment('_details', css='secondary') ] if len(self._authors.value) == 0: self._authors.hide() def __authors_selection_changed_evt(self): if self._authors.selected_row_index >= 0: self._addalias.show() self._authoralias.show() self._person.show() self._authoralias.value = self._authors.value[ self._authors.selected_row_index][0] else: self._addalias.hide() self._authoralias.hide() self._person.hide() def __add_author_alias_evt(self): if self._authoralias.value and self._person.value: a = AuthorAlias(name=self._authoralias.value, person=Person.objects.get(pk=self._person.value)) a.save() data = self._authors.value newdata = [] for row in data: if row[0] == self._authoralias.value: continue newdata.append(row) self._authors.value = newdata self._addalias.hide() self._authoralias.hide() self._person.hide() def __ignore_this_pub_evt(self): filepath = os.path.join(settings.MEDIA_ROOT, conf.APP_IMPORT_PUBLICATIONS_BLACKLIST_FILE) with open(filepath, 'a') as out: out.write(str(self.pub_hash) + '\n') self.close() @classmethod def has_permissions(cls, user): if user.is_superuser: return True return user.groups.filter( permissions__codename__in=['app_access_imp_pub']).exists()
class CommandEditor(BaseWidget): def __init__(self, task=None, when=None, command=None): title = "Post command editor" if when == TaskCommand.WHEN_POST else "Pre command editor" BaseWidget.__init__(self, title, parent_win=task) self.command = command self.task = task self.when = when self.set_margin(5) self._type = ControlCombo('Type of command', changed_event=self.__type_changed_evt) self._cancelbtn = ControlButton('Cancel', default=self.__cancel_evt) self._okbtn = ControlButton('Ok', default=self.__ok_evt) self._command = ControlText('External command', visible=False) self._filesbrowser = ControlTreeView('Files browser') self._type.add_item('Execute a gui script', 'script') self._type.add_item('Execute a external command', 'external') self.formset = [ '_type', '_command', '_filesbrowser', (' ', '_cancelbtn', '_okbtn'), ' ' ] root_path = os.path.abspath(task.path if task else '/') self.syspath_model = QFileSystemModel(self) self.syspath_model.setRootPath(root_path) self.syspath_model.setNameFilters(['*.py']) self.syspath_model.setNameFilterDisables(False) self._filesbrowser.value = self.syspath_model root_index = self.syspath_model.index(root_path) self._filesbrowser.setRootIndex(root_index) for i in range(1, 4): self._filesbrowser.hideColumn(i) def __type_changed_evt(self): if self._type.value == 'script': self._filesbrowser.show() self._command.hide() elif self._type.value == 'external': self._filesbrowser.hide() self._command.show() def __cancel_evt(self): self.close() self.task.cmdwin = None def __ok_evt(self): if self.command is not None: command = self.command else: command = self.task.create_scriptcmd( ) if self._type.value == 'script' else self.task.create_execcmd() command.when = self.when if self._type.value == 'script': for index in self._filesbrowser.selectedIndexes(): filepath = self.syspath_model.filePath(index) break if filepath is None: return file_path = Path(filepath) task_path = Path(self.task.path) relpath = file_path.relative_to(task_path) command.script = str(relpath) elif self._type.value == 'external': command.cmd = self._command.value self.task.update_commands() self.close() self.task.cmdwin = None
class SceneApp(HeatMapApp): def __init__(self, title=''): self._points_values = None #used to map a color for each tracking point super(SceneApp, self).__init__(title) ##### CONTROLS ############################################################################## self._scene_file = ControlFile('Scene') self._scene_toggle_objs_list = ControlButton('Show/Hide objects', checkable=True) self._scene_objs_list = ControlCheckBoxList('Objects') self._scene_opengl = ControlOpenGL('OpengGL Scene') self._scene_points_alfa = ControlSlider('Transparency', 10, 0, 100) self._scene_bg_color = ControlCombo('Background color') self._scene_apply_colorBnds = ControlButton('Apply colors boundaries') self._scene_points_size = ControlCombo('Points size') self._scene_obj_color = ControlText('Object color') ############################################################################################# self._modules_tabs.update({ 'Heat map': [('_heatmapColor', ' | ', 'Filters:', '_toggleHeatmapVars', '_toggleSphereVisibility', '_sphere', ' | ', '_apply2Heatmap', ' '), ('_heatmapVarsList', '_heatmapVars', '_heatmapHigherVarsValues', '_heatMapMinVar', '_heatmapVarsBnds', '_heatMapMaxVar'), ({ '1:Map': ['_heatmap'], '0:Scene': [[('_scene_file', ' ', '_scene_toggle_objs_list', ' ', '_scene_bg_color', ' | ', '_scene_points_size', ' | ', '_scene_apply_colorBnds'), '_scene_points_alfa', '_scene_obj_color', '_scene_objs_list'], '=', '_scene_opengl'] }, '_heatmapColorsBnds')] }) ############################################################################################# self._scene_bg_color += ('White', '1,1,1,1.0') self._scene_bg_color += ('Gray', '0.3,0.3,0.3,1.0') self._scene_bg_color += ('Black', 'None') self._scene_points_size += '1' self._scene_points_size += '3' self._scene_points_size += '6' self._scene_points_size += '8' self._scene_objs_list.hide() self._scene_obj_color.hide() self._scene_objs_list.changed = self.__changed_objects_list_event self._scene_toggle_objs_list.value = self.__toggle_objects_list_event self._scene_points_alfa.changed = self.__changed_scene_points_alfa_event self._scene_bg_color.changed = self.__changed_background_color_event self._scene_apply_colorBnds.value = self.__scene_apply_color_bnds_event self._scene_points_size.changed = self.__changed_scene_points_size_event self._scene_objs_list.selectionChanged = self.__selectionchanged_object_list_event self._scene_obj_color.changed = self.__changed_object_color_event self._scene = None self._scene_file.changed = self.__scene_file_selected self._scene_opengl.clear_color = 1, 1, 1, 1 #self._scene_file.value = '/home/ricardo/Desktop/01Apollo201403210900/01Apollo201403210900_Scenario.obj' def initForm(self): super(SceneApp, self).initForm() #self._splitters[0].setStretchFactor(0,10) #self._splitters[0].setStretchFactor(1,90) ############################################################################################ ### EVENTS ################################################################################# ############################################################################################ def __changed_object_color_event(self): index = self._scene_objs_list.mouseSelectedRowIndex self._scene.objects[index].color = eval(self._scene_obj_color.value) self._scene_opengl.repaint() def __selectionchanged_object_list_event(self): index = self._scene_objs_list.mouseSelectedRowIndex self._scene_obj_color.value = str(self._scene.objects[index].color) self._scene_obj_color.label = 'Object color ({0})'.format( self._scene.objects[index].name) def __changed_scene_points_size_event(self): self._scene.points_size = eval(self._scene_points_size.value) self._scene_opengl.repaint() def __toggle_objects_list_event(self): if self._scene_toggle_objs_list.checked: self._scene_objs_list.show() self._scene_obj_color.show() else: self._scene_objs_list.hide() self._scene_obj_color.hide() def __changed_background_color_event(self): self._scene_opengl.clear_color = eval(self._scene_bg_color.value) def __changed_scene_points_alfa_event(self): if self._points_values != None: self._scene.colors = self.__gen_colors(self._points_values.copy()) self._scene_opengl.repaint() def __changed_objects_list_event(self): x, y, z = 0.0, 0.0, 0.0 count = 0.0 for obj in self._scene.objects: obj.active = obj.name in self._scene_objs_list.value obj.draw_faces = True if obj.active: for point in obj.points: x += point[0] y += point[1] z += point[2] count += 1.0 if count == 0.0: count = 1.0 self._scene._center = x / count, y / count, z / count self._scene_opengl.repaint() def __scene_file_selected(self): if len(self._scene_file.value) == 0: return self._scene = CustomScene() w = WavefrontOBJReader(self._scene_file.value) self._scene.objects = w.objects self._scene_opengl.value = self._scene self._scene_objs_list.clear() for obj in self._scene.objects: self._scene_objs_list += (obj.name, True) def __gen_colors(self, values): if len(values) == 0: return [] if self._heatmapColor.value == vv.CM_BONE: func = 'bone' if self._heatmapColor.value == vv.CM_COOL: func = 'cool' if self._heatmapColor.value == vv.CM_COPPER: func = 'copper' if self._heatmapColor.value == vv.CM_GRAY: func = 'gray' if self._heatmapColor.value == vv.CM_HOT: func = 'hot' if self._heatmapColor.value == vv.CM_HSV: func = 'hsv' if self._heatmapColor.value == vv.CM_PINK: func = 'pink' if self._heatmapColor.value == vv.CM_JET: func = 'jet' if self._heatmapColor.value == vv.CM_AUTUMN: func = 'autumn' if self._heatmapColor.value == vv.CM_SPRING: func = 'spring' if self._heatmapColor.value == vv.CM_SUMMER: func = 'summer' if self._heatmapColor.value == vv.CM_WINTER: func = 'winter' normalized_vals = np.float32(values) / np.float32(values).max() normalized_vals = normalized_vals - normalized_vals.min() maximum = normalized_vals.max() func = getattr(cm, func) colors = [] alpha = float(self._scene_points_alfa.value) / 100.0 for v in normalized_vals: color = func(v / maximum) colors.append((color[0], color[1], color[2], alpha)) return colors def __scene_apply_color_bnds_event(self): self._scene_apply_colorBnds.form.setStyleSheet("") if self._heatmapImg is None or not self._heatmapImg.any(): return lower, higher = self._heatmapColorsBnds.value a = self._points_values.copy() a[a < lower] = lower a[a > higher] = higher self._scene.colors = self.__gen_colors(a) def changed_heatmap_colors_bounds_event(self): super(SceneApp, self).changed_heatmap_colors_bounds_event() self._scene_apply_colorBnds.form.setStyleSheet("color: red") def changed_heatmap_color_event(self): super(SceneApp, self).changed_heatmap_color_event() if self._points_values != None: self._scene.colors = self.__gen_colors(self._points_values.copy()) self._scene_opengl.repaint() def calculate_heatmap_event(self): super(SceneApp, self).calculate_heatmap_event() if self._scene: #Filter for the data from a lower and upper frame self._progress.min = lower = 0 if self._boundings.value[ 0] < 0 else int(self._boundings.value[0]) self._progress.max = higher = len( self._data) if self._boundings.value[1] > ( len(self._data) + 1) else int(self._boundings.value[1]) #Calculate the size of the map x_diff = self._data.xRange[1] - self._data.xRange[0] y_diff = self._data.yRange[1] - self._data.yRange[0] z_diff = self._data.zRange[1] - self._data.zRange[0] scale = self.fit_scale(x_diff, y_diff, z_diff) #Fit the best scale value try: sphere = sphere_x, sphere_y, sphere_z, sphere_r = eval( self._sphere.value) except: sphere = None min_var, max_var = self._heatmapVarsBnds.value which_var = 0 if self._heatmapVarsList.value == 'Velocity' else 1 values = [] points = [] for i in range(lower, higher): if (i % 3000) == 0: self._progress.value = i if self._data[i] != None: x, y, z = position = self._data[i].position x += abs(self._data.xRange[0]) y += abs(self._data.yRange[0]) z += abs(self._data.zRange[0]) x = int(round(x * scale)) y = int(round(y * scale)) z = int(round(z * scale)) #Filter position by a defined sphere if sphere != None and lin_dist3d( (x, y, z), (sphere_x, sphere_y, sphere_z)) > sphere_r: continue #Use variables to construct the map, or positions if self._toggleHeatmapVars.checked: #velocities array has less 1 element than positions array if which_var == 0 and len(self._velocities) <= i: continue #accelarations array has less 2 element than positions array if which_var == 1 and len(self._accelerations) <= i: continue var = self._velocities[ i] if which_var == 0 else self._accelerations[i] #Filter by variable boundaries if not (min_var <= var <= max_var): continue values.append(self._heatmapImg[z, x, y]) points.append(position) self._progress.value = higher self._points_values = np.float32(values) self._scene.points = points self._scene.colors = self.__gen_colors(self._points_values.copy()) self._scene_apply_colorBnds.form.setStyleSheet("") self._scene_opengl.repaint()
class VideosExporterGui(BaseWidget, VideosExporterPreview, VideosExporterProcess): def __init__(self, parent=None): super(VideosExporterGui, self).__init__('Videos exporter', parent_win=parent) self.set_margin(5) self.setMinimumHeight(400) self.setMinimumWidth(400) self._toolbox = ControlToolBox('Tool') self._panel_area = ControlEmptyWidget('Set the object area', default=DatasetsDialog(self)) self._panel_colors = ControlEmptyWidget('Set the object color', default=DatasetsDialog(self)) self._panel_imgs = ControlEmptyWidget('Set the video background', default=ImagesDialog(self)) #### path panel ################################################ self._panel_path = ControlEmptyWidget('Set the object path', default=DatasetsDialog(self)) self._drawpath = ControlCheckBox('Draw paths') ################################################################ #### draw events ############################################### self._drawevents = ControlCheckBoxList('Events') self._eventstitles = ControlCheckBox('Draw titles') self._evtsreload1 = ControlButton('Reload events') ################################################################ #### split by events ########################################### self._splitevents = ControlCheckBoxList('Events') self._evtsreload2 = ControlButton('Reload events') ################################################################ self._codec = ControlCheckBox('Force AVI') self._outdir = ControlDir('Output directory') self._outfile = ControlText('Output file name') self._player = ControlPlayer('Player') self._progress = ControlProgress('Progress') self._apply = ControlButton('Export video(s)', checkable=True) self._apply.icon = conf.ANNOTATOR_ICON_PATH self._apply.enabled = False self._usefixedsize = ControlCheckBox('Use a fixed size') self._usefixedcolor = ControlCheckBox('Use a fixed color') self._radius = ControlSlider('Circle radius', default=10, minimum=1, maximum=300) self._color = ControlText('BGR color', default='255,255,255') self.formset = [('_toolbox', '||', '_player'), '=', '_outdir', ('_outfile', '_codec'), '_apply', '_progress'] self._toolbox.value = [ ('Path', [self._panel_path, self._drawpath]), ('Circle (optional)', [self._panel_area, (self._usefixedsize, self._radius)]), ('Circle color (optional)', [self._panel_colors, (self._usefixedcolor, self._color)]), ('Background (optional)', [self._panel_imgs]), ('Draw events (optional)', [self._evtsreload1, self._drawevents, self._eventstitles]), ('Split files by events (optional)', [self._evtsreload2, self._splitevents]), ] self._panel_path.value.datasets_filter = lambda x: isinstance( x, (Contours, Path)) #self._panel_area.value.datasets_filter = lambda x: isinstance(x, Value ) self._panel_colors.value.datasets_filter = lambda x: isinstance( x, (Contours, Path)) and hasattr(x, 'has_colors_avg' ) and x.has_colors_avg ### Set the controls events ############################################# self._evtsreload1.value = self.__reload_events self._evtsreload2.value = self.__reload_events self._outfile.changed_event = self.outputfile_changed_event self._usefixedsize.changed_event = self.__usefixedsize_changed_event self._usefixedcolor.changed_event = self.__usefixedcolor_changed_event self._splitevents.selection_changed_event = self.outputfile_changed_event self._panel_path.value.video_selection_changed_event = self.__video_selection_changed_event self._codec.changed_event = self.__video_selection_changed_event ## function from VideosExporterProcess class self._apply.value = self.apply_event ## function from VideosExporterPreview class self._player.process_frame_event = self.player_processframe_event self._evtsreload1.icon = conf.ANNOTATOR_ICON_REFRESH self._evtsreload2.icon = conf.ANNOTATOR_ICON_REFRESH self._progress.hide() self._radius.hide() self._color.hide() self.__check_areatab_event() ########################################################################### ### UTILS ################################################################# ########################################################################### def __reload_events(self): """ Find all the events available on the timeline """ timeline = self.parent().timeline rows = timeline.rows events = {} for row in rows: for event in row.events: events[event.title] = True events = sorted(events.keys()) loaded_events = dict(self._drawevents.items) self._drawevents.value = [(e, loaded_events.get(e, False)) for e in events] loaded_events = dict(self._splitevents.items) self._splitevents.value = [(e, loaded_events.get(e, False)) for e in events] ########################################################################### ### EVENTS ################################################################ ########################################################################### def show(self): """ Load the events when the window is oppened """ super(VideosExporterGui, self).show() self.__reload_events() def __check_areatab_event(self): """ Activate or deactivate the color tab """ if len(list(self._panel_area.value.datasets) ) > 0 or self._usefixedsize.value: self._toolbox.set_item_enabled(2, True) else: self._toolbox.set_item_enabled(2, False) def __usefixedcolor_changed_event(self): if self._usefixedcolor.value: self._color.show() self._panel_colors.hide() else: self._color.hide() self._panel_colors.show() def __usefixedsize_changed_event(self): self.__check_areatab_event() if self._usefixedsize.value: self._radius.show() self._panel_area.hide() else: self._radius.hide() self._panel_area.show() def outputfile_changed_event(self): """ Update the output filename """ filename = self._outfile.value video = self._panel_path.value.selected_video if video is not None: filename = filename if len(filename) > 0 else video.filename videofilepath, video_extension = os.path.splitext(video.filename) outfilepath, outfile_extension = os.path.splitext(filename) names = [outfilepath] if len(outfilepath) > 0 else [] if '{videoindex}' not in outfilepath: names.append('{videoindex}') if len(list(self._splitevents.value)) > 0: if '{event}' not in outfilepath: names.append('{event}') if '{start}' not in outfilepath: names.append('{start}') if '{end}' not in outfilepath: names.append('{end}') self._outfile.value = ('-'.join(names) + video_extension) self._apply.enabled = True else: self._apply.enabled = False def __video_selection_changed_event(self): """ Activate the video preview """ video = self._panel_path.value.selected_video if video is not None: self._player.value = video.video_capture def get_object_area(self, path, areas, index): try: if self._usefixedsize.value: area = (self._radius.value**2 * math.pi) elif len(areas) > 0: a = areas[0] if isinstance(a, Value): area = a.get_value(index) else: area = a.get_area_value(index) else: area = path.get_area_value(index) return area except: return None def get_object_color(self, path, colors, index): try: if self._usefixedcolor.value: color = tuple(eval(self._color.value)) elif len(colors) > 0: color = colors[0].get_color_avg(index) else: color = path.get_color_avg(index) if color is None: raise Exception() except: color = 255, 255, 255 return color
class HeatMapApp(BaseApp): """Application form""" def __init__(self, title='Heat map'): super(HeatMapApp, self).__init__(title) self._heatmapImg = None #Store a numpy array with the heatmap self._velocities = None #Store the velocities for each frame self._accelerations = None #Store the accelarations for each frame ##### CONTROLS ############################################################################## self._heatmap = ControlVisVisVolume("Volume") self._toggleSphereVisibility = ControlButton('Filter by a region', checkable=True) self._sphere = ControlText('Position filter (x,y,z,radius)') self._toggleHeatmapVars = ControlButton('Select variables', checkable=True) self._heatmapVarsBnds = ControlBoundingSlider('Variable bounds', horizontal=True) self._heatmapHigherVarsValues = ControlCheckBox( 'Most higher', helptext='Show only the higher values') self._heatmapColor = ControlCombo('Color map') self._apply2Heatmap = ControlButton('Apply to map') self._heatmapColorsBnds = ControlBoundingSlider('Colors', horizontal=False) self._heatmapVarsList = ControlCombo('Variables') self._heatmapVars = ControlCheckBox('Map variables') self._heatMapMinVar = ControlText('Min vel.') self._heatMapMaxVar = ControlText('Max vel.') ############################################################################################# self._modules_tabs.update({ 'Heat map': [('_heatmapColor', ' | ', 'Filters:', '_toggleHeatmapVars', '_toggleSphereVisibility', '_sphere', ' | ', '_apply2Heatmap', ' '), ('_heatmapVarsList', '_heatmapVars', '_heatmapHigherVarsValues', '_heatMapMinVar', '_heatmapVarsBnds', '_heatMapMaxVar'), { 'Map': ('_heatmap', '_heatmapColorsBnds') }] }) ############################################################################################# self._heatmapVarsList += 'Velocity' self._heatmapVarsList += 'Acceleration' self._heatmapColor.add_item('Bone', vv.CM_BONE) self._heatmapColor.add_item('Cool', vv.CM_COOL) self._heatmapColor.add_item('Copper', vv.CM_COPPER) self._heatmapColor.add_item('Gray', vv.CM_GRAY) self._heatmapColor.add_item('Hot', vv.CM_HOT) self._heatmapColor.add_item('HSV', vv.CM_HSV) self._heatmapColor.add_item('Jet', vv.CM_JET) self._heatmapColor.add_item('Pink', vv.CM_PINK) self._heatmapColor.add_item('Autumn', vv.CM_AUTUMN) self._heatmapColor.add_item('Spring', vv.CM_SPRING) self._heatmapColor.add_item('Summer', vv.CM_SUMMER) self._heatmapColor.add_item('Winter', vv.CM_WINTER) self._heatmapColor.value = vv.CM_HSV self._sphere.hide() self._heatmapVarsBnds.hide() self._heatmapVarsList.hide() self._heatMapMinVar.hide() self._heatMapMaxVar.hide() self._heatmapVars.hide() self._heatmapHigherVarsValues.hide() self._heatmapVarsBnds.convert_2_int = False self._heatmapColorsBnds.convert_2_int = False self._apply2Heatmap.value = self.calculate_heatmap_event self._heatmapColor.changed = self.changed_heatmap_color_event self._toggleSphereVisibility.value = self.__toggle_sphere_visiblity_event self._toggleHeatmapVars.value = self.__toggle_variables_visibility_event self._heatmapVarsList.changed = self.__changed_heatmap_variables_list_event self._heatMapMinVar.changed = self.__changed_heatmap_minVar_event self._heatMapMaxVar.changed = self.__changed_heatmap_maxVar_event self._heatmapColorsBnds.changed = self.changed_heatmap_colors_bounds_event self._heatmapVars.changed = self.__changed_heatmap_variables_event ############################################################################################ ### AUXILIAR FUNCTIONS ##################################################################### ############################################################################################ def __calc_heatmap_size(self, x_diff, y_diff, z_diff, scale=None): """ Calculate the heatmap size """ if scale == None: scale = self.fit_scale(x_size, y_size, z_size) x_scaled_size = int(round((x_diff + 1) * scale)) y_scaled_size = int(round((y_diff + 1) * scale)) z_scaled_size = int(round((z_diff + 1) * scale)) return x_scaled_size, y_scaled_size, z_scaled_size def fit_scale(self, x_diff, y_diff, z_diff): """ Calculate the scale value that should be applied to each position, so they can fit in an numpy array """ scale = 1.0 new_scale = 1.0 x_size, y_size, z_size = 0, 0, 0 #The maximum allowed size for the heatmap is (2000,2000,2000) while x_size <= 2000.0 and y_size <= 2000.0 and z_size <= 2000.0: scale = new_scale new_scale = scale * 10.0 x_size, y_size, z_size = self.__calc_heatmap_size( x_diff, y_diff, z_diff, new_scale) return scale ############################################################################################ ### EVENTS ################################################################################# ############################################################################################ def __changed_heatmap_variables_event(self): if self._heatmapVars.value: self._heatmapHigherVarsValues.show() else: self._heatmapHigherVarsValues.hide() def __toggle_sphere_visiblity_event(self): if self._toggleSphereVisibility.checked: self._sphere.show() else: self._sphere.hide() def __toggle_variables_visibility_event(self): if self._toggleHeatmapVars.checked: self._heatmapVarsList.show() self._heatmapVarsBnds.show() self._heatMapMinVar.show() self._heatMapMaxVar.show() self._heatmapVars.show() else: self._heatmapVarsList.hide() self._heatmapVarsBnds.hide() self._heatMapMinVar.hide() self._heatMapMaxVar.hide() self._heatmapVars.hide() def changed_heatmap_colors_bounds_event(self): if self._heatmapImg is None or not self._heatmapImg.any(): return self._heatmap.colors_limits = self._heatmapColorsBnds.value def __changed_heatmap_minVar_event(self): if self._heatMapMinVar.value == '': return v = eval(self._heatMapMinVar.value) self._heatmapVarsBnds.min = v values = list(self._heatmapVarsBnds.value) if values[0] < v: values[0] = v self._heatmapVarsBnds.value = values def __changed_heatmap_maxVar_event(self): if self._heatMapMaxVar.value == '': return v = eval(self._heatMapMaxVar.value) self._heatmapVarsBnds.max = v values = list(self._heatmapVarsBnds.value) if values[1] > v: values[1] = v self._heatmapVarsBnds.value = values def __changed_heatmap_variables_list_event(self): if self._heatmapVarsList.value == 'Velocity' and self._velocities: lower = int(0 if self._boundings.value[0] < 0 else self._boundings. value[0]) higher = int( len(self._velocities) if self._boundings.value[1] >= len( self._velocities) else self._boundings.value[1]) max_val = max(self._velocities[lower:higher]) min_val = min(self._velocities[lower:higher]) self._heatmapVarsBnds.value = round(min_val, 2), round(max_val, 2) self._heatMapMinVar.value = str( round(min_val - (max_val - min_val) * 0.1, 2)) self._heatMapMaxVar.value = str( round(max_val + (max_val - min_val) * 0.1, 2)) if self._heatmapVarsList.value == 'Acceleration' and self._accelerations: lower = int(0 if self._boundings.value[0] < 0 else self._boundings. value[0]) higher = int( len(self._accelerations) if self._boundings.value[1] > (len(self._accelerations) + 1) else self._boundings.value[1]) max_val = max(self._accelerations[lower:higher]) min_val = min(self._accelerations[lower:higher]) self._heatmapVarsBnds.value = round(min_val, 2), round(max_val, 2) self._heatMapMinVar.value = str( round(min_val - (max_val - min_val) * 0.1, 2)) self._heatMapMaxVar.value = str( round(max_val + (max_val - min_val) * 0.1, 2)) def changed_heatmap_color_event(self): self._heatmap.colorMap = self._heatmapColor.value ############################################################################################ ### Map generation ######################################################################### ############################################################################################ def calculate_heatmap_event(self): #Filter for the data from a lower and upper frame if self._data is None: return self._progress.min = lower = 0 if self._boundings.value[0] < 0 else int( self._boundings.value[0]) self._progress.max = higher = len( self._data) if self._boundings.value[1] > ( len(self._data) + 1) else int(self._boundings.value[1]) #Calculate the size of the map x_diff = self._data.xRange[1] - self._data.xRange[0] y_diff = self._data.yRange[1] - self._data.yRange[0] z_diff = self._data.zRange[1] - self._data.zRange[0] scale = self.fit_scale(x_diff, y_diff, z_diff) #Fit the best scale value x_size, y_size, z_size = self.__calc_heatmap_size( x_diff, y_diff, z_diff, scale) #Return the best size for the map image try: sphere = sphere_x, sphere_y, sphere_z, sphere_r = eval( self._sphere.value) except: sphere = None min_var, max_var = self._heatmapVarsBnds.value which_var = 0 if self._heatmapVarsList.value == 'Velocity' else 1 #Create the map image img = np.zeros((z_size, x_size, y_size), dtype=np.float32) for i in range(lower, higher): if (i % 3000) == 0: self._progress.value = i if self._data[i] != None: position = self._data[i].position #shift and scale the coordenates, to avoid negative and decimal values #is only possible to map in the image positive and integer coordenates x, y, z = position x += abs(self._data.xRange[0]) y += abs(self._data.yRange[0]) z += abs(self._data.zRange[0]) x = int(round(x * scale)) y = int(round(y * scale)) z = int(round(z * scale)) #Filter position by a defined sphere if sphere != None and lin_dist3d( (x, y, z), (sphere_x, sphere_y, sphere_z)) > sphere_r: continue #Use variables to construct the map, or positions if self._toggleHeatmapVars.checked: #velocities array has less 1 element than positions array if which_var == 0 and len(self._velocities) <= i: continue #accelarations array has less 2 element than positions array if which_var == 1 and len(self._accelerations) <= i: continue var = self._velocities[ i] if which_var == 0 else self._accelerations[i] #Filter by variable boundaries if not (min_var <= var <= max_var): continue if self._heatmapVars.value: #Map the variables if self._heatmapHigherVarsValues.value: tmp = img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] tmp[tmp < var] = var else: img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] += var else: #Map positions img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] += 1.0 else: #Map positions img[z - 1:z + 1, x - 1:x + 1, y - 1:y + 1] += 1.0 self._progress.value = higher color_min = np.min(img) color_max = np.max(img) self._heatmapColorsBnds.min = color_min - (color_max - color_min) * 0.1 self._heatmapColorsBnds.max = color_max + (color_max - color_min) * 0.1 self._heatmapColorsBnds.value = color_min, color_max self._heatmap.value = np.zeros((1, 1), dtype=np.float32) self._heatmap.colors_limits = None self._heatmap.value = img self._heatmapImg = img ############################################################################################ ### CLASS OVERRIDE FUNCTIONS ############################################################### ############################################################################################ def frames_boundings_changed(self): super(HeatMapApp, self).frames_boundings_changed() self.__changed_heatmap_variables_list_event() def load_tracking_file(self): super(HeatMapApp, self).load_tracking_file() self.__changed_heatmap_variables_list_event() def export_tracking_file(self): filename, _ = QFileDialog.getSaveFileName(self, 'Select a file', selectedFilter='*.csv') if not filename: return filename = str(filename) if not filename.lower().endswith('.csv'): filename += '.csv' #Export only the selected bounds lower = 0 if self._boundings.value[0] < 0 else self._boundings.value[0] higher = len(self._data) if self._boundings.value[1] > ( len(self._data) + 1) else self._boundings.value[1] self._progress.min = lower self._progress.max = higher which_var = 0 if self._heatmapVarsList.value == 'Velocity' else 1 try: sphere = sphere_x, sphere_y, sphere_z, sphere_r = eval( self._sphere.value) except: sphere = None min_var, max_var = self._heatmapVarsBnds.value #Calculate the size of the map x_diff = self._data.xRange[1] - self._data.xRange[0] y_diff = self._data.yRange[1] - self._data.yRange[0] z_diff = self._data.zRange[1] - self._data.zRange[0] scale = self.fit_scale(x_diff, y_diff, z_diff) #Fit the best scale value with open(filename, 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',') for i in range(int(lower), int(higher)): self._progress.value = i position = self._data[i].position x, y, z = position x += abs(self._data.xRange[0]) y += abs(self._data.yRange[0]) z += abs(self._data.zRange[0]) x = int(round(x * scale)) y = int(round(y * scale)) z = int(round(z * scale)) if sphere != None and lin_dist3d( (x, y, z), (sphere_x, sphere_y, sphere_z)) > sphere_r: continue if self._toggleHeatmapVars.checked: var = self._velocities[ i] if which_var == 0 else self._accelerations[i] if not (min_var <= var <= max_var): continue if self._data[i] == None: continue row2save = self._data[i].row if i > lower: row2save = row2save + [self._velocities[i]] if (i + 1) > lower: row2save = row2save + [self._accelerations[i]] spamwriter.writerow(row2save)