Beispiel #1
0
    def stage6(self, water_type):
        """
        Arrange water atoms and replacements

        Provided variables:
        atoms: atomic positions of water molecules. (absolute)
        """

        self.logger.info("Stage6: Atomic positions of water.")

        # assert audit_name(water_type), "Dubious water name: {0}".format(water_type)
        # water = importlib.import_module("genice.molecules."+water_type)
        water = safe_import("molecule", water_type)

        try:
            mdoc = water.__doc__.splitlines()
        except BaseException:
            mdoc = []

        for line in mdoc:
            self.logger.info("  " + line)

        self.atoms = arrange_atoms(self.reppositions,
                                   self.repcell,
                                   self.rotmatrices,
                                   water.sites,
                                   water.labels,
                                   water.name,
                                   ignores=set(self.dopants))

        self.logger.info("Stage6: end.")
Beispiel #2
0
 def stage6(self, water_type):
     """
     arrange water atoms and replacements
     """
     self.logger.info("Stage6: Atomic positions of water.")
     # assert audit_name(water_type), "Dubious water name: {0}".format(water_type)
     # water = importlib.import_module("genice.molecules."+water_type)
     water = safe_import("molecule", water_type)
     self.atoms = arrange_atoms(self.reppositions,
                                self.repcell,
                                self.rotmatrices,
                                water.sites,
                                water.labels,
                                water.name,
                                ignores=set(self.dopants))
     self.logger.info("Stage6: end.")
Beispiel #3
0
    def stage6(self, water_type):
        """
        Arrange water atoms and replacements

        Provided variables:
        atoms: atomic positions of water molecules. (absolute)
        """
        self.logger.info("Stage6: Atomic positions of water.")
        # assert audit_name(water_type), "Dubious water name: {0}".format(water_type)
        # water = importlib.import_module("genice.molecules."+water_type)
        water = safe_import("molecule", water_type)
        self.atoms = arrange_atoms(self.reppositions,
                                   self.repcell,
                                   self.rotmatrices,
                                   water.sites,
                                   water.labels,
                                   water.name,
                                   ignores=set(self.dopants))
        self.logger.info("Stage6: end.")
Beispiel #4
0
def iterate(filename, oname, hname, filerange, framerange, suffix=None):
    logger = getLogger()
    rfile = str2range(filerange)
    rframe = str2rangevalues(framerange)
    logger.info(
        "  file number range: {0}:{1}:{2}".format(*str2rangevalues(filerange)))
    logger.info("  frame number range: {0}:{1}:{2}".format(*rframe))
    # test whether filename has a regexp for enumeration
    logger.info(filename)
    m = re.search("%[0-9]*d", filename)
    # prepare file list
    if m is None:
        filelist = [
            filename,
        ]
    else:
        filelist = []
        for num in rfile:
            fname = filename % num
            if os.path.exists(fname):
                filelist.append(fname)
    logger.debug("File list: {0}".format(filelist))
    frame = 0
    for fname in filelist:
        logger.info("  File name: {0}".format(fname))
        # single file may contain multiple frames
        if suffix is None:
            suffix = Path(fname).suffix[1:]
        loader = safe_import("loader", suffix)
        file = open(fname)
        for oatoms, hatoms, cellmat in loader.load_iter(file,
                                                        oname=oname,
                                                        hname=hname):
            if frame == rframe[0]:
                logger.info("Frame: {0}".format(frame))
                yield oatoms, hatoms, cellmat
                rframe[0] += rframe[2]
                if rframe[1] <= rframe[0]:
                    return
            else:
                logger.info("Skip frame: {0}".format(frame))
            frame += 1
