예제 #1
0
class FCHK(object):
    def __init__(self, fchkname='gaussian.fchk', w=None):
        self.mol = VibToolsMolecule()
        self.modes = None
        self.filename = fchkname
        self.lwl = w
        if os.path.splitext(self.filename)[1] in [".bz2", ".BZ2"]:
            self.bz2 = True
        else:
            self.bz2 = False

    freqs = property(lambda self: self.modes.freqs)

    def read(self):
        self.mol.read_from_fchk(filename=self.filename)
        self.modes = VibModes(self.mol.nmodes, self.mol)
        if self.lwl is None:
            self.lwl = self.get_pulsation()

    def get_pulsation(self):
        """
        Get the w value used in the TDHF(or equivalent) approach
        """
        lwls = self.get_property("Frequencies for FD properties")
        # Only take the first non-zero pulsation in the followings
        lwl = None
        if lwls is not None:
            for puls in lwls:
                if puls > 0.0:
                    lwl = float(puls)
                    break
            print("Pulsations in the calculations:", lwls)
            print("Pulsation used:", lwl)
        else:
            print("No Pulsation found in the file. Assume Zero")
            lwl = 0.000
        return lwl

    def get_property(self, prop):
        """
        Read a property name "property" in the fchk file
        return a numpy vector
        """
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        # find the block "property"
        first = 0
        last = 0
        cols = {"R": 5, "I": 6}
        numpytype = {"R": "d", "I": "int"}
        stype = "R"
        size = 0
        for i, l in enumerate(lines):
            if prop in l:
                l = l[len(prop):]
                if "N=" in l:
                    # read array of data
                    pattern = r"\d+"
                    size = int(re.findall(pattern, l)[0])
                    typepattern = r"   [IR]   "
                    try:
                        stype = re.findall(typepattern, l)[0].strip()
                    except IndexError:
                        raise Exception(
                            "The type of data in fchk is not recognized")
                    first = i + 1
                    nlines = (size - 1) // cols[stype] + 1
                    last = first + nlines
                    break
                else:
                    # single data
                    typepattern = r"   [IR]   "
                    try:
                        stype = re.findall(typepattern, l)[0].strip()
                    except IndexError:
                        raise Exception(
                            "The type of data in fchk is not recognized")
                    if stype == 'I':
                        pattern = r"\d+"
                        return int(re.findall(pattern, l)[0])
                    elif stype == 'R':
                        pattern = r"-?\d+\.\d*[ED]?[+\-]?\d*"
                        return float(re.findall(pattern, l)[0])
        lines = lines[first:last]
        if len(lines) == 0:
            return None
        # read the data
        data = []
        for line in lines:
            data.extend([float(fl) for fl in line.split()])
        data = numpy.array(data, numpytype[stype])
        if data.size != size:
            raise Exception(
                "The number of data recovered [%i] is not the same as the size written in the file [%i]"
                % (data.size, size))
        return data

    def get_forces(self):
        natoms = self.mol.natoms
        data = self.get_property("Cartesian Gradient")
        if isinstance(data, numpy.ndarray):
            forces = -data.reshape(natoms, 3)
        return forces

    def get_hessian(self):
        natoms = self.mol.natoms
        # find the block of date containing the Hessian
        # get the data (triangular matrix)
        data = self.get_property("Cartesian Force Constants")
        if data is None:
            return None
        index = 0
        hessian = numpy.zeros((3 * natoms, 3 * natoms))
        for i in range(3 * natoms):
            for j in range(i + 1):
                hessian[i, j] = data[index]
                index += 1

        # fill the other half of the hessian matrix
        hessian = hessian + hessian.transpose() - numpy.diag(
            hessian.diagonal())
        return hessian

    def read_normalmodes(self):
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        natoms = self.mol.natoms
        freqs = numpy.zeros((self.modes.nmodes))
        redmass = numpy.zeros((self.modes.nmodes))
        normalmodes = numpy.zeros((0, ))
        first1 = 0
        last1 = 0
        first2 = 0
        last2 = 0
        for i, l in enumerate(lines):
            if "Vib-E2" in l:
                pattern = r"\d+"
                size = int(re.findall(pattern, l)[1])
                first1 = i + 1
                last1 = i + 1 + (size - 1) // 5 + 1
            elif "Vib-Modes" in l:
                pattern = r"\d+"
                size = int(re.findall(pattern, l)[0])
                first2 = i + 1
                last2 = i + 1 + (size - 1) // 5 + 1
        lines1 = lines[first1:last1]
        lines2 = lines[first2:last2]
        data = []
        self.modes = VibModes(self.mol.nmodes, self.mol)
        if len(lines1) == 0:
            print(
                "No Normal modes found in fchk. Ask saveNM in the calculation."
            )
            print("Compute from hessian instead")
            prop = Property(self)
            hessian_mw = prop.get_hessian_mw()
            if hessian_mw is not None:
                self.modes.ComputeModes_without_TR(hessian_mw)
            return
        for i, sline in enumerate(lines1):
            line = [float(fl) for fl in sline.split()]
            data.extend(line)
        for i in range(self.modes.nmodes):
            freqs[i] = data[i]
            redmass[i] = data[i + self.modes.nmodes]
        for sline in lines2:
            array = [float(fl) for fl in sline.split()]
            array = numpy.array(array)
            normalmodes = numpy.append(normalmodes, array)
        self.modes.set_modes_c_norm(
            normalmodes.reshape((self.modes.nmodes, 3 * natoms)), redmass)
        self.modes.set_freqs(freqs)

    def get_molecularorbitalenergies(self):
        """
        Get the molecular orbital energies
        """
        # get the block with the MO coefficients
        moen = self.get_property("Alpha Orbital Energies")
        return moen

    def get_molecularorbitalcoeffs(self):
        """
        Get the molecular orbitals LCAO coefficients
        Output = M_ij with i which correspond to a MO and j to a AO
        Output = C+
        """
        # get the block with the MO coefficients
        mo = self.get_property("Alpha MO coefficients")
        if isinstance(mo, numpy.ndarray):
            nAO = self.get_property("Number of basis functions")
            nMO = self.get_property("Number of independent functions")
            mo = mo.reshape((nMO, nAO))
        return mo

    def get_dipole(self):
        """
        get dipole
        """
        dipole = self.get_property("Dipole Moment")
        return dipole

    def get_dipole_deriv_c(self):
        """
        get dmudx
        """
        dmudx = self.get_property("Dipole Derivatives")
        if isinstance(dmudx, numpy.ndarray):
            dmudx = dmudx.reshape(self.mol.natoms, 3, 3)
        return dmudx

    get_AAT = (lambda self: self.get_magneticdipole_deriv_c())

    def get_magneticdipole_deriv_c(self):
        """
        get atomic axial tensor
        """
        aat = self.get_property("AAT")
        if isinstance(aat, numpy.ndarray):
            aat = aat.reshape(self.mol.natoms, 3, 3)
        return aat

    def get_pollen(self):
        """
        get polarizability
        """
        alpha = {}  #dictionary with alpha values for different pulsations
        frequencies = self.get_property("Frequencies for FD properties")
        data = self.get_property("Alpha(-w,w)")
        if data is None:
            dummy = self.get_property("Polarizability")
            if isinstance(dummy, numpy.ndarray):
                data = numpy.zeros((3, 3))
                data[0, 0] = dummy[0]
                data[1, 0] = dummy[1]
                data[0, 1] = dummy[1]
                data[1, 1] = dummy[2]
                data[2, 0] = dummy[3]
                data[0, 2] = dummy[3]
                data[2, 1] = dummy[4]
                data[1, 2] = dummy[4]
                data[2, 2] = dummy[5]
                frequencies = [0.00000]
        if isinstance(data, numpy.ndarray):
            data = data.reshape((-1, 3, 3))
            for lwl, a in zip(frequencies, data):
                alpha[(lwl, )] = a
        if len(alpha) == 0:
            return None
        return alpha

    def get_gtenlen(self):
        """
        Read G'(-w;w)
        """
        Gprime = {}  #dictionary with Gprime values for different pulsations
        frequencies = self.get_property("Frequencies for FD properties")
        data = self.get_property("FD Optical Rotation Tensor")
        if isinstance(data, numpy.ndarray):
            data = data.reshape((-1, 3, 3))
            for lwl, a in zip(frequencies, data):
                Gprime[(
                    lwl, )] = a * lwl  # gaussian gives the transpose of G'/w
        if len(Gprime) == 0:
            return None
        return Gprime

    def get_aten(self):
        """
        read UpperA(-w;w)
        """
        UpperA = {}  #dictionary with UpperA values for different pulsations
        frequencies = self.get_property("Frequencies for FD properties")
        data = self.get_property("D-Q polarizability")
        if isinstance(data, numpy.ndarray):
            data = data.reshape((-1, 3, 6))
            for lwl, a in zip(frequencies, data):
                a *= 1.5  # gaussian give the traceless A but not multiply by 3/2
                UpperA[(lwl, )] = numpy.zeros((3, 3, 3))
                UpperA[(lwl, )][:, 0, 0] = a[:, 0]
                UpperA[(lwl, )][:, 1, 1] = a[:, 1]
                UpperA[(lwl, )][:, 2, 2] = a[:, 2]
                UpperA[(lwl, )][:, 0, 1] = a[:, 3]
                UpperA[(lwl, )][:, 1, 0] = a[:, 3]
                UpperA[(lwl, )][:, 0, 2] = a[:, 4]
                UpperA[(lwl, )][:, 2, 0] = a[:, 4]
                UpperA[(lwl, )][:, 1, 2] = a[:, 5]
                UpperA[(lwl, )][:, 2, 1] = a[:, 5]
        if len(UpperA) == 0:
            return None
        return UpperA

    def get_pollen_deriv_c(self):
        """
        Get dALphaDX
        """
        dalphadx = {}  #dictionary with dalphadx
        frequencies = self.get_property("Frequencies for DFD properties")
        data = self.get_property("Derivative Alpha(-w,w)")
        if data is None:
            dummy = self.get_property("Polarizability Derivatives")
            if isinstance(dummy, numpy.ndarray):
                data = numpy.zeros((self.mol.natoms * 3, 3, 3))
                data[:, 0, 0] = dummy[0::6]
                data[:, 1, 0] = dummy[1::6]
                data[:, 0, 1] = dummy[1::6]
                data[:, 1, 1] = dummy[2::6]
                data[:, 2, 0] = dummy[3::6]
                data[:, 0, 2] = dummy[3::6]
                data[:, 2, 1] = dummy[4::6]
                data[:, 1, 2] = dummy[4::6]
                data[:, 2, 2] = dummy[5::6]
                frequencies = [0.00000]
            else:
                data = None
        if isinstance(data, numpy.ndarray):
            data = data.reshape((-1, self.mol.natoms, 3, 3, 3))
            for lwl, dadx in zip(frequencies, data):
                dalphadx[(lwl, )] = dadx
        if len(dalphadx) == 0:
            return None
        return dalphadx

    def get_gtenlen_deriv_c(self):
        """
        Get dGprimeDX
        """
        dgprimedx = {}  #dictionary with dgprimedx
        frequencies = self.get_property("Frequencies for DFD properties")
        data = self.get_property("Derivative FD Optical Rotation Tensor")
        if isinstance(data, numpy.ndarray):
            data = data.reshape((-1, self.mol.natoms, 3, 3, 3))
            for lwl, dadx in zip(frequencies, data):
                dgprimedx[(
                    lwl,
                )] = dadx * lwl  # gaussian gives the transpose of G'/w
        if len(dgprimedx) == 0:
            return None
        return dgprimedx

    def get_aten_deriv_c(self):
        """
        Get dUpperADX
        """
        dupperAdx = {
        }  #dictionary with dupperAdx values for different pulsations

        frequencies = self.get_property("Frequencies for DFD properties")
        data = self.get_property("Derivative D-Q polarizability")
        if isinstance(data, numpy.ndarray):
            data = data.reshape((-1, self.mol.natoms, 3, 3, 6))
            for lwl, dadx in zip(frequencies, data):
                dadx *= 1.5  # gaussian give the traceless A but not multiply by 3/2
                dupperAdx[(lwl, )] = numpy.zeros((self.mol.natoms, 3, 3, 3, 3))
                dupperAdx[(lwl, )][:, :, :, 0, 0] = dadx[:, :, :, 0]
                dupperAdx[(lwl, )][:, :, :, 1, 1] = dadx[:, :, :, 1]
                dupperAdx[(lwl, )][:, :, :, 2, 2] = dadx[:, :, :, 2]
                dupperAdx[(lwl, )][:, :, :, 0, 1] = dadx[:, :, :, 3]
                dupperAdx[(lwl, )][:, :, :, 1, 0] = dadx[:, :, :, 3]
                dupperAdx[(lwl, )][:, :, :, 0, 2] = dadx[:, :, :, 4]
                dupperAdx[(lwl, )][:, :, :, 2, 0] = dadx[:, :, :, 4]
                dupperAdx[(lwl, )][:, :, :, 1, 2] = dadx[:, :, :, 5]
                dupperAdx[(lwl, )][:, :, :, 2, 1] = dadx[:, :, :, 5]
        if len(dupperAdx) == 0:
            return None
        return dupperAdx

    def get_energy_transition(self):
        data = self.get_property("ETran state values")
        GSen = self.get_property("SCF Energy")
        if (data is None) or (GSen is None):
            return None
        data = data.reshape((-1, 16))  # 16 values for each transition
        # energy, 3x <g|\mu|e>, 3x <g|mu_vel|e>, 3x <g|m|e>, 6 unknown
        energies = data[:, 0]
        # Make the difference with the smallest value of energy
        energies -= GSen

        return energies

    def get_dipole_transition(self):
        diptrans = self.get_property("ETran state values")
        if isinstance(diptrans, numpy.ndarray):
            diptrans = diptrans.reshape(
                (-1, 16))  # 16 values for each transition
            # energy, 3x <g|\mu|e>, 3x <g|mu_vel|e>, 3x <g|m|e>, 6 unknown
            diptrans = diptrans[:, 1:4]
        return diptrans

    def get_magneticdipole_transition(self):
        diptrans = self.get_property("ETran state values")
        if isinstance(diptrans, numpy.ndarray):
            diptrans = diptrans.reshape(
                (-1, 16))  # 16 values for each transition
            # energy, 3x <g|\mu|e>, 3x <g|mu_vel|e>, 3x <g|m|e>, 6 unknown
            diptrans = diptrans[:, 7:10]
        return diptrans

    def get_magneticshielding(self):
        """
        Get GIAO nuclear magnetic shielding
        """
        shielding = self.get_property("NMR shielding")
        if isinstance(shielding, numpy.ndarray):
            shielding = shielding.reshape((self.mol.natoms, 3, 3))
            # order of the elements: for each atom: XX, YX, ZX, XY, YY, ZY, XZ, YZ, ZZ
            # reorder the elements for each atom: XX, XY, XZ, YX, YY, YZ, ZX, ZY, ZZ
            shielding = numpy.transpose(shielding, axes=(0, 2, 1))
            shielding = shielding * Constants.a**2 * 1.0e6
        return shielding

    def get_density(self):
        """
        Get the non-perturbed density
        """
        data = self.get_property("Total SCF Density")
        density = None
        if isinstance(data, numpy.ndarray):
            nbasis = self.get_property("Number of basis functions")
            index = 0
            density = numpy.zeros((nbasis, nbasis))
            for i in range(nbasis):
                for j in range(i + 1):
                    density[i, j] = data[index]
                    index += 1

            # fill the other half of the density matrix
            density = density + density.transpose() - numpy.diag(
                density.diagonal())
        return density

    def get_spindensity(self):
        """
        Get the spin density
        """
        data = self.get_property("Spin SCF Density")
        density = None
        if isinstance(data, numpy.ndarray):
            nbasis = self.get_property("Number of basis functions")
            index = 0
            density = numpy.zeros((nbasis, nbasis))
            for i in range(nbasis):
                for j in range(i + 1):
                    density[i, j] = data[index]
                    index += 1

            # fill the other half of the density matrix
            density = density + density.transpose() - numpy.diag(
                density.diagonal())
        return density

    def get_density_magnetic(self):
        """
        Get the perturbed density by magnetic field
        """
        data = self.get_property("Magnetic Field P1 (GIAO)")
        density = None
        if isinstance(data, numpy.ndarray):
            nbasis = self.get_property("Number of basis functions")
            index = 0
            density = numpy.zeros((3, nbasis, nbasis))
            for idir in range(3):
                for i in range(nbasis):
                    for j in range(i + 1):
                        density[idir, i, j] = data[index]
                        index += 1

                # fill the other half of the density matrix
                density[idir] = density[idir] - density[idir].transpose()
        return density

    def get_basisset(self):
        """
        read the basis set
        return a list of AO objects
        """
        nshell = self.get_property("Number of contracted shells")
        shelltype = self.get_property("Shell types")
        primitive_pershell = self.get_property(
            "Number of primitives per shell")
        shell2atom = self.get_property("Shell to atom map")
        primitive_exp = self.get_property("Primitive exponents")
        primitive_coeff = self.get_property("Contraction coefficients")
        primitive_coeff_p = self.get_property(
            "P(S=P) Contraction coefficients")
        atomicnumbers = self.get_property("Atomic numbers")
        # basis set list
        basisset = []
        start = 0
        for ishell in range(nshell):
            nprim = primitive_pershell[ishell]
            # get the exponents and coeffs for all the primitive of the shell
            exponents = primitive_exp[start:start + nprim]
            coefficients = primitive_coeff[start:start + nprim]
            coefficients_p = None
            if primitive_coeff_p is not None:
                if numpy.nonzero(
                        primitive_coeff_p[start:start + nprim])[0].size != 0:
                    coefficients_p = primitive_coeff_p[start:start + nprim]
            iatom = shell2atom[ishell]
            an = int(atomicnumbers[iatom - 1])
            atype = int(shelltype[ishell])
            shell = BasisSet.SHELL(iatom,
                                   an,
                                   atype,
                                   exponents=exponents,
                                   coefficients=coefficients,
                                   coefficients_p=coefficients_p)
            basisset.append(shell)
            start = start + nprim
        if len(basisset) == 0:
            basisset = None
        else:
            basisset = BasisSet.BasisSet(basisset)
