net.maizegenetics.pangenome.db_loading.AddRefRangeGroupPlugin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of phg Show documentation
Show all versions of phg Show documentation
PHG - Practical Haplotype Graph
/**
*
*/
package net.maizegenetics.pangenome.db_loading;
import java.awt.Frame;
import java.io.BufferedReader;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import org.apache.log4j.Logger;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import net.maizegenetics.dna.map.Position;
import net.maizegenetics.plugindef.AbstractPlugin;
import net.maizegenetics.plugindef.DataSet;
import net.maizegenetics.plugindef.GeneratePluginCode;
import net.maizegenetics.plugindef.PluginParameter;
import net.maizegenetics.util.Utils;
/**
* This class creates a user defined ref range group, adds it to the
* specified db, associates requested reference ranges with the new group.
*
* Input:
* 1. anchor bed file: Should be a subset of reference ranges currently existing in the DB.
* Format is tab-delimited file with columns: chr startpos endpos
* No header, positions are BED file formatted, ie 0-based, inclusive/exclusive
* 2. Name for the new method, which is the ref range group.
* 3. Method details: user description for method
* 4. Config file with db connection info
*
* Output:
* 1. Database tables "methods" and "ref_range_ref_range_method" are updated.
*
* Algorithm:
* 1. Read bed file into an object
* 2. Read all reference ranges from db
* 3. Verify all entries from the bed file exist in the reference_ranges table (throw exception if false)
* 4. Verify method name does not exist in methods table (throw exception if false)
* 5. Add method name to db.
* 6. Add specified reference ranges to the ref_range_ref_range_methods table with method_id = new method id.
*
* @author lcj34
*
*/
public class AddRefRangeGroupPlugin extends AbstractPlugin {
private static final Logger myLogger = Logger.getLogger(AddRefRangeGroupPlugin.class);
private PluginParameter methodName = new PluginParameter.Builder("methodName", null, String.class).guiName("Method Name")
.required(true)
.description("Method name for this reference range group. ").build();
private PluginParameter methodDetails = new PluginParameter.Builder("methodDetails", null, String.class).guiName("Method Details")
.required(true)
.description("Desscription for this group of reference ranges.")
.build();
private PluginParameter ranges = new PluginParameter.Builder("ranges", null, String.class).guiName("Ranges File")
.required(true).inFile()
.description("Tab-delimited, BED Formatted file containing chrom, ref range start position, ref range end position. No header line.").build();
private PluginParameter configFile = new PluginParameter.Builder("configFile", null, String.class).guiName("DataBase Configuration File")
.required(true).inFile()
.description("Path to file containing database access information, separate lines for host=X, user=X, password=X, DB=X, DBtype=X where X is user defined, and DBtype is either sqlite or postgres.")
.build();
public AddRefRangeGroupPlugin() {
super(null, false);
}
public AddRefRangeGroupPlugin(Frame parentFrame) {
super(parentFrame, false);
}
public AddRefRangeGroupPlugin(Frame parentFrame, boolean isInteractive) {
super(parentFrame, isInteractive);
}
// public static void main(String[] args) {
// GeneratePluginCode.generate(AddRefRangeGroupPlugin.class);
// }
@Override
public DataSet processData(DataSet input) {
Connection dbConnect = DBLoadingUtils.connection(configFile(), false);
if (dbConnect == null) {
throw new IllegalStateException("AddRefRangeGroupPlugin: could not get db connection!");
}
PHGDataWriter phg = new PHGdbAccess(dbConnect);
// Verify range list from user input file.
// Create list of reference range ids to be added with new reference range method
// verifyRanges() will throw exception if any range isn't found in the db.
List refRangeIds = verifyRanges(ranges(), phg);
// Add method to the methods table
int methodId = phg.getMethodIdFromName(methodName());
if (methodId > 0) {
throw new IllegalArgumentException("AddRefRangeGroupPlugin: method name already exists. Try again with new method name. Dupliçate method name: " + methodName());
}
methodId = phg.putMethod(methodName(), DBLoadingUtils.MethodType.REF_RANGE_GROUP, pluginParameters());
// add ranges to the ref_range_ref_range_method table
phg.putRefRangeRefRangeMethod(methodId, refRangeIds);
try {
((PHGdbAccess)phg).close();
} catch (Exception exc) {
myLogger.debug("AddRefRangeGroupPlugin: failed when trying to close db connection : " + exc.getMessage());
}
return null;
}
public static List verifyRanges(String rangeFile, PHGDataWriter phg) {
List refRangeIds = new ArrayList<>();
RangeMap dbRanges = phg.getIntervalRangesWithIDForChrom("all");
// Read user ranges file, find Id or throw exception
try (BufferedReader rd = Utils.getBufferedReader(rangeFile)) {
String line;
while ((line = rd.readLine()) != null) {
String[] values = line.split("\\t");
// Add +1 to start pos as bed file is 0-based inclusive/exclusive, db is 1-based inclusive/inclusive
Range usrRange = Range.closed(Position.of(values[0],Integer.parseInt(values[1])+1),
Position.of(values[0],Integer.parseInt(values[2])));
Integer refRangeId = dbRanges.asMapOfRanges().get(usrRange);
if (refRangeId == null) {
throw new IllegalArgumentException("AddRefRangeGroup:verifyRanges: db has no range: " + usrRange.toString()
+ "\nPlease fix input file to include only ranges currently stored in db reference_ranges table.");
}
refRangeIds.add(refRangeId);
}
} catch (Exception ioe) {
throw new IllegalArgumentException("AddRefRangeGroup: error processing range file " + rangeFile + ": " + ioe.getMessage());
}
return refRangeIds;
}
@Override
public ImageIcon getIcon() {
return null;
}
@Override
public String getButtonName() {
return ("Add Reference Range Group");
}
@Override
public String getToolTipText() {
return ("Define new reference range groups based on existing entries in the database reference_ranges table");
}
/**
* Method name for this reference range group.
*
* @return Method Name
*/
public String methodName() {
return methodName.value();
}
/**
* Set Method Name. Method name for this reference range
* group.
*
* @param value Method Name
*
* @return this plugin
*/
public AddRefRangeGroupPlugin methodName(String value) {
methodName = new PluginParameter<>(methodName, value);
return this;
}
/**
* Desscription for this group of reference ranges.
*
* @return Method Details
*/
public String methodDetails() {
return methodDetails.value();
}
/**
* Set Method Details. Desscription for this group of
* reference ranges.
*
* @param value Method Details
*
* @return this plugin
*/
public AddRefRangeGroupPlugin methodDetails(String value) {
methodDetails = new PluginParameter<>(methodDetails, value);
return this;
}
/**
* Tab-delimited, BED Formatted file containing chrom,
* ref range start position, ref range end position. No
* header line.
*
* @return Ranges File
*/
public String ranges() {
return ranges.value();
}
/**
* Set Ranges File. Tab-delimited, BED Formatted file
* containing chrom, ref range start position, ref range
* end position. No header line.
*
* @param value Ranges File
*
* @return this plugin
*/
public AddRefRangeGroupPlugin ranges(String value) {
ranges = new PluginParameter<>(ranges, value);
return this;
}
/**
* Path to file containing database access information,
* separate lines for host=X, user=X, password=X, DB=X,
* DBtype=X where X is user defined, and DBtype is either
* sqlite or postgres.
*
* @return DataBase Configuration File
*/
public String configFile() {
return configFile.value();
}
/**
* Set DataBase Configuration File. Path to file containing
* database access information, separate lines for host=X,
* user=X, password=X, DB=X, DBtype=X where X is user
* defined, and DBtype is either sqlite or postgres.
*
* @param value DataBase Configuration File
*
* @return this plugin
*/
public AddRefRangeGroupPlugin configFile(String value) {
configFile = new PluginParameter<>(configFile, value);
return this;
}
}