Beispiel #5
0
def main():
    # Module-loading paths
    # 1. Look for the modules in the current working directory
    sys.path.append(".")
    #prepare user's workarea
    home = os.path.expanduser("~")
    if os.path.exists(home + "/Library/Application Support"):  #MacOS
        homegenice = home + "/Library/Application Support/GenIce"
    else:
        homegenice = os.path.expanduser(home + "/.genice")  #Other unix
    try:
        os.makedirs(homegenice + "/formats")
        os.makedirs(homegenice + "/lattices")
        os.makedirs(homegenice + "/molecules")
    except:
        pass  #just ignore when failed.
    # 2. Look for user's home.
    sys.path.append(homegenice)

    #Parse options
    options = getoptions()

    #Set verbosity level
    if options.debug:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(asctime)s %(levelname)s %(message)s")
    elif options.quiet:
        logging.basicConfig(level=logging.WARN,
                            format="%(levelname)s %(message)s")
    else:
        #normal
        logging.basicConfig(level=logging.INFO,
                            format="%(levelname)s %(message)s")
    logger = logging.getLogger()
    logger.debug("Debug mode.")
    logger.debug(options.Type)

    water_type = options.water[0]
    guests = options.guests
    lattice_type = options.Type[0]
    file_format = options.format[0]
    seed = options.seed[0]
    rep = options.rep
    density = options.dens[0]
    depolarize = not options.nodep
    anions = dict()
    if options.anions is not None:
        logger.info(options.anions)
        for v in options.anions:
            key, value = v[0].split("=")
            anions[int(key)] = value
    cations = dict()
    if options.cations is not None:
        for v in options.cations:
            key, value = v[0].split("=")
            cations[int(key)] = value
    spot_guests = dict()
    if options.spot_guests is not None:
        for v in options.spot_guests:
            key, value = v[0].split("=")
            spot_guests[int(key)] = value
    groups = dict()
    if options.groups is not None:
        for v in options.groups:
            key, value = v[0].split("=")
            groups[int(key)] = value

    del options  # Dispose for safety.
    # Set random seeds
    random.seed(seed)
    np.random.seed(seed)

    logger.debug("Lattice: {0}".format(lattice_type))
    # Main part of the program is contained in th Formatter object. (See formats/)
    logger.debug("Format: {0}".format(file_format))
    formatter = safe_import("format", file_format)
    lat = lattice.Lattice(
        lattice_type,
        density=density,
        rep=rep,
        depolarize=depolarize,
        cations=cations,
        anions=anions,
        spot_guests=spot_guests,
        spot_groups=groups,
    )
    # These arguments should also be in lattice, not in run()
    lat.format(water_type=water_type, guests=guests, formatter=formatter)
Beispiel #6
0
def main():
    # Module-loading paths
    # 1. Look for the modules in the current working directory
    sys.path.append(".")
    #prepare user's workarea
    home = os.path.expanduser("~")
    if os.path.exists(home + "/Library/Application Support"):  #MacOS
        homegenice = home + "/Library/Application Support/GenIce"
    else:
        homegenice = os.path.expanduser(home + "/.genice")  #Other unix
    try:
        os.makedirs(homegenice + "/formats")
        os.makedirs(homegenice + "/lattices")
        os.makedirs(homegenice + "/molecules")
    except:
        pass  #just ignore when failed.
    # 2. Look for user's home.
    sys.path.append(homegenice)

    #Parse options
    if sys.argv[0].find("analice") >= 0:
        options = getoptions_analice()
        mode = "analice"
    else:
        options = getoptions()
        mode = "genice"

    #Set verbosity level
    if options.debug:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(asctime)s %(levelname)s %(message)s")
    elif options.quiet:
        logging.basicConfig(level=logging.WARN,
                            format="%(levelname)s %(message)s")
    else:
        #normal
        logging.basicConfig(level=logging.INFO,
                            format="%(levelname)s %(message)s")
    logger = logging.getLogger()
    logger.debug("Debug mode.")

    if mode == "genice":
        logger.debug(options.Type)

        water_type = options.water[0]
        guests = options.guests
        lattice_type = options.Type[0]
        file_format = options.format[0]
        seed = options.seed[0]
        rep = options.rep
        density = options.dens[0]
        depolarize = not options.nodep
        asis = options.asis
        anions = dict()
        if options.anions is not None:
            logger.info(options.anions)
            for v in options.anions:
                key, value = v[0].split("=")
                anions[int(key)] = value
        cations = dict()
        if options.cations is not None:
            for v in options.cations:
                key, value = v[0].split("=")
                cations[int(key)] = value
        spot_guests = dict()
        if options.spot_guests is not None:
            for v in options.spot_guests:
                key, value = v[0].split("=")
                spot_guests[int(key)] = value
        groups = dict()
        if options.groups is not None:
            for v in options.groups:
                key, value = v[0].split("=")
                groups[int(key)] = value

        del options  # Dispose for safety.
        # Set random seeds
        random.seed(seed)
        np.random.seed(seed)

        logger.debug("Lattice: {0}".format(lattice_type))
        # Main part of the program is contained in th Formatter object. (See formats/)
        logger.debug("Format: {0}".format(file_format))
        formatter = safe_import("format", file_format)
        # Show the document of the module
        try:
            doc = formatter.__doc__.splitlines()
        except:
            doc = []
        for line in doc:
            logger.info("!!! {0}".format(line))
        lat = lattice.Lattice(
            lattice_type,
            density=density,
            rep=rep,
            depolarize=depolarize,
            asis=asis,
            cations=cations,
            anions=anions,
            spot_guests=spot_guests,
            spot_groups=groups,
        )
        lat.generate_ice(water_type=water_type,
                         guests=guests,
                         formatter=formatter)
    else:  #analice
        logger.debug(options.File)

        water_type = options.water[0]
        file_format = options.format[0]
        oname = options.oatom[0]
        hname = options.hatom[0]
        filename = options.File[0]

        del options  # Dispose for safety.

        # Main part of the program is contained in th Formatter object. (See formats/)
        logger.debug("Format: {0}".format(file_format))
        formatter = safe_import("format", file_format)
        # reuse gromacs plugin to load the file.
        s = "gromacs[{0}:{1}:{2}]".format(filename, oname, hname)
        lat = lattice.Lattice(lattice_type=s)
        lat.analize_ice(water_type=water_type, formatter=formatter)
