Java tutorial
/* * Copyright 2015 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.opencb.cellbase.lib.impl; import com.fasterxml.jackson.databind.ObjectMapper; import com.mongodb.QueryBuilder; import com.mongodb.client.MongoCursor; import com.mongodb.client.model.*; import org.bson.*; import org.bson.conversions.Bson; import org.opencb.biodata.models.core.Region; import org.opencb.cellbase.core.common.IntervalFeatureFrequency; import org.opencb.commons.datastore.core.Query; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.datastore.core.QueryResult; import org.opencb.commons.datastore.mongodb.MongoDBCollection; import org.opencb.commons.datastore.mongodb.MongoDataStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.math.BigInteger; import java.util.*; public class MongoDBAdaptor { enum QueryValueType { INTEGER, STRING } protected String species; protected String assembly; protected MongoDataStore mongoDataStore; protected MongoDBCollection mongoDBCollection; protected Logger logger = LoggerFactory.getLogger(this.getClass()); protected ObjectMapper objectMapper; public MongoDBAdaptor(MongoDataStore mongoDataStore) { this("", "", mongoDataStore); } public MongoDBAdaptor(String species, String assembly, MongoDataStore mongoDataStore) { this.species = species; this.assembly = assembly; this.mongoDataStore = mongoDataStore; logger = LoggerFactory.getLogger(this.getClass().toString()); objectMapper = new ObjectMapper(); initSpeciesAssembly(species, assembly); // jsonObjectMapper = new ObjectMapper(); } private void initSpeciesAssembly(String species, String assembly) { if (species != null && !species.equals("")) { // if 'version' parameter has not been provided the default version is selected if (this.assembly == null || this.assembly.trim().equals("")) { this.assembly = "default"; } } } protected QueryOptions addPrivateExcludeOptions(QueryOptions options) { if (options != null) { if (options.get("exclude") == null) { options.put("exclude", "_id,_chunkIds"); } else { String exclude = options.getString("exclude"); if (exclude.contains("_id,_chunkIds")) { return options; } else { options.put("exclude", exclude + ",_id,_chunkIds"); } } } else { options = new QueryOptions("exclude", "_id,_chunkIds"); } return options; } protected void createRegionQuery(Query query, String queryParam, List<Bson> andBsonList) { if (query != null && query.getString(queryParam) != null && !query.getString(queryParam).isEmpty()) { List<Region> regions = Region.parseRegions(query.getString(queryParam)); if (regions != null && regions.size() > 0) { // if there is only one region we add the AND filter directly to the andBsonList passed if (regions.size() == 1) { Bson chromosome = Filters.eq("chromosome", regions.get(0).getChromosome()); Bson start = Filters.lte("start", regions.get(0).getEnd()); Bson end = Filters.gte("end", regions.get(0).getStart()); andBsonList.add(Filters.and(chromosome, start, end)); } else { // when multiple regions then we create and OR list before add it to andBsonList List<Bson> orRegionBsonList = new ArrayList<>(regions.size()); for (Region region : regions) { Bson chromosome = Filters.eq("chromosome", region.getChromosome()); Bson start = Filters.lte("start", region.getEnd()); Bson end = Filters.gte("end", region.getStart()); orRegionBsonList.add(Filters.and(chromosome, start, end)); } andBsonList.add(Filters.or(orRegionBsonList)); } } else { logger.warn("Region query no created, region object is null or empty."); } } } protected void createRegionQuery(Query query, String queryParam, int chunkSize, List<Bson> andBsonList) { if (chunkSize <= 0) { // if chunkSize is not valid we call to the default method createRegionQuery(query, queryParam, andBsonList); } else { if (query != null && query.getString(queryParam) != null && !query.getString(queryParam).isEmpty()) { List<Region> regions = Region.parseRegions(query.getString(queryParam)); if (regions != null && regions.size() > 0) { if (regions.size() == 1) { Bson chunkQuery = createChunkQuery(regions.get(0), chunkSize); andBsonList.add(chunkQuery); } else { // if multiple regions we add them first to a OR list List<Bson> orRegionBsonList = new ArrayList<>(regions.size()); for (Region region : regions) { Bson chunkQuery = createChunkQuery(region, chunkSize); orRegionBsonList.add(chunkQuery); } andBsonList.add(Filters.or(orRegionBsonList)); } } } } } private Bson createChunkQuery(Region region, int chunkSize) { int startChunkId = getChunkId(region.getStart(), chunkSize); int endChunkId = getChunkId(region.getEnd(), chunkSize); List<String> chunkIds = new ArrayList<>(endChunkId - startChunkId + 1); for (int chunkId = startChunkId; chunkId <= endChunkId; chunkId++) { chunkIds.add(region.getChromosome() + "_" + chunkId + "_" + chunkSize / 1000 + "k"); } Bson chunk = Filters.in("_chunkIds", chunkIds); Bson start = Filters.lte("start", region.getEnd()); Bson end = Filters.gte("end", region.getStart()); return Filters.and(chunk, start, end); // // We only use chunks if region queried belongs to a single chunk // if (startChunkId == endChunkId) { // logger.info("Querying by chunkId, {}, {}", startChunkId, endChunkId); // Bson chunk = Filters.eq("_chunkIds", getChunkIdPrefix(region.getChromosomeInfo(), region.getStart(), chunkSize)); // Bson start = Filters.lte("start", region.getEnd()); // Bson end = Filters.gte("end", region.getStart()); // return Filters.and(chunk, start, end); // } else { // Bson chromosome = Filters.eq("chromosome", region.getChromosomeInfo()); // Bson start = Filters.lte("start", region.getEnd()); // Bson end = Filters.gte("end", region.getStart()); // return Filters.and(chromosome, start, end); // } } protected void createOrQuery(Query query, String queryParam, String mongoDbField, List<Bson> andBsonList) { createOrQuery(query, queryParam, mongoDbField, andBsonList, QueryValueType.STRING); } protected void createOrQuery(Query query, String queryParam, String mongoDbField, List<Bson> andBsonList, QueryValueType queryValueType) { if (query != null && query.getString(queryParam) != null && !query.getString(queryParam).isEmpty()) { switch (queryValueType) { case INTEGER: createOrQuery(query.getAsIntegerList(queryParam), mongoDbField, andBsonList); break; default: createOrQuery(query.getAsStringList(queryParam), mongoDbField, andBsonList); } } } protected <T> void createOrQuery(List<T> queryValues, String mongoDbField, List<Bson> andBsonList) { if (queryValues.size() == 1) { andBsonList.add(Filters.eq(mongoDbField, queryValues.get(0))); } else { List<Bson> orBsonList = new ArrayList<>(queryValues.size()); for (T queryItem : queryValues) { orBsonList.add(Filters.eq(mongoDbField, queryItem)); } andBsonList.add(Filters.or(orBsonList)); } } protected QueryResult groupBy(Bson query, String groupByField, String featureIdField, QueryOptions options) { if (groupByField == null || groupByField.isEmpty()) { return new QueryResult(); } if (groupByField.contains(",")) { // call to multiple groupBy if commas are present return groupBy(query, Arrays.asList(groupByField.split(",")), featureIdField, options); } else { Bson match = Aggregates.match(query); Bson project = Aggregates.project(Projections.include(groupByField, featureIdField)); Bson group; if (options.getBoolean("count", false)) { group = Aggregates.group("$" + groupByField, Accumulators.sum("count", 1)); return mongoDBCollection.aggregate(Arrays.asList(match, project, group), options); } else { // Limit the documents passed if count is false Bson limit = Aggregates.limit(options.getInt("limit", 10)); group = Aggregates.group("$" + groupByField, Accumulators.addToSet("features", "$" + featureIdField)); // TODO change the default "_id" returned by mongodb to id return mongoDBCollection.aggregate(Arrays.asList(match, limit, project, group), options); } } } protected QueryResult groupBy(Bson query, List<String> groupByField, String featureIdField, QueryOptions options) { if (groupByField == null || groupByField.isEmpty()) { return new QueryResult(); } if (groupByField.size() == 1) { // if only one field then we call to simple groupBy return groupBy(query, groupByField.get(0), featureIdField, options); } else { Bson match = Aggregates.match(query); // add all group-by fields to the projection together with the aggregation field name List<String> groupByFields = new ArrayList<>(groupByField); groupByFields.add(featureIdField); Bson project = Aggregates.project(Projections.include(groupByFields)); // _id document creation to have the multiple id Document id = new Document(); for (String s : groupByField) { id.append(s, "$" + s); } Bson group; if (options.getBoolean("count", false)) { group = Aggregates.group(id, Accumulators.sum("count", 1)); return mongoDBCollection.aggregate(Arrays.asList(match, project, group), options); } else { // Limit the documents passed if count is false Bson limit = Aggregates.limit(options.getInt("limit", 10)); group = Aggregates.group(id, Accumulators.addToSet("features", "$" + featureIdField)); // TODO change the default "_id" returned by mongodb to id return mongoDBCollection.aggregate(Arrays.asList(match, limit, project, group), options); } } } public QueryResult getIntervalFrequencies(Bson query, Region region, int intervalSize, QueryOptions options) { // MONGO QUERY TO IMPLEMENT // db.variation.aggregate({$match: {$and: [{chromosome: "1"}, {start: {$gt: 251391, $lt: 2701391}}]}}, {$group: // {_id: {$subtract: [{$divide: ["$start", 40000]}, {$divide: [{$mod: ["$start", 40000]}, 40000]}]}, totalCount: {$sum: 1}}}) // { // $match: { // $and: [{ // chromosome: "1" // }, { // start: { // $gt: 251391, // $lt: 2701391 // } // } // ] // } // }, { // $group: { // _id: { // $subtract: [{ // $divide: ["$start", 40000] // }, { // $divide: [{ // $mod: ["$start", 40000] // }, // 40000 // ] // } // ] // }, // totalCount: { // $sum: 1 // } // } // } int interval = 50000; if (intervalSize > 0) { interval = intervalSize; } Bson match = Aggregates.match(query); // group // Document divide1 = new Document(); // divide1.append("$start", interval); // divide1.add("$start"); // divide1.add(interval); BsonArray divide1 = new BsonArray(); divide1.add(new BsonString("$start")); divide1.add(new BsonInt32(interval)); // Document divide2 = new Document(); // divide2.add(new Document("$mod", divide1)); // divide2.add(interval); BsonArray divide2 = new BsonArray(); divide2.add(new BsonDocument("$mod", divide1)); divide2.add(new BsonInt32(interval)); // Document subtractList = new Document(); // subtractList.append("$divide", divide1); // subtractList.append("$divide", divide2); BsonArray subtractList = new BsonArray(); subtractList.add(new BsonDocument("$divide", divide1)); subtractList.add(new BsonDocument("$divide", divide2)); // subtractList.add(new Document("$divide", divide1)); // subtractList.add(new Document("$divide", divide2)); Document substract = new Document("$subtract", subtractList); Document totalCount = new Document("$sum", 1); Document g = new Document("_id", substract); g.append("features_count", totalCount); Document group = new Document("$group", g); // Bson sort = Sorts.ascending("$_id"); Document sort = new Document("$sort", new Document("_id", 1)); QueryResult<Document> aggregationOutput = mongoDBCollection.aggregate(Arrays.asList(match, group, sort), options); Map<Long, Document> ids = new HashMap<>(); for (Document intervalObj : aggregationOutput.getResult()) { Long id = Math.round((Double) intervalObj.get("_id")); //is double Document intervalVisited = ids.get(id); if (intervalVisited == null) { intervalObj.put("_id", id); intervalObj.put("chromosome", region.getChromosome()); intervalObj.put("start", getChunkStart(id.intValue(), interval)); intervalObj.put("end", getChunkEnd(id.intValue(), interval)); // intervalObj.put("features_count", Math.log((int) intervalObj.get("features_count"))); intervalObj.put("features_count", intervalObj.getInteger("features_count")); ids.put(id, intervalObj); } else { // Double sum = (Double) intervalVisited.get("features_count") + Math.log((int) intervalObj.get("features_count")); int sum = intervalVisited.getInteger("features_count") + intervalObj.getInteger("features_count"); intervalVisited.put("features_count", sum); } } List<Document> resultList = new ArrayList<>(); int firstChunkId = getChunkId(region.getStart(), interval); int lastChunkId = getChunkId(region.getEnd(), interval); Document intervalObj; for (int chunkId = firstChunkId; chunkId <= lastChunkId; chunkId++) { intervalObj = ids.get((long) chunkId); if (intervalObj == null) { intervalObj = new Document(); intervalObj.put("_id", chunkId); intervalObj.put("chromosome", region.getChromosome()); intervalObj.put("start", getChunkStart(chunkId, interval)); intervalObj.put("end", getChunkEnd(chunkId, interval)); intervalObj.put("features_count", 0); } else { intervalObj.put("features_count", Math.log(intervalObj.getInteger("features_count"))); } resultList.add(intervalObj); } QueryResult queryResult = new QueryResult(); queryResult.setResult(resultList); queryResult.setId(region.toString()); queryResult.setResultType("frequencies"); return queryResult; } protected QueryResult executeDistinct(Object id, String fields, Document query) { // long dbTimeStart, dbTimeEnd; // dbTimeStart = System.currentTimeMillis(); QueryResult queryResult = mongoDBCollection.distinct(fields, query); // List<Document> dbObjectList = new LinkedList<>(); // while (cursor.hasNext()) { // dbObjectList.add(cursor.next()); // } // dbTimeEnd = System.currentTimeMillis(); // setting queryResult fields queryResult.setId(id.toString()); // queryResult.setDbTime(Long.valueOf(dbTimeEnd - dbTimeStart).intValue()); // queryResult.setNumResults(dbObjectList.size()); return queryResult; } protected QueryResult executeQuery(Object id, Document query, QueryOptions options) { return executeQueryList2(Arrays.asList(id), Arrays.asList(query), options, mongoDBCollection).get(0); } protected QueryResult executeQuery(Object id, Document query, QueryOptions options, MongoDBCollection mongoDBCollection2) { return executeQueryList2(Arrays.asList(id), Arrays.asList(query), options, mongoDBCollection2).get(0); } protected List<QueryResult> executeQueryList2(List<? extends Object> ids, List<Document> queries, QueryOptions options) { return executeQueryList2(ids, queries, options, mongoDBCollection); } protected List<QueryResult> executeQueryList2(List<? extends Object> ids, List<Document> queries, QueryOptions options, MongoDBCollection mongoDBCollection2) { List<QueryResult> queryResults = new ArrayList<>(ids.size()); long dbTimeStart, dbTimeEnd; for (int i = 0; i < queries.size(); i++) { Document query = queries.get(i); QueryResult queryResult = new QueryResult(); queryResult.setId(ids.get(i).toString()); // Execute query and calculate time dbTimeStart = System.currentTimeMillis(); if (options.containsKey("count") && options.getBoolean("count")) { queryResult = mongoDBCollection2.count(query); } else { MongoCursor<Document> cursor = mongoDBCollection2.nativeQuery().find(query, options).iterator(); List<Document> dbObjectList = new LinkedList<>(); while (cursor.hasNext()) { dbObjectList.add(cursor.next()); } queryResult.setNumResults(dbObjectList.size()); queryResult.setResult(dbObjectList); // Limit is set in queryOptions, count number of total results if (options != null && options.getInt("limit", 0) > 0) { queryResult.setNumTotalResults(mongoDBCollection2.count(query).first()); } else { queryResult.setNumTotalResults(dbObjectList.size()); } } dbTimeEnd = System.currentTimeMillis(); queryResult.setDbTime(Long.valueOf(dbTimeEnd - dbTimeStart).intValue()); queryResults.add(queryResult); } return queryResults; } protected QueryResult executeAggregation2(Object id, List<Bson> pipeline, QueryOptions options) { return executeAggregationist2(Arrays.asList(id), Arrays.asList(pipeline), options, mongoDBCollection) .get(0); } protected List<QueryResult> executeAggregationList2(List<? extends Object> ids, List<List<Bson>> queries, QueryOptions options) { return executeAggregationist2(ids, queries, options, mongoDBCollection); } protected List<QueryResult> executeAggregationist2(List<? extends Object> ids, List<List<Bson>> pipelines, QueryOptions options, MongoDBCollection mongoDBCollection2) { List<QueryResult> queryResults = new ArrayList<>(ids.size()); // logger.info("executeQueryList2"); long dbTimeStart, dbTimeEnd; for (int i = 0; i < pipelines.size(); i++) { List<Bson> pipeline = pipelines.get(i); // QueryResult queryResult = new org.opencb.commons.datastore.core.QueryResult(); // Execute query and calculate time dbTimeStart = System.currentTimeMillis(); QueryResult queryResult = mongoDBCollection2.aggregate(pipeline, options); // List<Document> dbObjectList = new LinkedList<>(); // while (cursor.hasNext()) { // dbObjectList.add(cursor.next()); // } dbTimeEnd = System.currentTimeMillis(); // // setting queryResult fields queryResult.setId(ids.get(i).toString()); queryResult.setDbTime(Long.valueOf(dbTimeEnd - dbTimeStart).intValue()); queryResult.setNumResults(queryResult.getResult().size()); // // Limit is set in queryOptions, count number of total results // if(options != null && options.getInt("limit", 0) > 0) { // queryResult.setNumTotalResults(mongoDBCollection.count(pipeline).first()); // } else { // queryResult.setNumTotalResults(dbObjectList.size()); // } // queryResult.setResult(dbObjectList); queryResults.add(queryResult); } return queryResults; } protected String getChunkIdPrefix(String chromosome, int position, int chunkSize) { return chromosome + "_" + position / chunkSize + "_" + chunkSize / 1000 + "k"; } protected int getChunkId(int position, int chunkSize) { return position / chunkSize; } private int getChunkStart(int id, int chunkSize) { return (id == 0) ? 1 : id * chunkSize; } private int getChunkEnd(int id, int chunkSize) { return (id * chunkSize) + chunkSize - 1; } public QueryResult next(String chromosome, int position, QueryOptions options, MongoDBCollection mongoDBCollection) { QueryBuilder builder; if (options.getString("strand") == null || options.getString("strand").equals("") || (options.getString("strand").equals("1") || options.getString("strand").equals("+"))) { builder = QueryBuilder.start("chromosome").is(chromosome).and("start").greaterThanEquals(position); options.put("sort", new HashMap<String, String>().put("start", "asc")); options.put("limit", 1); } else { builder = QueryBuilder.start("chromosome").is(chromosome).and("end").lessThanEquals(position); options.put("sort", new HashMap<String, String>().put("end", "desc")); options.put("limit", 1); } return executeQuery("result", new Document(builder.get().toMap()), options, mongoDBCollection); } @Deprecated protected QueryOptions addIncludeReturnFields(String returnField, QueryOptions options) { if (options != null) { //&& !options.getBoolean(returnField, true) if (options.getList("include") != null) { // options.put("include", options.get("include") + "," + returnField); options.getList("include").add(returnField); } else { options.put("include", Arrays.asList(returnField)); } } else { options = new QueryOptions("include", Arrays.asList(returnField)); } return options; } @Deprecated protected QueryOptions addExcludeReturnFields(String returnField, QueryOptions options) { if (options != null) { //&& !options.getBoolean(returnField, true)) { if (options.getList("exclude") != null) { // options.put("exclude", options.get("exclude") + "," + returnField); List<Object> arr = options.getList("exclude"); arr.add(returnField); // options.getList("exclude").add(returnField); options.put("exclude", arr); } else { options.put("exclude", Arrays.asList(returnField)); } } else { options = new QueryOptions("exclude", Arrays.asList(returnField)); } return options; } @Deprecated protected Document getReturnFields(QueryOptions options) { // Select which fields are excluded and included in MongoDB query Document returnFields = new Document("_id", 0); if (options != null) { // List<Object> includeList = options.getList("include"); // Read and process 'exclude' field from 'options' object // if (options != null && options.get("include") != null && !options.getString("include").equals("")) { if (options != null && options.getList("include") != null && options.getList("include").size() > 0) { // String[] includedOptionFields = options.getString("include").split(","); // if (includedOptionFields != null && includedOptionFields.length > 0) { // if (options.getList("include") != null && options.getList("include").size() > 0) { for (Object field : options.getList("include")) { // returnFields.put(field, 1); returnFields.put(field.toString(), 1); } } else { // List<Object> excludeList = options.getList("exclude"); // if (options != null && options.get("exclude") != null && !options.getString("exclude").equals("")) { if (options != null && options.getList("exclude") != null && options.getList("exclude").size() > 0) { // String[] excludedOptionFields = options.getString("exclude").split(","); // if (excludedOptionFields != null && excludedOptionFields.length > 0) { for (Object field : options.getList("exclude")) { returnFields.put(field.toString(), 0); } } } } return returnFields; } // @Deprecated // protected BasicDBList executeFind(Document query, Document returnFields, QueryOptions options) { // return executeFind(query, returnFields, options, mongoDBCollection); // } // // @Deprecated // protected BasicDBList executeFind(Document query, Document returnFields, QueryOptions options, DBCollection dbCollection) { // BasicDBList list = new BasicDBList(); // // if (options.getBoolean("count")) { // Long count = dbCollection.count(query); // list.add(new Document("count", count)); // }else { // DBCursor cursor = dbCollection.find(query, returnFields); // // int limit = options.getInt("limit", 0); // if (limit > 0) { // cursor.limit(limit); // } // int skip = options.getInt("skip", 0); // if (skip > 0) { // cursor.skip(skip); // } // // Document sort = (Document) options.get("sort"); // if (sort != null) { // cursor.sort(sort); // } // try { // if (cursor != null) { // while (cursor.hasNext()) { // list.add(cursor.next()); // } // } // } finally { // if (cursor != null) { // cursor.close(); // } // } // } // return list; // } // @Deprecated // protected QueryResult executeDistinct(Object id, String key) { // return executeDistinct(id, key, mongoDBCollection); // } // // @Deprecated // protected QueryResult executeDistinct(Object id, String key, DBCollection dbCollection) { // QueryResult queryResult = new QueryResult(); // long dbTimeStart = System.currentTimeMillis(); // List<String> diseases = dbCollection.distinct(key); // long dbTimeEnd = System.currentTimeMillis(); // queryResult.setId(id.toString()); //// queryResult.setDbTime(dbTimeEnd - dbTimeStart); // queryResult.setResult(diseases); // queryResult.setNumResults(diseases.size()); // // return queryResult; // } // @Deprecated // protected QueryResult executeQuery(Object id, Document query, QueryOptions options) { // return executeQuery(id, query, options, mongoDBCollection); // } // @Deprecated // protected QueryResult executeQuery(Object id, Document query, QueryOptions options, DBCollection dbCollection) { // return executeQueryList(Arrays.asList(id), Arrays.asList(query), options, dbCollection).get(0); // } // // @Deprecated // protected List<QueryResult> executeQueryList(List<? extends Object> ids, List<Document> queries, QueryOptions options) { // return executeQueryList(ids, queries, options, mongoDBCollection); // } // public List<QueryResult> getAllIntervalFrequencies(List<Region> regions, QueryOptions queryOptions) { // List<QueryResult> queryResult = new ArrayList<>(regions.size()); // for (Region region : regions) { // queryResult.add(getIntervalFrequencies(region, queryOptions)); // } // return queryResult; // } /* * For histograms */ protected List<IntervalFeatureFrequency> getIntervalFeatureFrequencies(Region region, int interval, List<Object[]> objectList, int numFeatures, double maxSnpsInterval) { int numIntervals = (region.getEnd() - region.getStart()) / interval + 1; List<IntervalFeatureFrequency> intervalFeatureFrequenciesList = new ArrayList<>(numIntervals); float maxNormValue = 1; if (numFeatures != 0) { maxNormValue = (float) maxSnpsInterval / numFeatures; } int start = region.getStart(); int end = start + interval; for (int i = 0, j = 0; i < numIntervals; i++) { if (j < objectList.size() && ((BigInteger) objectList.get(j)[0]).intValue() == i) { if (numFeatures != 0) { intervalFeatureFrequenciesList.add( new IntervalFeatureFrequency(start, end, ((BigInteger) objectList.get(j)[0]).intValue(), ((BigInteger) objectList.get(j)[1]).intValue(), (float) Math.log(((BigInteger) objectList.get(j)[1]).doubleValue()) / numFeatures / maxNormValue)); } else { // no features for this chromosome intervalFeatureFrequenciesList.add( new IntervalFeatureFrequency(start, end, ((BigInteger) objectList.get(j)[0]).intValue(), ((BigInteger) objectList.get(j)[1]).intValue(), 0)); } j++; } else { intervalFeatureFrequenciesList.add(new IntervalFeatureFrequency(start, end, i, 0, 0.0f)); } start += interval; end += interval; } return intervalFeatureFrequenciesList; } protected List<IntervalFeatureFrequency> getIntervalFeatureFrequencies(Region region, int interval, List<Object[]> objectList) { int numIntervals = (region.getEnd() - region.getStart()) / interval + 1; List<IntervalFeatureFrequency> intervalFeatureFrequenciesList = new ArrayList<IntervalFeatureFrequency>( numIntervals); BigInteger max = new BigInteger("-1"); for (int i = 0; i < objectList.size(); i++) { if (((BigInteger) objectList.get(i)[1]).compareTo(max) > 0) { max = (BigInteger) objectList.get(i)[1]; } } int start = region.getStart(); int end = start + interval; for (int i = 0, j = 0; i < numIntervals; i++) { if (j < objectList.size() && ((BigInteger) objectList.get(j)[0]).intValue() == i) { intervalFeatureFrequenciesList.add( new IntervalFeatureFrequency(start, end, ((BigInteger) objectList.get(j)[0]).intValue(), ((BigInteger) objectList.get(j)[1]).intValue(), ((BigInteger) objectList.get(j)[1]).floatValue() / max.floatValue())); j++; } else { intervalFeatureFrequenciesList.add(new IntervalFeatureFrequency(start, end, i, 0, 0.0f)); } start += interval; end += interval; } return intervalFeatureFrequenciesList; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getAssembly() { return this.assembly; } public void setAssembly(String assembly) { this.assembly = assembly; } }