bng_species_reader_example.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. """
  2. This is free and unencumbered software released into the public domain.
  3. Anyone is free to copy, modify, publish, use, compile, sell, or
  4. distribute this software, either in source code form or as a compiled
  5. binary, for any purpose, commercial or non-commercial, and by any
  6. means.
  7. In jurisdictions that recognize copyright laws, the author or authors
  8. of this software dedicate any and all copyright interest in the
  9. software to the public domain. We make this dedication for the benefit
  10. of the public at large and to the detriment of our heirs and
  11. successors. We intend this dedication to be an overt act of
  12. relinquishment in perpetuity of all present and future rights to this
  13. software under copyright law.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  17. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. OTHER DEALINGS IN THE SOFTWARE.
  21. For more information, please refer to [http://unlicense.org]
  22. """
  23. import sys
  24. import os
  25. import pandas as pd
  26. MCELL_PATH = os.environ.get('MCELL_PATH', '')
  27. if MCELL_PATH:
  28. sys.path.append(os.path.join(MCELL_PATH, 'lib'))
  29. else:
  30. print("Error: variable MCELL_PATH that is used to find the mcell library was not set.")
  31. sys.exit(1)
  32. import mcell as m
  33. # utility module to load ASCII viz_output .dat file from
  34. import species_reader
  35. def get_bound_em(complex, src_em, comp_name):
  36. # assuming that there is a single component in src_em
  37. # (source elementary molecule) with comp_name that is bound
  38. bond_index = -1
  39. for c in src_em.components:
  40. if c.component_type.name == comp_name:
  41. # not allowed cases, we need the number
  42. assert c.bond != m.BOND_UNBOUND # no bond
  43. assert c.bond != m.BOND_ANY # !?
  44. assert c.bond != m.BOND_BOUND # !+
  45. bond_index = c.bond
  46. assert bond_index != -1, "Did not find " + comp_name + " in " + src_em.to_bngl_str()
  47. # find this bond in the complex (might be slow)
  48. for em in complex.elementary_molecules:
  49. if em is src_em:
  50. continue
  51. for c in em.components:
  52. if c.bond == bond_index:
  53. return em
  54. assert False, "Did not find paired bond " + str(bond_index) + " in " + complex.to_bngl_str()
  55. def convert_species_file(file_name):
  56. # read the .species file and parse complexes to the internal MCell
  57. # representation
  58. complex_counts = species_reader.read_species_file(file_name)
  59. # prepare the component type that we will append to the CaMKII molecules
  60. # the new component means 'upper' and has a boolean state
  61. ct_u = m.ComponentType('u', ['0','1'])
  62. # process the data by adding component 'u' to the CaMKII elementary molecules
  63. for (complex, count) in complex_counts:
  64. # if this a CaMKII dodecamer?
  65. camkiis = []
  66. for em in complex.elementary_molecules:
  67. em_name = em.elementary_molecule_type.name
  68. if em_name == 'CaMKII':
  69. camkiis.append(em)
  70. if len(camkiis) != 12:
  71. # output it directly
  72. print(complex.to_bngl_str() + " " + str(count))
  73. continue
  74. # ok, we have the holoenzyme, how can we figure out which
  75. # of the CaMKIIs belong to the upper and the lower
  76. # ring?
  77. # let's say that the first one is in the upper ring,
  78. # go along the 'r'
  79. upper_first = camkiis[0]
  80. upper_ring = [ upper_first ]
  81. curr = upper_first
  82. for i in range(1, 6):
  83. curr = get_bound_em(complex, curr, 'r')
  84. upper_ring.append(curr)
  85. assert upper_first is get_bound_em(complex, curr, 'r'), "A ring must be formed"
  86. # then go down along 'c' and go again along 'r' to get molecules of the lower ring
  87. lower_first = get_bound_em(complex, camkiis[0], 'c')
  88. lower_ring = [ lower_first ]
  89. curr = lower_first
  90. for i in range(1, 6):
  91. curr = get_bound_em(complex, curr, 'r')
  92. lower_ring.append(curr)
  93. assert lower_first is get_bound_em(complex, curr, 'r'), "A ring must be formed"
  94. # now the modifications - add components by instatiating the component type 'u'
  95. # the way how the complexes were is parsed was that each complex has its own instance
  96. # of the elementary molecule type for CaMKII so lets change one of them
  97. upper_first.elementary_molecule_type.components.append(ct_u)
  98. for em in upper_ring:
  99. em.components.append(ct_u.inst('1'))
  100. for em in lower_ring:
  101. em.components.append(ct_u.inst('0'))
  102. print(complex.to_bngl_str() + " " + str(count))
  103. if __name__ == '__main__':
  104. if len(sys.argv) != 2:
  105. print("Expected .species file name as argument")
  106. sys.exit(1)
  107. convert_species_file(sys.argv[1])