def __init__(self, abort_event):
     PrimerTaskBase.__init__(self, abort_event)
     self._print_lock = Lock()
     self._out_queue = OutQueueWithID()
     self._counter_mgr = WorkCounterManager()
     self._counter_mgr.start()
     self._subroutines = []
     self._time0 = time()
     self._newline_last = False
Exemple #2
0
 def __init__(self, abort_event):
     PrimerTaskBase.__init__(self, abort_event)
     self._print_lock   = Lock()
     self._out_queue    = OutQueueWithID()
     self._counter_mgr  = WorkCounterManager()
     self._counter_mgr.start()
     self._subroutines  = []
     self._time0        = time()
     self._newline_last = False
class AnalysisTask(PrimerTaskBase):
    '''This class gathers all calculations in a single pipeline with 
    parallelized subroutines for CPU-intensive computations.'''

    #file format for saving primers
    _fmt = 'fasta'
    _counter_threshold = 60

    def __init__(self, abort_event):
        PrimerTaskBase.__init__(self, abort_event)
        self._print_lock = Lock()
        self._out_queue = OutQueueWithID()
        self._counter_mgr = WorkCounterManager()
        self._counter_mgr.start()
        self._subroutines = []
        self._time0 = time()
        self._newline_last = False

    #end def

    def __del__(self):
        self._counter_mgr.shutdown()
        self._clean_subroutines()

    #end def

    def _clean_subroutines(self):
        for p_entry in self._subroutines:
            try:
                p_entry['manager'].shutdown()
            except:
                pass
        self._subroutines = []

    #end def

    def _generate_subroutine_entry(self):
        _id = (len(self._subroutines) + 1)
        with self._out_queue.set_id(_id):
            manager = SubroutineManager()
            manager.start()
        p_entry = {
            'id': _id,
            'manager': manager,
            'process': None,
            'counter': self._counter_mgr.WorkCounter()
        }
        self._subroutines.append(p_entry)
        return p_entry

    #end def

    def _run_subroutine(self, func, args, p_entry, p_name=None):
        '''Run a func in a thread with args'''
        routine_name = p_name if p_name else func.__name__
        routine_id = p_entry['id']
        args = [p_entry['counter']] + (list(args) if args else [])
        subroutine = WaitingThread(self._print_lock,
                                   routine_id,
                                   target=func,
                                   name=routine_name,
                                   args=args)
        p_entry['process'] = subroutine
        with self._print_lock:
            self._print(
                ('\nStarting CPU-intensive task #%d:\n  '
                 ' %s\nThis may take awhile...') % (routine_id, routine_name))
        subroutine.start()

    #end def

    def _run_analysis(self, args):
        analysis_routines = []
        #--------generate components calculate Tms and save the primers--------#
        if not self._prepare_primers(args): return None
        if not self._save_primers(): return None
        #----------------------------------------------------------------------#
        #following computations are CPU intensive, so they need parallelization#
        #check primers for hairpins, dimers and cross-dimers                   #
        self._print(
            '\nSearching for stable secondary structures of the primers...')
        p_entry = self._generate_subroutine_entry()
        all_sec_structures = p_entry['manager'].AllSecStructures(
            self._abort_event, args.job_id, self._primers)
        all_sec_structures.find_structures()
        if self.aborted(): return None
        analysis_routines.append(all_sec_structures)
        side_reactions = all_sec_structures.reactions()
        side_concentrations = all_sec_structures.concentrations()
        with self._print_lock:
            self._print('Done.')
        self._run_subroutine(
            all_sec_structures.calculate_equilibrium, None, p_entry,
            'Calculate relative concentrations of secondary structures at Tm.')
        #----------------------------------------------------------------------#
        #in-silico PCR simulation. This is only available if sequence database #
        #is provided in some form                                              #
        if args.template_files:
            p_entry = self._generate_subroutine_entry()
            ipcr = p_entry['manager'].iPCR(self._abort_event,
                                           args.max_mismatches, args.job_id,
                                           self._primers, args.min_amplicon,
                                           args.max_amplicon, args.polymerase,
                                           args.with_exonuclease, args.cycles,
                                           side_reactions, side_concentrations,
                                           args.analyse_all_annealings)
            analysis_routines.append(ipcr)
            #connect to sequence database
            self._run_subroutine(
                ipcr.simulate_PCR, (args.template_files, args.use_sequences),
                p_entry,
                'Simulate PCR using provided sequences as DNA templates.')
        #-----------------test for primers specificity by BLAST----------------#
        p_entry = self._generate_subroutine_entry()
        blast_primers = p_entry['manager'].BlastPrimers(
            self._abort_event,
            args.job_id,
            self._primers,
            args.min_amplicon,
            args.max_amplicon,
            args.polymerase,
            args.with_exonuclease,
            args.cycles,
            side_reactions,
            side_concentrations,
            include_side_annealings=args.analyse_all_annealings)
        analysis_routines.append(blast_primers)
        #if --do-blast flag was provided, make an actual query
        if args.do_blast:
            #construct Entrez query
            entrez_query = ''
            if args.organisms:
                for organism in args.organisms:
                    if entrez_query: entrez_query += ' OR '
                    entrez_query += organism + '[organism]'
            #do the blast and analyze the results
            self._run_subroutine(
                blast_primers.blast_and_analyze, (entrez_query, ), p_entry,
                'Make BLAST query, then simulate PCR using returned alignments.'
            )
        #else, try to load previously saved results and analyze them with current parameters
        elif blast_primers.have_saved_results():
            self._run_subroutine(
                blast_primers.load_and_analyze, None, p_entry,
                'Simulate PCR using alignments in BLAST results.')
        #----------------------------------------------------------------------#
        return analysis_routines

    #end def

    def _save_primers(self):
        for primer in self._primers:
            if self.aborted(): return False
            if not primer: continue
            filename = primer.id + '.' + self._fmt
            try:
                SeqIO.write(primer.all_seq_records, filename, self._fmt)
            except Exception, e:
                self._print(
                    '\nFailed to write %s primer and it\'s unambiguous components to:\n   %s'
                    % (primer.id, filename))
                print e
                return False
            self._print(
                '\n%s primer and it\'s unambiguous components were written to:\n   %s'
                % (primer.id, filename))
        return True
