def _straight_job(pipe, srcs, recs, cells, velocity, prop): if _cttime2d is not None: x_src, y_src = numpy.transpose(srcs).astype(numpy.float) x_rec, y_rec = numpy.transpose(recs).astype(numpy.float) times = _cttime2d.straight(x_src, y_src, x_rec, y_rec, len(srcs), cells, velocity, prop) else: times = _straight(cells, prop, srcs, recs, velocity) pipe.send(times) pipe.close()
def straight(cells, prop, srcs, recs, velocity=None, par=False): """ Calculate the travel times inside a mesh of square cells between source and receiver pairs assuming the rays are straight lines (no refraction or reflection). .. note:: Don't care about the units as long they are compatible. For a homogeneous model, *cells* can be a list with only one big cell. Parameters: * cells : list of :func:`fatiando.mesher.Square` The velocity model to use to trace the straight rays. Cells must have the physical property given in parameter *prop*. This will be used as the velocity of each cell. (*cells* can also be a :class:`~fatiando.mesher.SquareMesh`) * prop : str Which physical property of the cells to use as velocity. Normaly one would choose ``'vp'`` or ``'vs'`` * srcs : list fo lists List with [x, y] coordinate pairs of the wave sources. * recs : list fo lists List with [x, y] coordinate pairs of the receivers sources * velocity : float or None If not None, will use this value instead of the prop of cells as the velocity. Useful when building sensitivity matrices (use velocity = 1). * par : True or False If True, will run the calculations in parallel using all the cores available. Not recommended for Jacobian matrix building! *srcs* and *recs* are lists of source-receiver pairs. Each source in *srcs* is associated with the corresponding receiver in *recs* for a given travel time. For example:: >>> # One source was recorded at 3 receivers. >>> # The medium is homogeneous and can be >>> # represented by a single Square >>> from fatiando.mesher import Square >>> cells = [Square([0, 10, 0, 10], {'vp':2})] >>> src = (5, 0) >>> srcs = [src, src, src] >>> recs = [(0, 0), (5, 10), (10, 0)] >>> print straight(cells, 'vp', srcs, recs) [ 2.5 5. 2.5] Returns: * times : array The total times each ray took to get from a source to a receiver (in compatible units with *prop*) """ if len(srcs) != len(recs): raise ValueError("Must have the same number of sources and receivers") if not par: if _cttime2d is not None: x_src, y_src = numpy.transpose(srcs).astype(numpy.float) x_rec, y_rec = numpy.transpose(recs).astype(numpy.float) times = _cttime2d.straight(x_src, y_src, x_rec, y_rec, len(srcs), cells, velocity, prop) else: times = _straight(cells, prop, srcs, recs, velocity) return times # Divide the workload into jobs and run them in different processes jobs = multiprocessing.cpu_count() start = 0 size = len(srcs) perjob = size/jobs processes = [] pipes = [] for i in xrange(jobs): if i == jobs - 1: end = size else: end = start + perjob outpipe, inpipe = multiprocessing.Pipe() args = (inpipe, srcs[start:end], recs[start:end], cells, velocity, prop) proc = multiprocessing.Process(target=_straight_job, args=args) proc.start() processes.append(proc) pipes.append(outpipe) start = end times = [] for proc, pipe in zip(processes, pipes): times.extend(pipe.recv()) proc.join() return numpy.array(times)
def straight(cells, prop, srcs, recs, velocity=None, par=False): """ Calculate the travel times inside a mesh of square cells between source and receiver pairs assuming the rays are straight lines (no refraction or reflection). .. note:: Don't care about the units as long they are compatible. For a homogeneous model, *cells* can be a list with only one big cell. Parameters: * cells : list of :func:`fatiando.mesher.Square` The velocity model to use to trace the straight rays. Cells must have the physical property given in parameter *prop*. This will be used as the velocity of each cell. (*cells* can also be a :class:`~fatiando.mesher.SquareMesh`) * prop : str Which physical property of the cells to use as velocity. Normaly one would choose ``'vp'`` or ``'vs'`` * srcs : list fo lists List with [x, y] coordinate pairs of the wave sources. * recs : list fo lists List with [x, y] coordinate pairs of the receivers sources * velocity : float or None If not None, will use this value instead of the prop of cells as the velocity. Useful when building sensitivity matrices (use velocity = 1). * par : True or False If True, will run the calculations in parallel using all the cores available. Not recommended for Jacobian matrix building! *srcs* and *recs* are lists of source-receiver pairs. Each source in *srcs* is associated with the corresponding receiver in *recs* for a given travel time. For example:: >>> # One source was recorded at 3 receivers. >>> # The medium is homogeneous and can be >>> # represented by a single Square >>> from fatiando.mesher import Square >>> cells = [Square([0, 10, 0, 10], {'vp':2})] >>> src = (5, 0) >>> srcs = [src, src, src] >>> recs = [(0, 0), (5, 10), (10, 0)] >>> print straight(cells, 'vp', srcs, recs) [ 2.5 5. 2.5] Returns: * times : array The total times each ray took to get from a source to a receiver (in compatible units with *prop*) """ if len(srcs) != len(recs): raise ValueError("Must have the same number of sources and receivers") if not par: if _cttime2d is not None: x_src, y_src = numpy.transpose(srcs).astype(numpy.float) x_rec, y_rec = numpy.transpose(recs).astype(numpy.float) times = _cttime2d.straight(x_src, y_src, x_rec, y_rec, len(srcs), cells, velocity, prop) else: times = _straight(cells, prop, srcs, recs, velocity) return times # Divide the workload into jobs and run them in different processes jobs = multiprocessing.cpu_count() start = 0 size = len(srcs) perjob = size / jobs processes = [] pipes = [] for i in xrange(jobs): if i == jobs - 1: end = size else: end = start + perjob outpipe, inpipe = multiprocessing.Pipe() args = (inpipe, srcs[start:end], recs[start:end], cells, velocity, prop) proc = multiprocessing.Process(target=_straight_job, args=args) proc.start() processes.append(proc) pipes.append(outpipe) start = end times = [] for proc, pipe in zip(processes, pipes): times.extend(pipe.recv()) proc.join() return numpy.array(times)