blast_filter.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:30k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: blast_filter.c,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 18:07:16  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.45
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: blast_filter.c,v 1000.3 2004/06/01 18:07:16 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's offical duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author: Ilya Dondoshansky
  35.  *
  36.  */
  37. /** @file blast_filter.c
  38.  * All code related to query sequence masking/filtering for BLAST
  39.  */
  40. static char const rcsid[] = 
  41.     "$Id: blast_filter.c,v 1000.3 2004/06/01 18:07:16 gouriano Exp $";
  42. #include <algo/blast/core/blast_def.h>
  43. #include <algo/blast/core/blast_util.h>
  44. #include <algo/blast/core/blast_filter.h>
  45. #include <algo/blast/core/blast_dust.h>
  46. #include <algo/blast/core/blast_seg.h>
  47. #ifdef CC_FILTER_ALLOWED
  48. #include <algo/blast/core/urkpcc.h>
  49. #endif
  50. /* The following function will replace BlastSetUp_CreateSSeqRange */
  51. BlastSeqLoc* BlastSeqLocNew(Int4 from, Int4 to)
  52. {
  53.    BlastSeqLoc* loc = (BlastSeqLoc*) calloc(1, sizeof(BlastSeqLoc));
  54.    SSeqRange* di = (SSeqRange*) malloc(sizeof(SSeqRange));
  55.    di->left = from;
  56.    di->right = to;
  57.    loc->ptr = di;
  58.    return loc;
  59. }
  60. BlastSeqLoc* BlastSeqLocFree(BlastSeqLoc* loc)
  61. {
  62.    SSeqRange* dintp;
  63.    BlastSeqLoc* next_loc;
  64.    while (loc) {
  65.       next_loc = loc->next;
  66.       dintp = (SSeqRange*) loc->ptr;
  67.       sfree(dintp);
  68.       sfree(loc);
  69.       loc = next_loc;
  70.    }
  71.    return NULL;
  72. }
  73. BlastMaskLoc* BlastMaskLocNew(Int4 index, BlastSeqLoc *loc_list)
  74. {
  75.       BlastMaskLoc* retval = (BlastMaskLoc *) calloc(1, sizeof(BlastMaskLoc));
  76.       retval->index = index;
  77.       retval->loc_list = loc_list;
  78.       return retval;
  79. }
  80. BlastMaskLoc* BlastMaskLocFree(BlastMaskLoc* mask_loc)
  81. {
  82.    BlastMaskLoc* next_loc;
  83.    while (mask_loc) {
  84.       next_loc = mask_loc->next;
  85.       BlastSeqLocFree(mask_loc->loc_list);
  86.       sfree(mask_loc);
  87.       mask_loc = next_loc;
  88.    }
  89.    return NULL;
  90. }
  91. /** Used for qsort, compares two SeqLoc's by starting position. */
  92. static int SSeqRangeSortByStartPosition(const void *vp1, const void *vp2)
  93. {
  94.    ListNode* v1 = *((ListNode**) vp1);
  95.    ListNode* v2 = *((ListNode**) vp2);
  96.    SSeqRange* loc1 = (SSeqRange*) v1->ptr;
  97.    SSeqRange* loc2 = (SSeqRange*) v2->ptr;
  98.    
  99.    if (loc1->left < loc2->left)
  100.       return -1;
  101.    else if (loc1->left > loc2->left)
  102.       return 1;
  103.    else
  104.       return 0;
  105. }
  106. /* This will go in place of CombineSeqLocs to combine filtered locations */
  107. Int2
  108. CombineMaskLocations(BlastSeqLoc* mask_loc, BlastSeqLoc* *mask_loc_out,
  109.                      Int4 link_value)
  110. {
  111.    Int2 status=0; /* return value. */
  112.    Int4 start, stop; /* USed to merge overlapping SeqLoc's. */
  113.    SSeqRange* di = NULL,* di_next = NULL,* di_tmp=NULL;
  114.    BlastSeqLoc* loc_head=NULL,* last_loc=NULL,* loc_var=NULL;
  115.    BlastSeqLoc* new_loc = NULL,* new_loc_last = NULL;
  116.    
  117.    if (!mask_loc) {
  118.       *mask_loc_out = NULL;
  119.       return 0;
  120.    }
  121.    /* Put all the SeqLoc's into one big linked list. */
  122.    loc_head = last_loc = 
  123.       (BlastSeqLoc*) BlastMemDup(mask_loc, sizeof(BlastSeqLoc));
  124.          
  125.    /* Copy all locations, so loc points at the end of the chain */
  126.    while (last_loc->next) {
  127.       last_loc->next = 
  128.          (BlastSeqLoc*) BlastMemDup(last_loc->next, sizeof(BlastSeqLoc));
  129.       last_loc = last_loc->next;
  130.    }
  131.    
  132.    /* Sort them by starting position. */
  133.    loc_head = (BlastSeqLoc*) 
  134.       ListNodeSort ((ListNode*) loc_head, 
  135.                    SSeqRangeSortByStartPosition);
  136.    
  137.    di = (SSeqRange*) loc_head->ptr;
  138.    start = di->left;
  139.    stop = di->right;
  140.    loc_var = loc_head;
  141.    
  142.    while (loc_var) {
  143.       di = loc_var->ptr;
  144.       if (loc_var->next)
  145.          di_next = loc_var->next->ptr;
  146.       if (di_next && ((stop + link_value) > di_next->left)) {
  147.          stop = MAX(stop, di_next->right);
  148.       } else {
  149.          di_tmp = (SSeqRange*) malloc(sizeof(SSeqRange));
  150.          di_tmp->left = start;
  151.          di_tmp->right = stop;
  152.          if (!new_loc)
  153.             new_loc_last = ListNodeAddPointer(&new_loc, 0, di_tmp);
  154.          else
  155.             new_loc_last = ListNodeAddPointer(&new_loc_last, 0, di_tmp);
  156.          if (loc_var->next) {
  157.              start = di_next->left;
  158.              stop = di_next->right;
  159.          }
  160.       }
  161.       loc_var = loc_var->next;
  162.       di_next = NULL;
  163.    }
  164.    *mask_loc_out = new_loc;
  165.       
  166.    /* Free memory allocated for the temporary list of SeqLocs */
  167.    while (loc_head) {
  168.       loc_var = loc_head->next;
  169.       sfree(loc_head);
  170.       loc_head = loc_var;
  171.    }
  172.    return status;
  173. }
  174. Int2 
  175. BLAST_ComplementMaskLocations(Uint1 program_number, 
  176.    BlastQueryInfo* query_info, 
  177.    BlastMaskLoc* mask_loc, BlastSeqLoc* *complement_mask) 
  178. {
  179.    Int4 start_offset, end_offset, filter_start, filter_end;
  180.    Int4 context, index;
  181.    BlastSeqLoc* loc,* last_loc = NULL,* start_loc = NULL;
  182.    SSeqRange* double_int = NULL,* di;
  183.    Boolean first; /* Specifies beginning of query. */
  184.    Boolean last_interval_open=TRUE; /* if TRUE last interval needs to be closed. */
  185.    Boolean reverse = FALSE;
  186.    const Boolean k_is_na = (program_number == blast_type_blastn);
  187.    if (complement_mask == NULL)
  188. return -1;
  189.    *complement_mask = NULL;
  190.    for (context = query_info->first_context; 
  191.         context <= query_info->last_context; ++context) {
  192.       start_offset = query_info->context_offsets[context];
  193.       end_offset = query_info->context_offsets[context+1] - 2;
  194.       /* For blastn: check if this strand is not searched at all */
  195.       if (end_offset < start_offset)
  196.           continue;
  197.       index = (k_is_na ? context / 2 : context);
  198.       reverse = (k_is_na && ((context & 1) != 0));
  199.       first = TRUE;
  200.       if (!reverse) {
  201.          for ( ; mask_loc && mask_loc->index < index; 
  202.                mask_loc = mask_loc->next);
  203.       }
  204.       if (!mask_loc || (mask_loc->index > index) ||
  205.           !mask_loc->loc_list) {
  206.          /* No masks for this context */
  207.          double_int = (SSeqRange*) calloc(1, sizeof(SSeqRange));
  208.          double_int->left = start_offset;
  209.          double_int->right = end_offset;
  210.          if (!last_loc)
  211.             last_loc = ListNodeAddPointer(complement_mask, 0, double_int);
  212.          else 
  213.             last_loc = ListNodeAddPointer(&last_loc, 0, double_int);
  214.          continue;
  215.       }
  216.       
  217.       if (reverse) {
  218.          BlastSeqLoc* prev_loc = NULL;
  219.          /* Reverse the order of the locations */
  220.          for (start_loc = mask_loc->loc_list; start_loc; 
  221.               start_loc = start_loc->next) {
  222.             loc = (BlastSeqLoc*) BlastMemDup(start_loc, sizeof(BlastSeqLoc));
  223.             loc->next = prev_loc;
  224.             prev_loc = loc;
  225.          }
  226.          /* Save where this list starts, so it can be freed later */
  227.          start_loc = loc;
  228.       } else {
  229.          loc = mask_loc->loc_list;
  230.       }
  231.       for ( ; loc; loc = loc->next) {
  232.          di = loc->ptr;
  233.          if (reverse) {
  234.             filter_start = end_offset - di->right;
  235.             filter_end = end_offset - di->left;
  236.          } else {
  237.             filter_start = start_offset + di->left;
  238.             filter_end = start_offset + di->right;
  239.          }
  240.          /* The canonical "state" at the top of this 
  241.             while loop is that a SSeqRange has been 
  242.             created and one field was filled in on the 
  243.             last iteration. The first time this loop is 
  244.             entered in a call to the funciton this is not
  245.             true and the following "if" statement moves 
  246.             everything to the canonical state. */
  247.          if (first) {
  248.             last_interval_open = TRUE;
  249.             first = FALSE;
  250.             double_int = (SSeqRange*) calloc(1, sizeof(SSeqRange));
  251.             
  252.             if (filter_start > start_offset) {
  253.                /* beginning of sequence not filtered */
  254.                double_int->left = start_offset;
  255.             } else {
  256.                /* beginning of sequence filtered */
  257.                double_int->left = filter_end + 1;
  258.                continue;
  259.             }
  260.          }
  261.          double_int->right = filter_start - 1;
  262.          if (!last_loc)
  263.             last_loc = ListNodeAddPointer(complement_mask, 0, double_int);
  264.          else 
  265.             last_loc = ListNodeAddPointer(&last_loc, 0, double_int);
  266.          if (filter_end >= end_offset) {
  267.             /* last masked region at end of sequence */
  268.             last_interval_open = FALSE;
  269.             break;
  270.          } else {
  271.             double_int = (SSeqRange*) calloc(1, sizeof(SSeqRange));
  272.                double_int->left = filter_end + 1;
  273.          }
  274.       }
  275.       if (reverse) {
  276.          start_loc = ListNodeFree(start_loc);
  277.       }
  278.       
  279.       if (last_interval_open) {
  280.          /* Need to finish SSeqRange* for last interval. */
  281.          double_int->right = end_offset;
  282.          if (!last_loc)
  283.             last_loc = ListNodeAddPointer(complement_mask, 0, double_int);
  284.          else 
  285.             last_loc = ListNodeAddPointer(&last_loc, 0, double_int);
  286.          last_interval_open = FALSE;
  287.       }
  288.    }
  289.    return 0;
  290. }
  291. #define BLASTOPTIONS_BUFFER_SIZE 128
  292. /** Parses options used for dust.
  293.  * @param ptr buffer containing instructions. [in]
  294.  * @param level sets level for dust. [out]
  295.  * @param window sets window for dust [out]
  296.  * @param cutoff sets cutoff for dust. [out] 
  297.  * @param linker sets linker for dust. [out]
  298. */
  299. static Int2
  300. parse_dust_options(const char *ptr, Int2* level, Int2* window,
  301. Int2* cutoff, Int2* linker)
  302. {
  303. char buffer[BLASTOPTIONS_BUFFER_SIZE];
  304. Int4 arg, index, index1, window_pri=-1, linker_pri=-1, level_pri=-1, cutoff_pri=-1;
  305. long tmplong;
  306. arg = 0;
  307. index1 = 0;
  308. for (index=0; index<BLASTOPTIONS_BUFFER_SIZE; index++)
  309. {
  310. if (*ptr == ' ' || *ptr == NULLB)
  311. {
  312. buffer[index1] = NULLB;
  313. index1 = 0;
  314. switch(arg) {
  315. case 0:
  316. sscanf(buffer, "%ld", &tmplong);
  317. level_pri = tmplong;
  318. break;
  319. case 1:
  320. sscanf(buffer, "%ld", &tmplong);
  321. window_pri = tmplong;
  322. break;
  323. case 2:
  324. sscanf(buffer, "%ld", &tmplong);
  325. cutoff_pri = tmplong;
  326. break;
  327. case 3:
  328. sscanf(buffer, "%ld", &tmplong);
  329. linker_pri = tmplong;
  330. break;
  331. default:
  332. break;
  333. }
  334. arg++;
  335. while (*ptr == ' ')
  336. ptr++;
  337. /* end of the buffer. */
  338. if (*ptr == NULLB)
  339. break;
  340. }
  341. else
  342. {
  343. buffer[index1] = *ptr; ptr++;
  344. index1++;
  345. }
  346. }
  347. *level = level_pri; 
  348. *window = window_pri; 
  349. *cutoff = cutoff_pri; 
  350. *linker = linker_pri; 
  351. return 0;
  352. }
  353. /** parses a string to set three seg options. 
  354.  * @param ptr buffer containing instructions [in]
  355.  * @param window returns "window" for seg algorithm. [out]
  356.  * @param locut returns "locut" for seg. [out]
  357.  * @param hicut returns "hicut" for seg. [out]
  358. */
  359. static Int2
  360. parse_seg_options(const char *ptr, Int4* window, double* locut, double* hicut)
  361. {
  362. char buffer[BLASTOPTIONS_BUFFER_SIZE];
  363. Int4 arg, index, index1; 
  364. long tmplong;
  365. double tmpdouble;
  366. arg = 0;
  367. index1 = 0;
  368. for (index=0; index<BLASTOPTIONS_BUFFER_SIZE; index++)
  369. {
  370. if (*ptr == ' ' || *ptr == NULLB)
  371. {
  372. buffer[index1] = NULLB;
  373. index1 = 0;
  374. switch(arg) {
  375. case 0:
  376. sscanf(buffer, "%ld", &tmplong);
  377. *window = tmplong;
  378. break;
  379. case 1:
  380. sscanf(buffer, "%le", &tmpdouble);
  381. *locut = tmpdouble;
  382. break;
  383. case 2:
  384. sscanf(buffer, "%le", &tmpdouble);
  385. *hicut = tmpdouble;
  386. break;
  387. default:
  388. break;
  389. }
  390. arg++;
  391. while (*ptr == ' ')
  392. ptr++;
  393. /* end of the buffer. */
  394. if (*ptr == NULLB)
  395. break;
  396. }
  397. else
  398. {
  399. buffer[index1] = *ptr; ptr++;
  400. index1++;
  401. }
  402. }
  403. return 0;
  404. }
  405. #ifdef CC_FILTER_ALLOWED
  406. /** Coiled-coiled algorithm parameters. 
  407.  * @param ptr buffer containing instructions. [in]
  408.  * @param window returns window for coil-coiled algorithm. [out]
  409.  * @param cutoff cutoff for coil-coiled algorithm [out]
  410.  * @param linker returns linker [out]
  411. */
  412. static Int2
  413. parse_cc_options(const char *ptr, Int4* window, double* cutoff, Int4* linker)
  414. {
  415. char buffer[BLASTOPTIONS_BUFFER_SIZE];
  416. Int4 arg, index, index1;
  417. long tmplong;
  418. double tmpdouble;
  419. arg = 0;
  420. index1 = 0;
  421. for (index=0; index<BLASTOPTIONS_BUFFER_SIZE; index++)
  422. {
  423. if (*ptr == ' ' || *ptr == NULLB)
  424. {
  425. buffer[index1] = NULLB;
  426. index1 = 0;
  427. switch(arg) {
  428. case 0:
  429. sscanf(buffer, "%ld", &tmplong);
  430. *window = tmplong;
  431. break;
  432. case 1:
  433. sscanf(buffer, "%le", &tmpdouble);
  434. *cutoff = tmpdouble;
  435. break;
  436. case 2:
  437. sscanf(buffer, "%ld", &tmplong);
  438. *linker = tmplong;
  439. break;
  440. default:
  441. break;
  442. }
  443. arg++;
  444. while (*ptr == ' ')
  445. ptr++;
  446. /* end of the buffer. */
  447. if (*ptr == NULLB)
  448. break;
  449. }
  450. else
  451. {
  452. buffer[index1] = *ptr; ptr++;
  453. index1++;
  454. }
  455. }
  456. return 0;
  457. }
  458. #endif
  459. /** Copies filtering commands for one filtering algorithm from "instructions" to
  460.  * "buffer". 
  461.  * ";" is a delimiter for the commands for different algorithms, so it stops
  462.  * copying when a ";" is found. 
  463.  * Example filtering string: "m L; R -d rodents.lib"
  464.  * @param instructions filtering commands [in] 
  465.  * @param buffer filled with filtering commands for one algorithm. [out]
  466. */
  467. static const char *
  468. BlastSetUp_load_options_to_buffer(const char *instructions, char* buffer)
  469. {
  470. Boolean not_started=TRUE;
  471. char* buffer_ptr;
  472. const char *ptr;
  473. Int4 index;
  474. ptr = instructions;
  475. buffer_ptr = buffer;
  476. for (index=0; index<BLASTOPTIONS_BUFFER_SIZE && *ptr != NULLB; index++)
  477. {
  478. if (*ptr == ';')
  479. { /* ";" is a delimiter for different filtering algorithms. */
  480. ptr++;
  481. break;
  482. }
  483. /* Remove blanks at the beginning. */
  484. if (not_started && *ptr == ' ')
  485. {
  486. ptr++;
  487. }
  488. else
  489. {
  490. not_started = FALSE;
  491. *buffer_ptr = *ptr;
  492. buffer_ptr++; ptr++;
  493. }
  494. }
  495. *buffer_ptr = NULLB;
  496. if (not_started == FALSE)
  497. { /* Remove trailing blanks. */
  498. buffer_ptr--;
  499. while (*buffer_ptr == ' ' && buffer_ptr > buffer)
  500. {
  501. *buffer_ptr = NULLB;
  502. buffer_ptr--;
  503. }
  504. }
  505. return ptr;
  506. }
  507. #define CC_WINDOW 22
  508. #define CC_CUTOFF 40.0
  509. #define CC_LINKER 32
  510. Int2
  511. BlastSetUp_Filter(Uint1 program_number, Uint1* sequence, Int4 length, 
  512.    Int4 offset, const char* instructions, Boolean *mask_at_hash, 
  513.    BlastSeqLoc* *seqloc_retval)
  514. {
  515. Boolean do_default=FALSE, do_seg=FALSE, do_dust=FALSE; 
  516. char* buffer=NULL;
  517.    const char *ptr;
  518. Int2 seqloc_num;
  519. Int2 status=0; /* return value. */
  520. Int2 window_dust, level_dust, minwin_dust, linker_dust;
  521.    BlastSeqLoc* dust_loc = NULL,* seg_loc = NULL;
  522. SegParameters* sparamsp=NULL;
  523. #ifdef CC_FILTER_ALLOWED
  524.    Boolean do_coil_coil = FALSE;
  525.    BlastSeqLoc* cc_loc = NULL;
  526. PccDatPtr pccp;
  527.    Int4 window_cc, linker_cc;
  528. double cutoff_cc;
  529. #endif
  530. #ifdef TEMP_BLAST_OPTIONS
  531.    /* TEMP_BLAST_OPTIONS is set to zero until these are implemented. */
  532.    BlastSeqLoc* vs_loc = NULL,* repeat_loc = NULL;
  533. BLAST_OptionsBlkPtr repeat_options, vs_options;
  534. Boolean do_repeats=FALSE;  /* screen for orgn. specific repeats. */
  535. Boolean do_vecscreen=FALSE; /* screen for vector contamination. */
  536. Boolean myslp_allocated;
  537. char* repeat_database=NULL,* vs_database=NULL,* error_msg;
  538. SeqLocPtr repeat_slp=NULL, vs_slp=NULL;
  539. SeqAlignPtr seqalign;
  540. SeqLocPtr myslp, seqloc_var, seqloc_tmp;
  541. ListNode* vnp=NULL,* vnp_var;
  542. #endif
  543. #ifdef CC_FILTER_ALLOWED
  544. cutoff_cc = CC_CUTOFF;
  545. #endif
  546.    if (!seqloc_retval) 
  547.       return -1;
  548. /* FALSE is the default right now. */
  549. if (mask_at_hash)
  550.       *mask_at_hash = FALSE;
  551.    
  552.    *seqloc_retval = NULL;
  553. if (instructions == NULL || strcasecmp(instructions, "F") == 0)
  554. return status;
  555. /* parameters for dust. */
  556. /* -1 indicates defaults. */
  557. level_dust = -1;
  558. window_dust = -1;
  559. minwin_dust = -1;
  560. linker_dust = -1;
  561. if (strcasecmp(instructions, "T") == 0)
  562. { /* do_default actually means seg for proteins and dust for nt. */
  563. do_default = TRUE;
  564. }
  565. else
  566. {
  567. buffer = (char*) calloc(strlen(instructions), sizeof(char));
  568. ptr = instructions;
  569. /* allow old-style filters when m cannot be followed by the ';' */
  570. if (*ptr == 'm' && ptr[1] == ' ')
  571. {
  572. if (mask_at_hash)
  573. *mask_at_hash = TRUE;
  574. ptr += 2;
  575. }
  576. while (*ptr != NULLB)
  577. {
  578. if (*ptr == 'S')
  579. {
  580. sparamsp = SegParametersNewAa();
  581. sparamsp->overlaps = TRUE; /* merge overlapping segments. */
  582. ptr = BlastSetUp_load_options_to_buffer(ptr+1, buffer);
  583. if (buffer[0] != NULLB)
  584. {
  585. parse_seg_options(buffer, &sparamsp->window, &sparamsp->locut, &sparamsp->hicut);
  586. }
  587. do_seg = TRUE;
  588. }
  589. else if (*ptr == 'C')
  590. {
  591. #ifdef CC_FILTER_ALLOWED
  592. ptr = BlastSetUp_load_options_to_buffer(ptr+1, buffer);
  593. window_cc = CC_WINDOW;
  594. cutoff_cc = CC_CUTOFF;
  595. linker_cc = CC_LINKER;
  596. if (buffer[0] != NULLB)
  597. parse_cc_options(buffer, &window_cc, &cutoff_cc, &linker_cc);
  598. do_coil_coil = TRUE;
  599. #endif
  600. }
  601. else if (*ptr == 'D')
  602. {
  603. ptr = BlastSetUp_load_options_to_buffer(ptr+1, buffer);
  604. if (buffer[0] != NULLB)
  605. parse_dust_options(buffer, &level_dust, &window_dust, &minwin_dust, &linker_dust);
  606. do_dust = TRUE;
  607. }
  608. #ifdef TEMP_BLAST_OPTIONS
  609. else if (*ptr == 'R')
  610. {
  611. repeat_options = BLASTOptionNew("blastn", TRUE);
  612. repeat_options->expect_value = 0.1;
  613. repeat_options->penalty = -1;
  614. repeat_options->wordsize = 11;
  615. repeat_options->gap_x_dropoff_final = 90;
  616. repeat_options->dropoff_2nd_pass = 40;
  617. repeat_options->gap_open = 2;
  618. repeat_options->gap_extend = 1;
  619. ptr = BlastSetUp_load_options_to_buffer(ptr+1, buffer);
  620. if (buffer[0] != NULLB)
  621.                                    parse_blast_options(repeat_options,
  622.                                       buffer, &error_msg, &repeat_database,
  623.                                       NULL, NULL);
  624. if (repeat_database == NULL)
  625.                                    repeat_database = strdup("humlines.lib humsines.lib retrovir.lib");
  626. do_repeats = TRUE;
  627. }
  628. else if (*ptr == 'V')
  629. {
  630. vs_options = VSBlastOptionNew();
  631. ptr = BlastSetUp_load_options_to_buffer(ptr+1, buffer);
  632. if (buffer[0] != NULLB)
  633.                                    parse_blast_options(vs_options, buffer,
  634.                                       &error_msg, &vs_database, NULL, NULL); 
  635. vs_options = BLASTOptionDelete(vs_options);
  636. if (vs_database == NULL)
  637.                                    vs_database = strdup("UniVec_Core");
  638. do_vecscreen = TRUE;
  639. }
  640. #endif
  641. else if (*ptr == 'L')
  642. { /* do low-complexity filtering; dust for blastn, otherwise seg.*/
  643. do_default = TRUE;
  644. ptr++;
  645. }
  646. else if (*ptr == 'm')
  647. {
  648. if (mask_at_hash)
  649. *mask_at_hash = TRUE;
  650. ptr++;
  651. }
  652. else
  653. { /* Nothing applied. */
  654. ptr++;
  655. }
  656. }
  657.         sfree(buffer);
  658. }
  659. seqloc_num = 0;
  660. if (program_number != blast_type_blastn)
  661. {
  662. if (do_default || do_seg)
  663. {
  664. SeqBufferSeg(sequence, length, offset, sparamsp, &seg_loc);
  665. SegParametersFree(sparamsp);
  666. sparamsp = NULL;
  667. seqloc_num++;
  668. }
  669. #ifdef CC_FILTER_ALLOWED
  670. if (do_coil_coil)
  671. {
  672. pccp = PccDatNew ();
  673. pccp->window = window_cc;
  674. ReadPccData (pccp);
  675. scores = PredictCCSeqLoc(slp, pccp);
  676. cc_slp = FilterCC(scores, cutoff_cc, length, linker_cc,
  677.                                           SeqIdDup(sip), FALSE);
  678. sfree(scores);
  679. PccDatFree (pccp);
  680. seqloc_num++;
  681. }
  682. #endif
  683. }
  684. else
  685. {
  686. if (do_default || do_dust)
  687. {
  688.          SeqBufferDust(sequence, length, offset, level_dust, window_dust,
  689.                        minwin_dust, linker_dust, &dust_loc);
  690. seqloc_num++;
  691. }
  692. #ifdef TEMP_BLAST_OPTIONS
  693. if (do_repeats)
  694. {
  695. /* Either the SeqLocPtr is SEQLOC_WHOLE (both strands) or SEQLOC_INT (probably 
  696. one strand).  In that case we make up a double-stranded one as we wish to look at both strands. */
  697. myslp_allocated = FALSE;
  698. if (slp->choice == SEQLOC_INT)
  699. {
  700. myslp = SeqLocIntNew(SeqLocStart(slp), SeqLocStop(slp), Seq_strand_both, SeqLocId(slp));
  701. myslp_allocated = TRUE;
  702. }
  703. else
  704. {
  705. myslp = slp;
  706. }
  707. start_timer;
  708. repeat_slp = BioseqHitRangeEngineByLoc(myslp, "blastn", repeat_database, repeat_options, NULL, NULL, NULL, NULL, NULL, 0);
  709. stop_timer("after repeat filtering");
  710. repeat_options = BLASTOptionDelete(repeat_options);
  711. sfree(repeat_database);
  712. if (myslp_allocated)
  713. SeqLocFree(myslp);
  714. seqloc_num++;
  715. }
  716. if (do_vecscreen)
  717. {
  718. /* Either the SeqLocPtr is SEQLOC_WHOLE (both strands) or SEQLOC_INT (probably 
  719. one strand).  In that case we make up a double-stranded one as we wish to look at both strands. */
  720. myslp_allocated = FALSE;
  721. if (slp->choice == SEQLOC_INT)
  722. {
  723. myslp = SeqLocIntNew(SeqLocStart(slp), SeqLocStop(slp), Seq_strand_both, SeqLocId(slp));
  724. myslp_allocated = TRUE;
  725. }
  726. else
  727. {
  728. myslp = slp;
  729. }
  730. VSScreenSequenceByLoc(myslp, NULL, vs_database, &seqalign, &vnp, NULL, NULL);
  731. vnp_var = vnp;
  732. while (vnp_var)
  733. {
  734. seqloc_tmp = vnp_var->ptr;
  735. if (vs_slp == NULL)
  736. {
  737. vs_slp = seqloc_tmp;
  738. }
  739. else
  740. {
  741. seqloc_var = vs_slp;
  742. while (seqloc_var->next)
  743. seqloc_var = seqloc_var->next;
  744. seqloc_var->next = seqloc_tmp;
  745. }
  746. vnp_var->ptr = NULL;
  747. vnp_var = vnp_var->next;
  748. }
  749. vnp = ListNodeFree(vnp);
  750. seqalign = SeqAlignSetFree(seqalign);
  751. sfree(vs_database);
  752. if (myslp_allocated)
  753. SeqLocFree(myslp);
  754. seqloc_num++;
  755. }
  756. #endif
  757. }
  758. if (seqloc_num)
  759. BlastSeqLoc* seqloc_list=NULL;  /* Holds all SeqLoc's for
  760.                                                       return. */
  761. #if 0
  762. if (seg_slp)
  763. ListNodeAddPointer(&seqloc_list, SEQLOC_MIX, seg_slp);
  764. if (cc_slp)
  765. ListNodeAddPointer(&seqloc_list, SEQLOC_MIX, cc_slp);
  766. if (dust_slp)
  767. ListNodeAddPointer(&seqloc_list, SEQLOC_MIX, dust_slp);
  768. if (repeat_slp)
  769. ListNodeAddPointer(&seqloc_list, SEQLOC_MIX, repeat_slp);
  770. if (vs_slp)
  771. ListNodeAddPointer(&seqloc_list, SEQLOC_MIX, vs_slp);
  772. #endif
  773.       if (dust_loc)
  774.          seqloc_list = dust_loc;
  775.       if (seg_loc)
  776.          seqloc_list = seg_loc;
  777. *seqloc_retval = seqloc_list;
  778. }
  779. return status;
  780. }
  781. static Int2
  782. GetFilteringLocationsForOneContext(BLAST_SequenceBlk* query_blk, BlastQueryInfo* query_info, Int2 context, Uint1 program_number, const char* filter_string, BlastSeqLoc* *filter_out, Boolean* mask_at_hash)
  783. {
  784.         Int2 status = 0;
  785.         Int4 query_length = 0;      /* Length of query described by SeqLocPtr. */
  786.         Int4 context_offset;
  787.         BlastMaskLoc *mask_slp, *mask_slp_var; /* Auxiliary locations for lower-case masking  */
  788.         BlastSeqLoc *filter_slp = NULL;     /* SeqLocPtr computed for filtering. */
  789.         BlastSeqLoc *filter_slp_combined;   /* Used to hold combined SeqLoc's */
  790.         Uint1 *buffer;              /* holds sequence for plus strand or protein. */
  791.         Boolean is_na = (program_number == blast_type_blastn);
  792.         Int2 index = (is_na ? context / 2 : context);
  793.         context_offset = query_info->context_offsets[context];
  794.         buffer = &query_blk->sequence[context_offset];
  795.         if ((query_length = BLAST_GetQueryLength(query_info, context)) <= 0)
  796.            return 0;
  797.         if ((status = BlastSetUp_Filter(program_number, buffer,
  798.                        query_length, 0, filter_string,
  799.                              mask_at_hash, &filter_slp))) 
  800.              return status;
  801.         /* Extract the mask locations corresponding to this query 
  802.                (frame, strand), detach it from other masks.
  803.                NB: for translated search the mask locations are expected in 
  804.                protein coordinates. The nucleotide locations must be converted
  805.                to protein coordinates prior to the call to BLAST_MainSetUp.
  806.         */
  807.         mask_slp = NULL;
  808.         for (mask_slp_var=query_blk->lcase_mask; mask_slp_var; mask_slp_var=mask_slp_var->next)
  809.         {
  810.                 if (mask_slp_var->index == index)
  811.                 {
  812.                    mask_slp = mask_slp_var;
  813.                    break;
  814.                 }
  815.         }
  816.         /* Attach the lower case mask locations to the filter locations and combine them */
  817.         if (mask_slp) {
  818.              if (filter_slp) {
  819.                   BlastSeqLoc *loc;           /* Iterator variable */
  820.                   for (loc = filter_slp; loc->next; loc = loc->next);
  821.                     loc->next = mask_slp->loc_list;
  822.              } else {
  823.                    filter_slp = mask_slp->loc_list;
  824.              }
  825.                 /* Set location list to NULL, to allow safe memory deallocation */
  826.                 mask_slp->loc_list = NULL;
  827.         }
  828.         filter_slp_combined = NULL;
  829.         CombineMaskLocations(filter_slp, &filter_slp_combined, 0);
  830.         *filter_out = filter_slp_combined;
  831.         filter_slp = BlastSeqLocFree(filter_slp);
  832. return 0;
  833. }
  834. Int2
  835. BlastSetUp_GetFilteringLocations(BLAST_SequenceBlk* query_blk, BlastQueryInfo* query_info, Uint1 program_number, const char* filter_string, BlastMaskLoc* *filter_out, Boolean* mask_at_hash, Blast_Message * *blast_message)
  836. {
  837.     Int2 status = 0;
  838.     Int2 context = 0; /* loop variable. */
  839.     const Boolean k_is_na = (program_number == blast_type_blastn);
  840.     BlastMaskLoc *last_maskloc = NULL;
  841.     BlastMaskLoc *filter_maskloc = NULL;   /* Local variable for mask locs. */
  842.     Boolean no_forward_strand = (query_info->first_context > 0);  /* filtering needed on reverse strand. */
  843.     for (context = query_info->first_context;
  844.          context <= query_info->last_context; ++context) {
  845.       
  846.         BlastSeqLoc *filter_per_context = NULL;   /* Used to hold combined SeqLoc's */
  847.         Boolean reverse = (k_is_na && ((context & 1) != 0));
  848.         Int4 query_length;
  849.         /* For each query, check if forward strand is present */
  850.         if ((query_length = BLAST_GetQueryLength(query_info, context)) < 0)
  851.         {
  852.             if ((context & 1) == 0)
  853.                no_forward_strand = TRUE;
  854.             continue;
  855.         }
  856.       if (!reverse || no_forward_strand)
  857.       {
  858.         if ((status=GetFilteringLocationsForOneContext(query_blk, query_info, context, program_number, filter_string, &filter_per_context, mask_at_hash)))
  859.         {
  860.                Blast_MessageWrite(blast_message, BLAST_SEV_ERROR, 2, 1, 
  861.                   "Failure at filtering");
  862.                return status;
  863.         }
  864.         /* NB: for translated searches filter locations are returned in 
  865.                protein coordinates, because the DNA lengths of sequences are 
  866.                not available here. The caller must take care of converting 
  867.                them back to nucleotide coordinates. */
  868.        if (filter_per_context)
  869.        {
  870.         if (!last_maskloc) {
  871.                 last_maskloc = (BlastMaskLoc *) calloc(1, sizeof(BlastMaskLoc));
  872.                 filter_maskloc = last_maskloc;
  873.         } else {
  874.                 last_maskloc->next =
  875.                         (BlastMaskLoc *) calloc(1, sizeof(BlastMaskLoc));
  876.                 last_maskloc = last_maskloc->next;
  877.         }
  878.         last_maskloc->index = (k_is_na ? context / 2 : context);
  879.         last_maskloc->loc_list = filter_per_context;
  880.        }
  881.       }
  882.     }
  883.     if (filter_out && filter_maskloc)
  884. *filter_out = filter_maskloc;
  885.     return 0;
  886. }
  887. Int2
  888. Blast_MaskTheResidues(Uint1 * buffer, Int4 length, Boolean is_na,
  889.                            ListNode * mask_loc, Boolean reverse, Int4 offset)
  890. {
  891.     SSeqRange *loc = NULL;
  892.     Int2 status = 0;
  893.     Int4 index, start, stop;
  894.     Uint1 mask_letter;
  895.     if (is_na)
  896.         mask_letter = 14;
  897.     else
  898.         mask_letter = 21;
  899.     for (; mask_loc; mask_loc = mask_loc->next) {
  900.         loc = (SSeqRange *) mask_loc->ptr;
  901.         if (reverse) {
  902.             start = length - 1 - loc->right;
  903.             stop = length - 1 - loc->left;
  904.         } else {
  905.             start = loc->left;
  906.             stop = loc->right;
  907.         }
  908.         start -= offset;
  909.         stop -= offset;
  910.         for (index = start; index <= stop; index++)
  911.             buffer[index] = mask_letter;
  912.     }
  913.     return status;
  914. }
  915. Int2 
  916. BlastSetUp_MaskQuery(BLAST_SequenceBlk* query_blk, BlastQueryInfo* query_info, BlastMaskLoc *filter_maskloc, Uint1 program_number)
  917. {
  918.     const Boolean k_is_na = (program_number == blast_type_blastn);
  919.     Int4 context; /* loop variable. */
  920.     Int2 status=0;
  921.     for (context = query_info->first_context;
  922.          context <= query_info->last_context; ++context) {
  923.       
  924.         BlastMaskLoc* filter_maskloc_var = NULL;
  925.         BlastSeqLoc *filter_per_context = NULL;   /* Used to hold combined SeqLoc's */
  926.         Boolean reverse = (k_is_na && ((context & 1) != 0));
  927.         Int4 query_length;
  928.         Int4 context_offset;
  929.         Uint1 *buffer;              /* holds sequence */
  930.         /* For each query, check if forward strand is present */
  931.         if ((query_length = BLAST_GetQueryLength(query_info, context)) < 0)
  932.             continue;
  933.         context_offset = query_info->context_offsets[context];
  934.         buffer = &query_blk->sequence[context_offset];
  935. filter_maskloc_var = filter_maskloc;
  936.         while (filter_maskloc_var)
  937.         {
  938.              if (filter_maskloc_var->index == (k_is_na ? context / 2 : context))
  939.              {
  940. filter_per_context = filter_maskloc_var->loc_list;
  941.                 break;
  942.              }
  943.              filter_maskloc_var = filter_maskloc_var->next;
  944.         }
  945.         if (buffer) {
  946.             if ((status =
  947.                      Blast_MaskTheResidues(buffer, query_length, k_is_na,
  948.                                                 filter_per_context, reverse, 0)))
  949.             {
  950.                     return status;
  951.             }
  952.         }
  953.     }
  954.     return 0;
  955. }