use of javafx.scene.chart.ScatterChart in project jvarkit by lindenb.
the class CaseControlJfx method doWork.
@Override
public int doWork(final Stage primaryStage, final List<String> args) {
final VariantPartition partition;
Pedigree pedigree = null;
VcfIterator in = null;
try {
switch(this.partitionType) {
case variantType:
partition = new VariantTypePartition();
break;
case chromosome:
partition = new ChromosomePartition();
break;
case autosomes:
partition = new SexualContigPartition();
break;
case qual:
partition = new QualPartition();
break;
case vqslod:
partition = new VQSLODPartition();
break;
case typeFilter:
partition = new TypeAndFilterPartiton();
break;
case distance:
partition = new DisanceToDiagonalPartiton();
break;
case n_alts:
partition = new NAltsPartition();
break;
default:
throw new IllegalStateException(this.partitionType.name());
}
if (args.isEmpty()) {
in = VCFUtils.createVcfIteratorStdin();
primaryStage.setTitle(CaseControlJfx.class.getSimpleName());
} else if (args.size() == 1) {
in = VCFUtils.createVcfIterator(args.get(0));
primaryStage.setTitle(args.get(0));
} else {
LOG.error("Illegal Number of arguments: " + args);
return -1;
}
if (this.pedigreeFile != null) {
pedigree = Pedigree.newParser().parse(this.pedigreeFile);
} else {
pedigree = Pedigree.newParser().parse(in.getHeader());
}
if (this.controlTag != null) {
final VCFInfoHeaderLine infoHeaderLine = in.getHeader().getInfoHeaderLine(this.controlTag);
if (infoHeaderLine == null) {
LOG.error("No such attribute in the VCF header: " + this.controlTag);
return -1;
}
}
int count = 0;
final SAMSequenceDictionaryProgress progress = new SAMSequenceDictionaryProgress(in.getHeader());
while (in.hasNext() && (this.limit_to_N_variants < 0 || count < this.limit_to_N_variants)) {
final VariantContext ctx = progress.watch(in.next());
if (this.ignore_ctx_filtered && ctx.isFiltered())
continue;
++count;
final List<Allele> alternates = ctx.getAlternateAlleles();
for (int alt_idx = 0; alt_idx < alternates.size(); ++alt_idx) {
final Allele alt = alternates.get(alt_idx);
final Double[] mafs = { null, null };
for (int i = 0; i < 2; ++i) {
if (i == 1 && this.controlTag != null) {
if (ctx.hasAttribute(this.controlTag)) {
try {
final List<Double> dvals = ctx.getAttributeAsDoubleList(this.controlTag, Double.NaN);
if (alt_idx < dvals.size() && dvals.get(alt_idx) != null) {
final double d = dvals.get(alt_idx);
if (!Double.isNaN(d) && d >= 0 && d <= 1.0)
mafs[1] = d;
}
} catch (NumberFormatException err) {
}
}
} else {
final MafCalculator mafCalculator = new MafCalculator(alt, ctx.getContig());
mafCalculator.setNoCallIsHomRef(no_call_is_homref);
for (Pedigree.Person person : (i == 0 ? pedigree.getAffected() : pedigree.getUnaffected())) {
if (selectSamples.equals(SelectSamples.males) && !person.isMale())
continue;
if (selectSamples.equals(SelectSamples.females) && !person.isFemale())
continue;
final Genotype genotype = ctx.getGenotype(person.getId());
if (genotype == null)
continue;
if (ignore_gt_filtered && genotype.isFiltered())
continue;
mafCalculator.add(genotype, person.isMale());
}
if (!mafCalculator.isEmpty()) {
mafs[i] = mafCalculator.getMaf();
}
}
}
if (mafs[0] == null || mafs[1] == null)
continue;
final XYChart.Data<Number, Number> data = new XYChart.Data<Number, Number>(mafs[0], mafs[1]);
if (this.add_tooltip && this.outputFile == null) {
data.setExtraValue(ctx.getContig() + ":" + ctx.getStart());
}
partition.add(ctx, pedigree, data);
}
}
progress.finish();
in.close();
in = null;
} catch (final Exception err) {
LOG.error(err);
return -1;
} finally {
CloserUtil.close(in);
}
final NumberAxis xAxis = new NumberAxis(0.0, 1.0, 0.1);
xAxis.setLabel("Cases");
final NumberAxis yAxis = new NumberAxis(0.0, 1.0, 0.1);
yAxis.setLabel("Controls" + (this.controlTag == null ? "" : "[" + this.controlTag + "]"));
final ScatterChart<Number, Number> chart = new ScatterChart<>(xAxis, yAxis);
for (final XYChart.Series<Number, Number> series : partition.getSeries()) {
chart.getData().add(series);
}
String title = "Case/Control";
if (!args.isEmpty()) {
title = args.get(0);
int slash = title.lastIndexOf("/");
if (slash != -1)
title = title.substring(slash + 1);
if (title.endsWith(".vcf.gz"))
title = title.substring(0, title.length() - 7);
if (title.endsWith(".vcf"))
title = title.substring(0, title.length() - 4);
}
if (userTitle != null)
title = userTitle;
chart.setTitle(title);
chart.setAnimated(false);
chart.setLegendSide(this.legendSide);
final VBox root = new VBox();
MenuBar menuBar = new MenuBar();
Menu menu = new Menu("File");
MenuItem item = new MenuItem("Save image as...");
item.setOnAction(AE -> {
doMenuSave(chart);
});
menu.getItems().add(item);
menu.getItems().add(new SeparatorMenuItem());
item = new MenuItem("Quit");
item.setOnAction(AE -> {
Platform.exit();
});
menu.getItems().add(item);
menuBar.getMenus().add(menu);
root.getChildren().add(menuBar);
final BorderPane contentPane = new BorderPane();
contentPane.setCenter(chart);
root.getChildren().add(contentPane);
Rectangle2D screen = Screen.getPrimary().getVisualBounds();
double minw = Math.max(Math.min(screen.getWidth(), screen.getHeight()) - 50, 50);
chart.setPrefSize(minw, minw);
final Scene scene = new Scene(root, minw, minw);
primaryStage.setScene(scene);
if (this.outputFile != null) {
primaryStage.setOnShown(WE -> {
LOG.info("saving as " + this.outputFile);
try {
saveImageAs(chart, this.outputFile);
} catch (IOException err) {
LOG.error(err);
System.exit(-1);
}
Platform.exit();
});
}
primaryStage.show();
if (this.outputFile == null) {
// http://stackoverflow.com/questions/14117867
for (final XYChart.Series<Number, Number> series : partition.getSeries()) {
for (XYChart.Data<Number, Number> d : series.getData()) {
if (dataOpacity >= 0 && dataOpacity < 1.0) {
d.getNode().setStyle(d.getNode().getStyle() + "-fx-opacity:0.3;");
}
if (this.add_tooltip) {
final Tooltip tooltip = new Tooltip();
tooltip.setText(String.format("%s (%f / %f)", String.valueOf(d.getExtraValue()), d.getXValue().doubleValue(), d.getYValue().doubleValue()));
Tooltip.install(d.getNode(), tooltip);
}
}
}
}
return 0;
}
Aggregations