Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
GenDB3
lib.intervals
Commits
6dd91a94
Commit
6dd91a94
authored
Jun 14, 2013
by
Lukas Jelonek
Browse files
Added union, intersect complement and shift operations for Intervals.
parent
5a86a9ca
Changes
12
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
6dd91a94
...
...
@@ -4,7 +4,7 @@
<groupId>
de.cebitec.common
</groupId>
<artifactId>
intervals
</artifactId>
<version>
0.
3
.0
</version>
<version>
0.
4
.0
</version>
<packaging>
bundle
</packaging>
<name>
Intervals library
</name>
...
...
src/main/java/de/cebitec/common/sequencetools/intervals/IntegerIntervalOperations.java
0 → 100644
View file @
6dd91a94
/*
* Copyright (C) 2013 Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
de.cebitec.common.sequencetools.intervals
;
/**
*
* @author Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*/
public
class
IntegerIntervalOperations
implements
IntervalOperations
<
Integer
>
{
@Override
public
boolean
overlap
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
)
{
// normalize
fst
=
fst
.
as
(
Interval
.
Type
.
ZeroOpen
);
snd
=
snd
.
as
(
Interval
.
Type
.
ZeroOpen
);
if
(
fst
.
getStart
()
>
snd
.
getStart
())
{
Interval
<
Integer
>
tmp
=
fst
;
fst
=
snd
;
snd
=
tmp
;
}
return
!(
fst
.
getEnd
()
-
1
<
snd
.
getStart
());
}
@Override
public
boolean
adjacent
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
)
{
// normalize
fst
=
fst
.
as
(
Interval
.
Type
.
ZeroOpen
);
snd
=
snd
.
as
(
Interval
.
Type
.
ZeroOpen
);
// sort by start
if
(
fst
.
getStart
()
>
snd
.
getStart
())
{
Interval
<
Integer
>
tmp
=
fst
;
fst
=
snd
;
snd
=
tmp
;
}
return
fst
.
getEnd
()
==
snd
.
getStart
();
}
@Override
public
boolean
overlapOrAdjacent
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
)
{
return
overlap
(
fst
,
snd
)
||
adjacent
(
fst
,
snd
);
}
@Override
public
Interval
<
Integer
>
union
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
)
{
if
(!
overlapOrAdjacent
(
fst
,
snd
))
{
throw
new
IllegalArgumentException
(
"Can't union non overlapping intervals. "
+
fst
+
"; "
+
snd
);
}
// normalize
fst
=
fst
.
as
(
Interval
.
Type
.
OneClosed
);
snd
=
snd
.
as
(
Interval
.
Type
.
OneClosed
);
// sort by start
if
(
fst
.
getStart
()
>
snd
.
getStart
())
{
Interval
<
Integer
>
tmp
=
fst
;
fst
=
snd
;
snd
=
tmp
;
}
int
nstart
=
fst
.
getStart
();
int
nend
=
fst
.
getEnd
()
>
snd
.
getEnd
()
?
fst
.
getEnd
()
:
snd
.
getEnd
();
return
Intervals
.
createInterval
(
nstart
,
nend
,
Interval
.
Type
.
OneClosed
);
}
@Override
public
Interval
<
Integer
>
intersection
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
)
{
if
(!
overlap
(
fst
,
snd
))
{
return
Intervals
.
EMPTY
;
}
// normalize
fst
=
fst
.
as
(
Interval
.
Type
.
OneClosed
);
snd
=
snd
.
as
(
Interval
.
Type
.
OneClosed
);
// sort by start
if
(
fst
.
getStart
()
>
snd
.
getStart
())
{
Interval
<
Integer
>
tmp
=
fst
;
fst
=
snd
;
snd
=
tmp
;
}
int
nstart
=
snd
.
getStart
()
>
fst
.
getStart
()
?
snd
.
getStart
()
:
fst
.
getStart
();
int
nend
=
fst
.
getEnd
()
<
snd
.
getEnd
()
?
fst
.
getEnd
()
:
snd
.
getEnd
();
return
Intervals
.
createInterval
(
nstart
,
nend
,
Interval
.
Type
.
OneClosed
);
}
@Override
public
Interval
<
Integer
>
complement
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
)
{
if
(!
overlap
(
fst
,
snd
))
{
return
fst
;
}
if
(
fst
.
equals
(
snd
))
{
return
Intervals
.
EMPTY
;
}
// normalize
fst
=
fst
.
as
(
Interval
.
Type
.
OneClosed
);
snd
=
snd
.
as
(
Interval
.
Type
.
OneClosed
);
return
Intervals
.
createInterval
(
fst
.
getStart
(),
snd
.
getStart
()
-
1
,
Interval
.
Type
.
OneClosed
);
}
@Override
public
Interval
<
Integer
>
shift
(
Interval
<
Integer
>
i
,
Integer
by
)
{
Interval
<
Integer
>
as
=
i
.
as
(
Interval
.
Type
.
ZeroOpen
);
return
Intervals
.
createInterval
(
as
.
getStart
()
+
by
,
as
.
getEnd
()
+
by
);
}
}
src/main/java/de/cebitec/common/sequencetools/intervals/Interval.java
View file @
6dd91a94
...
...
@@ -17,10 +17,11 @@
package
de.cebitec.common.sequencetools.intervals
;
/**
* An Interval describes a part on an indexed region by a start and a end coordinate.
* An interval has a type that determines the start position and whether the end position is
* included or excluded from the interval. To instantiate intervals and interact with them use
* the methods in the Intervals class.
* An Interval describes a part on an indexed region by a start and a end
* coordinate. An interval has a type that determines the start position and
* whether the end position is included or excluded from the interval. To
* instantiate intervals and interact with them use the methods in the Intervals
* class.
*
* @see Intervals
*
...
...
@@ -31,29 +32,33 @@ public interface Interval<T extends Number> {
public
enum
Type
{
/**
* The first position is 1 and the last position n is in the interval, e.g. [1..n]. This is
* a common case in biological data. Needs a lot of +1-1 juggling, so it should be avoided
* for calculations. But it is desired for presentation.
* The first position is 1 and the last position n is in the interval,
* e.g. [1..n]. This is a common case in biological data. Needs a lot of
* +1-1 juggling, so it should be avoided for calculations. But it is
* desired for presentation.
*/
OneClosed
,
/**
* The first position is 0 and the last position n is not included in the interval, e.g.
* [0..n). Intervals are converted to this coordinate system by default.
* The first position is 0 and the last position n is not included in
* the interval, e.g. [0..n). Intervals are converted to this coordinate
* system by default.
*/
ZeroOpen
,
/**
* The first position is 1 and the last position n is not included in
the interval, e.g.
* [1..n).
* The first position is 1 and the last position n is not included in
*
the interval, e.g.
[1..n).
*/
OneOpen
,
/**
* The first position is 0 and the last position n is included in the interval, e.g. [1..n]
* The first position is 0 and the last position n is included in the
* interval, e.g. [1..n]
*/
ZeroClosed
}
/**
* The type of the interval.
*
* @return
*/
Type
getType
();
...
...
@@ -79,8 +84,16 @@ public interface Interval<T extends Number> {
*/
T
getEnd
();
/**
* Equivalent to getLength() == 0.
*
* @return true if this interval has zero length, false otherwise.
*/
boolean
isEmpty
();
/**
* Transforms the interval to the given type.
*
* @param newType
* @return The transformed interval.
*/
...
...
src/main/java/de/cebitec/common/sequencetools/intervals/IntervalOperations.java
0 → 100644
View file @
6dd91a94
/*
* Copyright (C) 2013 Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
de.cebitec.common.sequencetools.intervals
;
/**
*
* @author Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*/
public
interface
IntervalOperations
<
L
extends
Number
>
{
public
boolean
overlap
(
Interval
<
L
>
fst
,
Interval
<
L
>
snd
);
public
boolean
adjacent
(
Interval
<
L
>
fst
,
Interval
<
L
>
snd
);
public
boolean
overlapOrAdjacent
(
Interval
<
L
>
fst
,
Interval
<
L
>
snd
);
/**
* Shifts an interval by a given length, e.g. [2,3] shift by -2 results in [0,1].
*
* @param i
* @param by
* @return
*/
public
Interval
<
L
>
shift
(
Interval
<
L
>
i
,
L
by
);
/* ********* Operations on overlapping or adjacent intervals ************ */
public
Interval
<
L
>
union
(
Interval
<
L
>
fst
,
Interval
<
L
>
snd
);
public
Interval
<
L
>
intersection
(
Interval
<
L
>
fst
,
Interval
<
L
>
snd
);
public
Interval
<
L
>
complement
(
Interval
<
L
>
fst
,
Interval
<
L
>
snd
);
}
src/main/java/de/cebitec/common/sequencetools/intervals/Intervals.java
View file @
6dd91a94
...
...
@@ -100,12 +100,25 @@ public class Intervals {
}
}
@Override
public
boolean
isEmpty
()
{
return
getLength
()
==
0
;
}
@Override
public
Interval
<
java
.
lang
.
Integer
>
as
(
Type
newType
)
{
return
Intervals
.
transfromInterval
(
this
,
newType
);
}
}
}
public
static
final
Interval
<
Integer
>
EMPTY
=
emptyInterval
();
public
static
Interval
<
Integer
>
emptyInterval
()
{
if
(
EMPTY
==
null
)
{
return
createInterval
(
0
,
0
);
}
return
EMPTY
;
}
/**
* Creates an interval for the coordinates given in zeroOpen coordinates.
...
...
@@ -119,8 +132,9 @@ public class Intervals {
}
/**
* Creates an interval ranging from start to end in zeroOpen coordinates. If type is not
* ZeroOpen the start and end positions of the interval will be transformed to be ZeroOpen.
* Creates an interval ranging from start to end in zeroOpen coordinates. If
* type is not ZeroOpen the start and end positions of the interval will be
* transformed to be ZeroOpen.
*
* @param start The start of the interval.
* @param end The end of the interval.
...
...
@@ -128,6 +142,9 @@ public class Intervals {
* @return An interval in ZeroOpen coordinates.
*/
public
static
Interval
<
Integer
>
createInterval
(
int
start
,
int
end
,
Type
type
)
{
// if (start > end) {
// throw new IllegalArgumentException("Start must be lower than end.");
// }
return
new
IntervalImpl
.
Integer
(
Type
.
ZeroOpen
,
normalizeStart
(
start
,
type
),
normalizeEnd
(
end
,
type
));
}
...
...
@@ -165,7 +182,8 @@ public class Intervals {
}
/**
* Corrects the start depending on the type so that it can be used with a java String.
* Corrects the start depending on the type so that it can be used with a
* java String.
*
* @param start
* @param t
...
...
@@ -183,7 +201,8 @@ public class Intervals {
}
/**
* Corrects the end depending on the type so that it can be used with a java String.
* Corrects the end depending on the type so that it can be used with a java
* String.
*
* @param end an end position
* @param t the source type
...
...
@@ -238,6 +257,7 @@ public class Intervals {
/**
* Sums up the total length of a list of intervals.
*
* @param totalLength
* @return
*/
...
...
@@ -259,6 +279,4 @@ public class Intervals {
return
o1
.
getStart
().
compareTo
(
o2
.
getStart
());
}
}
}
src/test/java/de/cebitec/common/sequencetools/intervals/IntegerIntervaComplementOperationTest.java
0 → 100644
View file @
6dd91a94
/*
* Copyright (C) 2013 Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
de.cebitec.common.sequencetools.intervals
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
hamcrest
.
Matchers
.*;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
/**
*
* @author Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*/
@RunWith
(
Parameterized
.
class
)
public
class
IntegerIntervaComplementOperationTest
{
private
IntegerIntervalOperations
ops
=
new
IntegerIntervalOperations
();
private
Interval
<
Integer
>
fst
;
private
Interval
<
Integer
>
snd
;
private
Interval
<
Integer
>
result
;
@Parameterized
.
Parameters
public
static
Collection
<
Object
[]>
data
()
{
return
Arrays
.
asList
(
new
Object
[][]{
// ZeroOpen intervals
{
Intervals
.
createInterval
(
0
,
2
),
Intervals
.
createInterval
(
0
,
2
),
Intervals
.
EMPTY
},
{
Intervals
.
createInterval
(
0
,
2
),
Intervals
.
createInterval
(
2
,
3
),
Intervals
.
createInterval
(
0
,
2
)},
{
Intervals
.
createInterval
(
0
,
3
),
Intervals
.
createInterval
(
2
,
3
),
Intervals
.
createInterval
(
0
,
2
)},
// OneClosed intervals
{
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
),
Intervals
.
EMPTY
},
{
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
)
},
{
Intervals
.
createInterval
(
0
,
2
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
)
}
});
}
public
IntegerIntervaComplementOperationTest
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
,
Interval
<
Integer
>
result
)
{
this
.
fst
=
fst
;
this
.
snd
=
snd
;
this
.
result
=
result
;
}
@Test
public
void
testComplement
()
{
assertThat
(
ops
.
complement
(
fst
,
snd
),
is
(
result
));
}
}
\ No newline at end of file
src/test/java/de/cebitec/common/sequencetools/intervals/IntegerIntervalCompareOperationsTest.java
0 → 100644
View file @
6dd91a94
/*
* Copyright (C) 2013 Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
de.cebitec.common.sequencetools.intervals
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
hamcrest
.
Matchers
.*;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
/**
*
* @author Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*/
@RunWith
(
Parameterized
.
class
)
public
class
IntegerIntervalCompareOperationsTest
{
private
IntegerIntervalOperations
ops
=
new
IntegerIntervalOperations
();
private
Interval
<
Integer
>
fst
;
private
Interval
<
Integer
>
snd
;
private
boolean
adjacent
;
private
boolean
overlap
;
@Parameterized
.
Parameters
public
static
Collection
<
Object
[]>
data
()
{
return
Arrays
.
asList
(
new
Object
[][]{
// ZeroOpen intervals
{
Intervals
.
createInterval
(
0
,
1
),
Intervals
.
createInterval
(
2
,
3
),
false
,
false
},
{
Intervals
.
createInterval
(
0
,
2
),
Intervals
.
createInterval
(
2
,
3
),
true
,
false
},
{
Intervals
.
createInterval
(
0
,
3
),
Intervals
.
createInterval
(
2
,
3
),
false
,
true
},
// OneClosed intervals
{
Intervals
.
createInterval
(
0
,
0
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
false
,
false
},
{
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
true
,
false
},
{
Intervals
.
createInterval
(
0
,
2
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
false
,
true
}
});
}
public
IntegerIntervalCompareOperationsTest
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
,
boolean
adjacent
,
boolean
overlap
)
{
this
.
fst
=
fst
;
this
.
snd
=
snd
;
this
.
adjacent
=
adjacent
;
this
.
overlap
=
overlap
;
}
@Test
public
void
testOverlap
()
{
assertThat
(
ops
.
overlap
(
fst
,
snd
),
is
(
overlap
));
}
@Test
public
void
testAdjacent
()
{
assertThat
(
ops
.
adjacent
(
fst
,
snd
),
is
(
adjacent
));
}
@Test
public
void
testAdjacentOrOverlap
()
{
assertThat
(
ops
.
overlapOrAdjacent
(
fst
,
snd
),
is
(
adjacent
||
overlap
));
}
}
\ No newline at end of file
src/test/java/de/cebitec/common/sequencetools/intervals/IntegerIntervalIntersectionOperationTest.java
0 → 100644
View file @
6dd91a94
/*
* Copyright (C) 2013 Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
de.cebitec.common.sequencetools.intervals
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
hamcrest
.
Matchers
.*;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
/**
*
* @author Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*/
@RunWith
(
Parameterized
.
class
)
public
class
IntegerIntervalIntersectionOperationTest
{
private
IntegerIntervalOperations
ops
=
new
IntegerIntervalOperations
();
private
Interval
<
Integer
>
fst
;
private
Interval
<
Integer
>
snd
;
private
Interval
<
Integer
>
result
;
@Parameterized
.
Parameters
public
static
Collection
<
Object
[]>
data
()
{
return
Arrays
.
asList
(
new
Object
[][]{
// ZeroOpen intervals
{
Intervals
.
createInterval
(
0
,
2
),
Intervals
.
createInterval
(
2
,
3
),
Intervals
.
EMPTY
},
{
Intervals
.
createInterval
(
0
,
3
),
Intervals
.
createInterval
(
2
,
3
),
Intervals
.
createInterval
(
2
,
3
)},
// OneClosed intervals
{
Intervals
.
createInterval
(
0
,
1
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
Intervals
.
EMPTY
},
{
Intervals
.
createInterval
(
0
,
2
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
3
,
Interval
.
Type
.
OneClosed
),
Intervals
.
createInterval
(
2
,
2
,
Interval
.
Type
.
OneClosed
)
}
});
}
public
IntegerIntervalIntersectionOperationTest
(
Interval
<
Integer
>
fst
,
Interval
<
Integer
>
snd
,
Interval
<
Integer
>
result
)
{
this
.
fst
=
fst
;
this
.
snd
=
snd
;
this
.
result
=
result
;
}
@Test
public
void
testIntersect
()
{
assertThat
(
ops
.
intersection
(
fst
,
snd
),
is
(
result
));
}
}
\ No newline at end of file
src/test/java/de/cebitec/common/sequencetools/intervals/IntegerIntervalOperationsTest.java
0 → 100644
View file @
6dd91a94
/*
* Copyright (C) 2013 Lukas Jelonek <ljelonek at cebitec.uni-bielefeld.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.