| 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 |