def shrink_helix(model, anchor5_id, anchor3_id, anchor5_upper_id,
                 anchor3_upper_id):
    """*shrink_helix(model,  anchor5_id,  anchor3_id,  anchor5_upper_id,  anchor3_upper_id)*

Makes helix shorter - cuts out a helix fragment between given residues from the model.

:Arguments:
    * Template or RnaModel
    * anchor5 - residue id on the 5' side belonging to the first base pair that will remain
    * anchor3 - residue id on the 3' side belonging to the first base pair that will remain
    * anchor5_upper - residue id on the 5' side belonging to the pair that will end up next to the first.
    * anchor3_upper - residue id on the 3' side belonging to the pair that will end up next to the first.
    """
    model = validate_model(model)
    anchor5_id = validate_resnum(anchor5_id)
    anchor3_id = validate_resnum(anchor3_id)
    anchor5_upper_id = validate_resnum(anchor5_upper_id)
    anchor3_upper_id = validate_resnum(anchor3_upper_id)

    hbuilder = HelixBuilder()
    helix = hbuilder.build_helix(Sequence('AA_UU'))
    fr = ModernaFragment2D(helix, anchor5=model[anchor5_id], \
                           anchor3=model[anchor3_id], \
                           anchor5_upper=model[anchor5_upper_id], \
                           anchor3_upper=model[anchor3_upper_id], \
                           frag5_upper = helix['2'], frag3_upper = helix['401'], \
                           model=model)
    model.insert_fragment(fr)
def add_modification(residue,
                     modification_name,
                     model=None,
                     residue_number=None):
    """*add_modification(residue, modification_name, model=None, residue_number=None)*

Adds a modification to a single residue. An RNAModel can be given optionally. If this is given, the modified residue is subsequently copied to it.

Note that deoxynucleotides count as modified bases as well.

:Arguments:
    * residue from a Template or RNAModel object
    * modification name (abbreviated as e.g. 'm6Am', 'm1G', 'm3U', 'mnm5s2U')
    * model (optional; if this is given, the residue is copied)
    * residue position in model (optional; by default the residue number is kept)
    """
    residue = validate_resi(residue)
    modification_name = validate_alphabet(modification_name)
    if model: model = validate_model(model)
    if residue_number: validate_resnum(residue_number)

    if model != None:
        model.add_one_modification_copy(residue, modification_name,
                                        residue_number)
    else:
        modifications.add_modification(residue, modification_name)
def exchange_single_base(residue, new_name, model=None, new_number=None):
    """*exchange_single_base(residue, new_name, model=None, new_number=None)*
    
Exchanges standard RNA bases in a residue.
This can be used to modify residues already in a model,
or to exchange and copy them in one step, if an RnaModel is given.
It is also possible to modify the template this way!

The residue number does not change by default, but a new one can be given.

:Arguments:
    * Residues from a Template or RnaModel
    * Abbreviation of the new base ('A', 'G', 'C' or 'U')
    * RnaModel object (optional)
    * New residue number in the model (optional)
    """
    residue = validate_resi(residue)
    new_name = validate_alphabet(new_name)
    if model: model = validate_model(model)
    if new_number: new_number = validate_resnum(new_number)

    if model:
        model.copy_residue(residue, new_number)
        number = new_number or residue.identifier
        modifications.exchange_base(model[number], new_name)
    else:
        modifications.exchange_base(residue, new_name)
def apply_indel(model, res5_number, res3_number, sequence):
    """*apply_indel(model, res5_number, res3_number, sequence)*

Finds the best fitting fragment between two residues, and inserts it into the model. 
The procedure automatically retrieves the 20 best fitting candidates from the fragment database, 
checks whether they produce any clashes upon insertion, and inserts the best scoring candidate.

:Arguments:
    * RNAmodel object
    * number of the residue on the 5' end of the fragment
    * number of the residue on the 3' end of the fragment
    * sequence of the fragment (not including the two residues specified above).
    """
    model = validate_model(model)
    res5_number = validate_resnum(res5_number)
    res3_number = validate_resnum(res3_number)
    sequence = validate_seq(sequence)

    model.insert_best_fragment(res5_number, res3_number, sequence)
