Skip to content

Commit

Permalink
Entropy updates
Browse files Browse the repository at this point in the history
  • Loading branch information
alsinmr committed May 22, 2024
1 parent bc99eb1 commit 4db12f1
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 18 deletions.
113 changes: 96 additions & 17 deletions Entropy/Entropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from .. import clsDict,Defaults
from ..MDtools import vft
from ..misc.tools import AA
from ..IO.bin_IO import read_EntropyCC,write_EntropyCC
from copy import copy
import matplotlib.pyplot as plt
import os

from matplotlib.colors import ListedColormap

Expand All @@ -26,11 +28,40 @@ class EntropyCC:
R=8.31446261815324 #J/mol/K

def __init__(self,select):
"""
Initialize the Entropy Cross-Correlation object with either a selection
object or filename from a saved EntropyCC object
Parameters
----------
select : MolSelect or string
pyDR selection object or filename
Returns
-------
None
"""
filename=None
if isinstance(select,str):
filename=select
with open(filename,'rb') as f:
assert bytes.decode(f.readline()).strip()=='OBJECT:ENTROPYCC','Not an EntropyCC object'
temp=read_EntropyCC(f)
select=temp.select



self.select=copy(select)
self.select.molsys=copy(select.molsys)
self.select.molsys._traj=copy(select.traj)

self.reset()

if filename is not None:
self._Sres=temp._Sres
self._Scc=temp._Scc


def reset(self):
"""
Expand All @@ -45,7 +76,6 @@ def reset(self):
self._resid=None
self._sel=None
self._index=None
self._FrObj=None
self._vt=None
self._chi=None
self._v_avg=None
Expand All @@ -56,11 +86,19 @@ def reset(self):
self._CCstate=None
self._Scc=None
self._CC=None
self._DelS=None

self.project=self.select.project

return self

@property
def project(self):
if self.select.project is None:
self.select.molsys.project=clsDict['Project']()
return self.select.project

@project.setter
def project(self,project):
self.select.molsys.project=project

@property
def resi(self):
Expand Down Expand Up @@ -249,6 +287,23 @@ def load(self):
self.traj.ProgressBar=False
return self

@property
def t(self):
"""
Time axis in nanoseconds. Note that for appended trajectories, t is not
valid and will return None
Returns
-------
TYPE
np.array
"""
if self._state is not None:
if self.state.shape[1]!=len(self.traj):return None

return np.arange(len(self.traj))*self.traj.dt/1000

@property
def vt(self):
"""
Expand Down Expand Up @@ -450,6 +505,8 @@ def CC(self):
bottom+=self.Sres
bottom=bottom.T+self.Sres
top=2*bottom-2*self.Scc
i=top==0
bottom[i]=1
self._CC=top/bottom
return self._CC