#            basisset.check_contractedcoeff()
        return basisset
예제 #2
0
class DATA(object):
    def __init__(self, logname='file.data', w=None):
        self.mol = VibToolsMolecule()
        self.modes = None
        self.filename = logname
        self.lwl = w

    freqs = property(lambda self: self.modes.freqs)

    def read(self):
        self.mol.read_from_data(filename=self.filename)
        self.modes = VibModes(self.mol.nmodes, self.mol)
        if self.lwl is None:
            self.lwl = self.get_pulsation()

    def get_pulsation(self):
        """
        Get the first Pulsation value in the data file
        """
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        pattern = r"[+-]?0\.\d{6}"
        lwls = []
        for l in lines:
            if "Pulsation:" in l:
                alist = re.findall(pattern, l)
                w = [float(x) for x in alist]
                for puls in w:
                    if puls not in lwls:
                        lwls.append(puls)
#        # Only take the first non-zero pulsation in the followings
        lwl = None
        if len(lwls) != 0:
            for puls in lwls:
                if puls > 0.0:
                    lwl = puls
                    break
            print("Pulsations in the calculations:", lwls)
            print("Pulsation used:", lwl)
        return lwl

    get_forces = (lambda self: self.get_mechproperty("Forces"))
    get_hessian = (lambda self: self.get_mechproperty("Hessian"))
    get_cubic_forces = (lambda self: self.get_mechproperty("Cubic Forces"))

    def read_normalmodes(self):
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        natoms = self.mol.natoms
        # find the block of date containing the normal modes
        first = 0
        last = 0
        for i, l in enumerate(lines):
            if "[Vibrational Normal Modes]" in l:
                first = i + 2
            elif (first != 0) and "[" in l:
                last = i
                break
            elif (first != 0) and i == len(lines) - 1:
                last = i + 1
                break
        lines = lines[first:last]
        freqs = []
        redmass = []
        normalmodes = numpy.zeros((0, ))
        for i, l in enumerate(lines):
            if "Frequencies " in l:
                freqs.extend(l.split()[1:])
            elif "Reduced-masses" in l:
                redmass.extend(l.split()[1:])
            elif "Coord" in l:
                block = lines[i + 1:i + 3 * natoms + 1]
                array = []
                for blockline in block:
                    array.append([float(fl) for fl in blockline.split()[3:]])
                array = numpy.array(array)
                array = array.transpose()
                normalmodes = numpy.append(normalmodes, array)
        freqs = numpy.array([float(fl) for fl in freqs])
        redmass = numpy.array([float(fl) for fl in redmass])
        self.modes = VibModes(self.mol.nmodes, self.mol)
        if normalmodes.shape == (0, ):
            print("No normal modes found")
            print("Compute from hessian instead")
            from VibTools import Properties
            prop = Properties.Property(self)
            hessian_mw = prop.get_hessian_mw()
            if hessian_mw is not None:
                self.modes.ComputeModes_without_TR(hessian_mw)
            return
        else:
            self.modes.set_modes_c_norm(
                normalmodes.reshape((self.modes.nmodes, 3 * natoms)), redmass)
            self.modes.set_freqs(freqs)

    def read_property(self, lines):
        """
        read the property from a string
        """
        # remove empty lines and lines which start with Param
        lines = [l for l in lines if not len(l.strip()) == 0]
        lines = [l for l in lines if not l.startswith('Param')]

        nblines = len(lines)
        prop = numpy.zeros((nblines, 3))
        for iline, l in enumerate(lines):
            prop[iline] = [float(x) for x in l.strip().split()]
        return prop.ravel()

    def read_property_transition(self, lines):
        """
        read the property transition from a string
        """
        # remove empty lines and lines which start with Param
        lines = [l for l in lines if not len(l.strip()) == 0]
        lines = [l for l in lines if not l.startswith('Param')]

        nblines = len(lines)
        prop = []
        for l in lines:
            prop.append([float(x) for x in l.strip().split()[1:]])
        prop = numpy.array(prop)
        return prop.reshape((nblines, -1))

    def get_mechproperty(self, name):
        """
        get any type of mechanical property
        param name:name of the property
        """
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()

        # find the block of data containing the mechanical property
        prop = None
        for i, l in enumerate(lines):
            if "[" + name.strip() + "]" in l:
                nbelems = int(lines[i + 1].split()[1])
                if nbelems == 3 * self.mol.natoms:
                    nblines = self.mol.natoms
                else:
                    nblines = nbelems // 3 + nbelems // (3 * self.mol.natoms)
                prop = self.read_property(lines[i + 2:i + 2 + nblines])
                break
        return prop

    def get_property(self, name):
        """
        get any type of property
        param name:name of the property using the various operators from the response function
                    add _deriv_c for cartesian first-order derivative
                    add _deriv_c2 for cartesian second-order derivative
        return: a dictinary with pulsations as keys
        """
        from VibTools import Properties
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        # find the block of data containing the property
        props = []
        list_omegas = []
        puls_size = Properties.get_pulsation_size(name)
        for i, l in enumerate(lines):
            if "[" + name.strip() + "]" in l:
                omegas = []
                if puls_size > 0:
                    omegas = [
                        float(x) for x in lines[i + 1].strip().split()[1:]
                    ]
                    print("[%s] found with pulsation %s" %
                          (name.strip(), omegas))
                prop_size = Properties.get_property_size(name)
                nblines = int(prop_size // 3)
                nparams = 1
                # deriv_c?
                if name.find("_deriv") != -1:
                    try:
                        order = int(name[name.find("_deriv") + 8:])
                    except ValueError:
                        order = 1
                    nparams = (3 * self.mol.natoms)**order
                    nblines = (nblines + 1) * nparams
                prop = self.read_property(lines[i + 2:i + 2 + nblines])
                if nparams > 1:
                    prop = prop.reshape((nparams, prop_size))
                list_omegas.append(tuple(omegas))
                props.append(prop)
        if len(props) == 0:
            return None
        props = dict(zip(list_omegas, props))
        if puls_size == 0:
            props = props[()]
        return props

    def get_property_transition(self, name):
        """
        get any type of property transition
        param name:name of the property using the various operators from the response function
                    add _deriv_c for cartesian first-order derivative
                    add _deriv_c2 for cartesian second-order derivative
        """
        from VibTools import Properties
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        # find the block of data containing the property
        prop = None
        for i, l in enumerate(lines):
            if "[" + name.strip() + "_transition]" in l:
                #                if w is not None:
                #                    omegas=[float(x) for x in lines[i+1].strip().split()[1:]]
                #                    if tuple(omegas) != w:
                #                        continue
                nstates = int(lines[i + 1].strip().split()[1])
                prop_size = Properties.get_property_size(name)
                nblines = nstates
                nparams = 1
                # deriv_c?
                if name.find("_deriv") != -1:
                    try:
                        order = int(name[name.find("_deriv") + 8:])
                    except ValueError:
                        order = 1
                    nparams = (3 * self.mol.natoms)**order
                    nblines = (nblines + 1) * nparams
                prop = self.read_property_transition(lines[i + 2:i + 2 +
                                                           nblines])
                if nparams > 1:
                    prop = prop.reshape((-1, nparams, prop_size))
                break
        return prop

    def get_FCfactors(self, istate):
        """
        get Franck Condon factors for state istate
        """
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        # find the block of data containing the property
        FCfactors = None
        tline = "[FC factors of state %i]" % (istate)
        for i, l in enumerate(lines):
            if tline in l:
                nbfc = int(lines[i + 2].strip().split()[1])
                FCfactors = []
                for line in lines[i + 4:i + 4 + nbfc]:
                    FCfactors.append(
                        [float(x) for x in line.strip().split()[0:2]])
                FCfactors = numpy.array(FCfactors).transpose()
        return FCfactors

    def get_Delta_factors(self, istate):
        """
        get Dimensionless Delta factors for state istate
        """
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        # find the block of data containing the property
        Delta = None
        tline = "[Dimensionless Delta factors for state %i]" % (istate)
        for i, l in enumerate(lines):
            if tline in l:
                nbmodes = int(lines[i + 1].strip().split()[1])
                Delta = []
                for line in lines[i + 3:i + 3 + nbmodes]:
                    Delta.append(float(line.strip()))
                Delta = numpy.array(Delta)
        return Delta

    def get_HuangRhys_factors(self, istate):
        """
        get HuangRhys factors for state istate
        """
        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()
        # find the block of data containing the property
        HR = None
        tline = "[Huang-Rhys factors for state %i]" % (istate)
        for i, l in enumerate(lines):
            if tline in l:
                nbmodes = int(lines[i + 1].strip().split()[1])
                HR = []
                for line in lines[i + 3:i + 3 + nbmodes]:
                    HR.append(float(line.strip()))
                HR = numpy.array(HR)
        return HR