1 /*
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name: netblap3.c
27 *
28 * Author: Tom Madden
29 *
30 * Version Creation Date: 05/8/97
31 *
32 * File Description:
33 * Application Programming Interface (API) for BLAST network server
34 *
35 * RCS Modification History:
36 * $Log: netblap3.c,v $
37 * Revision 1.110 2007/05/07 13:30:08 kans
38 * added casts for Seq-data.gap (SeqDataPtr, SeqGapPtr, ByteStorePtr)
39 *
40 * Revision 1.109 2005/10/12 19:49:46 kans
41 * EntrezSetServer was removed, so commented out here
42 *
43 * Revision 1.108 2005/09/13 18:03:57 madden
44 * Fix so that tweak_parameters cna be in other_options
45 *
46 * Revision 1.107 2005/08/04 15:54:41 kans
47 * local variable defined before ASSERT in s_addTweakToOtherOptions for strict C compliance (CodeWarrior Carbon complained)
48 *
49 * Revision 1.106 2005/08/04 15:40:33 madden
50 * Add static functions s_parseOtherOptions and s_addTweakToOtherOptions to allow composition-based info to be passed
51 *
52 * Revision 1.105 2004/01/27 20:53:12 dondosha
53 * Value of no_traceback megablast option is now Uint1 instead of Boolean
54 *
55 * Revision 1.104 2003/01/13 18:08:26 bealer
56 * - Replace nonstandard snprintf() function with strcpy/strcat/strlen.
57 *
58 * Revision 1.103 2003/01/10 21:45:06 bealer
59 * - Modify to return errors from BLASTGetUidsFromQuery instead of logging them.
60 *
61 * Revision 1.102 2002/10/30 18:54:58 madden
62 * NULL out SeqLoc for lower-case masking
63 *
64 * Revision 1.101 2002/10/29 14:36:53 madden
65 * Fix problem with repeated error messages
66 *
67 * Revision 1.100 2002/10/24 16:41:23 merezhuk
68 * update to the BlastBioseq, will return all Blast-error responses instead off the first one
69 *
70 * Revision 1.99 2002/08/08 20:50:39 madden
71 * Remove SPLIT_BLAST macros
72 *
73 * Revision 1.98 2002/05/23 22:57:03 dondosha
74 * Made GetResponsePtr external
75 *
76 * Revision 1.97 2002/05/15 16:32:51 madden
77 * Make QueryIsProteinFromType extern
78 *
79 * Revision 1.96 2002/05/10 12:56:27 madden
80 * Allow network version of matrix as input
81 *
82 * Revision 1.95 2002/04/24 17:59:03 dondosha
83 * Added handling of parameters for database splitting and megablast with discontiguous words
84 *
85 * Revision 1.94 2002/04/03 16:29:48 dondosha
86 * Added SPLIT_BLAST macro to allow simultaneous use in current and new system
87 *
88 * Revision 1.93 2002/03/01 19:19:45 dondosha
89 * Previous change made in a wrong place
90 *
91 * Revision 1.92 2002/03/01 19:04:24 dondosha
92 * Set window size option to 0 for Web Mega BLAST
93 *
94 * Revision 1.91 2002/02/20 21:45:17 madden
95 * Add protection against truncated posFreq sequence
96 *
97 * Revision 1.90 2001/09/06 20:27:10 dondosha
98 * threshold_first removed from options
99 *
100 * Revision 1.89 2001/08/31 14:31:30 dondosha
101 * Correction to previous change needed for Mac
102 *
103 * Revision 1.88 2001/08/30 17:53:05 dondosha
104 * Fixed memory leak in Blast3GetDbinfo
105 *
106 * Revision 1.87 2001/05/02 19:42:48 egorov
107 * Make the NetBlastGetMatrix() external
108 *
109 * Revision 1.86 2001/04/26 21:55:43 juran
110 * Squelch compiler warnings.
111 *
112 * Revision 1.85 2001/04/02 18:49:13 dondosha
113 * Removed readdb_new_ex call
114 *
115 * Revision 1.84 2001/03/01 17:42:51 madden
116 * Removed unneeded line
117 *
118 * Revision 1.83 2001/03/01 15:16:46 dondosha
119 * Do pass matrix as well as pseudo frequences, if the former is provided
120 *
121 * Revision 1.82 2001/02/16 16:13:08 dondosha
122 * If posFreqs are present, do not copy matrix to and from net matrix
123 *
124 * Revision 1.81 2001/01/19 21:30:09 dondosha
125 * Call readdb...._ex functions to possibly save some time when finding db length
126 *
127 * Revision 1.80 2001/01/19 20:56:46 dondosha
128 * In NetDbinfo2TxDbinfo get database total length information from readdb
129 *
130 * Revision 1.79 2001/01/04 15:54:17 dondosha
131 * Added percent identity to the search parameters
132 *
133 * Revision 1.78 2000/12/19 18:41:37 madden
134 * Calls to BlastSetUserErrorString and BlastDeleteUserErrorString moved to blastool.c
135 *
136 * Revision 1.77 2000/11/16 22:26:31 dondosha
137 * Add endpoint results from Mega BLAST to search response
138 *
139 * Revision 1.76 2000/09/28 16:46:40 dondosha
140 * Changed MegaBlast related code to get a single SeqAlignPtr from server
141 *
142 * Revision 1.75 2000/09/20 22:10:25 madden
143 * Fix memory leaks
144 *
145 * Revision 1.74 2000/09/13 13:47:48 dondosha
146 * Typo fix
147 *
148 * Revision 1.73 2000/09/12 21:55:10 dondosha
149 * Pass the correct scoring matrix to ShowTextAlignFromAnnot
150 *
151 * Revision 1.72 2000/08/28 15:16:51 dondosha
152 * Added functionality to process megablast searches
153 *
154 * Revision 1.71 2000/08/03 20:54:51 shavirin
155 * Fixed some C++ specific errors.
156 *
157 * Revision 1.70 2000/08/03 18:32:27 shavirin
158 * Fixed bug in the function BlastNetMatrixToBlastMatrix()
159 *
160 * Revision 1.69 2000/06/22 18:01:49 shavirin
161 * Added check for 0s passed for required end and required start from
162 * the network.
163 *
164 * Revision 1.68 2000/06/19 19:02:52 dondosha
165 * Pass required_start and required_end between parameters and options - these are from and to positions on query
166 *
167 * Revision 1.67 2000/06/15 20:02:48 egorov
168 * Allow dispatcher == NULL in NetFini. We need
169 * this when call SubmitRequest->ReestablishNetBlast() from an external
170 * program, eg. blastque
171 *
172 * Revision 1.66 2000/06/15 16:22:44 egorov
173 * Make SubmitRequest() external
174 *
175 * Revision 1.65 2000/06/07 17:16:17 shavirin
176 * Added handligng of posFreqs matrix - S&W blastpgp specific.
177 *
178 * Revision 1.64 2000/06/06 14:08:54 madden
179 * Fill in matrix name if NULL, required for ASN.1
180 *
181 * Revision 1.63 2000/05/30 15:08:57 shavirin
182 * Rolled back revision without swaping UIDs from Entrez query.
183 *
184 * Revision 1.60 2000/05/05 18:44:05 shavirin
185 * Added protection against uids== NULL in BLASTGetUidsFromQuery().
186 *
187 * Revision 1.59 2000/05/04 18:09:26 shavirin
188 * Added new function BLASTGetUidsFromQuery().
189 *
190 * Revision 1.58 2000/04/28 18:05:46 shavirin
191 * Added parameter is_rps_blast to Network BLAST ASN.1
192 *
193 * Revision 1.57 2000/04/18 16:30:37 madden
194 * Fix memory leaks
195 *
196 * Revision 1.56 2000/01/20 18:37:13 madden
197 * Add vecscrn.h to includes
198 *
199 * Revision 1.55 2000/01/20 18:33:36 madden
200 * Use VSMakeSeqLoc in place of VSMakeDisplaySeqLoc
201 *
202 * Revision 1.54 2000/01/20 14:35:06 madden
203 * Updated VecScreen calls
204 *
205 * Revision 1.53 1999/12/03 16:43:22 egorov
206 * Add additional mutex in formating, which protects network fetch callbacks
207 * from MT-unsafe operations.
208 *
209 * Revision 1.52 1999/12/02 22:14:27 shavirin
210 * Fixed bug with printing H parameter in the bottom of Blast output.
211 *
212 * Revision 1.51 1999/11/24 21:42:30 vakatov
213 * Fixed for the C++ and/or MSVC DLL compilation
214 *
215 * Revision 1.50 1999/11/16 15:52:55 egorov
216 * Put additional mutex to protect GenericGetService function
217 *
218 * Revision 1.49 1999/11/12 16:35:00 shavirin
219 * Added adjustement of use_best_align parameters in OptionsToParameters
220 * and parameteresTooptions().
221 *
222 * Revision 1.48 1999/11/05 16:59:30 madden
223 * Fix more leaks
224 *
225 * Revision 1.47 1999/11/05 15:30:08 madden
226 * Fix some memory leaks
227 *
228 * Revision 1.46 1999/10/27 15:57:52 madden
229 * Changes for use_real_db_size
230 *
231 * Revision 1.45 1999/10/27 13:00:02 madden
232 * Changes to return-parts
233 *
234 * Revision 1.44 1999/09/22 14:06:26 madden
235 * NULL out gilist to prevent double freeing
236 *
237 * Revision 1.43 1999/08/19 19:37:48 shavirin
238 * Added new functions corresponding to the PHI/PSI Blast.
239 *
240 * Revision 1.41 1999/06/21 20:33:58 madden
241 * Plug some leaks
242 *
243 * Revision 1.40 1999/05/04 19:41:45 madden
244 * done now goes through callback
245 *
246 * Revision 1.39 1999/04/21 20:54:46 madden
247 * Make BlastBioseq non-private
248 *
249 * Revision 1.38 1999/04/20 14:51:35 madden
250 * BlastBioseqNetCore and BlastSeqLocNetCore have return status
251 *
252 * Revision 1.37 1999/04/16 19:05:40 madden
253 * Change done
254 *
255 * Revision 1.36 1999/04/16 15:53:25 madden
256 * Add TraditionalBlastReportExtra function
257 *
258 * Revision 1.35 1999/04/13 14:59:30 madden
259 * Add more options (searchsp, culling, strand)
260 *
261 * Revision 1.34 1999/04/02 16:25:53 madden
262 * Reestablish logic
263 *
264 * Revision 1.33 1999/03/19 21:47:38 madden
265 * Add Blast3GetDbinfo function
266 *
267 * Revision 1.32 1999/03/15 21:56:10 madden
268 * fix for error message that was freed
269 *
270 * Revision 1.31 1999/03/05 15:42:35 madden
271 * Fixed memory leaks
272 *
273 * Revision 1.30 1999/03/05 15:02:43 egorov
274 * Bug fixed. Return NULL if no kablk found in the list of responses in the BlastGetKaParams function.
275 *
276 * Revision 1.29 1999/03/04 17:59:57 egorov
277 * Allow error_returns == NULL on input
278 *
279 * Revision 1.28 1999/03/01 20:55:59 egorov
280 * Fix infinite loop reestablishing connection to blast server (thanx to Sergei Shavirin)
281 *
282 * Revision 1.27 1999/01/12 21:05:58 victorov
283 * server will now report an error if the ni-queue if full
284 *
285 * Revision 1.26 1998/12/09 15:27:05 madden
286 * Add wordsize
287 *
288 * Revision 1.25 1998/11/03 21:46:19 egorov
289 * Add support for entrez-query and org-name
290 *
291 * Revision 1.24 1998/10/26 19:42:57 madden
292 * Check for NULL matrix or filter_string
293 *
294 * Revision 1.23 1998/10/06 18:28:07 egorov
295 * Fix MT problem with dispatcher_lock
296 *
297 * Revision 1.22 1998/09/22 16:12:53 egorov
298 * Use BlastErrorPrintExtra instead of BlastErrorPrint to redirect error messages both to log and to program output file
299 *
300 * Revision 1.21 1998/09/01 20:17:03 madden
301 * Fixed uninitialzed problem in BlastNetBioseqFetchDisable, changed prototype
302 *
303 * Revision 1.20 1998/08/14 17:43:26 madden
304 * non-NULL f_order and g_order in formatting
305 *
306 * Revision 1.19 1998/08/14 16:04:48 egorov
307 * Create TLS for BlastNetFetchStruct to make it multi-thread safe. Using some of global variables is commented out
308 *
309 * Revision 1.18 1998/07/28 16:57:51 egorov
310 * Make StringSave() for some CharPtr in assignments to save memory and avoid memory crashes
311 *
312 * Revision 1.16 1998/06/08 21:58:36 madden
313 * Check for NULL Bioseq in FetchFunc, print out Error message if NULL
314 *
315 * Revision 1.15 1998/05/08 21:40:15 vakatov
316 * fixed a tiny type cast(one more *)
317 *
318 * Revision 1.14 1998/05/08 20:56:22 madden
319 * Fix PC compile warnings, rename callback
320 *
321 * Revision 1.13 1998/05/08 01:08:09 madden
322 * Removed unused variables
323 *
324 * Revision 1.12 1998/04/24 18:35:50 madden
325 * Do not send Seq-descr to server
326 *
327 * Revision 1.11 1998/04/24 16:01:41 egorov
328 * Remove BlastErrorPrint from BlastSeqLocNetCore
329 *
330 * Revision 1.10 1998/04/23 14:19:31 egorov
331 * Allow other_returns in BlastSeqLocNet to be NULL
332 *
333 * Revision 1.9 1998/04/22 18:10:06 egorov
334 * Add support for SeqLoc to blastcl3
335 *
336 * Revision 1.8 1998/04/17 19:24:00 madden
337 * Transmit expect value, hitlist_size, and genetic codes to server
338 *
339 * Revision 1.7 1998/04/16 19:35:31 madden
340 * Added Int4Ptr arg to TraditionalBlastReport specifying the numbers of hits
341 *
342 * Revision 1.6 1998/04/09 16:16:33 madden
343 * Added BlastNetFetchCompare function
344 *
345 * Revision 1.5 1997/12/16 19:10:51 madden
346 * Fixed Codecenter errors
347 *
348 * Revision 1.4 1997/12/01 22:05:51 madden
349 * Changed call to BlastValidateOptionsEx
350 *
351 * Revision 1.3 1997/11/28 18:17:39 madden
352 * Changes for multiple db searches
353 *
354 * Revision 1.1 1997/10/08 19:27:20 madden
355 * Network support for gapped blast
356 *
357 */
358
359 #include <ncbinet.h>
360 #include <ncbithr.h>
361 #include <txalign.h>
362 #include <jzmisc.h>
363 #include <blastpat.h>
364 #include <netblap3.h>
365 #include <vecscrn.h>
366 #include <ent2api.h>
367
368 #define BLAST_SERVER_RETRIES 2
369
370 #define BLASTNET_SHORT_BUFLEN 25
371 #define BLASTNET_BUF_SIZE 255
372 #define BLASTNET_INIT 0
373 #define BLASTNET_READY 1
374 #define BLASTNET_DISABLE 2
375
376 typedef struct _blastnetbioseqfetch {
377 Uint1 BlastNetFetchState;
378 CharPtr dbname; /* Name of the database. */
379 BlastNet3Hptr bl3hp; /* Network connection. */
380 Uint2 ctr;
381 Boolean is_prot; /* Is it a protein or not. */
382 } BlastNetFetchStruct, PNTR BlastNetFetchStructPtr;
383
384 static TNlmTls blastnetfetch_tls = NULL;
385
386 static Int2 num_attached = 0;
387 static NI_DispatcherPtr dispatcher = NULL;
388 /* Mutex for dispatcher. */
389 TNlmMutex dispatcher_lock = NULL;
390
391 static TNlmMutex formating_mutex; /* Mutex to regulate formating in TraditionalBlastReport */
392
393 static Boolean BlastInitEx PROTO((CharPtr program_name, BlastNet3Hptr bl3hp, BlastResponsePtr PNTR respp, Boolean reesatblish));
394
395 static Boolean RealSubmitRequest PROTO((BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback));
396
397 /* error_occurred and old_error_hook should not be accessed directly.
398 The functions BlastSetErrorStatus, BlastGetErrorStatus, and BlastSetErrorHook
399 will change these variables. */
400 static Boolean error_occurred;
401 static ErrHookProc old_error_hook;
402
403 /*
404 The next five functions set an error hook and detect
405 whether an error occurred (i.e., contact with the
406 server was lost).
407
408 BlastSetErrorHook should be called first, the function
409 BlastErrHookProc is set as the "handler"; BlastSetErrorStatus
410 should then be called to set the error status to FALSE;
411 BlastGetErrorStatus should be called to determine if an error
412 occurred; and then BlastResetOldHook should be called to restore
413 the original hook, in case BLAST is called from within another
414 application that uses this (original) hook.
415
416 BlastSetErrorStatus is also called, to set the error status
417 sometimes if a BlastAsnRead fails. This is taken as evidence
418 of an error, even if none is reported.
419 */
420
421 static int LIBCALLBACK
BlastErrHookProc(const ErrDesc * err)422 BlastErrHookProc(const ErrDesc *err)
423
424 {
425 error_occurred = TRUE;
426 return 1;
427 }
428
429 static void
BlastSetErrorHook(void)430 BlastSetErrorHook(void)
431
432 {
433 old_error_hook = Nlm_ErrSetHandler(BlastErrHookProc);
434 return;
435 }
436
437 static void
BlastSetErrorStatus(Boolean status)438 BlastSetErrorStatus(Boolean status)
439
440 {
441 error_occurred = status;
442 }
443
444 static Boolean
BlastGetErrorStatus(void)445 BlastGetErrorStatus(void)
446
447 {
448 return error_occurred;
449 }
450
451 static void
BlastResetOldHook(void)452 BlastResetOldHook(void)
453
454 {
455 Nlm_ErrSetHandler(old_error_hook);
456 return;
457 }
458
459 /*****************************************************************************
460 *
461 * NetInit ()
462 *
463 *****************************************************************************/
464
NetInit(void)465 static Boolean NetInit(void)
466 {
467 Boolean retval = FALSE;
468
469 NlmMutexLockEx(&dispatcher_lock);
470
471 if(num_attached++ > 0)
472 {
473 NlmMutexUnlock(dispatcher_lock);
474 return TRUE;
475 }
476
477 dispatcher = NI_GenericInit(NULL, NULL, TRUE, NULL, 0);
478
479 if (dispatcher)
480 retval = TRUE;
481
482 NlmMutexUnlock(dispatcher_lock);
483
484 return retval;
485 }
486
487
488 /*****************************************************************************
489 *
490 * ForceNetInit ()
491 *
492 *****************************************************************************/
493
ForceNetInit(void)494 static Boolean ForceNetInit(void)
495 {
496 Boolean retval;
497
498 NlmMutexLockEx(&dispatcher_lock);
499
500 num_attached = 0; /* force re-attempt to contact dispatcher */
501 retval = NetInit();
502
503 NlmMutexUnlock(dispatcher_lock);
504
505 return retval;
506 }
507
508 /*****************************************************************************
509 *
510 * NetFini ()
511
512 BlastNet3Hptr bl3hp: was returned by BlastInit
513 Boolean deallocate: should BlastNet3Hptr be deallocated (or will it be reused for
514 a reconnection).
515 *
516 *****************************************************************************/
517
NetFini(BlastNet3Hptr bl3hp,Boolean deallocate)518 static Boolean NetFini(BlastNet3Hptr bl3hp, Boolean deallocate)
519 {
520 NlmMutexLockEx(&dispatcher_lock);
521
522 if (num_attached > 0)
523 num_attached--;
524
525 if (bl3hp != NULL)
526 {
527 NI_ServiceDisconnect(bl3hp->svcp);
528 if (deallocate)
529 bl3hp = (BlastNet3Hptr) MemFree(bl3hp);
530
531 if (num_attached == 0)
532 { /* Disconnect if last service to dispatcher. */
533 if (dispatcher)
534 NI_EndServices (dispatcher);
535 dispatcher = NULL;
536 }
537 }
538
539 NlmMutexUnlock(dispatcher_lock);
540
541 return TRUE;
542 }
543
544
545 /*****************************************************************************
546 *
547 * GenericReestablishNet ()
548 *
549 *****************************************************************************/
550
GenericReestablishNet(CharPtr svcName,Boolean showErrs,BlastNet3Hptr bl3hp)551 static Boolean GenericReestablishNet(CharPtr svcName, Boolean showErrs, BlastNet3Hptr bl3hp)
552 {
553 Handle mon = NULL;
554 Boolean retval;
555 CharPtr buf;
556
557 buf = (CharPtr) MemNew(2 * StrLen(svcName) + 60);
558
559 if (showErrs) {
560 sprintf (buf, "Re-establishing %s Service", svcName);
561 mon = MonitorStrNew(buf, 40);
562 sprintf (buf, "Requesting %s service", svcName);
563 MonitorStrValue((MonitorPtr) mon, buf);
564 }
565
566 NetFini(bl3hp, FALSE);
567
568 retval = BlastInitEx(NULL, bl3hp, NULL, FALSE);
569
570 if (!retval)
571 {
572 sprintf (buf, "%s get failed; re-contacting dispatcher", svcName);
573 MonitorStrValue((MonitorPtr) mon, buf);
574 retval = FALSE;
575 if (ForceNetInit())
576 { /* successfully established contact w/dispatcher */
577 sprintf (buf, "%s get failed; re-requesting %s service",
578 svcName, svcName);
579 MonitorStrValue((MonitorPtr) mon, buf);
580 retval = BlastInitEx(NULL, bl3hp, NULL, FALSE);
581 }
582 else {
583 ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
584 if (showErrs) {
585 ErrShow();
586 }
587 }
588 }
589
590 MonitorFree((MonitorPtr) mon);
591
592 if (! retval )
593 {
594 sprintf (buf, "Unable to re-establish %s service", svcName);
595 ErrPost(CTX_UNKNOWN, 1, buf);
596 if (showErrs) {
597 ErrShow();
598 }
599 }
600
601 MemFree(buf);
602 return retval;
603 }
604
605 /*****************************************************************************
606 *
607 * ReestablishNetBlast ()
608 *
609 *****************************************************************************/
610
ReestablishNetBlast(BlastNet3Hptr bl3hp)611 static Boolean ReestablishNetBlast(BlastNet3Hptr bl3hp)
612 {
613 return GenericReestablishNet("NETBLAST", TRUE, bl3hp);
614 }
615
616 /*****************************************************************************
617 *
618 * BlastInit ()
619 *
620 *****************************************************************************/
621
BlastInitEx(CharPtr program_name,BlastNet3Hptr bl3hp,BlastResponsePtr PNTR respp,Boolean reestablish)622 static Boolean BlastInitEx (CharPtr program_name, BlastNet3Hptr bl3hp, BlastResponsePtr PNTR respp, Boolean reestablish)
623
624 {
625 BlastRequestPtr request;
626 BlastResponsePtr response;
627 NI_HandPtr svcp = NULL;
628
629 if (bl3hp == NULL)
630 {
631 return FALSE;
632 }
633
634
635 if (!NetInit())
636 {
637 ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
638 return FALSE;
639 }
640
641 NlmMutexLockEx(&dispatcher_lock);
642 svcp = NI_GenericGetService(dispatcher, NULL, "NETBLAST", "blast3", FALSE);
643 NlmMutexUnlock(dispatcher_lock);
644
645 if (svcp == NULL)
646 {
647 ErrPostEx(SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s)", ni_errlist[ni_errno], ni_errtext);
648 BlastFini(NULL);
649 return FALSE;
650 }
651
652 bl3hp->svcp = svcp;
653
654
655 request = ValNodeNew(NULL);
656 request->choice = BlastRequest_init;
657
658 SubmitRequest(bl3hp, request, &response, NULL, reestablish);
659 BlastRequestFree (request);
660
661 if (respp)
662 *respp = response;
663 else
664 BlastResponseFree (response);
665
666 return TRUE;
667
668 }
669
670 /*****************************************************************************
671 *
672 * BlastInit ()
673 *
674 *****************************************************************************/
675
676 NLM_EXTERN Boolean LIBCALL
BlastInit(CharPtr program_name,BlastNet3Hptr PNTR bl3hpp,BlastResponsePtr PNTR respp)677 BlastInit (CharPtr program_name, BlastNet3Hptr PNTR bl3hpp, BlastResponsePtr PNTR respp)
678
679 {
680 BlastNet3Hptr bl3hp_pri;
681
682 if (bl3hpp == NULL)
683 {
684 ErrPostEx(SEV_ERROR, 0, 0, "BlastInitMT, BlastNet3Hptr PNTR is NULL");
685 return FALSE;
686 }
687
688 bl3hp_pri = (BlastNet3Hptr) MemNew(sizeof(BlastNet3Hptr));
689 if (bl3hp_pri == NULL)
690 return FALSE;
691
692 *bl3hpp = bl3hp_pri;
693
694 return BlastInitEx(program_name, bl3hp_pri, respp, TRUE);
695 }
696
697 /*****************************************************************************
698 *
699 * BlastFini ()
700 *
701 *****************************************************************************/
702
s_BlastFini(BlastNet3Hptr bl3hptr)703 static Boolean s_BlastFini (BlastNet3Hptr bl3hptr)
704
705 {
706 Boolean retval = TRUE;
707 BlastRequestPtr request;
708 BlastResponsePtr response;
709
710
711 if (bl3hptr == NULL || bl3hptr->svcp == NULL)
712 return FALSE;
713
714 request = ValNodeNew(NULL);
715 request->choice = BlastRequest_fini;
716 SubmitRequest(bl3hptr, request, &response, NULL, FALSE);
717 BlastRequestFree (request);
718 BlastResponseFree (response);
719
720 NetFini(bl3hptr, TRUE);
721 return retval;
722 }
723
724 /* the only thing done here is to suppress errors */
725
726 NLM_EXTERN Boolean LIBCALL
BlastFini(BlastNet3Hptr bl3hptr)727 BlastFini (BlastNet3Hptr bl3hptr)
728
729 {
730 short erract;
731 ErrDesc err;
732 Boolean retval;
733
734 ErrGetOpts(&erract, NULL);
735 ErrSetOpts(ERR_IGNORE, 0);
736 ErrFetch(&err);
737
738 retval = s_BlastFini(bl3hptr);
739
740 ErrSetOpts(erract, 0);
741 ErrFetch(&err);
742
743 return retval;
744 }
745
746 void static
s_addTweakToOtherOptions(Uint1 tweak_parameters,BlastParametersPtr parameters)747 s_addTweakToOtherOptions(Uint1 tweak_parameters, BlastParametersPtr parameters)
748 {
749 const Int4 kBuffSize=128;
750 ASSERT(parameters);
751
752 if (tweak_parameters > 0)
753 {
754 char* other_options = NULL;
755 Int4 len = 0;
756 if (parameters->other_options && StringLen(parameters->other_options) > 0)
757 {
758 len = 1 + StringLen(parameters->other_options);
759 other_options = MemNew((len+kBuffSize)*sizeof(char));
760 StrCpy(other_options, parameters->other_options);
761 MemFree(parameters->other_options);
762 }
763 else
764 {
765 other_options = MemNew((kBuffSize)*sizeof(char));
766 }
767 sprintf(other_options+len, "-t%ld", (long) tweak_parameters);
768 parameters->other_options = other_options;
769 }
770
771 return;
772 }
773
774 NLM_EXTERN BlastParametersPtr LIBCALL
BlastOptionsToParameters(BLAST_OptionsBlkPtr options)775 BlastOptionsToParameters (BLAST_OptionsBlkPtr options)
776
777 {
778 BlastParametersPtr parameters;
779
780
781 if (options == NULL)
782 {
783 return NULL;
784 }
785
786 parameters = BlastParametersNew();
787 parameters->gapped_alignment = options->gapped_calculation;
788 if (options->cutoff_s == 0)
789 {
790 parameters->Cutoff_cutoff = ValNodeAddFloat(NULL, Cutoff_cutoff_evalue, options->expect_value);
791 }
792 else
793 {
794 parameters->Cutoff_cutoff = ValNodeAddInt(NULL, Cutoff_cutoff_score, options->cutoff_s);
795 }
796 if (options->cutoff_s2 == 0)
797 {
798 parameters->Cutoff2_cutoff2 = ValNodeAddFloat(NULL, Cutoff2_cutoff2_evalue, options->e2);
799 }
800 else
801 {
802 parameters->Cutoff2_cutoff2 = ValNodeAddInt(NULL, Cutoff2_cutoff2_score, options->cutoff_s2);
803 }
804 parameters->hitlist_size = options->hitlist_size;
805 parameters->first_threshold = options->threshold_second;
806 parameters->second_threshold = options->threshold_second;
807 parameters->nucl_penalty = options->penalty;
808 parameters->nucl_reward = options->reward;
809 parameters->gap_open = options->gap_open;
810 parameters->gap_extend = options->gap_extend;
811 parameters->genetic_code = options->genetic_code;
812 parameters->db_genetic_code = options->db_genetic_code;
813 parameters->low_complexity_filtering = options->filter;
814 parameters->ethresh = options->ethresh;
815 parameters->max_num_passes = options->maxNumPasses;
816 parameters->pseudo_count_const = options->pseudoCountConst;
817
818 parameters->gifile = StringSave(options->gifile);
819 parameters->gilist = options->gilist;
820 parameters->matrix = StringSave(options->matrix);
821 parameters->filter_string = StringSave(options->filter_string);
822 parameters->entrez_query = StringSave(options->entrez_query);
823 parameters->word_size = options->wordsize;
824 parameters->db_length = options->db_length;
825 parameters->searchsp_eff = options->searchsp_eff;
826 parameters->hsp_range_max = options->hsp_range_max;
827 parameters->block_width = options->block_width;
828 parameters->perform_culling = options->perform_culling;
829 parameters->strand_option = options->strand_option;
830
831 parameters->phi_pattern = StringSave(options->phi_pattern);
832 parameters->use_real_db_size = options->use_real_db_size;
833 #if 0
834 parameters->db_dir_prefix = StringSave(options->db_dir_prefix);
835 #endif
836 parameters->use_best_align = options->use_best_align;
837
838 if(options->required_start != 0)
839 parameters->required_start = options->required_start;
840
841 if(options->required_end != 0)
842 parameters->required_end = options->required_end;
843
844 parameters->is_rps_blast = options->is_rps_blast;
845
846 parameters->tweak_parameters = options->tweak_parameters;
847 if (options->tweak_parameters > 0)
848 s_addTweakToOtherOptions(options->tweak_parameters, parameters);
849
850 parameters->smith_waterman = options->smith_waterman;
851 parameters->is_megablast = options->is_megablast_search;
852 parameters->query_lcase_mask = (ValNodePtr) options->query_lcase_mask;
853 parameters->endpoint_results = (Boolean) options->no_traceback;
854 parameters->percent_identity = (FloatHi) options->perc_identity;
855 parameters->first_db_seq = options->first_db_seq;
856 parameters->final_db_seq = options->final_db_seq;
857 parameters->window_size = options->window_size;
858 parameters->mb_template_length = options->mb_template_length;
859 parameters->mb_disc_type = options->mb_disc_type;
860
861 return parameters;
862 }
863
864 /*
865 Translates the BlastDbinfoPtr into TxDfDbInfoPtr.
866 */
867
868 NLM_EXTERN TxDfDbInfoPtr LIBCALL
NetDbinfo2TxDbinfo(BlastDbinfoPtr net_dbinfo)869 NetDbinfo2TxDbinfo(BlastDbinfoPtr net_dbinfo)
870 {
871 TxDfDbInfoPtr dbinfo=NULL, dbinfo_head;
872
873 dbinfo_head = NULL;
874 while (net_dbinfo)
875 {
876 dbinfo = TxDfDbInfoNew(dbinfo);
877 dbinfo->is_protein = net_dbinfo->is_protein;
878 dbinfo->name = StringSave(net_dbinfo->name);
879 dbinfo->definition = StringSave(net_dbinfo->definition);
880 dbinfo->date = StringSave(net_dbinfo->date);
881 dbinfo->total_length = net_dbinfo->total_length;
882 /* total length in net_dbinfo is Int4, might be incorrect */
883 if (dbinfo->total_length < 0)
884 dbinfo->total_length += sizeof(Int4);
885 dbinfo->number_seqs = net_dbinfo->number_seqs;
886 if (dbinfo_head == NULL)
887 dbinfo_head = dbinfo;
888 net_dbinfo = net_dbinfo->next;
889 }
890
891 return dbinfo_head;
892 }
893
894 NLM_EXTERN BlastNet3BlockPtr LIBCALL
BlastNet3BlockDestruct(BlastNet3BlockPtr blnet)895 BlastNet3BlockDestruct(BlastNet3BlockPtr blnet)
896
897 {
898 BlastResponsePtr next, response;
899
900 if (blnet == NULL)
901 return NULL;
902
903 /* The entire gilist is not copied, so this prevents an error. */
904 if (blnet->parameters)
905 blnet->parameters->gilist = NULL;
906
907 /* The following is not allocated here */
908 blnet->parameters->query_lcase_mask = NULL;
909
910 BlastParametersFree(blnet->parameters);
911 /* individual elements freed elsewhere. */
912 response = blnet->response;
913 while(response)
914 {
915 next = response->next;
916 response->data.ptrvalue = NULL;
917 BlastResponseFree(response);
918 response = next;
919 }
920 MemFree(blnet->dbname);
921 MemFree(blnet);
922
923 return NULL;
924 }
925
926 /*
927 Creates a new BlastNet3BlockNew, used for searching.
928 */
929 NLM_EXTERN BlastNet3BlockPtr LIBCALL
BlastNet3BlockNew(CharPtr program,CharPtr dbname)930 BlastNet3BlockNew(CharPtr program, CharPtr dbname)
931
932 {
933 BlastNet3BlockPtr retval=NULL;
934
935 retval = (BlastNet3BlockPtr) MemNew(sizeof(BlastNet3Block));
936
937 if (retval)
938 {
939 if (StringICmp("blastn", program) == 0)
940 retval->prog_type = Blast_search_program_blastn;
941 else if (StringICmp("blastp", program) == 0)
942 retval->prog_type = Blast_search_program_blastp;
943 else if (StringICmp("blastx", program) == 0)
944 retval->prog_type = Blast_search_program_blastx;
945 else if (StringICmp("tblastn", program) == 0)
946 retval->prog_type = Blast_search_program_tblastn;
947 else if (StringICmp("tblastx", program) == 0)
948 retval->prog_type = Blast_search_program_tblastx;
949 if (dbname)
950 retval->dbname = StringSave(dbname);
951 }
952
953 return retval;
954 }
955
956 NLM_EXTERN Boolean LIBCALL
QueryIsProteinFromType(Uint2 type)957 QueryIsProteinFromType(Uint2 type)
958 {
959 switch (type)
960 {
961 case Blast_search_program_blastn:
962 return FALSE;
963 case Blast_search_program_blastp:
964 return TRUE;
965 case Blast_search_program_blastx:
966 return FALSE;
967 case Blast_search_program_tblastn:
968 return TRUE;
969 case Blast_search_program_tblastx:
970 return FALSE;
971 default:
972 return FALSE;
973 }
974 }
975
GetResponsePtr(BlastResponsePtr response,Nlm_Uint1 choice)976 BlastResponsePtr GetResponsePtr(BlastResponsePtr response, Nlm_Uint1 choice)
977
978 {
979 while (response)
980 {
981 if (response->choice == choice)
982 {
983 break;
984 }
985 response = response->next;
986 }
987
988 return response;
989 }
990
991 NLM_EXTERN BlastDbinfoPtr LIBCALL
BlastRequestDbInfo(BlastNet3Hptr bl3hp,CharPtr database,Boolean is_prot)992 BlastRequestDbInfo (BlastNet3Hptr bl3hp, CharPtr database, Boolean is_prot)
993
994 {
995 BlastRequestPtr request=NULL;
996 BlastResponsePtr response=NULL;
997 BlastDbinfoPtr dbinfo=NULL;
998 BlastDbinfoGetPtr dbinfo_get;
999
1000
1001 dbinfo_get = BlastDbinfoGetNew();
1002 dbinfo_get->name = database;
1003
1004 if (is_prot)
1005 dbinfo_get->type = Blast_dbinfo_get_type_protein;
1006 else
1007 dbinfo_get->type = Blast_dbinfo_get_type_nucleotide;
1008
1009 ValNodeAddPointer(&request, BlastRequest_db_info_specific, dbinfo_get);
1010 SubmitRequest(bl3hp, request, &response, NULL, TRUE);
1011 response = (BlastResponsePtr)
1012 GetResponsePtr(response, BlastResponse_db_info_specific);
1013
1014 if (response)
1015 {
1016 dbinfo = (BlastDbinfoPtr) response->data.ptrvalue;
1017 response->data.ptrvalue = NULL;
1018 BlastResponseFree(response);
1019 }
1020
1021 dbinfo_get->name = NULL; /* Not owned by this function. */
1022 BlastRequestFree(request);
1023
1024 return dbinfo;
1025 }
1026
1027 NLM_EXTERN BlastDbinfoPtr LIBCALL
BlastGetDbInfo(BlastNet3BlockPtr blnet3blkptr)1028 BlastGetDbInfo (BlastNet3BlockPtr blnet3blkptr)
1029
1030 {
1031 BlastResponsePtr response;
1032 BlastDbinfoPtr dbinfo=NULL, dbinfo_head, last;
1033
1034 last = NULL;
1035 dbinfo = NULL;
1036 dbinfo_head = NULL;
1037 response = blnet3blkptr->response;
1038 while (response)
1039 {
1040 response = (BlastResponsePtr)
1041 GetResponsePtr(response, BlastResponse_db_info_specific);
1042 if (response)
1043 {
1044 last = dbinfo;
1045 dbinfo = (BlastDbinfoPtr) response->data.ptrvalue;
1046 if (dbinfo_head == NULL)
1047 dbinfo_head = dbinfo;
1048 if (last)
1049 last->next = dbinfo;
1050 response = response->next;
1051 }
1052 }
1053
1054 return dbinfo_head;
1055 }
1056
1057 BlastMatrixPtr LIBCALL
NetBlastGetMatrix(BlastNet3BlockPtr blnet3blkptr)1058 NetBlastGetMatrix(BlastNet3BlockPtr blnet3blkptr)
1059
1060 {
1061 BlastResponsePtr response;
1062 BlastMatrixPtr matrix=NULL;
1063
1064
1065 response = (BlastResponsePtr)
1066 GetResponsePtr(blnet3blkptr->response, BlastResponse_matrix);
1067
1068 if (response)
1069 matrix = (BlastMatrixPtr) response->data.ptrvalue;
1070
1071 return matrix;
1072 }
1073
1074 NLM_EXTERN CharPtr LIBCALL
BlastGetParameterBuffer(BlastNet3BlockPtr blnet3blkptr)1075 BlastGetParameterBuffer (BlastNet3BlockPtr blnet3blkptr)
1076
1077 {
1078 BlastResponsePtr response;
1079 CharPtr buffer=NULL;
1080
1081 response = (BlastResponsePtr)
1082 GetResponsePtr(blnet3blkptr->response, BlastResponse_parameters);
1083
1084 if (response)
1085 buffer = (CharPtr) response->data.ptrvalue;
1086
1087 return buffer;
1088 }
1089
1090 /*
1091 Find the BlastKABlkPtr of the type (gapped or ungapped) specified.
1092 */
1093 NLM_EXTERN BlastKABlkPtr LIBCALL
BlastGetKaParams(BlastNet3BlockPtr blnet3blkptr,Boolean gapped)1094 BlastGetKaParams (BlastNet3BlockPtr blnet3blkptr, Boolean gapped)
1095
1096 {
1097 BlastResponsePtr response;
1098 BlastKABlkPtr kablk=NULL;
1099
1100
1101 response = blnet3blkptr->response;
1102 while (response)
1103 {
1104 response =(BlastResponsePtr)
1105 GetResponsePtr(response, BlastResponse_kablk);
1106 if (response)
1107 {
1108 kablk = (BlastKABlkPtr) response->data.ptrvalue;
1109 if (kablk->gapped == gapped)
1110 break;
1111 response = response->next;
1112 kablk = NULL;
1113 }
1114 }
1115
1116 return kablk;
1117 }
1118
1119 /*
1120 Converts 'standard' BLAST matrix to network matrix.
1121 */
1122
1123 NLM_EXTERN BlastMatrixPtr LIBCALL
BlastMatrixToBlastNetMatrix(BLAST_MatrixPtr matrix)1124 BlastMatrixToBlastNetMatrix(BLAST_MatrixPtr matrix)
1125
1126 {
1127 BlastMatrixPtr net_matrix;
1128 Int4 index1, index2;
1129 ValNodePtr vnp = NULL, newvnp = NULL;
1130
1131 if (matrix == NULL)
1132 return NULL;
1133
1134 net_matrix = (BlastMatrixPtr) MemNew(sizeof(BlastMatrix));
1135
1136 net_matrix->is_protein = matrix->is_prot;
1137
1138 if (matrix->name)
1139 net_matrix->name = StringSave(matrix->name);
1140 else
1141 net_matrix->name = StringSave("unknown");
1142
1143 net_matrix->row_length = matrix->rows;
1144 net_matrix->column_length = matrix->columns;
1145 net_matrix->karlinK = matrix->karlinK;
1146
1147 if(matrix->posFreqs != NULL) {
1148 for (vnp=NULL,index1 = matrix->rows-1; index1 >= 0; index1--) {
1149 for (index2 = matrix->columns-1; index2 >= 0; index2--) {
1150 newvnp = (ValNodePtr) Nlm_MemNew(sizeof(ValNode));
1151 newvnp->data.realvalue = matrix->posFreqs[index1][index2];
1152 newvnp->next = vnp;
1153 vnp = newvnp;
1154 }
1155 }
1156 net_matrix->posFreqs = vnp;
1157 }
1158 if (matrix->matrix != NULL) {
1159 for (vnp=NULL,index1 = matrix->rows-1; index1 >= 0; index1--) {
1160 for (index2 = matrix->columns-1; index2 >= 0; index2--) {
1161 newvnp = (ValNodePtr) Nlm_MemNew(sizeof(ValNode));
1162 newvnp->data.intvalue = matrix->matrix[index1][index2];
1163 newvnp->next = vnp;
1164 vnp = newvnp;
1165 }
1166 }
1167 net_matrix->scores = vnp;
1168 }
1169 return net_matrix;
1170
1171 }
1172
1173 /*
1174 Coverts the 'network' matrix to a 'tools' matrix.
1175 */
1176 NLM_EXTERN BLAST_MatrixPtr LIBCALL
BlastNetMatrixToBlastMatrix(BlastMatrixPtr net_matrix)1177 BlastNetMatrixToBlastMatrix (BlastMatrixPtr net_matrix)
1178
1179 {
1180 BLAST_MatrixPtr blast_matrix;
1181 Int4 index1, index2;
1182 Int4Ptr PNTR matrix;
1183 Nlm_FloatHi **posFreqs;
1184 ValNodePtr vnp;
1185
1186 if (net_matrix == NULL)
1187 return NULL;
1188
1189 blast_matrix = (BLAST_MatrixPtr) MemNew(sizeof(BLAST_Matrix));
1190
1191 blast_matrix->is_prot = net_matrix->is_protein;
1192 blast_matrix->name = StringSave(net_matrix->name);
1193 blast_matrix->rows = net_matrix->row_length;
1194 blast_matrix->columns = net_matrix->column_length;
1195 blast_matrix->karlinK = net_matrix->karlinK;
1196
1197 if(net_matrix->posFreqs != NULL) {
1198 vnp = net_matrix->posFreqs;
1199 posFreqs = (Nlm_FloatHi **)
1200 MemNew(blast_matrix->rows*sizeof(Nlm_FloatHi *));
1201
1202 for (index1=0; index1<blast_matrix->rows && vnp; index1++) {
1203 posFreqs[index1] = (Nlm_FloatHi *) MemNew(blast_matrix->columns*sizeof(Nlm_FloatHi));
1204 for (index2=0; index2<blast_matrix->columns && vnp; index2++) {
1205 posFreqs[index1][index2] = (Nlm_FloatHi) vnp->data.realvalue;
1206 vnp = vnp->next;
1207 }
1208 }
1209 blast_matrix->posFreqs = posFreqs;
1210
1211 /* Check if matrix was truncated. */
1212 if (index1 != blast_matrix->rows || index2 != blast_matrix->columns)
1213 {
1214 posFreqs = MemFree(posFreqs);
1215 blast_matrix->name = MemFree(blast_matrix->name);
1216 blast_matrix = MemFree(blast_matrix);
1217 return NULL;
1218 }
1219 }
1220
1221 if (net_matrix->scores != NULL) {
1222 vnp = net_matrix->scores;
1223 matrix = (Int4Ptr PNTR) MemNew(blast_matrix->rows*sizeof(Int4Ptr));
1224 for (index1=0; index1<blast_matrix->rows; index1++) {
1225 matrix[index1] = (Int4Ptr) MemNew(blast_matrix->columns*sizeof(Int4));
1226 for (index2=0; index2<blast_matrix->columns; index2++) {
1227 matrix[index1][index2] = (Int4) vnp->data.intvalue;
1228 vnp = vnp->next;
1229 }
1230 }
1231 blast_matrix->matrix = matrix;
1232 }
1233
1234
1235 return blast_matrix;
1236 }
1237
1238 NLM_EXTERN ValNodePtr LIBCALL
BlastGetMaskedLoc(BlastNet3BlockPtr blnet3blkptr)1239 BlastGetMaskedLoc (BlastNet3BlockPtr blnet3blkptr)
1240
1241 {
1242 BlastResponsePtr response;
1243 BlastMaskPtr blast_mask;
1244 ValNodePtr mask_loc=NULL;
1245
1246 response = blnet3blkptr->response;
1247
1248 while (response)
1249 {
1250 response = (BlastResponsePtr)
1251 GetResponsePtr(response, BlastResponse_mask);
1252 if (response)
1253 {
1254 blast_mask = (BlastMaskPtr) response->data.ptrvalue;
1255 /* location is turned over to calling routine to be deallocated. */
1256 ValNodeAddPointer(&mask_loc, blast_mask->frame, blast_mask->location);
1257 blast_mask->location = NULL;
1258 BlastMaskFree(blast_mask);
1259 response = response->next;
1260 }
1261 }
1262
1263 return mask_loc;
1264 }
1265
1266 static BioseqPtr
PrivateBlastGetBioseq(BlastNet3Hptr bl3hptr,CharPtr database,SeqIdPtr sip,Boolean is_prot)1267 PrivateBlastGetBioseq(BlastNet3Hptr bl3hptr, CharPtr database, SeqIdPtr sip, Boolean is_prot)
1268
1269 {
1270 BioseqPtr bsp=NULL;
1271 BlastSeqIdPtr blast_sip;
1272 BlastRequestPtr request = NULL;
1273 BlastResponsePtr response = NULL;
1274
1275 blast_sip = BlastSeqIdNew();
1276 blast_sip->is_protein = is_prot;
1277 blast_sip->database = database;
1278 blast_sip->id = sip;
1279 ValNodeAddPointer(&request, BlastRequest_db_seq_get, blast_sip);
1280 SubmitRequest(bl3hptr, request, &response, NULL, TRUE);
1281
1282 response = (BlastResponsePtr)
1283 GetResponsePtr(response, BlastResponse_db_seq_get);
1284 if (response)
1285 {
1286 bsp = (BioseqPtr) response->data.ptrvalue;
1287 response->data.ptrvalue = NULL;
1288 BlastResponseFree(response);
1289 }
1290
1291 /* These two were not allocated here. */
1292 blast_sip->id = NULL;
1293 blast_sip->database = NULL;
1294 BlastRequestFree(request);
1295
1296 return bsp;
1297 }
1298
1299 NLM_EXTERN BioseqPtr LIBCALL
BlastGetBioseq(BlastNet3BlockPtr blnet3blkptr,SeqIdPtr sip)1300 BlastGetBioseq(BlastNet3BlockPtr blnet3blkptr, SeqIdPtr sip)
1301
1302 {
1303 BioseqPtr bsp;
1304
1305 bsp = PrivateBlastGetBioseq(blnet3blkptr->bl3hptr, blnet3blkptr->dbname, sip, QueryIsProteinFromType(blnet3blkptr->prog_type));
1306
1307 return bsp;
1308 }
1309
1310 /*
1311 Basic functions to submit BLAST runs.
1312
1313 */
1314
1315 NLM_EXTERN SeqAlignPtr LIBCALL
BlastBioseq(BlastNet3BlockPtr blnet3blkptr,ValNodePtr * error_returns,Boolean PNTR status,ValNodePtr * other_returns)1316 BlastBioseq (BlastNet3BlockPtr blnet3blkptr, ValNodePtr *error_returns, Boolean
1317 PNTR status, ValNodePtr *other_returns)
1318
1319 {
1320 BlastRequestPtr request = NULL;
1321 BlastSearchPtr search = NULL;
1322 BlastResponsePtr response = NULL;
1323 ValNodePtr node;
1324 SeqAlignPtr seqalign=NULL;
1325 /* Uint1 err_id; */
1326
1327 #if 0
1328 err_id = BlastSetUserErrorString("netblast:", blnet3blkptr->bsp->id, TRUE);
1329 #endif
1330
1331 search = BlastSearchNew();
1332 search->program = blnet3blkptr->prog_type;
1333 /*
1334 search->query = (struct struct_Bioseq *) blnet3blkptr->bsp;
1335 */
1336 search->query = blnet3blkptr->bsp;
1337 search->database = blnet3blkptr->dbname;
1338 search->parameters = blnet3blkptr->parameters;
1339 search->mask = blnet3blkptr->mask;
1340 if (blnet3blkptr->blast_matrix)
1341 {
1342 search->matrix =
1343 BlastMatrixToBlastNetMatrix(blnet3blkptr->blast_matrix);
1344 }
1345 else
1346 {
1347 search->matrix = blnet3blkptr->net_matrix;
1348 }
1349 search->query_set = blnet3blkptr->bsp_set;
1350
1351 ValNodeAddPointer(&request, BlastRequest_search, search);
1352 *status = SubmitRequest(blnet3blkptr->bl3hptr, request, &response, blnet3blkptr->callback, TRUE);
1353
1354 blnet3blkptr->response = response;
1355 node = (BlastResponsePtr)
1356 GetResponsePtr(response, BlastResponse_alignment);
1357 if (node)
1358 seqalign = (SeqAlignPtr) node->data.ptrvalue;
1359
1360 if (other_returns) {
1361 /* MegaBLAST endpoint returns */
1362 node = (BlastResponsePtr)
1363 GetResponsePtr(response, BlastResponse_mbalign);
1364 if (node) {
1365 ValNodeAddPointer(other_returns, BlastResponse_mbalign,
1366 node->data.ptrvalue);
1367 }
1368 }
1369 if (error_returns)
1370 {
1371 /* return all blast error responses */
1372 node = (BlastResponsePtr)
1373 GetResponsePtr(response, BlastResponse_error);
1374 while (node)
1375 {
1376 ValNodeAddPointer(error_returns, BlastResponse_error, node->data.ptrvalue);
1377 node = node->next;
1378 node = (BlastResponsePtr)
1379 GetResponsePtr(node, BlastResponse_error);
1380 }
1381 }
1382
1383 /* These six are not allocated here. */
1384 search->query = NULL;
1385 search->database = NULL;
1386 search->parameters = NULL;
1387 search->mask = NULL;
1388 search->query_set = NULL;
1389 search->matrix = NULL;
1390 BlastRequestFree(request);
1391 #if 0
1392 BlastDeleteUserErrorString(err_id);
1393 #endif
1394
1395 return seqalign;
1396 }
1397
1398 /*
1399 Functions to submit BLAST runs and get back parts.
1400
1401 */
1402
1403 static BlastPartsPtr
BlastBioseqByParts(BlastNet3BlockPtr blnet3blkptr,ValNodePtr * error_returns,Boolean PNTR status)1404 BlastBioseqByParts (BlastNet3BlockPtr blnet3blkptr, ValNodePtr *error_returns, Boolean PNTR status)
1405
1406 {
1407 BlastRequestPtr request = NULL;
1408 BlastSearchPtr search = NULL;
1409 BlastResponsePtr response = NULL;
1410 ValNodePtr node;
1411 BlastPartsPtr blast_parts=NULL;
1412 /* Uint1 err_id; */
1413
1414 #if 0
1415 err_id = BlastSetUserErrorString("netblast:", blnet3blkptr->bsp->id, TRUE);
1416 #endif
1417
1418 search = BlastSearchNew();
1419 search->program = blnet3blkptr->prog_type;
1420 /*
1421 search->query = (struct struct_Bioseq *) blnet3blkptr->bsp;
1422 */
1423 search->query = blnet3blkptr->bsp;
1424 search->database = blnet3blkptr->dbname;
1425 search->parameters = blnet3blkptr->parameters;
1426 search->mask = blnet3blkptr->mask;
1427 search->matrix = BlastMatrixToBlastNetMatrix(blnet3blkptr->blast_matrix);
1428 search->return_parts = TRUE;
1429 ValNodeAddPointer(&request, BlastRequest_search, search);
1430 *status = SubmitRequest(blnet3blkptr->bl3hptr, request, &response, blnet3blkptr->callback, TRUE);
1431
1432 blnet3blkptr->response = response;
1433 node = (BlastResponsePtr)
1434 GetResponsePtr(response, BlastResponse_parts);
1435 if (node)
1436 blast_parts = (BlastPartsPtr) node->data.ptrvalue;
1437
1438 if (error_returns)
1439 {
1440 node = (BlastResponsePtr)
1441 GetResponsePtr(response, BlastResponse_error);
1442 if (node)
1443 ValNodeAddPointer(error_returns, BlastResponse_error, node->data.ptrvalue);
1444 }
1445
1446 /* These four are not allocated here. */
1447 search->query = NULL;
1448 search->database = NULL;
1449 search->parameters = NULL;
1450 search->mask = NULL;
1451 BlastRequestFree(request);
1452 #if 0
1453 BlastDeleteUserErrorString(err_id);
1454 #endif
1455
1456 return blast_parts;
1457 }
1458
1459 /* ------------ Set os functions to support PHI-Blast ----------- */
1460
1461 static BlastPhialignPtr LIBCALL
SeedBioseq(BlastNet3BlockPtr blnet3blkptr,ValNodePtr * error_returns,Boolean PNTR status,ValNodePtr PNTR vnp_out)1462 SeedBioseq (BlastNet3BlockPtr blnet3blkptr, ValNodePtr *error_returns,
1463 Boolean PNTR status, ValNodePtr PNTR vnp_out)
1464
1465 {
1466 BlastRequestPtr request = NULL;
1467 BlastSearchPtr search = NULL;
1468 BlastResponsePtr response = NULL;
1469 ValNodePtr node, vnp = NULL;
1470 /* Uint1 err_id; */
1471 BlastPhialignPtr bphp = NULL;
1472
1473 search = BlastSearchNew();
1474 search->program = blnet3blkptr->prog_type;
1475 search->query = blnet3blkptr->bsp;
1476 search->database = blnet3blkptr->dbname;
1477 search->parameters = blnet3blkptr->parameters;
1478 search->mask = blnet3blkptr->mask;
1479 search->matrix = BlastMatrixToBlastNetMatrix(blnet3blkptr->blast_matrix);
1480 ValNodeAddPointer(&request, BlastRequest_search, search);
1481 *status = SubmitRequest(blnet3blkptr->bl3hptr, request, &response,
1482 blnet3blkptr->callback, TRUE);
1483
1484 blnet3blkptr->response = response;
1485 node = (BlastResponsePtr)
1486 GetResponsePtr(response, BlastResponse_phialign);
1487 if (node)
1488 bphp = (BlastPhialignPtr) node->data.ptrvalue;
1489
1490 if (error_returns) {
1491 node = (BlastResponsePtr)
1492 GetResponsePtr(response, BlastResponse_error);
1493 if (node)
1494 ValNodeAddPointer(error_returns, BlastResponse_error,
1495 node->data.ptrvalue);
1496 }
1497
1498 /* Now re-creating ValNode from SeqAligns */
1499
1500 while (response) {
1501 if (response->choice == BlastResponse_alignment) {
1502 ValNodeAddPointer(&vnp, BlastResponse_alignment,
1503 response->data.ptrvalue);
1504 }
1505 response = response->next;
1506 }
1507 *vnp_out = vnp;
1508 response = blnet3blkptr->response;
1509
1510 /* These four are not allocated here. */
1511 search->query = NULL;
1512 search->database = NULL;
1513 search->parameters = NULL;
1514 search->mask = NULL;
1515 BlastRequestFree(request);
1516 #if 0
1517 BlastDeleteUserErrorString(err_id);
1518 #endif
1519
1520 return bphp;
1521 }
1522
1523 NLM_EXTERN BlastPhialignPtr LIBCALL
SeedBioseqNetCore(BlastNet3Hptr bl3hp,BioseqPtr bsp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback,BLAST_MatrixPtr blast_matrix,Boolean PNTR ret_status,ValNodePtr PNTR vnp_out)1524 SeedBioseqNetCore(BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program,
1525 CharPtr database, BLAST_OptionsBlkPtr options,
1526 ValNodePtr *other_returns, ValNodePtr *error_returns,
1527 NetProgressCallback callback, BLAST_MatrixPtr blast_matrix,
1528 Boolean PNTR ret_status, ValNodePtr PNTR vnp_out)
1529 {
1530 BlastKABlkPtr ka_blk;
1531 BlastDbinfoPtr dbinfo;
1532 BlastMatrixPtr net_matrix;
1533 BLAST_MatrixPtr matrix;
1534 BlastNet3BlockPtr blnet;
1535 Boolean options_allocated = FALSE;
1536 CharPtr params_buffer;
1537 Int2 status;
1538 TxDfDbInfoPtr txdbinfo;
1539 ValNodePtr descr, mask;
1540
1541 BlastPhialignPtr bphp = NULL;
1542
1543
1544 if (bl3hp == NULL || bsp == NULL || program == NULL || database == NULL)
1545 return NULL;
1546
1547 if (error_returns)
1548 *error_returns = NULL;
1549
1550 if (other_returns)
1551 *other_returns = NULL;
1552
1553 /* If no options, use default. */
1554 if (options == NULL) {
1555 options = BLASTOptionNew(program, FALSE);
1556 options_allocated = TRUE;
1557 }
1558
1559 status = BLASTOptionValidateEx(options, program, error_returns);
1560 if (status != 0) { /* error messages in other_returns? */
1561 return NULL;
1562 }
1563
1564 blnet = BlastNet3BlockNew(program, database);
1565 /*
1566 Remove the Seq-descr as this is not needed for
1567 BLASTing and the title often contains none-ASCII
1568 characters. Keep the pointer and replace.
1569 */
1570 descr = bsp->descr;
1571 bsp->descr = NULL;
1572
1573 blnet->bsp = bsp;
1574 blnet->parameters = BlastOptionsToParameters(options);
1575 if (options_allocated) {
1576 options = BLASTOptionDelete(options);
1577 }
1578
1579 blnet->callback = callback;
1580 blnet->bl3hptr = bl3hp;
1581 blnet->blast_matrix = blast_matrix;
1582
1583 bphp = SeedBioseq(blnet, error_returns, ret_status, vnp_out);
1584
1585 if (other_returns) {
1586 *other_returns = NULL;
1587 mask = BlastGetMaskedLoc(blnet);
1588 if (mask)
1589 ValNodeLink(other_returns, mask);
1590 dbinfo = BlastGetDbInfo(blnet);
1591 txdbinfo = NetDbinfo2TxDbinfo(dbinfo);
1592 ValNodeAddPointer (other_returns, TXDBINFO, txdbinfo);
1593 dbinfo = BlastDbinfoFree(dbinfo);
1594 params_buffer = BlastGetParameterBuffer(blnet);
1595 ValNodeAddPointer(other_returns, TXPARAMETERS, params_buffer);
1596 ka_blk = BlastGetKaParams(blnet, FALSE);
1597 if (ka_blk)
1598 ValNodeAddPointer (other_returns, TXKABLK_NOGAP, ka_blk);
1599 ka_blk = BlastGetKaParams(blnet, TRUE);
1600 if (ka_blk)
1601 ValNodeAddPointer (other_returns, TXKABLK_GAP, ka_blk);
1602 net_matrix = NetBlastGetMatrix(blnet);
1603 matrix = BlastNetMatrixToBlastMatrix(net_matrix);
1604 net_matrix = BlastMatrixFree(net_matrix);
1605 if (matrix)
1606 ValNodeAddPointer (other_returns, TXMATRIX, matrix);
1607 }
1608
1609 blnet = BlastNet3BlockDestruct(blnet);
1610
1611 bsp->descr = descr;
1612
1613 return bphp;
1614 }
1615
1616 /* -------------------------------------------------------------- */
1617
1618 NLM_EXTERN CharPtr LIBCALL
Blast3GetMotd(BlastNet3Hptr bl3hptr)1619 Blast3GetMotd(BlastNet3Hptr bl3hptr)
1620
1621 {
1622 BlastResponsePtr response=NULL;
1623 BlastRequestPtr request=NULL;
1624 CharPtr string;
1625
1626 request = ValNodeNew(NULL);
1627 request->choice = BlastRequest_motd;
1628 SubmitRequest(bl3hptr, request, &response, NULL, TRUE);
1629 BlastRequestFree (request);
1630 if (response == NULL || response->choice != BlastResponse_motd)
1631 return NULL;
1632
1633 string = StringSave((CharPtr) response->data.ptrvalue);
1634
1635 BlastResponseFree(response);
1636
1637 return string;
1638 }
1639
1640 NLM_EXTERN BlastDbinfoPtr LIBCALL
Blast3GetDbinfo(BlastNet3Hptr bl3hptr)1641 Blast3GetDbinfo(BlastNet3Hptr bl3hptr)
1642
1643 {
1644 BlastResponsePtr response=NULL;
1645 BlastRequestPtr request=NULL;
1646 BlastDbinfoPtr dbinfo;
1647
1648 request = ValNodeNew(NULL);
1649 request->choice = BlastRequest_db_info;
1650 SubmitRequest(bl3hptr, request, &response, NULL, TRUE);
1651 BlastRequestFree (request);
1652 if (response == NULL || response->choice != BlastResponse_db_info)
1653 return (BlastDbinfoPtr) BlastResponseFree(response);
1654
1655 dbinfo = (BlastDbinfoPtr) response->data.ptrvalue;
1656 MemFree(response);
1657
1658 return dbinfo;
1659 }
1660
1661 NLM_EXTERN Boolean
SubmitRequest(BlastNet3Hptr bl3hptr,BlastRequestPtr blreqp,BlastResponsePtr PNTR response,NetProgressCallback callback,Boolean reestablish)1662 SubmitRequest(BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback, Boolean reestablish)
1663
1664 {
1665 Boolean status;
1666 Int2 index;
1667
1668 for(index=0; index<BLAST_SERVER_RETRIES; index++)
1669 {
1670
1671 status = RealSubmitRequest(bl3hptr, blreqp, response, callback);
1672
1673 if (status == TRUE)
1674 break;
1675
1676 if (reestablish)
1677 ReestablishNetBlast(bl3hptr);
1678 }
1679
1680 return status;
1681
1682 }
1683
1684 /*
1685 Status returned indicates a (potential) error. if not done, this is an error.
1686 */
1687 #define PRINT_DEBUG_ASN 0
1688 #if PRINT_DEBUG_ASN
1689 static tmpi = 0;
1690 #endif
1691
1692 static Boolean
RealSubmitRequest(BlastNet3Hptr bl3hptr,BlastRequestPtr blreqp,BlastResponsePtr PNTR response,NetProgressCallback callback)1693 RealSubmitRequest(BlastNet3Hptr bl3hptr, BlastRequestPtr blreqp, BlastResponsePtr PNTR response, NetProgressCallback callback)
1694
1695 {
1696 AsnIoPtr asnin, asnout;
1697 Boolean cancel, done;
1698 BlastResponsePtr bllist, blresp, head;
1699 #if PRINT_DEBUG_ASN
1700 AsnIoPtr asnout_test;
1701 Char buf[1024];
1702 #endif
1703
1704 if (bl3hptr == NULL)
1705 return FALSE;
1706
1707 if (response == NULL)
1708 return FALSE;
1709
1710 asnout = bl3hptr->svcp->waip;
1711 asnin = bl3hptr->svcp->raip;
1712
1713 #if PRINT_DEBUG_ASN
1714 sprintf(buf, "request.%d.out", ++tmpi);
1715 asnout_test = AsnIoOpen(buf, "w");
1716 BlastRequestAsnWrite(blreqp, asnout_test, NULL);
1717 #endif
1718
1719 done = BlastRequestAsnWrite(blreqp, asnout, NULL);
1720 if (done == FALSE)
1721 return FALSE;
1722
1723 #if PRINT_DEBUG_ASN
1724 AsnIoReset(asnout_test);
1725 AsnIoClose(asnout_test);
1726 #endif
1727 AsnIoReset(asnout);
1728
1729 head = NULL;
1730 done = FALSE;
1731 while (!done && (blresp = BlastResponseAsnRead(asnin, NULL)) != NULL)
1732 {
1733 switch (blresp->choice)
1734 {
1735 case BlastResponse_done:
1736 done = TRUE;
1737 case BlastResponse_queued:
1738 case BlastResponse_start:
1739 case BlastResponse_progress:
1740 if (callback)
1741 {
1742 if (callback(blresp, &cancel) != TRUE)
1743 {
1744 done = TRUE;
1745 }
1746 }
1747 blresp = BlastResponseFree(blresp);
1748 break;
1749
1750 case BlastResponse_init:
1751 case BlastResponse_motd:
1752 case BlastResponse_fini:
1753 done = TRUE;
1754
1755 default:
1756 if (head == NULL)
1757 {
1758 head = blresp;
1759 bllist = blresp;
1760 }
1761 else
1762 {
1763 bllist->next = blresp;
1764 bllist = bllist->next;
1765 }
1766 break;
1767 }
1768 }
1769 *response = head;
1770 return done;
1771 }
1772
1773
BlastNetFetchCleanup(TNlmTls tls,VoidPtr ptr)1774 static void BlastNetFetchCleanup (TNlmTls tls, VoidPtr ptr)
1775 {
1776 BlastNetFetchStructPtr bnfsp = (BlastNetFetchStructPtr) ptr;
1777
1778 if (bnfsp) {
1779 bnfsp->dbname = (CharPtr) MemFree(bnfsp->dbname);
1780 MemFree(bnfsp);
1781 }
1782 return;
1783 }
1784
1785 /*
1786 Checks the chain of BlastNetFetchStructPtr's for one
1787 which belongs to the calling thread. If none is found,
1788 NULL isreturned; otherwise the BlastNetFetchStructPtr is
1789 returned.
1790 */
1791 static BlastNetFetchStructPtr
BlastNetFindFetchStruct(BlastNet3Hptr bl3hp,CharPtr dbname,Boolean is_na)1792 BlastNetFindFetchStruct(BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na)
1793
1794 {
1795 BlastNetFetchStructPtr bnfsp = NULL;
1796
1797 if (NlmTlsGetValue(blastnetfetch_tls, (VoidPtr *)(&bnfsp)))
1798 {
1799 if (bnfsp == NULL)
1800 {
1801 bnfsp = (BlastNetFetchStructPtr) MemNew(sizeof(BlastNetFetchStruct));
1802 bnfsp->dbname = StringSave(dbname);
1803 bnfsp->is_prot = (is_na == TRUE) ? FALSE : TRUE;
1804 bnfsp->bl3hp = bl3hp;
1805 bnfsp->BlastNetFetchState = BLASTNET_INIT;
1806 NlmTlsSetValue(&blastnetfetch_tls, bnfsp,
1807 BlastNetFetchCleanup);
1808 }
1809 }
1810
1811 return bnfsp;
1812 }
1813
BlastNetInit(BlastNetFetchStructPtr bnfsp)1814 static Boolean BlastNetInit(BlastNetFetchStructPtr bnfsp)
1815
1816 {
1817 return TRUE;
1818
1819 }
1820
1821
1822 /**********************************************************************
1823
1824 Fetches the Bioseq, based on the ordinal number of the
1825 sequence in the database.
1826
1827 ************************************************************************/
1828
BlastNetBioseqFetchFunc(Pointer data)1829 static Int2 LIBCALLBACK BlastNetBioseqFetchFunc(Pointer data)
1830 {
1831 Boolean status;
1832 Char buffer[64];
1833 OMProcControlPtr ompcp;
1834 ObjMgrProcPtr ompp;
1835 OMUserDataPtr omdp;
1836 SeqIdPtr sip, best_id;
1837 BlastNetFetchStructPtr blfsp;
1838 SeqEntryPtr sep;
1839 BioseqPtr bsp, core_bsp;
1840
1841 ompcp = (OMProcControlPtr)data;
1842 ompp = ompcp->proc;
1843
1844 blfsp = BlastNetFindFetchStruct(NULL, NULL, FALSE);
1845
1846 if (blfsp->BlastNetFetchState == BLASTNET_INIT)
1847 {
1848 status = BlastNetInit(blfsp);
1849 if (status == FALSE)
1850 return OM_MSG_RET_OK;
1851 blfsp->BlastNetFetchState = BLASTNET_READY;
1852 }
1853
1854 sip = (SeqIdPtr) (ompcp->input_data);
1855
1856 best_id = SeqIdFindBest(sip, SEQID_GI);
1857
1858 if (best_id == NULL)
1859 {
1860 core_bsp = BioseqFindCore(sip);
1861 if (core_bsp)
1862 best_id = SeqIdFindBest(core_bsp->id, SEQID_GI);
1863 }
1864
1865 if (best_id == NULL)
1866 return OM_MSG_RET_OK;
1867
1868
1869 /* A BioseqPtr is returned by this function. */
1870 bsp = PrivateBlastGetBioseq(blfsp->bl3hp, blfsp->dbname, best_id, blfsp->is_prot);
1871 if (bsp == NULL)
1872 {
1873 SeqIdWrite(best_id, buffer, PRINTID_FASTA_LONG, sizeof(buffer));
1874 ErrPost(CTX_UNKNOWN, 1, "Unable to retrieve %s", buffer);
1875 return OM_MSG_RET_ERROR;
1876 }
1877 sep = SeqEntryNew();
1878 sep->choice = 1;
1879 sep->data.ptrvalue = bsp;
1880 SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
1881 ompcp->output_data = (Pointer)bsp;
1882 ompcp->output_entityID = ObjMgrGetEntityIDForChoice(sep);
1883 omdp = ObjMgrAddUserData(ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
1884
1885 return OM_MSG_RET_DONE;
1886 }
1887
1888 /*
1889 Compare BlastNetFetchStructPtr structures with some traits. TRUE if identical, otherwise
1890 FALSE.
1891 */
1892 static Boolean
BlastNetFetchCompare(BlastNetFetchStructPtr blfsp1,BlastNet3Hptr bl3hp,CharPtr dbname,Boolean is_na)1893 BlastNetFetchCompare (BlastNetFetchStructPtr blfsp1, BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na)
1894
1895 {
1896 if (blfsp1 == NULL)
1897 return FALSE;
1898
1899 if (StringCmp(blfsp1->dbname, dbname) != 0)
1900 return FALSE;
1901 if (blfsp1->is_prot == is_na)
1902 return FALSE;
1903 if (blfsp1->bl3hp != bl3hp)
1904 return FALSE;
1905
1906 return TRUE;
1907 }
1908
1909 /*********************************************************************
1910
1911 Enables the fetching. Initializes needed structures and calls
1912 BlastNetInit.
1913
1914 **********************************************************************/
1915
1916 NLM_EXTERN Boolean LIBCALL
BlastNetBioseqFetchEnable(BlastNet3Hptr bl3hp,CharPtr dbname,Boolean is_na,Boolean now)1917 BlastNetBioseqFetchEnable(BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na, Boolean now)
1918
1919 {
1920 Boolean result;
1921 BlastNetFetchStructPtr blfsp = NULL;
1922 ObjMgrPtr omp;
1923 ObjMgrProcPtr ompp;
1924
1925 /* check if already enabled ***/
1926
1927 omp = ObjMgrGet();
1928 ompp = ObjMgrProcFind(omp, 0, "BlastNetBioseqFetch", OMPROC_FETCH);
1929 if (ompp != NULL) /* already initialized */
1930 {
1931 blfsp = BlastNetFindFetchStruct(bl3hp, dbname, is_na);
1932 if (BlastNetFetchCompare(blfsp, bl3hp, dbname, is_na) == FALSE)
1933 {
1934 blfsp->dbname = (CharPtr) MemFree(blfsp->dbname);
1935 blfsp->dbname = StringSave(dbname);
1936 blfsp->is_prot = (is_na == TRUE) ? FALSE : TRUE;
1937 blfsp->bl3hp = bl3hp;
1938
1939 }
1940 }
1941 else
1942 {
1943 blfsp = BlastNetFindFetchStruct(bl3hp, dbname, is_na);
1944
1945 ObjMgrProcLoad(OMPROC_FETCH, "BlastNetBioseqFetch",
1946 "BlastNetBioseqFetch", OBJ_SEQID, 0,OBJ_BIOSEQ,0,
1947 (Pointer)blfsp, BlastNetBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
1948
1949 blfsp->BlastNetFetchState = BLASTNET_INIT;
1950 }
1951
1952 blfsp->ctr++; /* count number of enables */
1953
1954 if (blfsp->BlastNetFetchState == BLASTNET_READY)
1955 {
1956 return TRUE;
1957 }
1958
1959 if (now)
1960 {
1961 result = BlastNetInit(blfsp);
1962 if (! result)
1963 {
1964 return result;
1965 }
1966 blfsp->BlastNetFetchState = BLASTNET_READY;
1967 }
1968 else
1969 {
1970 blfsp->BlastNetFetchState = BLASTNET_INIT;
1971 }
1972
1973 return TRUE;
1974 }
1975
1976 /*****************************************************************************
1977 *
1978 * BlastNetBioseqFetchDisable()
1979 *
1980 * Calls readdb_destruct if necessary to deallocate resources.
1981 *
1982 *****************************************************************************/
BlastNetBioseqFetchDisable(BlastNet3Hptr bl3hp,CharPtr dbname,Boolean is_na)1983 NLM_EXTERN void LIBCALL BlastNetBioseqFetchDisable(BlastNet3Hptr bl3hp, CharPtr dbname, Boolean is_na)
1984 {
1985 ObjMgrPtr omp;
1986 ObjMgrProcPtr ompp;
1987 BlastNetFetchStructPtr blfsp;
1988
1989 omp = ObjMgrGet();
1990 ompp = ObjMgrProcFind(omp, 0, "BlastNetBioseqFetch", OMPROC_FETCH);
1991 if (ompp == NULL) /* not initialized */
1992 return;
1993
1994 blfsp = BlastNetFindFetchStruct(bl3hp, dbname, is_na);
1995 if (! blfsp->ctr) /* no enables active */
1996 return;
1997
1998 blfsp->ctr--;
1999 if (blfsp->ctr) /* connection still pending */
2000 return;
2001
2002 if (blfsp->BlastNetFetchState == BLASTNET_READY)
2003 {
2004 blfsp->BlastNetFetchState = BLASTNET_DISABLE; /* not active */
2005 }
2006
2007 return;
2008 }
2009
2010 /*
2011 Runs a BLAST request and returns a SeqAlignPtr for formatting.
2012 Note that the network connection must be established beforehand
2013 (i.e., BlastNet3BlockPtr blnet should be initialized).
2014 */
2015 NLM_EXTERN SeqAlignPtr LIBCALL
BlastBioseqNet(BlastNet3Hptr bl3hp,BioseqPtr bsp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback)2016 BlastBioseqNet(BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback)
2017
2018 {
2019 Boolean status;
2020
2021 return BlastBioseqNetCore(bl3hp, bsp, program, database, options, other_returns, error_returns, callback, NULL, &status);
2022 }
2023
2024 NLM_EXTERN SeqAlignPtr LIBCALL
BlastSeqLocNet(BlastNet3Hptr bl3hp,SeqLocPtr slp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback)2025 BlastSeqLocNet(BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback)
2026
2027 {
2028 Boolean status;
2029
2030 return BlastSeqLocNetCore(bl3hp, slp, program, database, options, other_returns, error_returns, callback, NULL, &status);
2031 }
2032
2033 NLM_EXTERN SeqAlignPtr LIBCALL
MegaBlastSeqLocNetCore(BlastNet3Hptr bl3hp,SeqLocPtr slp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback,Boolean PNTR ret_status)2034 MegaBlastSeqLocNetCore(BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, Boolean PNTR ret_status)
2035 {
2036 BlastKABlkPtr ka_blk;
2037 BlastDbinfoPtr dbinfo;
2038 BlastNet3BlockPtr blnet;
2039 Boolean options_allocated = FALSE;
2040 CharPtr params_buffer;
2041 BlastMatrixPtr net_matrix;
2042 BLAST_MatrixPtr matrix;
2043 Int2 status;
2044 SeqAlignPtr seqalign = NULL;
2045 TxDfDbInfoPtr txdbinfo;
2046 ValNodePtr mask;
2047 SeqEntryPtr sep;
2048 BioseqPtr bsp;
2049 Uint2 entityID = 0;
2050
2051 if (bl3hp == NULL || slp == NULL || program == NULL || database == NULL)
2052 return NULL;
2053
2054 if (error_returns)
2055 *error_returns = NULL;
2056
2057 if (other_returns)
2058 *other_returns = NULL;
2059
2060 /* If no options, use default. */
2061 if (options == NULL)
2062 {
2063 options = BLASTOptionNew(program, FALSE);
2064 options_allocated = TRUE;
2065 }
2066
2067 status = BLASTOptionValidateEx(options, program, error_returns);
2068 if (status != 0)
2069 { /* error messages in other_returns? */
2070 return NULL;
2071 }
2072
2073 blnet = BlastNet3BlockNew(program, database);
2074
2075 blnet->bsp_set = BioseqSetNew();
2076 sep = NULL;
2077 for (; slp; slp = slp->next) {
2078 bsp = BioseqLockById(SeqLocId(slp));
2079 ValNodeAddPointer(&sep, 1, bsp);
2080 SeqMgrSeqEntry(OBJ_BIOSEQ, (Pointer)bsp, sep);
2081 BioseqUnlock(bsp);
2082 }
2083
2084 ((BioseqSetPtr)blnet->bsp_set)->seq_set = sep;
2085 entityID = ObjMgrRegister(OBJ_SEQENTRY, (Pointer)sep);
2086 blnet->bsp = (BioseqPtr)sep->data.ptrvalue;
2087 blnet->parameters = BlastOptionsToParameters(options);
2088 if (options_allocated)
2089 {
2090 options = BLASTOptionDelete(options);
2091 }
2092
2093 blnet->callback = callback;
2094 blnet->bl3hptr = bl3hp;
2095
2096 seqalign = BlastBioseq(blnet, error_returns, ret_status, other_returns);
2097
2098 /* BlastBioseq saves the MegaBLAST endpoint alignments in error_returns
2099 since there is nowhere else to save them */
2100
2101
2102 if (other_returns)
2103 {
2104 mask = BlastGetMaskedLoc(blnet);
2105 if (mask)
2106 ValNodeLink(other_returns, mask);
2107 dbinfo = BlastGetDbInfo(blnet);
2108 txdbinfo = NetDbinfo2TxDbinfo(dbinfo);
2109 ValNodeAddPointer (other_returns, TXDBINFO, txdbinfo);
2110 dbinfo = BlastDbinfoFree(dbinfo);
2111 params_buffer = BlastGetParameterBuffer(blnet);
2112 ValNodeAddPointer(other_returns, TXPARAMETERS, params_buffer);
2113 ka_blk = BlastGetKaParams(blnet, FALSE);
2114 if (ka_blk)
2115 ValNodeAddPointer (other_returns, TXKABLK_NOGAP, ka_blk);
2116 ka_blk = BlastGetKaParams(blnet, TRUE);
2117 if (ka_blk)
2118 ValNodeAddPointer (other_returns, TXKABLK_GAP, ka_blk);
2119 net_matrix = NetBlastGetMatrix(blnet);
2120 matrix = BlastNetMatrixToBlastMatrix(net_matrix);
2121 net_matrix = BlastMatrixFree(net_matrix);
2122 if (matrix)
2123 ValNodeAddPointer (other_returns, TXMATRIX, matrix);
2124 }
2125
2126 blnet = BlastNet3BlockDestruct(blnet);
2127
2128 return seqalign;
2129 }
2130
2131 NLM_EXTERN SeqAlignPtr LIBCALL
BlastBioseqNetCore(BlastNet3Hptr bl3hp,BioseqPtr bsp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback,BLAST_MatrixPtr blast_matrix,Boolean PNTR ret_status)2132 BlastBioseqNetCore(BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix, Boolean PNTR ret_status)
2133
2134 {
2135 BlastKABlkPtr ka_blk;
2136 BlastDbinfoPtr dbinfo;
2137 BlastMatrixPtr net_matrix;
2138 BLAST_MatrixPtr matrix;
2139 BlastNet3BlockPtr blnet;
2140 Boolean options_allocated = FALSE;
2141 CharPtr params_buffer=NULL;
2142 Int2 status;
2143 SeqAlignPtr seqalign = NULL;
2144 TxDfDbInfoPtr txdbinfo;
2145 ValNodePtr descr, mask;
2146
2147 if (bl3hp == NULL || bsp == NULL || program == NULL || database == NULL)
2148 return NULL;
2149
2150 if (error_returns)
2151 *error_returns = NULL;
2152
2153 if (other_returns)
2154 *other_returns = NULL;
2155
2156 /* If no options, use default. */
2157 if (options == NULL)
2158 {
2159 options = BLASTOptionNew(program, FALSE);
2160 options_allocated = TRUE;
2161 }
2162
2163 status = BLASTOptionValidateEx(options, program, error_returns);
2164 if (status != 0)
2165 { /* error messages in other_returns? */
2166 return NULL;
2167 }
2168
2169 blnet = BlastNet3BlockNew(program, database);
2170 /*
2171 Remove the Seq-descr as this is not needed for
2172 BLASTing and the title often contains none-ASCII
2173 characters. Keep the pointer and replace.
2174 */
2175 descr = bsp->descr;
2176 bsp->descr = NULL;
2177
2178 blnet->bsp = bsp;
2179 blnet->parameters = BlastOptionsToParameters(options);
2180 if (options_allocated)
2181 {
2182 options = BLASTOptionDelete(options);
2183 }
2184
2185 blnet->callback = callback;
2186 blnet->bl3hptr = bl3hp;
2187 blnet->blast_matrix = blast_matrix;
2188
2189 seqalign = BlastBioseq(blnet, error_returns, ret_status, NULL);
2190 dbinfo = BlastGetDbInfo(blnet);
2191 net_matrix = NetBlastGetMatrix(blnet);
2192 params_buffer = BlastGetParameterBuffer(blnet);
2193 if (other_returns)
2194 {
2195 *other_returns = NULL;
2196 mask = BlastGetMaskedLoc(blnet);
2197 if (mask)
2198 ValNodeLink(other_returns, mask);
2199 txdbinfo = NetDbinfo2TxDbinfo(dbinfo);
2200 ValNodeAddPointer (other_returns, TXDBINFO, txdbinfo);
2201 ValNodeAddPointer(other_returns, TXPARAMETERS, params_buffer);
2202 params_buffer = NULL; /* Prevents freeing below. */
2203 ka_blk = BlastGetKaParams(blnet, FALSE);
2204 if (ka_blk)
2205 ValNodeAddPointer (other_returns, TXKABLK_NOGAP, ka_blk);
2206 ka_blk = BlastGetKaParams(blnet, TRUE);
2207 if (ka_blk)
2208 ValNodeAddPointer (other_returns, TXKABLK_GAP, ka_blk);
2209 matrix = BlastNetMatrixToBlastMatrix(net_matrix);
2210 if (matrix)
2211 ValNodeAddPointer (other_returns, TXMATRIX, matrix);
2212 }
2213 /* The next three lines prevent memory leaks when other_returns is NULL. */
2214 params_buffer = MemFree(params_buffer);
2215 dbinfo = BlastDbinfoFree(dbinfo);
2216 net_matrix = BlastMatrixFree(net_matrix);
2217
2218 blnet = BlastNet3BlockDestruct(blnet);
2219
2220 bsp->descr = descr;
2221
2222 return seqalign;
2223 }
2224
2225 NLM_EXTERN BlastPartsPtr LIBCALL
BlastBioseqNetReturnParts(BlastNet3Hptr bl3hp,BioseqPtr bsp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback,BLAST_MatrixPtr blast_matrix,Boolean PNTR ret_status)2226 BlastBioseqNetReturnParts(BlastNet3Hptr bl3hp, BioseqPtr bsp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix, Boolean PNTR ret_status)
2227
2228 {
2229 BlastKABlkPtr ka_blk;
2230 BlastDbinfoPtr dbinfo;
2231 BlastMatrixPtr net_matrix;
2232 BLAST_MatrixPtr matrix;
2233 BlastNet3BlockPtr blnet;
2234 BlastPartsPtr blast_parts;
2235 Boolean options_allocated = FALSE;
2236 CharPtr params_buffer;
2237 Int2 status;
2238 TxDfDbInfoPtr txdbinfo;
2239 ValNodePtr descr, mask;
2240
2241 if (bl3hp == NULL || bsp == NULL || program == NULL || database == NULL)
2242 return NULL;
2243
2244 if (error_returns)
2245 *error_returns = NULL;
2246
2247 if (other_returns)
2248 *other_returns = NULL;
2249
2250 /* If no options, use default. */
2251 if (options == NULL)
2252 {
2253 options = BLASTOptionNew(program, FALSE);
2254 options_allocated = TRUE;
2255 }
2256
2257 status = BLASTOptionValidateEx(options, program, error_returns);
2258 if (status != 0)
2259 { /* error messages in other_returns? */
2260 return NULL;
2261 }
2262
2263 blnet = BlastNet3BlockNew(program, database);
2264 /*
2265 Remove the Seq-descr as this is not needed for
2266 BLASTing and the title often contains none-ASCII
2267 characters. Keep the pointer and replace.
2268 */
2269 descr = bsp->descr;
2270 bsp->descr = NULL;
2271
2272 blnet->bsp = bsp;
2273 blnet->parameters = BlastOptionsToParameters(options);
2274 if (options_allocated)
2275 {
2276 options = BLASTOptionDelete(options);
2277 }
2278
2279 blnet->callback = callback;
2280 blnet->bl3hptr = bl3hp;
2281 blnet->blast_matrix = blast_matrix;
2282
2283 blast_parts = BlastBioseqByParts(blnet, error_returns, ret_status);
2284 if (other_returns)
2285 {
2286 *other_returns = NULL;
2287 mask = BlastGetMaskedLoc(blnet);
2288 if (mask)
2289 ValNodeLink(other_returns, mask);
2290 dbinfo = BlastGetDbInfo(blnet);
2291 txdbinfo = NetDbinfo2TxDbinfo(dbinfo);
2292 ValNodeAddPointer (other_returns, TXDBINFO, txdbinfo);
2293 dbinfo = BlastDbinfoFree(dbinfo);
2294 params_buffer = BlastGetParameterBuffer(blnet);
2295 ValNodeAddPointer(other_returns, TXPARAMETERS, params_buffer);
2296 ka_blk = BlastGetKaParams(blnet, FALSE);
2297 if (ka_blk)
2298 ValNodeAddPointer (other_returns, TXKABLK_NOGAP, ka_blk);
2299 ka_blk = BlastGetKaParams(blnet, TRUE);
2300 if (ka_blk)
2301 ValNodeAddPointer (other_returns, TXKABLK_GAP, ka_blk);
2302 net_matrix = NetBlastGetMatrix(blnet);
2303 matrix = BlastNetMatrixToBlastMatrix(net_matrix);
2304 net_matrix = BlastMatrixFree(net_matrix);
2305 if (matrix)
2306 ValNodeAddPointer (other_returns, TXMATRIX, matrix);
2307 }
2308
2309 blnet = BlastNet3BlockDestruct(blnet);
2310
2311 bsp->descr = descr;
2312
2313 return blast_parts;
2314 }
2315
2316 NLM_EXTERN SeqAlignPtr LIBCALL
BlastSeqLocNetCore(BlastNet3Hptr bl3hp,SeqLocPtr slp,CharPtr program,CharPtr database,BLAST_OptionsBlkPtr options,ValNodePtr * other_returns,ValNodePtr * error_returns,NetProgressCallback callback,BLAST_MatrixPtr blast_matrix,Boolean PNTR status)2317 BlastSeqLocNetCore(BlastNet3Hptr bl3hp, SeqLocPtr slp, CharPtr program, CharPtr database, BLAST_OptionsBlkPtr options, ValNodePtr *other_returns, ValNodePtr *error_returns, NetProgressCallback callback, BLAST_MatrixPtr blast_matrix, Boolean PNTR status)
2318
2319 {
2320 SeqAlignPtr seqalign = NULL;
2321 ValNodePtr vnp;
2322
2323 SeqPortPtr spp;
2324 Bioseq bs;
2325 BioseqPtr bsp = &bs;
2326 Int4 the_len, res_index;
2327 Int2 residue;
2328 ByteStorePtr bp;
2329 SeqLocPtr whole_slp;
2330 ValNodePtr mask_loc;
2331
2332 /* get Bioseq by SeqLoc */
2333
2334
2335 the_len = SeqLocLen(slp);
2336 bp = BSNew((Uint4)the_len);
2337
2338 if (ISA_na(SeqLocMol(slp)))
2339 spp = SeqPortNewByLoc (slp, Seq_code_iupacna);
2340 else
2341 spp = SeqPortNewByLoc (slp, Seq_code_iupacaa);
2342
2343 MemSet((Pointer)bsp, 0, sizeof(Bioseq));
2344 bsp->length = (Int4)the_len;
2345 bsp->repr = Seq_repr_raw;
2346 bsp->mol = (Uint1) SeqLocMol(slp);
2347 bsp->id = SeqLocId(slp);
2348
2349 if (ISA_na(bsp->mol))
2350 bsp->seq_data_type = Seq_code_iupacna;
2351 else
2352 bsp->seq_data_type = Seq_code_iupacaa;
2353
2354 SeqPortSeek(spp, 0, SEEK_SET);
2355 BSSeek(bp, 0, SEEK_SET);
2356 for (res_index = 0; res_index < the_len; res_index++)
2357 {
2358 residue = SeqPortGetResidue(spp);
2359 BSPutByte(bp, residue);
2360 }
2361 bsp->seq_data = (SeqDataPtr) bp;
2362
2363 SeqPortFree(spp);
2364
2365 /* perform search */
2366
2367 seqalign = BlastBioseqNetCore(bl3hp, bsp, program, database, options,
2368 other_returns, error_returns, callback, NULL, status);
2369
2370 /* offset the alignment */
2371
2372 AdjustOffSetsInSeqAlign(seqalign, slp, NULL);
2373
2374 if (other_returns) {
2375 mask_loc = NULL;
2376 for (vnp=*other_returns; vnp; vnp = vnp->next)
2377 {
2378 switch (vnp->choice) {
2379 case SEQLOC_MASKING_NOTSET:
2380 case SEQLOC_MASKING_PLUS1:
2381 case SEQLOC_MASKING_PLUS2:
2382 case SEQLOC_MASKING_PLUS3:
2383 case SEQLOC_MASKING_MINUS1:
2384 case SEQLOC_MASKING_MINUS2:
2385 case SEQLOC_MASKING_MINUS3:
2386 ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
2387 break;
2388 default:
2389 break;
2390 }
2391 }
2392
2393 /* adjust offset in mask_loc */
2394
2395 if (mask_loc && slp) {
2396 SeqLocPtr maskslp;
2397 SeqIntPtr masksip;
2398 Int4 offset;
2399 ValNodePtr vnp;
2400
2401 whole_slp = NULL;
2402
2403 ValNodeAddPointer(&whole_slp, SEQLOC_WHOLE, SeqIdDup(SeqIdFindBest(bsp->id, SEQID_GI)));
2404
2405 offset = GetOffsetInLoc(slp, whole_slp, SEQLOC_START);
2406
2407 for (vnp = mask_loc; vnp; vnp = vnp->next) {
2408
2409 for (maskslp = (SeqLocPtr) vnp->data.ptrvalue; maskslp; maskslp = maskslp->next) {
2410 masksip = (SeqIntPtr) maskslp->data.ptrvalue;
2411
2412 masksip->from += offset;
2413 masksip->to += offset;
2414 }
2415 }
2416 }
2417 }
2418
2419 return seqalign;
2420 }
2421
2422 #if 0
2423 FILE *global_fp;
2424 #endif
2425
2426 static Boolean LIBCALLBACK
callback(BlastResponsePtr brp,Boolean PNTR cancel)2427 callback (BlastResponsePtr brp, Boolean PNTR cancel)
2428
2429 {
2430
2431 #if 0
2432 fprintf(global_fp, ".");
2433 fflush(global_fp);
2434 #endif
2435 return TRUE;
2436
2437 }
2438
2439 static Boolean
TraditionalBlastReportEngine(SeqLocPtr slp,BioseqPtr bsp,BLAST_OptionsBlkPtr options,BlastNet3Hptr bl3hp,CharPtr program,CharPtr database,Boolean html,FILE * outfp,Boolean verbose,Uint4 print_options,Uint4 align_options,Int4 number_of_descriptions,Int4 number_of_alignments,Int4Ptr number_of_hits,Uint4 overview)2440 TraditionalBlastReportEngine(SeqLocPtr slp, BioseqPtr bsp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits, Uint4 overview)
2441
2442 {
2443 BlastDbinfoPtr dbinfo;
2444 BlastKABlkPtr ka_params=NULL, ka_params_gap=NULL;
2445 BlastPruneSapStructPtr prune;
2446 BLAST_MatrixPtr matrix;
2447 Int4Ptr PNTR txmatrix;
2448 Boolean query_is_na, db_is_na;
2449 Boolean status;
2450 CharPtr params_buffer=NULL;
2451 Int4 number_of_hits_private=0, length;
2452 SeqAlignPtr seqalign = NULL, sap, next_seqalign;
2453 SeqAnnotPtr seqannot=NULL;
2454 TxDfDbInfoPtr tx_dbinfo=NULL, tx_dbinfo_head;
2455 ValNodePtr mask_loc, mask_loc_start, other_returns, error_returns, vnp, vnp1=NULL;
2456 Uint1 align_type;
2457 Uint1 f_order[FEATDEF_ANY], g_order[FEATDEF_ANY];
2458
2459 SeqLocPtr tmp_slp;
2460 DenseSegPtr dsp, next_dsp;
2461 MegaBlastResultsPtr mb_results = NULL;
2462
2463 MemSet((Pointer)(g_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
2464 MemSet((Pointer)(f_order), 0, (size_t)(FEATDEF_ANY* sizeof(Uint1)));
2465
2466 if (bsp == NULL && slp == NULL)
2467 return FALSE;
2468
2469 if (bl3hp == NULL || program == NULL || database == NULL || outfp == NULL)
2470 return FALSE;
2471
2472 align_type = BlastGetTypes(program, &query_is_na, &db_is_na);
2473 #if 0
2474 global_fp = outfp;
2475 #endif
2476
2477 init_buff_ex(85);
2478 dbinfo = BlastRequestDbInfo(bl3hp, database, !db_is_na);
2479 if (dbinfo)
2480 PrintDbInformationBasic(database, !db_is_na, 70, dbinfo->definition, dbinfo->number_seqs, dbinfo->total_length, outfp, html);
2481 dbinfo = BlastDbinfoFree(dbinfo);
2482 free_buff();
2483
2484 fprintf(outfp, "Searching");
2485
2486 if (bsp) {
2487 seqalign = BlastBioseqNetCore(bl3hp, bsp, program, database, options,
2488 &other_returns, &error_returns, callback,
2489 NULL, &status);
2490 } else if (options->is_megablast_search)
2491 seqalign = MegaBlastSeqLocNetCore(bl3hp, slp, program, database, options, &other_returns, &error_returns, callback, &status);
2492 else
2493 seqalign = BlastSeqLocNetCore(bl3hp, slp, program, database, options, &other_returns, &error_returns, callback, NULL, &status);
2494
2495 fprintf(outfp, " done\n");
2496
2497 if (overview) {
2498 fprintf(outfp, "\n\n");
2499 if (bsp)
2500 length= bsp->length;
2501 else
2502 length= SeqLocLen(slp);
2503
2504 VSMakeSeqLoc(&seqalign, &vnp1, length, NULL);
2505 VSPrintOverviewFromSeqLocs(vnp1, length, outfp);
2506 }
2507
2508 BlastErrorPrintExtra(error_returns, TRUE, outfp);
2509
2510 mask_loc = NULL;
2511 matrix = NULL;
2512 txmatrix = NULL;
2513 for (vnp=other_returns; vnp; vnp = vnp->next) {
2514 switch (vnp->choice) {
2515 case TXDBINFO:
2516 tx_dbinfo = (TxDfDbInfoPtr) vnp->data.ptrvalue;
2517 break;
2518 case TXKABLK_NOGAP:
2519 ka_params = (BlastKABlkPtr) vnp->data.ptrvalue;
2520 break;
2521 case TXKABLK_GAP:
2522 ka_params_gap = (BlastKABlkPtr) vnp->data.ptrvalue;
2523 break;
2524 case TXPARAMETERS:
2525 params_buffer = (CharPtr) vnp->data.ptrvalue;
2526 break;
2527 case TXMATRIX:
2528 /* This function should not use matrix ??? */
2529 matrix = (BLAST_MatrixPtr) vnp->data.ptrvalue;
2530 if (matrix)
2531 txmatrix = BlastMatrixToTxMatrix(matrix);
2532 /*BLAST_MatrixDestruct(matrix);*/
2533 break;
2534 case SEQLOC_MASKING_NOTSET:
2535 case SEQLOC_MASKING_PLUS1:
2536 case SEQLOC_MASKING_PLUS2:
2537 case SEQLOC_MASKING_PLUS3:
2538 case SEQLOC_MASKING_MINUS1:
2539 case SEQLOC_MASKING_MINUS2:
2540 case SEQLOC_MASKING_MINUS3:
2541 if (!options->is_megablast_search)
2542 ValNodeAddPointer(&mask_loc, vnp->choice, vnp->data.ptrvalue);
2543 break;
2544 case BlastResponse_mbalign:
2545 mb_results = (MegaBlastResultsPtr) vnp->data.ptrvalue;
2546 break;
2547 default:
2548 break;
2549 }
2550 }
2551
2552 NlmMutexLockEx(&formating_mutex);
2553
2554 ReadDBBioseqFetchEnable ("blastcl3", database, db_is_na, TRUE);
2555
2556 if (mb_results) {
2557 MegaBlastHitPtr mb_hit;
2558 /* Results come as alignment endpoints only from Mega BLAST */
2559 for (mb_hit=mb_results->mbhits; mb_hit; mb_hit = mb_hit->next) {
2560 fprintf(outfp, "%s\t%s\t%d\t%d\t%d\t%d\t%d\n", mb_hit->id1,
2561 mb_hit->id2, mb_hit->query_offset, mb_hit->subject_offset,
2562 mb_hit->query_end, mb_hit->subject_end, mb_hit->score);
2563 }
2564 MegaBlastResultsFree(mb_results);
2565 }
2566
2567
2568 tmp_slp = slp;
2569
2570 while (seqalign) {
2571 if (!options->is_megablast_search)
2572 next_seqalign = NULL;
2573 else {
2574 sap = seqalign;
2575 while (sap != NULL) {
2576 if (sap->next != NULL) {
2577 dsp = (DenseSegPtr) (sap->segs);
2578 next_dsp = (DenseSegPtr) (sap->next->segs);
2579
2580 if (SeqIdComp(dsp->ids, next_dsp->ids) != SIC_YES) {
2581 next_seqalign = sap->next;
2582 sap->next = NULL;
2583 }
2584 } else
2585 next_seqalign = NULL;
2586 sap = sap->next;
2587 }
2588
2589 dsp = (DenseSegPtr) (seqalign->segs);
2590 while (tmp_slp && SeqIdComp(dsp->ids, SeqLocId(tmp_slp)) != SIC_YES)
2591 tmp_slp = tmp_slp->next;
2592 if (tmp_slp == NULL) /* Should never happen */
2593 break;
2594 bsp = BioseqLockById(SeqLocId(tmp_slp));
2595 init_buff_ex(85);
2596 AcknowledgeBlastQuery(bsp, 70, outfp, FALSE, html);
2597 free_buff();
2598 BioseqUnlock(bsp);
2599 }
2600
2601 seqannot = SeqAnnotNew();
2602 seqannot->type = 2;
2603 AddAlignInfoToSeqAnnot(seqannot, align_type);
2604 seqannot->data = seqalign;
2605 prune = BlastPruneHitsFromSeqAlign(seqalign, number_of_descriptions, NULL);
2606 ObjMgrSetHold();
2607 init_buff_ex(85);
2608 PrintDefLinesFromSeqAlign(prune->sap, 80, outfp, print_options, FIRST_PASS, NULL);
2609 free_buff();
2610
2611 prune = BlastPruneHitsFromSeqAlign(seqalign, number_of_alignments, prune);
2612 seqannot->data = prune->sap;
2613 if (align_options & TXALIGN_MASTER)
2614 ShowTextAlignFromAnnot(seqannot, 60, outfp, f_order, g_order, align_options, txmatrix, mask_loc, NULL);
2615 else
2616 ShowTextAlignFromAnnot(seqannot, 60, outfp, f_order, g_order, align_options, txmatrix, mask_loc, FormatScoreFunc);
2617 seqannot->data = seqalign;
2618 number_of_hits_private = prune->original_number;
2619 prune = BlastPruneSapStructDestruct(prune);
2620 ObjMgrClearHold();
2621 ObjMgrFreeCache(0);
2622
2623 if (options->is_megablast_search)
2624 tmp_slp = tmp_slp->next;
2625
2626 if (seqannot)
2627 seqannot = SeqAnnotFree(seqannot);
2628
2629 seqalign = next_seqalign;
2630 }
2631 mask_loc_start = mask_loc;
2632 while (mask_loc) {
2633 SeqLocSetFree((SeqLocPtr) mask_loc->data.ptrvalue);
2634 mask_loc = mask_loc->next;
2635 }
2636 ValNodeFree(mask_loc_start);
2637
2638 BLAST_MatrixDestruct(matrix);
2639 if (txmatrix)
2640 txmatrix = TxMatrixDestruct(txmatrix);
2641
2642 if (verbose) {
2643 init_buff_ex(85);
2644 tx_dbinfo_head = tx_dbinfo;
2645 while (tx_dbinfo) {
2646 PrintDbReport(tx_dbinfo, 70, outfp);
2647 tx_dbinfo = tx_dbinfo->next;
2648 }
2649 tx_dbinfo_head = TxDfDbInfoDestruct(tx_dbinfo_head);
2650
2651 if (ka_params) {
2652 PrintKAParameters(ka_params->lambda, ka_params->k, ka_params->h, 70, outfp, FALSE);
2653 MemFree(ka_params);
2654 }
2655
2656 if (ka_params_gap) {
2657 PrintKAParameters(ka_params_gap->lambda, ka_params_gap->k, ka_params_gap->h, 70, outfp, TRUE);
2658 MemFree(ka_params_gap);
2659 }
2660 PrintTildeSepLines(params_buffer, 70, outfp);
2661 MemFree(params_buffer);
2662 free_buff();
2663 }
2664
2665 ReadDBBioseqFetchDisable();
2666 other_returns = ValNodeFree(other_returns);
2667
2668 NlmMutexUnlock(formating_mutex);
2669
2670 if (number_of_hits)
2671 *number_of_hits = number_of_hits_private;
2672 return status;
2673 }
2674 /*
2675 Formats a 'traditional' BLAST report.
2676 */
2677
2678 NLM_EXTERN Boolean LIBCALL
TraditionalBlastReport(BioseqPtr bsp,BLAST_OptionsBlkPtr options,BlastNet3Hptr bl3hp,CharPtr program,CharPtr database,Boolean html,FILE * outfp,Boolean verbose,Uint4 print_options,Uint4 align_options,Int4 number_of_descriptions,Int4 number_of_alignments,Int4Ptr number_of_hits)2679 TraditionalBlastReport(BioseqPtr bsp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits)
2680
2681 {
2682 return TraditionalBlastReportEngine(NULL, bsp, options, bl3hp, program, database, html, outfp, verbose, print_options, align_options, number_of_descriptions, number_of_alignments, number_of_hits, BLAST_OVERVIEW_NONE);
2683 }
2684
2685 NLM_EXTERN Boolean LIBCALL
TraditionalBlastReportExtra(BioseqPtr bsp,BLAST_OptionsBlkPtr options,BlastNet3Hptr bl3hp,CharPtr program,CharPtr database,Boolean html,FILE * outfp,Boolean verbose,Uint4 print_options,Uint4 align_options,Int4 number_of_descriptions,Int4 number_of_alignments,Int4Ptr number_of_hits,Uint4 overview)2686 TraditionalBlastReportExtra(BioseqPtr bsp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits, Uint4 overview)
2687
2688 {
2689 return TraditionalBlastReportEngine(NULL, bsp, options, bl3hp, program, database, html, outfp, verbose, print_options, align_options, number_of_descriptions, number_of_alignments, number_of_hits, overview);
2690 }
2691
2692
2693 NLM_EXTERN Boolean LIBCALL
TraditionalBlastReportLoc(SeqLocPtr slp,BLAST_OptionsBlkPtr options,BlastNet3Hptr bl3hp,CharPtr program,CharPtr database,Boolean html,FILE * outfp,Boolean verbose,Uint4 print_options,Uint4 align_options,Int4 number_of_descriptions,Int4 number_of_alignments,Int4Ptr number_of_hits)2694 TraditionalBlastReportLoc(SeqLocPtr slp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits)
2695
2696 {
2697 return TraditionalBlastReportEngine(slp, NULL, options, bl3hp, program, database, html, outfp, verbose, print_options, align_options, number_of_descriptions, number_of_alignments, number_of_hits, BLAST_OVERVIEW_NONE);
2698 }
2699
2700 NLM_EXTERN Boolean LIBCALL
TraditionalBlastReportLocExtra(SeqLocPtr slp,BLAST_OptionsBlkPtr options,BlastNet3Hptr bl3hp,CharPtr program,CharPtr database,Boolean html,FILE * outfp,Boolean verbose,Uint4 print_options,Uint4 align_options,Int4 number_of_descriptions,Int4 number_of_alignments,Int4Ptr number_of_hits,Uint4 overview)2701 TraditionalBlastReportLocExtra(SeqLocPtr slp, BLAST_OptionsBlkPtr options, BlastNet3Hptr bl3hp, CharPtr program, CharPtr database, Boolean html, FILE *outfp, Boolean verbose, Uint4 print_options, Uint4 align_options, Int4 number_of_descriptions, Int4 number_of_alignments, Int4Ptr number_of_hits, Uint4 overview)
2702
2703 {
2704 return TraditionalBlastReportEngine(slp, NULL, options, bl3hp, program, database, html, outfp, verbose, print_options, align_options, number_of_descriptions, number_of_alignments, number_of_hits, overview);
2705 }
2706
2707 /* Fills in other options based upon "other_options" string in BlastParametersPtr. */
2708
2709 static void
s_parseOtherOptions(char * other_options,BLAST_OptionsBlkPtr options)2710 s_parseOtherOptions(char* other_options, BLAST_OptionsBlkPtr options)
2711 {
2712
2713 char* opt_str = "t";
2714 char* *values;
2715 Int4 index;
2716
2717 ASSERT(options);
2718
2719 if (other_options == NULL)
2720 return;
2721
2722 if(!BlastParseInputString(other_options, opt_str, &values, NULL))
2723 return;
2724
2725 index = BlastGetLetterIndex(opt_str, 't');
2726
2727 if(values[index] != NULL) {
2728 options->tweak_parameters = atoi(values[index]);
2729 }
2730
2731 return;
2732 }
2733
2734
2735 /*
2736 Converst the BlastParametersPtr (used by network service) to
2737 BLAST_OptionsBlkPtr (used by blast).
2738 */
2739 #ifndef SPLIT_BLAST
2740 NLM_EXTERN BLAST_OptionsBlkPtr
parametersToOptions(BlastParametersPtr parameters,CharPtr program,ValNodePtr PNTR error_return)2741 parametersToOptions (BlastParametersPtr parameters, CharPtr program, ValNodePtr PNTR error_return)
2742
2743 {
2744 BLAST_OptionsBlkPtr options;
2745 Int2 status;
2746
2747 if (program == NULL)
2748 return NULL;
2749
2750 if (parameters == NULL) {
2751 options = BLASTOptionNew(program, TRUE);
2752 } else {
2753 options = BLASTOptionNew(program, (Boolean) parameters->gapped_alignment);
2754 options->threshold_second = parameters->second_threshold;
2755 if (parameters->Cutoff_cutoff)
2756 {
2757 if (parameters->Cutoff_cutoff->choice == Cutoff_cutoff_evalue)
2758 options->expect_value = parameters->Cutoff_cutoff->data.realvalue;
2759 else if (parameters->Cutoff_cutoff->choice == Cutoff_cutoff_score)
2760 options->cutoff_s = parameters->Cutoff_cutoff->data.intvalue;
2761 }
2762 if (parameters->Cutoff2_cutoff2)
2763 {
2764 if (parameters->Cutoff2_cutoff2->choice == Cutoff2_cutoff2_evalue)
2765 options->e2 = parameters->Cutoff2_cutoff2->data.realvalue;
2766 else if (parameters->Cutoff2_cutoff2->choice == Cutoff2_cutoff2_score)
2767 options->cutoff_s2 = parameters->Cutoff2_cutoff2->data.intvalue;
2768 }
2769 /* compensates for client not providing this. Remove this at some point? */
2770 if (parameters->hitlist_size != 0)
2771 options->hitlist_size = parameters->hitlist_size;
2772 options->penalty = parameters->nucl_penalty;
2773 options->reward = parameters->nucl_reward;
2774 options->gap_open = parameters->gap_open;
2775 options->gap_extend = parameters->gap_extend;
2776 /* compensates for client not providing this. Remove this at some point? */
2777 if (parameters->genetic_code != 0)
2778 options->genetic_code = parameters->genetic_code;
2779 /* compensates for client not providing this. Remove this at some point? */
2780 if (parameters->db_genetic_code != 0)
2781 options->db_genetic_code = parameters->db_genetic_code;
2782
2783 options->filter = parameters->low_complexity_filtering;
2784 options->ethresh = parameters->ethresh;
2785 options->maxNumPasses = parameters->max_num_passes;
2786 options->pseudoCountConst = parameters->pseudo_count_const;
2787
2788 if (parameters->gifile)
2789 {
2790 options->gifile = StringSave(parameters->gifile);
2791 }
2792 options->gilist = parameters->gilist;
2793 if (parameters->matrix)
2794 {
2795 options->matrix = (CharPtr) MemFree(options->matrix);
2796 options->matrix = StringSave(parameters->matrix);
2797 }
2798 if (parameters->filter_string)
2799 {
2800 options->filter_string = (CharPtr) MemFree(options->filter_string);
2801 options->filter_string = StringSave(parameters->filter_string);
2802 }
2803 if (parameters->entrez_query)
2804 options->entrez_query = StringSave(parameters->entrez_query);
2805 /* compensates for client not providing this. Remove this at some point? */
2806 if (parameters->word_size)
2807 options->wordsize = parameters->word_size;
2808 if (parameters->db_length)
2809 options->db_length = parameters->db_length;
2810 if (parameters->searchsp_eff)
2811 options->searchsp_eff = parameters->searchsp_eff;
2812 if (parameters->hsp_range_max)
2813 options->hsp_range_max = parameters->hsp_range_max;
2814 if (parameters->block_width || parameters->is_megablast)
2815 /* In case of megablast, block_width should be 0 by default
2816 instead of 20 returned from BLASTOptionNew */
2817 options->block_width = parameters->block_width;
2818 if (parameters->perform_culling)
2819 options->perform_culling = parameters->perform_culling;
2820 if (parameters->strand_option)
2821 options->strand_option = parameters->strand_option;
2822
2823 if(parameters->phi_pattern) {
2824 options->phi_pattern = StringSave(parameters->phi_pattern);
2825 options->isPatternSearch = TRUE;
2826 }
2827 options->use_real_db_size = parameters->use_real_db_size;
2828 #if 0
2829 if(parameters->db_dir_prefix) {
2830 options->db_dir_prefix = StringSave(parameters->db_dir_prefix);
2831 }
2832 #endif
2833 options->use_best_align = parameters->use_best_align;
2834
2835 if(parameters->required_start != 0)
2836 options->required_start = parameters->required_start;
2837 if(parameters->required_end != 0)
2838 options->required_end = parameters->required_end;
2839
2840 options->is_rps_blast = parameters->is_rps_blast;
2841 /* this value may be overwritten by the call to s_parseOtherOptions
2842 if different information is contained there. */
2843 options->tweak_parameters = parameters->tweak_parameters;
2844
2845 options->smith_waterman = parameters->smith_waterman;
2846 options->is_megablast_search = parameters->is_megablast;
2847 options->query_lcase_mask =
2848 (SeqLocPtr) parameters->query_lcase_mask;
2849 if (parameters->endpoint_results)
2850 options->no_traceback = 1;
2851 options->perc_identity = (FloatLo) parameters->percent_identity;
2852 options->first_db_seq = parameters->first_db_seq;
2853 options->final_db_seq = parameters->final_db_seq;
2854 options->window_size = parameters->window_size;
2855 if (options->window_size == 0 && StringCmp(program, "blastn"))
2856 options->window_size = 40;
2857 options->mb_template_length = parameters->mb_template_length;
2858 options->mb_disc_type = parameters->mb_disc_type;
2859 if (options->mb_template_length > 0 &&
2860 (options->gap_open > 0 || options->gap_extend > 0)) {
2861 options->mb_use_dyn_prog = TRUE;
2862 }
2863
2864 /* Parses out tweak_parameters. */
2865 s_parseOtherOptions(parameters->other_options, options);
2866 }
2867
2868 if ((status = BLASTOptionValidateEx(options, program, error_return))) {
2869 return NULL;
2870 }
2871
2872 return options;
2873 }
2874 /* This function is interface to the Entrez2 engine. It may be used
2875 to get list of gis corresponding to the Entrez Boolean string or
2876 just number of such hits in the Entrez database */
2877
BLASTGetUidsFromQuery(CharPtr query,Int4Ptr PNTR uids,Boolean is_na,Boolean count_only,BlastError ** blast_err)2878 NLM_EXTERN Int4 BLASTGetUidsFromQuery(CharPtr query,
2879 Int4Ptr PNTR uids,
2880 Boolean is_na,
2881 Boolean count_only,
2882 BlastError ** blast_err)
2883 {
2884 Entrez2ReplyPtr e2ry;
2885 Entrez2RequestPtr e2rq;
2886 E2ReplyPtr e2rp;
2887 Int4 count = 0;
2888 Entrez2BooleanReplyPtr e2br;
2889 Entrez2IdListPtr e2idlist;
2890
2891 if(uids != NULL)
2892 *uids = NULL;
2893
2894 EntrezSetProgramName ("BLAST API");
2895 /* EntrezSetServer ("www.ncbi.nlm.nih.gov", 80,
2896 "/entrez/utils/entrez2server.fcgi"); */
2897
2898 e2rq = EntrezCreateBooleanRequest (!count_only, FALSE,
2899 is_na? "Nucleotide" : "Protein",
2900 query, 0, 0, NULL, 0, 0);
2901
2902 e2ry = EntrezSynchronousQuery (e2rq);
2903
2904 if (e2ry == NULL) {
2905 if ( blast_err ) {
2906 *blast_err = BlastErrorNew();
2907
2908 (*blast_err)->level = Blast_error_level_error;
2909 (*blast_err)->msg = StrSave("NULL returned from EntrezSynchronousQuery()");
2910 } else {
2911 ErrPostEx(SEV_ERROR, 0, 0,
2912 "NULL returned from EntrezSynchronousQuery()");
2913 }
2914
2915 return -1;
2916 }
2917
2918 if((e2rp = e2ry->reply) == NULL) {
2919 if ( blast_err ) {
2920 *blast_err = BlastErrorNew();
2921
2922 (*blast_err)->level = Blast_error_level_error;
2923 (*blast_err)->msg = StrSave("Invalid ASN.1: E2ReplyPtr==NULL");
2924 } else {
2925 ErrPostEx(SEV_ERROR, 0, 0, "Invalid ASN.1: E2ReplyPtr==NULL");
2926 }
2927 return -1;
2928 }
2929
2930 switch(e2rp->choice) {
2931 case E2Reply_error:
2932 if ( blast_err ) {
2933 const char * msg1 = "Error in request: ";
2934 const char * msg2 = (CharPtr) e2rp->data.ptrvalue;
2935 char * msg3 = 0;
2936
2937 int msglen1 = strlen(msg1);
2938 int msglen2 = strlen(msg2);
2939
2940 msg3 = MemNew(msglen1 + msglen2 + 1);
2941
2942 if ( msg3 ) {
2943 strcpy(msg3, msg1);
2944 strcat(msg3, msg2);
2945
2946 *blast_err = BlastErrorNew();
2947
2948 (*blast_err)->level = Blast_error_level_error;
2949 (*blast_err)->msg = msg3;
2950 }
2951 } else {
2952 ErrPostEx(SEV_ERROR, 0, 0, "Error in request: %s", (CharPtr) e2rp->data.ptrvalue);
2953 }
2954 count = -1;
2955 break;
2956 case E2Reply_eval_boolean:
2957 e2br = (Entrez2BooleanReplyPtr) e2rp->data.ptrvalue;
2958 count = e2br->count;
2959 if((e2idlist = e2br->uids) != NULL) {
2960 count = e2idlist->num;
2961 if(uids != NULL) {
2962 *uids = (Int4Ptr) MemNew(sizeof(Int4)*count);
2963 BSSeek((ByteStorePtr) e2idlist->uids, 0, SEEK_SET);
2964 BSRead((ByteStorePtr) e2idlist->uids, *uids, sizeof(Int4)*count);
2965 }
2966 }
2967 break;
2968 default:
2969 if ( blast_err ) {
2970 const char * msg1 = "Invalid reply type from the server: ";
2971 const char * msg2 = (CharPtr) e2rp->data.ptrvalue;
2972 char * msg3 = 0;
2973
2974 int msglen1 = strlen(msg1);
2975 int msglen2 = strlen(msg2);
2976
2977 msg3 = MemNew(msglen1 + msglen2 + 1);
2978
2979 if ( msg3 ) {
2980 strcpy(msg3, msg1);
2981 strcat(msg3, msg2);
2982
2983 *blast_err = BlastErrorNew();
2984
2985 (*blast_err)->level = Blast_error_level_error;
2986 (*blast_err)->msg = msg3;
2987 }
2988 } else {
2989 ErrPostEx(SEV_ERROR, 0, 0, "Invalid reply type from the server: %d", e2rp->choice);
2990 }
2991 count = -1;
2992 break;
2993 }
2994
2995 Entrez2ReplyFree(e2ry);
2996 Entrez2RequestFree(e2rq);
2997
2998 return count;
2999 }
3000 #endif
3001
3002