def filter_mutations(self,mutations_I=[],sample_names_I=[], mutation_id_exclusion_list=[],max_position=4000000,
                row_pdist_metric_I='euclidean',row_linkage_method_I='complete',
                col_pdist_metric_I='euclidean',col_linkage_method_I='complete',
                order_sampleNameByMutationID_I=False):
        '''Execute hierarchical cluster on row and column data'''

        print('executing heatmap...');

        from sequencing_analysis.genome_diff import genome_diff
        genomediff = genome_diff();

        # partition into variables:
        if mutations_I: mutation_data = mutations_I;
        else: mutation_data = self.mutations;
        if sample_names_I: sample_names = sample_names_I;
        else: sample_names = self.sample_names;
        mutation_data_O = [];
        mutation_ids_all = [];
        for end_cnt,mutation in enumerate(mutation_data):
            if int(mutation['mutation_position']) > max_position: #ignore positions great than 4000000
                continue;
            # mutation id
            mutation_id = '';
            mutation_id = genomediff._make_mutationID(mutation['mutation_genes'],mutation['mutation_type'],int(mutation['mutation_position']))
            tmp = {};
            tmp.update(mutation);
            tmp.update({'mutation_id':mutation_id});
            mutation_data_O.append(tmp);
            mutation_ids_all.append(mutation_id);
        mutation_ids_all_unique = list(set(mutation_ids_all));
        mutation_ids = [x for x in mutation_ids_all_unique if not x in mutation_id_exclusion_list];
 def get_AllMutationLocations_experimentIDAndSampleName_dataStage01ResequencingMutationsAnnotated(self,experiment_id_I,sample_name_I):
     '''Query mutation_locations from data_stage01_resequencing_mutationsAnnotated'''
     try:
         data = self.session.query(data_stage01_resequencing_mutationsAnnotated.mutation_locations).filter(
                 data_stage01_resequencing_mutationsAnnotated.experiment_id.like(experiment_id_I),
                 data_stage01_resequencing_mutationsAnnotated.sample_name.like(sample_name_I)).order_by(
                 data_stage01_resequencing_mutationsAnnotated.mutation_locations.asc()).all();
         data_O = [];
         genomediff = genome_diff();
         for cnt,d in enumerate(data): 
             data_tmp_str = genomediff._make_mutationLocationsStr(d.mutation_locations);
             data_O.append(data_tmp_str);
         return data_O;
     except SQLAlchemyError as e:
         print(e);
 def get_allMutationClasses_experimentIDAndSampleName_dataStage01ResequencingMutationsSeqChanges(self,experiment_id_I,sample_name_I):
     '''Query mutation data'''
     try:
         data = self.session.query(data_stage01_resequencing_mutationsSeqChanges.mutation_class).filter(
                 data_stage01_resequencing_mutationsSeqChanges.experiment_id.like(experiment_id_I),
                 data_stage01_resequencing_mutationsSeqChanges.sample_name.like(sample_name_I)).order_by(
                 data_stage01_resequencing_mutationsSeqChanges.mutation_class.asc()).all();
         data_O = [];
         genomediff = genome_diff();
         for d in data: 
             data_tmp_str = genomediff._make_mutationClassStr(d.mutation_class);
             data_O.append(data_tmp_str);
         return data_O;
     except SQLAlchemyError as e:
         print(e);
from sequencing_analysis.gff_coverage import gff_coverage

#import and parse .gd files, filter the mutations, and export the filtered mutations tables to .csv
filenames_I = ['C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas/sbaas/data/tests/analysis_resequencing/breseq/ALEevo04-tpiA/output.gd',
             'C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas/sbaas/data/tests/analysis_resequencing/breseq/Evo04tpiAEvo01EP/output.gd',
             'C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas/sbaas/data/tests/analysis_resequencing/breseq/Evo04tpiAEvo02EP/output.gd',
             'C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas/sbaas/data/tests/analysis_resequencing/breseq/Evo04tpiAEvo03EP/output.gd',
             'C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas/sbaas/data/tests/analysis_resequencing/breseq/Evo04tpiAEvo04EP/output.gd',
             ];
