<commit_before>package edu.psu.compbio.seqcode.projects.sequtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import edu.psu.compbio.seqcode.deepseq.experiments.ControlledExperiment;
import edu.psu.compbio.seqcode.deepseq.experiments.ExperimentCondition;
import edu.psu.compbio.seqcode.deepseq.experiments.ExperimentManager;
import edu.psu.compbio.seqcode.deepseq.experiments.ExptConfig;
import edu.psu.compbio.seqcode.genome.GenomeConfig;
import edu.psu.compbio.seqcode.genome.location.Point;
import edu.psu.compbio.seqcode.gse.tools.utils.Args;
import edu.psu.compbio.seqcode.gse.utils.io.parsing.GFFEntry;
import edu.psu.compbio.seqcode.gse.utils.io.parsing.ParseGFF;
import edu.psu.compbio.seqcode.projects.multigps.features.BindingEvent;
import edu.psu.compbio.seqcode.projects.multigps.framework.BindingManager;
import edu.psu.compbio.seqcode.projects.multigps.framework.MultiGPSConfig;
import edu.psu.compbio.seqcode.projects.multigps.framework.EnrichmentSignificance;
import edu.psu.compbio.seqcode.projects.multigps.stats.CountsDataset;
import edu.psu.compbio.seqcode.projects.multigps.stats.DifferentialEnrichment;
import edu.psu.compbio.seqcode.projects.multigps.stats.EdgeRDifferentialEnrichment;
import edu.psu.compbio.seqcode.projects.multigps.stats.Normalization;

/**
 * Utility to quantify enrichment and assess significance of a set of peaks (from GFF file). 
 * If multiple conditions are specified, differential binding analysis is performed via edgeR.
 * Meant to be used by Pugh lab pipeline.
 * 
 * 	Input: 
 *		- Genome
 * 		- GFF file of potential peak locations
 * 		- Window around peaks in which to count reads
 * 	Output:
 * 		- Annotated GFF file (all peaks)
 * 		- Annotated GFF file (peaks passing threshold)
 * 		- Replicate count file
 * 
 * SignificanceTester performs no cleaning, merging, or shifting of input locations.
 *  
 * @author mahony
 *
 */
public class SignificanceTester {

	protected ExptConfig econfig;
	protected MultiGPSConfig config;
	protected ExperimentManager manager=null;
	protected BindingManager bindingManager;
	protected Normalization normalizer;
	protected HashMap<Point,GFFEntry> siteToGFFEntry;
	protected List<Point> potentialSites;
	protected int searchRegionWin = 50;
	protected double qThres = 0.01;
	protected double minFold = 2;
	protected boolean simpleReadAssignment=true;
	protected String outDirName, outFileBase;
	protected File outDir;
	protected boolean rankByQ;
	
