Ejemplo n.º 1
0
 def __init__(self, *args, **kwargs):
     super(TaskPlugin, self).__init__(*args, **kwargs)
     self.copasi_model = CopasiModel(
         os.path.join(self.task.directory, self.task.original_model))
Ejemplo n.º 2
0
 def __init__(self, *args, **kwargs):
     super(TaskPlugin, self).__init__(*args, **kwargs)
     self.copasi_model = CopasiModel(os.path.join(self.task.directory, self.task.original_model))
Ejemplo n.º 3
0
class TaskPlugin(BaseTask):

    subtasks = 2

    def __init__(self, *args, **kwargs):
        super(TaskPlugin, self).__init__(*args, **kwargs)
        self.copasi_model = CopasiModel(
            os.path.join(self.task.directory, self.task.original_model))

    def validate(self):
        #TODO:Abstract this to a new COPASI class in this plugin package
        return self.copasi_model.is_valid('SO')

    def initialize_subtasks(self):
        #Create new subtask objects, and save them

        #Create the main subtask
        self.create_new_subtask('main')
        #And a subtask to process any results
        self.create_new_subtask('process', local=True)

    def prepare_subtask(self, index):
        """Prepare the indexed subtask"""

        if index == 1:
            return self.process_first_subtask()
        elif index == 2:
            return self.process_second_subtask()
        else:
            raise Exception('No subtasks remaining')

    def process_first_subtask(self):
        #Get the first subtask
        subtask = self.get_subtask(1)

        #Construct the model files for this task

        model_path, model_filename = os.path.split(self.task.original_model)

        #If no load balancing step required:
        model_files = self.copasi_model.prepare_so_task()

        condor_pool = self.task.condor_pool

        condor_job_file = self.copasi_model.prepare_so_condor_job(
            condor_pool.pool_type,
            condor_pool.address,
            subtask_index=1,
            rank='')

        log.debug('Prepared copasi files %s' % model_files)
        log.debug('Prepared condor job %s' % condor_job_file)

        model_count = len(model_files)
        self.task.set_custom_field('model_count', model_count)

        subtask.spec_file = condor_job_file
        subtask.status = 'ready'
        subtask.save()

        return subtask

    def process_second_subtask(self):
        subtask = self.get_subtask(2)
        assert isinstance(subtask, Subtask)

        subtask.start_time = now()
        #Go through and collate the results
        #This is a computationally simple task, so we will run locally, not remotely

        directory = self.task.directory

        original_subtask = self.get_subtask(1)

        output_filename = 'output_1.%d.txt'

        results = self.copasi_model.get_so_results(save=True)
        log.debug('Results:')
        log.debug(results)

        subtask.task.set_custom_field('results_file', 'results.txt')

        log.debug('Setting subtask as finished')
        subtask.status = 'finished'
        subtask.finish_time = now()
        subtask.set_run_time(time_delta=subtask.finish_time -
                             subtask.start_time)
        subtask.save()

        return subtask

    def get_results_view_template_name(self, request):
        """Return a string with the HTML code to be used in the task results view page
        """
        #Get the name of the page we're displaying. If not specified, assume main
        page_name = request.GET.get('name', 'main')

        if page_name == 'main':
            return self.get_template_name('results_view')
        elif page_name == 'plot':
            return self.get_template_name('progress_plot')
        else:
            return ''

    def get_results_view_data(self, request):
        #Get the name of the page we're displaying. If not specified, assume main
        page_name = request.GET.get('name', 'main')
        if page_name == 'main':
            results = self.copasi_model.get_so_results(save=False)
            output = {'results': results}
            output[
                'sensitivity_object'] = self.copasi_model.get_sensitivities_object(
                )

            return output
        elif page_name == 'plot':
            output = {}

            results = self.copasi_model.get_so_results()
            variable_choices = []
            for result in results:
                variable_choices.append(result['name'] + '_max')
                variable_choices.append(result['name'] + '_min')

            if request.GET.get('custom'):
                form = SOPlotUpdateForm(request.GET,
                                        variable_choices=variable_choices)
            else:
                form = SOPlotUpdateForm(
                    variable_choices=variable_choices,
                    initial={'variables': range(len(variable_choices))})

            output['form'] = form

            if form.is_valid():
                variables = map(int, form.cleaned_data['variables'])
                log = form.cleaned_data['logarithmic']
                legend = form.cleaned_data['legend']
                grid = form.cleaned_data['grid']
                fontsize = form.cleaned_data['fontsize']
            else:
                variables = range(len(variable_choices))
                log = False
                legend = True
                grid = True
                fontsize = '12'

            #construct the string to load the image file
            img_string = '?variables=' + str(variables).strip('[').rstrip(
                ']').replace(' ', '')
            img_string += '&name=plot'
            if log:
                img_string += '&log=true'
            if legend:
                img_string += '&legend=true'
            if grid:
                img_string += '&grid=true'
            if fontsize:
                img_string += '&fontsize=' + str(fontsize)

            output['img_string'] = img_string
            return output
        else:
            return {}

    def get_results_download_data(self, request):
        page_name = request.GET.get('name', 'main')

        if page_name == 'main':
            #Return the file results.txt
            filename = os.path.join(self.task.directory, 'results.txt')
            if not os.path.isfile(filename):
                request.session['errors'] = [
                    ('Cannot Return Output',
                     'There was an internal error processing the results file')
                ]
                return HttpResponseRedirect(
                    reverse_lazy('task_details',
                                 kwargs={'task_id': self.task.id}))
            result_file = open(filename, 'r')
            response = HttpResponse(result_file,
                                    content_type='text/tab-separated-values')
            response[
                'Content-Disposition'] = 'attachment; filename=%s_results.txt' % (
                    self.task.name.replace(' ', '_'))
            response['Content-Length'] = os.path.getsize(filename)

            return response

        elif page_name == 'plot':
            return self.get_progress_plot(request)

    def get_progress_plot(self, request):
        """Return the plot image for the progress of a single sensitivity optimization parameter"""

        results = self.copasi_model.get_so_results()
        #Get parameter names, min and max
        variable_choices = []
        for result in results:
            variable_choices.append(result['name'] + '_max')
            variable_choices.append(result['name'] + '_min')

        #Look at the GET data to see what chart options have been set:
        get_variables = request.GET.get('variables')
        log = request.GET.get('log', 'false')

        legend = request.GET.get('legend', 'false')
        grid = request.GET.get('grid', 'false')
        fontsize = int(request.GET.get('fontsize', '12'))

        #Check to see if we should return as an attachment in .png or .svg or .pdf
        download_png = 'download_png' in request.POST
        download_svg = 'download_svg' in request.POST
        download_pdf = 'download_pdf' in request.POST

        try:
            variables = map(int, get_variables.split(','))
            assert max(variables) < len(variable_choices)
        except:
            raise
            variables = range(len(results))

        matplotlib.rc('font', size=fontsize)
        fig = plt.figure()
        #        plt.title(job.name + ' (' + str(job.runs) + ' repeats)', fontsize=12, fontweight='bold')
        plt.xlabel('Iterations')
        plt.ylabel('Optimization value')

        color_list = [
            'red', 'blue', 'green', 'cyan', 'magenta', 'yellow', 'black'
        ]

        j = 0  #used to keep cycle through colors in order
        jobs = CondorJob.objects.filter(subtask__task=self.task).order_by('id')
        for i in variables:
            #Go through each result and plot the progress
            label = variable_choices[i]

            #Check if we're plotting a min or a max. Min will be all even numbers, max all odd
            file_index = int(math.floor(i / 2))
            filename = os.path.join(self.task.directory,
                                    jobs.get(process_id=i).job_output)
            all_evals = []
            all_values = []
            linenumber = 0
            #Go through line by line; lines repeat every 4th line
            for line in open(filename, 'r'):
                if linenumber % 4 == 0:
                    pass
                elif linenumber % 4 == 1:
                    evals = int(
                        line.split()[2])  # Extract number from 'Evals = n'
                    all_evals.append(evals)
                elif linenumber % 4 == 2:
                    pass
                    #time = float(line.split()[2])
                elif linenumber % 4 == 3:
                    value = float(line)
                    all_values.append(value)

                linenumber += 1
            #Plot the progress
            plt.plot(all_evals,
                     all_values,
                     lw=1,
                     label=label,
                     color=color_list[j % len(color_list)])

            j += 1
        #Set a logarithmic scale if requested
        if log != 'false':
            plt.yscale('log')
        if legend != 'false':
            plt.legend(loc=0, prop={'size': fontsize})
        if grid != 'false':
            plt.grid(True)

        plt.show()

        #Remove spaces from the task name for saving
        name = self.task.name.replace(' ', '_')
        if download_png:
            response = HttpResponse(mimetype='image/png',
                                    content_type='image/png')
            fig.savefig(response, format='png', transparent=False, dpi=120)
            response[
                'Content-Disposition'] = 'attachment; filename=%s.png' % name
        elif download_svg:
            response = HttpResponse(mimetype='image/svg',
                                    content_type='image/svg')
            fig.savefig(response, format='svg', transparent=False, dpi=120)
            response[
                'Content-Disposition'] = 'attachment; filename=%s.svg' % name
        elif download_pdf:
            response = HttpResponse(mimetype='application/pdf',
                                    content_type='application/pdf')
            fig.savefig(response, format='pdf', transparent=False, dpi=120)
            response[
                'Content-Disposition'] = 'attachment; filename=%s.pdf' % name
        else:
            response = HttpResponse(mimetype='image/png',
                                    content_type='image/png')
            fig.savefig(response, format='png', transparent=False, dpi=120)
        return response
Ejemplo n.º 4
0
class TaskPlugin(BaseTask):
    
    subtasks = 2

    def __init__(self, *args, **kwargs):
        super(TaskPlugin, self).__init__(*args, **kwargs)
        self.copasi_model = CopasiModel(os.path.join(self.task.directory, self.task.original_model))
        

    def validate(self):
        #TODO:Abstract this to a new COPASI class in this plugin package
        return self.copasi_model.is_valid('SO')

    def initialize_subtasks(self):
        #Create new subtask objects, and save them
        
        #Create the main subtask
        self.create_new_subtask('main')
        #And a subtask to process any results
        self.create_new_subtask('process', local=True)
        
    def prepare_subtask(self, index):
        """Prepare the indexed subtask"""
        
        if index == 1:
            return self.process_first_subtask()
        elif index == 2:
            return self.process_second_subtask()
        else:
            raise Exception('No subtasks remaining')
        
        
    def process_first_subtask(self):
        #Get the first subtask
        subtask = self.get_subtask(1)
        
        #Construct the model files for this task
        
        
        model_path, model_filename = os.path.split(self.task.original_model)
        
        #If no load balancing step required:
        model_files = self.copasi_model.prepare_so_task()
        
        condor_pool = self.task.condor_pool
        
        condor_job_file = self.copasi_model.prepare_so_condor_job(condor_pool.pool_type, condor_pool.address, subtask_index=1, rank='')
        
        log.debug('Prepared copasi files %s'%model_files)
        log.debug('Prepared condor job %s' %condor_job_file)
        
        model_count = len(model_files)
        self.task.set_custom_field('model_count', model_count)
        
        
        subtask.spec_file = condor_job_file
        subtask.status = 'ready'
        subtask.save()
        
        return subtask
        
        
    def process_second_subtask(self):
        subtask=self.get_subtask(2)
        assert isinstance(subtask, Subtask)
        
        subtask.start_time = now()
        #Go through and collate the results
        #This is a computationally simple task, so we will run locally, not remotely
        
        directory = self.task.directory        
        
        original_subtask = self.get_subtask(1)
        
        output_filename = 'output_1.%d.txt'
        
        
        results = self.copasi_model.get_so_results(save=True)
        log.debug('Results:')
        log.debug(results)
        
        subtask.task.set_custom_field('results_file', 'results.txt')
        
        log.debug('Setting subtask as finished')
        subtask.status = 'finished'
        subtask.finish_time = now()
        subtask.set_run_time(time_delta=subtask.finish_time - subtask.start_time)
        subtask.save()
        
        return subtask
    
    def get_results_view_template_name(self, request):
        """Return a string with the HTML code to be used in the task results view page
        """
        #Get the name of the page we're displaying. If not specified, assume main
        page_name = request.GET.get('name', 'main')
        
        if page_name == 'main':
            return self.get_template_name('results_view')
        elif page_name == 'plot':
            return self.get_template_name('progress_plot')
        else: return ''

    
    def get_results_view_data(self, request):
        #Get the name of the page we're displaying. If not specified, assume main
        page_name = request.GET.get('name', 'main')
        if page_name == 'main':
            results = self.copasi_model.get_so_results(save=False)
            output = {'results': results}
            output['sensitivity_object'] = self.copasi_model.get_sensitivities_object()
            
            return output
        elif page_name == 'plot':
            output = {}
            
            results = self.copasi_model.get_so_results()
            variable_choices=[]
            for result in results:
                variable_choices.append(result['name'] + '_max')
                variable_choices.append(result['name'] + '_min')
            
            if request.GET.get('custom'):
                form=SOPlotUpdateForm(request.GET, variable_choices=variable_choices)
            else:
                form=SOPlotUpdateForm(variable_choices=variable_choices, initial={'variables' : range(len(variable_choices))})
                
            output['form'] = form
            
            if form.is_valid():
                variables = map(int,form.cleaned_data['variables'])
                log = form.cleaned_data['logarithmic']
                legend = form.cleaned_data['legend']
                grid = form.cleaned_data['grid']
                fontsize = form.cleaned_data['fontsize']
            else:
                variables=range(len(variable_choices))
                log=False
                legend=True
                grid=True
                fontsize = '12'
               
            #construct the string to load the image file
            img_string = '?variables=' + str(variables).strip('[').rstrip(']').replace(' ', '')
            img_string += '&name=plot'
            if log:
                img_string += '&log=true'
            if legend:
                img_string += '&legend=true'
            if grid:
                img_string += '&grid=true'
            if fontsize:
                img_string += '&fontsize=' + str(fontsize)
            
            output['img_string']=img_string
            return output
        else:
            return {}
        
    def get_results_download_data(self, request):
        page_name = request.GET.get('name', 'main')
        
        if page_name == 'main':
            #Return the file results.txt
            filename = os.path.join(self.task.directory, 'results.txt')
            if not os.path.isfile(filename):
                request.session['errors'] = [('Cannot Return Output', 'There was an internal error processing the results file')]
                return HttpResponseRedirect(reverse_lazy('task_details', kwargs={'task_id':self.task.id}))
            result_file = open(filename, 'r')
            response = HttpResponse(result_file, content_type='text/tab-separated-values')
            response['Content-Disposition'] = 'attachment; filename=%s_results.txt' % (self.task.name.replace(' ', '_'))
            response['Content-Length'] = os.path.getsize(filename)
   
            return response
            
        elif page_name == 'plot':
            return self.get_progress_plot(request)
    

    def get_progress_plot(self, request):    
        """Return the plot image for the progress of a single sensitivity optimization parameter"""

        results = self.copasi_model.get_so_results()
        #Get parameter names, min and max
        variable_choices = []
        for result in results:
            variable_choices.append(result['name'] + '_max')
            variable_choices.append(result['name'] + '_min')

        #Look at the GET data to see what chart options have been set:
        get_variables = request.GET.get('variables')
        log = request.GET.get('log', 'false')
    
        legend = request.GET.get('legend', 'false')
        grid = request.GET.get('grid', 'false')
        fontsize = int(request.GET.get('fontsize', '12'))
       
        #Check to see if we should return as an attachment in .png or .svg or .pdf
        download_png = 'download_png' in request.POST
        download_svg = 'download_svg' in request.POST
        download_pdf = 'download_pdf' in request.POST
        
        
        try:
            variables = map(int, get_variables.split(','))
            assert max(variables) < len(variable_choices)
        except:
            raise
            variables = range(len(results))
        
        matplotlib.rc('font', size=fontsize)
        fig = plt.figure()
    #        plt.title(job.name + ' (' + str(job.runs) + ' repeats)', fontsize=12, fontweight='bold')
        plt.xlabel('Iterations')
        plt.ylabel('Optimization value')
       
        color_list = ['red', 'blue', 'green', 'cyan', 'magenta', 'yellow', 'black']        
       
        j=0 #used to keep cycle through colors in order
        jobs = CondorJob.objects.filter(subtask__task=self.task).order_by('id')
        for i in variables:
            #Go through each result and plot the progress
            label = variable_choices[i]
           
            #Check if we're plotting a min or a max. Min will be all even numbers, max all odd
            file_index = int(math.floor(i/2))
            filename = os.path.join(self.task.directory, jobs.get(process_id=i).job_output)
            all_evals=[]
            all_values=[]
            linenumber=0
            #Go through line by line; lines repeat every 4th line
            for line in open(filename, 'r'):
                if linenumber%4 == 0:
                    pass
                elif linenumber%4 == 1:
                    evals = int(line.split()[2]) # Extract number from 'Evals = n'
                    all_evals.append(evals)
                elif linenumber%4 == 2:
                    pass
                    #time = float(line.split()[2])
                elif linenumber%4 == 3:
                    value = float(line)
                    all_values.append(value)
    
                linenumber += 1
            #Plot the progress
            plt.plot(all_evals, all_values, lw=1, label=label, color=color_list[j%len(color_list)])
           
            j+=1
        #Set a logarithmic scale if requested
        if log != 'false':
            plt.yscale('log')
        if legend != 'false':
            plt.legend(loc=0, prop={'size':fontsize} )
        if grid != 'false':
            plt.grid(True)
           
        plt.show()
           
        #Remove spaces from the task name for saving
        name = self.task.name.replace(' ', '_')
        if download_png:    
            response = HttpResponse(mimetype='image/png', content_type='image/png')
            fig.savefig(response, format='png', transparent=False, dpi=120)
            response['Content-Disposition'] = 'attachment; filename=%s.png' % name
        elif download_svg:
            response = HttpResponse(mimetype='image/svg', content_type='image/svg')
            fig.savefig(response, format='svg', transparent=False, dpi=120)
            response['Content-Disposition'] = 'attachment; filename=%s.svg' % name
        elif download_pdf:
            response = HttpResponse(mimetype='application/pdf', content_type='application/pdf')
            fig.savefig(response, format='pdf', transparent=False, dpi=120)
            response['Content-Disposition'] = 'attachment; filename=%s.pdf' % name
        else:    
            response = HttpResponse(mimetype='image/png', content_type='image/png')
            fig.savefig(response, format='png', transparent=False, dpi=120)
        return response