⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cn3d_cache.cpp

📁 ncbi源码
💻 CPP
字号:
/* * =========================================================================== * PRODUCTION $Log: cn3d_cache.cpp,v $ * PRODUCTION Revision 1000.2  2004/06/01 18:28:11  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15 * PRODUCTION * =========================================================================== *//*  $Id: cn3d_cache.cpp,v 1000.2 2004/06/01 18:28:11 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Authors:  Paul Thiessen** File Description:*      implements a basic cache for structures** ===========================================================================*/#ifdef _MSC_VER#pragma warning(disable:4018)   // disable signed/unsigned mismatch warning in MSVC#endif#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <objects/ncbimime/Ncbi_mime_asn1.hpp>#include <objects/ncbimime/Biostruc_seq.hpp>#include <objects/seqset/Seq_entry.hpp>#include <objects/seqset/Bioseq_set.hpp>#include <objects/mmdb1/Biostruc_id.hpp>#include <objects/mmdb1/Mmdb_id.hpp>// for file/directory manipulation stuff#ifdef __WXMSW__#include <windows.h>#include <wx/msw/winundef.h>#endif#include <wx/wx.h>#include <wx/datetime.h>#include <wx/file.h>#include <wx/filename.h>#include "cn3d_cache.hpp"#include "cn3d_tools.hpp"#include "asn_reader.hpp"#include "asn_converter.hpp"USING_NCBI_SCOPE;USING_SCOPE(objects);BEGIN_SCOPE(Cn3D)static string GetCacheFilePath(int mmdbID, EModel_type modelType){    string cachePath;    if (RegistryGetString(REG_CACHE_SECTION, REG_CACHE_FOLDER, &cachePath)) {        wxString cacheFile;        cacheFile.Printf("%s%c%i.%i", cachePath.c_str(), wxFILE_SEP_PATH, mmdbID, modelType);        cachePath = cacheFile.c_str();    } else        ERRORMSG("Can't get cache folder from registry");    return cachePath;}static bool CreateCacheFolder(void){    string cacheFolder;    if (!RegistryGetString(REG_CACHE_SECTION, REG_CACHE_FOLDER, &cacheFolder)) return false;    if (wxDirExists(cacheFolder.c_str())) return true;    bool okay = wxMkdir(cacheFolder.c_str());    TRACEMSG((okay ? "created" : "failed to create") << " folder " << cacheFolder);    return okay;}static void ExtractBioseqs(list < CRef < CSeq_entry > >& seqEntries, BioseqRefList *sequences){    list < CRef < CSeq_entry > >::iterator e, ee = seqEntries.end();    for (e=seqEntries.begin(); e!=ee; ++e) {        if ((*e)->IsSeq())            sequences->push_back(CRef<CBioseq>(&((*e)->SetSeq())));        else            ExtractBioseqs((*e)->SetSet().SetSeq_set(), sequences);    }}bool ExtractBiostrucAndBioseqs(CNcbi_mime_asn1& mime,    CRef < CBiostruc >& biostruc, BioseqRefList *sequences){    if (!mime.IsStrucseq()) {        ERRORMSG("ExtractBiostrucAndBioseqs() - expecting strucseq mime");        return false;    }    // copy mime's biostruc into existing object    biostruc.Reset(&(mime.SetStrucseq().SetStructure()));    // extract Bioseqs    if (sequences) {        sequences->clear();        ExtractBioseqs(mime.SetStrucseq().SetSequences(), sequences);    }    return true;}static CNcbi_mime_asn1 * GetStructureFromCacheFolder(int mmdbID, EModel_type modelType){    // try to load from cache    INFOMSG("looking for " << mmdbID << " (model type " << (int) modelType << ") in cache:");    string err, cacheFile = GetCacheFilePath(mmdbID, modelType);    CRef < CNcbi_mime_asn1 > mime(new CNcbi_mime_asn1());    SetDiagPostLevel(eDiag_Fatal); // ignore all but Fatal errors while reading data    bool gotFile = ReadASNFromFile(cacheFile.c_str(), mime.GetPointer(), true, &err);    SetDiagPostLevel(eDiag_Info);    if (!gotFile) {        WARNINGMSG("failed to load " << mmdbID            << " (model type " << (int) modelType << ") from cache: " << err);        return NULL;    }    // if successful, 'touch' the file to mark it as recently used    INFOMSG("loaded " << cacheFile);    wxFileName fn(cacheFile.c_str());    if (!fn.Touch())        WARNINGMSG("error touching " << cacheFile);    return mime.Release();}static CNcbi_mime_asn1 * GetStructureViaHTTPAndAddToCache(    const string& uid, int mmdbID, EModel_type modelType){    // construct URL    static const wxString host = "www.ncbi.nlm.nih.gov", path = "/Structure/mmdb/mmdbsrv.cgi";    wxString args;    if (mmdbID > 0)        args.Printf("uid=%i&form=6&db=t&save=Save&dopt=j&Complexity=", mmdbID);    else    // assume PDB id        args.Printf("uid=%s&form=6&db=t&save=Save&dopt=j&Complexity=", uid.c_str());    switch (modelType) {        case eModel_type_ncbi_all_atom: args += "Cn3D%20Subset"; break;        case eModel_type_pdb_model: args += "All%20Models"; break;        case eModel_type_ncbi_backbone:        default:            args += "Virtual%20Bond%20Model"; break;    }    // load from network    INFOMSG("Trying to load structure data from " << host.c_str() << path.c_str() << '?' << args.c_str());    string err;    CRef < CNcbi_mime_asn1 > mime(new CNcbi_mime_asn1());    if (!GetAsnDataViaHTTP(host.c_str(), path.c_str(), args.c_str(), mime.GetPointer(), &err) ||            !mime->IsStrucseq()) {        ERRORMSG("Failed to read structure " << uid << " from network\nreason: " << err);        return NULL;    } else {        // get MMDB ID from biostruc if not already known        if (mmdbID == 0) {            if (mime->GetStrucseq().GetStructure().GetId().front()->IsMmdb_id())                mmdbID = mime->GetStrucseq().GetStructure().GetId().front()->GetMmdb_id().Get();            else {                ERRORMSG("Can't get MMDB ID from Biostruc!");                return mime.Release();            }        }        bool cacheEnabled;        if (RegistryGetBoolean(REG_CACHE_SECTION, REG_CACHE_ENABLED, &cacheEnabled) && cacheEnabled) {            // add to cache            if (CreateCacheFolder() &&                WriteASNToFile(GetCacheFilePath(mmdbID, modelType).c_str(), *mime, true, &err)) {                INFOMSG("stored " << mmdbID << " (model type " << (int) modelType << ") in cache");                // trim cache to appropriate size if we've added a new file                int size;                if (RegistryGetInteger(REG_CACHE_SECTION, REG_CACHE_MAX_SIZE, &size))                    TruncateCache(size);            } else {                WARNINGMSG("Failed to write structure to cache folder");                if (err.size() > 0) WARNINGMSG("reason: " << err);            }        }    }    return mime.Release();}CNcbi_mime_asn1 * LoadStructureViaCache(const std::string& uid, ncbi::objects::EModel_type modelType){    // determine whether this is an integer MMDB ID or alphanumeric PDB ID    int mmdbID = 0;    if (uid.size() == 4 && (isalpha(uid[1]) || isalpha(uid[2]) || isalpha(uid[3]))) {        TRACEMSG("Fetching PDB " << uid);    } else {    // mmdb id        unsigned long tmp;        if (wxString(uid.c_str()).ToULong(&tmp)) {            mmdbID = (int) tmp;        } else {            ERRORMSG("LoadStructureViaCache() - invalid uid " << uid);            return false;        }        TRACEMSG("Fetching MMDB " << mmdbID);    }    // try loading from local cache folder first, if cache enabled in registry (but only with known mmdb id)    bool cacheEnabled;    CNcbi_mime_asn1 *mime = NULL;    if (mmdbID > 0 &&            RegistryGetBoolean(REG_CACHE_SECTION, REG_CACHE_ENABLED, &cacheEnabled) &&            cacheEnabled)        mime = GetStructureFromCacheFolder(mmdbID, modelType);    // otherwise, load via HTTP (and save in cache folder)    if (!mime)        mime = GetStructureViaHTTPAndAddToCache(uid, mmdbID, modelType);    return mime;}bool LoadStructureViaCache(const std::string& uid, ncbi::objects::EModel_type modelType,    CRef < CBiostruc >& biostruc, BioseqRefList *sequences){    CRef < CNcbi_mime_asn1 > mime(LoadStructureViaCache(uid, modelType));    return (mime.NotEmpty() && ExtractBiostrucAndBioseqs(*mime, biostruc, sequences));}void TruncateCache(int maxSize){    string cacheFolder;    if (!RegistryGetString(REG_CACHE_SECTION, REG_CACHE_FOLDER, &cacheFolder) ||        !wxDirExists(cacheFolder.c_str())) {        WARNINGMSG("can't find cache folder");        return;    }    INFOMSG("truncating cache to " << maxSize << " MB");    wxString cacheFolderFiles;    cacheFolderFiles.Printf("%s%c*", cacheFolder.c_str(), wxFILE_SEP_PATH);    // empty directory if maxSize <= 0    if (maxSize <= 0) {        wxString f;        while ((f=wxFindFirstFile(cacheFolderFiles, wxFILE)).size() > 0) {            if (!wxRemoveFile(f))                WARNINGMSG("can't remove file " << f);        }        return;    }    // otherwise, add up file sizes and keep deleting oldest until total size <= max    unsigned long totalSize = 0;    wxString oldestFileName;    do {        // if totalSize > 0, then we've already scanned the folder and know it's too big,        // so delete oldest file        if (totalSize > 0 && !wxRemoveFile(oldestFileName))            WARNINGMSG("can't remove file " << oldestFileName);        // loop through files, finding oldest and calculating total size        totalSize = 0;        time_t oldestFileDate = wxDateTime::GetTimeNow(), date;        wxString file = wxFindFirstFile(cacheFolderFiles, wxFILE);        for (; file.size() > 0; file = wxFindNextFile()) {            date = wxFileModificationTime(file);            if (date < oldestFileDate) {                oldestFileDate = date;                oldestFileName = file;            }            wxFile wx_file(file, wxFile::read);            if (wx_file.IsOpened()) {                totalSize += wx_file.Length();                wx_file.Close();            } else                WARNINGMSG("wxFile failed to open " << file);        }        INFOMSG("total size: " << totalSize << " oldest file: " << oldestFileName.c_str());    } while (totalSize > maxSize * 1024 * 1024);}END_SCOPE(Cn3D)/** ---------------------------------------------------------------------------* $Log: cn3d_cache.cpp,v $* Revision 1000.2  2004/06/01 18:28:11  gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15** Revision 1.15  2004/05/21 21:41:39  gorelenk* Added PCH ncbi_pch.hpp** Revision 1.14  2004/03/15 18:23:01  thiessen* prefer prefix vs. postfix ++/-- operators** Revision 1.13  2004/02/19 17:04:49  thiessen* remove cn3d/ from include paths; add pragma to disable annoying msvc warning** Revision 1.12  2004/01/17 00:17:29  thiessen* add Biostruc and network structure load** Revision 1.11  2003/04/02 17:49:18  thiessen* allow pdb id's in structure import dialog** Revision 1.10  2003/02/03 19:20:02  thiessen* format changes: move CVS Log to bottom of file, remove std:: from .cpp files, and use new diagnostic macros** Revision 1.9  2002/09/30 17:13:02  thiessen* change structure import to do sequences as well; change cache to hold mimes; change block aligner vocabulary; fix block aligner dialog bugs** Revision 1.8  2002/09/11 01:39:35  thiessen* fix cache file touch** Revision 1.7  2002/08/15 22:13:13  thiessen* update for wx2.3.2+ only; add structure pick dialog; fix MultitextDialog bug** Revision 1.6  2002/03/07 15:45:45  thiessen* compile fix ; extra file load messages** Revision 1.5  2002/02/27 16:29:40  thiessen* add model type flag to general mime type** Revision 1.4  2002/01/11 15:48:49  thiessen* update for Mac CW7** Revision 1.3  2001/11/09 15:19:16  thiessen* wxFindFirst file fixed on wxMac; call glViewport() from OnSize()** Revision 1.2  2001/11/01 19:01:40  thiessen* use meta key instead of ctrl on Mac** Revision 1.1  2001/10/30 02:54:11  thiessen* add Biostruc cache**/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -