Exemple #1
0
    # Define description of the network topology
    if args.LatticeTop == 'iscentroid':
        description = 'voronoized jammed'
    elif args.LatticeTop == 'kagome_isocent':
        description = 'kagomized jammed'
    elif args.LatticeTop == 'hucentroid':
        description = 'voronoized hyperuniform'
    elif args.LatticeTop == 'kagome_hucent':
        description = 'kagomized hyperuniform'
    elif args.LatticeTop == 'kagper_hucent':
        description = 'kagome decoration percolation'

    rootdir = '/Users/npmitchell/Dropbox/Soft_Matter/GPU/'
    outdir = rootdir + 'experiments/DOS_scaling/' + args.LatticeTop + '/'
    le.ensure_dir(outdir)
    lp = {
        'LatticeTop': args.LatticeTop,
        'NH': NH,
        'NV': NV,
        'rootdir': rootdir,
        'periodicBC': True,
    }

    # Collate DOS for many lattices
    gc = gyro_collection.GyroCollection()
    if args.LatticeTop == 'iscentroid':
        gc.add_meshfn(
            '/Users/npmitchell/Dropbox/Soft_Matter/GPU/networks/'+args.LatticeTop+'/'+\
            args.LatticeTop+'_square_periodic_hexner_size'+str(args.NP_load)+'_conf*_NP*'+str(args.NP_load))
    elif args.LatticeTop == 'kagome_isocent':