	//Constructor
	public SignificanceTester(ExptConfig econ, MultiGPSConfig config, ExperimentManager manager, BindingManager bman, String gffFileName, int win, double q, double minfold, boolean rankByQ) {
		this.econfig = econ;
		this.config = config;
		this.manager = manager;
		this.bindingManager = bman;
		potentialSites = new ArrayList<Point>();
		siteToGFFEntry = new HashMap<Point, GFFEntry>();
		searchRegionWin = win;
		qThres = q;
		this.minFold = minfold;
		this.rankByQ = rankByQ;
		//Load GFF file
		String gffDir="";
		try {
			File gffFile = new File(gffFileName);
			ParseGFF parser = new ParseGFF(gffFile);
			while(parser.hasNext()){
				GFFEntry site = parser.next();
				Point currPt = new Point(config.getGenome(), site.getChr(), site.getMidPoint());
				potentialSites.add(currPt);
				siteToGFFEntry.put(currPt, site);
			}
			if(gffFile.getParent() != null)
				gffDir = gffFile.getParent()+File.separator;
			outFileBase = gffFile.getName().replaceAll(".gff", "");
		} catch (IOException e) {
			//Silent exceptions
		}
		
		outDirName = gffDir+"signif_w"+searchRegionWin+"_q"+String.format("%.2e", qThres)+"_minfold"+String.format("%.1f", minFold);
		outDir = new File(outDirName);
		outDir.mkdir();
	}
	
	
	/**
	 * Execute the enrichment tester
	 */
	public void execute(){
		
		//Convert our points to events
		PointsToEvents p2e = new PointsToEvents(config, manager, bindingManager, potentialSites, searchRegionWin,!simpleReadAssignment);
		List<BindingEvent> events = p2e.execute();
		
		//Estimate signal fraction (necessary for calculating statistics)
		bindingManager.estimateSignalVsNoiseFractions(events);
				
		EnrichmentSignificance tester = new EnrichmentSignificance(config, manager, bindingManager, config.getMinEventFoldChange(), econfig.getMappableGenomeLength());
		tester.execute(searchRegionWin);
		
		bindingManager.setBindingEvents(events);
		bindingManager.writeReplicateCounts(outDirName+File.separator+outFileBase+"_replicatecounts.txt");
		writeBindingEventGFFFiles(outDirName+File.separator+outFileBase, events);
		
		//Statistical analysis: inter-condition differences
		if(manager.getNumConditions()>1 && config.getRunDiffTests()){
			DifferentialEnrichment edgeR = new EdgeRDifferentialEnrichment(config);
			CountsDataset data;
			File outImagesDir = new File(outDirName+File.separator+"images");
			outImagesDir.mkdir();
			
			for(int ref=0; ref<manager.getNumConditions(); ref++){
				data = new CountsDataset(manager, bindingManager.getBindingEvents(), ref);
				data = edgeR.execute(data);
				data.updateEvents(bindingManager.getBindingEvents(), manager);
				
				//Print MA scatters (inter-sample & inter-condition)
				data.savePairwiseConditionMAPlots(config.getDiffPMinThres(), outImagesDir.getAbsolutePath()+File.separator, true);
				<commit_msg>bug fix<commit_after>package edu.psu.compbio.seqcode.projects.sequtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import edu.psu.compbio.seqcode.deepseq.experiments.ControlledExperiment;
import edu.psu.compbio.seqcode.deepseq.experiments.ExperimentCondition;
import edu.psu.compbio.seqcode.deepseq.experiments.ExperimentManager;
import edu.psu.compbio.seqcode.deepseq.experiments.ExptConfig;
import edu.psu.compbio.seqcode.genome.GenomeConfig;
import edu.psu.compbio.seqcode.genome.location.Point;
import edu.psu.compbio.seqcode.gse.tools.utils.Args;
import edu.psu.compbio.seqcode.gse.utils.io.parsing.GFFEntry;
import edu.psu.compbio.seqcode.gse.utils.io.parsing.ParseGFF;
import edu.psu.compbio.seqcode.projects.multigps.features.BindingEvent;
import edu.psu.compbio.seqcode.projects.multigps.framework.BindingManager;
import edu.psu.compbio.seqcode.projects.multigps.framework.MultiGPSConfig;
import edu.psu.compbio.seqcode.projects.multigps.framework.EnrichmentSignificance;
import edu.psu.compbio.seqcode.projects.multigps.stats.CountsDataset;
import edu.psu.compbio.seqcode.projects.multigps.stats.DifferentialEnrichment;
import edu.psu.compbio.seqcode.projects.multigps.stats.EdgeRDifferentialEnrichment;
import edu.psu.compbio.seqcode.projects.multigps.stats.Normalization;

/**
 * Utility to quantify enrichment and assess significance of a set of peaks (from GFF file). 
 * If multiple conditions are specified, differential binding analysis is performed via edgeR.
 * Meant to be used by Pugh lab pipeline.
 * 
 * 	Input: 
 *		- Genome
 * 		- GFF file of potential peak locations
 * 		- Window around peaks in which to count reads
 * 	Output:
 * 		- Annotated GFF file (all peaks)
 * 		- Annotated GFF file (peaks passing threshold)
 * 		- Replicate count file
 * 
 * SignificanceTester performs no cleaning, merging, or shifting of input locations.
 *  
 * @author mahony
 *
 */
public class SignificanceTester {

	protected ExptConfig econfig;
	protected MultiGPSConfig config;
	protected ExperimentManager manager=null;
	protected BindingManager bindingManager;
	protected Normalization normalizer;
	protected HashMap<Point,GFFEntry> siteToGFFEntry;
	protected List<Point> potentialSites;
	protected int searchRegionWin = 50;
	protected double qThres = 0.01;
	protected double minFold = 2;
	protected boolean simpleReadAssignment=true;
	protected String outDirName, outFileBase;
	protected File outDir;
	protected boolean rankByQ;
	
	//Constructor
	public SignificanceTester(ExptConfig econ, MultiGPSConfig config, ExperimentManager manager, BindingManager bman, String gffFileName, int win, double q, double minfold, boolean rankByQ) {
		this.econfig = econ;
		this.config = config;
		this.manager = manager;
		this.bindingManager = bman;
		potentialSites = new ArrayList<Point>();
		siteToGFFEntry = new HashMap<Point, GFFEntry>();
		searchRegionWin = win;
		qThres = q;
		this.minFold = minfold;
		this.rankByQ = rankByQ;
		//Load GFF file
		String gffDir="";
		try {
			File gffFile = new File(gffFileName);
			ParseGFF parser = new ParseGFF(gffFile);
			while(parser.hasNext()){
				GFFEntry site = parser.next();
				Point currPt = new Point(config.getGenome(), site.getChr(), site.getMidPoint());
				potentialSites.add(currPt);
				siteToGFFEntry.put(currPt, site);
			}
			if(gffFile.getParent() != null)
				gffDir = gffFile.getParent()+File.separator;
			outFileBase = gffFile.getName().replaceAll(".gff", "");
		} catch (IOException e) {
			//Silent exceptions
		}
		
		outDirName = gffDir+"signif_w"+searchRegionWin+"_q"+String.format("%.2e", qThres)+"_minfold"+String.format("%.1f", minFold);
		outDir = new File(outDirName);
		outDir.mkdir();
	}
	
	
	/**
	 * Execute the enrichment tester
	 */
	public void execute(){
		
		//Convert our points to events
		PointsToEvents p2e = new PointsToEvents(config, manager, bindingManager, potentialSites, searchRegionWin,!simpleReadAssignment);
		List<BindingEvent> events = p2e.execute();
		bindingManager.setBindingEvents(events);
		
		//Estimate signal fraction (necessary for calculating statistics)
		bindingManager.estimateSignalVsNoiseFractions(events);
		
		EnrichmentSignificance tester = new EnrichmentSignificance(config, manager, bindingManager, config.getMinEventFoldChange(), econfig.getMappableGenomeLength());
		tester.execute(searchRegionWin);
		
		bindingManager.writeReplicateCounts(outDirName+File.separator+outFileBase+"_replicatecounts.txt");
		writeBindingEventGFFFiles(outDirName+File.separator+outFileBase, events);
		
		//Statistical analysis: inter-condition differences
		if(manager.getNumConditions()>1 && config.getRunDiffTests()){
			DifferentialEnrichment edgeR = new EdgeRDifferentialEnrichment(config);
			CountsDataset data;
			File outImagesDir = new File(outDirName+File.separator+"images");
			outImagesDir.mkdir();
			
			for(int ref=0; ref<manager.getNumConditions(); ref++){
				data = new CountsDataset(manager, bindingManager.getBindingEvents(), ref);
				data = edgeR.execute(data);
				data.updateEvents(bindingManager.getBindingEvents(), manager);
				
				//Print MA scatters (inter-sample & inter-condition)
				data.savePairwiseConditionMAPlots(config.getDiffPMinThres(), outImagesDir.getAbsolutePath()+File.separator, true);
				
{'fraction_non_alphanumeric': 0.1056221198156682, 'fraction_numerical': 0.0022119815668202765, 'mean_word_length': 5.229047072330655, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7661213', 'n_tokens_mistral': 3760, 'n_tokens_neox': 3419, 'n_words': 701}