#ifndef SKIP_DOXYGEN_PROCESSING static char const rcsid[] = "$Id: repeats_filter.c,v 1.19 2007/12/19 21:56:48 camacho Exp $"; #endif /* SKIP_DOXYGEN_PROCESSING */ /* * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * File Name: $RCSfile: repeats_filter.c,v $ * * Author: Ilya Dondoshansky * */ /** @file repeats_filter.c * Repeats filtering API for the new BLAST code */ /* Prototypes of functions defined below */ #include #include #include #include #include #include /** @addtogroup CToolkitAlgoBlast * * @{ */ /** Sets options for a repeats search. * @param options Options wrapper structure to modify [in] [out] */ static Int2 s_SetRepeatsSearchOptions(SBlastOptions* options) { Int2 status = 0; if (!options || !options->score_options || !options->word_options || !options->ext_options) return -1; if ((status = SBlastOptionsSetEvalue(options, REPEATS_SEARCH_EVALUE))) return status; if ((status = SBlastOptionsSetWordSize(options, REPEATS_SEARCH_WORD_SIZE))) return status; if ((status = SBlastOptionsSetFilterString(options, REPEATS_SEARCH_FILTER_STRING))) return status; options->lookup_options->lut_type = eNaLookupTable; options->score_options->penalty = REPEATS_SEARCH_PENALTY; options->score_options->gap_open = REPEATS_SEARCH_GAP_OPEN; options->score_options->gap_extend = REPEATS_SEARCH_GAP_EXTEND; options->word_options->x_dropoff = REPEATS_SEARCH_XDROP_UNGAPPED; options->ext_options->gap_x_dropoff_final = REPEATS_SEARCH_XDROP_FINAL; return status; } /** Create a SeqLoc with repeat masking locations, given the results of a * BLAST search against a database of repeats. * @param query_seqloc Query sequence locations [in] * @param results Internal results structure, returned from a BLAST search * against a repeats database [in] * @param mask_seqloc List of ValNode's, one per query, containing mask * locations. [out] */ static Int2 s_FillMaskLocFromBlastHSPResults(SeqLoc* query_seqloc, BlastHSPResults* results, SeqLoc* *mask_seqloc) { Int4 num_seqs = 0; Int4 query_index; SeqLoc* slp; BlastMaskLoc* mask; const EBlastProgramType kProgram = eBlastTypeBlastn; const Uint4 kNumContexts = BLAST_GetNumberOfContexts(eBlastTypeBlastn); if (!query_seqloc || !mask_seqloc) return -1; *mask_seqloc = NULL; if (!results) { return 0; } num_seqs = ValNodeLen(query_seqloc); mask = BlastMaskLocNew(num_seqs*kNumContexts); for (query_index = 0, slp = query_seqloc; slp; ++query_index, slp = slp->next) { Int4 query_length, query_start; Int4 hit_index; BlastSeqLoc* loc_list = NULL, *ordered_loc_list = NULL; BlastHitList* hit_list = results->hitlist_array[query_index]; if (!hit_list) { continue; } query_length = SeqLocLen(slp); query_start = SeqLocStart(slp); /* Find all HSP intervals in query */ for (hit_index = 0; hit_index < hit_list->hsplist_count; ++hit_index) { Int4 hsp_index; BlastHSPList* hsp_list = hit_list->hsplist_array[hit_index]; /* HSP lists cannot be NULL! */ ASSERT(hsp_list); for (hsp_index = 0; hsp_index < hsp_list->hspcnt; ++hsp_index) { Int4 left, right; BlastHSP* hsp = hsp_list->hsp_array[hsp_index]; /* HSP cannot be NULL! */ ASSERT(hsp); if (hsp->query.frame == hsp->subject.frame) { left = hsp->query.offset; right = hsp->query.end - 1; } else { left = query_length - hsp->query.end; right = query_length - hsp->query.offset - 1; } /* Shift the coordinates so they correspond to the full sequence. */ left += query_start; right += query_start; BlastSeqLocNew(&loc_list, left, right); } } /* Make the intervals unique */ BlastSeqLocCombine(&loc_list, REPEAT_MASK_LINK_VALUE); ordered_loc_list = loc_list; loc_list = NULL; mask->seqloc_array[query_index*kNumContexts] = ordered_loc_list; } *mask_seqloc = BlastMaskLocToSeqLoc(kProgram, mask, query_seqloc); mask = BlastMaskLocFree(mask); return 0; } Int2 Blast_FindRepeatFilterSeqLoc(SeqLoc* query_seqloc, const char* filter_string, SeqLoc* *mask_loc, SBlastMessage **message) { char* repeat_database = NULL; SBlastOptions* options = NULL; Blast_SummaryReturn* sum_returns = NULL; Int2 status = 0; BlastSeqSrc* seq_src = NULL; SeqLoc* filter_loc = NULL; /* Dummy variable, since search will be performed without filtering. */ BlastHSPResults* results = NULL; SBlastFilterOptions* filtering_options = NULL; ASSERT(message); if (filter_string == NULL) return 0; status = BlastFilteringOptionsFromString(eBlastTypeBlastn, filter_string, &filtering_options, NULL); if (status) return status; /* If repeat filtering not requested, return success. */ if (filtering_options == NULL || filtering_options->repeatFilterOptions == NULL) { filtering_options = SBlastFilterOptionsFree(filtering_options); return 0; } repeat_database = filtering_options->repeatFilterOptions->database; sum_returns = Blast_SummaryReturnNew(); status = SBlastOptionsNew("blastn", &options, sum_returns); seq_src = ReaddbBlastSeqSrcInit(repeat_database, FALSE, 0, 0); if (!seq_src) { SBlastMessageWrite(&sum_returns->error, SEV_ERROR, "Initialization of subject sequences source failed", NULL, FALSE); } else { char* error_str = BlastSeqSrcGetInitError(seq_src); if (error_str) SBlastMessageWrite(&sum_returns->error, SEV_ERROR, error_str, NULL, FALSE); } /* If there was an error initializing the sequence source, return without doing the search. */ if (sum_returns->error) { *mask_loc = NULL; *message = sum_returns->error; sum_returns->error = NULL; Blast_SummaryReturnFree(sum_returns); filtering_options = SBlastFilterOptionsFree(filtering_options); return -1; } s_SetRepeatsSearchOptions(options); status = Blast_RunSearch(query_seqloc, (Blast_PsiCheckpointLoc *) NULL, seq_src, (SeqLoc*) NULL, options, (BlastTabularFormatData*) NULL, &results, &filter_loc, sum_returns); /* The ReadDBFILE structure will not be destroyed here, because the initialising function used readdb_attach */ BlastSeqSrcFree(seq_src); Blast_SummaryReturnFree(sum_returns); /* filter_loc must be NULL on return from Blast_RunSearch, but call the destruction function anyway - in case changes are made in the future. */ filter_loc = Blast_ValNodeMaskListFree(filter_loc); options = SBlastOptionsFree(options); filtering_options = SBlastFilterOptionsFree(filtering_options); if (!status) { /* Extract the repeat locations from the search results */ s_FillMaskLocFromBlastHSPResults(query_seqloc, results, mask_loc); } results = Blast_HSPResultsFree(results); return status; } /* @} */