Exemple #2
0
def projector_site_vs_dist_glatparam(gcoll,
                                     omegac,
                                     proj_XY,
                                     plot_mag=True,
                                     plot_diff=False,
                                     save_plt=True,
                                     alpha=1.0,
                                     maxdistlines=True,
                                     reverse_order=False,
                                     check=True):
    """THIS HAS NOT BEEN UPDATED FOR BOTT INDEX SPECIFIC CALC
    Compare the projector values at distances relative to a particular site (gyro at location proj_XY).

    Parameters
    ----------
    gcoll : GyroCollection instance
        The collection of gyro_lattices for which to compare projectors as fn of distance from a given site.
    omegac : float
        Cutoff frequency for the projector
    proj_XY : 2 x 1 float numpy array
        The location at which to find the nearest gyro and consider projector elements relative to this site.
    plot : bool
        Whether to plot magproj vs dist for all GyroLattices in gcoll
    check : bool
        Display intermediate results

    Returns
    -------
    dist_list : list of NP x NP float arrays
        Euclidean distances between points. Element i,j is the distance between particle i and j
    proj_list : list of evxyprojs (2 x 2*NP float arrays)
        Each element is like magproj, but with x and y components separate.
        So, element 0,2*j gives the magnitude of the x component of the projector connecting the site in question
        to the x component of particle j and element 1,2*j+1 gives the
        magnitude of the y component of the projector connecting the site in question to the y component of particle j.
    """
    proj_list = []
    dist_list = []
    kk = 0
    if plot_mag:
        # magnitude plot
        mfig, magax, mcbar = leplt.initialize_1panel_cbar_fig()
    if plot_diff:
        # difference plot
        dfig, dax, dcbar = leplt.initialize_1panel_cbar_fig()
        # difference fraction plot
        dffig, dfax, dfcbar = leplt.initialize_1panel_cbar_fig()
        if maxdistlines:
            maxdist = []

    sat = 1
    light = 0.6
    colors = lecmaps.husl_palette(n_colors=len(gcoll.gyro_lattices),
                                  s=sat,
                                  l=light)
    if reverse_order:
        glat_list = gcoll.gyro_lattices[::-1]
    else:
        glat_list = gcoll.gyro_lattices

    for glat in glat_list:
        proj_ind = ((glat.lattice.xy - proj_XY)[:, 0]**2 +
                    (glat.lattice.xy - proj_XY)[:, 1]**2).argmin()
        outdir = dio.prepdir(glat.lp['meshfn'].replace('networks',
                                                       'projectors'))
        outfn = outdir + glat.lp[
            'LatticeTop'] + "_dist_singlept_{0:06d}".format(proj_ind) + ".pkl"

        if check:
            print 'identified proj_ind = ', proj_ind
            newfig = plt.figure()
            glat.lattice.plot_numbered(ax=plt.gca())

        # attempt to load
        if glob.glob(outfn):
            with open(outfn, "rb") as fn:
                dist = pickle.load(fn)

            outfn = outdir + glat.lp[
                'LatticeTop'] + "_evxyproj_singlept_{0:06d}".format(
                    proj_ind) + ".pkl"
            with open(outfn, "rb") as fn:
                evxyproj = pickle.load(fn)
        else:
            # compute dists and evxyproj_proj_ind
            xydiff = glat.lattice.xy - glat.lattice.xy[proj_ind]
            dist = np.sqrt(xydiff[:, 0]**2 + xydiff[:, 1]**2)
            print 'bottmagneticgyrofns: calculating projector...'
            proj = calc_small_projector(glat, omegac, attribute=False)

            outdir = dio.prepdir(glat.lp['meshfn'].replace(
                'networks', 'projectors'))
            le.ensure_dir(outdir)
            # save dist as pickle
            with open(outfn, "wb") as fn:
                pickle.dump(dist, fn)

            # evxyproj has dims 2 xlen(evect)
            evxyproj = np.dstack(
                (proj[2 * proj_ind, :], proj[2 * proj_ind + 1, :]))[0].T
            # save evxyproj as pickle
            outfn = outdir + glat.lp[
                'LatticeTop'] + "_evxyproj_singlept_{0:06d}".format(
                    proj_ind) + ".pkl"
            with open(outfn, "wb") as fn:
                pickle.dump(evxyproj, fn)

        proj_list.append(evxyproj)
        dist_list.append(dist)

        if plot_mag:
            tmp = np.sqrt(
                np.abs(evxyproj[0]).ravel()**2 +
                np.abs(evxyproj[1]).ravel()**2)
            magproj = np.array([
                np.sqrt(tmp[2 * ind].ravel()**2 + tmp[2 * ind + 1].ravel()**2)
                for ind in range(len(dist))
            ])
            magax.scatter(dist,
                          np.log10(magproj),
                          s=1,
                          color=colors[kk],
                          alpha=alpha)

        if plot_diff:
            if kk > 0:
                # find particles that are the same as in the reference network
                same_inds = np.where(le.dist_pts(glat.lattice.xy, xy0) == 0)
                # Order them by distance
                current = np.array(
                    [[2 * same_inds[0][ii], 2 * same_inds[0][ii] + 1]
                     for ii in range(len(same_inds[0]))])
                current = current.ravel()
                orig = np.array(
                    [[2 * same_inds[1][ii], 2 * same_inds[1][ii] + 1]
                     for ii in range(len(same_inds[0]))])
                orig = orig.ravel()

                # if check:
                #     origfig = plt.figure()
                #     origax = origfig.gca()
                #     [origax, origaxcb] = glat.lattice.plot_numbered(fig=origfig, ax=origax, axis_off=False,
                #                                                     title='Original lattice for proj comparison')
                #     origax.scatter(glat.lattice.xy[same_inds[0], 0], glat.lattice.xy[same_inds[0], 1])
                #     plt.pause(5)
                #     plt.close()
                if len(current) > 0:
                    evxydiff = evxyproj[:, current] - evxyproj0[:, orig]
                    tmp = np.sqrt(
                        np.abs(evxydiff[0]).ravel()**2 +
                        np.abs(evxydiff[1]).ravel()**2)
                    magdiff = np.array([
                        np.sqrt(tmp[2 * ind].ravel()**2 +
                                tmp[2 * ind + 1].ravel()**2)
                        for ind in range(len(same_inds[0]))
                    ])
                    # magnitude of fractional difference
                    magfdiff = np.array([
                        magdiff[same_inds[0][ii]] / mag0[same_inds[1][ii]]
                        for ii in range(len(same_inds[0]))
                    ])
                    dax.scatter(dist[same_inds[0]],
                                magdiff,
                                s=1,
                                color=colors[kk],
                                alpha=alpha)
                    dfax.scatter(dist[same_inds[0]],
                                 magfdiff,
                                 s=1,
                                 color=colors[kk],
                                 alpha=alpha)
                    if maxdistlines:
                        maxdist.append(np.max(dist[same_inds[0]]))

            else:
                origfig = plt.figure()
                origax = origfig.gca()
                [origax, origaxcb] = glat.lattice.plot_numbered(
                    fig=origfig,
                    ax=origax,
                    axis_off=False,
                    title='Original lattice for proj comparison')
                origfig.show()
                plt.close()
                evxyproj0 = copy.deepcopy(evxyproj)
                xy0 = copy.deepcopy(glat.lattice.xy)
                tmp = np.sqrt(
                    np.abs(evxyproj[0]).ravel()**2 +
                    np.abs(evxyproj[1]).ravel()**2)
                mag0 = np.array([
                    np.sqrt(tmp[2 * ind].ravel()**2 +
                            tmp[2 * ind + 1].ravel()**2)
                    for ind in range(len(dist))
                ])

        kk += 1

    # Save plots
    outsplit = dio.prepdir(glat.lp['meshfn'].replace('networks',
                                                     'projectors')).split('/')
    outdir = '/'
    for sdir in outsplit[0:-2]:
        outdir += sdir + '/'
    outdir += '/'

    if plot_mag:
        if maxdistlines and plot_diff:
            ylims = magax.get_ylim()
            print 'ylims = ', ylims
            ii = 1
            for dd in maxdist:
                magax.plot([dd, dd],
                           np.array([ylims[0], ylims[1]]),
                           '-',
                           color=colors[ii])
                ii += 1

        magax.set_title('Magnitude of projector vs distance')
        magax.set_xlabel(r'$|\mathbf{x}_i - \mathbf{x}_0|$')
        magax.set_ylabel(r'$|P_{i0}|$')
        # make a scalar mappable for colorbar'
        husl_cmap = lecmaps.husl_cmap(s=sat, l=light)
        sm = plt.cm.ScalarMappable(cmap=husl_cmap,
                                   norm=plt.Normalize(vmin=0, vmax=1))
        sm._A = []
        cbar = plt.colorbar(sm, cax=mcbar, ticks=[0, 1])
        cbar.ax.set_ylabel(r'$\alpha$', rotation=0)
        if save_plt:
            print 'kfns: saving magnitude comparison plot for gcoll (usually run from kitaev_collection)...'
            mfig.savefig(outdir + glat.lp['LatticeTop'] +
                         "_magproj_singlept.png",
                         dpi=300)
        else:
            plt.show()
    if plot_diff:
        dax.set_title('Projector differences')
        dax.set_xlabel(r'$|\mathbf{x}_i - \mathbf{x}_0|$')
        dax.set_ylabel(r'$|\Delta P_{i0}|$')
        # make a scalar mappable for colorbar'
        husl_cmap = lecmaps.husl_cmap(s=sat, l=light)
        sm = plt.cm.ScalarMappable(cmap=husl_cmap,
                                   norm=plt.Normalize(vmin=0, vmax=1))
        sm._A = []
        cbar = plt.colorbar(sm, cax=dcbar, ticks=[0, 1])
        cbar.ax.set_ylabel(r'$\alpha$', rotation=0)
        if maxdistlines:
            # Grab ylimits for setting after adding lines
            ylims = dax.get_ylim()
            df_ylims = dfax.get_ylim()
            ii = 1
            for dd in maxdist:
                dax.plot([dd, dd],
                         np.array([-0.05, -0.005]),
                         '-',
                         color=colors[ii])
                dfax.plot([dd, dd],
                          np.array([df_ylims[0], -0.01]),
                          '-',
                          color=colors[ii])
                ii += 1
            dax.set_ylim(-0.05, ylims[1])
            dfax.set_ylim(df_ylims[0], df_ylims[1])
        # now do fractional difference magnitude plot
        dfax.set_title('Fractional projector differences')
        dfax.set_xlabel(r'$|\mathbf{x}_i - \mathbf{x}_0|$')
        dfax.set_ylabel(r'$|\Delta P_{i0}|/|P_{i0}|$')
        # make a scalar mappable for colorbar'
        cbar = plt.colorbar(sm, cax=dfcbar, ticks=[0, 1])
        cbar.ax.set_ylabel(r'$\alpha$', rotation=0)
        if save_plt:
            print 'kfns: saving diff plot for gcoll projecctors (usually run from kitaev_collection)...'
            dfig.savefig(outdir + glat.lp['LatticeTop'] +
                         "_diffproj_singlept.png",
                         dpi=300)
            dffig.savefig(outdir + glat.lp['LatticeTop'] +
                          "_diffproj_singlept_fractionaldiff.png",
                          dpi=300)
            dfax.set_ylim(-0.1, 1)
            dffig.savefig(outdir + glat.lp['LatticeTop'] +
                          "_diffproj_singlept_fractionaldiff_zoom.png",
                          dpi=300)
            dfax.set_ylim(-0.02, 0.1)
            dffig.savefig(outdir + glat.lp['LatticeTop'] +
                          "_diffproj_singlept_fractionaldiff_extrazoom.png",
                          dpi=300)
        elif not plot_mag:
            plt.show()

    return dist_list, proj_list
save_ims = not args.skip_ims
save_DOS_ims = not args.skip_DOS_ims
save_DOS_pkl = args.save_DOS
check = args.check
checkout = args.checkout

# Use each value of N
for kk in range(len(Narr)):
    if doNP:
        N = Narr[kk]
    else:
        N = Narr[kk]

    print '\nN = ', N
    dataNdir = datadir + 'N_{0:03d}'.format(N) + '/'
    le.ensure_dir(dataNdir)
    NH = N
    NV = N
    Ns = min(NH, NV)

    # Get polygon over which to sum
    if LatticeTop in ['triangular', 'triangularz']:
        dist = 1.
    #else:
    #    # distance for NH=1 is dist
    #    if args.delta == '0.667':
    #        dist = 2.*le.polygon_apothem(1.0,6) # distance across one hexagon of bonds with bondlength=1
    #    else:
    #        a1, a2 = deformed_hexcell_to_hexagonal_sidelengths(args.delta,args.NH,args.NV)

    # Make Lattice
Exemple #4
0
def bond_length_histogram(xy,
                          NL,
                          KL,
                          BL,
                          PVx=[],
                          PVy=[],
                          fig=None,
                          ax=None,
                          outdir=None,
                          check=False,
                          savetxt=True):
    """Histogram the bond lengths of the lattice.
    If fig or axis is not None, adds to that fig/axis.
    
    Parameters
    ----------
    xy : NP x 2 float array
        positions of point set
    NL : NP x max(#neighbors) int array
        The ith row contains indices for the neighbors for the ith point
    KL : NP x max(#neighbors) int array
        spring connection/constant list, where 1 corresponds to a true connection,
        0 signifies that there is not a connection, -1 signifies periodic bond
    BL : array of dimension #bonds x 2
        Each row is a bond and contains indices of connected points. Negative values denote particles connected
        through periodic bonds.
    PVx : NP x NN float array (optional, for periodic lattices)
        ijth element of PVx is the x-component of the vector taking NL[i,j] to its image as seen by particle i
    PVy : NP x NN float array (optional, for periodic lattices)
        ijth element of PVy is the y-component of the vector taking NL[i,j] to its image as seen by particle i
    fig : matplotlib figure instance or None
        The figure in which to plot the bond length histogram. If None, uses current figure
    ax : matplotlib axis instance or None
        The axis in which to plot the histogram. If None, uses current axis.
    outdir : string or None
        The file path in which to save the figure, if not None
    check : bool
        Whether to view intermediate results
    savetxt: bool
        Whether to save the bin values and counts as a text file. Outdir must be specified for this to have an effect
        when True.

    Returns
    ----------
    bL : Nbonds x 1 float array
        bond lengths of the lattice
    """
    if fig is None and ax is None:
        close_fig = True
        fig = plt.gcf()
        fig.clf()
        ax = plt.gca()
    elif fig is None and ax is not None:
        close_fig = False
        fig = plt.gcf()
    else:
        close_fig = False

    if outdir is not None:
        infodir = outdir
        saveout = True
        le.ensure_dir(infodir)
    else:
        saveout = False

    # Make dir for lattice info
    BM = le.NL2BM(xy, NL, KL, PVx=PVx, PVy=PVy)
    bL = le.BM2bL(NL, BM, BL)
    nbonds, bins, patches = ax.hist(bL, bins=int(len(bL) * 0.5))
    #ax.set_title('Bond Lengths')
    ax.set_xlabel('Bond Length')
    ax.set_ylabel('Frequency')

    if saveout:
        plt.savefig(infodir + 'bond_lengths.png')
    if check:
        plt.show()
    if close_fig:
        plt.clf()

    if savetxt and saveout:
        print 'Calling bond_length_histogram with savetxt == True'
        print 'savetxt =', savetxt
        # get centers of each bin
        binc = 0.5 * (bins[1:] + bins[:-1])
        MM = np.dstack((binc, nbonds))[0]
        header = 'Bond length histogram: center of bin, number of bonds in that bin'
        np.savetxt(infodir + 'bond_length_hist.txt',
                   MM,
                   fmt='%.18e %i',
                   header=header,
                   delimiter=',')

    return bL, nbonds, bins
def plot_projector_locality_singlept(haldane_lattice,
                                     proj_ind,
                                     dists,
                                     magproj,
                                     ax=None,
                                     save=True,
                                     outdir=None,
                                     network_str='none',
                                     show=False,
                                     alpha=1.0):
    """
    Plot the locality of the projection operator wrt a point

    Parameters
    ----------
    haldane_lattice : HaldaneLattice instance
        The network on which to characterize the projector
    proj_ind : int
        The haldane index to analyze wrt
    dists : dists : NP x NP float array
        Euclidean distances between points. Element i,j is the distance between particle i and j
    magproj : NP x NP float array
        Element i,j gives the magnitude of the projector connecting site i to particle j
    evxymag : 2*NP x NP float array
        Same as magproj, but with x and y components separate. So, element 2*i,j gives the magnitude of the x component
        of the projector connecting site i to the full xy of particle j and element 2*i+1,j gives the
        magnitude of the y component of the projector connecting site i to the full xy of particle j.
    outdir : str or None
        Path to save dists and magproj as pickles in outdir, also saves plots there
    network_str : str
        Description of the network for the title of the plot. If 'none', network_str = haldane_lattice.lp['LatticeTop'].
    show : bool
        Plot the result (forces a matplotlib close event)
    alpha : float
        opacity
    """
    # Initialize plot
    if ax is None:
        fig, axes = leplt.initialize_1panel_fig(Wfig=90,
                                                Hfig=None,
                                                x0frac=0.15,
                                                y0frac=0.15,
                                                wsfrac=0.4,
                                                hs=None,
                                                vspace=5,
                                                hspace=8,
                                                tspace=10,
                                                fontsize=8)
        ax = axes[0]

    if network_str is 'none':
        network_str = haldane_lattice.lp['LatticeTop']

    ax.scatter(dists[proj_ind],
               np.log10(magproj[proj_ind]),
               s=1,
               color='k',
               alpha=alpha)
    ax.set_title('Locality of projection operator $P$\nfor ' + network_str +
                 ' network')
    ax.set_xlabel('Distance $|\mathbf{x}_i-\mathbf{x}_j|$')
    ax.set_ylabel('$\log_{10} |P_{ij}|$')
    if save:
        if outdir is None:
            outdir = le.prepdir(haldane_lattice.lp['meshfn'].replace(
                'networks', 'projectors'))
        le.ensure_dir(outdir)
        plt.savefig(outdir + haldane_lattice.lp['LatticeTop'] +
                    '_projector_xy2_log_{0:06d}'.format(proj_ind) + '.png',
                    dpi=300)

        ax.set_xlim(-0.5, 5)
        ax.set_ylim(-3, 0)
        plt.savefig(outdir + haldane_lattice.lp['LatticeTop'] +
                    '_projector_xy2_zoom_log_{0:06d}'.format(proj_ind) +
                    '.png',
                    dpi=300)

        # save dists and magproj as pkl
        outfn = outdir + haldane_lattice.lp[
            'LatticeTop'] + "_dists_singlept_{0:06d}".format(proj_ind) + ".pkl"
        with open(outfn, "wb") as fn:
            pickle.dump(dists[proj_ind], fn)
        with open(
                outdir + haldane_lattice.lp['LatticeTop'] +
                "_magproj_{0:06d}".format(proj_ind) + ".pkl", "wb") as fn:
            pickle.dump(magproj[proj_ind], fn)
    if show:
        plt.show()
def plot_projector_locality(haldane_lattice,
                            dists,
                            magproj,
                            evxymag,
                            outdir=None,
                            network_str='none',
                            show=False,
                            alpha=None):
    """
    Plot the locality of the projection operator

    Parameters
    ----------
    haldane_lattice : HaldaneLattice instance
        The network on which to characterize the projector
    dists : dists : NP x NP float array
        Euclidean distances between points. Element i,j is the distance between particle i and j
    magproj : NP x NP float array
        Element i,j gives the magnitude of the projector connecting site i to particle j
    evxymag : 2*NP x NP float array
        Same as magproj, but with x and y components separate. So, element 2*i,j gives the magnitude of the x component
        of the projector connecting site i to the full xy of particle j and element 2*i+1,j gives the
        magnitude of the y component of the projector connecting site i to the full xy of particle j.
    outdir : str or None
        Path to save dists and magproj as pickles in outdir, also saves plots there
    network_str : str
        Description of the network for the title of the plot. If 'none', network_str = haldane_lattice.lp['LatticeTop'].
    show : bool
        Plot the result (forces a matplotlib close event)
    alpha : float or None
        opacity. If none, sets alpha = 3./len(dists)
    """
    if alpha is None:
        alpha = 3. / len(dists)

    # Initialize plot
    fig, ax = leplt.initialize_1panel_fig(Wfig=90,
                                          Hfig=None,
                                          x0frac=0.15,
                                          y0frac=0.15,
                                          wsfrac=0.4,
                                          hs=None,
                                          vspace=5,
                                          hspace=8,
                                          tspace=10,
                                          fontsize=8)

    # print 'np.shape(xymag) = ', np.shape(xymag)
    for ind in range(len(dists)):
        ax[0].scatter(dists[ind],
                      np.log10(evxymag[:, 2 * ind].ravel()),
                      s=1,
                      color='r',
                      alpha=alpha)
        ax[0].scatter(dists[ind],
                      np.log10(evxymag[:, 2 * ind + 1].ravel()),
                      s=1,
                      color='b',
                      alpha=alpha)

    if network_str is 'none':
        network_str = haldane_lattice.lp['LatticeTop']

    ax[0].set_title('Locality of projection operator $P$\nfor ' + network_str +
                    ' network')
    ax[0].set_xlabel('Distance $|\mathbf{x}_i-\mathbf{x}_j|$')
    ax[0].set_ylabel('$|P_{ij}|$')
    if outdir is None:
        outdir = le.prepdir(haldane_lattice.lp['meshfn'].replace(
            'networks', 'projectors'))
    le.ensure_dir(outdir)
    plt.savefig(outdir + haldane_lattice.lp['LatticeTop'] +
                '_projector_log.png',
                dpi=300)

    ax[0].set_xlim(-0.5, 5)
    ax[0].set_ylim(-3.5, 0.5)
    plt.savefig(outdir + haldane_lattice.lp['LatticeTop'] +
                '_projector_zoom_log.png',
                dpi=300)
    if show:
        plt.show()
    plt.clf()

    # Combine x and y
    # put projector magnitude on log-log plot
    fig, ax = leplt.initialize_1panel_fig(Wfig=90,
                                          Hfig=None,
                                          x0frac=0.15,
                                          y0frac=0.15,
                                          wsfrac=0.4,
                                          hs=None,
                                          vspace=5,
                                          hspace=8,
                                          tspace=10,
                                          fontsize=8)
    for ind in range(len(dists)):
        ax[0].scatter(dists[ind],
                      np.log10(magproj[ind]),
                      s=1,
                      color='k',
                      alpha=alpha)
    ax[0].set_title('Locality of projection operator $P$\nfor ' + network_str +
                    ' network')
    ax[0].set_xlabel('Distance $|\mathbf{x}_i-\mathbf{x}_j|$')
    ax[0].set_ylabel('$\log_{10} |P_{ij}|$')
    if outdir is None:
        outdir = le.prepdir(haldane_lattice.lp['meshfn'].replace(
            'networks', 'projectors'))
    le.ensure_dir(outdir)
    plt.savefig(outdir + haldane_lattice.lp['LatticeTop'] +
                '_projector_xy2_log.png',
                dpi=300)

    ax[0].set_xlim(-0.5, 5)
    ax[0].set_ylim(-3.5, 0.5)
    plt.savefig(outdir + haldane_lattice.lp['LatticeTop'] +
                '_projector_xy2_zoom_log.png',
                dpi=300)
    if show:
        plt.show()
    plt.clf()

    # save dists and magproj as pkl
    with open(outdir + haldane_lattice.lp['LatticeTop'] + "_dists.pkl",
              "wb") as fn:
        pickle.dump(dists, fn)
    with open(outdir + haldane_lattice.lp['LatticeTop'] + "_magproj.pkl",
              "wb") as fn:
        pickle.dump(magproj, fn)
def movie_cherns_varyloc(ccoll, title='Chern number calculation for varied positions',
                         filename='chern_varyloc', rootdir=None, exten='.png', max_boxfrac=None, max_boxsize=None,
                         xlabel=None, ylabel=None, step=0.5, fracsteps=False, framerate=3):
    """Plot the chern as a function of space for each haldane_lattice examined

    Parameters
    ----------
    ccoll : ChernCollection instance
        The collection of varyloc chern calcs to make into a movie
    title : str
        title of the movie
    filename : str
        the name of the files to save
    rootdir : str or None
        The cproot directory to use (usually self.cp['rootdir'])
    exten : str (.png, .jpg, etc)
        file type extension
    max_boxfrac : float
        Fraction of spatial extent of the sample to use as maximum bound for kitaev sum
    max_boxsize : float or None
        If None, uses max_boxfrac * spatial extent of the sample asmax_boxsize
    xlabel : str
        label for x axis
    ylabel : str
        label for y axis
    step : float (default=1.0)
        how far apart to sample kregion vertices in varyloc
    fracsteps : bool
    framerate : int
        The framerate at which to save the movie
    max_boxfrac : float
        Fraction of spatial extent of the sample to use as maximum bound for kitaev sum
    max_boxsize : float or None
        If None, uses max_boxfrac * spatial extent of the sample asmax_boxsize
    """
    rad = 1.0
    divgmap = cmaps.diverging_cmap(250, 10, l=30)

    # plot it
    for hlat_name in ccoll.cherns:
        hlat = ccoll.cherns[hlat_name][0].haldane_lattice
        if hlat.lp['shape'] == 'square':
            # get extent of the network from Bounding box
            Radius = np.abs(hlat.lp['BBox'][0, 0])
        else:
            # todo: allow different geometries
            pass

        # Initialize the figure
        h_mm = 90
        w_mm = 120
        # To get space between subplots, figure out how far away ksize region needs to be, based on first chern
        # Compare max ksize to be used with spatial extent of the lattice. If comparable, make hspace large.
        # Otherwise, use defaults
        ksize = ccoll.cherns[hlat_name][0].chern_finsize[:, 2]
        cgll = ccoll.cherns[hlat_name][0].haldane_lattice.lattice
        maxsz = max(np.max(cgll.xy[:, 0]) - np.min(cgll.xy[:, 0]),
                    np.max(cgll.xy[:, 1]) - np.min(cgll.xy[:, 1]))
        if max_boxsize is not None:
            ksize = ksize[ksize < max_boxsize]
        else:
            if max_boxfrac is not None:
                max_boxsize = max_boxfrac * maxsz
                ksize = ksize[ksize < max_boxsize]
            else:
                ksize = ksize
                max_boxsize = np.max(ksize)
        if max_boxsize > 0.9 * maxsz:
            center0_frac = 0.3
            center2_frac = 0.75
        elif max_boxsize > 0.65 * maxsz:
            center0_frac = 0.35
            center2_frac = 0.72
        elif max_boxsize > 0.55 * maxsz:
            center0_frac = 0.375
            center2_frac = 0.71
        else:
            center0_frac = 0.4
            center2_frac = 0.7

        fig, ax = initialize_1p5panelcbar_fig(Wfig=w_mm, Hfig=h_mm, wsfrac=0.4, wssfrac=0.4,
                                              center0_frac=center0_frac, center2_frac=center2_frac)

        # dimensions of video in pixels
        final_h = 720
        final_w = 960
        actual_dpi = final_h / (float(h_mm) / 25.4)

        # Add the network to the figure
        hlat = ccoll.cherns[hlat_name][0].haldane_lattice
        netvis.movie_plot_2D(hlat.lattice.xy, hlat.lattice.BL, 0 * hlat.lattice.BL[:, 0],
                             None, None, ax=ax[0], fig=fig, axcb=None,
                             xlimv='auto', ylimv='auto', climv=0.1, colorz=False, ptcolor=None, figsize='auto',
                             colormap='BlueBlackRed', bgcolor='#ffffff', axis_off=True, axis_equal=True,
                             lw=0.2)

        # Add title
        if title is not None:
            ax[0].annotate(title, xy=(0.5, .95), xycoords='figure fraction',
                           horizontalalignment='center', verticalalignment='center')
        if xlabel is not None:
            ax[0].set_xlabel(xlabel)
        if ylabel is not None:
            ax[0].set_xlabel(ylabel)

        # Position colorbar
        sm = plt.cm.ScalarMappable(cmap=divgmap, norm=plt.Normalize(vmin=-1, vmax=1))
        # fake up the array of the scalar mappable.
        sm._A = []
        cbar = plt.colorbar(sm, cax=ax[1], orientation='horizontal', ticks=[-1, 0, 1])
        ax[1].set_xlabel(r'$\nu$')
        ax[1].xaxis.set_label_position("top")
        ax[2].axis('off')

        # Add patches (rectangles from cherns at each site) to the figure
        print 'Opening hlat_name = ', hlat_name
        done = False
        ind = 0
        while done is False:
            rectps = []
            colorL = []
            for chernii in ccoll.cherns[hlat_name]:
                # Grab small, medium, and large circles
                ksize = chernii.chern_finsize[:, 2]
                if max_boxsize is not None:
                    ksize = ksize[ksize < max_boxsize]
                else:
                    if max_boxfrac is not None:
                        cgll = chernii.haldane_lattice.lattice
                        maxsz = max(np.max(cgll.xy[:, 0]) - np.min(cgll.xy[:, 0]),
                                    np.max(cgll.xy[:, 1]) - np.min(cgll.xy[:, 1]))
                        max_boxsize = max_boxfrac * maxsz
                        ksize = ksize[ksize < max_boxsize]
                    else:
                        ksize = ksize
                        max_boxsize = np.max(ksize)

                # print 'ksize =  ', ksize
                # print 'max_boxsize =  ', max_boxsize

                xx = float(chernii.cp['poly_offset'].split('/')[0])
                yy = float(chernii.cp['poly_offset'].split('/')[1])
                nu = chernii.chern_finsize[:, -1]
                rad = step
                rect = plt.Rectangle((xx-rad*0.5, yy-rad*0.5), rad, rad, ec="none")
                colorL.append(nu[ind])
                rectps.append(rect)

            p = PatchCollection(rectps, cmap=divgmap, alpha=1.0, edgecolors='none')
            p.set_array(np.array(np.array(colorL)))
            p.set_clim([-1., 1.])

            # Add the patches of nu calculations for each site probed
            ax[0].add_collection(p)

            # Draw the kitaev cartoon in second axis with size ksize[ind]
            polygon1, polygon2, polygon3 = kfns.get_kitaev_polygons(ccoll.cp['shape'], ccoll.cp['regalph'],
                                                                    ccoll.cp['regbeta'], ccoll.cp['reggamma'],
                                                                    ksize[ind])
            patchlist = []
            patchlist.append(patches.Polygon(polygon1, color='r'))
            patchlist.append(patches.Polygon(polygon2, color='g'))
            patchlist.append(patches.Polygon(polygon3, color='b'))
            polypatches = PatchCollection(patchlist, cmap=cm.jet, alpha=0.4, zorder=99, linewidths=0.4)
            colors = np.linspace(0, 1, 3)[::-1]
            polypatches.set_array(np.array(colors))
            ax[2].add_collection(polypatches)
            ax[2].set_xlim(ax[0].get_xlim())
            ax[2].set_ylim(ax[0].get_ylim())

            # Save the plot
            # make index string
            indstr = '_{0:06d}'.format(ind)
            hlat_cmesh = kfns.get_cmeshfn(ccoll.cherns[hlat_name][0].haldane_lattice.lp, rootdir=rootdir)
            specstr = '_Nks' + '{0:03d}'.format(len(ksize)) + '_step' + sf.float2pstr(step) \
                      + '_maxbsz' + sf.float2pstr(max_boxsize)
            outdir = hlat_cmesh + '_' + hlat.lp['LatticeTop'] + '_varyloc_stills' + specstr + '/'
            fnout = outdir + filename + specstr + indstr + exten
            print 'saving figure: ' + fnout
            le.ensure_dir(outdir)
            fig.savefig(fnout, dpi=actual_dpi*2)

            # Save at lower res after antialiasing
            f_img = Image.open(fnout)
            f_img.resize((final_w, final_h), Image.ANTIALIAS).save(fnout)

            # clear patches
            p.remove()
            polypatches.remove()
            # del p

            # Update index
            ind += 1
            if ind == len(ksize):
                done = True

        # Turn into movie
        imgname = outdir + filename + specstr
        movname = hlat_cmesh + filename + specstr + '_mov'
        subprocess.call(['./ffmpeg', '-framerate', str(int(framerate)), '-i', imgname + '_%06d' + exten, movname + '.mov',
                         '-vcodec', 'libx264', '-profile:v', 'main', '-crf', '12', '-threads', '0',
                         '-r', '30', '-pix_fmt', 'yuv420p'])
