libSBML Python API  5.11.0
setIdFromNames.py

Program that renames all SIds that also have names specified. The new identifiers will be derived from the name, with all invalid characters removed.

1 #!/usr/bin/env python
2 ##
3 ## @file setIdFromNames.py
4 ## @brief Utility program, renaming all SIds that also has
5 ## names specified. The new id will be derived from
6 ## the name, with all invalid characters removed.
7 ##
8 ## @author Frank T. Bergmann
9 ##
10 ##
11 ## <!--------------------------------------------------------------------------
12 ## This sample program is distributed under a different license than the rest
13 ## of libSBML. This program uses the open-source MIT license, as follows:
14 ##
15 ## Copyright (c) 2013-2014 by the California Institute of Technology
16 ## (California, USA), the European Bioinformatics Institute (EMBL-EBI, UK)
17 ## and the University of Heidelberg (Germany), with support from the National
18 ## Institutes of Health (USA) under grant R01GM070923. All rights reserved.
19 ##
20 ## Permission is hereby granted, free of charge, to any person obtaining a
21 ## copy of this software and associated documentation files (the "Software"),
22 ## to deal in the Software without restriction, including without limitation
23 ## the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 ## and/or sell copies of the Software, and to permit persons to whom the
25 ## Software is furnished to do so, subject to the following conditions:
26 ##
27 ## The above copyright notice and this permission notice shall be included in
28 ## all copies or substantial portions of the Software.
29 ##
30 ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
33 ## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
35 ## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
36 ## DEALINGS IN THE SOFTWARE.
37 ##
38 ## Neither the name of the California Institute of Technology (Caltech), nor
39 ## of the European Bioinformatics Institute (EMBL-EBI), nor of the University
40 ## of Heidelberg, nor the names of any contributors, may be used to endorse
41 ## or promote products derived from this software without specific prior
42 ## written permission.
43 ## ------------------------------------------------------------------------ -->
44 ##
45 ##
46 
47 import sys
48 import os.path
49 import time
50 import libsbml
51 
52 # This class implements an identifier transformer, that means it can be used
53 # to rename all sbase elements.
54 class SetIdFromNames(libsbml.IdentifierTransformer):
55  def __init__(self, ids):
56  # call the constructor of the base class
57  libsbml.IdentifierTransformer.__init__(self)
58  # remember existing ids ...
59  self.existingIds = ids
60 
61  # The function actually doing the transforming. This function is called
62  # once for each SBase element in the model.
63  def transform(self, element):
64  # return in case we don't have a valid element
65  if (element == None or element.getTypeCode() == libsbml.SBML_LOCAL_PARAMETER):
66  return libsbml.LIBSBML_OPERATION_SUCCESS;
67 
68  # or if there is nothing to do
69  if (element.isSetName() == False or element.getId() == element.getName()):
70  return libsbml.LIBSBML_OPERATION_SUCCESS;
71 
72  # find the new id
73  newId = self.getValidIdForName(element.getName());
74 
75  # set it
76  element.setId(newId);
77 
78  # remember it
79  self.existingIds.append(newId);
80 
81  return libsbml.LIBSBML_OPERATION_SUCCESS;
82 
83  def nameToSbmlId(self, name):
84  IdStream = []
85  count = 0;
86  end = len(name)
87 
88  if '0' <= name[count] and name[count] <= '9':
89  IdStream.append('_');
90  for count in range (0, end):
91  if (('0' <= name[count] and name[count] <= '9') or
92  ('a' <= name[count] and name[count] <= 'z') or
93  ('A' <= name[count] and name[count] <= 'Z')):
94  IdStream.append(name[count]);
95  else:
96  IdStream.append('_');
97  Id = ''.join(IdStream);
98  if (Id[len(Id) - 1] != '_'):
99  return Id;
100 
101  return Id[:-1]
102  #
103  # Generates the id out of the name, and ensures it is unique.
104  # It does so by appending numbers to the original name.
105  #
106  def getValidIdForName(self, name):
107  baseString = self.nameToSbmlId(name);
108  id = baseString;
109  count = 1;
110  while (self.existingIds.count(id) != 0):
111  id = "{0}_{1}".format(baseString, count);
112  count = count + 1
113  return id;
114 
115 
116 
117 #
118 # Returns a list of all ids from the given list of elements
119 #
120 def getAllIds(allElements):
121  result = []
122  if (allElements == None or allElements.getSize() == 0):
123  return result;
124 
125  for i in range (0, allElements.getSize()):
126  current = allElements.get(i);
127  if (current.isSetId() and current.getTypeCode() != libsbml.SBML_LOCAL_PARAMETER):
128  result.append(current.getId());
129  return result;
130 
131 
132 
133 def main (args):
134  """Usage: setIdFromNames filename output
135  """
136  if len(args) != 3:
137  print(main.__doc__)
138  sys.exit(1)
139 
140  filename = args[1];
141  output = args[2];
142 
143  # read the document
144  start = time.time() * 1000;
145  document = libsbml.readSBMLFromFile(filename);
146  stop = time.time() * 1000;
147 
148 
149  print ""
150  print " filename: {0}".format( filename);
151  print " read time (ms): {0}".format( stop - start);
152 
153  # stop in case of serious errors
154  errors = document.getNumErrors(libsbml.LIBSBML_SEV_ERROR);
155  if (errors > 0):
156  print " error(s): {0}".format(errors);
157  document.printErrors();
158  sys.exit (errors);
159 
160 
161  # get a list of all elements, as we will need to know all identifiers
162  # so that we don't create duplicates.
163  allElements = document.getListOfAllElements();
164 
165  # get a list of all ids
166  allIds = getAllIds(allElements);
167 
168  # create the transformer with the ids
169  trans = SetIdFromNames(allIds);
170 
171  # rename the identifiers (using the elements we already gathered before)
172  start = time.time() * 1000;
173  document.getModel().renameIDs(allElements, trans);
174  stop = time.time() * 1000;
175  print " rename time (ms): {0}".format(stop - start);
176 
177  # write to file
178  start = time.time() * 1000;
179  libsbml.writeSBMLToFile(document, output);
180  stop = time.time() * 1000;
181  print " write time (ms): {0}".format(stop - start);
182  print "";
183 
184  # if we got here all went well ...
185 
186 if __name__ == '__main__':
187  main(sys.argv)