I added a new dimension to an existing netCDF file in fortran using the following code -
retval = nf_open(cfn,NF_WRITE,ncid)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_redef(ncid)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_def_dim(ncid,"xyz",len,dimid_xyz)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_enddef(ncid)
Now I want to be able to fill this dimension with values of zero. The cardinality of this set is equal to the cardinality of the variable in my case geopotential height. In addition I have three other dimensions - time(unlimited), latitude, longitude and level.
I looked up the netCDF API in fortran and I am not sure what is the API to call.When I use the following API
retval = nf_put_var_real(ncid,dimid_xyz,xyzArray)
if (retval .ne. nf_noerr) call handle_err(retval)
it ends up overwriting the geopotential height values with 0.0(which is the only variable in my netCDF file)
How do I go about doing this ?
As I understand it a dimension is distinct from a variable, dimensions can't have values but variables can -- I think a fairly common practice may be to create the dimension and also create a variable with the same name. You can then give the variable whatever values you want.
Your code may look like
retval = nf_open(cfn,NF_WRITE,ncid)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_redef(ncid)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_def_dim(ncid,"xyz",len,dimid_xyz)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_def_var(ncid,"xyz",netcdf_real,1,[dimid_xyz], varid_xyz)
if (retval .ne. nf_noerr) call handle_err(retval)
retval = nf_enddef(ncid)
retval = nf_put_vara(ncid,varid_xyz,[1],[len],arrayOfZero)
if (retval .ne. nf_noerr) call handle_err(retval)
Note I'd recommend against using a variable named len inside your fortran code -- this will clash with the intrinsic of the same name.
Related
While using the fortran interface for HDF5, I created a file using:
CALL h5fcreate_f(filename(1:len_file) &
& , H5F_ACC_TRUNC_F, file_id, error)
and closed datapace/datasets with
CALL h5dclose_f(dataspace_id, error)
CALL h5sclose_f(dataspace_id, error)
finally closed the file with
CALL h5fclose_f(file_id, error)
But the file is not being written immediately. I suspect this is because some dataset/dataspace is still open. Is there a routine to identify or close all open datasets/dataspaces. so the file can be closed?
You can query the number of open identifiers using H5Fget_obj_count_f. You can query the open identifiers themselves using H5Fget_obj_ids. The H5I* procedures then let you query the nature of those open identifiers.
For example:
PROGRAM test_hdf5_get_obj_ids
USE HDF5
IMPLICIT NONE
INTEGER(HID_T) :: file_id
INTEGER(HID_T) :: group_id
INTEGER(HID_T) :: space_id
INTEGER(HID_T) :: set_id
INTEGER :: error
REAL, ALLOCATABLE, TARGET :: data(:)
data = [1.0, 2.0, 3.0]
CALL H5open_f(error)
IF (error < 0) ERROR STOP 'H5open_f failed'
CALL H5Fcreate_f( &
NAME='test_hdf5.h5', &
ACCESS_FLAGS=H5F_ACC_TRUNC_F, & ! HDF5 docs dummy argument spelling error.
FILE_ID=file_id, &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5Fcreate_f failed'
CALL H5Gcreate_f( &
LOC_ID=file_id, &
NAME='Group', &
GRP_ID=group_id, &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5Gcreate_f failed'
CALL H5Screate_simple_f( &
RANK=1, &
DIMS=SHAPE(data, KIND=HSIZE_T), &
SPACE_ID=space_id, &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5Screate_simple_f failed'
CALL H5Dcreate_f( &
LOC_ID=group_id, &
NAME='Dataset', &
TYPE_ID=H5T_NATIVE_REAL, &
SPACE_ID=space_id, &
DSET_ID=set_id, &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5Dcreate_f failed'
CALL H5Dwrite_f( &
DSET_ID=set_id, &
MEM_TYPE_ID=H5T_NATIVE_REAL, &
BUF=C_LOC(data), &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5Dwrite_f failed'
CALL H5Dclose_f(set_id, error)
CALL H5Sclose_f(space_id, error)
! CALL H5Gclose_f(group_id, error) ! Oops - forgot this one.
CALL H5Fclose_f(file_id, error)
BLOCK
INTEGER(SIZE_T) :: obj_count
CALL H5Fget_obj_count_f( &
FILE_ID=INT(H5F_OBJ_ALL_F, HID_T), &
OBJ_TYPE=H5F_OBJ_ALL_F, &
OBJ_COUNT=obj_count, &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5Fget_obj_count_f failed'
PRINT "(I0,' open identifiers')", obj_count
BLOCK
INTEGER(HID_T) :: obj_ids(obj_count)
INTEGER :: i
INTEGER :: type
CHARACTER(:), ALLOCATABLE :: type_text
CALL H5Fget_obj_ids_f( &
FILE_ID=INT(H5F_OBJ_ALL_F, HID_T), &
OBJ_TYPE=H5F_OBJ_ALL_F, &
MAX_OBJS=obj_count, &
OBJ_IDS=obj_ids, &
HDFERR=error )
IF (error < 0) ERROR STOP 'H5F_get_obj_ids_f failed'
DO i = 1, SIZE(obj_ids)
CALL H5Iget_type_f(obj_ids(i), type, error)
IF (error < 0) ERROR STOP 'H5Iget_type_f failed'
IF (type == H5I_FILE_F) THEN
type_text = 'file'
ELSE IF (type == H5I_GROUP_F) THEN
type_text = 'group'
ELSE IF (type == H5I_DATATYPE_F) THEN
type_text = 'datatype'
ELSE IF (type == H5I_DATASPACE_F) THEN
type_text = 'dataspace'
ELSE IF (type == H5I_DATASET_F) THEN
type_text = 'dataset'
ELSE IF (type == H5I_ATTR_F) THEN
type_text = 'attribute'
ELSE
type_text = 'unknown'
END IF
PRINT "('Open identifier ',I0,' is a ',A)", i, type_text
END DO
END BLOCK
END BLOCK
CALL H5close_f(error)
END PROGRAM test_hdf5_get_obj_ids
I have tried the tricks posted here (at least the ones I have found), but I still can't seem to rid myself of the dreaded "Bad DLL Calling Convention" error. Here is my (very simple) c++ code:
VRTTCONVERSION_API long controlVTT(BYTE controlVal, BYTE valueVal)
{
LPSTR controlStr = new char[256];
PCHAR convstrout = new char[256];
if (controlVal == 1) {
controlStr = "Ping";
}else if (controlVal == 2) {
controlStr = "0 Init Tool Default";
}
if (bGetGeneralAccessFunctionPointer()) {
return (pGeneral)(controlStr, convstrout, 256);
}
else {
printf("failed to acquire function pointer.\n");
return -1;
}
}
This SHOULD accept bytes as inputs and return a long. I know the return works as I have another function that doesn't accept any inputs and returns the long and that one works fine.
Here is the VBA code (again, simple):
Public Declare PtrSafe Function controlVTT Lib "VRTTConversionDLL.dll" Alias "#4" (ByVal controlVal As Byte, ByVal valueVal As Byte) As Long
Sub testControl()
Dim retval As Long
Dim bFunc As Byte
Dim bVal As Byte
bVal = 0
bFunc = 1
retval = controlVTT(bFunc, bVal)
MsgBox retval
bFunc = 2
retval = controlVTT(bFunc, bVal)
MsgBox retval
End Sub
I know the #4 alias is correct (from using DLL Export Viewer). This function also works when I call it from another C++ function (see below):
int main()
{
long retVal;
retVal = controlVTT(1, 0);
printf("Return: %08X \n", retVal);
retVal = controlVTT(2, 0);
printf("Return: %08X \n", retVal);
return 0; return 0;
}
Obviously, I'm not a professional programmer and I'm probably missing something basic, but I am truly stuck.
Unfortunatelly, the documentation completely lacks examples (what is really strange), as if it assumes all its readers to be good programmers. Whereas, I'm quite new to C++ and can not really figure out from the documentation how to really prepare and execute statements. I love the way how it is implemented in PDO for PHP. Normally, I just do it like this:
$s = $db->prepare("SELECT id FROM mytable WHERE id = :id");
$s->bindParam(':id', $id);
$s->execute();
or do it using ? tokens:
$data = array();
$data[] = 1;
$data[] = 2;
$s = $db->prepare("SELECT id FROM mytable WHERE id = ? or id = ?");
$s->execute($data);
Now, I have C++ and sqlite3.h in my hands. At this moment, I know just how to connect to database - I do it and get no errors:
sqlite3 * conn;
int rc = sqlite3_open(db_name, &conn);
Please, give some instructions (with clear tiny examples) about how to implement similar things that PDO does in PHP - prepare a statement using named arguments and using ? tokens.
You can find a decent amount of documentation here: sqlite.org
This example does not explain the sqlite3 function calls and parameters in detail, as that is quite a lot of information to cover - instead refer to the given link for more in-depth detail.
This example binds values to the statement in your question multiple times, and reads all query results after each bind:
sqlite3* conn;
sqlite3_stmt* stmt = 0;
int rc = sqlite3_open(db_name, &conn);
// Good idea to always check the return value of sqlite3 function calls.
// Only done once in this example:
if ( rc != SQLITE_OK ) { // Do something }
rc = sqlite3_prepare_v2( conn, "SELECT id FROM myTable WHERE id = ? or id = ?", -1, &stmt, 0 );
// Optional, but will most likely increase performance.
rc = sqlite3_exec( conn, "BEGIN TRANSACTION", 0, 0, 0 );
for ( int bindIndex = 0; bindIndex < number_of_times_you_wish_to_bind; bindIndex++ ) {
// Binding integer values in this example.
// Bind functions for other data-types are available - see end of post.
// Bind-parameter indexing is 1-based.
rc = sqlite3_bind_int( stmt, 1, int_you_wish_to_bind ); // Bind first parameter.
rc = sqlite3_bind_int( stmt, 2, int_you_wish_to_bind ); // Bind second parameter.
// Reading interger results in this example.
// Read functions for other data-types are available - see end of post.
while ( sqlite3_step( stmt ) == SQLITE_ROW ) { // While query has result-rows.
// In your example the column count will be 1.
for ( int colIndex = 0; colIndex < sqlite3_column_count( stmt ); colIndex++ ) {
int result = sqlite3_column_int( stmt, colIndex );
// Do something with the result.
}
}
// Step, Clear and Reset the statement after each bind.
rc = sqlite3_step( stmt );
rc = sqlite3_clear_bindings( stmt );
rc = sqlite3_reset( stmt );
}
char *zErrMsg = 0; // Can perhaps display the error message if rc != SQLITE_OK.
rc = sqlite3_exec( conn, "END TRANSACTION", 0, 0, &zErrMsg ); // End the transaction.
rc = sqlite3_finalize( stmt ); // Finalize the prepared statement.
More Bind Functions
More Read Functions
As I understand from http://hoogli.com/items/Avoid_sqlite3_clear_bindings().html, the step rc = sqlite3_clear_bindings( stmt ); is not necessary in this case.
Unfortunately, I am not yet allowed to post this as a comment to the very good previous answer.
I am using the Cassandra C++ driver in my application. I am observing many crashes. After debugging I identified that even when the query output is zero rows , the if (result == NULL) is false and when I iterate through the result, one place or other it is crashing. Below is the code sample. Please suggest me any solution for this.
const char* query = "SELECT variable_id, variable_name FROM aqm_wfvariables WHERE template_id = ?;";
CassError rc = CASS_OK;
CassSession* session = NULL;
if((session=CassandraDbConnect::getInstance()->getSessionForCassandra())==NULL){
return false;
}
CassStatement* statement = cass_statement_new(query, 1);
cass_statement_bind_int32(statement, 0, wf_template_id );
CassFuture* query_future = cass_session_execute(session, statement);
cass_future_wait(query_future);
rc = cass_future_error_code(query_future);
if (rc != CASS_OK) {
logMsg(DEBUG, 7, "cass_session_execute failed for query #%d:%s:%s", 1, __FILE__, query);
cass_statement_free(statement);
return false;
}
cass_statement_free(statement);
const CassResult* result = cass_future_get_result(query_future);
if (result == NULL) {
cass_future_free(query_future);
logMsg(DEBUG, 7, "No values are returned for query #%d:%s:%s", 1, __FILE__, query);
return false;
}
cass_future_free(query_future);
CassIterator* row_iterator = cass_iterator_from_result(result);
while (cass_iterator_next(row_iterator)) {
const CassRow* row = cass_iterator_get_row(row_iterator);
/* Copy data from the row */
You should use
(result.cass_result_row_count>0)
instead of
(result == NULL)
to verify if query returns zero rows. In your code, result is always an instance of CassResult and not a null reference when zero rows are returned.
add c/c++ code embedding python. all problem is in c code, I don't known how to get the pixel value.
python code:
import Image
format = ""
mode = ""
size = ""
data = list()
def getImage(file):
im = Image.open(file)
global format
global mode
global size
global data
format = im.format
mode = im.mode
size = im.size
width, height = im.size
for x in range(0, height):
for y in range(0, width):
data.append(im.getpixel((x,y)))
return None
in C/C++ code
My get the data length is 0. Any problems of the two for loop?
void loadImage(char *file) {
Image* img = NULL;
Py_Initialize();
if ( !Py_IsInitialized() ) {
std::cerr<<"Python initalize failed.\n";
return NULL;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pName, *pModule, *pFunc, *pArgs;
pName = PyString_FromString("loadImage");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if ( !pModule ) {
PyErr_Print();
std::cerr<<"import loadImage module faild, please confirm where the file 'loadImage.py' is.\n";
return NULL;
}
pFunc = PyObject_GetAttrString(pModule, "getImage");
if ( !pFunc ) {
PyErr_Print();
std::cerr<<"Can't find method getImage in loadImage module.\n";
return NULL;
}
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", file));
PyObject_CallObject(pFunc, pArgs);
PyObject *pFormat, *pMode, *pSize, *pData, *pSeq, *pPixel;
pFormat = PyObject_GetAttrString(pModule, "format");
pMode = PyObject_GetAttrString(pModule, "mode");
pSize = PyObject_GetAttrString(pModule, "size");
if ( !PyTuple_Check(pSize) ) {
std::cerr<<"pSize is not tupple object.\n";
return NULL;
}
pData = PyObject_GetAttrString(pModule, "data");
if ( !pData ) {
std::cerr<<"pData is null.\n";
return NULL;
}
if ( !PyList_Check(pData) ) {
std::cerr<<"pData is not list object.\n";
return NULL;
}
int n = PyList_GET_SIZE(pData);
std::cerr<<n<<"\n";
Py_DECREF(pData);
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_DECREF(pArgs);
std::cerr<<"Py_DECREF over.\n";
}
I get the lenght of pData(is n) is 0.
Well, your code can literally be replaced with a single line:
data = list(Image.open(file).getdata())
The getdata method of Image objects returns the pixels packed into a list, line-by-line. If you need them in column-major order (as you are doing), apply .transpose with the appropriate arguments first. The result will still be substantially faster and simpler than iterating over all the pixels.
You aren't checking the return value from PyObject_CallObject. It might have returned NULL (Python exception), and consequently failed to modify the data list.
You should check every Python API call you make, since exception handling is critically important to making the interpreter work correctly.
If you do get a NULL, you can call PyErr_Print() to get the traceback printed out to stderr (cerr).
The Python code you run by calling PyObject_CallObject is probably throwing an exception.
NULL means an exception was thrown. You can use various python api functions to get at
the actual error: http://docs.python.org/c-api/exceptions.html. This is probably the simplest.
if( PyObject_CallObject(pFunc, pArgs ) == NULL )
{
// Print the exception (a traceback may or may not be available)
PyErr_Print();
// Do any cleanup...
// Always return NULL after a python api function returns NULL.
return NULL;
}
The problem may caused by the python version 2.7 in my computer. I changed to python 3.2, all code can got ideal return.