Work with base-pairs in an object-oriented way
npm install @rnacanvas/base-pairs.oopifiedWith npm:
```
npm install @rnacanvas/base-pairs.oopified
All exports of this package can be accessed as named imports.
`javascript`
// some example imports
import { BasePair, Stem } from '@rnacanvas/base-pairs.oopified';
import { RadializableStructure } from '@rnacanvas/base-pairs.oopified';
A pairing of two nucleobase objects.
`javascript
// two nucleobase objects
var base1 = {};
var base2 = {};
var basePair = new BasePair(base1, base2);
basePair[0]; // the first base
basePair[1]; // the second base
// is iterable
[...basePair];
`
Returns true if the base-pair equals the specified base-pair
(i.e., they both pair the same two bases).
`javascript
var base1 = {};
var base2 = {};
var bp = new BasePair(base1, base2);
bp.equals(new BasePair(base1, base2)); // true
bp.equals(new BasePair(base1, {})); // false
bp.equals(new BasePair({}, base2)); // false
// can also input a base-pair tuple
bp.equals([base1, base2]); // true
bp.equals([base1, {}]); // false
bp.equals([{}, base2]); // false
// order doesn't matter
bp.equals([base2, base1]); // true
`
Returns a new base-pair object that pairs the same two bases (in the same order).
`javascript
var base1 = {};
var base2 = {};
var bp1 = new BasePair(base1, base2);
var bp2 = bp1.duplicate();
bp1[0] === bp2[0]; // true
bp1[1] === bp2[1]; // true
bp1 === bp2; // false
`
Represents the connection between two consecutive stem sides.
Is composed of the last base of the preceding stem side,
the unpaired bases between the two stem sides,
and the first base of the following stem side.
A hairpin loop is an example of a linker.
Between every pair of neighboring stems there is a linker.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
[...linker].length; // 6
// linkers must have at least two bases
new Linker([]); // throws
new Linker([bases[0]]); // throws
`
All bases in the linker.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
[...linker.bases].length; // 6
// is synonymous to iterating over the linker itself
[...linker].length; // 6
`
The number of bases in the linker.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
linker.numBases; // 6
`
The first base in the linker
(i.e., the last base of the preceding stem side).
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
linker.firstBase; // bases[0]
`
The last base in the linker
(i.e., the first base of the following stem side).
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
linker.lastBase; // bases[5]
`
The unpaired bases in the linker
(i.e., all bases between the first and last bases).
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
[...linker.unpairedBases]; // bases.slice(1, 5)
// a linker with no unpaired bases
var linker = new Linker(bases.slice(0, 2));
[...linker.unpairedBases]; // []
`
The number of unpaired bases in the linker.
(Is always two less than the total number of bases in the linker.)
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var linker = new Linker(bases);
linker.numBases; // 6
linker.numUnpairedBases; // 4
// no unpaired bases
var linker = new Linker(bases.slice(0, 2));
linker.numBases; // 2
linker.numUnpairedBases; // 0
`
A structure amenable to radializing layout drawing algorithms.
Repeat base-pairs, conflicting base-pairs, self base-pairs and base-pairs creating pseudoknots
are omitted from the structure at construction.
Pseudoknots are omitted according to the incremental range heuristic (see Smit et al., 2008).
`javascript
// an array of nucleobase objects
var bases = [...'1234567890123456'].map(() => ({}));
// an array of base-pair tuples (creating a stem)
var basePairs = [
[bases[0], bases[9]],
[bases[1], bases[8]],
[bases[2], bases[7]],
];
var structure1 = new RadializableStructure(bases, basePairs);
[...structure1.basePairs].length; // 3
// a repeat base-pair
basePairs.push([bases[0], bases[9]]);
// a conflicting base-pair
// (the first base is already paired with the tenth base)
basePairs.push([bases[0], bases[10]]);
// a self base-pair
basePairs.push([bases[5], bases[5]]);
// a base-pair creating a pseudoknot
basePairs.push([bases[3], bases[11]]);
// will be equal to structure 1
var structure2 = new RadializableStructure(bases, basePairs);
[...structure2.basePairs].length; // 3
`
All bases in the structure.
The ordering of bases in this iterable is the ordering of bases in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
[...structure.bases].length; // 6
`
The number of bases in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.numBases; // 6
`
The number of bases in the structure.
(An alias for the numBases() getter.)
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.length; // 6
`
Returns the base at the zero-based index in the structure.
Throws for out-of-bounds indices.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.atIndex(0); // bases[0]
structure.atIndex(2); // bases[2]
structure.atIndex(5); // bases[5]
structure.atIndex(-1); // throws
structure.atIndex(6); // throws
`
Returns the zero-based index of the specified base
in the sequence of bases for the structure.
Throws if the base is not in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'1234567890'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.indexOf(bases[0]); // 0
structure.indexOf(bases[2]); // 2
structure.indexOf(bases[6]); // 6
structure.indexOf({}); // throws
`
Returns the base at the one-based position in the structure.
Throws for out-of-bounds positions.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.atPosition(1); // bases[0]
structure.atPosition(3); // bases[2]
structure.atPosition(6); // bases[5]
structure.atPosition(0); // throws
structure.atPosition(7); // throws
`
Returns the one-based position of the specified base
in the sequence of bases for the structure.
Throws if the base is not in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'1234567890'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.positionOf(bases[0]); // 1
structure.positionOf(bases[2]); // 3
structure.positionOf(bases[6]); // 7
structure.positionOf({}); // throws
`
The first base in the structure.
Throws for empty structures.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.firstBase; // bases[0]
// an empty structure
var structure = new RadializableStructure([], []);
structure.firstBase; // throws
`
The last base in the structure.
Throws for empty structures.
`javascript
// an array of nucleobase objects
var bases = [...'123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.lastBase; // bases[5]
// an empty structure
var structure = new RadializableStructure([], []);
structure.lastBase; // throws
`
Returns the subsequence defined by a starting base and an ending base, inclusive.
The starting and ending base can be input to this method in either order.
(This method will never return the subsequence in reverse order.)
`javascript
// an array of nucleobase objects
var bases = [...'1234567890'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
[...structure.subsequence(bases[3], bases[7])]; // bases.slice(3, 7 + 1)
[...structure.subsequence(bases[7], bases[3])]; // bases.slice(3, 7 + 1)
`
This method will throw if either the starting base or ending base are not present in the structure.
Returns the subsequence of bases between two bases (not including the two bases themselves).
The two bases can be input to this method in either order.
(This method will never return the intervening bases in reverse order.)
`javascript
// an array of nucleobase objects
var bases = [...'1234567890123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
[...structure.interveningBases(bases[3], bases[9])]; // bases.slice(4, 8 + 1)
[...structure.interveningBases(bases[9], bases[3])]; // bases.slice(4, 8 + 1)
// when there are no intervening bases
[...structure.interveningBases(bases[3], bases[3])]; // []
[...structure.interveningBases(bases[3], bases[4])]; // []
`
This method will throw if either of the two bases input to it are not present in the structure.
All base-pairs in the structure.
(An iterable of base-pair objects.)
`javascript
// an array of nucleobase objects
var bases = [...'123456789'].map(() => ({}));
var basePairs = [
[bases[0], bases[9]],
[bases[1], bases[8]],
[bases[2], bases[7]],
];
var structure = new RadializableStructure(bases, basePairs);
[...structure.basePairs].length; // 3
[...structure.basePairs][0]; // [bases[0], bases[9]]
[...structure.basePairs][1]; // [bases[1], bases[8]]
[...structure.basePairs][2]; // [bases[2], bases[7]]
`
Returns true if the specified base is in a base-pair in the structurefalse
and returns otherwise.
`javascript
// an array of nucleobase objects
var bases = [...'1234567890'].map(() => ({}));
var basePairs = [
[bases[2], bases[9]],
[bases[3], bases[8]],
];
var structure = new RadializableStructure(bases, basePairs);
structure.isPaired(bases[2]); // true
structure.isPaired(bases[8]); // true
structure.isPaired(bases[0]); // false
structure.isPaired(bases[4]); // false
`
Returns true if the specified base is not in a base-pairfalse
and returns otherwise.
`javascript
// an array of nucleobase objects
var bases = [...'1234567890'].map(() => ({}));
var basePairs = [
[bases[2], bases[9]],
[bases[3], bases[8]],
];
var structure = new RadializableStructure(bases, basePairs);
structure.isUnpaired(bases[2]); // false
structure.isUnpaired(bases[8]); // false
structure.isUnpaired(bases[0]); // true
structure.isUnpaired(bases[4]); // true
`
Returns the partner base for the specified base.
Throws if the specified base is unpaired
(or not present in the structure).
`javascript
// an array of nucleobase objects
var bases = [...'1234567890'].map(() => ({}));
var basePairs = [
[bases[2], bases[8]],
[bases[3], bases[7]],
];
var structure = new RadializableStructure(bases, basePairs);
structure.partnerOf(bases[2]); // bases[8]
structure.partnerOf(bases[7]); // bases[3]
// the first base doesn't have a partner
structure.partnerOf(bases[0]); // throws
structure.partnerOf({}); // throws
`
The first paired base in the structure.
Throws if the structure does not have any paired bases.
`javascript
// an array of nucleobase objects
var bases = [...'12345678901234'].map(() => ({}));
var basePairs = [...parseDotBracket(bases, '..(((...)))...')];
var structure = new RadializableStructure(bases, basePairs);
structure.firstPairedBase; // bases[2]
// a structure without any paired bases
var structure = new RadializableStructure(bases, []);
structure.firstPairedBase; // throws
`
The last paired base in the structure.
Throws if the structure does not have any paired bases.
`javascript
// an array of nucleobase objects
var bases = [...'12345678901234'].map(() => ({}));
var basePairs = [...parseDotBracket(bases, '..(((...)))...')];
var structure = new RadializableStructure(bases, basePairs);
structure.lastPairedBase; // bases[10]
// a structure without any paired bases
var structure = new RadializableStructure(bases, []);
structure.lastPairedBase; // throws
`
All stems in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'12345678901234567890'].map(() => ({}));
var basePairs = [];
// stem 1
basePairs.push(
[bases[1], bases[18]],
[bases[2], bases[17]],
[bases[3], bases[16]],
);
// stem 2
basePairs.push(
[bases[5], bases[14]],
[bases[6], bases[13]],
[bases[7], bases[12]],
);
var structure = new RadializableStructure(bases, basePairs);
[...structure.stems].length; // 2
[...structure.stems][0].bottomBasePair[0]; // bases[1]
[...structure.stems][0].bottomBasePair[1]; // bases[18]
[...structure.stems][1].bottomBasePair[0]; // bases[5]
[...structure.stems][1].bottomBasePair[1]; // bases[14]
`
The number of stems in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345678901234567890'].map(() => ({}));
var basePairs = [];
var structure = new RadializableStructure(bases, basePairs);
structure.numStems; // 0
var basePairs = [...parseDotBracket(bases, '..(((....))).((..(((...))).)).')];
var structure = new RadializableStructure(bases, basePairs);
structure.numStems; // 3
`
All linkers in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345678901234'].map(() => ({}));
var basePairs = [...parseDotBracket(bases, '.(((....(((.....))).))).')];
var structure = new RadializableStructure(bases, basePairs);
[...structure.linkers].length; // 3
[...structure.linkers][0].firstBase; // bases[3]
[...structure.linkers][0].lastBase; // bases[8]
[...structure.linkers][1].firstBase; // bases[10]
[...structure.linkers][1].lastBase; // bases[16]
[...structure.linkers][2].firstBase; // bases[18]
[...structure.linkers][2].lastBase; // bases[20]
`
The number of linkers in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345678901234567890'].map(() => ({}));
var basePairs = [];
var structure = new RadializableStructure(bases, basePairs);
structure.numLinkers; // 0
var basePairs = [...parseDotBracket(bases, '..(((....))).((..(((...))).)).')];
var structure = new RadializableStructure(bases, basePairs);
structure.numLinkers; // 5
`
The 5' dangling bases
(i.e., the bases preceding the first paired base in the structure).
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345678'].map(() => ({}));
var basePairs = [...parseDotBracket(bases, '.....(((.....)))..')];
var structure = new RadializableStructure(bases, basePairs);
[...structure.danglingBases5]; // bases.slice(0, 5);
`
`javascript
// no 5' dangling bases
var basePairs = [...parseDotBracket(bases, '(((.....)))...')];
var structure = new RadializableStructure(bases, basePairs);
[...structure.danglingBases5]; // []
`
`javascript
// a structure with no base-pairs
var structure = new RadializableStructure(bases, []);
[...structure.danglingBases5]; // []
`
The 3' dangling bases
(i.e., the bases following the last paired base in the structure).
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345678'].map(() => ({}));
var basePairs = [...parseDotBracket(bases, '...(((.....)))....')];
var structure = new RadializableStructure(bases, basePairs);
[...structure.danglingBases3]; // bases.slice(14, 18);
`
`javascript
// no 3' dangling bases
var basePairs = [...parseDotBracket(bases, '....((((......))))')];
var structure = new RadializableStructure(bases, basePairs);
[...structure.danglingBases3]; // []
`
`javascript
// a structure with no base-pairs
var structure = new RadializableStructure(bases, []);
[...structure.danglingBases3]; // []
`
Returns an object representing the outermost loop of the structure,
which is the loop containing the 5' and 3' termini of the structure.
`javascript
// an array of nucleobase objects
var bases = (new Array(36)).fill().map(() => ({}));
var basePairs = [...parseDotBracket(bases, '..(((....)))..(((...((....))..)))...')];
var structure = new RadializableStructure(bases, basePairs);
var outermostLoop = structure.outermostLoop;
// all bases in the outermost loop
[...outermostLoop.bases]; // [...bases.slice(0, 3), ...bases.slice(11, 15), ...bases.slice(32, 36)]
// all stems in the outermost loop
[...outermostLoop.stems].length; // 2
[...[...outerostLoop.stems][0].bottomBasePair]; // [bases[2], bases[11]]
[...[...outerostLoop.stems][1].bottomBasePair]; // [bases[14], bases[32]]
// all stems emanating from the outermost loop
// (an alias for all stems in the outermost loop)
[...outermostLoop.emanatingStems].length; // 2
// all linkers in the outermost loop
[...outermostLoop.linkers].length; // 1
[...[...outermostLoop.linkers][0].bases]; // bases.slice(11, 15)
// 5' dangling bases
[...outermostLoop.danglingBases5]; // bases.slice(0, 2)
// 3' dangling bases
[...outermostLoop.danglingBases3]; // bases.slice(33, 36)
// always returns false
// (the outermost loop can never be a hairpin loop)
outermostLoop.isHairpinLoop(); // false
`
All loops in the structure that are closed by a stem.
`javascript
// an array of nucleobase objects
var bases = (new Array(46)).fill().map(() => ({}));
var basePairs = [...parseDotBracket(bases, '...((((....(((.....)))...((((......))))..)))).')];
var structure = new RadializableStructure(bases, basePairs);
var closedLoops = [...structure.closedLoops];
closedLoops.length; // 3
[...closedLoops[0].bases]; // [...bases.slice(6, 12), ...bases.slice(21, 26), ...bases.slice(38, 42)]
[...closedLoops[1].bases]; // bases.slice(13, 20)
[...closedLoops[2].bases]; // bases.slice(28, 36)
[...closedLoops[0].closingStem.topBasePair]; // [bases[6], bases[41]]
[...closedLoops[1].closingStem.topBasePair]; // [bases[13], bases[19]]
[...closedLoops[2].closingStem.topBasePair]; // [bases[28], bases[35]]
[...closedLoops[0].closingBasePair]; // [bases[6], bases[41]]
[...closedLoops[1].closingBasePair]; // [bases[13], bases[19]]
[...closedLoops[2].closingBasePair]; // [bases[28], bases[35]]
[...closedLoops[0].emanatingStems].length; // 2
[...[...closedLoops[0].emanatingStems][0].bottomBasePair]; // [bases[11], bases[21]]
[...[...closedLoops[0].emanatingStems][1].bottomBasePair]; // [bases[25], bases[38]]
[...closedLoops[1].emanatingStems].length; // 0
[...closedLoops[2].emanatingStems].length; // 0
[...closedLoops[0].linkers].length; // 3
[...[...closedLoops[0].linkers][0].bases]; // bases.slice(6, 12)
[...[...closedLoops[0].linkers][1].bases]; // bases.slice(21, 26)
[...[...closedLoops[0].linkers][2].bases]; // bases.slice(38, 42)
[...closedLoops[1].linkers].length; // 1
[...closedLoops[2].linkers].length; // 1
[...[...closedLoops[1].linkers][0].bases]; // bases.slice(13, 20)
[...[...closedLoops[2].linkers][0].bases]; // bases.slice(28, 36)
closedLoops[0].isHairpinLoops(); // false
closedLoops[1].isHairpinLoops(); // true
closedLoops[2].isHairpinLoops(); // true
`
All loops in the structure
(i.e., the outermost loop plus all closed loops).
`javascript
// an array of nucleobase objects
var bases = (new Array(39)).fill().map(() => ({}));
var basePairs = [...parseDotBracket(bases, '...(((((.....)))))..((...(((....))).)).')];
var structure = new RadializableStructure(bases, basePairs);
[...structure.loops]; // [structure.outermostLoop, ...structure.closedLoops]
[...structure.loops].length; // 4
`
Returns the subsequence between the two bases of a base-pair
(not including the two bases of the base-pair).
The two bases of the input base-pair can be ordered either way within the base-pair.
(This method will never return the spanned bases in reverse order.)
`javascript
// an array of nucleobase objects
var bases = [...'1234567890123456'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
[...structure.spannedBases([bases[3], bases[11]])]; // bases.slice(4, 10 + 1)
[...structure.spannedBases([bases[11], bases[3]])]; // bases.slice(4, 10 + 1)
// zero spanned bases
[...structure.spannedBases([bases[3], bases[3]])]; // []
[...structure.spannedBases([bases[3], bases[4]])]; // []
`
This method will throw if either base of the input base-pair is not present in the structure.
Note that it is allowed for the input base-pair to not be present in the structure,
so long as its two bases are present in the structure.
Returns the number of bases spanned by the specified base-pair
(not including the bases in the base-pair).
`javascript
// an array of nucleobase objects
var bases = (new Array(10)).fill().map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.numSpannedBases([bases[2], bases[7]]); // 4
structure.numSpannedBases([bases[2], bases[3]]); // 0
structure.numSpannedBases([bases[2], bases[2]]); // 0
`
Returns the sequence of bases joined by a base-pair
(including the two bases in the base-pair).
The ordering of the two bases within the input base-pair doesn't matter.
(This method will never return the joined bases in reverse order.)
`javascript
// an array of nucleobase objects
var bases = [...'12345678901234567890'].map(() => ({}));
var structure = new RadializableStructure(bases, []);
[...structure.joinedBases([bases[5], bases[10]])]; // [...bases.slice(0, 5 + 1), ...bases.slice(10)]
[...structure.joinedBases([bases[10], bases[5]])]; // [...bases.slice(0, 5 + 1), ...bases.slice(10)]
// neighboring bases
[...structure.joinedBases([bases[5], bases[6]])]; // [...bases]
// a self-pair
[...structure.joinedBases([bases[5], bases[5]])]; // [...bases]
`
This method will throw if either base in the input base-pair is not present in the structure.
Returns the number of bases joined by the specified base-pair,
including the bases in the base-pair.
`javascript
// an array of nucleobase objects
var bases = (new Array(10)).fill().map(() => ({}));
var structure = new RadializableStructure(bases, []);
structure.numJoinedBases([bases[2], bases[7]]); // 6
structure.numJoinedBases([bases[0], bases[7]]); // 4
structure.numJoinedBases([bases[0], bases[9]]); // 2
`
Returns the substructure defined by a starting base and an ending base, inclusive.
Only base-pairs involving bases exclusively within the substructure are included.
The starting and ending bases can be input to this method in either order.
(This method will never return the substructure in reverse order.)
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345678901234'].map(() => ({}));
var basePairs = [];
// an outer stem
basePairs.push(
[bases[1], bases[21]],
[bases[2], bases[20]],
[bases[3], bases[19]],
);
// an inner stem
basePairs.push(
[bases[6], bases[16]],
[bases[7], bases[15]],
[bases[8], bases[14]],
);
var structure = new RadializableStructure(bases, basePairs);
var substructure = structure.substructure(bases[5], bases[17]);
[...substructure.bases]; // bases.slice(5, 17 + 1)
[...substructure.basePairs].length; // 3
[...[...substructure.basePairs][0]]; // [bases[6], bases[16]]
[...[...substructure.basePairs][1]]; // [bases[7], bases[15]]
[...[...substructure.basePairs][2]]; // [bases[8], bases[14]]
`
This method will throw if either the starting base or the ending base are not present in the structure.
Returns the mountain plot height for a given base
in the mountain plot traversal of the structure.
Throws if the given base is not in the structure.
`javascript
// an array of nucleobase objects
var bases = [...'123456789012345'].map(() => ({}));
bases.length; // 15
var basePairs = [
[bases[2], bases[11]],
[bases[3], bases[10]],
[bases[4], bases[9]],
];
var structure = new RadializableStructure(bases, basePairs);
structure.mountainPlotHeight(bases[0]); // 0
structure.mountainPlotHeight(bases[1]); // 0
structure.mountainPlotHeight(bases[2]); // 0
structure.mountainPlotHeight(bases[3]); // 1
structure.mountainPlotHeight(bases[4]); // 2
structure.mountainPlotHeight(bases[5]); // 3
structure.mountainPlotHeight(bases[6]); // 3
structure.mountainPlotHeight(bases[7]); // 3
structure.mountainPlotHeight(bases[8]); // 3
structure.mountainPlotHeight(bases[9]); // 2
structure.mountainPlotHeight(bases[10]); // 1
structure.mountainPlotHeight(bases[11]); // 0
structure.mountainPlotHeight(bases[12]); // 0
structure.mountainPlotHeight(bases[13]); // 0
structure.mountainPlotHeight(bases[14]); // 0
``