示例#1
0
def build_lattice(lattice):
    """Build the lattice based on the values stored in the lp dictionary attribute of supplied lattice instance.

    Returns
    -------
    lattice : lattice_class lattice instance
        The instance of the lattice class, with the following attributes populated:
        lattice.xy = xy
        lattice.NL = NL
        lattice.KL = KL
        lattice.BL = BL
        lattice.PVx = PVx
        lattice.PVy = PVy
        lattice.PVxydict = PVxydict
        lattice.PV = PV
        lattice.lp['BBox'] : #vertices x 2 float array
            BBox is the polygon used to crop the lattice or defining the extent of the lattice; could be hexagonal, for instance.
        lattice.lp['LL'] : tuple of 2 floats
            LL are the linear extent in each dimension of the lattice. For ex:
            ( np.max(xy[:,0])-np.min(xy[:,0]), np.max(xy[:,1])-np.min(xy[:,1]) )
        lattice.lp['LV'] = LV
        lattice.lp['UC'] = UC
        lattice.lp['lattice_exten'] : str
            A string specifier for the lattice built
        lattice.lp['slit_exten'] = slit_exten
    """
    # Define some shortcut variables
    lattice_type = lattice.lp['LatticeTop']
    shape = lattice.lp['shape']
    NH = lattice.lp['NH']
    NV = lattice.lp['NV']
    lp = lattice.lp
    networkdir = lattice.lp['rootdir'] + 'networks/'
    check = lattice.lp['check']
    if lattice_type == 'hexagonal':
        from build_hexagonal import build_hexagonal
        xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_hexagonal(
            lp)
    elif lattice_type == 'hexmeanfield':
        from build_hexagonal import build_hexmeanfield
        xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_hexmeanfield(
            lp)
    elif lattice_type == 'hexmeanfield3gyro':
        from build_hexagonal import build_hexmeanfield3gyro
        xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_hexmeanfield3gyro(
            lp)
    elif 'selregion' in lattice_type:
        # amorphregion_isocent or amorphregion_kagome_isocent, for ex
        # Example usage: python ./build/make_lattice.py -LT selregion_randorg_gammakick1p60_cent -spreadt 0.8 -NP 225
        #  python ./build/make_lattice.py -LT selregion_iscentroid -N 30
        #  python ./build/make_lattice.py -LT selregion_hyperuniform -N 80
        from lepm.build.build_select_region import build_select_region
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_select_region(
            lp)
    elif lattice_type == 'frame1dhex':
        from build_hexagonal import build_frame1dhex
        # keep only the boundary of the lattice, eliminate the bulk
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_frame1dhex(
            lp)
    elif lattice_type == 'square':
        import lepm.build.build_square as bs
        print '\nCreating square lattice...'
        xy, NL, KL, BL, lattice_exten = bs.generate_square_lattice(
            shape, NH, NV, lp['eta'], lp['theta'])
        print 'lattice_exten = ', lattice_exten
        PVx = []
        PVy = []
        PVxydict = {}
        LL = (NH + 1, NV + 1)
        LVUC = 'none'
        UC = 'none'
        LV = 'none'
        BBox = np.array([[-LL[0] * 0.5, -LL[1] * 0.5],
                         [LL[0] * 0.5,
                          -LL[1] * 0.5], [LL[0] * 0.5, LL[1] * 0.5],
                         [-LL[0] * 0.5, LL[1] * 0.5]])
    elif lattice_type == 'triangular':
        import lepm.build.build_triangular as bt
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = bt.build_triangular_lattice(
            lp)
    elif lattice_type == 'linear':
        from lepm.build.build_linear_lattices import build_zigzag_lattice
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_zigzag_lattice(
            lp)
        lp['NV'] = 1
    elif lattice_type == 'deformed_kagome':
        from lepm.build.build_kagome import generate_deformed_kagome
        xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = generate_deformed_kagome(
            lp)
    elif lattice_type == 'deformed_martini':
        from lepm.build.build_martini import build_deformed_martini
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_deformed_martini(
            lp)
    elif lattice_type == 'twisted_kagome':
        from lepm.build.build_kagome import build_twisted_kagome
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_twisted_kagome(
            lp)
    elif lattice_type == 'hyperuniform':
        from lepm.build.build_hyperuniform import build_hyperuniform
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hyperuniform(
            lp)
    elif lattice_type == 'hyperuniform_annulus':
        from lepm.build.build_hyperuniform import build_hyperuniform_annulus
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hyperuniform_annulus(
            lp)
        lp['shape'] = 'annulus'
    elif lattice_type == 'isostatic':
        from lepm.build.build_jammed import build_isostatic
        # Manually tune coordination of jammed packing (lets you tune through isostatic point)
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_isostatic(
            lp)
    elif lattice_type == 'jammed':
        from lepm.build.build_jammed import build_jammed
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_jammed(
            lp)
    elif lattice_type == 'triangularz':
        from lepm.build.build_triangular import build_triangularz
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_triangularz(
            lp)
    elif lattice_type == 'hucentroid':
        from lepm.build.build_hucentroid import build_hucentroid
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hucentroid(
            lp)
    elif lattice_type == 'hucentroid_annulus':
        from lepm.build.build_hucentroid import build_hucentroid_annulus
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hucentroid_annulus(
            lp)
        lp['shape'] = 'annulus'
    elif lattice_type == 'huvoronoi':
        from lepm.build.build_voronoized import build_huvoronoi
        xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten = build_huvoronoi(
            lp)
        LVUC = 'none'
        LV = 'none'
        UC = 'none'
    elif lattice_type == 'kagome_hucent':
        from lepm.build.build_hucentroid import build_kagome_hucent
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_hucent(
            lp)
    elif lattice_type == 'kagome_hucent_annulus':
        from lepm.build.build_hucentroid import build_kagome_hucent_annulus
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_hucent_annulus(
            lp)
        lp['shape'] = 'annulus'
    elif lattice_type == 'kagome_huvor':
        from lepm.build.build_voronoized import build_kagome_huvor
        print('Loading hyperuniform to build lattice...')
        xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten = build_kagome_huvor(
            lp)
        LV, LVUC, UC = 'none', 'none', 'none'
    elif lattice_type == 'iscentroid':
        from lepm.build.build_iscentroid import build_iscentroid
        print('Loading isostatic to build lattice...')
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten = build_iscentroid(
            lp)
    elif lattice_type == 'kagome_isocent':
        from lepm.build.build_iscentroid import build_kagome_isocent
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten = build_kagome_isocent(
            lp)
    elif lattice_type == 'overcoordinated1':
        from lepm.build.build_overcoordinated import generate_overcoordinated1_lattice
        xy, NL, KL, BL, SBL, LV, UC, LVUC, lattice_exten = generate_overcoordinated1_lattice(
            NH, NV)
        PVxydict = {}
        PVx = []
        PVy = []
        if lp['check']:
            le.display_lattice_2D(xy, BL)
    elif lattice_type == 'circlebonds':
        from lepm.build.build_linear_lattices import generate_circle_lattice
        xy, NL, KL, BL, LV, UC, LVUC, lattice_exten = generate_circle_lattice(
            NH)
        PVxydict = {}
        PVx = []
        PVy = []
        lp['NV'] = 1
        minx = np.min(xy[:, 0])
        maxx = np.max(xy[:, 0])
        miny = np.min(xy[:, 1])
        maxy = np.max(xy[:, 1])
        BBox = np.array([[minx, miny], [minx, maxy], [maxx, maxy],
                         [maxx, miny]])
        LL = (maxx - minx, maxy - miny)
    elif lattice_type == 'dislocatedRand':
        from lepm.build.build_dislocatedlattice import build_dislocated_lattice
        xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten = build_dislocated_lattice(
            lp)
    elif lattice_type == 'dislocated':
        if lp['dislocation_xy'] != 'none':
            dislocX = lp['dislocation_xy'].split('/')[0]
            dislocY = lp['dislocation_xy'].split('/')[1]
            dislocxy_exten = '_dislocxy_' + dislocX + '_' + dislocY
            pt = np.array([[float(dislocX), float(dislocY)]])
        else:
            pt = np.array([[0., 0.]])
            dislocxy_exten = ''
        if lp['Bvec'] == 'random':
            Bvecs = 'W'
        else:
            Bvecs = lp['Bvec']
        xy, NL, KL, BL, lattice_exten = generate_dislocated_hexagonal_lattice(
            shape, NH, NV, pt, Bvecs=Bvecs, check=lp['check'])
        lattice_exten += dislocxy_exten
        PVx = []
        PVy = []
        PVxydict = {}
        LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]),
              np.max(xy[:, 1]) - np.min(xy[:, 1]))
        BBox = np.array([[np.min(xy[:, 0]), np.min(xy[:, 1])],
                         [np.max(xy[:, 0]), np.min(xy[:, 1])],
                         [np.max(xy[:, 0]), np.max(xy[:, 1])],
                         [np.min(xy[:, 0]), np.max(xy[:, 1])]])
        LV = 'none'
        UC = 'none'
        LVUC = 'none'
    elif lattice_type == 'penroserhombTri':
        if lp['periodicBC']:
            from lepm.build.build_quasicrystal import generate_periodic_penrose_rhombic
            xy, NL, KL, BL, PVxydict, BBox, PV, lattice_exten = generate_periodic_penrose_rhombic(
                lp)
            LL = (PV[0, 0], PV[1, 1])
            PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL)
        else:
            from lepm.build.build_quasicrystal import generate_penrose_rhombic_lattice
            xy, NL, KL, BL, lattice_exten, Num_sub = generate_penrose_rhombic_lattice(
                shape, NH, NV, check=lp['check'])
            LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]),
                  np.max(xy[:, 1]) - np.min(xy[:, 1]))
            BBox = blf.auto_polygon(shape, NH, NV, eps=0.00)
            PVx = []
            PVy = []
            PVxydict = {}

        LVUC = 'none'
        LV = 'none'
        UC = 'none'
    elif lattice_type == 'penroserhombTricent':
        from lepm.build.build_quasicrystal import generate_penrose_rhombic_centroid_lattice
        xy, NL, KL, BL, PVxydict, PV, LL, BBox, lattice_exten = generate_penrose_rhombic_centroid_lattice(
            lp)
        # deepcopy PVxydict to generate new pointers
        PVxydict = copy.deepcopy(PVxydict)
        if lp['periodicBC']:
            PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL)
        else:
            PVx, PVy = [], []

        # Rescale so that median bond length is unity
        bL = le.bond_length_list(xy, BL, NL=NL, KL=KL, PVx=PVx, PVy=PVy)
        scale = 1. / np.median(bL)
        xy *= scale
        PV *= scale
        print 'PV = ', PV
        BBox *= scale
        LL = (LL[0] * scale, LL[1] * scale)

        print 'after updating other things: PVxydict = ', PVxydict
        if lp['periodicBC']:
            PVx *= scale
            PVy *= scale
            PVxydict.update(
                (key, val * scale) for key, val in PVxydict.items())
        else:
            PVx = []
            PVy = []

        LVUC = 'none'
        LV = 'none'
        UC = 'none'
    elif lattice_type == 'kagome_penroserhombTricent':
        from build.build_quasicrystal import generate_penrose_rhombic_centroid_lattice
        xy, NL, KL, BL, lattice_exten = generate_penrose_rhombic_centroid_lattice(
            shape, NH + 5, NV + 5, check=lp['check'])

        # Decorate lattice as kagome
        print('Decorating lattice as kagome...')
        xy, BL, PVxydict = blf.decorate_as_kagome(xy, BL)
        lattice_exten = 'kagome_' + lattice_exten

        xy, NL, KL, BL = blf.mask_with_polygon(shape,
                                               NH,
                                               NV,
                                               xy,
                                               BL,
                                               eps=0.00,
                                               check=False)

        # Rescale so that median bond length is unity
        bL = le.bond_length_list(xy, BL)
        xy *= 1. / np.median(bL)

        minx = np.min(xy[:, 0])
        miny = np.min(xy[:, 1])
        maxx = np.max(xy[:, 0])
        maxy = np.max(xy[:, 1])
        BBox = np.array([[minx, miny], [minx, maxy], [maxx, maxy],
                         [maxx, miny]])
        LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]),
              np.max(xy[:, 1]) - np.min(xy[:, 1]))
        PVx = []
        PVy = []
        PVxydict = {}
        LVUC = 'none'
        LV = 'none'
        UC = 'none'
    elif lattice_type == 'random':
        xx = np.random.uniform(low=-NH * 0.5 - 10,
                               high=NH * 0.5 + 10,
                               size=(NH + 20) * (NV + 20))
        yy = np.random.uniform(low=-NV * 0.5 - 10,
                               high=NV * 0.5 + 10,
                               size=(NH + 20) * (NV + 20))
        xy = np.dstack((xx, yy))[0]
        Dtri = Delaunay(xy)
        TRI = Dtri.vertices
        BL = le.Tri2BL(TRI)
        NL, KL = le.BL2NLandKL(BL, NN='min')

        # Crop to polygon (instead of trimming boundaries)
        # NL, KL, BL, TRI = le.delaunay_cut_unnatural_boundary(xy, NL, KL, BL, TRI, thres=lp['trimbound_thres'])
        shapedict = {shape: [NH, NV]}
        keep = blf.argcrop_lattice_to_polygon(shapedict, xy, check=check)
        xy, NL, KL, BL = le.remove_pts(keep, xy, BL, NN='min')

        lattice_exten = lattice_type + '_square_thres' + sf.float2pstr(
            lp['trimbound_thres'])
        polygon = blf.auto_polygon(shape, NH, NV, eps=0.00)
        BBox = polygon
        LL = (np.max(BBox[:, 0]) - np.min(BBox[:, 0]),
              np.max(BBox[:, 1]) - np.min(BBox[:, 1]))
        PVx = []
        PVy = []
        PVxydict = {}
        LVUC = 'none'
        LV = 'none'
        UC = 'none'
    elif lattice_type == 'randomcent':
        from lepm.build.build_random import build_randomcent
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_randomcent(
            lp)
    elif lattice_type == 'kagome_randomcent':
        from lepm.build.build_random import build_kagome_randomcent
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_randomcent(
            lp)
    elif lattice_type == 'randomspreadcent':
        from lepm.build.build_randomspread import build_randomspreadcent
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_randomspreadcent(
            lp)
    elif lattice_type == 'kagome_randomspread':
        from lepm.build.build_randomspread import build_kagome_randomspread
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_randomspread(
            lp)
    elif 'randorg_gammakick' in lattice_type and 'kaghi' not in lattice_type:
        # lattice_type is like 'randorg_gamma0p20_cent' and uses Hexner pointsets
        # NH is width, NV is height, NP_load is total number of points. This is different than other conventions.
        from build_randorg_gamma import build_randorg_gamma_spread
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_randorg_gamma_spread(
            lp)
    elif 'randorg_gamma' in lattice_type and 'kaghi' not in lattice_type:
        # lattice_type is like 'randorg_gamma0p20_cent' and uses Hexner pointsets
        from build_randorg_gamma import build_randorg_gamma_spread_hexner
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = \
            build_randorg_gamma_spread_hexner(lp)
    elif 'random_organization' in lattice_type:
        try:
            if isinstance(lp['relax_timesteps'], str):
                relax_tag = lp['relax_timesteps']
            else:
                relax_tag = '{0:02d}'.format(lp['relax_timesteps'])
        except:
            raise RuntimeError(
                'lattice parameters dictionary lp needs key relax_timesteps')

        points = np.loadtxt(
            networkdir +
            'random_organization_source/random_organization/random/' +
            'random_kick_' + relax_tag + 'relax/out_d' +
            '{0:02d}'.format(int(lp['conf'])) + '_xy.txt')
        points -= np.mean(points, axis=0)
        xytmp, trash1, trash2, trash3 = blf.mask_with_polygon(shape,
                                                              NH,
                                                              NV,
                                                              points, [],
                                                              eps=0.00)

        xy, NL, KL, BL = le.delaunay_centroid_lattice_from_pts(xytmp,
                                                               polygon='auto',
                                                               check=check)
        polygon = blf.auto_polygon(shape, NH, NV, eps=0.00)

        if check:
            le.display_lattice_2D(xy, BL)

        # Rescale so that median bond length is unity
        bL = le.bond_length_list(xy, BL, NL=NL, KL=KL, PVx=PVx, PVy=PVy)
        xy *= 1. / np.median(bL)
        polygon *= 1. / np.median(bL)

        lattice_exten = lattice_type + '_relax' + relax_tag + '_' + shape + '_d' + \
                        '{0:02d}'.format(int(lp['loadlattice_number']))
        LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]),
              np.max(xy[:, 1]) - np.min(xy[:, 1]))
        PVxydict = {}
        PVx = []
        PVy = []
        BBox = polygon
    elif lattice_type == 'flattenedhexagonal':
        from lepm.build.build_hexagonal import generate_flattened_honeycomb_lattice
        xy, NL, KL, BL, LVUC, LV, UC, PVxydict, PVx, PVy, lattice_exten = \
            generate_flattened_honeycomb_lattice(shape, NH, NV, lp['aratio'], lp['delta'], lp['phi'], eta=0., rot=0.,
                                                 periodicBC=False, check=check)
    elif lattice_type == 'cairo':
        from lepm.build.build_cairo import build_cairo
        xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_cairo(
            lp)
    elif lattice_type == 'kagper_hucent':
        from lepm.build.build_hucentroid import build_kagper_hucent
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagper_hucent(
            lp)
    elif lattice_type == 'hex_kagframe':
        from lepm.build.build_kagcentframe import build_hex_kagframe
        # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hexagonal lattice
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hex_kagframe(
            lp)
    elif lattice_type == 'hex_kagcframe':
        from lepm.build.build_kagcentframe import build_hex_kagcframe
        # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hexagonal lattice
        # as circlular annulus
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hex_kagcframe(
            lp)
    elif lattice_type in ['hucent_kagframe', 'hucent_kagcframe']:
        from lepm.build.build_kagcentframe import build_hucent_kagframe
        # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hucentroid decoration
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hucent_kagframe(
            lp)
    elif lattice_type == 'kaghu_centframe':
        from lepm.build.build_kagcentframe import build_kaghu_centframe
        # Use lp['alph'] to determine the beginning of the centroid frame, surrounding kagomized decoration
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kaghu_centframe(
            lp)
    elif lattice_type in ['isocent_kagframe', 'isocent_kagcframe']:
        from lepm.build.build_kagcentframe import build_isocent_kagframe
        # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hucentroid decoration
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_isocent_kagframe(
            lp)
    elif lattice_type == 'kagsplit_hex':
        from lepm.build.build_kagome import build_kagsplit_hex
        # Use lp['alph'] to determine what fraction (on the right) is kagomized
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagsplit_hex(
            lp)
    elif lattice_type == 'kagper_hex':
        from lepm.build.build_kagome import build_kagper_hex
        # Use lp['alph'] to determine what fraction of the radius/width (in the center) is kagomized
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagper_hex(
            lp)
    elif lattice_type == 'hex_kagperframe':
        from lepm.build.build_kagcentframe import build_hex_kagperframe
        # Use lp['alph'] to determine what fraction of the radius/width (in the center) is partially kagomized
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hex_kagperframe(
            lp)
    elif lattice_type == 'kagome':
        from lepm.build.build_kagome import build_kagome
        # lets you make a square kagome
        xy, NL, KL, BL, PVx, PVy, PVxydict, PV, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagome(
            lp)
    elif 'uofc' in lattice_type:
        from lepm.build.build_kagcent_words import build_uofc
        # ['uofc_hucent', 'uofc_kaglow_hucent', 'uofc_kaghi_hucent', 'uofc_kaglow_isocent']:
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_uofc(
            lp)
    elif 'chicago' in lattice_type:
        from lepm.build.build_kagcent_words import build_chicago
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_chicago(
            lp)
    elif 'chern' in lattice_type:
        from lepm.build.build_kagcent_words import build_kagcentchern
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentchern(
            lp)
    elif 'csmf' in lattice_type:
        from lepm.build.build_kagcent_words import build_kagcentcsmf
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentcsmf(
            lp)
    elif 'thanks' in lattice_type:
        # example:
        # python ./build/make_lattice.py -LT kaghi_isocent_thanks -skip_gyroDOS -NH 300 -NV 70 -thres 5.5 -skip_polygons
        from lepm.build.build_kagcent_words import build_kagcentthanks
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentthanks(
            lp)
    elif 'curvys' in lattice_type:
        # for lattice_type in ['kaghi_isocent_curvys', 'kaglow_isocent_curvys',
        #                      'kaghi_hucent_curvys', 'kaglow_hucent_curvys', kaghi_randorg_gammakick1p60_cent_curvys',
        #                      'kaghi_randorg_gammakick0p50_cent_curvys', ... ]
        # example usage:
        # python ./build/make_lattice.py -LT kaghi_isocent_curvys -NH 100 -NV 70 -thres 5.5 -skip_polygons -skip_gyroDOS
        from lepm.build.build_kagcent_words import build_kagcentcurvys
        xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentcurvys(
            lp)
    elif 'hexannulus' in lattice_type:
        from lepm.build.build_conformal import build_hexannulus
        xy, NL, KL, BL, lattice_exten, lp = build_hexannulus(lp)
        LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]),
              np.max(xy[:, 1]) - np.min(xy[:, 1]))
        PVxydict = {}
        PVx = []
        PVy = []
        UC = np.array([0, 0])
        LV = 'none'
        LVUC = 'none'
        minx = np.min(xy[:, 0])
        miny = np.min(xy[:, 1])
        maxx = np.max(xy[:, 0])
        maxy = np.max(xy[:, 1])
        BBox = np.array([[minx, miny], [minx, maxy], [maxx, maxy],
                         [maxx, miny]])
    elif 'accordion' in lattice_type:
        # accordionhex accordiony accordionkagy
        # Example usage:
        # python ./build/make_lattice.py -LT accordionkag -alph 0.9 -intparam 2 -N 6 -skip_polygons -skip_gyroDOS
        # nzag controlled by lp['intparam'], and the rotation of the kagome element is controlled by lp['alph']
        if lattice_type == 'accordionhex':
            from lepm.build.build_hexagonal import build_accordionhex
            xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp, xyvx = build_accordionhex(
                lp)
        elif lattice_type == 'accordionkag':
            from lepm.build.build_kagome import build_accordionkag
            xy, NL, KL, BL, PVx, PVy, PVxydict, PV, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_accordionkag(
                lp)
        elif lattice_type == 'accordionkag_hucent':
            from lepm.build.build_hucentroid import build_accordionkag_hucent
            xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = \
                build_accordionkag_hucent(lp)
        elif lattice_type == 'accordionkag_isocent':
            from lepm.build.build_iscentroid import build_accordionkag_isocent
            xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = \
                build_accordionkag_isocent(lp)
    elif 'spindle' in lattice_type:
        if lattice_type == 'spindle':
            from lepm.build.build_spindle import build_spindle
            xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_spindle(
                lp)
    elif lattice_type == 'stackedrhombic':
        from lepm.build.build_rhombic import build_stacked_rhombic
        xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_stacked_rhombic(
            lp)
    elif 'junction' in lattice_type:
        # accordionhex accordiony accordionkagy
        if lattice_type == 'hexjunction':
            from lepm.build.build_hexagonal import build_hexjunction
            xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp, xyvx = build_hexjunction(
                lp)
        elif lattice_type == 'kagjunction':
            from lepm.build.build_kagome import build_kagjunction
            xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagjunction(
                lp)

    ###########

    # For reference: this is how to change z
    # le.cut_bonds_z(BL,lp['target_z'])
    # ##cut N bonds for z
    # N2cut = int(round((z_start-target_z)*len(BL)/z_start))
    # allrows = range(len(BL))
    # inds = random.sample(allrows, N2cut)
    # keep = np.setdiff1d(allrows,inds)
    # bnd_z = BL[keep]

    # Cut slit
    if lp['make_slit']:
        print('Cuting notch or slit...')
        L = max(xy[:, 0]) - min(xy[:, 0])
        cutL = L * lp['cutLfrac']
        x0 = -L * 0. + cutL * 0.5 - 1.  # 0.25*L+0.5
        BL, xy = blf.cut_slit(BL, xy, cutL + 1e-3, x0, y0=0.2)
        slit_exten = '_cutL' + str(cutL / L) + 'L_x0_' + str(x0)

        print('Rebuilding NL,KL...')
        NP = len(xy)
        if latticetop == 'deformed_kagome':
            nn = 4
        elif lattice_type == 'linear':
            if NP == 1:
                nn = 0
            else:
                nn = 2
        else:
            nn = 'min'

        NL, KL = le.BL2NLandKL(BL, NP=NP, NN=nn)

        # remake BL too
        BL = le.NL2BL(NL, KL)
    else:
        slit_exten = ''
        NP = len(xy)

    if lp['check']:
        print 'make_lattice: Showing lattice before saving...'
        # print 'PVx = ', PVx
        # print 'PVy = ', PVy
        le.display_lattice_2D(xy, BL, PVxydict=PVxydict)
    ################

    lattice.xy = xy
    lattice.NL = NL
    lattice.KL = KL
    lattice.BL = BL
    lattice.PVx = PVx
    lattice.PVy = PVy
    lattice.PVxydict = PVxydict
    lattice.LVUC = LVUC
    lattice.lp = lp
    lattice.lp['BBox'] = BBox
    lattice.lp['LL'] = LL
    lattice.lp['LV'] = LV
    lattice.lp['UC'] = UC
    lattice.lp['lattice_exten'] = lattice_exten
    lattice.lp['slit_exten'] = slit_exten
    lattice.lp['Nparticles'] = NP
    return lattice
