/** astra_mex_data2d('change_geometry', id, geom); * * Change the associated geometry of a 2d data object (volume or sinogram) * id: identifier of the 2d data object as stored in the astra-library. * geom: the new geometry struct, as created by astra_create_vol/proj_geom */ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { // step1: check input if (nrhs < 3) { mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); return; } if (!mxIsDouble(prhs[1])) { mexErrMsgTxt("Identifier should be a scalar value. \n"); return; } // step2: get data object int iDataID = (int)(mxGetScalar(prhs[1])); CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID); if (!pDataObject || !pDataObject->isInitialized()) { mexErrMsgTxt("Data object not found or not initialized properly.\n"); return; } CFloat32ProjectionData2D* pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject); if (pSinogram) { // Projection data // Read geometry if (!mxIsStruct(prhs[2])) { mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); } XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]); Config cfg; cfg.self = xml->getRootNode(); // FIXME: Change how the base class is created. (This is duplicated // in 'create' and Projector2D.cpp.) std::string type = cfg.self->getAttribute("type"); CProjectionGeometry2D* pGeometry; if (type == "sparse_matrix") { pGeometry = new CSparseMatrixProjectionGeometry2D(); } else if (type == "fanflat") { //CFanFlatProjectionGeometry2D* pFanFlatProjectionGeometry = new CFanFlatProjectionGeometry2D(); //pFanFlatProjectionGeometry->initialize(Config(node)); //m_pProjectionGeometry = pFanFlatProjectionGeometry; pGeometry = new CFanFlatProjectionGeometry2D(); } else if (type == "fanflat_vec") { pGeometry = new CFanFlatVecProjectionGeometry2D(); } else { pGeometry = new CParallelProjectionGeometry2D(); } if (!pGeometry->initialize(cfg)) { mexErrMsgTxt("Geometry class not initialized. \n"); delete pGeometry; delete xml; return; } // If data is specified, check dimensions if (pGeometry->getDetectorCount() != pSinogram->getDetectorCount() || pGeometry->getProjectionAngleCount() != pSinogram->getAngleCount()) { mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); delete pGeometry; delete xml; return; } // If ok, change geometry pSinogram->changeGeometry(pGeometry); delete pGeometry; delete xml; return; } CFloat32VolumeData2D* pVolume = dynamic_cast<CFloat32VolumeData2D*>(pDataObject); if (pVolume) { // Volume data // Read geometry if (!mxIsStruct(prhs[2])) { mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); } XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]); Config cfg; cfg.self = xml->getRootNode(); CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D(); if (!pGeometry->initialize(cfg)) { mexErrMsgTxt("Geometry class not initialized. \n"); delete xml; delete pGeometry; return; } // If data is specified, check dimensions if (pGeometry->getGridColCount() != pVolume->getWidth() || pGeometry->getGridRowCount() != pVolume->getHeight()) { mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); delete xml; delete pGeometry; return; } // If ok, change geometry pVolume->changeGeometry(pGeometry); delete xml; delete pGeometry; } mexErrMsgTxt("Data object not found or not initialized properly.\n"); return; }
/** id = astra_mex_data2d('create', datatype, geometry, data); * * Create a new data 2d object in the astra-library. * type: '-vol' for volume data, '-sino' for projection data * geom: MATLAB struct with the geometry for the data * data: Optional. Can be either a MATLAB matrix containing the data. In that case the dimensions * should match that of the geometry of the object. It can also be a single value, in which case * the entire data will be set to that value. If this isn't specified all values are set to 0. * id: identifier of the 2d data object as it is now stored in the astra-library. */ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[]) { // step1: get datatype if (nrhs < 3) { mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); return; } string sDataType = mex_util_get_string(prhs[1]); CFloat32Data2D* pDataObject2D = NULL; if (nrhs >= 4 && !(mex_is_scalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) { mexErrMsgTxt("Data must be single, double or logical."); return; } if (mxIsSparse(prhs[2])) { mexErrMsgTxt("Data may not be sparse."); return; } // SWITCH DataType if (sDataType == "-vol") { // Read geometry if (!mxIsStruct(prhs[2])) { mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); } XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]); if (!xml) return; Config cfg; cfg.self = xml->getRootNode(); CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D(); if (!pGeometry->initialize(cfg)) { mexErrMsgTxt("Geometry class not initialized. \n"); delete xml; delete pGeometry; return; } // If data is specified, check dimensions if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { if (pGeometry->getGridColCount() != mxGetN(prhs[3]) || pGeometry->getGridRowCount() != mxGetM(prhs[3])) { mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); delete xml; delete pGeometry; return; } } // Initialize data object pDataObject2D = new CFloat32VolumeData2D(pGeometry); delete pGeometry; delete xml; } else if (sDataType == "-sino") { // Read geometry if (!mxIsStruct(prhs[2])) { mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); } XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]); if (!xml) return; Config cfg; cfg.self = xml->getRootNode(); // FIXME: Change how the base class is created. (This is duplicated // in 'change_geometry' and Projector2D.cpp.) std::string type = cfg.self->getAttribute("type"); CProjectionGeometry2D* pGeometry; if (type == "sparse_matrix") { pGeometry = new CSparseMatrixProjectionGeometry2D(); } else if (type == "fanflat") { //CFanFlatProjectionGeometry2D* pFanFlatProjectionGeometry = new CFanFlatProjectionGeometry2D(); //pFanFlatProjectionGeometry->initialize(Config(node)); //m_pProjectionGeometry = pFanFlatProjectionGeometry; pGeometry = new CFanFlatProjectionGeometry2D(); } else if (type == "fanflat_vec") { pGeometry = new CFanFlatVecProjectionGeometry2D(); } else { pGeometry = new CParallelProjectionGeometry2D(); } if (!pGeometry->initialize(cfg)) { mexErrMsgTxt("Geometry class not initialized. \n"); delete pGeometry; delete xml; return; } // If data is specified, check dimensions if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { if (pGeometry->getDetectorCount() != mxGetN(prhs[3]) || pGeometry->getProjectionAngleCount() != mxGetM(prhs[3])) { mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); delete pGeometry; delete xml; return; } } // Initialize data object pDataObject2D = new CFloat32ProjectionData2D(pGeometry); delete pGeometry; delete xml; } else { mexErrMsgTxt("Invalid datatype. Please specify '-vol' or '-sino'. \n"); return; } // Check initialization if (!pDataObject2D->isInitialized()) { mexErrMsgTxt("Couldn't initialize data object.\n"); delete pDataObject2D; return; } // Store data if (nrhs == 3) { for (int i = 0; i < pDataObject2D->getSize(); ++i) { pDataObject2D->getData()[i] = 0.0f; } } // Store data if (nrhs >= 4) { // fill with scalar value if (mex_is_scalar(prhs[3])) { float32 fValue = (float32)mxGetScalar(prhs[3]); for (int i = 0; i < pDataObject2D->getSize(); ++i) { pDataObject2D->getData()[i] = fValue; } } // fill with array value else { const mwSize* dims = mxGetDimensions(prhs[3]); // Check Data dimensions if (pDataObject2D->getWidth() != mxGetN(prhs[3]) || pDataObject2D->getHeight() != mxGetM(prhs[3])) { mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); return; } // logical data if (mxIsLogical(prhs[3])) { bool* pbMatlabData = mxGetLogicals(prhs[3]); int i = 0; int col, row; for (col = 0; col < dims[1]; ++col) { for (row = 0; row < dims[0]; ++row) { pDataObject2D->getData2D()[row][col] = (float32)pbMatlabData[i]; ++i; } } // double data } else if (mxIsDouble(prhs[3])) { double* pdMatlabData = mxGetPr(prhs[3]); int i = 0; int col, row; for (col = 0; col < dims[1]; ++col) { for (row = 0; row < dims[0]; ++row) { pDataObject2D->getData2D()[row][col] = pdMatlabData[i]; ++i; } } // single data } else if (mxIsSingle(prhs[3])) { const float* pfMatlabData = (const float *)mxGetData(prhs[3]); int i = 0; int col, row; for (col = 0; col < dims[1]; ++col) { for (row = 0; row < dims[0]; ++row) { pDataObject2D->getData2D()[row][col] = pfMatlabData[i]; ++i; } } } else { ASTRA_ASSERT(false); } } } // step4: store data object int iIndex = CData2DManager::getSingleton().store(pDataObject2D); // step5: return data id if (1 <= nlhs) { plhs[0] = mxCreateDoubleScalar(iIndex); } }
CVolumeGeometry2D * CVolumeGeometry3D::createVolumeGeometry2D() const { CVolumeGeometry2D * pOutput = new CVolumeGeometry2D(); pOutput->initialize(getGridColCount(), getGridRowCount()); return pOutput; }