Esempio n. 1
0
def simulator(oriConc = 10,                     # the max concentration released from the source of chemoattractant
              cellConc = 1,                     # the max concentration released by cells (determining the degree of intercellular communication)
              Diff = 10,                        # the diffusion rate of chemoattractant 
              kd = 10,                          # constant associated with Hills coefficient for autocrinic release
              DispScale = 100000,               # Displacement Scale ... wrong name I guess 
              searchingRange = 0.1,             # searching range around the cell 
              numOfCells1 = 50,                 # a total number of cells in the 1st section of simulation box 
              numOfCells2 = 50,                 # a total number of cells in the 2nd section of simulation box 
              CentoR = None,                       # this will determine the size of 1st section of simulation box in x axis
              pdbFileName = 'temp',             # generated PDB file name 
              dcdfilename = 'test_output2',     # generated DCD file name 
              lowlimBoxlen =0,                  # in angstrom = 1/10 of nanometer (REMEMBER!!) ??? do I need this? 
              highlimBoxlen =1000,              # in angstrom = 1/10 of nanometer (REMEMBER!!)
              simLength = 10000,                # a total number of the simulation steps 
              dumpSize = 100,                   # dump size in the dcd generation process 
              restingRatio1 = 0.8,              # the proportion of resting cells in the overall population of cells in the 1st section 
              restingRatio2 = 0.8,              # the proportion of resting cells in the overall population of cells in the 2nd section 
              restMig = 0.5,                    # the degree of migratory response of resting cells 
              actMig = 0.1,                     # the degree of migratory response of activated cells 
              restAuto = 10,                    # the degree of autocrinic release of resting cells: the larger, the less insensitive
              actAuto = 0.1,                    # the degree of autocrinic release of activated cells
              shape = 'slab',                   # shape of simulation box: either slab or square 
              DiffState = 'steady',             # the characteristics of diffusion of chemoattractant: steady, error, or linear 
              NoParticleZone = None,
              cellPerdead = 50,
              stateVar = 'on',
              placement = 'far'
              ):
    
    # This will generate the random structure that makes no sence but will be processed again
    ## Note: This will generate dummy pdb file that will pass the test run but it is irrelevant to the actual calculation.
        
    if cellPerdead > 0:
        num_dead_cell_core = 50
        #num_dead_cell_core = round((numOfCells1+numOfCells2)/cellPerdead)
        dead_cell = np.random.randint(150,200, size=(num_dead_cell_core))
        
    elif cellPerdead == 0:
        num_dead_cell_core = 1
        dead_cell = [1]
        
    num_dead_cell = np.sum(dead_cell)
    
    calc.PDBgenNoPBC(pdbFileName,
                     numOfCells1,
                     numOfCells2,
                     restingRatio1,
                     restingRatio2,
                     num_dead_cell,
                     num_dead_cell_core) # Dead cell must be placed in here first
    
    pdb = PDBFile(pdbFileName+'.pdb')        
    
    # Configure Dumping frequency 
    dumpingstep = dumpSize
    dcdReporter = DCDReporter(dcdfilename+'.dcd', dumpingstep)
        
    # Simulation Box Dimension in angstrom
    ## Slab case
    if shape == 'slab':
        shape_factor = 10 # What where this goes to.
        dummy = (np.int(highlimBoxlen*shape_factor))/(10)
        OriginOfExternalSignal = [dummy,0,0] # in nanometer 
        # This indicates the far end of X-axis
    ## Square case
    elif shape == 'square':
        shape_factor = 1
        dummy = (np.int(highlimBoxlen))/(10)
        OriginOfExternalSignal = [dummy/2,dummy/2,0]
        # This indicates the center of simulation box
   
    # Defining the dimension of simulation box 
    x = [lowlimBoxlen,highlimBoxlen*shape_factor]
    y = [lowlimBoxlen,highlimBoxlen]
    z = [0,0]
    highBC = np.array([x[1],y[1],z[1]])
    
    # Configure Simulation Length 
    Repeat = simLength
    stepFreq = 1 

    # Parameters determining the dynamics of cells 
    MassOfCell = 50 
    MassOfDead = 1000

    RepulsiveScale = 0.05 # this can determine the distance among cells themselves
    RepulsiveScaleDead = 0.15

    ### Simulation parameters
    temperature = 1.0 #0.0    # K   <---- set to 0 to get rid of wiggling for now
    frictionCoeff = 1.0  # 1/ps
    step_size = 0.002    # ps
    
    ##########################################################
    ###              OpenMM Simulation Control             ###
    ##########################################################
    # Create an OpenMM System object
    system = System()

    # Create CustomNonbondedForce. We use it to implement repulsive potential between particles.
    # Only keep repulsive part of L-J potential
    #nonbond = CustomNonbondedForce("(sigma/r)^12; sigma=0.5*(sigma1+sigma2)")
    nonbond = CustomNonbondedForce("(sigma/r)^12-delta*(sigma/r)^6; sigma=0.5*(sigma1+sigma2); delta=0.5*(delta1+delta2)")
    nonbond.addPerParticleParameter("sigma")
    nonbond.addPerParticleParameter("delta")
    # Here we don't use cutoff for repulsive potential, but adding cutoff might speed things up a bit as interaction
    # strength decays very fast.
    #nonbond.setNonbondedMethod(CustomNonbondedForce.NoCutoff)
    nonbond.setCutoffDistance(9)
    # Add force to the System
    system.addForce(nonbond)
    
    # FeedInForce is an OpenMM Force object that serves as the interface to feed forces into the simulation. It stores
    # additional forces that we want to introduce internally and has a method
    # .updateForceInContext(OpenMM::Context context, vector< vector<double> > in_forces). in_forces should be a vector of
    # 3d vectors - one 3d vector per particle and each 3d vector should contain X,Y,Z components of the force.
    # updateForceInContext() will copy forces from in_forces into internal variable that will keep them
    # until updateForceInContext() is called again. Every simulation step OpenMM will add forces stored in FeedInForce to
    # the simulation. You don't need to call updateForceInContext() every step if the forces didn't change - OpenMM will
    # use the forces from the last call of updateForceInContext().
    in_force = FeedInForce()
    # Add in_force to the system
    system.addForce(in_force)

    num_particles = len(pdb.getPositions())
    
    ### Make it 2D 
    energy_expression = 'k * (z^2)'
    force = openmm.CustomExternalForce(energy_expression)
    force.addGlobalParameter('k', 999)
    for particle_index in range(num_particles):
        force.addParticle(particle_index, [])
    system.addForce(force)
    ## This will generate more reasonable structure but still needs to take number of particle from the arbitrary structure 
    ## The reason I choose to do so is generating PDB file is little tricky due to its sensitivity to line arrangement 
    min_dist_among_cells = 2.5
    xlow_end = x[0]
    xhigh_end = x[1]
    ylow_end = y[0]
    yhigh_end = y[1]
    
   
    '''
    [Outcomes of genCellCoord3D]
    initPosInNm: coordnates of cells in array format (num_particles by [x,y,z]) 
    marker: a list of markers for resting and activated cells (length of num_particles) 
    migration_factor: a list of constants for migration degree for resting and activated (length of num_particles)
    autocrine_factor: a list of constants for autocrinic degree for resting and activated (lengh of num_particles)
    '''
    initPosInNm, marker, mig_factor, auto_factor, Cell_Constitution = calc.genCellCoord3D(numOfCells1,
                                                                                          numOfCells2,
                                                                                          dead_cell,
                                                                                          min_dist_among_cells,
                                                                                          CentoR,
                                                                                          xlow_end,
                                                                                          xhigh_end,
                                                                                          ylow_end,
                                                                                          yhigh_end,
                                                                                          restingRatio1,
                                                                                          restingRatio2,
                                                                                          restMig,
                                                                                          actMig,
                                                                                          restAuto,
                                                                                          actAuto,
                                                                                          shape_factor,
                                                                                          NoParticleZone,
                                                                                          placement)
    
    
    DeadCellRef1 = Cell_Constitution['Dead']
    
    for i in range(num_particles):
        if i <= DeadCellRef1:
            system.addParticle(MassOfDead)
            sigma = RepulsiveScaleDead
            delta = 1
            nonbond.addParticle([sigma,delta])
            #nonbond.addParticle([sigma])
        else:
            # Populate the system with particles.
            # system.addParticle(mass in atomic mass units)
            system.addParticle(MassOfCell)  # 100.0 is a particle mass
            # Add particles to CustomNonbondedForce. Here we define repulsion strength sigma for each particle. If particles
            # have different value of sigma, combination rule sigma=0.5*(sigma1+sigma2) will be applied as defined in
            # CustomNonbondedForce force expression.
            sigma = RepulsiveScale
            delta = 0
            nonbond.addParticle([sigma,delta])
            #nonbond.addParticle([sigma])

    # Create integrator
    integrator = BrownianIntegrator(temperature, frictionCoeff, step_size)

    # Create platform
    platform = Platform.getPlatformByName('CUDA')

    # Create simulation
    simulation = Simulation(pdb.topology, system, integrator, platform)
    print('Simulation is initiated')
    print('REMARK  Using OpenMM platform %s' % simulation.context.getPlatform().getName())

    # Set initial positions for the particles
    simulation.context.setPositions(initPosInNm)

    # Simulate
    # We can add dcd or other reporters to the simulation to get desired output with
    ## Note: Ben's version 
    simulation.reporters.append(dcdReporter)

    time = 0.001 # <----- can't start at 0; Otherwise, the calculation blows up 
    
    
    ## Set the initial stateVariable: Starting from 0 for now. 
    #odeiter = 5
    live_num_cells = numOfCells1 + numOfCells2
    stateVariable = np.ones([live_num_cells])
   
    positions = simulation.context.getState(getPositions=True).getPositions()
    
    print("|------ calibration initiated -----|")
    for num_iter in range(1, 10000): ### What is this? 
        positions = simulation.context.getState(getPositions=True).getPositions()
        simulation.step(stepFreq)
        state = simulation.context.getState(getEnergy=True, getForces=True)
        time += stepFreq
    
    print("|----- simulation initiated -----|")
    
    time_state = 1e-14
    
    
    Ix = np.ones(live_num_cells)
    Iy = np.ones(live_num_cells)
    DMx = np.zeros(live_num_cells)
    DMy = np.zeros(live_num_cells)
    UMx = np.zeros(live_num_cells)
    UMy = np.zeros(live_num_cells)
    
    odes = {'Ix': Ix,
            'Iy': Iy,
            'DMx': DMx,
            'DMy': DMy,
            'UMx': UMx, 
            'UMy': UMy}
    
    dummy_force_x = []
    
    for num_iter in range(1, Repeat): ### What is this? 
        positions = simulation.context.getState(getPositions=True).getPositions()
        # forces_vec will contain external forces that we want to feed into OpenMM.
        # Get current positions of the particles for concentration field/forces calculation
        ##################################################################################################################
        ###                                    Where All the Magical Things Happen                                     ###
        ##################################################################################################################
        if num_iter == 1:
            ConcByCell = np.zeros(live_num_cells) + 1e-14
        
        
        fvX, fvY, fvZ, ConcbyCell, odes, ConcbyOrigin = calc.calcForce(positions,
                                                                       live_num_cells,
                                                                       DeadCellRef1,
                                                                       OriginOfExternalSignal,
                                                                       oriConc,
                                                                       cellConc,
                                                                       Diff,
                                                                       time_state,
                                                                       kd,
                                                                       highBC,
                                                                       DispScale,
                                                                       searchingRange,
                                                                       marker,
                                                                       auto_factor,
                                                                       DiffState,
                                                                       ConcByCell,
                                                                       odes,
                                                                       step_size,
                                                                       shape_factor)
        
        
        
        stateVariable, stateDepFactor = calc.calcStateVariable(live_num_cells, 
                                                               time_state, 
                                                               ConcbyCell, 
                                                               stateVariable) 
        
        
        forces_vec                    = calc.calcForceModified(num_particles,
                                                               DeadCellRef1,
                                                               fvX, 
                                                               fvY, 
                                                               fvZ, 
                                                               stateDepFactor, 
                                                               mig_factor,
                                                               stateVar)
        
        #print(forces_vec[1])
        
        # Feed external forces into OpenMM
        in_force.updateForceInContext(simulation.context, forces_vec)
        # Advance simulation for 1 steps
        simulation.step(stepFreq)
        state = simulation.context.getState(getEnergy=True, getForces=True)
        time += stepFreq
        time_state += stepFreq
    
    
    #plt.plot(range(1,Repeat),dummy_force_x)
    #plt.savefig("force.png")
    #print(ConcbyOrigin)
    if state == 'steady':
        print('from ',num_particles,' of cells, total of ',np.sum(ConcbyOrigin),' is being released by Cells with given conditions')