示例#2
0
def data2stills_2Dgyros(datadir,
                        simoutdir,
                        params,
                        framedir_name='stills',
                        init_skip=10,
                        climv=0.1,
                        numbering='adopt',
                        rough=False,
                        roughmov=True,
                        exaggerate=1.0,
                        rm_stills=True,
                        resolution=150,
                        figsize='auto',
                        color_particles='k',
                        DOSexcite=None,
                        lp=None,
                        framerate=10,
                        mov_exten='',
                        title='',
                        dos_meshfn_dir=None,
                        movname=None,
                        lw=2,
                        **kwargs):
    """Converts a list of data into a stack of png images of gyroscopic lattice using timestep_plot for each timestep.

    Parameters
    ----------
    simoutdir : string
        The output directory for the simulation (contains subdirs for xyv, KL)
    params : dict
        Parameters dictionary
    framedir_name : string
        Subdirectory of simoutdir in which to save movie images
    vsaved : bool
        whether the velocites are recorded (vsaved = False for Nash gyros, True for gHST, for example)
    init_skip : int
        One out of every init_skip frames will be written first, then the intermittent frames will be written, to see
        briefly what happens
    climv : float or tuple
        Color limit for coloring bonds by bond strain
    numbering : 'natural' or 'adopt' (default = 'adopt')
        Use indexing '0','1','2','3',... or adopt the index of the input file.
    rough : boolean
        Plot every init_skip files ONLY? (if False, writes every init_skip files first, then does the rest)
    exaggerate : float (default 1.0 --> in which case it is ignored)
        Exaggerate the displacements of each particle from its initial position by this factor. Ignored if == 1.0
    rm_stills : bool
        Whether or not to delete the stills after making them.
    DOSexcite : tuple of floats or None
        (excitation frequency, stdev time), or else None if DOS plot is not desired
    lp : dict
        Lattice parameters. If not None, then if eigval is not found in main dir, attempts to load eigval from gyro
        network, but will not compute it
    framerate : int or float (optional, default=10)
        framerate for movie
    mov_exten : str (optional)
        additional description to append to movie name, if movname is None
    movname : str or None
        Name or full path with name of movie to output of the simulation
    **kwargs : keyword arguments for leplt.timestep_plot()
        such as bgcolor, cmap (the strain colormap), color_particles, mimic_expt


    Returns
    ----------
    """
    plt.close('all')
    print 'Running data2stills_2Dgyros with DOSexcite = ', DOSexcite
    # get dirs
    # vsaved denotes whether the velocites are recorded
    # vsaved = False for Nash gyros, True for gHST, for example
    print 'simoutdir = ', simoutdir
    try:
        xypath = sorted(glob.glob(simoutdir + 'xyv/'))[0]
        vsaved = True
    except IndexError:
        xypath = sorted(glob.glob(simoutdir + 'xy/'))[0]
        vsaved = False
    # list files
    xyfiles = sorted(glob.glob(xypath + '*.txt'))
    # load setup
    NLfile = sorted(glob.glob(datadir + 'NL.txt'))[0]
    NL = np.loadtxt(NLfile, dtype='int', delimiter=',')
    xy0file = sorted(glob.glob(datadir + 'xy.txt'))[0]
    xy0 = np.loadtxt(xy0file, delimiter=',', usecols=(0, 1))

    if 'deform' in params:
        if params['deform']:
            deform_xy0 = True
            xy0path = sorted(glob.glob(simoutdir + 'xy0/'))[0]
            xy0files = sorted(glob.glob(xy0path + '*.txt'))
        else:
            deform_xy0 = False
            xy0files = []

    try:
        KLpath = sorted(glob.glob(simoutdir + 'KL/'))[0]
        KLfiles = sorted(glob.glob(KLpath + '*.txt'))
        if KLfiles:
            print 'found KLfiles --> update KL each timestep'
            update_KL_each_timestep = True
            KL = np.loadtxt(KLfiles[0], delimiter=',')
        else:
            print 'KLfiles =', KLfiles, '\n --> do not update KL'
            update_KL_each_timestep = False
            KL = np.loadtxt(datadir + 'KL.txt', dtype='int', delimiter=',')
            BM0 = le.NL2BM(xy0, NL, KL)
    except IndexError:
        print 'no KLfiles --> do not update KL'
        update_KL_each_timestep = False
        KL = np.loadtxt(datadir + 'KL.txt', dtype='int', delimiter=',')
        BM0 = le.NL2BM(xy0, NL, KL)

    if 'h' in params:
        hh = params['h']
    elif 'hh' in params:
        hh = params['hh']
    else:
        hfile = sorted(glob.glob(datadir + 'h.txt'))[0]
        hh = np.loadtxt(hfile)

    # get base name from xyfile
    name = 'still'
    if vsaved:
        # name = (xyfiles[0].split('/')[-1]).split('xyv')[0]
        try:
            x, y, vx, vy = np.loadtxt(xyfiles[0], delimiter=',', unpack=True)
        except:
            x, y, z, vx, vy, vz = np.loadtxt(xyfiles[0],
                                             delimiter=',',
                                             unpack=True)
    else:
        # name = (xyfiles[0].split('/')[-1]).split('xy')[0]
        try:
            '''Data is 2D'''
            x, y = np.loadtxt(xyfiles[0], delimiter=',', unpack=True)
        except:
            try:
                '''Data is 3D'''
                x, y, z = np.loadtxt(xyfiles[0], delimiter=',', unpack=True)
            except:
                '''Data is X,Y,dX,dY'''
                X, Y, dX, dY = np.loadtxt(xyfiles[0],
                                          delimiter=',',
                                          unpack=True)

    # get length of index string from xyfile
    index_sz = str(len((xyfiles[0].split('_')[-1]).split('.')[0]))
    # make output dir
    outdir = simoutdir + framedir_name + '/'
    dio.ensure_dir(outdir)
    # set range of window from first values
    xlimv = np.ceil(max(x) * 5. / 4.)
    ylimv = np.ceil(max(y) * 5. / 4.)

    # Initial bond list and
    # count initial bonds (double counted)
    # nzcount = np.count_nonzero(KL)
    BL0 = le.NL2BL(NL, KL)
    bo = le.bond_length_list(xy0, BL0)

    # make list of indices to plot-- first sparse then dense
    do1 = [0] + range(0, len(xyfiles), init_skip)

    # Set up figure
    if figsize == 'auto':
        fig = plt.gcf()
        plt.clf()
    else:
        plt.close('all')
        fig = plt.figure(figsize=figsize)

    print 'DOSexcite = ', DOSexcite
    if DOSexcite is not None:
        # Load DOS eigvals:
        eigvalpklglob = glob.glob(datadir + 'eigval.pkl')
        if eigvalpklglob:
            with open(datadir + 'eigval.pkl', "rb") as input_file:
                eigval = cPickle.load(input_file)
            eval_loaded = True
        else:
            print 'Did not find eigval in simulation dir (datadir), attempting to load based on supplied meshfn...'
            # If you want to load eigvals from a lattice other than the one being simulated, put a "pointer file"
            # txt file with the path to that meshfn in your simulation directory: for ex, put 'meshfn_eigvals.txt'
            # in the simdir, with contents '/Users/username/...path.../hexagonal_square_delta0p667_...000010_x_000010/'
            if dos_meshfn_dir is None or dos_meshfn_dir == 'none':
                dos_meshfn_dir = datadir

            meshfn_specfn = glob.glob(
                dio.prepdir(dos_meshfn_dir) + 'meshfn_eig*.txt')
            print 'dos_meshfn_dir = ', dos_meshfn_dir
            print 'meshfn_specfn = ', meshfn_specfn
            if meshfn_specfn:
                with open(meshfn_specfn[0], 'r') as myfile:
                    meshfn = myfile.read().replace('\n', '')
                if lp is not None:
                    # Build correct eigval to load based on lp (gyro lattice parameters) by grabbing lp[meshfn_exten]
                    import lepm.lattice_class
                    import lepm.gyro_lattice_class
                    # lp = {'LatticeTop': params['LatticeTop'], 'meshfn': params['meshfn']}
                    lat = lepm.lattice_class.Lattice(lp=lp)
                    lat.load()
                    mlat = lepm.magnetic_gyro_lattice_class.MagneticGyroLattice(
                        lat, lp)
                    eigvalfn = dio.prepdir(
                        meshfn) + 'eigval' + mlat.lp['meshfn_exten'] + '.pkl'
                else:
                    print 'since no lp supplied, assuming eigval is default in datadir...'
                    eigvalfn = dio.prepdir(meshfn) + 'eigval_magnetic.pkl'
                with open(eigvalfn, "rb") as fn:
                    eigval = cPickle.load(fn)
                eval_loaded = True
            else:
                print 'plotting.time_domain_magnetic: Did not find eigval or eigval pointer file in datadir, ' + \
                      'attempting to load based on lp...'
                if lp is not None:
                    print 'Loading based on lp...'
                    # No eigval saved in lattice GyroLattice's meshfn, seeking alternative
                    import lepm.lattice_class
                    import lepm.gyro_lattice_class
                    # lp = {'LatticeTop': params['LatticeTop'], 'meshfn': params['meshfn']}
                    lat = lepm.lattice_class.Lattice(lp=lp)
                    lat.load()
                    print 'lp = ', lp
                    print 'lp[Omk] = ', lp['Omk']
                    mlat = lepm.magnetic_gyro_lattice_class.MagneticGyroLattice(
                        lat, lp)
                    eigval = mlat.load_eigval()
                    if eigval is None:
                        eigval = mlat.get_eigval()
                        print 'Calculated eigval based on supplied GyroLattice instance, using lp dictionary.'
                    else:
                        print 'Loaded eigval from disk, from a location determined by the lp dictionary.'
                    eval_loaded = True
                else:
                    eval_loaded = False
                    raise RuntimeError(
                        'Did not supply lp and eigval is not in datadir!')

        if eval_loaded:
            # Attempt to load ipr for network
            iprglob = glob.glob(datadir + 'ipr.pkl')
            if iprglob:
                with open(datadir + 'ipr.pkl', "rb") as input_file:
                    ipr = cPickle.load(input_file)
                    colorV = 1. / ipr
                    linewidth = 0
                    cax_label = r'$p$'
                    colormap = 'viridis_r'
                    vmin_hdr = None
                    vmax_hdr = None
                    cbar_ticklabels = None
                    cbar_nticks = 4
            else:
                locglob = glob.glob(datadir + 'localization*.txt')
                if locglob:
                    localization = np.loadtxt(locglob[0], delimiter=',')
                    ill = localization[:, 2]
                    ill_full = np.zeros(len(eigval), dtype=float)
                    ill_full[0:int(len(eigval) * 0.5)] = ill[::-1]
                    ill_full[int(len(eigval) * 0.5):len(eigval)] = ill
                    colorV = ill_full
                    linewidth = 0
                    cax_label = r'$\lambda^{-1}$'
                    colormap = 'viridis'
                    vmin_hdr = 0.0
                    vmax_hdr = 1. / (np.max(np.abs(xy0.ravel())))
                    cbar_ticklabels = ['0', r'$1/L$', r'$2/L$']
                    cbar_nticks = 3
                else:
                    print 'plotting.time_domain_magnetic: Did not find ipr in simulation dir (datadir), ' +\
                          'attempting to load based on supplied meshfn...'
                    # First seek directly supplied files in the simulation datadir
                    meshfn_specfn = glob.glob(datadir + 'meshfn_*ipr.txt')
                    if meshfn_specfn:
                        with open(meshfn_specfn[0], 'r') as myfile:
                            meshfn = myfile.read().replace('\n', '')
                        with open(
                                dio.prepdir(meshfn) + 'ipr' +
                                lp['meshfn_exten'] + '.pkl', "rb") as fn:
                            ipr = cPickle.load(fn)
                        colorV = 1. / ipr
                        cax_label = r'$p$'
                        colormap = 'viridis_r'
                        linewidth = 0
                        vmin_hdr = None
                        vmax_hdr = None
                        cbar_ticklabels = None
                        cbar_nticks = 4
                    else:
                        print '\n\n\nComputing localization from supplied meshfn\n\n\n'
                        if dos_meshfn_dir is None or dos_meshfn_dir == 'none':
                            dos_meshfn_dir = datadir

                        meshfn_specfn = glob.glob(
                            dio.prepdir(dos_meshfn_dir) +
                            'meshfn_*localization.txt')
                        print 'meshfn_specfn = ', meshfn_specfn
                        if meshfn_specfn:
                            with open(meshfn_specfn[0], 'r') as myfile:
                                meshfn = myfile.read().replace('\n', '')
                            if lp is not None:
                                print 'Loading based on lp...'
                                import lepm.lattice_class
                                import lepm.gyro_lattice_class
                                # lp = {'LatticeTop': params['LatticeTop'], 'meshfn': params['meshfn']}
                                lat = lepm.lattice_class.Lattice(lp=lp)
                                lat.load()
                                mlat = lepm.magnetic_gyro_lattice_class.MagneticGyroLattice(
                                    lat, lp)
                                loczfn = dio.prepdir(
                                    meshfn) + 'localization' + mlat.lp[
                                        'meshfn_exten'] + '.txt'
                                specmeshfn_xy = lat.xy
                            else:
                                print 'plotting.time_domain_magnetic: no lp supplied, assuming default lattice ' +\
                                      'params to load localization in attempt to load localization...'
                                loczfn = dio.prepdir(
                                    meshfn) + 'localization_magnetic.txt'
                                try:
                                    specmeshfn_xy = np.loadtxt(meshfn +
                                                               '_xy.txt')
                                except:
                                    specmeshfn_xy = np.loadtxt(meshfn +
                                                               '_xy.txt',
                                                               delimiter=',')

                            localization = np.loadtxt(loczfn, delimiter=',')
                            ill = localization[:, 2]
                            ill_full = np.zeros(len(eigval), dtype=float)
                            ill_full[0:int(len(eigval) * 0.5)] = ill[::-1]
                            ill_full[int(len(eigval) * 0.5):len(eigval)] = ill
                            colorV = ill_full
                            linewidth = 0
                            cax_label = r'$\lambda^{-1}$'
                            colormap = 'viridis'
                            vmin_hdr = 0.0
                            vmax_hdr = 1. / (np.max(
                                np.abs(specmeshfn_xy.ravel())))
                            cbar_ticklabels = ['0', r'$1/L$', r'$2/L$']
                            cbar_nticks = 3
                        else:
                            print 'plotting.time_domain_magnetic: Did not find ipr or localization in datadirs,' +\
                                  ' attempting to load based on lp...'
                            if lp is not None:
                                print 'Loading based on lp...'
                                import lepm.lattice_class
                                import lepm.gyro_lattice_class
                                # lp = {'LatticeTop': params['LatticeTop'], 'meshfn': params['meshfn']}
                                lat = lepm.lattice_class.Lattice(lp=lp)
                                lat.load()
                                mlat = lepm.magnetic_gyro_lattice_class.MagneticGyroLattice(
                                    lat, lp)
                                if mlat.lp['periodicBC']:
                                    localization = mlat.get_localization()
                                    ill = localization[:, 2]
                                    ill_full = np.zeros(len(eigval),
                                                        dtype=float)
                                    ill_full[0:int(len(eigval) *
                                                   0.5)] = ill[::-1]
                                    ill_full[int(len(eigval) *
                                                 0.5):len(eigval)] = ill
                                    colorV = ill_full
                                    cax_label = r'$\lambda^{-1}$'
                                    vmin_hdr = 0.0
                                    vmax_hdr = 1. / (np.max(np.abs(
                                        xy0.ravel())))
                                else:
                                    ipr = mlat.get_ipr()
                                    colorV = 1. / ipr
                                    cax_label = r'$p$'
                                    colormap = 'viridis_r'
                                    vmin_hdr = None
                                    vmax_hdr = None
                                    cbar_ticklabels = None
                                    cbar_nticks = 4
                                linewidth = 0
                            else:
                                print 'Did not supply lp and neither ipr nor localization are in datadir!'
                                colorV = None
                                linewidth = 1
                                cax_label = ''
                                colormap = 'viridis'
                                vmin_hdr = None
                                vmax_hdr = None
                                cbar_ticklabels = None
                                cbar_nticks = 4

            plt.close('all')
            if np.max(xy0[:, 0]) - np.min(
                    xy0[:, 0]) > 2.0 * (np.max(xy0[:, 1]) - np.min(xy0[:, 1])):
                # Plot will be very wide, so initialize a wide plot (landscape 16:9)
                orientation = 'landscape'
                # Note: header axis is [0.30, 0.80, 0.45, 0.18]
                if title == '' or title is None:
                    ax_pos = [0.1, 0.05, 0.8, 0.54]
                    cbar_pos = [0.79, 0.80, 0.012, 0.15]
                else:
                    ax_pos = [0.1, 0.03, 0.8, 0.50]
                    cbar_pos = [0.79, 0.70, 0.012, 0.15]
            else:
                # Plot will be roughly square or tall, so initialize a portfolio-style plot
                orientation = 'portrait'
                if title == '' or title is None:
                    ax_pos = [0.1, 0.10, 0.8, 0.60]
                    cbar_pos = [0.79, 0.80, 0.012, 0.15]
                else:
                    ax_pos = [0.1, 0.03, 0.8, 0.60]
                    cbar_pos = [0.79, 0.75, 0.012, 0.15]

            # Determine line width
            if len(xy0) > 2000:
                lw = 1
            else:
                lw = 2

            if cax_label == r'$\lambda^{-1}$':
                if 'penrose' in lp['LatticeTop']:
                    dos_ylabel = 'Density of states, ' + r'$D(\omega)$' + '\nfor periodic approximant'
                else:
                    dos_ylabel = 'Density of states, ' + r'$D(\omega)$' + '\nfor periodic system'
                ylabel_pad = 30
                ylabel_rot = 90
            else:
                dos_ylabel = r'$D(\omega)$'
                ylabel_pad = 20
                ylabel_rot = 0

            print 'plt.get_fignums() = ', plt.get_fignums()
            fig, DOS_ax, ax = \
                leplt.initialize_eigvect_DOS_header_plot(eigval, xy0, sim_type='gyro',
                                                         page_orientation=orientation,
                                                         ax_pos=ax_pos, cbar_pos=cbar_pos,
                                                         colorV=colorV, vmin=vmin_hdr, vmax=vmax_hdr,
                                                         DOSexcite=DOSexcite, linewidth=linewidth,
                                                         cax_label=cax_label, colormap=colormap,
                                                         cbar_nticks=cbar_nticks,
                                                         cbar_tickfmt='%0.2f', cbar_ticklabels=cbar_ticklabels,
                                                         cbar_labelpad=17,
                                                         yaxis_ticks=[], ylabel=dos_ylabel,
                                                         ylabel_rot=ylabel_rot, ylabel_pad=ylabel_pad,
                                                         nbins=120, xlabel_pad=15)
            # DOSexcite = (frequency, sigma_time)
            # amp(x) = exp[- acoeff * time**2]
            # amp(k) = sqrt(pi/acoeff) * exp[- pi**2 * k**2 / acoeff]
            # So 1/(2 * sigma_freq**2) = pi**2 /acoeff
            # So sqrt(acoeff/(2 * pi**2)) = sigma_freq

            # sigmak = 1./DOSexcite[1]
            # xlims = DOS_ax.get_xlim()
            # ktmp = np.linspace(xlims[0], xlims[1], 300)
            # gaussk = 0.8 * DOS_ax.get_ylim()[1] * np.exp(-(ktmp - DOSexcite[0])**2 / (2. * sigmak))
            # DOS_ax.plot(ktmp, gaussk, 'r-')
            # plt.sca(ax)
        else:
            print 'Could not find eigval.pkl to load for DOS portion of data2stills plots!'
            ax = plt.gca()
    else:
        ax = plt.gca()

    # Check for evolving rest lengths in params
    if 'prestrain' in params:
        prestrain = params['prestrain']
    else:
        prestrain = 0.

    if 'shrinkrate' in params:
        shrinkrate = params['shrinkrate']
    else:
        shrinkrate = 0.0

    if roughmov:
        print 'creating rough gyro movie...'
        tdgyros.stills2mov_gyro(fig,
                                ax,
                                do1,
                                xyfiles,
                                KLfiles,
                                xy0files,
                                xy0,
                                NL,
                                KL,
                                BM0,
                                params,
                                hh,
                                numbering,
                                index_sz,
                                outdir,
                                name,
                                simoutdir,
                                update_KL_each_timestep,
                                deform_xy0,
                                exaggerate,
                                xlimv,
                                ylimv,
                                climv,
                                resolution,
                                color_particles,
                                shrinkrate,
                                prestrain,
                                framerate=float(framerate) / 5.,
                                mov_exten='_rough',
                                linewidth=lw,
                                startind=0,
                                title=title,
                                show_bonds=False,
                                **kwargs)

    # Now do detailed movie if rough is False
    if not rough:
        print 'creating fine gyro movie (not skipping any frames)...'
        doall = [0] + range(0, len(xyfiles))
        # do2 = list(set(doall)-set(do1))
        # ftodo = do1 + do2

        print 'tdmagnetic: exiting here since it is broken here'
        # sys.exit()
        tdgyros.stills2mov_gyro(fig,
                                ax,
                                doall,
                                xyfiles,
                                KLfiles,
                                xy0files,
                                xy0,
                                NL,
                                KL,
                                BM0,
                                params,
                                hh,
                                numbering,
                                index_sz,
                                outdir,
                                name,
                                simoutdir,
                                update_KL_each_timestep,
                                deform_xy0,
                                exaggerate,
                                xlimv,
                                ylimv,
                                climv,
                                resolution,
                                color_particles,
                                shrinkrate,
                                prestrain,
                                framerate=framerate,
                                mov_exten=mov_exten,
                                linewidth=lw,
                                startind=0,
                                title=title,
                                movname=movname,
                                show_bonds=False,
                                **kwargs)

        if rm_stills:
            # Delete the original images
            print 'Deleting folder ' + simoutdir + 'stills/'
            subprocess.call(['rm', '-r', simoutdir + 'stills/'])
        with open(meshfn + '/harmonic_diffusivity_sigmay.pkl',
                  "rb") as input_file:
            SSy = pickle.load(input_file)
        with open(meshfn + '/eigval_mass.pkl', "rb") as input_file:
            eigval = pickle.load(input_file)
    else:
        xyload, NLload, KLload, meshfn = le.find_lattice(args.LatticeTop,
                                                         shape,
                                                         sourcedir,
                                                         NH,
                                                         NV,
                                                         lattice_params=lp)
        xy = xyload.astype(float)
        NL = NLload.astype(int)
        KL = KLload.astype(int)
        BL = le.NL2BL(NL, KL)
        try:
            z = le.compute_bulk_z(xy, NL, KL)
        except:
            print 'Could not compute coordination (perhaps too few pts). \nSetting z=0.'
            z = 0
        OmK = args.Omk * KL.astype(float)
        Omg = args.Omg * np.ones_like(xy[:, 0])

        params = {}
        NP = len(xy)

        # Make or load Dynamical Matrix
        if args.basis == 'XY':
            # Check if eigvect, eigval, DM exist
            print '/n/n/n find-->', glob.glob(meshfn + '/eigval_mass.pkl')