def add_pair_to_base(model, anchor_id, new_id=None, new_sequence=None):
    """*add_pair_to_base(model,  anchor_id,  new_id=None,  new_sequence=None)*

Adds Watson-Crick paired second strand to single nucleotide.

:Arguments:
    * RNAModel object
    * Identifier of residue to which a new base pair will be added
    * New identifier for second strand
    * New sequence for second strand
    """
    model = validate_model(model)
    anchor_id = validate_resnum(anchor_id)
    if new_id: new_id = validate_resnum(new_id)
    if new_sequence: new_sequence = validate_seq(new_sequence)

    fr = ModernaFragmentStrand(anchor=model[anchor_id],
                               identifier=new_id,
                               new_sequence=new_sequence)
    model.insert_fragment(fr)
def delete_residue(residue_number, model):
    """*delete_residue(residue_number, model)*
    
Removes a residue from a RNAModel object.
   
:Arguments:
    * residue identifier e.g. '1', '6', '6A'
    * RnaModel object
    """
    model = validate_model(model)
    residue_number = validate_resnum(residue_number)

    model.remove_residue(residue_number)
def renumber_chain(struc, start_identifier='1'):
    """*renumber_chain(struc, start_id)*

Changes numeration of residues in the chain.
Starts with the given identifier. The new numeration is continuous.

:Arguments:
    * RnaModel or ModernaStructure object
    * identifier for first residue
    """
    struc = validate_structure(struc)
    start_identifier = validate_resnum(start_identifier)
    struc.renumber_chain(start_identifier)
def extend_helix(model, anchor5_id, anchor3_id, new_sequence=None):
    """*extend_helix(model, anchor5_id, anchor3_id, new_sequence=None)*

Makes a helix longer by adding A-type RNA Watson-Crick base pairs. 
A helix of any size may be added to the model.
A helix may be added at the end or inside an already existing helix.

:Arguments:
    * Template or RnaModel
    * Identifier of the residue on the 5' side to which helix will be added
    * Identifier of the residue on the 3' side to which helix will be added
    * Helix sequence as Sequence obiect e.g. Sequence('AAAA_UUUU')
    """
    model = validate_model(model)
    anchor5_id = validate_resnum(anchor5_id)
    anchor3_id = validate_resnum(anchor3_id)
    if new_sequence: new_sequence = validate_seq(new_sequence)

    hb = HelixFragmentBuilder()
    frag = hb.build_fragment(anchor5= model[anchor5_id], \
                    anchor3=model[anchor3_id], sequence=new_sequence, \
                    model=model)
    model.insert_fragment(frag)
def fix_backbone(model, resi1_number=None, resi2_number=None):
    """*fix_backbone(structure)*

Fixes interrupted backbones between adjacent residues.

This function either examines the backbone of all nt in a structure (and repairs them if broken), 
or only does this for the two residues specified. For repairing, first only the phosphate and adjacent oxygens are remodeled. 
In case this fails, the FCCD Loop Closing Algorithm (Boomsma/Hamelryck 2005) is used for the entire O3'..C4' segment.
If the two residues are far from each other or oriented in a weird angle, the result will be awkward.
    
:Arguments:
    * RnaModel object
    * residue number on the 5' side of the broken backbone (optional).
    * residue number on the 3' side of the broken backbone (optional).
    """
    model = validate_model(model)
    if resi1_number: resi1_number = validate_resnum(resi1_number)
    if resi2_number: resi2_number = validate_resnum(resi2_number)

    if resi1_number and resi2_number:
        model.fix_backbone_between_resis(model[resi1_number],
                                         model[resi2_number])
    else:
        model.fix_backbone()
def find_fragment(model,
                  res5_number,
                  res3_number,
                  sequence,
                  number_of_candidates=NUMBER_OF_FRAGMENT_CANDIDATES,
                  secstruc=None):
    """*find_fragment(model, res5_number, res3_number, sequence, number_of_candidates=20, secstruc=None)*

Searches fragment candidate structures that fit between two given residues. 
Produces a list of fragments candidate objects. The fragment search sorts candidates 
according to the geometrical fit of their backbones.

As an optional argument, a secondary structure can be specified in dot-bracket format. 
This restricts the found fragment candidates to those having exactly the same Watson-Crick pairs.

:Arguments:
    * RnaModel object
    * number of the residue at the 5' end of the fragment
    * number of the residue at the 3' end of the fragment
    * sequence of the fragment to be inserted (not including the two residues above)
    * number of candidate fragments to be returned (default=20)
    * secondary structure of the fragment in dot-bracket format (optional).
    """
    model = validate_model(model)
    res5_number = validate_resnum(res5_number)
    res3_number = validate_resnum(res3_number)
    sequence = validate_seq(sequence)
    if secstruc: secstruc = validate_secstruc(secstruc)

    r5 = model[res5_number]
    r3 = model[res3_number]
    return model.find_fragment_candidates(r5,
                                          r3,
                                          sequence,
                                          number_of_candidates,
                                          secstruc=secstruc)
