cmtkImageXformDB.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2010 SRI International
00004 //
00005 //  This file is part of the Computational Morphometry Toolkit.
00006 //
00007 //  http://www.nitrc.org/projects/cmtk/
00008 //
00009 //  The Computational Morphometry Toolkit is free software: you can
00010 //  redistribute it and/or modify it under the terms of the GNU General Public
00011 //  License as published by the Free Software Foundation, either version 3 of
00012 //  the License, or (at your option) any later version.
00013 //
00014 //  The Computational Morphometry Toolkit is distributed in the hope that it
00015 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00016 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU General Public License along
00020 //  with the Computational Morphometry Toolkit.  If not, see
00021 //  <http://www.gnu.org/licenses/>.
00022 //
00023 //  $Revision: 2398 $
00024 //
00025 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00026 //
00027 //  $LastChangedBy: torstenrohlfing $
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   // create entity tables
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     // if either space is not in the database, then clearly no transformation can reach it
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     // if either space is not in the database, then clearly no transformation can reach it
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines