#!/usr/bin/env python
# Time-stamp: <2009-05-15 13:50:37 Tao Liu>

"""Module Description

@status:  beta
@version: $Revision$
@author:  Wenmin Qi, Xiang Zhang and Tao Liu
@contact: taoliu@jimmy.harvard.edu
"""

# ------------------------------------
# python modules
# ------------------------------------

import sys
import logging

logging.basicConfig(level=20,
                    format='%(levelname)-5s @ %(asctime)s: %(message)s ',
                    datefmt='%a, %d %b %Y %H:%M:%S'
                    )

# ------------------------------------
# own python modules
# ------------------------------------
from MA2C import *

def execute():
    tagFileName = sys.argv[1]

    logging.info("reading tag file...")
    tagFileInfo = TagFileReader.read(tagFileName)
    
    logging.info("validating tag file...")        
    TagFileValidator.validate(tagFileInfo)
    
    logging.info("reading ndf and pos files to generate tpmap...")
    TpmapFileGenerator.generate(tagFileInfo)
    
    logging.info("reading pairdata files and generating raw files...")        
    ChipsRawGenerator.generate(tagFileInfo)
    
    logging.info("normalizing files...")
    NormalizedFileGenerator.generate(tagFileInfo)
    
    logging.info("loading normalized data...")
    data = PeakDataLoader.read(tagFileInfo)

    logging.info("calculating MA2Cscore...")
    ScoreCalc.calculate(data,tagFileInfo["peakDetection"]["bandwidth"],
                        tagFileInfo["peakDetection"]["minProbes"])

    logging.info("building Null Model...")
    (nullMean,nullStdErr) = NullModelCalc.calculate(data,tagFileInfo["peakDetection"]["bandwidth"])
    
    logging.info("calculating p-value...")
    PValueCalc.calculate(data, nullMean, nullStdErr)


    logging.info("preparing data...")
    # convert data to peakinput
    pos_input = ScorePeakConvert.score2PeakInput(data)

    # generate neg input
    neg_input  = ScorePeakConvert.makeNegPeakInput(pos_input,nullMean)

    logging.info("save MA2Cscore to gzipped wiggle file: %s" % (tagFileInfo["output"]["wiggle"]))
    OutputWriter.save_score_to_wig(pos_input,tagFileInfo)    


    logging.info("calculating FDR table...")
    FDRtable = FdrCalc.calculate(pos_input,neg_input,nullMean,nullStdErr,
                                 tagFileInfo["peakDetection"]["maxGap"])

    logging.info("calling peaks...")
    (ppeaks,npeaks)  = FindPeaks.find(pos_input,neg_input,FDRtable,
                                      tagFileInfo["peakDetection"]["method"],
                                      tagFileInfo["peakDetection"]["threshold"],
                                      tagFileInfo["peakDetection"]["maxGap"],
                                      nullMean,nullStdErr)

    (ppeaks_result,npeaks_result)  = AnnotatePeaks.calculate(data,ppeaks,npeaks,
                                                             FDRtable,
                                                             tagFileInfo["peakDetection"]["bandwidth"])

    logging.info("done!")
    logging.info("saving...")

    logging.info("save FDR table to %s" % (tagFileInfo["output"]["FDRtable"]))
    OutputWriter.print_FDR_table(FDRtable,tagFileInfo)

    logging.info("save peaks and negative peaks to %s and %s" 
                 % (tagFileInfo["output"]["PeakXLS"],tagFileInfo["output"]["NegPeakXLS"]))
    OutputWriter.print_peak_to_xls(ppeaks_result,npeaks_result,tagFileInfo)    

    logging.info("save peaks to %s" % (tagFileInfo["output"]["PeakBED"]))
    OutputWriter.print_peak_to_bed(ppeaks_result,tagFileInfo)    


    logging.info("writing R script for plotting...")

    logging.info("check the output files in ./MA2C_Output!")
    # TODO
    
def usage():
    print "MA2C-python version 1.1.3"
    print "Usage: MA2C <sample.tag>"

def main():
    
    if len(sys.argv) == 2:
        execute()
    else:
        usage()
    
def test_output(data):
    f = open("log","w")
    for seqid in data[0].keys():
        for i in range(len(data[0][seqid])):
            print >> f, "\t".join(map(str,(seqid,data[0][seqid][i],data[1][seqid][i])))

if __name__ == "__main__":
    main()
