Exemple #1
0
def intersection_over_union(target, list_of_bboxes, xp):
    print list_of_bboxes.shape
    target = LinearRing(get_vertex(target))
    list_of_bboxes = [LinearRing(get_vertex(i)) for i in list_of_bboxes]
    areas = xp.zeros(len(list_of_bboxes))
    for index, item in enumerate(list_of_bboxes):
        vertex = []
        if target.intersects(item):
            if isinstance(target.intersection(item),Point):
                continue
            for ver in target.intersection(item):
                if isinstance(ver,LineString):
                    u, v = ver.xy
                    vertex.append([u[0], v[0]])
                    vertex.append([u[1], v[1]])
                else:
                    vertex.append([ver.x, ver.y])
            for ver in target.coords[:4]:
                if Point(ver).within(Polygon(item)):
                    vertex.append(list(ver))
            for ver in item.coords[:4]:
                if Point(ver).within(Polygon(target)):
                    vertex.append(list(ver))
            areas[index] = Polygon(PolygonSort(vertex)).area
    return areas
            def intersections(a, b):
                ea = LinearRing(a)
                eb = LinearRing(b)
                mp = ea.intersection(eb)

                x = [p.x for p in mp]
                y = [p.y for p in mp]
                return x, y
def ellipse_intersect(a, b, ret_points=False):
    ea = LinearRing(a)
    eb = LinearRing(b)
    mp = ea.intersection(eb)

    if ret_points:
        x = [p.x for p in mp]
        y = [p.y for p in mp]
        return x, y
    return bool(mp)
Exemple #4
0
def IoU(bbox_a,bbox_b):
    bbox_a = LinearRing(get_vertex(bbox_a))
    bbox_b = LinearRing(get_vertex(bbox_b))
    vertex = []
    if bbox_a.intersects(bbox_b):
        if isinstance(bbox_a.intersection(bbox_b),Point):
            return 0
        for ver in bbox_a.intersection(bbox_b):
            if isinstance(ver,LineString):
                u, v = ver.xy
                vertex.append([u[0], v[0]])
                vertex.append([u[1], v[1]])
            else:
                vertex.append([ver.x, ver.y])
        for ver in bbox_a.coords[:4]:
            if Point(ver).within(Polygon(bbox_b)):
                vertex.append(list(ver))
        for ver in bbox_b.coords[:4]:
            if Point(ver).within(Polygon(bbox_a)):
                vertex.append(list(ver))
        return Polygon(PolygonSort(vertex)).area
    return 0
Exemple #5
0
    def intersections(self, a, b):
        """check if two polylines are intersected

        Args:
            a (polyline): polyline a
            b (polyline): polyline b

        Returns:
            boolean: true if polylines are intersected
        """
        try:
            ea = LinearRing(a)
            eb = LinearRing(b)
            return ea.intersection(eb)
        except:
            return False
def ellipses_intersect(ellipse1, ellipse2):
    a, b = ellipse_polyline((ellipse1, ellipse2))
    ea = LinearRing(a)
    eb = LinearRing(b)
    mp = ea.intersection(eb)
    #encloses = ea.contains(eb)
    #encloses = ea.contains(Point(ellipse2[0], ellipse2[1]))
    pa = Polygon(a)
    pb = Polygon(b)
    encloses = pa.contains(pb)

    x = [p.x for p in mp]
    y = [p.y for p in mp]
    if len(x) > 0:
        intersects = True
    else:
        intersects =  False
    
    return intersects, encloses
def generate_scans_for_particles(pose):

    global obstacles

    theta_start = pose.z - 0.523599
    theta_stop = pose.z + 0.523599
    STEP_SIZE = 0.019652407

    steps = np.arange(theta_start, theta_stop, STEP_SIZE)
    steps = steps[::-1]
    scan = []
    distance = []

    for i in range(54):
        x = pose.x
        y = pose.y
        theta = steps[i]
        pose_temp = Pose(x, y, theta)
        pose_temp = compute_x_y(pose_temp)
        laser = (pose_temp.x + x, pose_temp.y + y)
        robot_pose = (pose.x, pose.y)
        possible_scans = []

        line = LineString([robot_pose, laser])
        for obstacle in obstacles:
            polygons = LinearRing(list(obstacle.exterior.coords))
            intersections = polygons.intersection(line)
            if intersections:
                if intersections.type == 'Point':
                    possible_scans.append((intersections.x, intersections.y))
                else:
                    for points in intersections:
                        if points:
                            possible_scans.append((points.x, points.y))

        x = compute_length(pose, possible_scans)
        #print(x)
        scan.append(x[0])
        distance.append(x[1])

    return distance