def calc_kitaev_chern_from_evs(xy,
                               eigval,
                               eigvect,
                               cp,
                               pp=None,
                               check=False,
                               contributions=False,
                               verbose=False,
                               vis_exten='.png',
                               contrib_exten='.pdf',
                               delta=2. / 3.):
    """Compute the chern number for a gyro_lattice

    Parameters
    ----------
    xy : NP x 2 float array
        points of the gyro network
    eigval : 2NP x 1 complex array
        Eigenvalues of the system
    eigvect : 2NP x 2NP complex array
        Eigenvectors of the system
    pp : len(gyro_lattice.lattice.xy)*2 x len(gyro_lattice.lattice.xy)*2 complex array (optional)
        projection operator, if already calculated previously. If None, this function calculates this.
    check : bool (optional)
        Display intermediate results
    contributions : bool (optional)
        Compute the contribution of each individual particle to the chern result for the given summation regions
    verbose : bool (optional)
        Print more output on command line
    vis_exten : str ('.png', '.pdf', '.jpg', etc, default = '.png')
        Extension for the plotted output, if cp['save_ims'] == True
    contrib_exten : str ('.png', '.pdf', '.jpg', etc, default = '.pdf')
        Extension for the plotted contributions of each particle, if cp['save_ims'] == True and contributions==True

    Returns
    -------
    chern_finsize : len(cp['ksize_frac_arr']) x 6 complex array
        np.dstack((Nreg1V, ksize_frac_arr, ksize_V, ksys_sizeV, ksys_fracV, nuV))[0]
    params_regs : dict
        For each kitaev region size (ksize), there is a key '{0:0.3f}'.format(ksize) and value pair, of the form
        params_regs['{0:0.3f}'.format(ksize)] = {'reg1': reg1, 'reg2': reg2, 'reg3': reg3,
                                                 'polygon1': polygon1, 'polygon2': polygon2, 'polygon3': polygon3,
                                                 'reg1_xy': reg1_xy, 'reg2_xy': reg2_xy, 'reg3_xy': reg3_xy}
    contribs : dict or None
        If contributions == True, contribs is a dictionary with values storing the contributions to the chern result for
        each particle in reg1, reg2, and reg3. Contribs has keys which are '{0:0.3f}'.format(ksize) for each ksize, and
        each value of contribs['{0:0.3f}'.format(ksize)] is itself a dictionary with keys 'reg1', 'reg2', 'reg3' and
        values as the contributions of each particle, for particles indexed by reg1, 2, 3.
        ie, contribs['{0:0.3f}'.format(ksize)] = {'reg1': cb1, 'reg2': cb2, 'reg3': cb3}
        Here cb1,2,3 are (# particles in region n) x 1 complex arrays -- contributions of each particle in each region
        to the total result (when summed over the other two regions)
    """
    save_ims = cp['save_ims']
    modsave = cp['modsave']
    shape = cp['shape']
    ksize_frac_arr = cp['ksize_frac_arr']
    omegac = cp['omegac']
    if save_ims:
        # Register colormaps
        lecmaps.register_colormaps()
        imagedir = cp['cpmeshfn'] + 'visualization/'
        le.ensure_dir(imagedir)

    NP = len(xy)

    if pp is None:
        print 'Computing projector...'
        pp = calc_projector_from_evs(eigval, eigvect, omegac)

    # Initialize empty region index arrays for speedup by comparing with prev iteration
    reg1 = np.array([])
    reg2 = np.array([])
    reg3 = np.array([])
    nu = 0.0 + 0.0 * 1j
    epskick = 0.001 * np.random.rand(len(xy), 2)

    # Preallocate arrays
    nuV = np.zeros(len(ksize_frac_arr))
    Nreg1V = np.zeros(len(ksize_frac_arr))
    ksize_V = np.zeros(len(ksize_frac_arr))
    ksys_sizeV = np.zeros(len(ksize_frac_arr))
    ksys_fracV = np.zeros(len(ksize_frac_arr))
    params_regs = {}
    if contributions:
        contribs = {}
    else:
        contribs = None

    # Get max(width, height) of network
    maxsz = max(
        np.max(xy[:, 0]) - np.min(xy[:, 0]),
        np.max(xy[:, 1]) - np.min(xy[:, 1]))

    # If we want to look at individual contributions from each gyro, find h first
    if contributions and NP < 800:
        method = '2current'
        print 'constructing 2-current h_ijk...'
        hh = np.einsum('jk,kl,lj->jkl', pp, pp, pp) - np.einsum(
            'jl,lk,kj->jkl', pp, pp, pp)
        # hh = np.zeros((len(pp), len(pp), len(pp)), dtype=complex)
        # for j in range(len(pp)):
        #     for k in range(len(pp)):
        #         for l in range(len(pp)):
        #             hh[j, k, l] = pp[j, k] * pp[k, l] * pp[l, j] - pp[j, l] * pp[l, k] * pp[k, j]
        hh *= 12 * np.pi * 1j
    else:
        method = 'projector'

    jj = 0
    # for each ksize_frac, perform sum
    for kk in range(len(ksize_frac_arr)):
        ksize_frac = ksize_frac_arr[kk]
        ksize = ksize_frac * maxsz
        if verbose:
            print 'ksize = ', ksize

        polygon1, polygon2, polygon3 = kfns.get_kitaev_polygons(
            shape,
            cp['regalph'],
            cp['regbeta'],
            cp['reggamma'],
            ksize,
            delta_pi=delta,
            outerH=cp['outerH'])
        if cp['polyT']:
            polygon1 = np.fliplr(polygon1)
            polygon2_tmp = np.fliplr(polygon3)
            polygon3 = np.fliplr(polygon2)
            polygon2 = polygon2_tmp

        if cp['poly_offset'] != 'none' and cp['poly_offset'] is not None:
            if '/' in cp['poly_offset']:
                splitpo = cp['poly_offset'].split('/')
            else:
                splitpo = cp['poly_offset'].split('_')
            # print 'split_po = ', splitpo
            poly_offset = np.array([float(splitpo[0]), float(splitpo[1])])
            polygon1 += poly_offset
            polygon2 += poly_offset
            polygon3 += poly_offset

        # Save the previous reg1,2,3
        r1old = reg1
        r2old = reg2
        r3old = reg3

        reg1_xy = le.inds_in_polygon(xy + epskick, polygon1)
        reg2_xy = le.inds_in_polygon(xy + epskick, polygon2)
        reg3_xy = le.inds_in_polygon(xy + epskick, polygon3)

        if cp['basis'] == 'XY':
            reg1 = np.sort(np.vstack((2 * reg1_xy, 2 * reg1_xy + 1)).ravel())
            reg2 = np.sort(np.vstack((2 * reg2_xy, 2 * reg2_xy + 1)).ravel())
            reg3 = np.sort(np.vstack((2 * reg3_xy, 2 * reg3_xy + 1)).ravel())
        elif cp['basis'] == 'psi':
            if verbose:
                print 'stacking regions with right-moving selves...'
            reg1 = np.sort(np.vstack((reg1, NP + reg1)).ravel())
            reg2 = np.sort(np.vstack((reg2, NP + reg2)).ravel())
            reg3 = np.sort(np.vstack((reg3, NP + reg3)).ravel())

        if contributions:
            if method == '2current':
                nu, [cb1, cb2,
                     cb3] = kfns.sum_kitaev_with_contributions(reg1,
                                                               reg2,
                                                               reg3,
                                                               r1old,
                                                               r2old,
                                                               r3old,
                                                               hh,
                                                               nu,
                                                               verbose=verbose)
            else:
                nu, [cb1, cb2,
                     cb3] = kfns.sum_kitaev_with_contributions_projector(
                         reg1,
                         reg2,
                         reg3,
                         r1old,
                         r2old,
                         r3old,
                         pp,
                         nu,
                         verbose=verbose)
            contribs['{0:0.3f}'.format(ksize)] = {
                'reg1': cb1,
                'reg2': cb2,
                'reg3': cb3
            }
        else:
            nu = kfns.sum_kitaev_projector(reg1,
                                           reg2,
                                           reg3,
                                           r1old,
                                           r2old,
                                           r3old,
                                           pp,
                                           nu,
                                           verbose=verbose)

        # print 'nu = ', nu
        nuV[kk] = np.real(nu)
        Nreg1V[kk] = len(reg1)
        ksize_V[kk] = ksize
        ksys_sizeV[kk] = len(reg1) + len(reg2) + len(reg3)
        ksys_fracV[kk] = ksys_sizeV[kk] / len(xy)

        # Save regions
        params_regs['{0:0.3f}'.format(ksize)] = {
            'reg1': reg1,
            'reg2': reg2,
            'reg3': reg3,
            'polygon1': polygon1,
            'polygon2': polygon2,
            'polygon3': polygon3,
            'reg1_xy': reg1_xy,
            'reg2_xy': reg2_xy,
            'reg3_xy': reg3_xy
        }
        if save_ims and (kk % modsave == 0 or kk == (len(ksize_frac_arr) - 1)):
            plt.clf()
            filename = 'division_lattice_regions_{0:06d}'.format(
                jj) + vis_exten
            # title = r'Division of lattice: $\nu = ${0:0.3f}'.format(nu.real)
            # Commented out: plot just the regs and the title
            # plot_chern_realspace(gyro_lattice, reg1_xy, reg2_xy, reg3_xy, polygon1, polygon2, polygon3,
            #                     ax=None, outdir=imagedir, filename=filename, title=title, check=check)
            # New way: plot the regs with title plus curve of nu vs ksize
            kfns.plot_chern_realspace_2panel(xy,
                                             ksys_fracV,
                                             nuV,
                                             kk,
                                             reg1_xy,
                                             reg2_xy,
                                             reg3_xy,
                                             polygon1,
                                             polygon2,
                                             polygon3,
                                             outdir=imagedir,
                                             filename=filename,
                                             title='',
                                             check=check)

            if contributions:
                # Save plot of contributions from individual gyroscopes
                plt.clf()
                filename = 'contributions_ksize{0:0.3f}'.format(
                    ksize_frac) + contrib_exten
                kfns.plot_chern_contributions_experiment(xy,
                                                         reg1,
                                                         reg2,
                                                         reg3,
                                                         cb1,
                                                         cb2,
                                                         cb3,
                                                         polygon1,
                                                         polygon2,
                                                         polygon3,
                                                         basis=cp['basis'],
                                                         outdir=imagedir,
                                                         filename=filename)

            jj += 1

    if save_ims:
        movname = cp['cpmeshfn'] + 'visualization'
        imgname = imagedir + 'division_lattice_regions_'
        print 'glob.glob(imgname) = ', glob.glob(imgname + '*')
        print 'len(glob.glob(imgname)[0]) = ', len(glob.glob(imgname + '*'))
        framerate = float(len(glob.glob(imgname + '*'))) / 7.0
        print 'framerate = ', framerate
        subprocess.call([
            './ffmpeg', '-framerate',
            str(framerate), '-i', imgname + '%6d.png', movname + '.mov',
            '-vcodec', 'libx264', '-profile:v', 'main', '-crf', '12',
            '-threads', '0', '-r', '1', '-pix_fmt', 'yuv420p'
        ])

    chern_finsize = np.dstack(
        (Nreg1V, ksize_frac_arr, ksize_V, ksys_sizeV, ksys_fracV, nuV))[0]
    return chern_finsize, params_regs, contribs
