NCBI C++ ToolKit
blast_tool_manager.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: blast_tool_manager.cpp 47479 2023-05-02 13:24:02Z ucko $
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  * Authors: Andrey Yazhuk
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 
33 
38 
40 
42 
44 
46 #include <objmgr/seq_entry_ci.hpp>
47 #include <serial/iterator.hpp>
48 
50 
51 #include <wx/panel.h>
52 #include <wx/arrstr.h>
53 #include <wx/msgdlg.h>
54 
55 
58 
59 ///////////////////////////////////////////////////////////////////////////////
60 /// CBLASTToolManager
62  : m_Descriptor("BLAST", "",
63  "Align sequences using BLAST",
64  "Perform sequence similarity comparison "
65  "with sets of sequences, NCBI BLAST database or local BLAST database",
66  "https://www.ncbi.nlm.nih.gov/tools/gbench/tutorial1/#tools"),
67  m_SrvLocator(NULL),
68  m_ParentWindow(NULL),
69  m_UseNucForMixInput(true),
70  m_State(eInvalid),
71  m_OptionsPanel(NULL),
72  m_ParamsPanel(NULL)
73 {
74  m_Descriptor.SetLogEvent("tools");
75 }
76 
78 {
79  return "blast_tool_manager";
80 }
81 
82 
84 {
85  return "BLAST Tool";
86 }
87 
89 {
90  m_SrvLocator = srv_locator;
91 }
92 
93 
94 void CBLASTToolManager::SetParentWindow(wxWindow* parent)
95 {
96  m_ParentWindow = parent;
97 }
98 
99 
101 {
102  return m_Descriptor;
103 }
104 
105 
107 {
108  // initially tool panels are not displayed and so the first
109  // step of the Run Tool dialog corresponds to invalid state
110  m_State = eInvalid;
111  m_InputObjects.clear();
112 
115 }
116 
117 
119 {
120  m_State = eInvalid;
121  m_InputObjects.clear();
122 
123  //TODO Current panel lifetime management
126 }
127 
128 
130 {
132  optionsPanel->Create(m_ParentWindow);
133  return optionsPanel;
134 }
135 
137 {
138  switch(m_State) {
139  case eOptions:
140  return m_OptionsPanel;
141  case eParams:
142  return m_ParamsPanel;
143  default:
144  return NULL;
145  }
146 }
147 
148 
150 {
151  if(m_OptionsPanel == NULL) {
152  // preapare input data
154 
157 
158  // Create Options panel and initialize it
160  m_OptionsPanel->Setup(*blast_ds, m_Descriptor.GetLabel());
162 
164 
165  m_OptionsPanel->SetRegistryPath(m_RegPath + ".OptionsPanel");
167  }
168 }
169 
171 {
174 
175  CIRef<IUIDataSource> ds = ds_srv->GetUIDataSourceByLabel("NCBI Net BLAST");
176  CNetBLASTUIDataSource* blast_ds = dynamic_cast<CNetBLASTUIDataSource*>(ds.GetPointer());
177  return CRef<CNetBLASTUIDataSource>(blast_ds);
178 }
179 
180 
182 {
183  if( m_ParamsPanel == NULL ){
186  }
187  return true;
188 }
189 
190 
192 {
193  switch(m_State) {
194  case eInvalid:
195  return action == eNext;
196  case eOptions:
197  return action == eNext;
198  case eParams:
199  return action == eNext || action == eBack;
200  case eCompleted:
201  return false; // nothing left to do
202  default:
203  _ASSERT(false);
204  return false;
205  }
206 }
207 
208 
210 {
211  return m_State == eParams;
212 }
213 
214 
216 {
217  return m_State == eCompleted;
218 }
219 
220 
222 {
223  bool next = action == eNext;
224 
225  if(m_State == eInvalid && next) {
226  m_State = eOptions;
229  return true;
230  } else if(m_State == eOptions) {
231  if(next) {
234  m_State = eParams;
237  return true;
238  } else return false;
239  } else {
241  m_State = eInvalid;
242  return true;
243  }
244  } else if(m_State == eParams) {
245  if(next) {
247  try{
248  LOG_POST(Trace << "Validationg BLAST Search params...");
252  return true;
253  } catch (CException& e) {
254  ERR_POST(e.ReportAll());
255  NcbiErrorBox(e.GetMsg());
256  }
257  }
258  } else {
259  m_State = eOptions;
261  return true;
262  }
263  return false;
264  }
265  _ASSERT(false);
266  return false;
267 }
268 
270 {
273 
276  );
277  task->Init_SubmitSearch(m_Params);
278 
279  // Log the parameters
280  m_Params.PrintParams("CBLASTSearchToolManager::");
281 
282  CSelectProjectOptions options;
284  task->SetLoadingOptions(options);
285 
286  return task.Release();
287  }
288  else {
291 
292  // Log the parameters
293  m_Params.PrintParams("CBLASTSeqToolManager::");
294 
295  CSelectProjectOptions options;
297 
298  CRef<CDataLoadingAppTask> task(new CDataLoadingAppTask(srv, options, *job));
299  return task.Release();
300  }
301 }
302 
303 
305 {
307  NON_CONST_ITERATE(vector<TConstScopedObjects>, it, m_InputObjects) {
308  if (!it->empty()) {
310  m_ProjectParams.m_FolderName = "BLAST Results";
312  break;
313  }
314  }
315 }
316 
317 
318 /// validate parameters after Params page
320 {
322  return handle->SetOptions().Validate();
323 }
324 
325 
327 {
328  return "Alignment Creation";
329 }
330 
331 
332 string CBLASTToolManager::SetInputObjects(const vector<TConstScopedObjects>& objects)
333 {
334  CRef<objects::CScope> scope;
335  ITERATE(vector<TConstScopedObjects>, it, objects) {
336  ITERATE(TConstScopedObjects, it2, *it) {
337  if (!scope) {
338  scope = it2->scope;
339  continue;
340  }
341  else {
342  if (scope != it2->scope) {
343  return "This tool gives unpredictable results with objects\nfrom different projects.\n\nPlease move all objects to the same project\nand try again.";
344  }
345  }
346  }
347  }
348 
350 
351  return "";
352 }
353 
355 {
357 }
358 
359 static const char* kSelectedSequences = "Selected sequences";
360 
362 {
363  if (CBLASTParams::eNCBIDB != m_Params.GetSubjectType()) return 0;
364 
366 
368 
370 
371  if (m_Params.IsNucInput()) {
373  if (it != m_NucObjects.end()) {
374  copy(it->second.begin(), it->second.end(), back_inserter(m_Params.GetSeqLocs()));
375  }
376  else {
377  for (const auto& i : m_NucObjects)
378  copy(i.second.begin(), i.second.end(), back_inserter(m_Params.GetSeqLocs()));
379  }
380  }
381  else {
383  if (it != m_ProtObjects.end()) {
384  copy(it->second.begin(), it->second.end(), back_inserter(m_Params.GetSeqLocs()));
385  }
386  else {
387  for (const auto& i : m_ProtObjects)
388  copy(i.second.begin(), i.second.end(), back_inserter(m_Params.GetSeqLocs()));
389  }
390 
391  if (m_UseNucForMixInput){
392  for (const auto& i : m_NucObjects)
393  copy(i.second.begin(), i.second.end(), back_inserter(m_Params.GetSeqLocs()));
394  }
395  }
396 
397  SProjectSelectorParams project_params;
398  project_params.m_CreateFolder = false;
399  project_params.m_FolderName = "";
400 
402 
403  vector<CProjectService::TProjectId> projects;
404  prj_srv->GetObjProjects(m_Params.GetSeqLocs(), projects);
405  if (projects.empty()){
407  }
408  else {
410  project_params.m_SelectedProjectId = projects.front();
411  }
412 
413  return GetTask();
414 }
415 
417 {
418  wxBusyCursor wait;
419 
422 
423  TConstScopedObjects convert, original;
424  set<CBioseq_Handle> seqSet;
425  for (auto v : m_InputObjects) {
426  for (auto o : v) {
427  const CSeq_loc* seqLoc = dynamic_cast<const CSeq_loc*>(o.object.GetPointer());
428  const CSeq_id* seqId = dynamic_cast<const CSeq_id*>(o.object.GetPointer());
429  const CSeq_entry* seqEntry = dynamic_cast<const CSeq_entry*>(o.object.GetPointer());
430  const CBioseq* bioSeq = dynamic_cast<const CBioseq*>(o.object.GetPointer());
431  const CBioseq_set* bioSeqSet = dynamic_cast<const CBioseq_set*>(o.object.GetPointer());
432 
433  if (seqLoc) {
434  original.push_back(o);
435  }
436  else if (seqId) {
437  CBioseq_Handle h = o.scope->GetBioseqHandle(*seqId);
438  if (h && seqSet.insert(h).second) {
439  CRef<CSeq_id> id(new CSeq_id());
440  id->Assign(*h.GetSeqId());
441  CRef<CSeq_loc> seq_whole(new CSeq_loc());
442  seq_whole->SetWhole(*id);
443  original.push_back(SConstScopedObject(seq_whole, o.scope));
444  }
445  }
446  else if (seqEntry) {
447  CSeq_entry_Handle seh = o.scope->GetSeq_entryHandle(*seqEntry);
448  if (!seh) continue;
450  if (ci->IsSeq()) {
451  CBioseq_Handle h = ci->GetSeq();
452  if (h && seqSet.insert(h).second) {
453  CRef<CSeq_id> id(new CSeq_id());
454  id->Assign(*h.GetSeqId());
455  CRef<CSeq_loc> seq_whole(new CSeq_loc());
456  seq_whole->SetWhole(*id);
457  original.push_back(SConstScopedObject(seq_whole, o.scope));
458  }
459  }
460  }
461  }
462  else if (bioSeq) {
463  CBioseq_Handle h = o.scope->GetBioseqHandle(*bioSeq);
464  if (h && seqSet.insert(h).second) {
465  CRef<CSeq_id> id(new CSeq_id());
466  id->Assign(*h.GetSeqId());
467  CRef<CSeq_loc> seq_whole(new CSeq_loc());
468  seq_whole->SetWhole(*id);
469  original.push_back(SConstScopedObject(seq_whole, o.scope));
470  }
471  }
472  else if (bioSeqSet) {
473  CTypeConstIterator<CBioseq> iter(*bioSeqSet);
474  for (; iter; ++iter) {
475  CBioseq_Handle h = o.scope->GetBioseqHandle(*iter);
476  if (h && seqSet.insert(h).second) {
477  CRef<CSeq_id> id(new CSeq_id());
478  id->Assign(*h.GetSeqId());
479  CRef<CSeq_loc> seq_whole(new CSeq_loc());
480  seq_whole->SetWhole(*id);
481  original.push_back(SConstScopedObject(seq_whole, o.scope));
482  }
483  }
484  }
485  else
486  convert.push_back(o);
487  }
488  }
489  seqSet.clear();
490 
492 
493  if (!convert.empty()) {
494  AsyncConvertObjects(CSeq_loc::GetTypeInfo(), convert, seqLocs);
495  }
496 
498  if (it != seqLocs.end()) {
499  TConstScopedObjects& other = seqLocs["Other"];
500  other.insert(other.end(), it->second.begin(), it->second.end());
501  seqLocs.erase(it);
502  }
503 
504  if (!original.empty())
505  seqLocs[kSelectedSequences] = original;
506 
507  for (auto& i : seqLocs) {
508  for (auto& j : i.second) {
509  const CSeq_loc* seq_loc = dynamic_cast<const CSeq_loc*>(j.object.GetPointer());
510  if (!seq_loc || !seq_loc->GetId())
511  continue;
512 
513  CBioseq_Handle handle = j.scope->GetBioseqHandle(*seq_loc->GetId());
514  if (!handle)
515  continue;
517  target[i.first].push_back(j);
518  }
519  }
520 }
521 
522 /// defines whether Nucleotide or Protein options shall be selected by default
524 {
525  if(m_ProtObjects.empty()) {
526  return true; // no proteins - select Nucleotides
527  } else {
528  // have proteins - use them if not nucleotides, otherwise
529  // use m_UseNucForMixInput setting
531  }
532 }
533 
534 
535 void CBLASTToolManager::SetRegistryPath(const string& path)
536 {
537  m_RegPath = path; // store for later use
538 }
539 
540 static const char* kParamsTag = "Params";
541 static const char* kUseNucForMixInput = "UseNucForMixInput";
542 static const char* kLocalWinMaskDirPath = "Workbench.Services.DefaultUIDS.LocalMaskPath";
543 
545 {
546  if( ! m_RegPath.empty()) {
548  CRegistryWriteView view = gui_reg.GetWriteView(m_RegPath);
549 
550  if( ! m_ProtObjects.empty() && ! m_NucObjects.empty()) {
551  // update option
553  }
555 
556  /// save BLAST parameters
558  CRef<CUser_field> field =
560  field->SetData().SetObject(*param_obj);
561 
562  if(m_OptionsPanel) {
564  }
565  }
566 }
567 
568 
570 {
571  if( ! m_RegPath.empty()) {
573  CRegistryReadView view = gui_reg.GetReadView(m_RegPath);
574 
576 
577  /// load BLAST parameters
579  if(view.HasField(key)) {
580  const CUser_object& param_obj = view.GetField(key)->GetData().GetObject();
581  m_Params.FromUserObject(param_obj);
582  }
583 
585  }
586 }
587 
589 {
590  wxPanel* current_panel = GetCurrentPanel();
591  if (!current_panel)
592  return;
593  CAlgoToolManagerParamsPanel* params_panel = dynamic_cast<CAlgoToolManagerParamsPanel*>(current_panel);
594  if(!params_panel)
595  return;
596  if (wxOK != wxMessageBox("The active page settings will be restored to their original defaults.", "Confirm", wxOK | wxCANCEL))
597  return;
598  params_panel->RestoreDefaults();
599 }
600 
void AsyncConvertObjects(const CTypeInfo *typeInfo, const TConstScopedObjects &inputObjects, map< string, TConstScopedObjects > &results)
static const char * kUseNucForMixInput
USING_SCOPE(objects)
static const char * kSelectedSequences
static const char * kParamsTag
static const char * kLocalWinMaskDirPath
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static TDSRET convert(TDSSOCKET *tds, TDSICONV *conv, TDS_ICONV_DIRECTION direction, const char *from, size_t from_len, char *dest, size_t *dest_len)
Definition: charconv.c:57
CAlgoToolManagerParamsPanel.
virtual void SetRegistryPath(const string &reg_path)
CAlgoToolManagerParamsPanel.
virtual void RestoreDefaults()=0
override in derived classes
CBLASTSeqToolJob.
CBioseq_Handle –.
CDataLoadingAppTask - a task that executes CDataLoadingAppJob.
static string MakeKey(const string &section, const string &key, const string &delim=CGuiRegistry::kDecimalDot)
create a key from a section and a subkey
Definition: registry.cpp:504
CRegistryWriteView GetWriteView(const string &section)
get a read-write view at a particular level.
Definition: registry.cpp:462
static CGuiRegistry & GetInstance()
access the application-wide singleton
Definition: registry.cpp:400
CRegistryReadView GetReadView(const string &section) const
get a read-only view at a particular level.
Definition: registry.cpp:428
string GetString(const string &key, const string &default_val=kEmptyStr) const
Definition: registry.cpp:148
CProjectService - a service providing API for operations with Workspaces and Projects.
void GetObjProjects(TConstScopedObjects &objects, vector< TProjectId > &ids)
class CRegistryReadView provides a nested hierarchical view at a particular key.
Definition: reg_view.hpp:58
bool GetBool(const string &key, bool default_val=false) const
Definition: reg_view.cpp:241
bool HasField(const string &key) const
Does a field with this section and key exist in this view?
Definition: reg_view.cpp:352
CConstRef< objects::CUser_field > GetField(const string &key) const
provide raw field access
Definition: reg_view.cpp:104
CRef< objects::CUser_field > SetField(const string &key)
provide raw field access
Definition: reg_view.cpp:502
void Set(const string &key, int val)
access a named key at this level, with no recursion
Definition: reg_view.cpp:533
CProjectSelectOptions - describes how new Project Items shall be added to a workspace.
CSeq_entry_CI –.
CSeq_entry_Handle –.
Definition: Seq_entry.hpp:56
Template class for iteration on objects of class C (non-medifiable version)
Definition: iterator.hpp:767
CUIDataSourceService.
IAppTask.
Definition: app_task.hpp:83
IServiceLocator - an abstract mechanism for locating services.
Definition: service.hpp:71
IUIObject - object that provides basic properties often required in a UI object.
Definition: ui_object.hpp:63
void erase(iterator pos)
Definition: map.hpp:167
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
bool empty() const
Definition: map.hpp:149
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
void clear()
Definition: set.hpp:153
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
void Trace(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1179
string ReportAll(TDiagPostFlags flags=eDPF_Exception) const
Report all exceptions.
Definition: ncbiexpt.cpp:370
CIRef< T > GetServiceByType()
retrieves a typed reference to a service, the name of C++ type is used as the name of the service.
Definition: service.hpp:91
virtual string GetExtensionIdentifier() const
returns the unique human-readable identifier for the extension the id should use lowercase letters se...
CRef< blast::CBlastOptionsHandle > ToBlastOptions(bool local=false) const
virtual void LoadSettings()
virtual string GetExtensionLabel() const
returns a displayable label for this extension ( please capitalize the key words - "My Extension" )
virtual const IUIObject & GetDescriptor() const
Returns the object describing this tool (UI meta data).
vector< TConstScopedObjects > m_InputObjects
void Setup(CNetBLASTUIDataSource &ds, const string &tool_name)
bool x_ValidateParams()
validate parameters after Params page
virtual void InitUI()
Initializes the Manager before using it in UI.
TConstScopedObjects & GetSeqLocs()
virtual wxPanel * GetMaxPanel()
Return the panel that occupies max size on display, to calculate dialog window size.
CBLASTSearchParamsPanel * m_ParamsPanel
IServiceLocator * m_SrvLocator
virtual bool CanDo(EAction action)
Indicates whether given transition is possible in the current state.
virtual void x_CreateOptionsPanelIfNeeded()
virtual bool DoTransition(EAction action)
Performs transition if possible and returns true, otherwise the function shall warn the user about th...
SProjectSelectorParams m_ProjectParams
virtual IAppTask * QuickLaunch()
virtual wxPanel * GetCurrentPanel()
Return the panel corresponding to the current state of Tool Manager.
virtual IAppTask * GetTask()
Once parameters are gathered and validated this function is called to produce the final Task object t...
CBLASTToolManager()
CBLASTToolManager.
map< string, TConstScopedObjects > m_ProtObjects
void FromUserObject(const objects::CUser_object &user_obj)
CUIObject m_Descriptor
describes the Manager's UI properties
virtual void SetRegistryPath(const string &path)
virtual void SetServiceLocator(IServiceLocator *srv_locator)
Sets / unsets Service Locator.
virtual bool CanQuickLaunch() const
virtual bool x_IsNucInput() const
defines whether Nucleotide or Protein options shall be selected by default
virtual void SaveSettings() const
virtual bool IsCompletedState()
Manager goes into "Complete" state when "Finish" button is pressed and all input data is gatherred an...
CBLASTSearchOptionsPanel * m_OptionsPanel
void SetParams(CBLASTParams *params)
virtual void x_SelectCompatibleInputObjects()
virtual void RestoreDefaults()
Restores the default options for the current panel.
virtual string SetInputObjects(const vector< TConstScopedObjects > &input)
sets input objects that can be used as arguments for the tool.
bool Create(wxWindow *parent, wxWindowID id=ID_CBLASTSEARCHOPTIONSPANEL, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(), long style=wxTAB_TRAVERSAL)
virtual void CleanUI()
CleanUI() is called after the host finished using the manager.
virtual void SetParentWindow(wxWindow *parent)
void SetParams(CBLASTParams *params, map< string, TConstScopedObjects > *nuc_objects, map< string, TConstScopedObjects > *prot_objects)
void PrintParams(const string &log_title) const
LOG_POST params for forensic purposes.
CRef< CNetBLASTUIDataSource > GetBLASTDataSource()
virtual bool IsFinalState()
True if Tool Manager has reached its final state, i.e.
virtual void SaveSettings() const
override in derived classes
virtual bool x_CreateParamsPanelIfNeeded()
virtual string GetCategory()
returns the name for the ToolCategory to which the tool belongs.
ESubjectType GetSubjectType() const
map< string, TConstScopedObjects > m_NucObjects
objects::CUser_object * ToUserObject() const
void NcbiErrorBox(const string &message, const string &title="Error")
specialized Message Box function for reporting critical errors
virtual void SetLogEvent(const string &log_event)
Definition: ui_object.cpp:118
virtual const string & GetLabel() const
Definition: ui_object.cpp:124
vector< SConstScopedObject > TConstScopedObjects
Definition: objects.hpp:65
void SetWhole(TWhole &v)
Definition: Seq_loc.hpp:982
const CSeq_id * GetId(void) const
Get the id of the location return NULL if has multiple ids or no id at all.
Definition: Seq_loc.hpp:941
CConstRef< CSeq_id > GetSeqId(void) const
Get id which can be used to access this bioseq handle Throws an exception if none is available.
bool IsNa(void) const
@ fIncludeGivenEntry
Include the top (given) entry.
@ fRecursive
Iterate recursively.
TObjectType * Release(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:846
TObjectType & GetObject(void) const
Get object.
Definition: ncbiobj.hpp:1697
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
void SetData(TData &value)
Assign a value to Data data member.
int i
const struct ncbi::grid::netcache::search::fields::KEY key
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
SProjectSelectorParams - holds data for CProjectSelectorPanel.
void SelectProjectByObjects(TConstScopedObjects &objects, CProjectService *srv)
is all objects belong to the same project - selects the project
bool m_CreateFolder
package in a single item
void ToLoadingOptions(CSelectProjectOptions &options)
#define _ASSERT
Modified on Tue Dec 05 02:10:32 2023 by modify_doxy.py rev. 669887