Sleipnir
|
00001 /***************************************************************************** 00002 * This file is provided under the Creative Commons Attribution 3.0 license. 00003 * 00004 * You are free to share, copy, distribute, transmit, or adapt this work 00005 * PROVIDED THAT you attribute the work to the authors listed below. 00006 * For more information, please see the following web page: 00007 * http://creativecommons.org/licenses/by/3.0/ 00008 * 00009 * This file is a component of the Sleipnir library for functional genomics, 00010 * authored by: 00011 * Curtis Huttenhower (chuttenh@princeton.edu) 00012 * Mark Schroeder 00013 * Maria D. Chikina 00014 * Olga G. Troyanskaya (ogt@princeton.edu, primary contact) 00015 * 00016 * If you use this library, the included executable tools, or any related 00017 * code in your work, please cite the following publication: 00018 * Curtis Huttenhower, Mark Schroeder, Maria D. Chikina, and 00019 * Olga G. Troyanskaya. 00020 * "The Sleipnir library for computational functional genomics" 00021 *****************************************************************************/ 00022 #include "stdafx.h" 00023 #include "dot.h" 00024 00025 #define JAVASCRIPT_DIR "../javascripts/" 00026 00027 using namespace boost; 00028 00029 const float CDot::c_dEdgeOpacity = 0.13f; 00030 const float CDot::c_dScale = 36; 00031 const char CDot::c_szHeader00[] = 00032 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" 00033 "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n" 00034 "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" 00035 " xmlns:a3=\"http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/\"\n" 00036 " a3:scriptImplementation=\"Adobe\"\n" 00037 " onload=\"init( )\"\n" 00038 " viewBox=\"-20 -5 "; 00039 const char CDot::c_szHeader01[] = "\"\n" 00040 " width=\"100%\" height=\"100%\"\n" 00041 " >\n" 00042 " <script a3:scriptImplementation=\"Adobe\" type=\"text/ecmascript\" xlink:href=\"" JAVASCRIPT_DIR "/helper_functions.js\" />\n" 00043 " <script a3:scriptImplementation=\"Adobe\" type=\"text/ecmascript\" xlink:href=\"" JAVASCRIPT_DIR "/mapApp.js\" />\n" 00044 " <script a3:scriptImplementation=\"Adobe\" type=\"text/ecmascript\" xlink:href=\"" JAVASCRIPT_DIR "/simple.js\" />\n" 00045 " <g id=\"graph\" class=\"graph\" style=\"font-family:Times-Roman;font-size:12pt\" context=\""; 00046 const char CDot::c_szHeader02[] = "\">\n" 00047 " <title>G</title>\n"; 00048 const char CDot::c_szCutoffBox[] = 00049 " <g id=\"cutoff_control_box\">\n" 00050 " <g transform=\"scale(0.5)\">\n" 00051 " <rect x=\"-10\" y=\"-10\" width=\"40\" height=\"32\"\n" 00052 " fill=\"white\" stroke=\"none\" />\n" 00053 " <path id=\"cutoff_uparrow\"\n" 00054 " stroke-antialiasing=\"true\"\n" 00055 " stroke=\"black\" fill=\"cyan\"\n" 00056 " d=\"M -5 32 L 25 32 L 10 10 z\" />\n" 00057 " <rect x=\"-10\" y=\"43\" width=\"40\" height=\"32\"\n" 00058 " fill=\"white\" stroke=\"none\" />\n" 00059 " <path id=\"cutoff_downarrow\"\n" 00060 " stroke-antialiasing=\"true\"\n" 00061 " stroke=\"black\" fill=\"cyan\"\n" 00062 " d=\"M -5 48 L 25 48 L 10 70 z\" />\n" 00063 " <rect x=\"-15\" y=\"0\" width=\"50\" height=\"80\"\n" 00064 " fill=\"none\" stroke-linejoin=\"round\"\n" 00065 " stroke-width=\"1\" stroke=\"black\" />\n" 00066 " </g>\n" 00067 " <text x=\"20\" y=\"15\"\n" 00068 " font-family=\"Helvetica\" font-size=\"14\">\n" 00069 " Cutoff value:\n" 00070 " </text>\n" 00071 " <g id=\"cutoff_value_text\" x=\"20\" y=\"35\" />\n" 00072 " </g>\n"; 00073 00074 bool CDot::Open( const char* szDot ) { 00075 ifstream ifsm; 00076 bool fRet; 00077 00078 m_pProperties->property( "node_id", get( vertex_name, m_Graph ) ); 00079 m_pProperties->property( "pos", get( vertex_attribute, m_Graph ) ); 00080 m_pProperties->property( "width", get( vertex_index1, m_Graph ) ); 00081 m_pProperties->property( "height", get( vertex_index2, m_Graph ) ); 00082 m_pProperties->property( "pos", get( edge_attribute, m_Graph ) ); 00083 ifsm.open( szDot ); 00084 if( !( fRet = ( ifsm.is_open( ) && read_graphviz( ifsm, m_Graph, *m_pProperties ) ) ) ) 00085 cerr << "Could not open: " << szDot << endl; 00086 00087 return fRet; } 00088 00089 bool CDot::Save( ostream& ostm, const vector<bool>& vecfQuery, size_t iContext ) const { 00090 graph_traits<TGraph>::edge_iterator iterEdge, iterEdgeEnd; 00091 graph_traits<TGraph>::vertex_iterator iterVertex, iterVertexEnd; 00092 size_t iMaxX, iMaxY, iCurX, iCurY; 00093 00094 ostm << c_szHeader00; 00095 iMaxX = iMaxY = 0; 00096 for( tie( iterVertex, iterVertexEnd ) = vertices( m_Graph ); iterVertex != iterVertexEnd; ++iterVertex ) { 00097 string strPos; 00098 float dWidth, dHeight; 00099 vector<string> vecstrPos; 00100 00101 dWidth = (float)atof( get( "width", *m_pProperties, *iterVertex ).c_str( ) ); 00102 dHeight = (float)atof( get( "height", *m_pProperties, *iterVertex ).c_str( ) ); 00103 strPos = get( "pos", *m_pProperties, *iterVertex ); 00104 CMeta::Tokenize( strPos.c_str( ), vecstrPos, "," ); 00105 if( vecstrPos.size( ) != 2 ) 00106 continue; 00107 iCurX = atoi( vecstrPos[ 0 ].c_str( ) ) + (size_t)( c_dScale * dWidth ); 00108 iCurY = atoi( vecstrPos[ 1 ].c_str( ) ) + (size_t)( c_dScale * dHeight ); 00109 if( iCurX > iMaxX ) 00110 iMaxX = iCurX; 00111 if( iCurY > iMaxY ) 00112 iMaxY = iCurY; } 00113 ostm << ( iMaxX + 5 ) << ' ' << ( iMaxY + 5 ); 00114 ostm << c_szHeader01 << iContext << c_szHeader02; 00115 00116 ostm << " <g id=\"edges\" class=\"edgeList\">" << endl; 00117 for( tie( iterEdge, iterEdgeEnd ) = edges( m_Graph ); iterEdge != iterEdgeEnd; ++iterEdge ) 00118 if( !SaveEdge( ostm, *iterEdge ) ) 00119 return false; 00120 ostm << " </g>" << endl; 00121 00122 ostm << " <g id=\"nodes\" class=\"nodeList\">" << endl; 00123 for( tie( iterVertex, iterVertexEnd ) = vertices( m_Graph ); iterVertex != iterVertexEnd; ++iterVertex ) 00124 if( !SaveVertex( ostm, *iterVertex, vecfQuery ) ) 00125 return false; 00126 ostm << " </g>" << endl; 00127 00128 // ostm << c_szCutoffBox; 00129 ostm << " </g>" << endl << "</svg>" << endl; 00130 00131 return true; } 00132 00133 bool CDot::SaveEdge( ostream& ostm, const TEdge& Edge ) const { 00134 static const char c_acTabs[] = " "; 00135 static const size_t c_iBuffer = 16; 00136 char acBuffer[ c_iBuffer ]; 00137 size_t i, iHead, iTail; 00138 float dWeight; 00139 string strPath; 00140 vector<string> vecstrPath; 00141 00142 iHead = source( Edge, m_Graph ); 00143 iTail = target( Edge, m_Graph ); 00144 if( iTail < iHead ) { 00145 i = iHead; 00146 iHead = iTail; 00147 iTail = i; } 00148 if( CMeta::IsNaN( dWeight = m_Dat.Get( iHead, iTail ) ) ) { 00149 cerr << "CDot::SaveEdge( ) no edge found for: " << iHead << " (" << m_Dat.GetGene( iHead ) << "), " << 00150 iTail << " (" << m_Dat.GetGene( iTail ) << ')' << endl; 00151 return false; } 00152 sprintf_s( acBuffer, "%d_%d", iHead, iTail ); 00153 00154 strPath = get( "pos", *m_pProperties, Edge ); 00155 CMeta::Tokenize( strPath.c_str( ), vecstrPath, " " ); 00156 if( vecstrPath.size( ) < 1 ) { 00157 cerr << "CDot::SaveEdge( ) no path found for: " << iHead << " (" << m_Dat.GetGene( iHead ) << "), " << 00158 iTail << " (" << m_Dat.GetGene( iTail ) << ')' << endl; 00159 return false; } 00160 strPath = "M"; 00161 strPath += vecstrPath[ 0 ]; 00162 for( i = 1; i < vecstrPath.size( ); ++i ) 00163 strPath += ( ( i == 1 ) ? "C" : " " ) + vecstrPath[ i ]; 00164 00165 ostm << 00166 c_acTabs << "<g id=\"edge" << acBuffer << "\" class=\"edge\" stroke-opacity=\"" << 00167 c_dEdgeOpacity << "\">" << endl << 00168 c_acTabs << " <title>" << iHead << "--" << iTail << "--" << dWeight << "</title>" << endl << 00169 c_acTabs << " <text display=\"none\" id=\"edge" << acBuffer << "_confidence\">" << dWeight << 00170 "</text>" << endl << 00171 c_acTabs << " <g id=\"edge" << acBuffer << "_nodes\" display=\"none\">" << endl << 00172 c_acTabs << " <text>node" << iHead << "</text>" << endl << 00173 c_acTabs << " <text>node" << iTail << "</text>" << endl << 00174 c_acTabs << " </g>" << endl << 00175 c_acTabs << " <path style=\"fill:none;stroke:#" << CColor::Interpolate( dWeight, CColor::c_Green, 00176 CColor::c_Black, CColor::c_Red ).ToRGB( ) << ";stroke-width:3;\" d=\"" + strPath + "\" />" << 00177 endl << 00178 c_acTabs << "</g>" << endl; 00179 00180 return true; } 00181 00182 bool CDot::SaveVertex( ostream& ostm, const TVertex& Vertex, const vector<bool>& vecfQuery ) const { 00183 static const char c_acTabs[] = " "; 00184 static const size_t c_iBuffer = 16; 00185 char acBuffer[ c_iBuffer ]; 00186 graph_traits<TGraph>::out_edge_iterator iterEdge, iterEdgeEnd; 00187 string strID, strPos, strCX, strCY, strRX, strRY; 00188 string strForeground, strBackground; 00189 size_t i; 00190 float dWidth, dHeight; 00191 vector<string> vecstrPos; 00192 00193 strID = get( "node_id", *m_pProperties, Vertex ); 00194 dWidth = (float)atof( get( "width", *m_pProperties, Vertex ).c_str( ) ); 00195 dHeight = (float)atof( get( "height", *m_pProperties, Vertex ).c_str( ) ); 00196 strPos = get( "pos", *m_pProperties, Vertex ); 00197 CMeta::Tokenize( strPos.c_str( ), vecstrPos, "," ); 00198 if( vecstrPos.size( ) != 2 ) 00199 return false; 00200 strCX = vecstrPos[ 0 ]; 00201 strCY = vecstrPos[ 1 ]; 00202 sprintf_s( acBuffer, "%d", (size_t)( c_dScale * dWidth ) ); 00203 strRX = acBuffer; 00204 sprintf_s( acBuffer, "%d", (size_t)( c_dScale * dHeight ) ); 00205 strRY = acBuffer; 00206 00207 ostm << 00208 c_acTabs << "<g id=\"node" << Vertex << "\" class=\"node\" gene=\"" << m_Dat.GetGene( Vertex ) << 00209 "\">" << endl << 00210 c_acTabs << " <title>" << m_Dat.GetGene( Vertex ) << "</title>" << endl << 00211 c_acTabs << " <g id=\"node" << Vertex << "_edges\" display=\"none\">" << endl; 00212 for( tie( iterEdge, iterEdgeEnd ) = out_edges( Vertex, m_Graph ); iterEdge != iterEdgeEnd; ++iterEdge ) { 00213 size_t iHead, iTail; 00214 00215 iHead = source( *iterEdge, m_Graph ); 00216 iTail = target( *iterEdge, m_Graph ); 00217 if( iTail < iHead ) { 00218 i = iHead; 00219 iHead = iTail; 00220 iTail = i; } 00221 ostm << c_acTabs << " <text>edge" << iHead << '_' << iTail << "</text>" << endl; } 00222 ostm << c_acTabs << " </g>" << endl; 00223 00224 strForeground = "black"; 00225 strBackground = vecfQuery[ Vertex ] ? "lightgrey" : "white"; 00226 ostm << 00227 c_acTabs << " <ellipse cx=\"" << strCX << "\" cy=\"" << strCY << "\" rx=\"" << strRX << 00228 "\" ry=\"" << strRY << "\" style=\"fill:" << strBackground << ";stroke:black\" />" << endl << 00229 c_acTabs << " <text id=\"node" << Vertex << "_title\" text-anchor=\"middle\" style=\"fill:" << 00230 strForeground << ";stroke:" << strForeground << "\" x=\"" << strCX << "\" y=\"" << 00231 ( atof( strCY.c_str( ) ) + 5 ) << "\">" << m_Dat.GetGene( Vertex ) << "</text>" << endl << 00232 c_acTabs << "</g>" << endl; 00233 00234 return true; }