Exemple #8
0
def ellipse_polyline_intersection(ellipses, n=500):
    '''
    This function transfer an ellipse to ellipse_poluline and then check the intersections of two ellipses. It
    returns the intercetion coordinate 
    '''
    t = np.linspace(0, 2 * np.pi, n, endpoint=False)
    st = np.sin(t)
    ct = np.cos(t)
    result = []
    for x0, y0, a, b, angle, angle2 in ellipses:  #angle2: tangential direction of the ellilpse, not used in intersection expectation
        angle = np.deg2rad(angle)
        sa = np.sin(angle)
        ca = np.cos(angle)
        pointE = np.empty((n, 2))
        pointE[:, 0] = x0 + a * ca * ct - b * sa * st
        pointE[:, 1] = y0 + a * sa * ct + b * ca * st
        result.append(pointE)
    #ellipseA, ellipseB are the dots of two ellipse
    ellipseA = result[0]
    ellipseB = result[1]
    ea = LinearRing(ellipseA)
    eb = LinearRing(ellipseB)
    mp = ea.intersection(eb)
    #intersectionX, intersectionY are the intersections
    #if type(mp) == types.GeneratorType:
    # print(mp.geom_type)
    # print(mp)
    if mp.geom_type == 'Point':
        #print(mp.geom_type)
        #print(mp.x)
        return [mp.x], [mp.y]
    elif mp.geom_type == 'LineString':
        newmp = list(mp.coords)
        #print("newmp", newmp)
        intersectionX = [pE[0] for pE in newmp]
        intersectionY = [pE[1] for pE in newmp]
        return intersectionX, intersectionY
    else:
        intersectionX = [pE.x for pE in mp]
        intersectionY = [pE.y for pE in mp]
        return intersectionX, intersectionY
def plot_graph(robots, obstacles):
    # split the graph into subplots for plotting robots & obstacles on same graph
    fig, ax = plt.subplots()
    graph = nx.Graph()
    # nodes are labelled 0,1,...,n where n = number of robots
    nodes = range(len(robots))
    # edges map each node to every other node
    edges = list(itertools.product(nodes, nodes))
    # add all edges and nodes to graph
    graph.add_nodes_from(nodes, pos=robots)
    graph.add_edges_from(edges)
    nx.draw(graph, pos=robots)

    #plot obstacles
    for obstacle in obstacles:
        ring = LinearRing(obstacle)
        #calculate their intersections with any edges
        print(ring.intersection(LineString(edges)))
        x, y = ring.xy
        ax.plot(x, y)
    plt.show()
Exemple #10
0
    def find_background_grad(self, stars, ellipse_a=0.15, ellipticity=0.43,
                             clockrot=169.2, marker='o', markersize='1',
                             color='black', show_figure=False, binwidth=0.02, show_rotate=False):
        # same process carried out for c, m or agb stars, defined as argument
        self.stars = stars
        # default arguments for ngc205, reset here if m32 chosen
        if self.galaxy == 'm32':

            ellipticity = 0.14
            clockrot = 157.9
            ellipse_a = 0.1
        # choose appropriate dataset
        if stars == 'agb':

            data = self.data

        elif stars == 'm':

            data = self.mdata

        elif stars == 'c':

            data = self.cdata

        # galaxy stars inside defined ellipse masked
        e = selection_utils()

        dE_stars = e.select_ellipse(
            data, afl=ellipse_a, eccentricity=ellipticity, clockrot=clockrot, unselect=True)
        dE_ellipse = dE_stars[2]
        # only backgroud stars chosen
        data = dE_stars[0]

        # convert m31 coords to local tangent coords

        m31ra = 10.68470833
        m31dec = 41.26875

        if self.galaxy == 'ngc205':
            tra = 10.09189356
            tdec = 41.68541564
        elif self.galaxy == 'm32':
            tra = 10.6742708
            tdec = 40.8651694
        # m31 centre defined from centre of chosen galaxy
        m31xi, m31eta = self.eq_to_tan(m31ra, m31dec, tra, tdec)

        # find angle of rotation so that m31 gradient is on x axis
        theta = np.arctan((m31eta)/(m31xi))
        # xi and eta coordinates retrieved from data files
        xi = data.xi.copy()
        eta = data.eta.copy()

        # rotated coordinates constructed
        data['alpha'] = self.rotate_coords(xi, eta, theta)[0]
        data['beta'] = self.rotate_coords(xi, eta, theta)[1]
        if show_rotate == True:
            plt.figure()
            params = {'legend.fontsize': '12', 'axes.labelsize': '20',
                      'axes.titlesize': '12', 'xtick.labelsize': '10',
                      'ytick.labelsize': '10', 'lines.linewidth': 2, 'axes.linewidth': 2, 'animation.html': 'html5'}
            plt.rcParams.update(params)
            plt.rcParams.update({'figure.max_open_warning': 0})

            markersize = 3
            marker = 'o'
            plt.scatter(data['alpha'], data['beta'],
                        marker=marker, s=markersize)
            plt.xlabel(r'$\alpha$')
            plt.ylabel(r'$\beta$')
            plt.gca().invert_xaxis()
            plt.savefig(self.galaxy+'_rotated_coords')
            # m31 coordinates found in terms of alpha and beta
            # conversion from radians required for imported coordinates
        m31xi = np.degrees(m31xi)
        m31eta = np.degrees(m31eta)

        m31_alpha = self.rotate_coords(m31xi, m31eta, theta)[0]
        m31_beta = self.rotate_coords(m31xi, m31eta, theta)[1]

        # seaborn formatting set
        sns.set_context('paper')

        params = {'legend.fontsize': '12', 'axes.labelsize': '15',
                  'axes.titlesize': '12', 'xtick.labelsize': '10',
                  'ytick.labelsize': '10', 'lines.linewidth': 2, 'axes.linewidth': 2, 'animation.html': 'html5'}
        plt.rcParams.update(params)
        plt.rcParams.update({'figure.max_open_warning': 0})
        # plot image demonstrating rotation and new coordinate system
        # if chosen
        if show_figure == True:

            plt.plot(data.alpha, data.beta, marker=marker, markersize=markersize,
                     linestyle='none', color=color, label=self.galaxy.upper())
            if self.galaxy == 'm32':

                plt.xlim(0.3, -0.3)
                plt.ylim(-0.3, 0.3)

            else:

                plt.gca().invert_xaxis()
            plt.gca().set_ylabel(r'$\beta$ (degrees)')
            plt.gca().set_xlabel(r'$\alpha$ (degrees)')
        # define vertices of rotated set
        corner1 = np.array([np.min(data.xi), np.min(data.eta)])
        corner2 = np.array([np.min(data.xi), np.max(data.eta)])
        corner3 = np.array([np.max(data.xi), np.max(data.eta)])
        corner4 = np.array([np.max(data.xi), np.min(data.eta)])

        corners = [corner1, corner2, corner3, corner4]
        corners_rot = []
        for i in corners:

            corners_rot.append(self.rotate_coords(i[0], i[1], theta))
        # construct ring encircling dataset
        border = LinearRing(corners_rot)
        # create polygon containing all stars
        s = Polygon(border)
        corners_x = np.array(
            [corners_rot[0][0], corners_rot[1][0], corners_rot[2][0], corners_rot[3][0]])
        # define lower and upper bounds of set in alpha coordinates
        upper_bound = np.max(corners_x)-binwidth
        lower_bound = np.min(corners_x)

        # construct thin vertical bins

        bin_nums = []
        bin_areas = []
        bin_locs = []
        # define masked ellipse
        mask = dE_ellipse
        theta_deg = np.degrees(theta)
        # rotate galaxy masking ellipse for new coordinates
        # required to subtract bin and mask overlap regions
        mask = shapely.affinity.rotate(dE_ellipse, -theta_deg)
        # outer ellipse ring defined
        x, y = mask.exterior.xy
        # list to contain bin shapes
        bin_shapes = []
        # while loop to construct bins across whole alpha axis
        while upper_bound-lower_bound > binwidth:
            # bin width set by extended polygon of correct width
            bin_slice_fill = box(upper_bound-binwidth, -1.0, upper_bound, 1.0)
            # polygon changed to 1D line
            bin_slice = bin_slice_fill.exterior

            # find intercept to trim the vertical extent of bins
            bin_corners = border.intersection(bin_slice)
            # intersection points reordered for processing
            swap0 = bin_corners[0]
            swap1 = bin_corners[1]
            swap2 = bin_corners[3]
            swap3 = bin_corners[2]

            corners = [swap0, swap1, swap2, swap3]
            # intersection points represent vertices of final bin
            bin_corners = MultiPoint([swap0, swap1, swap2, swap3])
            # bin shape set as polygon
            final_bin = Polygon(bin_corners)
            # polygon added to list
            bin_shapes.append(final_bin)
            # bin exterior coordinates found
            x, y = final_bin.exterior.xy
        # if chosen, figure showing bins displayed
            if show_figure == True:

                plt.plot(x, y, color='orange')

                leg = plt.legend(handlelength=0, handletextpad=0,
                                 frameon=False, loc='upper right', markerscale=0.001)
                for item in leg.legendHandles:
                    item.set_visible(False)

                plt.savefig(self.galaxy + '_background_bins.png')
                plt.savefig(self.galaxy + '_background_bins.pdf')
            # define area
            final_bin_area = final_bin.area

            # count number of stars in each bin
            box_data = data.copy()

            for i in box_data.index:

                if final_bin.contains(Point(box_data.alpha[i], box_data.beta[i])) == False:

                    box_data.loc[i] = np.nan

            bin_nums.append(len(box_data.dropna()))

            # subtract area overlapping with ellipse

            if bin_slice_fill.intersects(mask) == True:

                overlap_area = mask.intersection(bin_slice_fill).area

                final_bin_area = final_bin_area-overlap_area
            # define alpha coordinates of bin
            bin_locs.append(upper_bound-(binwidth/2))
            # define area of bin
            bin_areas.append(final_bin_area)
            # increment bound so loop creates adjacent bin
            upper_bound = upper_bound-binwidth

            # criterion for while loop slightly different for m32
            # loop broken if below criterion reached
            if self.galaxy == 'm32' and upper_bound-lower_bound < (binwidth * 2):

                break
        # convert lists into arrays
        bin_nums = np.array(bin_nums)
        bin_locs = np.array(bin_locs)
        bin_areas = np.array(bin_areas)
        # define poisson uncertainties
        bin_uncs = np.sqrt(bin_nums)
        # define densities in n/arcsec
        bin_densities = (bin_nums/bin_areas)/3600
        # convert uncertainties
        bin_uncs = (bin_uncs/bin_areas)/3600
        # convert locations to arcmins
        bin_locs = bin_locs * 60

        m31_alpha = m31_alpha*60
        # set bin locations with horizontal translation to m31 basis
        # m31 at alpha=0
        m31_bin_locs = bin_locs-m31_alpha
        # create dataframe with useful background data
        background = pd.DataFrame({'bin_densities': bin_densities, 'bin_uncs': bin_uncs,
                                  'bin_locs': bin_locs, 'm31_bin_locs': m31_bin_locs})
        # set as class attributes for retrieval
        self.background = background

        self.bin_shapes = bin_shapes
        self.stars = stars
