00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <Registration/cmtkImageXformDB.h>
00032
00033 #include <System/cmtkConsole.h>
00034
00035 #include <string>
00036 #include <sstream>
00037
00038 #include <stdlib.h>
00039 #include <cassert>
00040
00041 cmtk::ImageXformDB
00042 ::ImageXformDB( const std::string& dbPath, const bool readOnly )
00043 : cmtk::SQLite( dbPath, readOnly )
00044 {
00045
00046 if ( ! this->TableExists( "images" ) )
00047 {
00048 this->Exec( "CREATE TABLE images(id INTEGER PRIMARY KEY, space INTEGER, path TEXT)" );
00049 }
00050
00051 if ( ! this->TableExists( "xforms" ) )
00052 {
00053 this->Exec( "CREATE TABLE xforms(id INTEGER PRIMARY KEY, path TEXT, invertible INTEGER, level INTEGER, spacefrom INTEGER, spaceto INTEGER)" );
00054 }
00055 }
00056
00057 void
00058 cmtk::ImageXformDB
00059 ::AddImage( const std::string& imagePath, const std::string& spacePath )
00060 {
00061 PrimaryKeyType imageKey = this->FindImageSpaceID( imagePath );
00062 if ( imageKey != Self::NOTFOUND )
00063 return;
00064
00065 if ( (spacePath == "") )
00066 {
00067 this->Exec( "INSERT INTO images (path) VALUES ('"+imagePath+"')" );
00068 this->Exec( "UPDATE images SET space=(SELECT id FROM images WHERE path='"+imagePath+"') WHERE path='"+imagePath+"'" );
00069 }
00070 else
00071 {
00072 PrimaryKeyType spaceKey = this->FindImageSpaceID( spacePath );
00073 if ( (spaceKey == Self::NOTFOUND) )
00074 {
00075 this->Exec( "INSERT INTO images (path) VALUES ('"+spacePath+"')" );
00076 this->Exec( "UPDATE images SET space=(SELECT id FROM images WHERE path='"+spacePath+"') WHERE path='"+spacePath+"'" );
00077 spaceKey = this->FindImageSpaceID( spacePath );
00078 }
00079
00080 std::ostringstream sql;
00081 sql << "INSERT INTO images (space,path) VALUES ( " << spaceKey << ", '" << imagePath << "')";
00082 this->Exec( sql.str() );
00083 }
00084 }
00085
00086 bool
00087 cmtk::ImageXformDB
00088 ::AddImagePairXform
00089 ( const std::string& xformPath, const bool invertible, const std::string& imagePathSrc, const std::string& imagePathTrg )
00090 {
00091 PrimaryKeyType spaceKeySrc = this->FindImageSpaceID( imagePathSrc );
00092 if ( spaceKeySrc == Self::NOTFOUND )
00093 {
00094 this->AddImage( imagePathSrc );
00095 spaceKeySrc = this->FindImageSpaceID( imagePathSrc );
00096 assert( spaceKeySrc != Self::NOTFOUND );
00097 }
00098
00099 PrimaryKeyType spaceKeyTrg = this->FindImageSpaceID( imagePathTrg );
00100 if ( spaceKeyTrg == Self::NOTFOUND )
00101 {
00102 this->AddImage( imagePathTrg );
00103 spaceKeyTrg = this->FindImageSpaceID( imagePathTrg );
00104 assert( spaceKeyTrg != Self::NOTFOUND );
00105 }
00106
00107 if ( spaceKeyTrg == spaceKeySrc )
00108 {
00109 StdErr << "WARNING - cmtk::ImageXformDB::AddXform - source and target image of transformation are in the same space; bailing out.\n";
00110 return false;
00111 }
00112
00113 std::ostringstream sql;
00114 sql << "INSERT INTO xforms (path,invertible,level,spacefrom,spaceto) VALUES ( '" << xformPath << "', " << (invertible ? 1 : 0) << ", 0, " << spaceKeySrc << ", " << spaceKeyTrg << ")";
00115 this->Exec( sql.str() );
00116
00117 return true;
00118 }
00119
00120 bool
00121 cmtk::ImageXformDB
00122 ::AddRefinedXform
00123 ( const std::string& xformPath, const bool invertible, const std::string& xformInitPath, const bool initInverse )
00124 {
00125 const std::string sql = "SELECT level,spacefrom,spaceto FROM xforms WHERE ( path='" + xformInitPath + "' )";
00126
00127 SQLite::TableType table;
00128 this->Query( sql, table );
00129
00130 if ( !table.size() || !table[0].size() )
00131 {
00132 return false;
00133 }
00134
00135 const int level = 1 + atoi( table[0][0].c_str() );
00136 const Self::PrimaryKeyType spacefrom = atoi( table[0][1].c_str() );
00137 const Self::PrimaryKeyType spaceto = atoi( table[0][2].c_str() );
00138
00139 if ( spacefrom == Self::NOTFOUND || spaceto == Self::NOTFOUND )
00140 {
00141 StdErr << "WARNING - cmtk::ImageXformDB::AddXform - given initializing transformation has invalid space ID(s). Bailing out.\n";
00142 return false;
00143 }
00144
00145 std::ostringstream sqlAdd;
00146 sqlAdd << "INSERT INTO xforms (path,invertible,level,spacefrom,spaceto) VALUES ( '" << xformPath << "', " << (invertible ? 1 : 0) << ", " << level << ", ";
00147 if ( initInverse )
00148 sqlAdd << spaceto << ", " << spacefrom;
00149 else
00150 sqlAdd << spacefrom << ", " << spaceto;
00151 sqlAdd << ")";
00152
00153 this->Exec( sqlAdd.str() );
00154
00155 return true;
00156 }
00157
00158 cmtk::ImageXformDB::PrimaryKeyType
00159 cmtk::ImageXformDB
00160 ::FindImageSpaceID( const std::string& imagePath ) const
00161 {
00162 if ( imagePath != "" )
00163 {
00164 const std::string sql = "SELECT space FROM images WHERE path='"+imagePath+"'";
00165
00166 SQLite::TableType table;
00167 this->Query( sql, table );
00168
00169 if ( table.size() && table[0].size() )
00170 return atoi( table[0][0].c_str() );
00171 }
00172
00173 return Self::NOTFOUND;
00174 }
00175
00176 const std::vector<std::string>
00177 cmtk::ImageXformDB
00178 ::GetSpaceImageList( const Self::PrimaryKeyType& spaceKey, const bool sortById )
00179 {
00180 std::vector<std::string> results;
00181 if ( spaceKey == Self::NOTFOUND )
00182 {
00183 return results;
00184 }
00185
00186 std::ostringstream sql;
00187 sql << "SELECT path FROM images WHERE space=" << spaceKey;
00188
00189 if ( sortById )
00190 {
00191 sql << " ORDER BY id ASC";
00192 }
00193
00194 SQLite::TableType table;
00195 this->Query( sql.str(), table );
00196 for ( size_t i = 0; i < table.size(); ++i )
00197 {
00198 if ( table[i].size() )
00199 results.push_back( table[i][0] );
00200 }
00201
00202 return results;
00203 }
00204
00205 bool
00206 cmtk::ImageXformDB
00207 ::FindXform( const std::string& imagePathSrc, const std::string& imagePathTrg, std::string& xformPath, bool& inverse ) const
00208 {
00209 const PrimaryKeyType spaceKeySrc = this->FindImageSpaceID( imagePathSrc );
00210 const PrimaryKeyType spaceKeyTrg = this->FindImageSpaceID( imagePathTrg );
00211
00212 if ( (spaceKeySrc == Self::NOTFOUND) || (spaceKeyTrg == Self::NOTFOUND) )
00213 {
00214
00215 return false;
00216 }
00217
00218 if ( spaceKeySrc == spaceKeyTrg )
00219 {
00220 xformPath = "";
00221 inverse = false;
00222 return true;
00223 }
00224
00225 std::ostringstream sql;
00226 sql << "SELECT path FROM xforms WHERE ( spacefrom=" << spaceKeySrc << " AND spaceto=" << spaceKeyTrg << " ) ORDER BY level DESC, invertible ASC";
00227
00228 SQLite::TableType table;
00229 this->Query( sql.str(), table );
00230 if ( table.size() && table[0].size() )
00231 {
00232 inverse = false;
00233 xformPath = table[0][0];
00234 return true;
00235 }
00236
00237 sql.str( "" );
00238 sql << "SELECT path FROM xforms WHERE ( spacefrom=" << spaceKeyTrg << " AND spaceto=" << spaceKeySrc << " ) ORDER BY level DESC, invertible ASC";
00239
00240 this->Query( sql.str(), table );
00241 if ( table.size() && table[0].size() )
00242 {
00243 inverse = true;
00244 xformPath = table[0][0];
00245 return true;
00246 }
00247
00248 return false;
00249 }
00250
00251 const std::vector<std::string>
00252 cmtk::ImageXformDB
00253 ::FindAllXforms( const std::string& imagePathSrc, const std::string& imagePathTrg ) const
00254 {
00255 std::vector<std::string> result;
00256
00257 const PrimaryKeyType spaceKeySrc = this->FindImageSpaceID( imagePathSrc );
00258 const PrimaryKeyType spaceKeyTrg = this->FindImageSpaceID( imagePathTrg );
00259
00260 if ( (spaceKeySrc == Self::NOTFOUND) || (spaceKeyTrg == Self::NOTFOUND) )
00261 {
00262
00263 return result;
00264 }
00265
00266 if ( spaceKeySrc == spaceKeyTrg )
00267 {
00268 result.push_back( "" );
00269 return result;
00270 }
00271
00272 std::ostringstream sql;
00273 sql << "SELECT path FROM xforms WHERE ( spacefrom=" << spaceKeySrc << " AND spaceto=" << spaceKeyTrg << " ) ORDER BY level DESC, invertible ASC";
00274
00275 SQLite::TableType table;
00276 this->Query( sql.str(), table );
00277 for ( size_t i = 0; i < table.size(); ++i )
00278 {
00279 if ( table[i].size() )
00280 result.push_back( table[i][0] );
00281 }
00282 return result;
00283 }
00284
00285 int
00286 cmtk::ImageXformDB
00287 ::FindXformLevel( const std::string& xformPath ) const
00288 {
00289 const std::string sql = "SELECT level FROM xforms WHERE ( path='" + xformPath + "' )";
00290
00291 SQLite::TableType table;
00292 this->Query( sql, table );
00293
00294 if ( table.size() && table[0].size() )
00295 {
00296 return atoi( table[0][0].c_str() );
00297 }
00298
00299 return -1;
00300 }