Exemple #4
0
class AnalysisTask(PrimerTaskBase):
    '''This class gathers all calculations in a single pipeline with 
    parallelized subroutines for CPU-intensive computations.'''
    
    #file format for saving primers
    _fmt = 'fasta'
    _counter_threshold = 60

    def __init__(self, abort_event):
        PrimerTaskBase.__init__(self, abort_event)
        self._print_lock   = Lock()
        self._out_queue    = OutQueueWithID()
        self._counter_mgr  = WorkCounterManager()
        self._counter_mgr.start()
        self._subroutines  = []
        self._time0        = time()
        self._newline_last = False
    #end def
    
    def __del__(self):
        self._counter_mgr.shutdown() 
        self._clean_subroutines()
    #end def

    def _clean_subroutines(self):
        for p_entry in self._subroutines:
            try: p_entry['manager'].shutdown()
            except: pass
        self._subroutines = []
    #end def


    def _generate_subroutine_entry(self):
        _id = (len(self._subroutines)+1)
        with self._out_queue.set_id(_id):
            manager = SubroutineManager()
            manager.start()
        p_entry  = {'id'       : _id,
                    'manager'  : manager,
                    'process'  : None,
                    'counter'  : self._counter_mgr.WorkCounter()}
        self._subroutines.append(p_entry)
        return p_entry
    #end def
    
    
    def _run_subroutine(self, func, args, p_entry, p_name=None):
        '''Run a func in a thread with args'''
        routine_name = p_name if p_name else func.__name__
        routine_id   = p_entry['id']
        args = [p_entry['counter']]+(list(args) if args else [])
        subroutine   = WaitingThread(self._print_lock, routine_id, target=func, 
                                     name=routine_name, args=args)
        p_entry['process'] = subroutine
        with self._print_lock: 
            self._print(('\nStarting CPU-intensive task #%d:\n  '
                         ' %s\nThis may take awhile...') %
                        (routine_id, routine_name))
        subroutine.start()
    #end def
    
    
    def _run_analysis(self, args):
        analysis_routines = []
        #--------generate components calculate Tms and save the primers--------#
        if not self._prepare_primers(args): return None
        if not self._save_primers(): return None
        #----------------------------------------------------------------------#
        #following computations are CPU intensive, so they need parallelization#
        #check primers for hairpins, dimers and cross-dimers                   #
        self._print('\nSearching for stable secondary structures of the primers...')
        p_entry = self._generate_subroutine_entry()
        all_sec_structures  = p_entry['manager'].AllSecStructures(self._abort_event, args.job_id, self._primers)
        all_sec_structures.find_structures()
        if self.aborted(): return None
        analysis_routines.append(all_sec_structures)
        side_reactions      = all_sec_structures.reactions()
        side_concentrations = all_sec_structures.concentrations()
        with self._print_lock: self._print('Done.')
        self._run_subroutine(all_sec_structures.calculate_equilibrium, None, p_entry,
                             'Calculate relative concentrations of secondary structures at Tm.')
        #----------------------------------------------------------------------#
        #in-silico PCR simulation. This is only available if sequence database #
        #is provided in some form                                              #
        if args.template_files:
            p_entry = self._generate_subroutine_entry()
            ipcr = p_entry['manager'].iPCR(self._abort_event,
                                           args.max_mismatches,
                                           args.job_id, 
                                           self._primers, 
                                           args.min_amplicon, 
                                           args.max_amplicon, 
                                           args.polymerase, 
                                           args.with_exonuclease, 
                                           args.cycles,
                                           side_reactions, 
                                           side_concentrations,
                                           args.analyse_all_annealings)
            analysis_routines.append(ipcr)
            #connect to sequence database
            self._run_subroutine(ipcr.simulate_PCR, 
                                 (args.template_files, 
                                  args.use_sequences), p_entry,
                                 'Simulate PCR using provided sequences as DNA templates.')
        #-----------------test for primers specificity by BLAST----------------#
        p_entry = self._generate_subroutine_entry()
        blast_primers = p_entry['manager'].BlastPrimers(self._abort_event,
                                                        args.job_id, 
                                                        self._primers, 
                                                        args.min_amplicon, 
                                                        args.max_amplicon, 
                                                        args.polymerase, 
                                                        args.with_exonuclease, 
                                                        args.cycles,
                                                        side_reactions, 
                                                        side_concentrations,
                                                        include_side_annealings=args.analyse_all_annealings)
        analysis_routines.append(blast_primers)
        #if --do-blast flag was provided, make an actual query
        if args.do_blast:
            #construct Entrez query
            entrez_query = ''
            if args.organisms:
                for organism in args.organisms:
                    if entrez_query: entrez_query += ' OR '
                    entrez_query += organism+'[organism]'
            #do the blast and analyze the results
            self._run_subroutine(blast_primers.blast_and_analyze, 
                                 (entrez_query,),
                                 p_entry,
                                 'Make BLAST query, then simulate PCR using returned alignments.')
        #else, try to load previously saved results and analyze them with current parameters
        elif blast_primers.have_saved_results():
            self._run_subroutine(blast_primers.load_and_analyze, 
                                 None, 
                                 p_entry,
                                 'Simulate PCR using alignments in BLAST results.')
        #----------------------------------------------------------------------#
        return analysis_routines
    #end def


    def _save_primers(self):
        for primer in self._primers:
            if self.aborted(): return False
            if not primer: continue
            filename = primer.id+'.'+self._fmt
            try:
                SeqIO.write(primer.all_seq_records, filename, self._fmt)
            except Exception, e:
                self._print('\nFailed to write %s primer and it\'s unambiguous components to:\n   %s' % (primer.id, filename))
                print e
                return False 
            self._print('\n%s primer and it\'s unambiguous components were written to:\n   %s' % (primer.id, filename))
        return True