Как прочитать файл данных в классе в Python? - PullRequest
1 голос
/ 12 февраля 2020

Я хочу прочитать данные из двух разных файлов. В моем коде у меня есть два полимерных объекта, и я хочу прочитать их начальные координаты из файла CSV. На данный момент я могу прочитать только один файл. Может кто-нибудь подсказать, как я могу это сделать за секунду?

Вот полный код и метод, использованный для чтения первого файла.

#Define an object called 'monomer' which consists of a position (list with 3 entries)
class monomer:
    def __init__(self, pos):
    # assign the given position to the 'pos' attribute
        self.pos = pos
        #self.m = np.loadtxt('traj_T_4.csv')

    @classmethod
    def from_file(cls, filename):
        instances = []
        with open(filename, 'r') as file:
            for line in file:
                pos = str(map(float, line.split(',')))
                instances.append(cls(pos))
        return instances

    def LJ(self, other):
    # Define the LJ interaction between one and another monomer

        # Calculate the distance between position of one and the other monomer
        rij =self.distance(other)

        sig_by_r6 = np.power(sigma**2 / rij, 6)
        sig_by_r12 = np.power(sigma**2 / rij, 12)

        return 4*epsilon*(sig_by_r12 - sig_by_r6)

    def FENE(self, other):
        rij =self.distance(other)


        fene = (-0.5 * K * np.power(R,2) * np.log(1 - ((np.sqrt(rij) - r0) / R)**2))


        if not np.isfinite(fene): # Make sure, that NaN (or - infinity) values (because of the log) are never passed to the energy calculation, as the programme behaves uncontrollably then
            return float("inf")   # Rather return infinity, since this will always fail the energy comparison
        else:
            return fene

    def distance(self, other):

        return np.linalg.norm(list(np.array(self.pos) - np.array(other.pos)))

    def shift(self, vector):
    # Move a monomer by 'vector'
         self.pos += vector

# Define an object called 'polymer', which is a chain (list) of monomer objects
class polymer:
    def __init__(self, base, N):

        self.chain = []
        # append each monomer to the polymer's chain
        # base (list of 2) represents the initial x and y value of all monomers
        for i in range(N):
            self.chain.append( monomer([base[0], base[1], i*0.7]) )

    def FENE_Energy(self):
        # Define polymer FENE energy as sum of FENE interactions between bonded monomers
        fene  = 0.0
        for i in range(N-1):
            fene += self.chain[i].FENE(self.chain[i+1])
        return fene

    def LJ_Energy(self):
        LJ = 0.0

        for i in range(N):
            for j in range(N):
                if np.absolute(i-j) > 1:
                    if self.chain[i].distance(self.chain[j]) < rcutoff: # LJ only for non-bonded monomers, i.e. distance is greater than 1
                        LJ += self.chain[i].LJ(self.chain[j])

        return LJ/2.

    def Energy(self):
        return self.LJ_Energy() + self.FENE_Energy()

    def move(self): # Method returns a 'polymer' object, which is either the same as put in or a shifted one
        backup = copy.deepcopy(self) # "backup = self" does not work as expected, as 'backup' becomes a mere synonym of 'self', but not an independent (immutable) object, as intended

        monomer_index = np.random.randint(low=1, high=N) # choose a random monomer but 0, since it is grafted

        direction = np.random.rand(3) - [0.5, 0.5, 0.5] # random vector consists of movement between [-0.5, -0.5, -0.5] and [0.5, 0.5, 0.5]

        self.chain[monomer_index].shift(direction)
        if self.chain[monomer_index].pos[2] < 0.0:
            return backup

        rnd = np.random.rand(1)
        deltaE = self.Energy() - backup.Energy()

        if np.exp(-(1/k_B*T)*deltaE) < rnd:
            return backup
        else:
            return self # return the shifted polymer

if __name__ == "__main__":

    list_of_monomers = monomer.from_file('monomer.csv')
    list_of_monomers = monomer.from_file('monomer1.csv')

    K = 40.0
    R = 0.3
    r0 = 0.7
    sigma = r0/2**6
    rcutoff = 2.5*sigma
    epsilon = 1.0
    max_delta = 0.21 # -sigma/10 to sigma/10
    N = 20
    k_B = 1
    T = 4.0
    shifts = 100

# Declare two variables to be 'polymers'
    pol1 = polymer([-r0/2, 0.0], N)
    pol2 = polymer([ r0/2, 0.0], N)

1 Ответ

0 голосов
/ 13 февраля 2020

Я не знаю формат файла, но допустим, что он разделен запятыми с 3D-координатой в каждой строке:

class monomer:
    @classmethod
    def from_file(cls, filename):
        instances = []
        with open(filename, ‘r’) as file:
            for line in file:
                pos = list(map(float, line.split(‘,’)))
                instances.append(cls(pos))
        return instances

, которая может называться:

list_of_monomers = monomer.from_file(‘monomers.csv’)
...