package de.uni_luebeck.inb.krabbenhoeft.eQTL.server; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.hibernate.Session; import org.hibernate.Transaction; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.CalculationInProgressException; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.DataRetrieval; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.DataSetLayerOverview; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.DataSetOverview; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.ExpressionQtlTrackEntry; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.ExpressionQtlTrackEntry2D; import de.uni_luebeck.inb.krabbenhoeft.eQTL.api.gwt.GenomeRange; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.ColumnForDataSetLayer; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.DataSet; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.DataSetLayer; import de.uni_luebeck.inb.krabbenhoeft.eQTL.entities.HajoEntity; import de.uni_luebeck.inb.krabbenhoeft.eQTL.server.helpers.persistence.CassandraSession; import de.uni_luebeck.inb.krabbenhoeft.eQTL.server.helpers.persistence.GeoBoxHelper; import de.uni_luebeck.inb.krabbenhoeft.eQTL.server.helpers.persistence.RunWithHibernate; import de.uni_luebeck.inb.krabbenhoeft.eQTL.server.helpers.persistence.StreamingEntityRead; public class DataRetrievalService extends RemoteServiceServlet implements DataRetrieval { private static final long serialVersionUID = 1L; public Map<Integer, String> enumerateDataSets() { return new RunWithHibernate<Map<Integer, String>>() { public Map<Integer, String> work(Transaction transaction, Session session) throws Exception { final List<DataSet> dataSets = DataSetHelpers.listMyDataSets(session, getCurrentUser()); Map<Integer, String> map = new HashMap<Integer, String>(); for (DataSet dataSet : dataSets) { map.put(dataSet.getKey(), dataSet.getName() + SimpleDateFormat.getDateTimeInstance().format(dataSet.getDateCreated())); } return map; } }.run(); } public DataSetOverview getOverview(final Integer dataSetKey) { return new RunWithHibernate<DataSetOverview>() { public DataSetOverview work(Transaction transaction, Session session) throws Exception { DataSet dataSet = (DataSet) session.load(DataSet.class, dataSetKey); DataSetOverview overview = new DataSetOverview(); overview.dateCreated = dataSet.getDateCreated(); overview.key = dataSet.getKey(); final List<DataSetLayer> layers = dataSet.getLayers(); overview.layers = new DataSetLayerOverview[layers.size()]; for (int i = 0; i < layers.size(); i++) { overview.layers[i] = DataSetHelpers.generateOverviewForDataSetLayer(dataSetKey, layers.get(i)); } overview.name = dataSet.getName(); return overview; } }.run(); } public String[][] getLayerRows(final Integer dataSetLayerKey, final int offset, final int numberOfItems) { return new ClientRowsFromIterator(dataSetLayerKey) { public Iterator<HajoEntity> prepareIterator(StreamingEntityRead read) { return read.getEntitiesFromSearchIndex("lodScore", false, offset, numberOfItems); } }.run(); } public DataSetLayerOverview getLayerAfterCalculationCompletes(final Integer dataSetKey, final Integer dataSetLayerKey) { final DataSetLayerOverview dataSetLayerOverview = new RunWithHibernate<DataSetLayerOverview>() { public DataSetLayerOverview work(Transaction transaction, Session session) throws Exception { DataSetLayer dataSetLayer = (DataSetLayer) session.load(DataSetLayer.class, dataSetLayerKey); if (!dataSetLayer.isCalculationComplete()) return null; return DataSetHelpers.generateOverviewForDataSetLayer(dataSetKey, dataSetLayer); } }.run(); if (dataSetLayerOverview == null) throw new CalculationInProgressException(); return dataSetLayerOverview; } public String[][] getTopRowsForRange(Integer dataSetLayerKey, final String locationColumnName, final GenomeRange tableRange) { return new ClientRowsFromIterator(dataSetLayerKey) { public Iterator<HajoEntity> prepareIterator(StreamingEntityRead read) { return read.getEntitiesFromGeoboxRange(locationColumnName, tableRange.chromosome, tableRange.fromBP, tableRange.toBP); } }.run(); } public ExpressionQtlTrackEntry[] getTopEntriesForRange(final Integer dataSetLayerKey, final String locationColumnName, final GenomeRange genomeRange) { return new RunWithHibernate<ExpressionQtlTrackEntry[]>() { public ExpressionQtlTrackEntry[] work(Transaction transaction, Session session) throws Exception { DataSetLayer dsl = (DataSetLayer) session.load(DataSetLayer.class, dataSetLayerKey); ColumnForDataSetLayer[] columns = dsl.getColumns().toArray(new ColumnForDataSetLayer[0]); ColumnForDataSetLayer lodColumn = null; ColumnForDataSetLayer locationColumn = null; for (ColumnForDataSetLayer col : columns) { if (col.getName().equals("lodScore")) lodColumn = col; if (col.getName().equals(locationColumnName)) locationColumn = col; } CassandraSession cassandra = new CassandraSession(); StreamingEntityRead read = new StreamingEntityRead(cassandra, dsl); final List<ExpressionQtlTrackEntry> output = new ArrayList<ExpressionQtlTrackEntry>(); final Iterator<HajoEntity> reader = read.getEntitiesFromGeoboxRange(locationColumnName, genomeRange.chromosome, genomeRange.fromBP, genomeRange.toBP); while (reader.hasNext()) { final HajoEntity entity = reader.next(); final ExpressionQtlTrackEntry addme = new ExpressionQtlTrackEntry(); addme.locusId = entity.getName("locusId"); addme.traitId = entity.getName("traitId"); addme.lodScore = entity.getNumerical("lodScore"); addme.lodScoreInMinMaxRange = (addme.lodScore - lodColumn.getMin()) / (lodColumn.getMax() - lodColumn.getMin()); addme.positionStart = entity.getLocation(locationColumnName); final String indexRangeEndField = locationColumn.getIndexRangeEndField(); if (indexRangeEndField == null) addme.positionEnd = addme.positionStart; else addme.positionEnd = entity.getLocation(indexRangeEndField); output.add(addme); if (output.size() >= 25) break; } cassandra.close(); return output.toArray(new ExpressionQtlTrackEntry[0]); } }.run(); } public ExpressionQtlTrackEntry2D[] getTopEntriesForArea(final Integer dataSetLayerKey, final String positionColumnX, final GenomeRange genomeRangeX, final String positionColumnY, final GenomeRange genomeRangeY) { return new RunWithHibernate<ExpressionQtlTrackEntry2D[]>() { public ExpressionQtlTrackEntry2D[] work(Transaction transaction, Session session) throws Exception { DataSetLayer dsl = (DataSetLayer) session.load(DataSetLayer.class, dataSetLayerKey); ColumnForDataSetLayer[] columns = dsl.getColumns().toArray(new ColumnForDataSetLayer[0]); ColumnForDataSetLayer lodColumn = null; ColumnForDataSetLayer locationColumnX = null; ColumnForDataSetLayer locationColumnY = null; for (ColumnForDataSetLayer col : columns) { if (col.getName().equals("lodScore")) lodColumn = col; if (col.getName().equals(positionColumnX)) locationColumnX = col; if (col.getName().equals(positionColumnY)) locationColumnY = col; } long rangeLen = Math.max(genomeRangeX.toBP - genomeRangeX.fromBP, genomeRangeY.toBP - genomeRangeY.fromBP); int shiftToUse; for (shiftToUse = GeoBoxHelper.minShift; shiftToUse < GeoBoxHelper.maxShift; shiftToUse++) { final long boxSize = GeoBoxHelper.getSizeForBox(shiftToUse); if (boxSize >= rangeLen) break; } CassandraSession cassandra = new CassandraSession(); StreamingEntityRead read = new StreamingEntityRead(cassandra, dsl); final List<ExpressionQtlTrackEntry2D> output = new ArrayList<ExpressionQtlTrackEntry2D>(); final long boxX = GeoBoxHelper.getBoxForValue(shiftToUse, genomeRangeX.fromBP); final long boxY = GeoBoxHelper.getBoxForValue(shiftToUse, genomeRangeY.fromBP); final Iterator<HajoEntity> reader = read.getEntitiesFromGeobox2D(positionColumnX, positionColumnY, shiftToUse, genomeRangeX.chromosome, boxX, boxY); while (reader.hasNext()) { final HajoEntity entity = reader.next(); final ExpressionQtlTrackEntry2D addme = new ExpressionQtlTrackEntry2D(); addme.positionXStart = entity.getLocation(positionColumnX); if (addme.positionXStart > genomeRangeX.toBP) continue; final String indexRangeEndField = locationColumnX.getIndexRangeEndField(); if (indexRangeEndField == null) addme.positionXEnd = addme.positionXStart; else addme.positionXEnd = entity.getLocation(indexRangeEndField); if (addme.positionXEnd < genomeRangeX.fromBP) continue; addme.positionYStart = entity.getLocation(positionColumnY); if (addme.positionYStart > genomeRangeY.toBP) continue; final String indexRangeEndField2 = locationColumnY.getIndexRangeEndField(); if (indexRangeEndField2 == null) addme.positionYEnd = addme.positionYStart; else addme.positionYEnd = entity.getLocation(indexRangeEndField2); if (addme.positionYEnd < genomeRangeY.fromBP) continue; addme.locusId = entity.getName("locusId"); addme.traitId = entity.getName("traitId"); addme.lodScore = entity.getNumerical("lodScore"); addme.lodScoreInMinMaxRange = (addme.lodScore - lodColumn.getMin()) / (lodColumn.getMax() - lodColumn.getMin()); output.add(addme); } cassandra.close(); return output.toArray(new ExpressionQtlTrackEntry2D[0]); } }.run(); } // little helper class private static abstract class ClientRowsFromIterator extends RunWithHibernate<String[][]> { private final Integer dataSetLayerKey; private ClientRowsFromIterator(Integer dataSetLayerKey) { this.dataSetLayerKey = dataSetLayerKey; } public String[][] work(Transaction transaction, Session session) throws Exception { DataSetLayer dsl = (DataSetLayer) session.load(DataSetLayer.class, dataSetLayerKey); ColumnForDataSetLayer[] columns = dsl.getColumns().toArray(new ColumnForDataSetLayer[0]); CassandraSession cassandra = new CassandraSession(); StreamingEntityRead read = new StreamingEntityRead(cassandra, dsl); final List<String[]> output = new ArrayList<String[]>(); final Iterator<HajoEntity> reader = prepareIterator(read); while (reader.hasNext()) { final HajoEntity entity = reader.next(); String[] tmp = new String[columns.length]; for (int j = 0; j < columns.length; j++) { tmp[j] = entity.getAsString(columns[j].getName()); } output.add(tmp); if (output.size() >= 25) break; } cassandra.close(); return output.toArray(new String[0][]); } public abstract Iterator<HajoEntity> prepareIterator(StreamingEntityRead read); } }