#!/opt/anaconda1anaconda2anaconda3/bin/python
# File created on 23 Jul 2011
# based on beta_diversity.py
from __future__ import division

__author__ = "Antonio Gonzalez Pena"
__copyright__ = "Copyright 2011, The QIIME Project"
__credits__ = ["Antonio Gonzalez Pena", "Andrew J. King"]
__license__ = "GPL"
__version__ = "1.8.0"
__maintainer__ = "Antonio Gonzalez Pena"
__email__ = "antgonza@gmail.com"
 

from qiime.util import parse_command_line_parameters, make_option
from qiime.format import format_distance_matrix
from qiime.distance_matrix_from_mapping import compute_distance_matrix_from_metadata, calculate_dist_vincenty 
from qiime.parse import parse_mapping_file_to_dict
import os.path

import warnings
warnings.filterwarnings('ignore', 'Not using MPI as mpi4py not found')


script_info={}
script_info['brief_description']="""Calculate the pairwise dissimilarity on one column of a mappping file"""
script_info['script_description']="""The input for this script is a mapping file and the name of a column, it has to be numeric, from which a distance matrix will be created. The output of this script is a distance matrix containing a dissimilarity value for each pairwise comparison.

As this is a univariate procedure only one metric is supported: d = c-b."""
script_info['script_usage']=[]
script_info['script_usage'].append(
    ("Pairwise dissimilarity:",
     "To calculate the distance matrix (using euclidean distance) on a column of the mapping file, where the results are output to DOB.txt, use the following command:",
     "%prog -i Fasting_Map.txt -c DOB"))
script_info['script_usage'].append(
    ("Pairwise dissimilarity using the Vincenty formula for distance between two Latitude/Longitude points:",
     "To calculate the distance matrix (using Vincenty formula) on a column of the mapping file, where the results are output to lat_long.txt, use the following command:",
     "%prog -i lat_long.txt -c Latitute,Longitude -o lat_long_dtx_matrix.txt"))
script_info['output_description']="""The output of distance_matrix_from_mapping.py is a file containing a distance matrix between rows corresponding to a pair of columns in a mapping file."""
script_info['required_options']=[
 make_option('-i', '--input_path',
     help='Mapping filepath.', type='existing_path'),
 make_option('-c', '--column', type='string',\
        help="string containing the name of the column in the mapping file, e.g. 'DOB'. If you pass two colums separated by a comma (e.g. 'Latitude,Longitud') the script will calculate the Vincenty formula (WGS-84) for distance between two Latitude/Longitude points."),
]
script_info['optional_options']=[
 make_option('-o', '--output_fp',
     help="Output directory. One will be created if it doesn't exist. [default=%default]",
     type='new_dirpath', default="map_distance_matrix.txt")
]
script_info['option_label']={'input_path':'Mapping filepath',
                             'column':'List of samples for compute',
                             'output_fp': 'Output filename'}
                             
script_info['version'] = __version__


def main():
    option_parser, opts, args = parse_command_line_parameters(**script_info)

    data, comments = parse_mapping_file_to_dict(opts.input_path)
    column_headers = []
    if ',' not in opts.column:
        column_data = []
        column_name = opts.column
        for i in data:
            if column_name not in data[i]:
                raise ValueError, "No column: '%s' in the mapping file. Existing columns are: %s" % (column_name ,data[i].keys())
                
            try:
                column_data.append(float(data[i][opts.column]))
            except ValueError:
                raise ValueError, "All the values in the column '%s' must be numeric but '%s' has '%s'" % (column_name, i, data[i][column_name])
            
            column_headers.append(i)
        dtx_mtx = compute_distance_matrix_from_metadata(column_data)
    else:
        latitudes = []
        longitudes = []
        try:
             latitude, longitude = opts.column.split(',')
        except ValueError:
            raise ValueError, "This script accepts a maximum of 2 colums separated by comma and you passed: %s" % (opts.column)
            
        for i in data:
            if latitude not in data[i] or longitude not in data[i]:
                raise ValueError, "One of these columns or both do not exist: '%s' or '%s' in the mapping file. Existing columns are: %s" % (latitude, longitude, data[i].keys())
                
            try:
                latitudes.append(float(data[i][latitude]))
                longitudes.append(float(data[i][longitude]))
            except ValueError:
                raise ValueError, "All the values in the columnd '%s' & '%s' must be numeric but '%s' has '%s'" % (latitude, longitude, i, data[i][column_name])
            
            column_headers.append(i)
        
        dtx_mtx = calculate_dist_vincenty(latitudes, longitudes)
        
    dtx_txt = format_distance_matrix(column_headers, dtx_mtx)
    
    outfilepath = os.path.join(opts.output_fp)
    f = open(outfilepath,'w')
    f.write(dtx_txt)
    f.close()
    

if __name__ == "__main__":
    main()