samplenames = ['Evo04tpiA',
               'Evo04tpiAEvo01EP',
               'Evo04tpiAEvo02EP',
               'Evo04tpiAEvo03EP',
               'Evo04tpiAEvo04EP',
               ];
gd = genome_diff();
for cnt,filename in enumerate(filenames_I):
    gd.import_gd(filename,experiment_id='ALEsKOs01',sample_name=samplenames[cnt]);
    #use default settings to filter the data
    gd.filter_mutations_population(); 
    #annotate the genome using genbank and MG1655
    gd.annotate_mutations(table_I = 'mutationsFiltered',
                          ref_genome_I = 'C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas/sbaas/data/U00096.2.gb',
                          ref_I = 'genbank',
                          geneReference_I = 'C:/Users/dmccloskey-sbrg/Documents/GitHub/sbaas_workspace/sbaas_workspace/workspace_data/_input/150527_MG1655_geneReference.csv',
                          biologicalmaterial_id_I = 'MG1655')
    #export the filtered and annotated data for later use
    filename_O = samplenames[cnt] + ".csv"
    gd.export_mutationsAnnotated(filename_O);
    gd.clear_data();
    def export_dataStage01ResequencingMutationsAnnotatedLineageArea_js(self,analysis_id_I,mutation_id_exclusion_list=[],frequency_threshold=0.1,max_position=4630000,data_dir_I="tmp"):
        '''export data_stage01_resequencing_mutationsAnnotated to js file
        Visualization: scatterlineplot of mutation frequency across jump time
        '''
        
        genomediff = genome_diff();
        print('exportingdataStage01ResequencingMutationsAnnotated...')
        # get the analysis information
        experiment_ids,sample_names,time_points = [],[],[];
        experiment_ids,sample_names,time_points = self.get_experimentIDAndSampleNameAndTimePoint_analysisID_dataStage01ResequencingAnalysis(analysis_id_I);
        # convert time_point to intermediates
        time_points_int = [int(x) for x in time_points];
        intermediates,time_points,experiment_ids,sample_names = (list(t) for t in zip(*sorted(zip(time_points_int,time_points,experiment_ids,sample_names))))
        intermediates = [i for i,x in enumerate(intermediates)];
        mutation_data_O = [];
        mutation_ids = [];
        for sample_name_cnt,sample_name in enumerate(sample_names):
            # query mutation data:
            mutations = [];
            mutations = self.get_mutations_experimentIDAndSampleName_dataStage01ResequencingMutationsAnnotated(experiment_ids[sample_name_cnt],sample_name);
            for end_cnt,mutation in enumerate(mutations):
                if mutation['mutation_position'] > max_position: #ignore positions great than 4000000
                    continue;
                if mutation['mutation_frequency']<frequency_threshold:
                    continue;
                # mutation id
                mutation_id = genomediff._make_mutationID(mutation['mutation_genes'],mutation['mutation_type'],mutation['mutation_position']);
                #mutation_id = self._make_mutationID(mutation['mutation_genes'],mutation['mutation_type'],mutation['mutation_position']);
                tmp = {};
                tmp.update(mutation);
                tmp.update({'mutation_id':mutation_id});
                mutation_data_O.append(tmp);
                mutation_ids.append(mutation_id);
        # screen out mutations
        mutation_ids_screened = [x for x in mutation_ids if not x in mutation_id_exclusion_list];
        mutation_ids_unique = list(set(mutation_ids_screened));
        # get mutation information for all unique mutations
        mutation_ids_uniqueInfo = [];
        for mutation_id in mutation_ids_unique:
            for mutation in mutation_data_O:
                if mutation_id == mutation['mutation_id']:
                    tmp = {};
                    #tmp['mutation_id']=mutation['mutation_id']
                    #tmp['mutation_frequency']=mutation['mutation_frequency'];
                    #tmp['mutation_genes']=mutation['mutation_genes'];
                    #tmp['mutation_position']=mutation['mutation_position'];
                    #tmp['mutation_annotations']=mutation['mutation_annotations'];
                    #tmp['mutation_locations']=mutation['mutation_locations'];
                    #tmp['mutation_links']=mutation['mutation_links'];
                    #tmp['mutation_type']=mutation['mutation_type'];
                    tmp['mutation_id']=mutation['mutation_id'];
                    tmp['mutation_frequency']=mutation['mutation_frequency'];
                    if mutation['mutation_genes']:
                        tmp['mutation_genes']=";".join([x for x in mutation['mutation_genes'] if x is not None]);
                    else: tmp['mutation_genes']=mutation['mutation_genes'];
                    if mutation['mutation_position']:
                        tmp['mutation_position']=mutation['mutation_position'];
                    else: tmp['mutation_position']=mutation['mutation_position'];
                    if mutation['mutation_annotations']:
                        tmp['mutation_annotations']=";".join([x for x in mutation['mutation_annotations'] if x is not None]);
                    else: tmp['mutation_annotations']=mutation['mutation_annotations'];
                    if mutation['mutation_locations']:
                        tmp['mutation_locations']=";".join([x for x in mutation['mutation_locations'] if x is not None]);
                    else: tmp['mutation_locations']=mutation['mutation_locations'];
                    if mutation['mutation_links']:
                        tmp['mutation_links']=";".join([x for x in mutation['mutation_links'] if x is not None]);
                    else: tmp['mutation_links']=mutation['mutation_links'];
                    tmp['mutation_type']=mutation['mutation_type'];
                    tmp['used_']=mutation['used_'];
                    tmp['comment_']=mutation['comment_'];
                    mutation_ids_uniqueInfo.append(tmp);   
                    break;       
        data_O = [];
        # add in 0.0 frequency for mutations that are not found
        for sample_name_cnt,sample_name in enumerate(sample_names):
            for mutation_id in mutation_ids_uniqueInfo:
                tmp = {};
                tmp_fitted = {};
                tmp['mutation_id']=mutation_id['mutation_id']
                tmp['time_point']=time_points[sample_name_cnt]
                tmp['intermediate']=intermediates[sample_name_cnt]
                tmp['experiment_id']=experiment_ids[sample_name_cnt]
                tmp['sample_name']=sample_name
                tmp['mutation_frequency']=0.0;  
                tmp['mutation_genes']=mutation_id['mutation_genes'];
                tmp['mutation_position']=mutation_id['mutation_position'];
                tmp['mutation_annotations']=mutation_id['mutation_annotations'];
                tmp['mutation_locations']=mutation_id['mutation_locations'];
                tmp['mutation_links']=mutation_id['mutation_links'];
                tmp['mutation_type']=mutation_id['mutation_type'];
                tmp['used_']=mutation_id['used_'];
                tmp['comment_']=mutation_id['comment_'];
                for mutation in mutation_data_O:
                    if sample_name == mutation['sample_name'] and mutation_id['mutation_id'] == mutation['mutation_id']:
                        tmp['mutation_frequency']=mutation['mutation_frequency'];
                        tmp['comment_']=mutation['comment_'];
                        break;
                data_O.append(tmp);
        # dump chart parameters to a js files
        data1_keys = [
                    #'experiment_id',
                    #'sample_name',
                    'mutation_id',
                    #'mutation_frequency',
                    'mutation_type',
                    'mutation_position',
                    #'mutation_data',
                    #'mutation_annotations',
                    'mutation_genes',
                    #'mutation_links',
                    'mutation_locations'
                    ];
        data1_nestkeys = ['mutation_id']; #horizontalareaplot2d_01
        #data1_nestkeys = ['intermediate']; #verticalbarschart2d_01
        data1_keymap = {'xdata':'intermediate',
                        'ydata':'mutation_frequency',
                        'serieslabel':'mutation_id',
                        'featureslabel':''};
        parameters = {"chart1margin":{ 'top': 50, 'right': 150, 'bottom': 50, 'left': 50 },
                    "chart1width":500,"chart1height":350,
                  "chart1title":"Population mutation frequency", "chart1x1axislabel":"jump_time_point","chart1y1axislabel":"frequency"}
        # make the data object
        dataobject_O = [{"data":data_O,"datakeys":data1_keys,"datanestkeys":data1_nestkeys},{"data":data_O,"datakeys":data1_keys,"datanestkeys":data1_nestkeys}];
        # make the tile parameter objects
        formtileparameters_O = {'tileheader':'Filter menu','tiletype':'html','tileid':"filtermenu1",'rowid':"row1",'colid':"col1",
            'tileclass':"panel panel-default",'rowclass':"row",'colclass':"col-sm-4"};
        formparameters_O = {'htmlid':'filtermenuform1','htmltype':'form_01',"formsubmitbuttonidtext":{'id':'submit1','text':'submit'},"formresetbuttonidtext":{'id':'reset1','text':'reset'},"formupdatebuttonidtext":{'id':'update1','text':'update'}};
        formtileparameters_O.update(formparameters_O);
        svgparameters_O = {
            #"svgtype":'verticalbarschart2d_01',
            "svgtype":'horizontalareaplot2d_01',
            "svgkeymap":[data1_keymap,data1_keymap],
            'svgid':'svg1',
            "svgmargin":{ 'top': 50, 'right': 150, 'bottom': 50, 'left': 50 },
            "svgwidth":500,"svgheight":350,
            "svgstackoffset":"extend",
            "svgx1axislabel":"jump_time_point","svgy1axislabel":"frequency",
    		'svgformtileid':'filtermenu1','svgresetbuttonid':'reset1','svgsubmitbuttonid':'submit1'};
        svgtileparameters_O = {'tileheader':'Population mutation frequency','tiletype':'svg','tileid':"tile2",'rowid':"row1",'colid':"col2",
            'tileclass':"panel panel-default",'rowclass':"row",'colclass':"col-sm-8"};
        svgtileparameters_O.update(svgparameters_O);
        tableparameters_O = {"tabletype":'responsivetable_01',
                    'tableid':'table1',
                    "tablefilters":None,
                    "tableclass":"table  table-condensed table-hover",
    			    'tableformtileid':'filtermenu1','tableresetbuttonid':'reset1','tablesubmitbuttonid':'submit1'};
        tabletileparameters_O = {'tileheader':'Population mutation frequency','tiletype':'table','tileid':"tile3",'rowid':"row2",'colid':"col1",
            'tileclass':"panel panel-default",'rowclass':"row",'colclass':"col-sm-12"};
        tabletileparameters_O.update(tableparameters_O);
        parametersobject_O = [formtileparameters_O,svgtileparameters_O,tabletileparameters_O];
        tile2datamap_O = {"filtermenu1":[0],"tile2":[0],"tile3":[0]};
        # dump the data to a json file

        ddtutilities = ddt_container(parameters_I = parametersobject_O,data_I = dataobject_O,tile2datamap_I = tile2datamap_O,filtermenu_I = None);
        if data_dir_I=='tmp':
            filename_str = self.settings['visualization_data'] + '/tmp/ddt_data.js'
        elif data_dir_I=='project':
            filename_str = self.settings['visualization_data'] + '/project/' + analysis_id_I + '_data_stage01_resequencing_mutationsAnnotated' + '.js'
        elif data_dir_I=='data_json':
            data_json_O = ddtutilities.get_allObjects_js();
            return data_json_O;
        with open(filename_str,'w') as file:
            file.write(ddtutilities.get_allObjects());
    def export_dataStage01ResequencingMutationsAnnotated_js(self,analysis_id_I,mutation_id_exclusion_list=[],frequency_threshold=0.1,max_position=4630000,data_dir_I="tmp"):
        '''export data_stage01_resequencing_mutationsAnnotated to js file
        Visualization: treemap of the mutations
        '''
        
        print('exportingdataStage01ResequencingMutationsAnnotated...')
        
        genomediff = genome_diff();
        # get the analysis information
        experiment_ids,sample_names,time_points = [],[],[];
        experiment_ids,sample_names,time_points = self.get_experimentIDAndSampleNameAndTimePoint_analysisID_dataStage01ResequencingAnalysis(analysis_id_I);
        mutation_data_O = [];
        mutation_ids = [];
        for sample_name_cnt,sample_name in enumerate(sample_names):
            # query mutation data:
            mutations = [];
            mutations = self.get_mutations_experimentIDAndSampleName_dataStage01ResequencingMutationsAnnotated(experiment_ids[sample_name_cnt],sample_name);
            for end_cnt,mutation in enumerate(mutations):
                if mutation['mutation_position'] > max_position:
                    continue;
                if mutation['mutation_frequency']<frequency_threshold:
                    continue;
                if not mutation['mutation_genes']:
                    mutation['mutation_genes'] = ['unknown'];
                # mutation id
                mutation_id = genomediff._make_mutationID(mutation['mutation_genes'],mutation['mutation_type'],mutation['mutation_position']);
                if mutation_id in mutation_id_exclusion_list:
                    continue;
                tmp = {};
                tmp['analysis_id']=analysis_id_I;
                tmp['time_point']=time_points[sample_name_cnt]
                tmp['experiment_id']=experiment_ids[sample_name_cnt]
                tmp['sample_name']=sample_name
                tmp['mutation_id']=mutation_id;
                if mutation['mutation_annotations']:
                    tmp['mutation_annotations']=";".join([x for x in mutation['mutation_annotations'] if x is not None]);
                else: tmp['mutation_annotations']=mutation['mutation_annotations'];
                if mutation['mutation_links']:
                    tmp['mutation_links']=";".join([x for x in mutation['mutation_links'] if x is not None]);
                else: tmp['mutation_links']=mutation['mutation_links'];
                if mutation['mutation_genes']:
                    tmp['mutation_genes']=";".join([x for x in mutation['mutation_genes'] if x is not None]);
                else: tmp['mutation_genes']=mutation['mutation_genes'];
                if mutation['mutation_position']:
                    tmp['mutation_position']=mutation['mutation_position'];
                else: tmp['mutation_position']=mutation['mutation_position'];
                if mutation['mutation_locations']:
                    tmp['mutation_locations']=";".join([x for x in mutation['mutation_locations'] if x is not None]);
                else: tmp['mutation_locations']=mutation['mutation_locations'];
                tmp.update(mutation);
                mutation_data_O.append(tmp);

        # dump chart parameters to a js files
        data1_keys = [
                    'experiment_id',
                    'sample_name',
                    'mutation_id',
                    #'mutation_frequency',
                    'mutation_type',
                    'mutation_position',
                    #'mutation_data',
                    'mutation_annotations',
                    'mutation_genes',
                    #'mutation_links',
                    'mutation_locations'
                    ];
        data1_nestkeys = ['analysis_id',
                          'mutation_genes',
                          'mutation_position',
                          'mutation_type',
                          #'sample_name'
                          ];
        data1_keymap = {'xdata':'intermediate',
                        'ydata':'mutation_frequency',
                        'serieslabel':'mutation_id',
                        'featureslabel':''};
        # make the data object
        dataobject_O = [{"data":mutation_data_O,"datakeys":data1_keys,"datanestkeys":data1_nestkeys},
                        {"data":mutation_data_O,"datakeys":data1_keys,"datanestkeys":data1_nestkeys}
                        ];
        # make the tile parameter objects
        # tile 0: form
        formtileparameters_O = {'tileheader':'Filter menu','tiletype':'html','tileid':"filtermenu1",'rowid':"row1",'colid':"col1",
            'tileclass':"panel panel-default",'rowclass':"row",'colclass':"col-sm-12"};
        formparameters_O = {'htmlid':'filtermenuform1','htmltype':'form_01',"formsubmitbuttonidtext":{'id':'submit1','text':'submit'},"formresetbuttonidtext":{'id':'reset1','text':'reset'},"formupdatebuttonidtext":{'id':'update1','text':'update'}};
        formtileparameters_O.update(formparameters_O);
        # tile 1: treelayout2d_01
        svgparameters_O = {"svgtype":'treelayout2d_01',
                           "svgkeymap":[data1_keymap],
                            'svgid':'svg1',
                            "svgmargin":{ 'top': 100, 'right': 100, 'bottom': 100, 'left': 100 },
                            "svgwidth":1000,
                            "svgheight":1000,
                            "svgduration":750,
                            "datalastchild":'sample_name'
                            };
        svgtileparameters_O = {
                'tileheader':'Mutations annotated',
                'tiletype':'svg',
                'tileid':"tile1",
                'rowid':"row2",
                'colid':"col1",
                'tileclass':"panel panel-default",
                'rowclass':"row",
                'colclass':"col-sm-12"
                };
        svgtileparameters_O.update(svgparameters_O);

        # tile 2: table
        tableparameters_O = {
                    "tabletype":'responsivetable_01',
                    'tableid':'table1',
                    "tablefilters":None,
                    "tableclass":"table  table-condensed table-hover",
    			    };
        tabletileparameters_O = {
                    'tileheader':'Mutations annotated',
                    'tiletype':'table',
                    'tileid':"tile2",
                    'rowid':"row3",
                    'colid':"col1",
                    'tileclass':"panel panel-default",
                    'rowclass':"row",
                    'colclass':"col-sm-12"
                    };
        tabletileparameters_O.update(tableparameters_O);
        parametersobject_O = [formtileparameters_O,svgtileparameters_O,tabletileparameters_O];
        tile2datamap_O = {"filtermenu1":[0],"tile1":[0],"tile2":[1]}; #pass two identical data objects to the treemap and table
        # dump the data to a json file
        data_str = 'var ' + 'data' + ' = ' + json.dumps(dataobject_O) + ';';
        parameters_str = 'var ' + 'parameters' + ' = ' + json.dumps(parametersobject_O) + ';';
        tile2datamap_str = 'var ' + 'tile2datamap' + ' = ' + json.dumps(tile2datamap_O) + ';';
        ddtutilities = ddt_container(parameters_I = parametersobject_O,data_I = dataobject_O,tile2datamap_I = tile2datamap_O,filtermenu_I = None);
        if data_dir_I=='tmp':
            filename_str = self.settings['visualization_data'] + '/tmp/ddt_data.js'
        elif data_dir_I=='data_json':
            data_json_O = ddtutilities.get_allObjects_js();
            return data_json_O;
        with open(filename_str,'w') as file:
            file.write(ddtutilities.get_allObjects());
    def execute_heatmap_mutationsAnnotated(self, analysis_id_I,mutation_id_exclusion_list=[],frequency_threshold=0.1,max_position=4630000,
                row_pdist_metric_I='euclidean',row_linkage_method_I='complete',
                col_pdist_metric_I='euclidean',col_linkage_method_I='complete',
                order_sampleNameByMutationID_I=False,
                sample_names_I=[],
                mutationIDs_I=[],
                ):
        '''Execute hierarchical cluster on row and column data'''
        calculateheatmap = calculate_heatmap();
        mutationsheatmap =  mutations_heatmap();
        genomediff = genome_diff();

        print('executing heatmap...');
        # get the analysis information
        experiment_ids,sample_names = [],[];
        experiment_ids,sample_names = self.get_experimentIDAndSampleName_analysisID_dataStage01ResequencingAnalysis(analysis_id_I);
        #mutations_all = [];
        mutation_data_O = [];
        for sample_name_cnt,sample_name in enumerate(sample_names):
            # query mutation data:
            mutations = [];
            mutations = self.get_mutations_experimentIDAndSampleName_dataStage01ResequencingMutationsAnnotated(experiment_ids[sample_name_cnt],sample_name);
            #mutations_all.extend(mutations);
            for mutation in mutations:
                if mutation['mutation_position'] > max_position:
                    continue;
                if mutation['mutation_frequency']<frequency_threshold:
                    continue;
                #if not mutation['mutation_genes']:
                #    mutation['mutation_genes'] = ['unknown'];
                # mutation id
                mutation_id = genomediff._make_mutationID(mutation['mutation_genes'],mutation['mutation_type'],mutation['mutation_position']);
                if mutation_id in mutation_id_exclusion_list:
                    continue;
                tmp = {};
                tmp.update(mutation);
                tmp.update({'mutation_id':mutation_id});
                mutation_data_O.append(tmp);
        heatmap_O = [];
        dendrogram_col_O = {};
        dendrogram_row_O = {};
        if order_sampleNameByMutationID_I:
            heatmap_O,dendrogram_col_O,dendrogram_row_O = calculateheatmap.make_heatmap(mutation_data_O,
                'sample_name','mutation_id','mutation_frequency',
                row_pdist_metric_I=row_pdist_metric_I,row_linkage_method_I=row_linkage_method_I,
                col_pdist_metric_I=col_pdist_metric_I,col_linkage_method_I=col_linkage_method_I,
                filter_rows_I=sample_names_I,
                filter_columns_I=mutationIDs_I,
                order_rowsFromTemplate_I=sample_names_I,
                order_columnsFromTemplate_I=mutationIDs_I,);
        else:
            heatmap_O,dendrogram_col_O,dendrogram_row_O = calculateheatmap.make_heatmap(mutation_data_O,
                'mutation_id','sample_name','mutation_frequency',
                row_pdist_metric_I=row_pdist_metric_I,row_linkage_method_I=row_linkage_method_I,
                col_pdist_metric_I=col_pdist_metric_I,col_linkage_method_I=col_linkage_method_I,
                filter_rows_I=mutationIDs_I,
                filter_columns_I=sample_names_I,
                order_rowsFromTemplate_I=mutationIDs_I,
                order_columnsFromTemplate_I=sample_names_I);
        ## generate the clustering for the heatmap
        #mutationsheatmap.mutations = mutations_all;
        #mutationsheatmap.sample_names = sample_names;
        #mutationsheatmap.make_heatmap(mutation_id_exclusion_list=mutation_id_exclusion_list,max_position=max_position,
        #        row_pdist_metric_I=row_pdist_metric_I,row_linkage_method_I=row_linkage_method_I,
        #        col_pdist_metric_I=col_pdist_metric_I,col_linkage_method_I=col_linkage_method_I)
        #heatmap_O = mutationsheatmap.heatmap;
        #dendrogram_col_O = mutationsheatmap.dendrogram_col;
        #dendrogram_row_O = mutationsheatmap.dendrogram_row;
        # add data to to the database for the heatmap
        for d in heatmap_O:
            row = None;
            row = data_stage01_resequencing_heatmap(
                analysis_id_I,
                d['col_index'],
                d['row_index'],
                d['value'],
                d['col_leaves'],
                d['row_leaves'],
                d['col_label'],
                d['row_label'],
                d['col_pdist_metric'],
                d['row_pdist_metric'],
                d['col_linkage_method'],
                d['row_linkage_method'],
                'frequency',True, None);
            self.session.add(row);
        # add data to the database for the dendrograms
        row = None;
        row = data_stage01_resequencing_dendrogram(
            analysis_id_I,
            dendrogram_col_O['leaves'],
            dendrogram_col_O['icoord'],
            dendrogram_col_O['dcoord'],
            dendrogram_col_O['ivl'],
            dendrogram_col_O['colors'],
            dendrogram_col_O['pdist_metric'],
            dendrogram_col_O['pdist_metric'],
            'frequency',True, None);
        self.session.add(row);
        row = None;
        row = data_stage01_resequencing_dendrogram(
            analysis_id_I,
            dendrogram_row_O['leaves'],
            dendrogram_row_O['icoord'],
            dendrogram_row_O['dcoord'],
            dendrogram_row_O['ivl'],
            dendrogram_row_O['colors'],
            dendrogram_row_O['pdist_metric'],
            dendrogram_row_O['pdist_metric'],
            'frequency',True, None);
        self.session.add(row);
        self.session.commit();
    def export_dataStage01ResequencingEndpointLineages_js(self,analysis_id_I,
                        query_I={},
                        data_dir_I='tmp'):
        '''
        Pie chart or bar chart of mutation counts
        INPUT:
        analysis_id_I = string,
        query_I = additional query deliminators
        '''

        data_O = self.getGroupAndCount_analysisIDAndMutationTypeAndMutationPositionAndMutationGenes_analysisID_dataStage01ResequencingEndpointLineages(
                analysis_id_I,
                column_name_I = 'analysis_id',
                aggregate_function_I='count',
                aggregate_label_I='count_1',
                query_I=query_I,
                output_O='listDict',
                dictColumn_I=None);

        #add in the mutationID
        genomediff = genome_diff();
        for d in data_O:
            d['mutation_id'] = genomediff._make_mutationID(
                d['mutation_genes'],d['mutation_type'],d['mutation_position']
                );
            if d['mutation_genes']:
                d['mutation_genes']=";".join([x for x in d['mutation_genes'] if x is not None]);
            else: d['mutation_genes']=d['mutation_genes'];
        
        # make the tile objects  
        #data1 = filter menu and table    
        data1_keys = ['analysis_id',
                      'mutation_type',
                      'mutation_position',
                      'mutation_genes',
                      'count_1',
                      'mutation_id'
                    ];
        data1_nestkeys = ['mutation_id'];
        data1_keymap = {
            'xdata':'mutation_id',
            'ydata':'count_1',
            'serieslabel':'analysis_id',
            'featureslabel':'mutation_id',
            'tooltiplabel':'mutation_id',
            };     
        
        nsvgtable = ddt_container_filterMenuAndChart2dAndTable();
        nsvgtable.make_filterMenuAndChart2dAndTable(
            data_filtermenu=data_O,
            data_filtermenu_keys=data1_keys,
            data_filtermenu_nestkeys=data1_nestkeys,
            data_filtermenu_keymap=data1_keymap,
            data_svg_keys=None,
            data_svg_nestkeys=None,
            data_svg_keymap=None,
            data_table_keys=None,
            data_table_nestkeys=None,
            data_table_keymap=None,
            data_svg=None,
            data_table=None,
            svgtype='verticalbarschart2d_01',
            tabletype='responsivetable_01',
            svgx1axislabel='',
            svgy1axislabel='',
            tablekeymap = [data1_keymap],
            svgkeymap = [data1_keymap],
            formtile2datamap=[0],
            tabletile2datamap=[0],
            svgtile2datamap=[0], #calculated on the fly
            svgfilters=None,
            svgtileheader='Mutation counts',
            tablefilters=None,
            tableheaders=None
            );

        if data_dir_I=='tmp':
            filename_str = self.settings['visualization_data'] + '/tmp/ddt_data.js'
        elif data_dir_I=='data_json':
            data_json_O = nsvgtable.get_allObjects_js();
            return data_json_O;
        with open(filename_str,'w') as file:
            file.write(nsvgtable.get_allObjects());