1 // ***************************************************************************
2 // BamIndexFactory_p.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 5 April 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides interface for generating BamIndex implementations
8 // ***************************************************************************
10 #include <api/BamAux.h>
11 #include <api/internal/BamIndexFactory_p.h>
12 #include <api/internal/BamStandardIndex_p.h>
13 #include <api/internal/BamToolsIndex_p.h>
14 using namespace BamTools;
15 using namespace BamTools::Internal;
20 // generates index filename from BAM filename (depending on requested type)
21 // if type is unknown, returns empty string
22 const string BamIndexFactory::CreateIndexFilename(const string& bamFilename,
23 const BamIndex::IndexType& type)
26 case ( BamIndex::STANDARD ) : return ( bamFilename + BamStandardIndex::Extension() );
27 case ( BamIndex::BAMTOOLS ) : return ( bamFilename + BamToolsIndex::Extension() );
29 cerr << "BamIndexFactory ERROR: unknown index type" << type << endl;
34 // creates a new BamIndex object, depending on extension of @indexFilename
35 BamIndex* BamIndexFactory::CreateIndexFromFilename(const string& indexFilename, BamReaderPrivate* reader) {
37 // if file doesn't exist, return null index
38 if ( !BamTools::FileExists(indexFilename) )
41 // get file extension from index filename, including dot (".EXT")
42 // if can't get file extension, return null index
43 const string extension = FileExtension(indexFilename);
44 if ( extension.empty() )
47 // create index based on extension
48 if ( extension == BamStandardIndex::Extension() ) return new BamStandardIndex(reader);
49 else if ( extension == BamToolsIndex::Extension() ) return new BamToolsIndex(reader);
54 // creates a new BamIndex, object of requested @type
55 BamIndex* BamIndexFactory::CreateIndexOfType(const BamIndex::IndexType& type,
56 BamReaderPrivate* reader)
59 case ( BamIndex::STANDARD ) : return new BamStandardIndex(reader);
60 case ( BamIndex::BAMTOOLS ) : return new BamToolsIndex(reader);
62 cerr << "BamIndexFactory ERROR: unknown index type " << type << endl;
67 // retrieves file extension (including '.')
68 const string BamIndexFactory::FileExtension(const string& filename) {
70 // if filename cannot contain valid path + extension, return empty string
71 if ( filename.empty() || filename.length() <= 4 )
74 // look for last dot in filename
75 size_t lastDotPosition = filename.find_last_of('.');
77 // if none found, return empty string
78 if ( lastDotPosition == string::npos )
81 // return substring from last dot position
82 return filename.substr(lastDotPosition);
85 // returns name of existing index file that corresponds to @bamFilename
86 // will defer to @preferredType if possible, if not will attempt to load any supported type
87 // returns empty string if not found
88 const string BamIndexFactory::FindIndexFilename(const string& bamFilename,
89 const BamIndex::IndexType& preferredType)
91 // try to find index of preferred type first
92 // return index filename if found
93 string indexFilename = CreateIndexFilename(bamFilename, preferredType);
94 if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
97 // couldn't find preferred type, try the other supported types
98 // return index filename if found
99 if ( preferredType != BamIndex::STANDARD ) {
100 indexFilename = CreateIndexFilename(bamFilename, BamIndex::STANDARD);
101 if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
102 return indexFilename;
104 if ( preferredType != BamIndex::BAMTOOLS ) {
105 indexFilename = CreateIndexFilename(bamFilename, BamIndex::BAMTOOLS);
106 if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
107 return indexFilename;
110 // otherwise couldn't find any index matching this filename