Beispiel #7
0
    def stage7(self, guests):
        """
        Arrange guest atoms

        Provided variables:
        atoms: atomic positions of all molecules.
        """

        self.logger.info("Stage7: Atomic positions of the guest.")

        if self.cagepos is not None:

            # the cages around the dopants.
            dopants_neighbors = self.dopants_info(self.dopants,
                                                  self.reppositions,
                                                  self.repcagepos,
                                                  self.repcell)

            # put the (one-off) groups
            if len(self.spot_groups) > 0:
                # process the -H option
                for cage, group_to in self.spot_groups.items():
                    group, root = group_to.split(":")
                    self.add_group(cage, group, int(root))

            molecules = defaultdict(list)

            if len(self.spot_guests) > 0:

                # process the -G option
                for cage, molec in self.spot_guests.items():
                    molecules[molec].append(cage)
                    self.filled_cages.add(cage)

            if guests is not None:

                # process the -g option
                for arg in guests:
                    self.logger.debug(arg[0])
                    cagetype, spec = arg[0].split("=")
                    assert cagetype in self.cagetypes, "Nonexistent cage type: {0}".format(
                        cagetype)
                    resident = dict()
                    rooms = list(self.cagetypes[cagetype] - self.filled_cages)

                    for room in rooms:
                        resident[room] = None

                    # spec contains a formula consisting of "+" and "*"
                    contents = spec.split("+")
                    vacant = len(rooms)

                    for content in contents:

                        if "*" in content:
                            molec, frac = content.split("*")
                            frac = float(frac)
                        else:
                            molec = content
                            frac = 1.0

                        nmolec = int(frac * len(rooms) + 0.5)
                        vacant -= nmolec
                        assert vacant >= 0, "Too many guests."
                        remain = nmolec
                        movedin = []

                        while remain > 0:
                            r = random.randint(0, len(rooms) - 1)
                            room = rooms[r]

                            if resident[room] is None:
                                resident[room] = molec
                                molecules[molec].append(room)
                                movedin.append(room)
                                remain -= 1

            # Now ge got the address book of the molecules.
            if len(molecules):
                self.logger.info("  Summary of guest placements:")
                self.guests_info(self.cagetypes, molecules)

            if len(self.spot_groups) > 0:
                self.logger.info("  Summary of groups:")
                self.groups_info(self.groups)

            # semi-guests
            for root, cages in self.groups.items():
                assert root in self.dopants
                name = self.dopants[root]
                molname = "G{0}".format(root)
                pos = self.reppositions[root]
                rot = self.rotmatrices[root]
                self.atoms.append(
                    [0, molname, name,
                     self.repcell.rel2abs(pos), 0])
                del self.dopants[root]  # processed.
                self.logger.debug((root, cages, name, molname, pos, rot))

                for cage, group in cages.items():
                    assert group in self.groups_placer
                    assert cage in dopants_neighbors[root]
                    cpos = self.repcagepos[cage]
                    self.atoms += self.groups_placer[group](cpos, pos,
                                                            self.repcell,
                                                            molname)

            # molecular guests
            for molec, cages in molecules.items():
                gmol = safe_import("molecule", molec)

                try:
                    mdoc = gmol.__doc__.splitlines()
                except BaseException:
                    mdoc = []
                for line in mdoc:
                    logger.info("  " + line)
                cpos = [self.repcagepos[i] for i in cages]
                cmat = [np.identity(3) for i in cages]
                self.atoms += arrange_atoms(cpos, self.repcell, cmat,
                                            gmol.sites, gmol.labels, gmol.name)

        # Assume the dopant is monatomic and replaces one water molecule
        atomset = defaultdict(set)
        for label, name in self.dopants.items():
            atomset[name].add(label)

        for name, labels in atomset.items():
            pos = [self.reppositions[i] for i in sorted(labels)]
            rot = [self.rotmatrices[i] for i in sorted(labels)]
            self.atoms += arrange_atoms(pos, self.repcell, rot, [
                [0., 0., 0.],
            ], [name], name)

        self.logger.info("Stage7: end.")
Beispiel #8
0
    def __init__(self,
                 lattice_type=None,
                 density=0,
                 rep=(1, 1, 1),
                 depolarize=True,
                 asis=False,
                 cations=dict(),
                 anions=dict(),
                 spot_guests=dict(),
                 spot_groups=dict(),
                 ):
        self.logger      = logging.getLogger()
        self.lattice_type = lattice_type
        self.rep         = rep
        self.depolarize  = depolarize
        self.asis        = asis
        self.cations     = cations
        self.anions      = anions
        self.spot_guests = spot_guests
        self.spot_groups = spot_groups
        if lattice_type is None:
            return
        lat = safe_import("lattice", lattice_type)
        # Show the document of the module
        try:
            self.doc = lat.__doc__.splitlines()
        except:
            self.doc = []
        self.doc.append("")
        self.doc.append("Command line: {0}".format(" ".join(sys.argv)))
        for line in self.doc:
            self.logger.info("!!! {0}".format(line))
        # ================================================================
        # rotmatrices (analice)
        #
        try:
            self.rotmatrices = lat.rotmat
        except:
            self.logger.info("No rotmatrices in lattice")
            pass
        # ================================================================
        # waters: positions of water molecules
        #
        self.waters = load_numbers(lat.waters)
        self.logger.debug("Waters: {0}".format(len(self.waters)))
        self.waters = self.waters.reshape((self.waters.size // 3, 3))

        # ================================================================
        # cell: cell dimension
        # celltype: symmetry of the cell
        #   see parse_cell for syntax.
        #
        self.cell = Cell(lat.cell, lat.celltype)
        #self.cell = parse_cell(lat.cell, lat.celltype)

        # ================================================================
        # coord: "relative" or "absolute"
        #   Inside genice, molecular positions are always treated as "relative"
        #
        if lat.coord == "absolute":
            self.waters = self.cell.abs2rel(self.waters)
        self.waters = np.array([w - np.floor(w) for w in self.waters])

        # ================================================================
        # pairs: specify the pairs of molecules that are connected.
        #   Bond orientation will be shuffled later
        #   unless it is "fixed".
        #
        self.pairs = None
        try:
            if type(lat.pairs) is str:
                lines = lat.pairs.split("\n")
                self.pairs = []
                for line in lines:
                    columns = line.split()
                    if len(columns) == 2:
                        i, j = [int(x) for x in columns]
                        self.pairs.append((i, j))
            elif type(lat.pairs) is list:
                self.pairs = lat.pairs
                # for pair in lat.pairs:
                #    self.pairs.append(pair)
        except AttributeError:
            self.logger.info("Graph is not defined.")

        # ================================================================
        # bondlen: specify the bond length threshold.
        #   This is used when "pairs" are not specified.
        #   It is applied to the original positions of molecules (before density setting).
        #
        self.bondlen = None
        try:
            self.bondlen = lat.bondlen
            self.logger.info("Bond length (specified): {0}".format(self.bondlen))
        except AttributeError:
            self.bondlen = 1.1 * shortest_distance(self.waters, self.cell)
            self.logger.info("Bond length (assumed): {0}".format(self.bondlen))
        # Set density
        mass = 18  # water
        NB = 6.022e23
        nmol = self.waters.shape[0]  # nmol in a unit cell
        volume = self.cell.volume()  # volume of a unit cell in nm**3
        density0 = mass * nmol / (NB * volume * 1e-21)
        if density <= 0:
            try:
                self.density = lat.density
            except AttributeError:
                self.logger.info(
                    "Density is not specified. Assume the density from lattice.")
                dmin = shortest_distance(self.waters, self.cell)
                self.logger.info(
                    "Closest pair distance: {0} (should be around 0.276 nm)".format(dmin))
                self.density = density0 / (0.276 / dmin)**3
                # self.density = density0
        else:
            self.density = density
        self.logger.info("Target Density: {0}".format(self.density))
        self.logger.info("Original Density: {0}".format(density0))

        # scale the cell according to the (specified) density
        ratio = (density0 / self.density)**(1.0 / 3.0)
        self.cell.scale(ratio)
        if self.bondlen is not None:
            self.bondlen *= ratio
        self.logger.info("Bond length (scaled, nm): {0}".format(self.bondlen))

        # ================================================================
        # double_network: True or False
        #   This is a special option for ices VI and VII that have
        #   interpenetrating double network.
        #   GenIce's fast depolarization algorithm fails in some case.
        #
        try:
            self.double_network = lat.double_network
        except AttributeError:
            self.double_network = False

        # ================================================================
        # cages: positions of the centers of cages
        #   In fractional coordinate.
        #
        self.cagepos = None
        self.cagetype = None
        if "cages" in lat.__dict__:
            self.cagepos, self.cagetype = parse_cages(lat.cages)

        # ================================================================
        # fixed: specify the bonds whose directions are fixed.
        #   you can specify them in pairs at a time.
        #   You can also leave it undefined.
        #
        try:
            if type(lat.fixed) is str:
                lines = lat.fixed.split("\n")
                self.fixed = []
                for line in lines:
                    columns = line.split()
                    if len(columns) == 2:
                        i, j = [int(x) for x in columns]
                        self.fixed.append((i, j))  # Is a tuple
            elif type(lat.fixed) is list:
                self.fixed = []
                for pair in lat.fixed:
                    self.fixed.append(tuple(pair[:2]))  # Must be a tuple
        except AttributeError:
            self.fixed = []
        if "dopeIonsToUnitCell" in lat.__dict__:
            self.dopeIonsToUnitCell = lat.dopeIonsToUnitCell
        else:
            self.dopeIonsToUnitCell = None
        self.dopants = set()
        # if asis, make pairs to be fixed.
        if self.asis and len(self.fixed) == 0:
            self.fixed = self.pairs

        # filled cages
        self.filled_cages = set()
        # groups info
        self.groups = defaultdict(dict)

        # groups for the semi-guest
        # experimental; there are many variation of semi-guest inclusion.
        self.groups_placer = {"Bu-": butyl,
                              "Butyl-": butyl,
                              "Pentyl-": pentyl,
                              "Propyl-": propyl,
                              "2,2-dimethylpropyl-": _2_2_dimethylpropyl,
                              "2,3-dimethylbutyl-": _2_3_dimethylbutyl,
                              "3,3-dimethylbutyl-": _3_3_dimethylbutyl,
                              "3-methylbutyl-": _3_methylbutyl,
                              "Ethyl-": ethyl}
Beispiel #9
0
def main():
    # Module-loading paths
    # 1. Look for the modules in the current working directory
    sys.path.append(".")
    #prepare user's workarea
    home = os.path.expanduser("~")
    if os.path.exists(home+"/Library/Application Support"): #MacOS
        homegenice = home+"/Library/Application Support/GenIce"
    else:
        homegenice = os.path.expanduser(home + "/.genice") #Other unix
    try:
        os.makedirs(homegenice+"/formats")
        os.makedirs(homegenice+"/lattices")
        os.makedirs(homegenice+"/molecules")
    except:
        pass #just ignore when failed.
    # 2. Look for user's home.
    sys.path.append(homegenice)


    #Parse options
    if sys.argv[0].find("analice") >= 0:
        options = getoptions_analice()
        mode    = "analice"
    else:
        options = getoptions()
        mode    = "genice"

    
    #Set verbosity level
    if options.debug:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(asctime)s %(levelname)s %(message)s")
    elif options.quiet:
        logging.basicConfig(level=logging.WARN,
                            format="%(levelname)s %(message)s")
    else:
        #normal
        logging.basicConfig(level=logging.INFO,
                            format="%(levelname)s %(message)s")
    logger = logging.getLogger()
    logger.debug("Debug mode.")

    if mode == "genice":
        logger.debug(options.Type)

        water_type   = options.water[0]
        guests       = options.guests
        lattice_type = options.Type[0]
        file_format  = options.format[0]
        seed         = options.seed[0]
        rep          = options.rep
        density      = options.dens[0]
        depolarize   = not options.nodep
        asis         = options.asis
        anions = dict()
        if options.anions is not None:
            logger.info(options.anions)
            for v in options.anions:
                key, value = v[0].split("=")
                anions[int(key)] = value
        cations = dict()
        if options.cations is not None:
            for v in options.cations:
                key, value = v[0].split("=")
                cations[int(key)] = value
        spot_guests = dict()
        if options.spot_guests is not None:
            for v in options.spot_guests:
                key, value = v[0].split("=")
                spot_guests[int(key)] = value
        groups = dict()
        if options.groups is not None:
            for v in options.groups:
                key, value = v[0].split("=")
                groups[int(key)] = value

        del options  # Dispose for safety.
        # Set random seeds
        random.seed(seed)
        np.random.seed(seed)
    
        logger.debug("Lattice: {0}".format(lattice_type))
        # Main part of the program is contained in th Formatter object. (See formats/)
        logger.debug("Format: {0}".format(file_format))
        formatter = safe_import("format", file_format)
        # Show the document of the module
        try:
            doc = formatter.__doc__.splitlines()
        except:
            doc = []
        for line in doc:
            logger.info("!!! {0}".format(line))
        lat = lattice.Lattice(lattice_type,
                              density=density,
                              rep=rep,
                              depolarize=depolarize,
                              asis=asis,
                              cations=cations,
                              anions=anions,
                              spot_guests=spot_guests,
                              spot_groups=groups,
        )
        lat.generate_ice(water_type=water_type,
                   guests=guests,
                   formatter=formatter
        )
    else: #analice
        logger.debug(options.File)

        water_type   = options.water[0]
        file_format  = options.format[0]
        oname        = options.oatom[0]
        hname        = options.hatom[0]
        filename     = options.File[0]
        
        del options  # Dispose for safety.
    
        # Main part of the program is contained in th Formatter object. (See formats/)
        logger.debug("Format: {0}".format(file_format))
        formatter = safe_import("format", file_format)
        # reuse gromacs plugin to load the file.
        s = "gromacs[{0}:{1}:{2}]".format(filename,oname,hname)
        lat = lattice.Lattice(lattice_type=s)
        lat.analize_ice(water_type=water_type,
                        formatter=formatter)
Beispiel #10
0
def main():
    # Module-loading paths
    # 1. Look for the modules in the current working directory
    sys.path.append(".")

    # Parse options
    if sys.argv[0].find("analice") >= 0:
        options = analice.getoptions()
        mode = "analice"
    else:
        options = genice.getoptions()
        mode = "genice"

    # Set verbosity level
    if options.debug:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(asctime)s %(levelname)s %(message)s")
    elif options.quiet:
        logging.basicConfig(level=logging.WARN,
                            format="%(levelname)s %(message)s")
    else:
        # normal
        logging.basicConfig(level=logging.INFO,
                            format="%(levelname)s %(message)s")
    logger = logging.getLogger()
    logger.debug("Debug mode.")

    if mode == "genice":
        logger.debug(options.Type)

        lattice_type = options.Type
        seed = options.seed
        rep = options.rep
        density = options.dens
        asis = options.asis
        anions = dict()
        if options.anions is not None:
            logger.info(options.anions)
            for v in options.anions:
                key, value = v[0].split("=")
                anions[int(key)] = value
        cations = dict()
        if options.cations is not None:
            for v in options.cations:
                key, value = v[0].split("=")
                cations[int(key)] = value
        spot_guests = dict()
        if options.spot_guests is not None:
            for v in options.spot_guests:
                key, value = v[0].split("=")
                spot_guests[int(key)] = value
        groups = dict()
        if options.groups is not None:
            for v in options.groups:
                key, value = v[0].split("=")
                groups[int(key)] = value

        # Set random seeds
        random.seed(seed)
        np.random.seed(seed)

        logger.debug("Lattice: {0}".format(lattice_type))
        assert lattice_type is not None

        # Initialize the Lattice class with arguments which are required for plugins.
        lat = genice.GenIce(safe_import("lattice", lattice_type),
                            sys.argv,
                            density=density,
                            rep=rep,
                            cations=cations,
                            anions=anions,
                            spot_guests=spot_guests,
                            spot_groups=groups,
                            asis=asis,
        )

        water_type = options.water
        guests = options.guests
        noise = options.noise
        depolarize = not options.nodep
        file_format = options.format

        # Main part of the program is contained in th Formatter object. (See formats/)
        logger.debug("Output file format: {0}".format(file_format))
        formatter = safe_import("format", file_format)

        if options.visual != "":
            record_depolarization_path = open(options.visual, "w")
        else:
            record_depolarization_path = None

        del options  # Dispose for safety.

        lat.generate_ice(water_type=water_type,
                         guests=guests,
                         formatter=formatter,
                         record_depolarization_path=record_depolarization_path,
                         noise=noise,
                         depolarize=depolarize,
                         )
    else:  # analice
        logger.debug(options.File)

        water_type = options.water
        file_format = options.format
        oname = options.oatom
        hname = options.hatom
        filename = options.File
        noise = options.noise
        avgspan = options.avgspan
        filerange = options.filerange
        framerange = options.framerange
        suffix = options.suffix
        if options.output is None:
            output = None
            stdout = None
        else:
            output = options.output
            stdout = sys.stdout

        logger.debug(filerange)
        logger.debug(framerange)
        logger.debug(oname)
        logger.debug(hname)
        logger.debug(suffix)
        logger.info("Output:{0}".format(output))

        del options  # Dispose for safety.

        for i, (oatoms, hatoms, cellmat) in enumerate(load.average(lambda:load.iterate(filename, oname, hname, filerange, framerange, suffix=suffix), span=avgspan)):
            # Main part of the program is contained in th Formatter object. (See formats/)
            logger.debug("Output file format: {0}".format(file_format))
            formatter = safe_import("format", file_format)
            lattice_info = load.make_lattice_info(oatoms, hatoms, cellmat)
            lat = analice.AnalIce(lattice_info, sys.argv)
            if output is not None:
                sys.stdout = open(output % i, "w")
            lat.analyze_ice(water_type=water_type,
                            formatter=formatter,
                            noise=noise,
                            )
        if stdout is not None:
            # recover stdout
            sys.stdout = stdout
Beispiel #11
0
    def stage7(self, guests):
        """
        Arrange guest atoms

        Provided variables:
        atoms: atomic positions of all molecules.
        """
        self.logger.info("Stage7: Atomic positions of the guest.")
        if self.cagepos is not None:
            # the cages around the dopants.
            dopants_neighbors = self.dopants_info(
                self.dopants, self.reppositions, self.repcagepos, self.repcell)
            # put the (one-off) groups
            if len(self.spot_groups) > 0:
                # process the -H option
                for cage, group_to in self.spot_groups.items():
                    group, root = group_to.split(":")
                    self.add_group(cage, group, int(root))
            molecules = defaultdict(list)
            if len(self.spot_guests) > 0:
                # process the -G option
                for cage, molec in self.spot_guests.items():
                    molecules[molec].append(cage)
                    self.filled_cages.add(cage)
            if guests is not None:
                # process the -g option
                for arg in guests:
                    cagetype, spec = arg[0].split("=")
                    assert cagetype in self.cagetypes, "Nonexistent cage type: {0}".format(
                        cagetype)
                    resident = dict()
                    rooms = list(self.cagetypes[cagetype] - self.filled_cages)
                    for room in rooms:
                        resident[room] = None
                    # spec contains a formula consisting of "+" and "*"
                    contents = spec.split("+")
                    vacant = len(rooms)
                    for content in contents:
                        if "*" in content:
                            molec, frac = content.split("*")
                            frac = float(frac)
                        else:
                            molec = content
                            frac = 1.0
                        nmolec = int(frac * len(rooms) + 0.5)
                        vacant -= nmolec
                        assert vacant >= 0, "Too many guests."
                        remain = nmolec
                        movedin = []
                        while remain > 0:
                            r = random.randint(0, len(rooms) - 1)
                            room = rooms[r]
                            if resident[room] is None:
                                resident[room] = molec
                                molecules[molec].append(room)
                                movedin.append(room)
                                remain -= 1
                        #self.logger.info(
                        #    "    {0} * {1} @ {2}".format(molec, nmolec, movedin))
            # Now ge got the address book of the molecules.
            if len(molecules):
                self.logger.info("  Summary of guest placements:")
                self.guests_info(self.cagetypes, molecules)
            if len(self.spot_groups) > 0:
                self.logger.info("  Summary of groups:")
                self.groups_info(self.groups)
            # semi-guests
            for root, cages in self.groups.items():
                assert root in self.dopants
                name = self.dopants[root]
                molname = "G{0}".format(root)
                pos = self.reppositions[root]
                rot = self.rotmatrices[root]
                self.atoms.append([0, molname, name, self.repcell.rel2abs(pos), 0])
                del self.dopants[root]  # processed.
                self.logger.debug((root,cages,name,molname,pos,rot))
                for cage, group in cages.items():
                    assert group in self.groups_placer
                    assert cage in dopants_neighbors[root]
                    cpos = self.repcagepos[cage]
                    self.atoms += self.groups_placer[group](cpos,
                                                            pos,
                                                            self.repcell,
                                                            molname)
            # molecular guests
            for molec, cages in molecules.items():
                gmol = safe_import("molecule", molec)
                cpos = [self.repcagepos[i] for i in cages]
                cmat = [np.identity(3) for i in cages]
                self.atoms += arrange_atoms(cpos, self.repcell,
                                            cmat, gmol.sites, gmol.labels, gmol.name)
        # Assume the dopant is monatomic and replaces one water molecule
        atomset = defaultdict(set)
        for label, name in self.dopants.items():
            atomset[name].add(label)
        for name, labels in atomset.items():
            pos = [self.reppositions[i] for i in sorted(labels)]
            rot = [self.rotmatrices[i] for i in sorted(labels)]
            self.atoms += arrange_atoms(pos,
                                        self.repcell,
                                        rot,
                                        [[0., 0., 0.], ],
                                        [name],
                                        name)
        self.logger.info("Stage7: end.")
Beispiel #12
0
    def __init__(self,
                 lattice_type=None,
                 density=0,
                 rep=(1, 1, 1),
                 depolarize=True,
                 asis=False,
                 cations=dict(),
                 anions=dict(),
                 spot_guests=dict(),
                 spot_groups=dict(),
                 ):
        self.logger      = logging.getLogger()
        self.lattice_type = lattice_type
        self.rep         = rep
        self.depolarize  = depolarize
        self.asis        = asis
        self.cations     = cations
        self.anions      = anions
        self.spot_guests = spot_guests
        self.spot_groups = spot_groups
        if lattice_type is None:
            return
        lat = safe_import("lattice", lattice_type)
        # Show the document of the module
        try:
            self.doc = lat.__doc__.splitlines()
        except:
            self.doc = []
        self.doc.append("")
        self.doc.append("Command line: {0}".format(" ".join(sys.argv)))
        for line in self.doc:
            self.logger.info("!!! {0}".format(line))
        # ================================================================
        # rotmatrices (analice)
        #
        try:
            self.rotmatrices = lat.rotmat
        except:
            self.logger.info("No rotmatrices in lattice")
            pass
        # ================================================================
        # waters: positions of water molecules
        #
        self.waters = load_numbers(lat.waters)
        self.logger.debug("Waters: {0}".format(len(self.waters)))
        self.waters = self.waters.reshape((self.waters.size // 3, 3))

        # ================================================================
        # cell: cell dimension
        # celltype: symmetry of the cell
        #   see parse_cell for syntax.
        #
        self.cell = Cell(lat.cell, lat.celltype)
        #self.cell = parse_cell(lat.cell, lat.celltype)

        # ================================================================
        # coord: "relative" or "absolute"
        #   Inside genice, molecular positions are always treated as "relative"
        #
        if lat.coord == "absolute":
            self.waters = self.cell.abs2rel(self.waters)
        self.waters = np.array([w - np.floor(w) for w in self.waters])

        # ================================================================
        # pairs: specify the pairs of molecules that are connected.
        #   Bond orientation will be shuffled later
        #   unless it is "fixed".
        #
        self.pairs = None
        try:
            if type(lat.pairs) is str:
                lines = lat.pairs.split("\n")
                self.pairs = []
                for line in lines:
                    columns = line.split()
                    if len(columns) == 2:
                        i, j = [int(x) for x in columns]
                        self.pairs.append((i, j))
            elif type(lat.pairs) is list:
                self.pairs = lat.pairs
                # for pair in lat.pairs:
                #    self.pairs.append(pair)
        except AttributeError:
            self.logger.info("Graph is not defined.")

        # ================================================================
        # bondlen: specify the bond length threshold.
        #   This is used when "pairs" are not specified.
        #   It is applied to the original positions of molecules (before density setting).
        #
        self.bondlen = None
        try:
            self.bondlen = lat.bondlen
            self.logger.info("Bond length (specified): {0}".format(self.bondlen))
        except AttributeError:
            self.bondlen = 1.1 * shortest_distance(self.waters, self.cell)
            self.logger.info("Bond length (assumed): {0}".format(self.bondlen))
        # Set density
        mass = 18  # water
        NB = 6.022e23
        nmol = self.waters.shape[0]  # nmol in a unit cell
        volume = self.cell.volume()  # volume of a unit cell in nm**3
        density0 = mass * nmol / (NB * volume * 1e-21)
        if density <= 0:
            try:
                self.density = lat.density
            except AttributeError:
                self.logger.info(
                    "Density is not specified. Assume the density from lattice.")
                dmin = shortest_distance(self.waters, self.cell)
                self.logger.info(
                    "Closest pair distance: {0} (should be around 0.276 nm)".format(dmin))
                self.density = density0 / (0.276 / dmin)**3
                # self.density = density0
        else:
            self.density = density
        self.logger.info("Target Density: {0}".format(self.density))
        self.logger.info("Original Density: {0}".format(density0))

        # scale the cell according to the (specified) density
        ratio = (density0 / self.density)**(1.0 / 3.0)
        self.cell.scale(ratio)
        if self.bondlen is not None:
            self.bondlen *= ratio
        self.logger.info("Bond length (scaled, nm): {0}".format(self.bondlen))

        # ================================================================
        # double_network: True or False
        #   This is a special option for ices VI and VII that have
        #   interpenetrating double network.
        #   GenIce's fast depolarization algorithm fails in some case.
        #
        try:
            self.double_network = lat.double_network
        except AttributeError:
            self.double_network = False

        # ================================================================
        # cages: positions of the centers of cages
        #   In fractional coordinate.
        #
        self.cagepos = None
        self.cagetype = None
        if "cages" in lat.__dict__:
            self.cagepos, self.cagetype = parse_cages(lat.cages)

        # ================================================================
        # fixed: specify the bonds whose directions are fixed.
        #   you can specify them in pairs at a time.
        #   You can also leave it undefined.
        #
        try:
            if type(lat.fixed) is str:
                lines = lat.fixed.split("\n")
                self.fixed = []
                for line in lines:
                    columns = line.split()
                    if len(columns) == 2:
                        i, j = [int(x) for x in columns]
                        self.fixed.append((i, j))  # Is a tuple
            elif type(lat.fixed) is list:
                self.fixed = []
                for pair in lat.fixed:
                    self.fixed.append(tuple(pair[:2]))  # Must be a tuple
        except AttributeError:
            self.fixed = []
        if "dopeIonsToUnitCell" in lat.__dict__:
            self.dopeIonsToUnitCell = lat.dopeIonsToUnitCell
        else:
            self.dopeIonsToUnitCell = None
        self.dopants = set()
        # if asis, make pairs to be fixed.
        if self.asis and len(self.fixed) == 0:
            self.fixed = self.pairs

        # filled cages
        self.filled_cages = set()
        # groups info
        self.groups = defaultdict(dict)

        # groups for the semi-guest
        # experimental; there are many variation of semi-guest inclusion.
        self.groups_placer = {"Bu-": butyl,
                              "Butyl-": butyl,
                              "Pentyl-": pentyl,
                              "Propyl-": propyl,
                              "2,2-dimethylpropyl-": _2_2_dimethylpropyl,
                              "2,3-dimethylbutyl-": _2_3_dimethylbutyl,
                              "3,3-dimethylbutyl-": _3_3_dimethylbutyl,
                              "3-methylbutyl-": _3_methylbutyl,
                              "Ethyl-": ethyl}