Exemple #11
0
def ellipse_polyline_intersection_full(ellipses, n=500):
    '''
    This function transfer an ellipse to ellipse_polyline and then check the intersections of two ellipses. It
    returns the intercetion coordinate 
    '''
    t = np.linspace(0, 2 * np.pi, n, endpoint=False)
    st = np.sin(t)
    ct = np.cos(t)
    result_radial = []
    result_tangential = []
    for x0, y0, a, b, angle, angle2 in ellipses:  #angle2: tangential direction of the ellilpse
        angle = np.deg2rad(angle)
        sa = np.sin(angle)
        ca = np.cos(angle)
        pointE = np.empty((n, 2))
        pointE[:, 0] = x0 + a * ca * ct - b * sa * st
        pointE[:, 1] = y0 + a * sa * ct + b * ca * st
        result_radial.append(pointE)

        angle2 = np.deg2rad(angle2)
        sa2 = np.sin(angle2)
        ca2 = np.cos(angle2)
        pointE_t = np.empty((n, 2))
        pointE_t[:, 0] = x0 + a * ca2 * ct - b * sa2 * st
        pointE_t[:, 1] = y0 + a * sa2 * ct + b * ca2 * st
        result_tangential.append(pointE_t)

    #ellipseA, ellipseB are the dots of two ellipse
    ellipseA = result_radial[0]
    ellipseB = result_radial[1]
    ea = LinearRing(ellipseA)
    eb = LinearRing(ellipseB)
    mp = ea.intersection(eb)  #2 radial ellipses

    #same for ellipseC and ellipseD, the dots of two ellipses
    ellipseC = result_tangential[0]
    ellipseD = result_tangential[1]
    ec = LinearRing(ellipseC)
    ed = LinearRing(ellipseD)
    mp2 = ec.intersection(ed)  #2 tangential ellipses

    mp3 = ea.intersection(ed)  # 1 tangental and 1 radial
    mp4 = eb.intersection(ec)

    #intersectionX, intersectionY are the intersections
    #if type(mp) == types.GeneratorType:
    # print(mp.geom_type)
    # print(mp)
    mp_list = []
    mp_list = [mp, mp2, mp3, mp4]
    #loop to judge all 4 situations
    for i_mp in mp_list:
        #point: 相切,only one point overloop
        if i_mp.geom_type == 'Point':
            #print(mp.geom_type)
            #print(mp.x)
            return [i_mp.x], [i_mp.y]
        #lingstring: two ellipses overlap
        elif i_mp.geom_type == 'LineString':
            newmp = list(mp.coords)
            #print("newmp", newmp)
            intersectionX = [pE[0] for pE in newmp]
            intersectionY = [pE[1] for pE in newmp]
            return intersectionX, intersectionY
        #normal situation:if len()==0 means there is no overlap return empty list[][]
        #if len()>0 return the two points
        else:
            intersectionX = [pE.x for pE in i_mp]
            intersectionY = [pE.y for pE in i_mp]
            if len(intersectionX
                   ) == 0:  #if len()==0: no overlap, next situation
                continue
            else:  #if len()>0 return the two points
                return intersectionX, intersectionY
    #all four situations no overlap
    return [], []