Exemple #9
0
    def save_chern(self):
        # Make output directories
        le.ensure_dir(self.cp['cpmeshfn'])
        if self.params_regs or self.contribs is not None:
            le.ensure_dir(self.cp['cpmeshfn'] + 'params_regs/')
        if self.contribs is not None:
            le.ensure_dir(self.cp['cpmeshfn'] + 'contribs/')

        # Save the chern calculation to cp['cpmeshfn']
        if self.chern_finsize is None:
            raise RuntimeError(
                'Cannot save chern calculation since it has not been computed!'
            )

        # Save chern parameters
        fn = self.cp['cpmeshfn'] + 'chern_params.txt'
        header = 'Parameters for chern calculation'
        le.save_dict(self.cp, fn, header)

        # Save chern_finsize
        fn = self.cp['cpmeshfn'] + 'chern_finsize.txt'
        header = 'Nreg1, ksize_frac, ksize, ksys_size (note this is 2*NP_summed), ksys_frac, nu' + \
                 'for Chern calculation: basis=' + \
                 self.cp['basis'] + ' Omg=' + ' Omk=' + '{0:0.3f}'.format(self.gyro_lattice.lp['Omk']) +\
                 ' Omk=' + '{0:0.3f}'.format(self.gyro_lattice.lp['Omk'])

        print 'saving chern_finsize to ', fn
        np.savetxt(fn, self.chern_finsize, delimiter=',', header=header)

        # Save chern_finsize as a plot
        plt.clf()
        plt.plot(self.chern_finsize[:, -2] * 0.5, self.chern_finsize[:, -1],
                 'o-')
        plt.title('Chern number versus system size')
        plt.xlabel('Fraction of system size in sum')
        plt.ylabel('Chern number')
        plt.savefig(self.cp['cpmeshfn'] + 'chern_finsize_ksizeSum.png')
        plt.close('all')

        # Save kitaev region parameters for each ksize
        if self.params_regs or self.contribs is not None:
            for ksize in self.params_regs:
                header = 'Indices of kitaev regions: ksize = ' + le.prepstr(
                    ksize)
                fn = self.cp[
                    'cpmeshfn'] + 'params_regs/params_regs_ksize' + le.prepstr(
                        ksize) + '.txt'
                le.save_dict(self.params_regs[ksize], fn, header)

            print 'saved (many) params_regs. Last one was:', fn

        # Save lattice parameters too for convenience (gives info about disorder, spinning speeds etc)
        print 'saving lattice_params...'
        header = 'Lattice parameters, copied from meshfn: ' + self.gyro_lattice.lp[
            'meshfn']
        le.save_dict(self.gyro_lattice.lp,
                     self.cp['cpmeshfn'] + 'lattice_params.txt', header)

        if self.contribs is not None:
            # Save kitaev region parameters for each ksize
            for ksize in self.contribs:
                header = 'Saving contribs for ksize = ' + le.prepstr(ksize)
                fn = self.cp[
                    'cpmeshfn'] + 'contribs/contribs_ksize' + le.prepstr(
                        ksize) + '.txt'
                le.save_dict(self.contribs[ksize], fn, header)