def insert_two_strand_fragment(model, anchor5_id, anchor3_id, anchor5_upper_id, anchor3_upper_id, \
                 frag_anchor5_id,  frag_anchor3_id, frag_anchor5_upper_id, frag_anchor3_upper_id,  fragment_file,  chain_name='A'):
    """*insert_2D_fragment(model, anchor5_id, anchor3_id, anchor5_upper_id, anchor3_upper_id, \
                 frag_anchor5_id,  frag_anchor3_id, frag_anchor5_upper_id, frag_anchor3_upper_id,  fragment_file,  chain_name='A')*

Inserts a given 2D fragment between two pairs of indicated residues.
Requires to indicate connecting residues from both model (4) and fragment (4).

:Arguments:
    * model - RNAModel object
    * anchor5_id - anchor residue in the model on the 5' side of the fragment.
    * anchor3_id - anchor residue in the model on the 3' side of the fragment.
    * anchor5_upper_id - anchor residue in the model on the 5' side of the middle part of the fragment.
    * anchor3_upper_id - anchor residue in the model on the 3' side of the middle part of the fragment.
    * frag_anchor5_id - anchor residue in the fragment on the 5' side of the fragment.
    * frag_anchor3_id - anchor residue in the fragment on the 3' side of the fragment.
    * frag_anchor5_upper_id - anchor residue in the fragment on the 5' side of the middle part of the fragment.
    * frag_anchor3_upper_id - anchor residue in the fragment on the 3' side of the middle part of the fragment.
    * fragment_file - name of the fragment PDB file
    * chain_name - chain ID (default: 'A')
    """
    model = validate_model(model)
    anchor5_id = validate_resnum(anchor5_id)
    anchor3_id = validate_resnum(anchor3_id)
    anchor5_upper_id = validate_resnum(anchor5_upper_id)
    anchor3_upper_id = validate_resnum(anchor3_upper_id)
    frag_anchor5_id = validate_resnum(frag_anchor5_id)
    frag_anchor3_id = validate_resnum(frag_anchor3_id)
    frag_anchor5_upper_id = validate_resnum(frag_anchor5_upper_id)
    frag_anchor3_upper_id = validate_resnum(frag_anchor3_upper_id)
    fragment_file = validate_filename(fragment_file)

    struc = ModernaStructure(data_type='file',
                             data=fragment_file,
                             chain_name=chain_name)
    mf = ModernaFragment2D(struc, \
                anchor5=model[anchor5_id], anchor3=model[anchor3_id], \
                anchor5_upper=model[anchor5_upper_id], \
                anchor3_upper=model[anchor3_upper_id], \
                frag5_upper=struc[frag_anchor5_upper_id], \
                frag3_upper=struc[frag_anchor3_upper_id], \
                model=model)
    model.insert_fragment(mf)
def copy_single_residue(residue, model, new_number=None, strict=True):
    """*copy_single_residue(residue, model, new_number=None, strict=True)*
    
Copies a single residue into the model.
The residue can be taken from a Template, or another RnaModel.

Residues are specified by their PDB residue number in quotes and square brackets, e.g. template['5'].
eventually accompanied by the insertion letter (abbreviated as number).
By default, the number of the residue is kept, but it can be given optionally. 

:Arguments:
    * Residue from a Template or RnaModel
    * RnaModel object
    * new residue number in the model (optional)
    * strict=1 complains when a residue with the given number exists already (default); strict=0 copies anyway
    """
    residue = validate_resi(residue)
    model = validate_model(model)
    if new_number: new_number = validate_resnum(new_number)

    model.copy_residue(residue, new_number, strict=strict)
def remove_modification(residue, model=None, new_number=None):
    """*remove_modification(residue, model=None, new_number=None)*
    
Removes base modifications from a single residue. The nucleotide is
transformed into the standard base from which the modification originated.
A RnaModel can be given optionally. If this is given, the
modified residue is subsequently copied to it.

Note that desoxynucleotides count as modified bases as well.
  
:Arguments:
    * residue from a Template or RnaModel object
    * RnaModel object (optional)
    * new residue number after copying (optional)
    """
    residue = validate_resi(residue)
    if model: model = validate_model(model)
    if new_number: new_number = validate_resnum(new_number)

    if model:
        model.remove_one_modification_copy(residue, new_number)
    else:
        modifications.remove_modification(residue)