Conditions | 20 |
Total Lines | 155 |
Code Lines | 61 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like build.rna_tools.tools.PyMOL4RNA.external_flatten_object.flatten_obj() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | """ |
||
177 | def flatten_obj(name="",selection="",state=0,rename=0,quiet=1,chain_map=""): |
||
178 | """ |
||
179 | DESCRIPTION |
||
180 | |||
181 | "flatten_obj" combines multiple objects or states into a single object, |
||
182 | renaming chains where required |
||
183 | |||
184 | USAGE |
||
185 | |||
186 | flatten_obj name, selection[, state[, rename[, quiet[, chain_map]]]] |
||
187 | |||
188 | ARGUMENTS |
||
189 | |||
190 | name = a unique name for the flattened object {default: flat} |
||
191 | |||
192 | selection = the set of objects to include in the flattening. The selection |
||
193 | will be expanded to include all atoms of objects. {default: all} |
||
194 | |||
195 | state = the source state to select. Use 0 or -1 to flatten all states {default: 0} |
||
196 | |||
197 | rename = The scheme to use for renaming chains: {default: 0} |
||
198 | (0) preserve chains IDs where possible, rename other chains |
||
199 | alphabetically |
||
200 | (1) rename all chains alphabetically |
||
201 | (2) rename chains using the original chain letter, object name, and state |
||
202 | |||
203 | quiet = If set to 0, print some additional information about progress and |
||
204 | chain renaming {default: 1} |
||
205 | |||
206 | chain_map = An attribute name for the 'stored' scratch object. If |
||
207 | specified, `stored.<chain_map>` will be populated with a dictionary |
||
208 | mapping the new chain names to a tuple giving the originated object, |
||
209 | state, and chainID. {default: ""} |
||
210 | |||
211 | NOTES |
||
212 | |||
213 | Like the select command, if name is omitted then the default object name |
||
214 | ("flat") is used as the name argument. |
||
215 | |||
216 | Chain renaming is tricky. PDB files originally limited chains to single |
||
217 | letter identifiers containing [A-Za-z0-9]. When this was found to be |
||
218 | limiting, multi-letter chains (ideally < 4 chars) were allowed. This is |
||
219 | supported as of PyMOL 1.7. Earlier versions do not accept rename=2, and |
||
220 | will raise an exception when flattening a structure with more than 62 |
||
221 | chains. |
||
222 | |||
223 | EXAMPLES |
||
224 | |||
225 | flatten_obj flat, nmrObj |
||
226 | flatten_obj ( obj1 or obj2 ) |
||
227 | |||
228 | SEE ALSO |
||
229 | |||
230 | split_states |
||
231 | |||
232 | """ |
||
233 | |||
234 | # arguments |
||
235 | |||
236 | # Single argument; treat as selection |
||
237 | if name and not selection: |
||
238 | selection = name |
||
239 | name = "" |
||
240 | # default name and selection |
||
241 | if not name: |
||
242 | name = "flat" |
||
243 | if not selection: |
||
244 | selection = "(all)" |
||
245 | |||
246 | state = int(state) |
||
247 | rename = int(rename) |
||
248 | quiet = int(quiet) |
||
249 | |||
250 | # Wrap in extra parantheses for get_object_list |
||
251 | selection = "( %s )" % selection |
||
252 | |||
253 | if rename == 0: |
||
254 | chainSet = DefaultChainSet() |
||
255 | elif rename == 1: |
||
256 | chainSet = SequentialChainSet() |
||
257 | elif rename == 2: |
||
258 | chainSet = LongChainSet() |
||
259 | else: |
||
260 | raise ValueError("Unrecognized rename option (Valid: 0,1,2)") |
||
261 | |||
262 | metaprefix = "temp" #TODO unique prefix |
||
263 | |||
264 | # store original value of retain_order, which causes weird interleaving of |
||
265 | # structures if enabled. |
||
266 | retain_order = cmd.get("retain_order") |
||
267 | try: |
||
268 | cmd.set("retain_order",0) |
||
269 | |||
270 | # create new object for each state |
||
271 | for obj in cmd.get_object_list(selection): |
||
272 | |||
273 | if state <= 0: |
||
274 | # all states |
||
275 | prefix = "%s_%s_"%(metaprefix,obj) |
||
276 | cmd.split_states(obj,prefix=prefix) |
||
277 | else: |
||
278 | prefix = "%s_%s_%04d"%(metaprefix,obj,state) |
||
279 | cmd.create(prefix, obj, state, 1) |
||
280 | |||
281 | # renumber all states |
||
282 | statere = re.compile("^%s_(.*)_(\d+)$" % metaprefix) # matches split object names |
||
283 | |||
284 | warn_lowercase = False |
||
285 | |||
286 | # Iterate over all objects with metaprefix |
||
287 | try: |
||
288 | for obj in cmd.get_object_list("(%s_*)"%(metaprefix) ): |
||
289 | m = statere.match(obj) |
||
290 | if m is None: |
||
291 | print(("Failed to match object %s" %obj)) |
||
292 | continue |
||
293 | origobj = m.group(1) |
||
294 | statenum = int(m.group(2)) |
||
295 | |||
296 | chains = cmd.get_chains(obj) |
||
297 | |||
298 | rev_chain_map = {} #old -> new, for this obj only |
||
299 | for chain in sorted(chains,key=lambda x:(len(x),x)): |
||
300 | new_chain = chainSet.map_chain(origobj,statenum,chain) |
||
301 | rev_chain_map[chain] = new_chain |
||
302 | if not quiet: |
||
303 | print((" %s state %d chain %s -> %s"%(origobj,statenum,chain, new_chain) )) |
||
304 | if not _long_chains: |
||
305 | if len(new_chain) > 1: |
||
306 | raise OutOfChainsError("No additional chains available (max 62).") |
||
307 | |||
308 | space = {'rev_chain_map':rev_chain_map} |
||
309 | cmd.alter(obj,"chain = rev_chain_map[chain]",space=space) |
||
310 | |||
311 | print(("Creating object from %s_*"%metaprefix)) |
||
312 | # Recombine into a single object |
||
313 | cmd.create(name,"%s_*"%metaprefix) |
||
314 | |||
315 | # Set chain_map |
||
316 | if chain_map: |
||
317 | setattr(stored,chain_map,chainSet) |
||
318 | |||
319 | # Warn if lowercase chains were generated |
||
320 | if cmd.get("ignore_case") == "on" and any([c.upper() != c for c in list(chainSet.keys())]): |
||
321 | print("Warning: using lower-case chain IDs. Consider running the " |
||
322 | "following command:\n set ignore_case, 0" ) |
||
323 | |||
324 | finally: |
||
325 | # Clean up |
||
326 | print("Cleaning up intermediates") |
||
327 | cmd.delete("%s_*"%metaprefix) |
||
328 | finally: |
||
329 | # restore original parameters |
||
330 | print("Resetting variables") |
||
331 | cmd.set("retain_order",retain_order) |
||
332 | |||
339 |