def update_inverse(self): angle, scalexy, scalez, dx, dy, dz = map(float, [box.text() for box in [self.inv_angle, self.inv_scalexy, self.inv_scalez, self.inv_dx, self.inv_dy, self.inv_dz]]) self.inverse_trans = Transformation(angle, scalexy, scalez, dx, dy, dz) self.trans = self.inverse_trans.inverse() self.dx.setText(str(self.trans.translation.dx)) self.dy.setText(str(self.trans.translation.dy)) self.dz.setText(str(self.trans.translation.dz)) self.angle.setText(str(self.trans.rotation.angle)) self.scalexy.setText(str(self.trans.scaling.horizontal_factor)) self.scalez .setText(str(self.trans.scaling.vertical_factor))
def slf_base(args): with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() output_header = resin.header.copy() # Shift mesh coordinates if necessary if args.shift: output_header.transform_mesh([Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Set mesh origin coordinates if args.set_mesh_origin: output_header.set_mesh_origin(args.set_mesh_origin[0], args.set_mesh_origin[1]) # Toggle output file endianness if necessary if args.toggle_endianness: output_header.toggle_endianness() # Convert to single precision if args.to_single_precision: if resin.header.is_double_precision(): output_header.to_single_precision() else: logger.warn('Input file is already single precision! Argument `--to_single_precision` is ignored') # Remove variables if necessary if args.var2del: output_header.empty_variables() for var_ID, var_name, var_unit in zip(resin.header.var_IDs, resin.header.var_names, resin.header.var_units): if var_ID not in args.var2del: output_header.add_variable(var_ID, var_name, var_unit) # Add new derived variables if args.var2add is not None: for var_ID in args.var2add: if var_ID in output_header.var_IDs: logger.warn('Variable %s is already present (or asked)' % var_ID) else: output_header.add_variable_from_ID(var_ID) us_equation = get_US_equation(args.friction_law) necessary_equations = get_necessary_equations(resin.header.var_IDs, output_header.var_IDs, is_2d=resin.header.is_2d, us_equation=us_equation) with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout: resout.write_header(output_header) for time_index, time in tqdm(resin.subset_time(args.start, args.end, args.ech), unit='frame'): values = do_calculations_in_frame(necessary_equations, resin, time_index, output_header.var_IDs, output_header.np_float_type, is_2d=output_header.is_2d, us_equation=us_equation, ori_values={}) resout.write_entire_frame(output_header, time, values)
def load(self): msg = QMessageBox.warning( None, 'Confirm load', 'Do you want to load configuration file?\n(Your current workspace will be erased)', QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if msg == QMessageBox.Cancel: return filename, _ = QFileDialog.getOpenFileName( self, 'Choose the file name', '', 'All files (*)', options=QFileDialog.Options() | QFileDialog.DontUseNativeDialog) if not filename: return try: with open(filename, 'r') as f: new_labels = f.readline().rstrip().split('|') coords = f.readline().rstrip().split('|') new_rectangles = [] for coord in coords: x, y = map(int, coord.split(',')) new_rectangles.append( QRect(x, y, self.recWidth, self.recHeight)) new_transformations = {} for line in f.readlines(): i, j, params = line.rstrip().split('|') i, j = int(i), int(j) angle, scalexy, scalez, dx, dy, dz = map( float, params.split()) new_transformations[i, j] = Transformation( angle, scalexy, scalez, dx, dy, dz) new_transformations[j, i] = new_transformations[i, j].inverse() if len(new_labels) < 2: raise ValueError if not is_connected(list(range(len(new_labels))), new_transformations.keys()): raise ValueError except (ValueError, IndexError): QMessageBox.critical(self, 'Error', 'The configuration is not valid.', QMessageBox.Ok) return self.btnAddConnect.setEnabled(False) self.btnSave.setEnabled(True) self.labels = new_labels self.rectangles = new_rectangles self.transformations = new_transformations self.repaint()
def slf_to_raster(args): with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() header = resin.header logger.info(header.summary()) resin.get_time() if args.vars is None: var_names = [ var_name.decode('utf-8') for var_name in header.var_names ] var_IDs = header.var_IDs else: var_names = [] var_IDs = [] for var_ID, var_name in zip(header.var_IDs, header.var_names): if var_ID in args.vars: var_names.append(var_name.decode('utf-8')) var_IDs.append(var_ID) # Shift mesh coordinates if necessary if args.shift: header.transform_mesh( [Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Build output regular grid and matplotlib triangulation of the mesh m_xi, m_yi = np.meshgrid( np.arange(header.x.min(), header.x.max(), args.resolution), np.arange(header.y.min(), header.y.max(), args.resolution)) triang = mtri.Triangulation(header.x, header.y, triangles=header.ikle_2d - 1) # Build list containing all interpolated variables on the regular grid array_list = [] for i, (var_ID, var_name) in enumerate(zip(var_IDs, var_names)): values = resin.read_var_in_frame(args.frame_index, var_ID) interp = mtri.LinearTriInterpolator(triang, values) data = interp( m_xi, m_yi)[::-1] # reverse array so the tif looks like the array array_list.append((var_name, data)) logger.info( "Min and max values for interpolated %s variable: [%f, %f]" % (var_name, data.min(), data.max())) # Write data in the raster output file arrays2raster(args.out_tif, (header.x.min(), header.y.max()), args.resolution, -args.resolution, array_list)
def check(self): try: angle, scalexy, scalez, dx, dy, dz = map(float, [box.text() for box in [self.angle, self.scalexy, self.scalez, self.dx, self.dy, self.dz]]) except ValueError: QMessageBox.critical(self, 'Error', 'The transformation parameters should be numbers!', QMessageBox.Ok) return if scalexy == 0 or scalez == 0: QMessageBox.critical(self, 'Error', 'The scaling factors cannot be equal to zero!', QMessageBox.Ok) return self.transformation = Transformation(angle, scalexy, scalez, dx, dy, dz) self.accept()
def slf_last(args): with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() output_header = resin.header.copy() # Shift mesh coordinates if necessary if args.shift: output_header.transform_mesh( [Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Toggle output file endianness if necessary if args.toggle_endianness: output_header.toggle_endianness() # Convert to single precision if args.to_single_precision: if resin.header.is_double_precision(): output_header.to_single_precision() else: logger.warn( 'Input file is already single precision! Argument `--to_single_precision` is ignored' ) values = np.empty((output_header.nb_var, output_header.nb_nodes), dtype=output_header.np_float_type) with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout: resout.write_header(output_header) time_index = len(resin.time) - 1 time = resin.time[-1] if args.time is None else args.time for i, var_ID in enumerate(output_header.var_IDs): values[i, :] = resin.read_var_in_frame(time_index, var_ID) resout.write_entire_frame(output_header, time, values)
def get_zones_from_i3s_file(shp_name, threshold, operator_str): polylines = [] attributes = shp.get_numeric_attribute_names(shp_name) if args.attr_to_shift_z is not None: try: index_attr = [attr for _, attr in attributes].index(args.attr_to_shift_z) except ValueError: logger.critical('Attribute "%s" is not found.' % args.attr_to_shift_z) sys.exit(1) for polyline in shp.get_open_polylines(shp_name): if not polyline.polyline().is_valid: sys.exit("ERROR: polyline is not valid (probably because it intersects itself)!") # Shift z (if requested) if args.attr_to_shift_z is not None: dz = polyline.attributes()[index_attr] print(dz) polyline = polyline.apply_transformations([Transformation(0.0, 1.0, 1.0, 0.0, 0.0, dz)]) # Linear interpolation along the line for values below the threshold if threshold is not None: np_coord = np.array(polyline.coords()) Xt = np.sqrt(np.power(np.ediff1d(np_coord[:, 0], to_begin=0.), 2) + np.power(np.ediff1d(np_coord[:, 1], to_begin=0.), 2)) Xt = Xt.cumsum() ref_rows = np_coord[:, 2] > args.threshold np_coord[:, 2] = np.interp(Xt, Xt[ref_rows], np_coord[ref_rows, 2]) polyline = geo.LineString(np_coord) polylines.append(polyline) zones = [] for prev_line, next_line in zip(polylines[:-1], polylines[1:]): zones.append(Zone(prev_line, next_line, operator_str)) return zones
def slf_sedi_chain(args): # Check that float parameters are positive (especially ws!) for arg in ('Cmud', 'ws', 'C', 'M'): if getattr(args, arg) < 0: logger.critical('The argument %s has to be positive' % args) sys.exit(1) with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() us_equation = get_US_equation(args.friction_law) necessary_equations = get_necessary_equations(resin.header.var_IDs, ['TAU'], is_2d=True, us_equation=us_equation) if resin.header.nb_frames < 1: logger.critical('The input file must have at least one frame!') sys.exit(1) output_header = resin.header.copy() # Shift mesh coordinates if necessary if args.shift: output_header.transform_mesh( [Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Toggle output file endianness if necessary if args.toggle_endianness: output_header.toggle_endianness() # Convert to single precision if args.to_single_precision: if resin.header.is_double_precision(): output_header.to_single_precision() else: logger.warn( 'Input file is already single precision! Argument `--to_single_precision` is ignored' ) output_header.empty_variables() output_header.add_variable_from_ID('B') output_header.add_variable_from_ID('EV') with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout: resout.write_header(output_header) prev_time = None prev_tau = None initial_bottom = resin.read_var_in_frame(0, 'B') bottom = copy(initial_bottom) for time_index, time in enumerate(resin.time): tau = do_calculations_in_frame(necessary_equations, resin, time_index, ['TAU'], output_header.np_float_type, is_2d=True, us_equation=us_equation, ori_values={})[0] if prev_time is not None: dt = time - prev_time mean_tau = (prev_tau + tau) / 2 if args.Tcd > 0: bottom += args.Cmud * args.ws * args.C * \ (1 - np.clip(mean_tau/args.Tcd, a_min=None, a_max=1.)) * dt if args.Tce > 0: bottom -= args.Cmud * args.M * (np.clip( mean_tau / args.Tce, a_min=1., a_max=None) - 1.) * dt evol_bottom = bottom - initial_bottom resout.write_entire_frame(output_header, time, np.vstack((bottom, evol_bottom))) prev_time = time prev_tau = tau
def slf_3d_to_2d(args): with Serafin.Read(args.in_slf, args.lang) as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() if resin.header.is_2d: logger.critical('The input file is not 3D.') sys.exit(1) if 'Z' not in resin.header.var_IDs: logger.critical('The elevation variable Z is not found in the Serafin file.') sys.exit(1) if args.layer is not None: upper_plane = resin.header.nb_planes if args.layer < 1 or args.layer > upper_plane: logger.critical('Layer has to be in [1, %i]' % upper_plane) sys.exit(1) output_header = resin.header.copy_as_2d() # Shift mesh coordinates if necessary if args.shift: output_header.transform_mesh([Transformation(0, 1, 1, args.shift[0], args.shift[1], 0)]) # Toggle output file endianness if necessary if args.toggle_endianness: output_header.toggle_endianness() # Convert to single precision if args.to_single_precision: if resin.header.is_double_precision(): output_header.to_single_precision() else: logger.warn('Input file is already single precision! Argument `--to_single_precision` is ignored') if args.aggregation is not None: if args.aggregation == 'max': operation_type = operations.MAX elif args.aggregation == 'min': operation_type = operations.MIN else: # args.aggregation == 'mean' operation_type = operations.MEAN selected_vars = [var for var in output_header.iter_on_all_variables()] vertical_calculator = operations.VerticalMaxMinMeanCalculator(operation_type, resin, output_header, selected_vars, args.vars) output_header.set_variables(vertical_calculator.get_variables()) # sort variables # Add some elevation variables for var_ID in args.vars: output_header.add_variable_from_ID(var_ID) with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout: resout.write_header(output_header) vars_2d = np.empty((output_header.nb_var, output_header.nb_nodes_2d), dtype=output_header.np_float_type) for time_index, time in enumerate(tqdm(resin.time, unit='frame')): if args.aggregation is not None: vars_2d = vertical_calculator.max_min_mean_in_frame(time_index) else: for i, var in enumerate(output_header.var_IDs): vars_2d[i, :] = resin.read_var_in_frame_as_3d(time_index, var)[args.layer - 1, :] resout.write_entire_frame(output_header, time, vars_2d)
def ADCP_comp(args): x_mes = [] y_mes = [] cord_mes = open(args.inADCP_GPS).read().splitlines() for x_l in cord_mes: y, x = x_l.split(',') if x == NODATA or y == NODATA: print("Warning: one point is missing") else: x_mes.append(x) y_mes.append(y) x_mes = [float(a) for a in x_mes] y_mes = [float(a) for a in y_mes] inProj = Proj("+init=EPSG:%i" % args.inEPSG) outProj = Proj("+init=EPSG:%i" % args.outEPSG) x_mes, y_mes = transform(inProj, outProj, x_mes, y_mes) SCHEMA = {'geometry': 'LineString', 'properties': {'nom': 'str'}} with fiona.open(args.outADCP_GPS, 'w', 'ESRI Shapefile', SCHEMA, crs=from_epsg(args.outEPSG)) as out_shp: Ltest = LineString([(x_2, y_2) for x_2, y_2 in zip(x_mes, y_mes)]) elem = {} elem['geometry'] = mapping(Ltest) elem['properties'] = {'nom': 'ADCP line'} out_shp.write(elem) p_raw = RawProfileObj(args.inADCP) processing_settings = {'proj_method': 2} startingpoint = dict(start=Vector(0, 0)) p0 = ProcessedProfileObj(p_raw, processing_settings, startingpoint) profile_averaged = averaging.get_averaged_profile(p0, cfg={'order': 15}) header = 'X;Y;Uadcp;Vadcp;MagnitudeXY;Hadcp\n' writeAscii2D(profile_averaged, '{x};{y};{vx};{vy};{vmag};{depth}', args.outADCP, header=header) if args.inTELEMAC: with open(args.outT2DCSV, 'w', newline='') as csvfile: csvwriter = csv.writer(csvfile, delimiter=';') HEADER = [ 'folder', 'time_id', 'time', 'point_x', 'point_y', 'distance', 'value' ] csvwriter.writerow(HEADER) for slf_path in args.inTELEMAC: folder = os.path.basename(os.path.split(slf_path)[0]) with Serafin.Read(slf_path, 'fr') as resin: resin.read_header() logger.info(resin.header.summary()) resin.get_time() output_header = resin.header.copy() if args.shift: output_header.transform_mesh([ Transformation(0, 1, 1, args.shift[0], args.shift[1], 0) ]) mesh = MeshInterpolator(output_header, True) lines = [] for poly in Shapefile.get_lines(args.outADCP_GPS, shape_type=3): lines.append(poly) nb_nonempty, indices_nonempty, line_interpolators, line_interpolators_internal = \ mesh.get_line_interpolators(lines) res = mesh.interpolate_along_lines( resin, 'M', list(range(len(resin.time))), indices_nonempty, line_interpolators, '{:.6e}') csvwriter.writerows([[folder] + x[2] for x in res])
class EditTransformationDialog(QDialog): def __init__(self, from_label, to_label, trans, inverse_trans): super().__init__() self.deleted = False self.trans = trans self.inverse_trans = inverse_trans buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) deleteButton = QPushButton('Delete') deleteButton.setFixedSize(110, 30) deleteButton.clicked.connect(self.deleteEvent) self.dx = QLineEdit(str(trans.translation.dx)) self.dy = QLineEdit(str(trans.translation.dy)) self.dz = QLineEdit(str(trans.translation.dz)) self.angle = QLineEdit(str(trans.rotation.angle)) self.scalexy = QLineEdit(str(trans.scaling.horizontal_factor)) self.scalez = QLineEdit(str(trans.scaling.vertical_factor)) self.inv_dx = QLineEdit(str(inverse_trans.translation.dx)) self.inv_dy = QLineEdit(str(inverse_trans.translation.dy)) self.inv_dz = QLineEdit(str(inverse_trans.translation.dz)) self.inv_angle = QLineEdit(str(inverse_trans.rotation.angle)) self.inv_scalexy = QLineEdit( str(inverse_trans.scaling.horizontal_factor)) self.inv_scalez = QLineEdit(str(inverse_trans.scaling.vertical_factor)) self.dx.editingFinished.connect(self.edit_dx) self.dy.editingFinished.connect(self.edit_dy) self.dz.editingFinished.connect(self.edit_dz) self.angle.editingFinished.connect(self.edit_angle) self.scalexy.editingFinished.connect(self.edit_scalexy) self.scalez.editingFinished.connect(self.edit_scalez) self.inv_dx.editingFinished.connect(self.edit_inv_dx) self.inv_dy.editingFinished.connect(self.edit_inv_dy) self.inv_dz.editingFinished.connect(self.edit_inv_dz) self.inv_angle.editingFinished.connect(self.edit_inv_angle) self.inv_scalexy.editingFinished.connect(self.edit_inv_scalexy) self.inv_scalez.editingFinished.connect(self.edit_inv_scalez) mainLayout = QVBoxLayout() vlayout = QVBoxLayout() lb = QLabel('<b>Transformation from %s to %s<b>' % (from_label, to_label)) vlayout.addWidget(lb) vlayout.setAlignment(lb, Qt.AlignHCenter) vlayout.addItem(QSpacerItem(10, 10)) glayout = QGridLayout() glayout.addWidget(QLabel('<b>Rotation<b>'), 1, 1) glayout.addWidget(QLabel('angle (rad)'), 2, 2, Qt.AlignRight) glayout.addWidget(self.angle, 2, 3) glayout.addWidget(QLabel('<b>Scaling<b>'), 3, 1) glayout.addWidget(QLabel('XY factor'), 4, 2, Qt.AlignRight) glayout.addWidget(self.scalexy, 4, 3) glayout.addWidget(QLabel('Z factor'), 4, 4, Qt.AlignRight) glayout.addWidget(self.scalez, 4, 5) glayout.addWidget(QLabel('<b>Translation<b>'), 5, 1) glayout.addWidget(QLabel('translate X'), 6, 2, Qt.AlignRight) glayout.addWidget(self.dx, 6, 3) glayout.addWidget(QLabel('translate Y'), 6, 4, Qt.AlignRight) glayout.addWidget(self.dy, 6, 5) glayout.addWidget(QLabel('translate Z'), 6, 6, Qt.AlignRight) glayout.addWidget(self.dz, 6, 7) vlayout.addLayout(glayout) mainLayout.addLayout(vlayout) mainLayout.setAlignment(vlayout, Qt.AlignTop) mainLayout.addItem(QSpacerItem(10, 20)) vlayout = QVBoxLayout() lb = QLabel('<b>Transformation from %s to %s<b>' % (to_label, from_label)) vlayout.addWidget(lb) vlayout.setAlignment(lb, Qt.AlignHCenter) vlayout.addItem(QSpacerItem(10, 10)) glayout = QGridLayout() glayout.addWidget(QLabel('<b>Rotation<b>'), 1, 1) glayout.addWidget(QLabel('angle (rad)'), 2, 2, Qt.AlignRight) glayout.addWidget(self.inv_angle, 2, 3) glayout.addWidget(QLabel('<b>Scaling<b>'), 3, 1) glayout.addWidget(QLabel('XY factor'), 4, 2, Qt.AlignRight) glayout.addWidget(self.inv_scalexy, 4, 3) glayout.addWidget(QLabel('Z factor'), 4, 4, Qt.AlignRight) glayout.addWidget(self.inv_scalez, 4, 5) glayout.addWidget(QLabel('<b>Translation<b>'), 5, 1) glayout.addWidget(QLabel('translate X'), 6, 2, Qt.AlignRight) glayout.addWidget(self.inv_dx, 6, 3) glayout.addWidget(QLabel('translate Y'), 6, 4, Qt.AlignRight) glayout.addWidget(self.inv_dy, 6, 5) glayout.addWidget(QLabel('translate Z'), 6, 6, Qt.AlignRight) glayout.addWidget(self.inv_dz, 6, 7) vlayout.addLayout(glayout) mainLayout.addLayout(vlayout) mainLayout.setAlignment(vlayout, Qt.AlignTop) mainLayout.addItem(QSpacerItem(50, 20)) mainLayout.addWidget(deleteButton, Qt.AlignLeft) mainLayout.addItem(QSpacerItem(50, 20)) mainLayout.addWidget(buttons) self.setLayout(mainLayout) self.setWindowTitle('Edit transformation') self.resize(self.sizeHint()) def edit_dx(self): try: _ = float(self.dx.text()) self.update() except ValueError: self.dx.setText(str(self.trans.translation.dx)) def edit_dy(self): try: _ = float(self.dy.text()) self.update() except ValueError: self.dy.setText(str(self.trans.translation.dy)) def edit_dz(self): try: _ = float(self.dz.text()) self.update() except ValueError: self.dz.setText(str(self.trans.translation.dz)) def edit_angle(self): try: _ = float(self.angle.text()) self.update() except ValueError: self.angle.setText(str(self.trans.rotation.angle)) def edit_scalexy(self): try: scalexy = float(self.scalexy.text()) if scalexy == 0: self.scalexy.setText(str(self.trans.scaling.horizontal_factor)) else: self.update() except ValueError: self.scalexy.setText(str(self.trans.scaling.horizontal_factor)) def edit_scalez(self): try: scalez = float(self.scalez.text()) if scalez == 0: self.scalez.setText(str(self.trans.scaling.vertical_factor)) else: self.update() except ValueError: self.scalez.setText(str(self.trans.scaling.vertical_factor)) def edit_inv_dx(self): try: _ = float(self.inv_dx.text()) self.update_inverse() except ValueError: self.inv_dx.setText(str(self.inverse_trans.translation.dx)) def edit_inv_dy(self): try: _ = float(self.inv_dy.text()) self.update_inverse() except ValueError: self.inv_dy.setText(str(self.inverse_trans.translation.dy)) def edit_inv_dz(self): try: _ = float(self.inv_dz.text()) self.update_inverse() except ValueError: self.inv_dz.setText(str(self.inverse_trans.translation.dz)) def edit_inv_angle(self): try: _ = float(self.inv_angle.text()) self.update_inverse() except ValueError: self.inv_angle.setText(str(self.inverse_trans.rotation.angle)) def edit_inv_scalexy(self): try: scalexy = float(self.inv_scalexy.text()) if scalexy == 0: self.inv_scalexy.setText( str(self.inverse_trans.scaling.horizontal_factor)) else: self.update_inverse() except ValueError: self.inv_scalexy.setText( str(self.inverse_trans.scaling.horizontal_factor)) def edit_inv_scalez(self): try: scalez = float(self.inv_scalez.text()) if scalez == 0: self.inv_scalez.setText( str(self.inverse_trans.scaling.vertical_factor)) else: self.update_inverse() except ValueError: self.inv_scalez.setText( str(self.inverse_trans.scaling.vertical_factor)) def update(self): angle, scalexy, scalez, dx, dy, dz = map(float, [ box.text() for box in [self.angle, self.scalexy, self.scalez, self.dx, self.dy, self.dz] ]) self.trans = Transformation(angle, scalexy, scalez, dx, dy, dz) self.inverse_trans = self.trans.inverse() self.inv_dx.setText(str(self.inverse_trans.translation.dx)) self.inv_dy.setText(str(self.inverse_trans.translation.dy)) self.inv_dz.setText(str(self.inverse_trans.translation.dz)) self.inv_angle.setText(str(self.inverse_trans.rotation.angle)) self.inv_scalexy.setText( str(self.inverse_trans.scaling.horizontal_factor)) self.inv_scalez.setText(str( self.inverse_trans.scaling.vertical_factor)) def update_inverse(self): angle, scalexy, scalez, dx, dy, dz = map(float, [ box.text() for box in [ self.inv_angle, self.inv_scalexy, self.inv_scalez, self.inv_dx, self.inv_dy, self.inv_dz ] ]) self.inverse_trans = Transformation(angle, scalexy, scalez, dx, dy, dz) self.trans = self.inverse_trans.inverse() self.dx.setText(str(self.trans.translation.dx)) self.dy.setText(str(self.trans.translation.dy)) self.dz.setText(str(self.trans.translation.dz)) self.angle.setText(str(self.trans.rotation.angle)) self.scalexy.setText(str(self.trans.scaling.horizontal_factor)) self.scalez.setText(str(self.trans.scaling.vertical_factor)) def deleteEvent(self): msg = QMessageBox.warning( None, 'Confirm delete', 'Do you want to delete this transformation?', QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if msg == QMessageBox.Cancel: return self.deleted = True self.reject()