Exemple #12
0
    def TakeAction(self, action):
        if not self.injail:
            proposal = Point((self.current_state.x + action[0],
                              self.current_state.y + action[1]))
            #print proposal.x, proposal.y
            path = LineString([self.current_state, proposal])

            if self.obstacles:
                for obstacle in self.obstacles:
                    if obstacle.intersects(path):
                        self.injail = True
                        self.current_state = Point((-1, -1))
                        return
            if self.muds:
                for mud in self.muds:
                    if mud.intersects(path):
                        #                         print 'we are here'
                        path_inmud = mud.intersection(path)
                        coords = [path.coords[0], path.coords[1]]
                        for loc in path_inmud.coords:
                            if loc not in coords:
                                coords.append(loc)
                        coords.sort(key=lambda tup: tup[1])
                        p_in_mud = proposal.intersects(mud)
                        s_in_mud = self.current_state.intersects(mud)
                        if p_in_mud and not s_in_mud:
                            #                             print 'current not in mud'
                            if coords.index((self.current_state.x,
                                             self.current_state.y)) == 0:
                                x = coords[1][0] - coords[0][0] + 0.5 * (
                                    coords[-1][0] - coords[1][0])
                                y = coords[1][1] - coords[0][1] + 0.5 * (
                                    coords[-1][1] - coords[1][1])
                                proposal = Point(
                                    (coords[0][0] + x, coords[0][1] + y))
                            else:
                                x = coords[1][0] - coords[-1][0] + 0.5 * (
                                    coords[0][0] - coords[1][0])
                                y = coords[1][1] - coords[-1][1] + 0.5 * (
                                    coords[0][1] - coords[1][1])
                                proposal = Point(
                                    (coords[-1][0] + x, coords[-1][1] + y))
                        elif s_in_mud and not p_in_mud:
                            #                             print 'proposal not in mud'
                            if coords.index((self.current_state.x,
                                             self.current_state.y)) == 0:
                                x = 0.5 * (coords[1][0] - coords[0][0]) + (
                                    coords[-1][0] - coords[1][0])
                                y = 0.5 * (coords[1][1] - coords[0][1]) + (
                                    coords[-1][1] - coords[1][1])
                                proposal = Point(
                                    (coords[0][0] + x, coords[0][1] + y))
                            else:
                                x = 0.5 * (coords[1][0] - coords[-1][0]) + (
                                    coords[0][0] - coords[1][0])
                                y = 0.5 * (coords[1][1] - coords[-1][1]) + (
                                    coords[0][1] - coords[1][1])
                                proposal = Point(
                                    (coords[-1][0] + x, coords[-1][1] + y))
                        else:
                            proposal = Point(
                                (self.current_state.x + action[0] * 0.5,
                                 self.current_state.y + action[1] * 0.5))

            path = LineString([self.current_state, proposal])
            bounds = LinearRing(self.maze.exterior.coords)
            if bounds.intersects(path):
                onedge = bounds.intersection(path)
                if type(onedge) is MultiPoint:
                    for point in onedge:
                        if not point.equals(self.current_state):
                            proposal = point
                elif type(onedge) is Point:
                    if not onedge.equals(self.current_state):
                        proposal = onedge
                    elif not self.maze.contains(proposal):
                        proposal = bounds.interpolate(bounds.project(proposal))

            self.current_state = proposal
        else:
            self.deadend_toleration = self.deadend_toleration - 1
        return self.GetCurrentState()