Expand All @@ -466,18 +523,6 @@ def Smax(self):
"""
return np.log(self.total_mult)*self.R

@property
def DelS(self):
"""
Returns the change in the total entropy resulting from a given residue
being removed from the system.
Returns
-------
None.
"""
x=np.cumsum([self.total_mult])

#%% Plotting

Expand Down Expand Up @@ -649,7 +694,8 @@ def chimera(self,index=None,scaling:float=None,norm:bool=True,color=[1,0,0,1]):
ID=self.project.chimera.CMXid
else:
ID=CMXRemote.launch()
mn=CMXRemote.valid_models(ID)[-1]
mn=CMXRemote.valid_models(ID)[-1]
CMXRemote.send_command(ID,f'~show #{mn}')
CMXRemote.send_command(ID,f'ribbon #{mn}')
CMXRemote.send_command(ID,f'show #{mn}&~@H*&~:GLY,ALA,PRO')

Expand Down Expand Up @@ -717,13 +763,18 @@ def CCchimera(self,index=None,indexCC:int=None,scaling:float=None,norm:bool=True
self.select.chimera(x=x,index=index)
sel0=self.select.repr_sel[index][indexCC]
mn=CMXRemote.valid_models(ID)[-1]
CMXRemote.send_command(ID,'color '+'|'.join(['#{0}/{1}:{2}@{3}'.format(mn,s.segid,s.resid,s.name) for s in sel0])+' black')
CMXRemote.send_command(ID,'color '+'|'.join([f'#{mn}/{s.segid}:{s.resid}@{s.name}' for s in sel0])+' black')
CMXRemote.send_command(ID,f'~show #{mn}')
CMXRemote.send_command(ID,f'ribbon #{mn}')
CMXRemote.send_command(ID,f'show #{mn}&~@H*&~:GLY,ALA,PRO')
CMXRemote.send_command(ID,f'set bgColor gray')
# print('color '+'|'.join(['#{0}/{1}:{2}@{3}'.format(mn,s.segid,s.resid,s.name) for s in sel0])+' black')
else:

self.select.chimera()
mn=CMXRemote.valid_models(ID)[-1]
CMXRemote.send_command(ID,f'color #{mn} tan')
CMXRemote.send_command(ID,f'~show #{mn}')
CMXRemote.send_command(ID,f'ribbon #{mn}')
CMXRemote.send_command(ID,f'show #{mn}&~@H*&~:GLY,ALA,PRO')
CMXRemote.send_command(ID,f'set bgColor gray')
Expand All @@ -734,6 +785,34 @@ def CCchimera(self,index=None,indexCC:int=None,scaling:float=None,norm:bool=True

if self.project is not None:
self.project.chimera.command_line(self.project.chimera.saved_commands)

def save(self,filename:str,overwrite:bool=False):
"""
Save the EntropyCC object to a file. This will store the states for
reanalysis. Re-accessing the vectors will require a full reload. The project
object is also not saved, but reloading will create a new dummy project
(Entropy data is not stored in projects, so the project function only
provides chimera functionality)
Reloading is performed by calling EntropyCC with the filename rather than
the selection object.
Parameters
----------
filename : str
Storage location.
overwrite : bool
Overwrite existing file
Returns
-------
None.
"""
if not(overwrite):
assert not(os.path.exists(filename)),'File already exists. Set overwrite=True to save anyway'
with open(filename,'wb') as f:
write_EntropyCC(f,self)



Expand Down
28 changes: 28 additions & 0 deletions IO/bin_IO.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def write_file(filename,ob,overwrite=False):
write_Data_iRED(f,ob)
elif object_class=='Source':
write_Source(f,ob)
elif object_class=='EntropyCC':
write_EntropyCC(f,ob)

def read_file(filename:str,directory:str='')->object:
with open(filename,'rb') as f:
Expand All @@ -78,6 +80,8 @@ def read_file(filename:str,directory:str='')->object:
return out
if l=='OBJECT:MOLSELECT':
return read_MolSelect(f,directory=directory)
if l=='OBJECT:ENTROPYCC':
return read_EntropyCC(f)


#%% Info Input/Output
Expand Down Expand Up @@ -465,6 +469,30 @@ def read_MolSelect(f,directory=''):
line=decode(f.readline())[:-1]
return select

#%% EntropyCC
def write_EntropyCC(f,ECC):
f.write(b'OBJECT:ENTROPYCC\n')
write_MolSelect(f, ECC.select)
flds=['Sres','Scc']

for fld in flds:
f.write(bytes(f'\n{fld}\n','utf-8'))
np.save(f,getattr(ECC,fld),allow_pickle=True)
f.write(b'END:OBJECT\n')

def read_EntropyCC(f):
EntropyCC=clsDict['EntropyCC']
line=decode(f.readline())[:-1]
assert line=='OBJECT:MOLSELECT','First object in EntropyCC should be the selection object'
ECC=EntropyCC(read_MolSelect(f))

flds=['Sres','Scc']
for l in f:
k=decode(l)[:-1]
if k=='END:OBJECT':break
if k in flds:
setattr(ECC,f'_{k}',np.load(f,allow_pickle=False))
return ECC

#%% Numpy object Input/Ouput
def write_np_object(f,ob):
Expand Down
8 changes: 7 additions & 1 deletion __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,18 @@

from pyDR.Project import Project,Source

from pyDR.Entropy import EntropyCC

clsDict.update({'Data':Data,'Data_iRED':Data_iRED,'Source':Source,'Info':Sens.Info,
'Sens':Sens.Sens,'Detector':Sens.Detector,'NMR':Sens.NMR,'MD':Sens.MD,'SolnNMR':Sens.SolnNMR,
'MolSys':MolSys,'MolSelect':MolSelect,'Project':Project,
'FrameObj':Frames.FrameObj,'Ctcalc':MDtools.Ctcalc,
'DataPlots':Plotting.DataPlots,'CMXRemote':CMXRemote,'Movies':Movies})
'DataPlots':Plotting.DataPlots,'CMXRemote':CMXRemote,'Movies':Movies,
'EntropyCC':EntropyCC})



#%% Edit matlabplot subplotspec behavior to be consistent across versions
from matplotlib.axes import Subplot as _Subplot
from matplotlib.gridspec import SubplotSpec as _SubplotSpec
if hasattr(_SubplotSpec,'is_first_col'):
Expand All @@ -92,6 +96,8 @@ def _fun(self):
return self.get_subplotspec().is_last_row()
_Subplot.is_last_row=_fun


#%% Warning handling
import warnings
warnings.filterwarnings("ignore", category=UserWarning)
warnings.filterwarnings('ignore', module='MDAnalysis')

0 comments on commit 4db12f1

Please sign in to comment.