void GridEditor::saveGridCallback(GLMotif::FileSelectionDialog::OKCallbackData* cbData) { try { /* Write the current contents of the grid to a floating-point vol file: */ IO::FilePtr gridFile(cbData->selectedDirectory->openFile(cbData->selectedFileName,IO::File::WriteOnly)); gridFile->setEndianness(Misc::BigEndian); gridFile->write<int>(grid->getNumVertices().getComponents(),3); gridFile->write<int>(0); float domainSize[3]; for(int i=0;i<3;++i) domainSize[i]=float(grid->getNumVertices(i)-1)*grid->getCellSize(i); gridFile->write<float>(domainSize,3); /* Write the grid data values: */ for(EditableGrid::Index i(0);i[0]<grid->getNumVertices(0);i.preInc(grid->getNumVertices())) gridFile->write<float>(grid->getValue(i)); } catch(std::runtime_error err) { Vrui::showErrorMessage("Save Grid...",Misc::printStdErrMsg("Could not save grid due to exception %s",err.what())); } }
int main(int argc, char* argv[]) try { const auto prm = example::initParam(argc, argv); const auto cellID = prm.getDefault("cell", 0); const auto rset = example::identifyResultSet(prm); const auto init = Opm::ECLInitFileData(rset.initFile()); const auto graph = Opm::ECLGraph::load(rset.gridFile(), init); auto pvtCC = Opm::ECLPVT::ECLPvtCurveCollection(graph, init); if (prm.has("unit")) { pvtCC.setOutputUnits(makeUnits(prm.get<std::string>("unit"), init)); } const auto x = CellState{ graph, rset, cellID }; auto props = std::vector<Property>{}; for (const auto& prop : enumerateProperties()) { if (prm.getDefault(prop.first, false)) { props.push_back(Property{ prop.first, (*prop.second)(pvtCC, x) }); } } if (! props.empty()) { std::cout.precision(16); std::cout.setf(std::ios_base::scientific); writeResults(x, props); } } catch (const std::exception& e) { std::cerr << "Caught Exception: " << e.what() << '\n'; return EXIT_FAILURE; }
Visualization::Abstract::DataSet* CitcomtVectorFile::load(const std::vector<std::string>& args,Comm::MulticastPipe* pipe) const { /* Open the data file: */ Misc::File dataFile(args[0].c_str(),"rt"); /* Check if the user wants to load a specific variable: */ bool logScale=false; const char* varStart=0; const char* varEnd=0; int varLen=0; if(args.size()>2&&args[2][0]!='-') { /* Parse the search variable name: */ varStart=args[2].c_str(); if(strncasecmp(varStart,"log(",4)==0) { /* Use a logarithmic scale: */ logScale=true; /* Take the string in parentheses as search variable name: */ varStart+=4; for(varEnd=varStart;*varEnd!='\0'&&*varEnd!=')';++varEnd) ; } else { /* Take the entire string as search variable name: */ for(varEnd=varStart;*varEnd!='\0';++varEnd) ; } varLen=varEnd-varStart; } /********************************************************* Parse any useful information from the CITCOMT file header: *********************************************************/ /* Size of data set in C memory / file order: Z varies fastest, then X, then Y: */ DS::Index numNodes(-1,-1,-1); /* Ordering of coordinate columns in the file: */ int coordColumn[3]={-1,-1,-1}; /* Index of data columns: */ int dataColumn[1]={-1}; char* dataNames[1]={0}; /* Mapping from coordinate columns to spherical coordinates (lat, long, rad): */ int sphericalOrder[3]={-1,-1,-1}; /* Read the first line: */ char line[256]; dataFile.gets(line,sizeof(line)); /* Parse the entire header: */ while(line[0]=='#') { /* Skip hash marks and whitespace: */ char* cPtr=line; while(*cPtr!='\0'&&(*cPtr=='#'||isspace(*cPtr))) ++cPtr; /* Check which header line this is: */ if(strncasecmp(cPtr,"NODES",5)==0) { /* Parse the number of nodes: */ do { /* Check which dimension this is and parse the number of nodes: */ if(toupper(cPtr[5])=='Y') // Y column varies most slowly numNodes[0]=atoi(cPtr+7); else if(toupper(cPtr[5])=='X') numNodes[1]=atoi(cPtr+7); if(toupper(cPtr[5])=='Z') // Z column varies fastest numNodes[2]=atoi(cPtr+7); /* Go to the next field: */ while(*cPtr!='\0'&&!isspace(*cPtr)) ++cPtr; while(*cPtr!='\0'&&isspace(*cPtr)) ++cPtr; } while(strncasecmp(cPtr,"NODES",5)==0); } else if((toupper(cPtr[0])=='X'||toupper(cPtr[0])=='Y'||toupper(cPtr[0])=='Z')&&cPtr[1]=='-') { /* Parse spherical coordinate assignments: */ do { /* Remember which coordinate this is: */ int coordIndex=int(toupper(cPtr[0]))-int('X'); /* Find the end of the spherical component string: */ char* endPtr; for(endPtr=cPtr;*endPtr!='\0'&&*endPtr!=','&&!isspace(*endPtr);++endPtr) ; /* Check which component is assigned: */ if(endPtr-cPtr==5&&strncasecmp(cPtr+2,"LAT",3)==0) sphericalOrder[0]=coordIndex; else if(endPtr-cPtr==5&&strncasecmp(cPtr+2,"LON",3)==0) sphericalOrder[1]=coordIndex; if(endPtr-cPtr==8&&strncasecmp(cPtr+2,"RADIUS",3)==0) sphericalOrder[2]=coordIndex; /* Go to the next field: */ cPtr=endPtr; if(*cPtr==',') ++cPtr; while(*cPtr!='\0'&&isspace(*cPtr)) ++cPtr; } while((toupper(cPtr[0])=='X'||toupper(cPtr[0])=='Y'||toupper(cPtr[0])=='Z')&&cPtr[1]=='-'); } else if(*cPtr=='|') { /* Parse column assignments: */ int columnIndex=0; do { /* Skip separator and whitespace: */ while(*cPtr!='\0'&&(*cPtr=='|'||isspace(*cPtr))) ++cPtr; /* Find the end of the column string: */ char* endPtr; for(endPtr=cPtr;*endPtr!='\0'&&!isspace(*endPtr);++endPtr) ; /* Check which column this is: */ if(endPtr-cPtr==1&&strncasecmp(cPtr,"X",1)==0) coordColumn[0]=columnIndex; else if(endPtr-cPtr==1&&strncasecmp(cPtr,"Y",1)==0) coordColumn[1]=columnIndex; else if(endPtr-cPtr==1&&strncasecmp(cPtr,"Z",1)==0) coordColumn[2]=columnIndex; else if(endPtr-cPtr==4&&strncasecmp(cPtr,"NODE",1)==0) { /* Ignore this column */ } else if(dataColumn[0]<0) { if(varStart==0||(endPtr-cPtr==varLen&&strncasecmp(varStart,cPtr,varLen)==0)) { /* Treat this column as the data column: */ dataColumn[0]=columnIndex; /* Remember the name of the data value: */ if(logScale) { dataNames[0]=new char[varLen+6]; memcpy(dataNames[0],"Log(",4); memcpy(dataNames[0]+4,cPtr,varLen); dataNames[0][4+varLen]=')'; dataNames[0][4+varLen+1]='\0'; } else { dataNames[0]=new char[varLen+1]; memcpy(dataNames[0],cPtr,varLen); dataNames[0][varLen]='\0'; } } } /* Go to the next column: */ cPtr=endPtr; while(*cPtr!='\0'&&isspace(*cPtr)) ++cPtr; ++columnIndex; } while(*cPtr=='|'); } /* Go to the next line: */ dataFile.gets(line,sizeof(line)); } /* Check if all required header information has been read: */ bool headerValid=true; for(int i=0;i<3;++i) if(numNodes[i]<0) headerValid=false; for(int i=0;i<3;++i) if(coordColumn[i]<0) headerValid=false; for(int i=0;i<1;++i) if(dataColumn[i]<0) { if(varStart!=0) Misc::throwStdErr("CitcomtFile::load: Data variable %s not found in CITCOMT header in input file %s",args[2].c_str(),args[0].c_str()); headerValid=false; } if(!headerValid) Misc::throwStdErr("CitcomtFile::load: Invalid CITCOMT header in input file %s",args[0].c_str()); /* Create result data set: */ EarthDataSet<DataSet>* result=new EarthDataSet<DataSet>(args); result->getDs().setData(numNodes); result->setFlatteningFactor(0.0); // Spherical geoid model to simplify vector transformation /* Set the data value's name: */ result->getDataValue().setScalarVariableName(dataNames[0]); result->getDataValue().setVectorVariableName("Velocity"); /* Check if the file is stored in spherical coordinates: */ bool sphericalCoordinates=true; for(int i=0;i<3;++i) if(sphericalOrder[i]<0) sphericalCoordinates=false; /* Constant parameters for geoid formula: */ const double a=6378.14e3; // Equatorial radius in m // const double f=1.0/298.247; // Geoid flattening factor const double scaleFactor=1.0e-3; // Scale factor for Cartesian coordinates /* Determine the number of significant columns: */ int numColumns=0; for(int i=0;i<3;++i) if(numColumns<coordColumn[i]) numColumns=coordColumn[i]; for(int i=0;i<1;++i) if(numColumns<dataColumn[i]) numColumns=dataColumn[i]; ++numColumns; /* Compute a mapping from column indices to coordinate components/data value: */ int* columnMapping=new int[numColumns]; for(int i=0;i<numColumns;++i) columnMapping[i]=-1; for(int i=0;i<3;++i) columnMapping[coordColumn[i]]=i; for(int i=0;i<1;++i) columnMapping[dataColumn[i]]=3+i; /* Read all vertex positions and values: */ Misc::File vectorFile(args[1].c_str(),"rt"); std::cout<<"Reading grid vertex positions and values... 0%"<<std::flush; DS::Array& vertices=result->getDs().getVertices(); DS::Index index; for(index[0]=0;index[0]<vertices.getSize(0);++index[0]) { for(index[1]=0;index[1]<vertices.getSize(1);++index[1]) for(index[2]=0;index[2]<vertices.getSize(2);++index[2]) { /* Parse the coordinate components and the data value from the line: */ double columns[4]; char* cPtr=line; for(int i=0;i<numColumns;++i) { /* Read the column value: */ double val=strtod(cPtr,&cPtr); if(columnMapping[i]>=0) columns[columnMapping[i]]=val; } /* Read the next line from the vector file and parse the vector components: */ vectorFile.gets(line,sizeof(line)); cPtr=line; double vector[3]; /* Order in the file is longitude, radius, latitude: */ vector[1]=strtod(cPtr,&cPtr); vector[2]=strtod(cPtr,&cPtr); vector[0]=strtod(cPtr,&cPtr); DS::GridVertex& v=vertices(index); if(sphericalCoordinates) { /* Convert from spherical to Cartesian coordinates: */ double latitude=columns[sphericalOrder[0]]; double longitude=columns[sphericalOrder[1]]; double radius=columns[sphericalOrder[2]]; double s0=Math::sin(latitude); double c0=Math::cos(latitude); double s1=Math::sin(longitude); double c1=Math::cos(longitude); #if 1 double r=a*radius*scaleFactor; // Use spherical globe model to simplify vector conversion #else double r=(a*(1.0-f*Math::sqr(s0))*radius)*scaleFactor; #endif double xy=r*c0; v.pos[0]=float(xy*c1); v.pos[1]=float(xy*s1); v.pos[2]=float(r*s0); /* Store the scalar value: */ if(logScale) v.value.scalar=float(Math::log10(columns[3])); else v.value.scalar=float(columns[3]); /* Convert the vector value from spherical to Cartesian coordinates: */ v.value.vector[0]=float(c1*(c0*vector[2]-s0*vector[0])-s1*vector[1]); v.value.vector[1]=float(s1*(c0*vector[2]-s0*vector[0])+c1*vector[1]); v.value.vector[2]=float(c0*vector[0]+s0*vector[2]); } else { /* Store the vertex position and value: */ for(int i=0;i<3;++i) v.pos[i]=float(columns[i]); if(logScale) v.value.scalar=float(Math::log10(columns[3])); else v.value.scalar=float(columns[3]); for(int i=0;i<3;++i) v.value.vector[i]=float(vector[i]); } /* Read the next line from the file: */ dataFile.gets(line,sizeof(line)); } std::cout<<"\b\b\b\b"<<std::setw(3)<<((index[0]+1)*100)/vertices.getSize(0)<<"%"<<std::flush; } std::cout<<"\b\b\b\bdone"<<std::endl; /* Clean up: */ delete[] columnMapping; /* Finalize the grid structure: */ result->getDs().finalizeGrid(); #if 0 { /* Save the grid to a pair of binary files: */ Misc::LargeFile gridFile("GridFile.grid","wb",Misc::LargeFile::LittleEndian); Misc::LargeFile dataFile("GridFile.dat","wb",Misc::LargeFile::LittleEndian); /* Write the grid file headers: */ gridFile.write<int>(result->getDs().getNumVertices().getComponents(),3); dataFile.write<int>(result->getDs().getNumVertices().getComponents(),3); dataFile.write<int>(2); dataFile.write<int>(1); dataFile.write<int>(strlen(dataNames[0])); dataFile.write<char>(dataNames[0],strlen(dataNames[0])); dataFile.write<int>(3); dataFile.write<int>(strlen("Velocity")); dataFile.write<char>("Velocity",strlen("Velocity")); /* Write the vertex positions: */ for(DS::Array::iterator vIt=vertices.begin();vIt!=vertices.end();++vIt) { gridFile.write<float>(vIt->pos.getComponents(),3); dataFile.write<Value>(vIt->value); } } #endif /* Clean up and return result: */ delete[] dataNames[0]; return result; }
bool GPSGrid::Preprocess( IImporter* importer, QString dir ) { QString filename = fileInDirectory( dir, "GPSGrid" ); QFile gridFile( filename + "_grid" ); QFile configFile( filename + "_config" ); if ( !openQFile( &gridFile, QIODevice::WriteOnly ) ) return false; if ( !openQFile( &configFile, QIODevice::WriteOnly ) ) return false; std::vector< IImporter::RoutingNode > inputNodes; std::vector< IImporter::RoutingEdge > inputEdges; std::vector< unsigned > nodeIDs; std::vector< unsigned > edgeIDs; std::vector< IImporter::RoutingNode > edgePaths; if ( !importer->GetRoutingNodes( &inputNodes ) ) return false; if ( !importer->GetRoutingEdges( &inputEdges ) ) return false; if ( !importer->GetIDMap( &nodeIDs ) ) return false; if ( !importer->GetEdgeIDMap( &edgeIDs ) ) return false; if ( !importer->GetRoutingEdgePaths( &edgePaths ) ) return false; static const int width = 32 * 32 * 32; std::vector< GridImportEdge > grid; Timer time; for ( std::vector< IImporter::RoutingEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) { std::vector< UnsignedCoordinate > path; path.push_back( inputNodes[i->source].coordinate ); for ( unsigned pathID = 0; pathID < i->pathLength; pathID++ ) path.push_back( edgePaths[pathID + i->pathID].coordinate ); path.push_back( inputNodes[i->target].coordinate ); std::vector< std::pair< unsigned, unsigned > > gridCells; for ( unsigned segment = 1; segment < path.size(); segment++ ) { ProjectedCoordinate sourceCoordinate = path[segment - 1].ToProjectedCoordinate(); ProjectedCoordinate targetCoordinate = path[segment].ToProjectedCoordinate(); sourceCoordinate.x *= width; sourceCoordinate.y *= width; targetCoordinate.x *= width; targetCoordinate.y *= width; NodeID minYGrid = floor( sourceCoordinate.y ); NodeID minXGrid = floor( sourceCoordinate.x ); NodeID maxYGrid = floor( targetCoordinate.y ); NodeID maxXGrid = floor( targetCoordinate.x ); if ( minYGrid > maxYGrid ) std::swap( minYGrid, maxYGrid ); if ( minXGrid > maxXGrid ) std::swap( minXGrid, maxXGrid ); for ( NodeID yGrid = minYGrid; yGrid <= maxYGrid; ++yGrid ) { for ( NodeID xGrid = minXGrid; xGrid <= maxXGrid; ++xGrid ) { if ( !clipEdge( sourceCoordinate, targetCoordinate, ProjectedCoordinate( xGrid, yGrid ), ProjectedCoordinate( xGrid + 1, yGrid + 1 ) ) ) continue; gridCells.push_back( std::pair< unsigned, unsigned >( xGrid, yGrid ) ); } } } std::sort( gridCells.begin(), gridCells.end() ); gridCells.resize( std::unique( gridCells.begin(), gridCells.end() ) - gridCells.begin() ); GridImportEdge clippedEdge; clippedEdge.edge = i - inputEdges.begin(); for ( unsigned cell = 0; cell < gridCells.size(); cell++ ) { clippedEdge.x = gridCells[cell].first; clippedEdge.y = gridCells[cell].second; grid.push_back( clippedEdge ); } } qDebug() << "GPS Grid: distributed edges:" << time.restart() << "ms"; qDebug() << "GPS Grid: overhead:" << grid.size() - inputEdges.size() << "duplicated edges"; qDebug() << "GPS Grid: overhead:" << ( grid.size() - inputEdges.size() ) * 100 / inputEdges.size() << "% duplicated edges"; std::sort( grid.begin(), grid.end() ); qDebug() << "GPS Grid: sorted edges:" << time.restart() << "ms"; std::vector< gg::GridIndex > tempIndex; qint64 position = 0; for ( std::vector< GridImportEdge >::const_iterator edge = grid.begin(); edge != grid.end(); ) { gg::Cell cell; gg::GridIndex entry; entry.x = edge->x; entry.y = edge->y; entry.position = position; tempIndex.push_back( entry ); do { const IImporter::RoutingEdge& originalEdge = inputEdges[edge->edge]; gg::Cell::Edge newEdge; newEdge.source = nodeIDs[originalEdge.source]; newEdge.target = nodeIDs[originalEdge.target]; newEdge.edgeID = edgeIDs[edge->edge]; newEdge.bidirectional = originalEdge.bidirectional; newEdge.pathID = cell.coordinates.size(); newEdge.pathLength = 2 + originalEdge.pathLength; cell.coordinates.push_back( inputNodes[originalEdge.source].coordinate ); for ( unsigned pathID = 0; pathID < originalEdge.pathLength; pathID++ ) cell.coordinates.push_back( edgePaths[pathID + originalEdge.pathID].coordinate ); cell.coordinates.push_back( inputNodes[originalEdge.target].coordinate ); cell.edges.push_back( newEdge ); edge++; } while ( edge != grid.end() && edge->x == entry.x && edge->y == entry.y ); ProjectedCoordinate min( ( double ) entry.x / width, ( double ) entry.y / width ); ProjectedCoordinate max( ( double ) ( entry.x + 1 ) / width, ( double ) ( entry.y + 1 ) / width ); unsigned maxSize = cell.edges.size() * sizeof( gg::Cell::Edge ) * 2 + cell.coordinates.size() * sizeof( UnsignedCoordinate ) * 2 + 100; unsigned char* buffer = new unsigned char[maxSize]; memset( buffer, 0, maxSize ); int size = cell.write( buffer, UnsignedCoordinate( min ), UnsignedCoordinate( max ) ); assert( size < ( int ) maxSize ); #ifndef NDEBUG gg::Cell unpackCell; unpackCell.read( buffer, UnsignedCoordinate( min ), UnsignedCoordinate( max ) ); assert( unpackCell == cell ); #endif gridFile.write( ( const char* ) &size, sizeof( size ) ); gridFile.write( ( const char* ) buffer, size ); delete[] buffer; position += size + sizeof( size ); } qDebug() << "GPS Grid: wrote cells:" << time.restart() << "ms"; gg::Index::Create( filename + "_index", tempIndex ); qDebug() << "GPS Grid: created index:" << time.restart() << "ms"; return true; }