Exemple #13
0
def intersectionsGridFrontiere(P, X, Y):
    """Calcule la trace de la grille cartésienne définie par X, Y sur le Polyligne P
     autrement dit les intersections de P  avec les droites
        - x = X[i] verticales et
        - y = Y[j] horizontales
        qui représentent la grille.
    :param P : un polyligne np.ndarray de shape (n,3) ou (n,2). La 3-eme dimension est ignorée.
    :param X, Y : la grille cartésienne.
        X et Y sont des np.ndarray de shape (nx,1) et (ny,1) qui représentent
        les abscisses et les ordonnées de la grille
        - On suppose que X et Y sont croissants (i)
        - On suppose également que la grille recouvre entièrement P, et déborde, i.e.
            min(X) < xmin(P) <= xmax(P) < max(X)
            min(Y) < ymin(P) <= ymax(P) < max(Y)
    :return PD: np.ndarray((npd,2)) contenant les points
    """
    #     nx, ny = len(X), len(Y)
    #     for x in X : plt.plot(ny*[x], Y, 'y-', linewidth=0.3,)
    #     for y in Y : plt.plot(X, nx*[y], 'y-', linewidth=0.3)
    #     plt.plot(P[:,0],P[:,1], 'r.')
    #     P = LineString(P)
    P = LinearRing(P)
    #     x,y = P.xy
    #     plt.plot(x,y,'g-')
    #     plt.axes().set_aspect('equal')
    #     debug(P)
    (minx, miny, maxx, maxy) = P.bounds
    #     debug(P.bounds)
    #Les numeros de droites verticales intersectant P
    iX = np.where(np.logical_and(minx < X, X < maxx))[0]
    #     px = X[iX]#une croix pour marquer les droite concernées (graphique)
    #     plt.plot(px, len(px)*[min(Y)], 'rx')
    #les droites verticales
    ms = [((X[i], Y[0]), (X[i], Y[-1])) for i in iX]

    #Les numeros de droites horizontales intersectant P
    iY = np.where(np.logical_and(miny < Y, Y < maxy))[0]
    #     px = Y[iY]#une croix pour marquer les droite concernées
    #     plt.plot(len(px)*[max(X)], px, 'rx')

    #     plt.legend()
    #     plt.show()
    #Les droites horizontales concernées par P
    ms.extend([((X[0], Y[i]), (X[-1], Y[i])) for i in iY])

    D = MultiLineString(ms)  #La famille des droites de la grille
    #     debug(len(D))

    #convex_hull pour réordonner les points, en faire un polygone
    #array_interface pour recuperer les data pures numpy
    PD = P.intersection(D)  #.array_interface()
    #     debug(type(PD))
    D = [P.project(pd)
         for pd in PD]  #abscisse curviligne des points d'intersection
    D.sort()
    PD = [P.interpolate(d).xy for d in D]  #Les points dans l'ordre
    #     PD = PD.array_interface()
    #     exit()
    #.convex_hull.exterior

    #     shape = PD['shape']
    #PD.reshape(...) : si le tableau PD doit être recopié => en silence
    #PD = array(PD['data']).reshape(shape)
    #     PD = array(PD['data'])
    PD = array(PD)
    #PD.shape=... : si le tableau PD doit être recopié => erreur
    #     PD.shape = shape
    return PD