Esempio n. 2
0
def simulator(
    oriConc=10,  # the max concentration released from the source of chemoattractant
    cellConc=1,  # the max concentration released by cells (determining the degree of intercellular communication)
    Diff=10,  # the diffusion rate of chemoattractant 
    kd=10,  # constant associated with Hills coefficient for autocrinic release
    DispScale=100000,  # Displacement Scale ... wrong name I guess 
    searchingRange=0.1,  # searching range around the cell 
    numOfCells1=50,  # a total number of cells in the 1st section of simulation box 
    numOfCells2=50,  # a total number of cells in the 2nd section of simulation box 
    CentoR=0,  # this will determine the size of 1st section of simulation box in x axis
    pdbFileName='temp',  # generated PDB file name 
    dcdfilename='test_output2',  # generated DCD file name 
    lowlimBoxlen=0,  # in angstrom = 1/10 of nanometer (REMEMBER!!) ??? do I need this? 
    highlimBoxlen=1000,  # in angstrom = 1/10 of nanometer (REMEMBER!!)
    SourceOfOrigin=None,  # None = One end of simulation box in x axis, Center = the center of simulation box 
    simLength=10000,  # a total number of the simulation steps 
    dumpSize=100,  # dump size in the dcd generation process 
    restingRatio1=0.8,  # the proportion of resting cells in the overall population of cells in the 1st section 
    restingRatio2=0.8,  # the proportion of resting cells in the overall population of cells in the 2nd section 
    restMig=0.5,  # the degree of migratory response of resting cells 
    actMig=0.1,  # the degree of migratory response of activated cells 
    restAuto=10,  # the degree of autocrinic release of resting cells: the larger, the less insensitive
    actAuto=0.1,  # the degree of autocrinic release of activated cells
    shape='slab',  # shape of simulation box: either slab or square 
    DiffState='steady'  # the characteristics of diffusion of chemoattractant: steady, error, or linear 
):

    # This will generate the random structure that makes no sence but will be processed again
    ## Note: This will generate dummy pdb file that will pass the test run but it is irrelevant to the actual calculation.
    calc.PDBgenNoPBC(pdbFileName, numOfCells1, numOfCells2, restingRatio1,
                     restingRatio2)
    pdb = PDBFile(pdbFileName + '.pdb')

    # Configure Dumping frequency
    dumpingstep = dumpSize
    dcdReporter = DCDReporter(dcdfilename + '.dcd', dumpingstep)

    # Simulation Box Dimension in angstrom
    if shape == 'slab':
        shape_factor = 3
    elif shape == 'square':
        shape_factor = 1

    ## Configure the coordinate of origin of external signal cascades
    if SourceOfOrigin is None:
        dummy = (np.int(highlimBoxlen * shape_factor)) / (10)
        OriginOfExternalSignal = [dummy, 0, 0]  # in nanometer
    elif SourceOfOrigin == 'Center':
        dummy = (np.int(highlimBoxlen)) / (10)
        OriginOfExternalSignal = [dummy * shape_factor / 2, dummy / 2, 0]

    # Defining the dimension of simulation box
    x = [lowlimBoxlen, highlimBoxlen * shape_factor]
    y = [lowlimBoxlen, highlimBoxlen]
    z = [0, 0]
    highBC = np.array([x[1], y[1], z[1]])

    # Configure Simulation Length
    Repeat = simLength
    stepFreq = 1

    # Parameters determining the dynamics of cells
    MassOfCell = 100
    RepulsiveScale = 0.01  # this can determine the distance among cells themselves
    ### Simulation parameters
    temperature = 295  #0.0    # K   <---- set to 0 to get rid of wiggling for now
    frictionCoeff = 1.0  # 1/ps
    step_size = 0.002  # ps

    ##########################################################
    ###              OpenMM Simulation Control             ###
    ##########################################################
    # Create an OpenMM System object
    system = System()

    # Create CustomNonbondedForce. We use it to implement repulsive potential between particles.
    # Only keep repulsive part of L-J potential
    nonbond = CustomNonbondedForce("(sigma/r)^12; sigma=0.5*(sigma1+sigma2)")
    nonbond.addPerParticleParameter("sigma")
    # Here we don't use cutoff for repulsive potential, but adding cutoff might speed things up a bit as interaction
    # strength decays very fast.
    nonbond.setNonbondedMethod(CustomNonbondedForce.NoCutoff)
    # Add force to the System
    system.addForce(nonbond)

    # FeedInForce is an OpenMM Force object that serves as the interface to feed forces into the simulation. It stores
    # additional forces that we want to introduce internally and has a method
    # .updateForceInContext(OpenMM::Context context, vector< vector<double> > in_forces). in_forces should be a vector of
    # 3d vectors - one 3d vector per particle and each 3d vector should contain X,Y,Z components of the force.
    # updateForceInContext() will copy forces from in_forces into internal variable that will keep them
    # until updateForceInContext() is called again. Every simulation step OpenMM will add forces stored in FeedInForce to
    # the simulation. You don't need to call updateForceInContext() every step if the forces didn't change - OpenMM will
    # use the forces from the last call of updateForceInContext().
    in_force = FeedInForce()
    # Add in_force to the system
    system.addForce(in_force)

    num_particles = len(pdb.getPositions())

    ### Make it 2D
    energy_expression = 'k * (z^2)'
    force = openmm.CustomExternalForce(energy_expression)
    force.addGlobalParameter('k', 999)
    for particle_index in range(num_particles):
        force.addParticle(particle_index, [])
    system.addForce(force)
    ## This will generate more reasonable structure but still needs to take number of particle from the arbitrary structure
    ## The reason I choose to do so is generating PDB file is little tricky due to its sensitivity to line arrangement
    min_dist_among_cells = 5
    xlow_end = x[0]
    xhigh_end = x[1]
    ylow_end = y[0]
    yhigh_end = y[1]
    '''
    [Outcomes of genCellCoord3D]
    initPosInNm: coordnates of cells in array format (num_particles by [x,y,z]) 
    marker: a list of markers for resting and activated cells (length of num_particles) 
    migration_factor: a list of constants for migration degree for resting and activated (length of num_particles)
    autocrine_factor: a list of constants for autocrinic degree for resting and activated (lengh of num_particles)
    '''
    initPosInNm, marker, mig_factor, auto_factor = calc.genCellCoord3D(
        numOfCells1, numOfCells2, min_dist_among_cells, CentoR, xlow_end,
        xhigh_end, ylow_end, yhigh_end, restingRatio1, restingRatio2, restMig,
        actMig, restAuto, actAuto)

    for i in range(num_particles):
        # Populate the system with particles.
        # system.addParticle(mass in atomic mass units)
        system.addParticle(MassOfCell)  # 100.0 is a particle mass
        # Add particles to CustomNonbondedForce. Here we define repulsion strength sigma for each particle. If particles
        # have different value of sigma, combination rule sigma=0.5*(sigma1+sigma2) will be applied as defined in
        # CustomNonbondedForce force expression.
        sigma = RepulsiveScale
        nonbond.addParticle([sigma])

    # Create integrator
    integrator = BrownianIntegrator(temperature, frictionCoeff, step_size)

    # Create platform
    platform = Platform.getPlatformByName('CUDA')

    # Create simulation
    simulation = Simulation(pdb.topology, system, integrator, platform)
    print('Simulation is initiated')
    print('REMARK  Using OpenMM platform %s' %
          simulation.context.getPlatform().getName())

    # Set initial positions for the particles
    simulation.context.setPositions(initPosInNm)

    # Simulate
    # We can add dcd or other reporters to the simulation to get desired output with
    ## Note: Ben's version
    simulation.reporters.append(dcdReporter)

    time = 0.001  # <----- can't start at 0; Otherwise, the calculation blows up

    ## Set the initial stateVariable: Starting from 0 for now.
    #odeiter = 5
    stateVariable = np.ones([num_particles])

    # storing initial position
    rest_cell_no = int(numOfCells1 * restingRatio1) + int(
        numOfCells2 * restingRatio2) + 2
    act_cell_no = num_particles - rest_cell_no
    resting_start = np.zeros([2, rest_cell_no])
    activated_start = np.zeros([2, act_cell_no])

    positions = simulation.context.getState(getPositions=True).getPositions()

    rest_cnt = 0
    act_cnt = 0
    cell_cnt = 0

    for pos in enumerate(positions):
        if marker[cell_cnt] == 'resting':
            resting_start[0][rest_cnt] = pos[1][0].value_in_unit(angstroms)
            resting_start[1][rest_cnt] = pos[1][1].value_in_unit(angstroms)
            rest_cnt += 1

        elif marker[cell_cnt] == 'activated':
            activated_start[0][act_cnt] = pos[1][0].value_in_unit(angstroms)
            activated_start[1][act_cnt] = pos[1][1].value_in_unit(angstroms)
            act_cnt += 1

        cell_cnt += 1

    print("|------ calibration initiated -----|")
    for num_iter in range(1, 5000):  ### What is this?
        positions = simulation.context.getState(
            getPositions=True).getPositions()
        simulation.step(stepFreq)
        state = simulation.context.getState(getEnergy=True, getForces=True)
        time += stepFreq

    print("|----- simulation initiated -----|")

    time_state = 1e-14
    for num_iter in range(1, Repeat):  ### What is this?
        positions = simulation.context.getState(
            getPositions=True).getPositions()
        # forces_vec will contain external forces that we want to feed into OpenMM.
        # Get current positions of the particles for concentration field/forces calculation
        ##################################################################################################################
        ###                                    Where All the Magical Things Happen                                     ###
        ##################################################################################################################
        if num_iter == 1:
            ConcByCell = np.zeros(num_particles) + 1e-14

        fvX, fvY, fvZ, ConcbyCell = calc.calcForce(
            positions, num_particles, OriginOfExternalSignal, SourceOfOrigin,
            oriConc, cellConc, Diff, time_state, kd, highBC, DispScale,
            searchingRange, marker, auto_factor, DiffState, ConcByCell)

        #print(ConcbyCell[1])
        stateVariable, stateDepFactor = calc.calcStateVariable(
            num_particles, time_state, ConcbyCell, stateVariable)
        if num_iter == 1:
            print('#********* The Beginning **********#')
            print(fvX[1], fvY[1])
        elif num_iter == Repeat - 1:
            print('#********* The Ending **********#')
            print(fvX[1], fvY[1])

        forces_vec = calc.calcForceModified(num_particles, fvX, fvY, fvZ,
                                            stateDepFactor, mig_factor)

        #print(forces_vec[1])

        # Feed external forces into OpenMM
        in_force.updateForceInContext(simulation.context, forces_vec)
        # Advance simulation for 1 steps
        simulation.step(stepFreq)
        state = simulation.context.getState(getEnergy=True, getForces=True)
        time += stepFreq
        time_state += stepFreq