示例#4
0
def le_plot_gyros(xy, xy0, NL, KL, BM, params, t, ii, name, fig, ax, outdir, climv='auto', exaggerate=1.0,
                  dpi=300, fontsize=12, title='', **kwargs):
    """Plots a single gyroscopic lattice time step using timestep plot.

    Parameters
    ----------
    t : float
        time stamp for image
    ii : int
        index to name file ( ie 'name_000ii.png')
    name : string
        the name of the file (before _index.png)
    fig : matplotlib.pyplot figure handle, or 'none'
        the figure on which to plot the gyros. If 'none', uses plt.gcf() and clears figure.
    ax : matplotlib.pyplot axis handle, or 'none'
        the axis on which to plot the gyros. If 'none', uses plt.gca()
    outdir : string
        The output directory for the image
    climv : float or tuple
        Color limit for coloring bonds by bond strain, overriddes params['climv'] if climv!='auto'
        If 'climv' is not a key in params, and climv=='auto', then uses default min/max.
        If 'climv' is a key in params, and climv=='auto', then uses params['climv'].
    exaggerate : float (default 1.0 --> in which case it is ignored)
        Exaggerate the displacements of each particle from its initial position by this factor. Ignored if == 1.0
    dpi : float
        pixels per inch, resolution of saved plot
    **kwargs: Additional timestep_plot() keyword arguments
        color_particles='k', fontsize=14, linewidth=2

    Returns
    ----------
    """
    # If fig and ax are not supplied, declare them
    if fig is None or fig == 'none':
        fig = plt.gcf()
        plt.clf()
    if ax is None or ax == 'none':
        ax = plt.gca()

    # make output dir
    outdir = dio.prepdir(outdir)
    dio.ensure_dir(outdir)
    # set range of window from first values
    if 'xlimv' in params:
        xlimv = params['xlimv']
        if 'ylimv' in params:
            ylimv = params['ylimv']
        else:
            ylimv = (xlimv - max(xy0[:, 0])) + np.ceil(max(xy0[:, 1]))
    else:
        xlimv = np.ceil(max(xy0[:, 0]) * 5./ 4.)
        ylimv = (xlimv - max(xy0[:, 0])) + max(xy0[:, 1])

    # save current data as stills
    index = '{0:08d}'.format(ii)
    outname = outdir + '/' + name + '_' + index + '.png'
    BL = le.NL2BL(NL, KL)
    # print 'BL = ', BL

    suptitle = copy.deepcopy(title)

    if 'prestrain' in params:
        prestrain = params['prestrain']
    else:
        prestrain = 0.

    if 'shrinkrate' in params:
        shrinkrate = params['shrinkrate']
        title = 't = ' + '%07.0f' % t + '  a = ' + '%07.5f' % (1. - shrinkrate * t - prestrain)
    elif 'prestrain' in params:
        shrinkrate = 0.0
        title = 't = ' + '%07.0f' % t + '  a = ' + '%07.5f' % (1. - prestrain)
    else:
        shrinkrate = 0.0
        title = 't = ' + '%07.0f' % t + r' $\Omega_g^{-1}$'

    if exaggerate != 1.0:
        title += '   amplified ' + str(int(exaggerate)) + 'x  '

    if 'Omk' in params and params['Omk'] != -1.:
        title += '\n' + r'$\Omega_g$=' + '{0:.3f}'.format(params['Omg'])
    if 'Omg' in params and params['Omk'] != -1.:
        title += r'   $\Omega_k$=' + '{0:.3f}'.format(params['Omk'][0, 0])
    if 'split_spin' in params:
        title += ' NV=' + str(int(params['NV']))
        if 'split_k' in params:
            title += r'   $k_s$=' + str(params['split_k'])

    # title +='\n'

    # if params['BCtype'] == 'excite':
    #     title += r'   $\omega_d$ = ' + '{0:.3f}'.format(params['frequency'])

    if 'eta' in params:
        if params['eta'] != 0.000:
            title += r'   $\eta$=' + '{0:.3f}'.format(params['eta'])

            # calculate strain
            # bs = bond_strain_list(xy,BL,bL0)

            # if exaggerate==1.0:
            # movie_plot_2D_gyros(xy, BL, bs, outname, title, xlimv, ylimv, climv)
            # else:
            # xye = xy0+(xy-xy0)*exaggerate
            # movie_plot_2D_gyros(xye, BL, bs, outname, title, xlimv, ylimv, climv)

    if climv == 'auto':
        if 'climv' in params:
            climv = params['climv']

    [scat_fg, lines_st, p] = leplt.timestep_plot(xy, xy0, NL, KL, BM, ax=ax, factor=exaggerate, amp=climv, title=title,
                                                 fontsize=fontsize, suptitle=suptitle, **kwargs)

    # print 'color_particles = ', scat_fg
    ax.set_xlim(-xlimv, xlimv)
    ax.set_ylim(-ylimv, ylimv)

    plt.savefig(outname, dpi=dpi)

    # clear_array = [scat_fg, lines_st, p]
    # for i in range(len(clear_array)):
    #     clear_array[i].remove()

    return [scat_fg, lines_st, p]
    print 'Solving haldane eigenvalue problem'
    params = le.load_params(datadir)
    xyload = np.loadtxt(datadir + 'xy.txt',
                        delimiter=',',
                        skiprows=1,
                        usecols=(0, 1),
                        unpack=True)
    KLload = np.loadtxt(datadir + 'KL.txt', delimiter=',', skiprows=1)
    NLload = np.loadtxt(datadir + 'NL.txt', delimiter=',', skiprows=1)
    xy0 = (xyload.T).astype(float)
    xy = np.dstack((xy0[:, 0], xy0[:, 1]))[0]
    NL = (NLload).astype(np.intc)
    KL = (KLload).astype(np.intc)
    NP = np.shape(KL)[0]
    NN = np.shape(KL)[1]
    BL = le.NL2BL(NL, KL)
    eigvect, eigval, DM = le.save_normal_modes_haldane(datadir,
                                                       xy,
                                                       NL,
                                                       KL,
                                                       BL,
                                                       epsilon=epsilon)

    np.savetxt(datadir + 'haldane_matrix.txt', DM, delimiter=',')
    le.plot_complex_matrix(DM,
                           name='Dyn. M.',
                           outpath=datadir + 'haldane_matrix',
                           show=False,
                           clear=True)
    le.plot_complex_matrix(DM,
                           name='Dyn. M.',
示例#6
0
def stills2mov_util(todo,
                    xyfiles,
                    KLfiles,
                    params,
                    h,
                    numbering,
                    index_sz,
                    framedir_name,
                    name,
                    update_KL_each_timestep,
                    exaggerate,
                    xlimv,
                    ylimv,
                    climv,
                    framerate=10,
                    mov_exten=''):
    """Make a sequence of images and save it as a movie. This funciton is a utility function called by data2stills_2D()

    Parameters
    ----------
    todo : int array or list
        The indices of the stills to plot and save in a movie
    xyfiles : list of strings
        paths of xy data to load
    KLfiles : list of strings
        paths of connectivity files to load, if connectivity changes during sequence
    params : dict
        parameters for the simulation
    h : float
        timestep
    numbering : string specifier ('natural' or other)
        Whether to place the index of the frame as the index of the output timestep or of the frame index
    index_sz : int
        How many digits in the index (with leading zeros)
    framedir_name : str
        path for the frames
    name : str
        non-index part of the frame names
    update_KL_each_timestep : bool
        Whether connectivity is changing during simulation
    exaggerate : float
        Exaggeration of the displacement
    xlimv : tuple of floats
        limits for x axis
    ylimv : tuple of floats
        limits for y axis
    climv : tuple of floats
        limits for color axis
    mov_exten : str (optional, default is '')
        an extension to the movie name describing the movie
    """
    # Go through data and save as stills
    for i in todo:
        if np.mod(i, 50) == 0:
            print 'Saving still:' + str(i) + '/' + str(len(todo))

        xy = np.loadtxt(xyfiles[i], delimiter=',', usecols=(0, 1))

        iterind = (xyfiles[i].split('_')[-1]).split('.')[0]

        if numbering == 'natural':
            index = ('{0:0' + index_sz + 'd}').format(i)
        else:
            index = iterind

        outname = datadir + framedir_name + '/' + name + index + '.png'

        # Recalculate bo for each timestep if KL is evolving
        if update_KL_each_timestep:
            KL = np.loadtxt(KLfiles[i], delimiter=',')

            BL = le.NL2BL(NL, KL)

            # Calc rest bond lengths
            # --> have to do this if bonds are cut so that BL and bo are same size
            # --> can't do if statement if rough is False
            # if np.count_nonzero(KL)!=nzcount: #can only do this is rough is true (or if in order)
            bo = le.bond_length_list(xy0, BL)

        if 'prestrain' in params:
            prestrain = params['prestrain']
        else:
            prestrain = 0.

        if 'shrinkrate' in params:
            shrinkrate = params['shrinkrate']
            title = 't = ' + '%09.4f' % (float(iterind) * h) + '  a = ' + \
                    '%07.5f' % (1. - shrinkrate * float(iterind) * h - prestrain)
        elif 'prestrain' in params:
            shrinkrate = 0.0
            title = 't = ' + '%09.4f' % (
                float(iterind) * h) + '  a = ' + '%07.5f' % (1. - prestrain)
        else:
            shrinkrate = 0.0
            title = 't = ' + '%09.4f' % (float(iterind) * h)

        print 'Calculating bond strain... '
        # calculate strain
        bs = le.bond_strain_list(
            xy, BL, bo * (1. - shrinkrate * (float(iterind) * h) - prestrain))
        # if bond lengths are all unity, then simple:
        # bs = bond_strain_list(xy,BL, np.ones_like(BL[:,0]))

        if exaggerate == 1.0:
            movie_plot_2D(xy,
                          BL,
                          bs,
                          outname,
                          title,
                          xlimv=xlimv,
                          ylimv=ylimv,
                          climv=climv)
        else:
            print 'making frame in movie plot'
            xye = xy0 + (xy - xy0) * exaggerate
            movie_plot_2D(xye,
                          BL,
                          bs,
                          outname,
                          title,
                          xlimv=xlimv,
                          ylimv=ylimv,
                          climv=climv)

    # MAKE MOVIE
    hostdir = datadir + 'stills/'
    fname, index_sz = dio.get_fname_and_index_size(hostdir)
    print 'index_sz = ', index_sz
    print 'hostdir = ', hostdir
    fps = 15
    imgname = hostdir + fname
    paths = datadir.split('/')
    datedir = ''
    for ii in range(len(paths) - 2):
        pn = paths[ii]
        datedir += pn + '/'
    movname = datedir + datadir.split('/')[-2]

    subprocess.call([
        './ffmpeg', '-framerate',
        str(framerate), '-i', imgname + '%' + str(index_sz) + 'd.png',
        movname + mov_exten + '.mov', '-vcodec', 'libx264', '-profile:v',
        'main', '-crf', '12', '-threads', '0', '-r', '30', '-pix_fmt',
        'yuv420p'
    ])
示例#7
0
def load(lat, meshfn='auto', load_polygons=False, load_LVUC=False, load_gxy=False, check=False):
    """Load a saved lattice into the lattice instance. If meshfn is specified, loads that lattice.
        Otherwise, attempts to load lattice based on parameter lat.lp['meshfn']. If that is also unavailable,
        loads from lp[rootdir]/networks/lat.LatticeTop/lat.lp[lattice_exten]_NH_x_NV.
    """
    print '\n\n\n\nLoading network: meshfn == ', meshfn
    if meshfn == 'auto':
        fn = lat.automeshfn()
    else:
        fnglob = sorted(glob.glob(meshfn))
        print 'lattice_functions: globbing meshfn: fnglob = ', fnglob
        is_a_dir = np.where(np.array([os.path.isdir(ii) for ii in fnglob]))[0]
        print 'lattice_functions: meshfn = ', meshfn
        fn = fnglob[is_a_dir[0]]
        # print 'is_a_dir = ', is_a_dir
        # print 'np.size(is_a_dir) = ', np.size(is_a_dir)
        # print 'fn = ', fn
        if np.size(is_a_dir) > 1:
            print 'lattice_functions: Found multiple lattices matching meshfn in lattice.load(). Using the first matching lattice.'
            fn = fn[0]

        lat.lp['meshfn'] = fn

    if fn[-1] == '/':
        fn = fn[:-1]
    lat.lp = le.load_params(fn + '/', params=lat.lp, paramsfn='lattice_params', ignore=physics_to_ignore())
    if not glob.glob(lat.lp['meshfn']):
        print "\n\nlattice_class: Warning: could not find lp[meshfn] = \n" + \
              lat.lp['meshfn'] + '\nso instead replacing lp[meshfn] with --->\n' + fn + '\n\n'
        lat.lp['meshfn'] = fn

    # Fix up the lattice parameters dictionary by adding any necessary key-vals that aren't already in there
    lat.lp = complete_lp(lat.lp)

    lat.xy = np.loadtxt(fn + '_xy.txt', delimiter=',')
    lat.NL = np.loadtxt(fn + '_NL.txt', delimiter=',', dtype=int)
    lat.KL = np.loadtxt(fn + '_KL.txt', delimiter=',', dtype=int)

    try:
        lat.BL = np.loadtxt(fn + '_BL.txt', delimiter=',', dtype=int)
    except IOError:
        lat.BL = le.NL2BL(lat.NL, lat.KL)

    # Make sure that BL is 2D, even if only one row
    if len(np.shape(lat.BL)) < 2:
        lat.BL = np.array([lat.BL])

    name = fn.split('/')[-1]

    try:
        print 'lattice_functions.load(): loading ' + name + '_PVxydict/Pvx/Pvy.txt ...'
        lat.PVxydict = le.load_evaled_dict(fn + '/', filename=name + '_PVxydict.txt')
        lat.PVx = np.loadtxt(fn + '/' + name + '_PVx.txt', delimiter=',', dtype=float)
        lat.PVy = np.loadtxt(fn + '/' + name + '_PVy.txt', delimiter=',', dtype=float)
        if (lat.PVx == lat.PVy).all():
            print 'lattice_functions:PVx and PVy are identical (this was a bug in early versions of the code), need to trash one: ' \
                  'overwriting then exiting.'
            lat.PVx, lat.PVy = le.PVxydict2PVxPVy(lat.PVxydict, lat.NL)
            header = 'PVx: ijth element of PVx are the x-components of the vector taking NL[i,j] to ' + \
                     'its image as seen by particle i'
            np.savetxt(fn + '/' + name + '_PVx.txt', lat.PVx, delimiter=',', header=header)
            header = 'PVy: ijth element of PVy are the y-components of the vector taking NL[i,j] to ' + \
                     'its image as seen by particle i'
            np.savetxt(fn + '/' + name + '_PVy.txt', lat.PVy, delimiter=',', header=header)
            print 'lattice_class: exiting here'
            sys.exit()

        # load periodic vectors if they exists
        try:
            lat.load_PV(meshfn=fn)
            print 'lattice_functions: loaded PV'
        except IOError:
            print 'lattice_functions.load(): no PV file exists, saving it...'
            lat.PV = le.PVxydict2PV(lat.PVxydict, periodic_strip=lat.lp['periodic_strip'])
            lat.save_PV()
        # print 'lattice_functions: exiting here for debug'
    except:
        print 'lattice_functions.load(): Could not load PVx and PVy, loading PVxydict to calculate them...'
        # print ' --> actually, just exiting since this should not happen anymore!'
        # sys.exit()
        try:
            lat.PVxydict = le.load_evaled_dict(fn + '/', filename=name + '_PVxydict.txt')
            lat.PVx, lat.PVy = le.PVxydict2PVxPVy(lat.PVxydict, lat.NL, lat.KL)
            header = 'PVx: ijth element of PVx are the x-components of the vector taking NL[i,j] to ' + \
                     'its image as seen by particle i'
            np.savetxt(fn + '/' + name + '_PVx.txt', lat.PVx, delimiter=',', header=header)
            header = 'PVy: ijth element of PVy are the y-components of the vector taking NL[i,j] to ' + \
                     'its image as seen by particle i'
            np.savetxt(fn + '/' + name + '_PVy.txt', lat.PVy, delimiter=',', header=header)
            try:
                lat.load_PV(meshfn=fn)
            except IOError:
                lat.PV = le.PVxydict2PV(lat.PVxydict)

        except IOError:
            print 'lattice_functions: No periodic vectors stored for this lattice, assuming not periodic.'

    # Load the boundary of the sample, since that is cheap (sqrt(N) at most)
    single_bndy = glob.glob(fn + '/' + name + '_boundary.txt')
    double_bndy = glob.glob(fn + '/' + name + '_boundary0.txt')
    if single_bndy:
        boundary = np.loadtxt(fn + '/' + name + '_boundary.txt', delimiter=',', dtype=int)
        lat.boundary = boundary
    elif double_bndy:
        boundary0 = np.loadtxt(fn + '/' + name + '_boundary0.txt', delimiter=',', dtype=int)
        boundary1 = np.loadtxt(fn + '/' + name + '_boundary1.txt', delimiter=',', dtype=int)
        boundary = (boundary0, boundary1)
        lat.boundary = boundary
    else:
        if not lat.lp['periodicBC'] or lat.lp['periodic_strip']:
            print 'lattice_functions: No boundary file found for (partially/fully) openBC network, saving the boundary to file...'
            bndry = lat.get_boundary(attribute=True, check=check)
            print 'lattice_functions: bndry = ', bndry
            if isinstance(bndry, tuple):
                np.savetxt(fn + '/' + name + '_boundary0.txt', bndry[0], fmt='%d',
                           header="indices of one of the network's boundaries -- boundary zero")
                np.savetxt(fn + '/' + name + '_boundary1.txt', bndry[1], fmt='%d',
                           header="indices of one of the network's boundaries -- boundary one")
            else:
                np.savetxt(fn + '/' + name + '_boundary.txt', bndry, fmt='%d',
                           header='indices of the network boundary')

            # print image of the boundaries
            try:
                lat.plot_boundary(show=False, save=True, outdir=fn + '/', outname=name + '_boundary.png')
            except:
                print('Could not save boundary as png. Skipping...')

    if load_LVUC:
        lat.load_LUVC()

    if load_polygons:
        lat.load_polygons()

    if load_gxy:
        lat.load_gxy()

    # Convert some floats to ints
    if isinstance(lat.lp['NH'], float):
        lat.lp['NH'] = int(lat.lp['NH'])
    if isinstance(lat.lp['NV'], float):
        lat.lp['NV'] = int(lat.lp['NV'])