def saveImage(menuitem, image, filename, format, mode): immidge = oofimage.getImage(image) if immidge and (mode == "w" or not os.path.exists(filename)): if config.dimension() == 3: # A separate file will be stored for each slice. The # filename must contain '%i', which will be replaced by an # integer to differentiate the slices. If the given name # doesn't contain '%i', '_%i' will be appended to it. If # the given name looks like "name.suffix", the new name # will be "name_%i.suffix". path, fname = os.path.split(filename) if "%i" not in fname: if not os.path.exists(path): os.makedirs(path) fn = fname.rsplit(".", 1) if len(fn) > 1: fname = fn[0] + "_%i." + fn[1] # filename = path + "/" + fn[0] + "_%i." + fn[1] else: fname = fn[0] + "_i" # filename = path + "/" + filename + "_%i" filename = os.path.join(path, fname) immidge.save(filename, format.string()) else: reporter.warn("Image was not saved!")
def getBase(self, registration): # Get the original value of the parameter, in base form, # and store it so you can pass it to widgets for other representations. try: self.base_value = registration.getParamValuesAsBase() except ValueError, exc: reporter.warn(exc)
def delete(self, name): reg = self.data[name].object if hasattr(reg, "parent"): self.materialmanager.delete_prop(name) reg.unregister() self.data.delete(name) else: reporter.warn("Predefined properties cannot be deleted!")
def readfile(self, filename, prog, z=0): tslfile = file(filename, "r") prog.setMessage("Reading " + filename) count = 1 # line counter lines = tslfile.readlines() nlines = len(lines) data = utils.ReservableList(nlines) angletype = None for line in lines: if line[0] == '#': if line.startswith("Column 1-3", 2): if "radians" in line: angletype = "radians" else: angletype = "degrees" debug.fmsg("Angles are in %s." % angletype) else: # line[0] != '#' substrings = line.split() if len(substrings) < 5: raise ooferror.ErrUserError( "Too few numbers in line %d of %s" % (count, filename)) values = map(float, substrings[:5]) if angletype == "radians": angles = values[:3] elif angletype == "degrees": angles = map(math.radians, values[:3]) else: raise ooferror.ErrDataFileError( "Angle type not specified in TSL data file") orientation = corientation.COrientBunge(*angles) if config.dimension() == 2: point = primitives.Point(values[3], values[4]) elif config.dimension() == 3: point = primitives.Point(values[3], values[4], z) data.append(DataPoint(point, # position angles, ' '.join(substrings[10:]))) # phase name count += 1 # count actual file lines, comments and all prog.setMessage("read %d/%d lines" % (count, nlines)) prog.setFraction(float(count)/nlines) npts = len(data) debug.fmsg("read %d lines, %d data points" % (count, npts)) # We don't yet know if the points are on a rectangular or a # hexagonal lattice, so split the data up into rows. # getrows() is a generator, but we need an actual list so that # we can index into it. rows = list(getrows(data)) if len(rows) < 2: raise ooferror.ErrUserError( "Orientation map data has too few rows.") if rows[0][0].position[0] != rows[1][0].position[0]: # Must be a hexagonal lattice. Throw out every other row. reporter.warn("Converting hexagonal lattice to rectangular by discarding alternate rows.") rows = rows[::2] # discard odd numbered rows return rows, npts
def profile_start(menuitem, filename, fudge): global prof ## import hotshot ## prof = hotshot.Profile(filename) ## prof.start() if thread_enable.enabled(): reporter.warn("Multithreaded profiling is unreliable!\nUse the --unthreaded startup option.") from ooflib.common.EXTRA import profiler prof = profiler.Profiler(filename, fudge=fudge)
def _modify(menuitem, skeleton, modifier): context = skeletoncontext.skeletonContexts[skeleton] context.reserve() start_nnodes = context.getObject().nnodes() start_nelems = context.getObject().nelements() try: context.begin_writing() cdebug.ProfilerStart("mod.prof") try: skel = modifier.apply(context.getObject()) ## skel is None whenever the modifier fails ## or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") return context.pushModification(skel) skel.needsHash() finally: context.end_writing() ## If the skeleton is modified in postProcess, use ## begin/end_writing inside the function call to guarantee ## that no dead-locking occurs because of possible switchboard ## calls that may make use of begin/end_reading(). See ## cfiddlenodes.spy for an example. modifier.postProcess(context) modifier.cleanUp() cdebug.ProfilerStop() skel.incrementTimestamp() end_nnodes = context.getObject().nnodes() end_nelems = context.getObject().nelements() if end_nnodes > start_nnodes: reporter.report(end_nnodes - start_nnodes, "more nodes.") elif end_nnodes < start_nnodes: reporter.report(start_nnodes - end_nnodes, "fewer nodes.") if end_nelems > start_nelems: reporter.report(end_nelems - start_nelems, "more elements.") elif end_nelems < start_nelems: reporter.report(start_nelems - end_nelems, "fewer elements.") finally: context.cancel_reservation() # "Skeleton modified" indicates that a specific modifier has been # applied. "Skeleton changed" indicates that something has # changed, which might or might not have involved a # SkeletonModifier. "Skeleton changed" is not redundant with "who # changed", because "who changed" is issued by pushModification # before postProcess is called, and postProcess might do most of # the work in a SkeletonModifier. ## TODO OPT: Some modifiers send these notifications in ## postProcess. Don't send them again here. switchboard.notify('Skeleton modified', skeleton, modifier) switchboard.notify('Skeleton changed', skeleton) switchboard.notify('redraw')
def optionCB(self, widget, regname): if self.currentOption is not None: if self.paramWidget is not None: # If there is a current option and a current widget, # copy the values into the parameters. self.paramWidget.get_values() self.paramWidget.destroy() # Retrieve the current value of the outgoing option. try: old = self.getParamValues() got_old = True except ValueError, exc: reporter.warn(exc) got_old = False
def _ops_callback(menuitem, mesh, time, data, domain, sampling, destination, **kwargs): if parallel_enable.enabled(): menuitem.ipcmenu(mesh=mesh, data=data, domain=domain, sampling=sampling, destination=destination) return operation = menuitem.data() # data is a DataOperation Registration direct = getattr(menuitem.data, 'direct', False) if not (direct or data.allowsArithmetic()): raise ooferror2.ErrUserError("Output '" + data.name + "' can only be used with Direct output") # Set the mesh in the domain, then run the operation. domain.set_mesh(mesh) domain.read_lock() # acquires Mesh's read lock. try: # The domain has all the mesh data, so we don't have to pass that data. meshctxt = ooflib.engine.mesh.meshes[mesh] meshctxt.precompute_all_subproblems() t = meshctxt.getTime(time) # converts '<latest>' to time, if needed meshctxt.restoreCachedData(t) destination.open() try: if sampling.make_samples(domain): printHeaders(destination, operation, data, domain, sampling) # Do the calculation operation(t, data, domain, sampling, destination) else: reporter.warn("Analysis domain is empty! No output produced.") finally: meshctxt.releaseCachedData() destination.close() finally: domain.read_release() # domain holds a reference to the mesh, and since it's a # Parameter value, the command history holds a reference to # domain. We need to clear the mesh reference so that the # mesh can be destroyed when everybody else is done with it. domain.set_mesh(None) sampling.clearSamples()
def _modify(menuitem, skeleton, modifier): # context is actually the Who of the skeleton context = skeletoncontext.skeletonContexts[skeleton] context.reserve() start_nnodes = context.getObject().nnodes() start_nelems = context.getObject().nelements() try: context.begin_writing() try: skel = modifier.apply(context.getObject(), context) # skel is None whenever the modifier fails # or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") return context.pushModification(skel) # parallelized skel.needsHash() finally: context.end_writing() # If the skeleton is modified in postProcess, use # begin/end_writing inside the function call to guarantee # that no dead-locking occurs because of possible switchboard # calls to READ or REDRAW that may make use of # begin/end_reading(). See anneal.py for an example. modifier.postProcess(context) # parallelize for each modifier skel.updateGeometry() # force recalculation of homogeneity, etc end_nnodes = context.getObject().nnodes() end_nelems = context.getObject().nelements() if end_nnodes > start_nnodes: reporter.report(end_nnodes - start_nnodes, "more nodes.") elif end_nnodes < start_nnodes: reporter.report(start_nnodes - end_nnodes, "fewer nodes.") if end_nelems > start_nelems: reporter.report(end_nelems - start_nelems, "more elements.") elif end_nelems < start_nelems: reporter.report(start_nelems - end_nelems, "fewer elements.") finally: context.cancel_reservation() switchboard.notify('redraw') switchboard.notify('Skeleton modified', skeleton, modifier)
def _modify(menuitem, skeleton, modifier): # context is actually the Who of the skeleton context = skeletoncontext.skeletonContexts[skeleton] context.reserve() start_nnodes = context.getObject().nnodes() start_nelems = context.getObject().nelements() try: context.begin_writing() try: skel = modifier.apply(context.getObject(), context) # skel is None whenever the modifier fails # or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") return context.pushModification(skel) # parallelized skel.needsHash() finally: context.end_writing() # If the skeleton is modified in postProcess, use # begin/end_writing inside the function call to guarantee # that no dead-locking occurs because of possible switchboard # calls to READ or REDRAW that may make use of # begin/end_reading(). See anneal.py for an example. modifier.postProcess(context) # parallelize for each modifier end_nnodes = context.getObject().nnodes() end_nelems = context.getObject().nelements() if end_nnodes > start_nnodes: reporter.report(end_nnodes - start_nnodes, "more nodes.") elif end_nnodes < start_nnodes: reporter.report(start_nnodes - end_nnodes, "fewer nodes.") if end_nelems > start_nelems: reporter.report(end_nelems - start_nelems, "more elements.") elif end_nelems < start_nelems: reporter.report(start_nelems - end_nelems, "fewer elements.") finally: context.cancel_reservation() switchboard.notify("redraw") switchboard.notify("Skeleton modified", skeleton, modifier)
def apply(self, oldskeleton, context): #skel = oldskeleton.properCopy(skeletonpath=context.path()) # vigilante doesn't really need a properCopy! skel = oldskeleton.deputyCopy() skel.activate() suckers = skel.illegalElements() # illegalset holds the elements to be checked. It is # initially set to the illegal elements in the unmodified # skeleton, but new element can be added to it if moving one # node fixes two elements and breaks one. illegalset = set() for el in suckers: illegalset.add(el) random.shuffle(suckers) nguilty = len(suckers) # arbitrary number just to keep us out of an infinite loop max = 222 count = 0 while illegalset and count < max: count += 1 self.smoothIllegalElements(skel, illegalset, suckers) ndone = nguilty - len(illegalset) if illegalset: reporter.warn("Could not remove all illegal elements!") reporter.report("%d illegal element%s removed." % (ndone, "s" * (ndone != 1))) ## TODO: There are cases in which this doesn't work, that ## could be solved by moving a node *towards* the average ## position of its neighbors, but not all the way. Try moving ## problem nodes until their elements become barely legal. skel.cleanUp() skel.checkIllegality() return skel
def apply(self, oldskeleton, context): # skel = oldskeleton.properCopy(skeletonpath=context.path()) # vigilante doesn't really need a properCopy! skel = oldskeleton.deputyCopy() skel.activate() suckers = skel.illegalElements() # illegalset holds the elements to be checked. It is # initially set to the illegal elements in the unmodified # skeleton, but new element can be added to it if moving one # node fixes two elements and breaks one. illegalset = set() for el in suckers: illegalset.add(el) random.shuffle(suckers) nguilty = len(suckers) # arbitrary number just to keep us out of an infinite loop max = 222 count = 0 while illegalset and count < max: count += 1 self.smoothIllegalElements(skel, illegalset, suckers) ndone = nguilty - len(illegalset) if illegalset: reporter.warn("Could not remove all illegal elements!") reporter.report("%d illegal element%s removed." % (ndone, "s" * (ndone != 1))) ## TODO: There are cases in which this doesn't work, that ## could be solved by moving a node *towards* the average ## position of its neighbors, but not all the way. Try moving ## problem nodes until their elements become barely legal. skel.cleanUp() skel.checkIllegality() return skel
def _read(self, datafile, prog): # readData gets data from the file, but does no processing data = self.readData(datafile, prog) rows = list(getrows(data)) # sorts data # The grid is hexagonal if the first two rows don't start at the same x. if rows[0][0].position[0] != rows[1][0].position[0]: # Throw out every other row. reporter.warn("Converting hexagonal lattice to rectangular" " by discarding alternate rows.") rows = rows[::2] # discard odd numbered rows # Check that all rows are the same length, and flip the # coordinates if requested. nx = len(rows[0]) ny = len(rows) ymax = rows[-1][0].position[1] ymin = rows[0][0].position[1] xmax = rows[0][-1].position[0] xmin = rows[0][0].position[0] count = 0 for row in rows: count += 1 if len(row) != nx: raise ooferror.ErrUserError( "Orientation map data appears to be incomplete.\n" "len(row 0)=%d len(row %d)=%d" % (nx, count, len(row))) for point in row: if self.flip_x: point.position[0] = xmax - point.position[0] else: point.position[0] = point.position[0] - xmin if self.flip_y: point.position[1] = ymax - point.position[1] else: point.position[1] = point.position[1] - ymin # pixel size dx = abs(rows[0][1].position[0] - rows[0][0].position[0]) dy = abs(rows[0][0].position[1] - rows[1][0].position[1]) pxlsize = primitives.Point(dx, dy) width = abs(rows[0][0].position[0] - rows[0][-1].position[0]) height = abs(rows[0][0].position[1] - rows[-1][0].position[1]) # If we assume that the points are in the centers of the # pixels, then the actual physical size is one pixel bigger # than the range of the xy values. size = primitives.Point(width, height) + pxlsize npts = len(rows) * len(rows[0]) od = orientmapdata.OrientMap(primitives.iPoint(nx, ny), size * self.scale_factor) prog.setMessage("%d/%d orientations" % (0, npts)) count = 0 for row in rows: for datum in row: ij = primitives.iPoint( int(round(datum.position[0] / pxlsize[0])), int(round(datum.position[1] / pxlsize[1]))) for groupname in datum.groups: try: self.groupmembers[groupname].append(ij) except KeyError: self.groupmembers[groupname] = [ij] if self.angle_units == 'Degrees': offset = math.radians(self.angle_offset) angleargs = datum.angletuple else: # angle units are Radians offset = self.angle_offset # All Orientation subclasses that take angle args # assume that they're in degrees. They have a # static radians2Degrees method that converts the # angle args from radians to degrees. angleargs = self.angle_type.radians2Degrees( *datum.angletuple) # Create an instance of the Orientation subclass. orient = self.angle_type(*angleargs) if self.angle_offset != 0: orient = orient.rotateXY(self.angle_offset) # Insert this point into the OrientMap object. self.set_angle(od, ij, orient.corient) prog.setMessage("%d/%d orientations" % (count, npts)) prog.setFraction(float(count) / npts) count += 1 if prog.stopped(): return None return od
def _warning(menuitem): reporter.warn("You'd better be home by 11, young lady!")
def saveImage(menuitem, image, filename, overwrite): immidge = oofimage.getImage(image) if immidge and (overwrite or not os.path.exists(filename)): immidge.save(filename) else: reporter.warn("Image was not saved!")
def _modify(menuitem, skeleton, modifier): global _rank if _rank == 0: ModifyProgressBar = menuitem.getProgressBar(modifier.get_progressbar_type()) context = skeletoncontext.skeletonContexts[skeleton] context.reserve() try: context.begin_writing() try: if _rank == 0: reporter.start_progressbar() skel = modifier.apply_parallel(context.getObject(), context) if _rank == 0: reporter.progressbar_completed() reporter.end_progressbar() # skel is None whenever the modifier fails # or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") # return will force all the finally's to be executed return mpitools.Barrier() context.pushModification(skel) skel.needsHash() finally: context.end_writing() if _rank == 0: reporter.start_progressbar() mpitools.Barrier() modifier.postProcess_parallel(context) if _rank == 0: reporter.progressbar_completed() reporter.end_progressbar() # If the skeleton is modified in postProcess, use # begin/end_writing inside the function call to guarantee # that no dead-locking occurs because of possible switchboard # calls to READ or REDRAW that may make use of # begin/end_reading(). See anneal.py for an example. finally: # guarantee that the reservation is cancelled even if an # exception is raised context.cancel_reservation() if _rank == 0: if ModifyProgressBar.query_stop() or ModifyProgressBar.get_success() < 0: ModifyProgressBar.set_failure() ModifyProgressBar.set_message("Failed") return else: ModifyProgressBar.set_success() ModifyProgressBar.set_message("Succeeded") switchboard.notify("redraw") switchboard.notify("Skeleton modified", skeleton, modifier)
def _assignMat(menuitem, mesh, elements, material): reporter.warn( "Explicit material assignments to mesh elements are no longer supported!" )
def _read(self, datafile, prog): # readData gets data from the file, but does no processing data = self.readData(datafile, prog) rows = list(getrows(data)) # sorts data # The grid is hexagonal if the first two rows don't start at the same x. if rows[0][0].position[0] != rows[1][0].position[0]: # Throw out every other row. reporter.warn( "Converting hexagonal lattice to rectangular" " by discarding alternate rows.") rows = rows[::2] # discard odd numbered rows # Check that all rows are the same length, and flip the # coordinates if requested. nx = len(rows[0]) ny = len(rows) ymax = rows[-1][0].position[1] ymin = rows[0][0].position[1] xmax = rows[0][-1].position[0] xmin = rows[0][0].position[0] count = 0 for row in rows: count += 1 if len(row) != nx: raise ooferror.ErrUserError( "Orientation map data appears to be incomplete.\n" "len(row 0)=%d len(row %d)=%d" % (nx, count, len(row))) for point in row: if self.flip_x: point.position[0] = xmax - point.position[0] else: point.position[0] = point.position[0] - xmin if self.flip_y: point.position[1] = ymax - point.position[1] else: point.position[1] = point.position[1] - ymin # pixel size dx = abs(rows[0][1].position[0] - rows[0][0].position[0]) dy = abs(rows[0][0].position[1] - rows[1][0].position[1]) pxlsize = primitives.Point(dx, dy) width = abs(rows[0][0].position[0] - rows[0][-1].position[0]) height = abs(rows[0][0].position[1] - rows[-1][0].position[1]) # If we assume that the points are in the centers of the # pixels, then the actual physical size is one pixel bigger # than the range of the xy values. size = primitives.Point(width, height) + pxlsize npts = len(rows)*len(rows[0]) od = orientmapdata.OrientMap(primitives.iPoint(nx, ny), size*self.scale_factor) prog.setMessage("%d/%d orientations" % (0, npts)) count = 0 for row in rows: for datum in row: ij = primitives.iPoint( int(round(datum.position[0]/pxlsize[0])), int(round(datum.position[1]/pxlsize[1]))) for groupname in datum.groups: try: self.groupmembers[groupname].append(ij) except KeyError: self.groupmembers[groupname] = [ij] if self.angle_units == 'Degrees': offset = math.radians(self.angle_offset) angleargs = datum.angletuple else: # angle units are Radians offset = self.angle_offset # All Orientation subclasses that take angle args # assume that they're in degrees. They have a # static radians2Degrees method that converts the # angle args from radians to degrees. angleargs = self.angle_type.radians2Degrees( *datum.angletuple) # Create an instance of the Orientation subclass. orient = self.angle_type(*angleargs) if self.angle_offset != 0: orient = orient.rotateXY(self.angle_offset) # Insert this point into the OrientMap object. self.set_angle(od, ij, orient.corient) prog.setMessage("%d/%d orientations" % (count, npts)) prog.setFraction(float(count)/npts) count += 1 if prog.stopped(): return None return od
def _assigninterfacemat(menuitem, microstructure, material, skeleton, interfaces): reporter.warn( "Interface Materials are not supported in this version of OOF2.")
def _assigninterfacemat(menuitem, microstructure, material, skeleton,interfaces): reporter.warn( "Interface Materials are not supported in this version of OOF2.")
def _read(self, tslfile, prog): data, hexgrid = self.readData(tslfile, prog) npts = len(data) rows = list(getrows(data)) # sorts data if hexgrid is None: # readData didn't set hexgrid. The grid is hexagonal if # the first two rows don't start at the same x. hexgrid = rows[0][0].position[0] != rows[1][0].position[0] if hexgrid: # Throw out every other row. reporter.warn( "Converting hexagonal lattice to rectangular" " by discarding alternate rows.") rows = rows[::2] # discard odd numbered rows nx = len(rows[0]) ny = len(rows) count = 0 for row in rows: count += 1 if len(row) != nx: raise ooferror.ErrUserError( "Orientation map data appears to be incomplete.\n" "len(row 0)=%d len(row %d)=%d" % (nx, count, len(row))) # TSL puts the origin at the top left, so it's using a left # handed coordinate system! If flip_y==True, fix that. Also, # make sure there are no negative x or y values. ymax = rows[-1][0].position[1] ymin = rows[0][0].position[1] xmax = rows[0][-1].position[0] xmin = rows[0][0].position[0] for row in rows: for point in row: if self.flip_x: point.position[0] = xmax - point.position[0] else: point.position[0] = point.position[0] - xmin if self.flip_y: point.position[1] = ymax - point.position[1] else: point.position[1] = point.position[1] - ymin # If flipped, the rows are still ordered top to bottom, but # the coordinates increase bottom to top. # pixel size dx = abs(rows[0][1].position[0] - rows[0][0].position[0]) dy = abs(rows[0][0].position[1] - rows[1][0].position[1]) pxlsize = primitives.Point(dx, dy) width = abs(rows[0][0].position[0] - rows[0][-1].position[0]) height = abs(rows[0][0].position[1] - rows[-1][0].position[1]) # If we assume that the points are in the centers of the # pixels, then the actual physical size is one pixel bigger # than the range of the xy values. size = primitives.Point(width, height) + pxlsize od = orientmapdata.OrientMap(primitives.iPoint(nx, ny), size) prog.setMessage("%d/%d orientations" % (0, npts)) count = 0 for row in rows: for datum in row: ij = primitives.iPoint( int(round(datum.position[0]/pxlsize[0])), int(round(datum.position[1]/pxlsize[1]))) try: self.phaselists[datum.phasename].append(ij) except KeyError: self.phaselists[datum.phasename] = [ij] self.set_angle(od, ij, datum.euler()) prog.setMessage("%d/%d orientations" % (count,npts)) prog.setFraction(float(count)/npts) count += 1 if prog.stopped(): return None prog.finish() return od
def _modify(menuitem, skeleton, modifier): global _rank if _rank == 0: ModifyProgressBar = menuitem.getProgressBar( modifier.get_progressbar_type()) context = skeletoncontext.skeletonContexts[skeleton] context.reserve() try: context.begin_writing() try: if _rank == 0: reporter.start_progressbar() skel = modifier.apply_parallel(context.getObject(), context) if _rank == 0: reporter.progressbar_completed() reporter.end_progressbar() # skel is None whenever the modifier fails # or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") # return will force all the finally's to be executed return mpitools.Barrier() context.pushModification(skel) skel.needsHash() finally: context.end_writing() if _rank == 0: reporter.start_progressbar() mpitools.Barrier() modifier.postProcess_parallel(context) if _rank == 0: reporter.progressbar_completed() reporter.end_progressbar() # If the skeleton is modified in postProcess, use # begin/end_writing inside the function call to guarantee # that no dead-locking occurs because of possible switchboard # calls to READ or REDRAW that may make use of # begin/end_reading(). See anneal.py for an example. finally: # guarantee that the reservation is cancelled even if an # exception is raised context.cancel_reservation() if _rank == 0: if ModifyProgressBar.query_stop() or \ ModifyProgressBar.get_success()<0: ModifyProgressBar.set_failure() ModifyProgressBar.set_message("Failed") return else: ModifyProgressBar.set_success() ModifyProgressBar.set_message("Succeeded") switchboard.notify('redraw') switchboard.notify('Skeleton modified', skeleton, modifier)
def _read(self, tslfile, prog): data, hexgrid = self.readData(tslfile, prog) npts = len(data) rows = list(getrows(data)) # sorts data if hexgrid is None: # readData didn't set hexgrid. The grid is hexagonal if # the first two rows don't start at the same x. hexgrid = rows[0][0].position[0] != rows[1][0].position[0] if hexgrid: # Throw out every other row. reporter.warn("Converting hexagonal lattice to rectangular" " by discarding alternate rows.") rows = rows[::2] # discard odd numbered rows nx = len(rows[0]) ny = len(rows) count = 0 for row in rows: count += 1 if len(row) != nx: raise ooferror.ErrUserError( "Orientation map data appears to be incomplete.\n" "len(row 0)=%d len(row %d)=%d" % (nx, count, len(row))) # TSL puts the origin at the top left, so it's using a left # handed coordinate system! If flip_y==True, fix that. Also, # make sure there are no negative x or y values. ymax = rows[-1][0].position[1] ymin = rows[0][0].position[1] xmax = rows[0][-1].position[0] xmin = rows[0][0].position[0] for row in rows: for point in row: if self.flip_x: point.position[0] = xmax - point.position[0] else: point.position[0] = point.position[0] - xmin if self.flip_y: point.position[1] = ymax - point.position[1] else: point.position[1] = point.position[1] - ymin # If flipped, the rows are still ordered top to bottom, but # the coordinates increase bottom to top. # pixel size dx = abs(rows[0][1].position[0] - rows[0][0].position[0]) dy = abs(rows[0][0].position[1] - rows[1][0].position[1]) pxlsize = primitives.Point(dx, dy) width = abs(rows[0][0].position[0] - rows[0][-1].position[0]) height = abs(rows[0][0].position[1] - rows[-1][0].position[1]) # If we assume that the points are in the centers of the # pixels, then the actual physical size is one pixel bigger # than the range of the xy values. size = primitives.Point(width, height) + pxlsize od = orientmapdata.OrientMap(primitives.iPoint(nx, ny), size) prog.setMessage("%d/%d orientations" % (0, npts)) count = 0 for row in rows: for datum in row: ij = primitives.iPoint( int(round(datum.position[0] / pxlsize[0])), int(round(datum.position[1] / pxlsize[1]))) try: self.phaselists[datum.phasename].append(ij) except KeyError: self.phaselists[datum.phasename] = [ij] self.set_angle(od, ij, datum.euler()) prog.setMessage("%d/%d orientations" % (count, npts)) prog.setFraction(float(count) / npts) count += 1 if prog.stopped(): return None prog.finish() return od