libSBML Python API  5.10.0
 All Classes Namespaces Files Functions Variables Modules Pages
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)