template<typename T> inline mxArray * ptr2Mat(std::shared_ptr<T> ptr) { mexLock(); mxArray *out = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL); *((uint64_t *)mxGetData(out)) = reinterpret_cast<uint64_t>(new Handle<T>(ptr)); return out; }
extern bool aperture_bft_ctor_manual(mxArray*& plhs, const mxArray* mx_pos_vec) { const float_type* pos_vec; size_t n_dim; size_t n_elements; size_t length; Aperture* p_aperture; Call(mxIsRealFloat, (mx_pos_vec)); n_elements = mxGetM(mx_pos_vec); Call(2 == mxGetNumberOfDimensions,(mx_pos_vec)); n_dim = (size_t) mxGetDimensions(mx_pos_vec)[1]; length = n_dim*n_elements; if (n_dim != (int) 3) Fail("Positions must be 3D"); pos_vec = ((const float_type *) mxGetData(mx_pos_vec)); p_aperture = new Aperture(pos_vec, (size_t)length); plhs = create_handle<Aperture>(p_aperture); enable_aperture_destructor = true; mexLock(); // Fixed static variables return true; }
template<class base> inline mxArray *convertPtr2Mat(base *ptr) { mexLock(); mxArray *out = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL); *((uint64_t *)mxGetData(out)) = reinterpret_cast<uint64_t>(new class_handle<base>(ptr)); return out; }
extern bool aperture_bft_ctor_field(mxArray*& plhs, const mxArray* mx_type, const mxArray* mx_n_elements, const mxArray* mx_pitch, const mxArray* mx_f0) { const float_type *pitch; mwSize n_elements; char type[256]; Aperture* p_aperture; Call(mxIsChar, (mx_type)); Call(mxu_fixed_string, (type, 256, mx_type, "1st argument")); if (strcmp(type,"linear_array")) { mexPrintf(type); Fail("Unsupported Field II aperture"); } Call(mxIsScalarFloat, (mx_pitch)); Call(mxIsScalarInt32, (mx_n_elements)); pitch = ((const float_type *) mxGetData(mx_pitch)); n_elements = mxGetInt(mx_n_elements); Aperture::_f0 = *((const float_type*) mxGetData(mx_f0)); p_aperture = new Aperture((size_t) n_elements, *pitch); plhs = create_handle<Aperture>(p_aperture); enable_aperture_destructor = true; mexLock(); return true; }
static void UpdateUserData(mxArray *new_mtlb_data, kimInterfaceData kimData) { mexUnlock(); mxDestroyArray(kimData->mtlb_data); kimData->mtlb_data = mxDuplicateArray(new_mtlb_data); mexMakeArrayPersistent(kimData->mtlb_data); mexLock(); }
static void UpdateMonitorDataB(mxArray *mx_newdata) { mexUnlock(); mxDestroyArray(mx_MONdataB); mx_MONdataB = mxDuplicateArray(mx_newdata); mexMakeArrayPersistent(mx_MONdataB); mexLock(); }
static void UpdateMonitorData(mxArray *new_mtlb_data, cvmPbData pb) { mexUnlock(); mxDestroyArray(pb->MONdata); pb->MONdata = mxDuplicateArray(new_mtlb_data); mexMakeArrayPersistent(pb->MONdata); mexLock(); }
static void UpdateUserData(mxArray *mx_newdata) { mexUnlock(); mxDestroyArray(mx_data); mx_data = mxDuplicateArray(mx_newdata); mexMakeArrayPersistent(mx_data); mexLock(); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { GPUmatResult_t status = GPUmatSuccess; // tmp mxArray *lhs[2]; if (nrhs != 1) mexErrMsgTxt("Wrong number of arguments"); // the passed element should be a GPUsingle if (!(mxIsClass(prhs[0], "GPUdouble"))) mexErrMsgTxt(ERROR_EXPECTED_GPUDOUBLE); if (init == 0) { // Initialize function mexLock(); // load GPUmanager mexCallMATLAB(2, &lhs[0], 0, NULL, "GPUmanager"); GPUman = (GPUmanager *) (UINTPTR mxGetScalar(lhs[0])); mxDestroyArray(lhs[0]); init = 1; } GPUtype *p = mxToGPUtype(prhs[0], GPUman); int numel = p->getNumel(); int ndims = p->getNdims(); int *size = p->getSize(); int mysize = p->getMySize(); gpuTYPE_t type = p->getType(); // create dest array // dims re set to [1 numel]. A reshape is required outside // this function mwSize dims[2]; // create destination if (type == gpuDOUBLE) { dims[0] = 1; dims[1] = numel; plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); } else if (type == gpuCDOUBLE) { dims[0] = 1; dims[1] = 2 * numel; plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); } try { status = GPUopCudaMemcpy(mxGetPr(plhs[0]), p->getGPUptr(), mysize * numel, cudaMemcpyDeviceToHost, p->getGPUmanager()); } catch (GPUexception ex) { mexErrMsgTxt(ex.getError()); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int mode; /* Modes: 1 - initialize KINSOL solver 2 - solve problem 3 - get solver stats 4 - extract data from kin_mem 5 - set one optional input at a time 6 - finalize */ mode = (int)mxGetScalar(prhs[0]); mexUnlock(); switch(mode) { case 1: if (kim_Kdata != NULL) { /* a previous pb ws initialized, we must clear memory */ KIM_Free(nlhs, plhs, nrhs-1, &prhs[1]); KIM_final(); } KIM_init(); KIM_Malloc(nlhs, plhs, nrhs-1, &prhs[1]); break; case 2: KIM_Solve(nlhs, plhs, nrhs-1, &prhs[1]); break; case 3: KIM_Stats(nlhs, plhs, nrhs-1, &prhs[1]); break; case 4: KIM_Get(nlhs, plhs, nrhs-1, &prhs[1]); break; case 5: KIM_Set(nlhs, plhs, nrhs-1, &prhs[1]); break; case 6: KIM_Free(nlhs, plhs, nrhs-1, &prhs[1]); KIM_final(); break; } /* do not call KIM_makePersistent after free */ if (mode != 6) KIM_makePersistent(); mexLock(); return; }
void initMEX(void) { #ifdef CONSOLEDEBUG ThorMexDebugger::getInstance()->setConsoleAttribsForThread(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY); CONSOLETRACE(); #endif scannerMap::scannerID2ThorLSMObj = new std::map<int,ThorLSM*>; assert(scannerMap::scannerID2ThorLSMObj!=NULL); mexLock(); mexAtExit(uninitMEX); mexInitted = true; }
//============================================================================= // MexFile::init //============================================================================= int MexFile::init (void) { // return if already initialized if (MexFile::initialized) { return kNoError; } #if ! defined(SCILAB) mexLock(); #endif try { Tango::ApiUtil * tapiu = Tango::ApiUtil::instance(); tapiu->create_orb(); } catch (...) { //-::mexPrintf("mexFunction::ORB initialization failed\n"); return kError; } // initialize utilities if (MexUtils::init() == kError) { //-- can't use error stack since it may not be initialized return kError; } // initialize the TANGO binding class if (TangoBinding::init() == kError) { //-::mexPrintf("mexFunction::TangoBinding initialization failed\n"); return kError; } #if ! defined(WIN32) //- set cleanup function (called when mex-file is discarded from memory) # if ! defined(SCILAB) ::mexAtExit(c_cleanup); # else ::mexAtExit((mxArray*)(&c_cleanup)); # endif #endif // initialization done MexFile::initialized = 1; MEX_MSG(("MEX-File initialized")); return kNoError; }
/* ---- */ void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { char id[512]; if (nrhs == 0) { mexPrintf("Mex function installed\n"); return; } if (mxGetString(prhs[0], id, sizeof(id)) != 0) mexErrMsgTxt("Identifier should be a string"); else if (strcmp(id, stubids1_) == 0) mexStub1(nlhs,plhs, nrhs-1,prhs+1); else if (strcmp(id, stubids2_) == 0) mexStub2(nlhs,plhs, nrhs-1,prhs+1); else if (strcmp(id, stubids3_) == 0) mexStub3(nlhs,plhs, nrhs-1,prhs+1); else if (strcmp(id, "*profile on*") == 0) { if (!mexprofrecord_) { mexprofrecord_ = (int*) malloc(4 * sizeof(int)); mexLock(); } memset(mexprofrecord_, 0, 4 * sizeof(int)); } else if (strcmp(id, "*profile off*") == 0) { if (mexprofrecord_) { free(mexprofrecord_); mexUnlock(); } mexprofrecord_ = NULL; } else if (strcmp(id, "*profile report*") == 0) { if (!mexprofrecord_) mexPrintf("Profiler inactive\n"); mexPrintf("%d calls to rotproj_r2012a.mw:50\n", mexprofrecord_[1]); mexPrintf("%d calls to rotproj_r2012a.mw:54\n", mexprofrecord_[2]); mexPrintf("%d calls to rotproj_r2012a.mw:111\n", mexprofrecord_[3]); } else if (strcmp(id, "*profile log*") == 0) { FILE* logfp; if (nrhs != 2 || mxGetString(prhs[1], id, sizeof(id)) != 0) mexErrMsgTxt("Must have two string arguments"); logfp = fopen(id, "w+"); if (!logfp) mexErrMsgTxt("Cannot open log for output"); if (!mexprofrecord_) fprintf(logfp, "Profiler inactive\n"); fprintf(logfp, "%d calls to rotproj_r2012a.mw:50\n", mexprofrecord_[1]); fprintf(logfp, "%d calls to rotproj_r2012a.mw:54\n", mexprofrecord_[2]); fprintf(logfp, "%d calls to rotproj_r2012a.mw:111\n", mexprofrecord_[3]); fclose(logfp); } else mexErrMsgTxt("Unknown identifier"); }
/* Initialize a ZMQ server */ int initialize(char *socket_addr) { int rc; mexLock(); ctx = zmq_ctx_new(); socket_ptr = zmq_socket(ctx, ZMQ_REP); rc = zmq_bind(socket_ptr, socket_addr); if (!rc) { initialized = 1; return 0; } else { return -1; } }
// This function does all the work. It spawns all of the threads that do all the searching. void mexFunction(int nlhs,mxArray* plhs[], int nrhs, const mxArray* prhs[]) { // Don't ever allow this mex file to be cleared. This prevents a hang // because this call utilizes the MIC processor. mexLock(); if( nrhs < 2 ) { mexErrMsgTxt("result = SearchNNBMEX(SolidImage, ReconInfoStruct)"); } else if( !( mxIsDouble(prhs[0])&&mxIsStruct(prhs[1])) ) { mexErrMsgTxt("SolidImage must be of type double. ReconInfoStruct must be a structure."); } if( nlhs < 1 ) mexErrMsgTxt("Too few output arguments specified."); // Get the reconstruction image double *S_start = mxGetPr(prhs[0]); // Get the number of dimensions mwSize NUM_DIMS = mxGetNumberOfDimensions(prhs[0]); const int *DIMS = mxGetDimensions(prhs[0]); Image4D S(S_start, DIMS[0], DIMS[1], DIMS[2], 1); if(NUM_DIMS < 2) mexErrMsgTxt("SolidImage must at least be 2D"); int XSIZE = DIMS[0]; // Number of rows int YSIZE = DIMS[1]; // Number of columns int ZSIZE = (NUM_DIMS < 3) ? 1 : DIMS[2]; int TOTAL_SIZE = XSIZE*YSIZE*ZSIZE*sizeof(double); // Extract all the fields from our structure. ReconInfo * Recon = new ReconInfo(prhs[1]); // Run the search, this function has side effects. It will // update the nearest neighborhoods table. unsigned int * nnb_table = Recon->SearchIt(S); // Copy the result to an output array. int NNB_DIMS[] = {XSIZE, YSIZE, ZSIZE, Recon->getNumExemplars()}; plhs[0] = mxCreateNumericArray(4, NNB_DIMS, mxUINT32_CLASS, mxREAL); memcpy(mxGetData(plhs[0]), (void *)nnb_table, XSIZE*YSIZE*ZSIZE*Recon->getNumExemplars()*sizeof(unsigned int)); delete Recon; delete nnb_table; }
template<class base> inline mxArray *convertPtr2Mat(base *ptr) { // lock the memory used in this function so it is not automatically // cleaned up by matlab/octave mexLock(); // create a 64 bit integer array to return a pointer to the class for // storage in a normal matlab variable mxArray *out = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL); // now create a new instance of a class_handle class wrapping the c++ // class to be wrapped, convert the pointer to the class to a uint64 // and place it in the array created to hold it *((uint64_t *)mxGetData(out)) = reinterpret_cast<uint64_t>(new class_handle<base>(ptr)); return out; }
/* * Initializes numerics MODULE. * 1) Load GPU kernels * 2) Register functions in GPUmat structure * */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs != 0) mexErrMsgTxt("Wrong number of arguments"); if (init == 0) { // Initialize function mexLock(); // load GPUmat gm = gmGetGPUmat(); // load module // nothing to load //************************************************************************ // INIT //************************************************************************ seed = 0; // init curand //if (curandCreateGenerator(&gen,CURAND_RNG_PSEUDO_DEFAULT)!=CURAND_STATUS_SUCCESS) { // mexErrMsgTxt(ERROR_CURAND_INIT); //} //************************************************************************ // REGISTER FUNCTION IN GPUMAT STRUCTURE //************************************************************************ // put here functions to be registered gm->rand.rand = GPUrand; gm->rand.mxRandDrv = GPUmxRandDrv; gm->rand.randn = GPUrandn; gm->rand.mxRandnDrv = GPUmxRandnDrv; //************************************************************************ // UPDATE FLAGS //************************************************************************ gm->mod.rand = 1; // rand module was loaded init = 1; } }
static void lock_persistent() { if ( !mexIsLocked() ) { mexLock(); if ( atExitSubscribe(&persistentAtExit) < 0 ) { mexErrMsgTxt("lock_persistent(): atExitSubscribe() failed.\n" "This is a bug probably. Please report it.\n"); } } else { mexErrMsgTxt("lock_persistent(): persistent is already locked.\n" "This is a bug probably. Please report it.\n"); } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int result; if (nrhs != 0) { mexErrMsgIdAndTxt("glfw:usage", "Usage: glfwInit()"); return; } result = glfwInit(); if (result == GL_FALSE) { mexErrMsgIdAndTxt("glfw:failed", "An error occurred"); return; } // Lock this function in memory to stop Windows from failing to init after calling "clear all" prior to glfwTerminate. mexLock(); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { bool amLocked = mexIsLocked(); /* Our check for if this has been called already */ if(nlhs == 1) { mwSize dims[2]; dims[0] = 1; dims[1] = 1; plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); } int x, y; x = MPI_Initialized(&y); if(amLocked || y) { if(nlhs == 1) *(mxGetPr(plhs[0])) = 1.0; return; } mexLock(); MPI_Init(NULL, NULL); if(nlhs == 1) *(mxGetPr(plhs[0])) = 0.0; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { AVbinOptions options; AVbinResult result; if (nrhs != 0) { mexErrMsgIdAndTxt("avbin:usage", "Usage: avbin_init()"); return; } options.structure_size = sizeof(options); options.thread_count = 0; result = avbin_init_options(&options); if (result == AVBIN_RESULT_ERROR) { mexErrMsgIdAndTxt("avbin:failed", "An error occurred"); return; } // Lock this function in memory to prevent a call to "clear all" from crashing Matlab. mexLock(); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { static first = 1; char key[MAXNAME]; int i; if (first==1) { first = 0; /* prevent Matlab from clearing GridLAB */ mexLock(); /* register Matlab output routines */ output_set_stdout(mexPrintf); output_set_stderr(cmex_printerr); /* display legal stuff */ legal_license(); /* initialize GridLAB */ exec_init(); } /* check number of input arguments */ if (nrhs<1) { output_error("Use gl('help') for a list of commands."); return; } /* check type of first argument */ if (!mxIsChar(prhs[0])) { output_error("token must be a string"); return; } /* read first argument */ if (mxGetString(prhs[0],key,sizeof(key))!=0) output_warning("GridLAB key string too long"); /* scan command map to find call function */ for (i=0; i<sizeof(cmdMap)/sizeof(cmdMap[0]); i++) { if (strcmp(key,cmdMap[i].name)==0) { if (cmdMap[i].call == NULL) /* help request */ { int j; if (nrhs==1) { output_raw("Available top-level commands\n"); for (j=0; j<sizeof(cmdMap)/sizeof(cmdMap[0]); j++) output_raw("\t%s\t%s\n", cmdMap[j].name, cmdMap[j].brief); output_raw("Use gl('help',command) for details\n"); return; } else if (mxIsChar(prhs[1])) { char cmd[MAXNAME]; if (mxGetString(prhs[1],cmd,sizeof(cmd))!=0) output_warning("command string too long to read fully"); for (j=0; j<sizeof(cmdMap)/sizeof(cmdMap[0]); j++) { if (strcmp(cmd,cmdMap[j].name)==0) { output_raw("Help for command '%s'\n\n%s\n", cmd, cmdMap[j].detail ? cmdMap[j].detail : "\tNo details available\n"); return; } } output_error("Command '%s' does not exist", cmd); return; } else { output_error("command must be a string"); return; } } else { (cmdMap[i].call)(nlhs,plhs,nrhs-1,prhs+1); return; } } } /* function not found */ { int nret = nlhs; output_error("unrecognized GridLAB operation--gl('help') for list"); while (nret-->0) plhs[nret] = mxCreateDoubleMatrix(0,0,mxREAL); } return; }
/* * Initializes numerics MODULE. * 1) Load GPU kernels * 2) Register functions in GPUmat structure * */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs != 0) mexErrMsgTxt("Wrong number of arguments"); if (init == 0) { // Initialize function mexLock(); // load GPUmat gm = gmGetGPUmat(); // load module CUmodule *drvmod = gmGetModule("numerics"); //************************************************************************ // EYE GPU KERNELS //************************************************************************ // load float GPU function CUresult status = cuModuleGetFunction(&EYEdrvfuns[N_EYEF], *drvmod, "EYEF"); if (CUDA_SUCCESS != status) { mexErrMsgTxt("Unable to load user function."); } // load complex GPU function status = cuModuleGetFunction(&EYEdrvfuns[N_EYEC], *drvmod, "EYEC"); if (CUDA_SUCCESS != status) { mexErrMsgTxt("Unable to load user function."); } // load double GPU function status = cuModuleGetFunction(&EYEdrvfuns[N_EYED], *drvmod, "EYED"); if (CUDA_SUCCESS != status) { mexErrMsgTxt("Unable to load user function."); } // load complex GPU function status = cuModuleGetFunction(&EYEdrvfuns[N_EYEDC], *drvmod, "EYEDC"); if (CUDA_SUCCESS != status) { mexErrMsgTxt("Unable to load user function."); } //************************************************************************ // REGISTER FUNCTION IN GPUMAT STRUCTURE //************************************************************************ // put here functions to be registered gm->gputype.mxRepmatDrv = GPUmxRepmatDrv; gm->gputype.mxPermuteDrv = GPUmxPermuteDrv; gm->gputype.mxEyeDrv = GPUmxEyeDrv; gm->gputype.eye = GPUeye; gm->gputype.mxZerosDrv = GPUmxZerosDrv; gm->gputype.zeros = GPUzeros; gm->gputype.mxOnesDrv = GPUmxOnesDrv; gm->gputype.ones = GPUones; gm->gputype.mxFill = GPUmxFill; gm->gputype.mxColonDrv = GPUmxColon; gm->gputype.mxMemCpyDtoD = GPUmxMemCpyDtoD; gm->gputype.mxMemCpyHtoD = GPUmxMemCpyHtoD; // aux gm->aux.mxAssign = GPUmxAssign; gm->aux.mxSliceDrv = GPUmxSliceDrv; //************************************************************************ // UPDATE FLAGS //************************************************************************ gm->mod.numerics = 1; // numerics module was loaded init = 1; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *y; int buflen, i, t; char *task = "", *parName = ""; U32 serialnumber; /* make sure plDevices stays in memory, even when doing 'clear all' or 'clear mex'. */ mexLock(); plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL); y = mxGetPr(plhs[0]); y[0]=1; if ((nrhs > 0) && mxIsChar(prhs[0])) /* 1st argument (task) should be a string */ { /* allocate memory for task string and get the 1st argument */ buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0]) * sizeof(mxChar)) + 1; task = (char *)mxCalloc(buflen, sizeof(char)); mxGetString(prhs[0], task, buflen); if (nrhs >= 2) /* if it exists, the 2nd argument is the serial number */ { if (!mxIsDouble(prhs[1])) { mexPrintf("Internal error: call to plDevices failed.\n"); mexPrintf("2nd argument should be the serial number.\n"); mexErrMsgTxt("\n"); } /* get the 2nd argument (serial number) */ serialnumber = (U32)mxGetScalar(prhs[1]); } switch (nrhs) { /* print has 1 argument (task) */ case 1: if (!strcmp(task, "print")) { for (i = 0; i < deviceCount; i++) { mexPrintf("Device nr: %d --> %d, %d: GrabOutputType = %d\n", i, deviceArray[i].serialNumber, deviceArray[i].deviceID, deviceArray[i].grabOutputType); } } else { mexPrintf("Internal error: call to plDevices failed.\n"); mexPrintf("Wrong number of arguments (1) is given or unknown task %s.", task); mexErrMsgTxt("\n"); } break; /* remove, isopen, get have 2 arguments (task, serialnumber) */ case 2: if (!strcmp(task, "remove")) { for (i = 0; i < deviceCount; i++) { if (deviceArray[i].serialNumber == serialnumber) { for (t = i; t < deviceCount; t++) { deviceArray[t].serialNumber = deviceArray[t+1].serialNumber; deviceArray[t].deviceID = deviceArray[t+1].deviceID; } deviceCount--; } } } else if (!strcmp(task, "isopen")) { /* initialise return value */ //plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL); //y = mxGetPr(plhs[0]); /* return 0, unless the loop finds a matching serialnumber */ y[0] = 0; for (i = 0; i < deviceCount;i++) { if (deviceArray[i].serialNumber == serialnumber) { y[0] = 1; /* found matching serialnumber, return 1 */ break; } } } else if (!strcmp(task, "get")) { /* initialise return value */ //plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL); //y = mxGetPr(plhs[0]); /* return -1, unless the loop finds a matching serialnumber */ y[0] = -1; for (i = 0; i < deviceCount;i++) { if (deviceArray[i].serialNumber == serialnumber) { y[0] = (double)deviceArray[i].deviceID; break; /* found a matching serialnumber, end search */ } } } else { mexPrintf("Internal error: call to plDevices failed.\n"); mexPrintf("Wrong number of arguments (2) is given or unknown task %s.", task); mexErrMsgTxt("\n"); } break; /* add has 3 arguments (task, serialnumber, deviceid) * getpar has 3 arguments (task, serialnumber, parameter name) */ case 3: if (!strcmp(task, "add")) { if (deviceCount >= 32) mexErrMsgTxt("Maximum number of open devices (32) reached.\n"); deviceArray[deviceCount].serialNumber = serialnumber; deviceArray[deviceCount].deviceID = (U32)mxGetScalar(prhs[2]); //deviceArray[deviceCount].grabColorConversion = PIXEL_FORMAT_BAYER8_GRBG; //modified to new version deviceArray[deviceCount].grabOutputType = RAW; deviceCount++; } else if (!strcmp(task, "getpar")) { /* allocate memory for parName string and get the 3rd argument */ buflen = (mxGetM(prhs[2]) * mxGetN(prhs[2]) * sizeof(mxChar)) + 1; parName = (char *)mxCalloc(buflen, sizeof(char)); mxGetString(prhs[2], parName, buflen); if (!strcmp(parName, "GrabOutputType")) { t = 1; for (i = 0; i < deviceCount;i++) { if (deviceArray[i].serialNumber == serialnumber) { y[0] = (double)deviceArray[i].grabOutputType; t = 0; break; /* found a matching serialnumber, end search */ } } if (t) { mexPrintf("Internal error: getpar called with unknown serial number %d", serialnumber); mexErrMsgTxt("\n"); } } else { mexPrintf("getpar called with unknown parameter name %s.", parName); mexErrMsgTxt("\n"); } } else { mexPrintf("Internal error: call to plDevices failed.\n"); mexPrintf("Wrong number of arguments (3) is given or unknown task %s.", task); mexErrMsgTxt("\n"); } break; /* setpar has 4 arguments */ case 4: if (!strcmp(task, "setpar")) { /* allocate memory for parName string and get the 3rd argument */ buflen = (mxGetM(prhs[2]) * mxGetN(prhs[2]) * sizeof(mxChar)) + 1; parName = (char *)mxCalloc(buflen, sizeof(char)); mxGetString(prhs[2], parName, buflen); if (!strcmp(parName, "GrabOutputType")) { t = 1; for (i = 0; i < deviceCount;i++) { if (deviceArray[i].serialNumber == serialnumber) { deviceArray[i].grabOutputType = (U32)mxGetScalar(prhs[3]); t = 0; break; /* found a matching serialnumber, end search */ } } if (t) { mexPrintf("Internal error: setpar called with unknown serial number %d", serialnumber); mexErrMsgTxt("\n"); } } else { mexPrintf("getpar called with unknown parameter name %s.", parName); mexErrMsgTxt("\n"); } } else { mexPrintf("Internal error: call to plDevices failed.\n"); mexPrintf("Wrong number of arguments (4) is given or unknown task %s.", task); mexErrMsgTxt("\n"); } break; default: mexPrintf("Internal error: call to plDevices failed.\n"); mexErrMsgTxt("Number of arguments out of range.\n"); } } else { y[0]=-1; mexPrintf("Internal error: call to plDevices failed.\n"); mexPrintf("First argument should be a string with the name of the task to be performed.\n"); mexErrMsgTxt("\n"); } }
//========================================================================= void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Documentation of the calling forms is given within each if clause if (!locked) { //NOTE: If we run clear all this will clear the definition of //this file and depending on whether or not we had open references //could cause Matlab to crash. By locking this file we prevent //clearing the file (which means we can't recompile it unless we //close Matlab) but we also prevent Matlab from crashing. // //TODO: Implement allowing unlock by reference counting //TODO: Alternatively we could pass in a command to unlock mexLock(); locked = 1; } ADI_FileHandle fileH(0); //Setup output result code //----------------------------------------------- //Each function returns a result code, indicating if the function call //worked or not. ADIResultCode result; int *out_result; //Each function will return a result code as well as //possibly other values .. plhs[0] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); out_result = (int *) mxGetData(plhs[0]); //Which function to call double function_option = mxGetScalar(prhs[0]); //Function list //-------------------------------------- // 0 ADI_OpenFile // 1 ADI_GetNumberOfRecords // 2 ADI_GetNumberOfChannels // 3 ADI_GetNumTicksInRecord // 4 ADI_GetRecordTickPeriod // 5 ADI_GetNumSamplesInRecord // 6 ADI_CreateCommentsAccessor // 7 ADI_CloseCommentsAccessor // 8 ADI_GetCommentInfo // 9 ADI_NextComment // 10 ADI_GetSamples // 11 ADI_GetUnitsName // 12 ADI_GetChannelName // 13 ADI_CloseFile // 14 ADI_GetErrorMessage // 15 ADI_GetRecordSamplePeriod // 16 ADI_GetRecordTime // 17 ADI_CreateFile if (function_option == 0) { // ADI_OpenFile <> openFile // =================================================== // [result_code,file_h] = sdk_mex(0,file_path) wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); //long openMode = getLongInput(prhs,2); result = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadOnly); out_result[0] = result; setFileHandle(plhs,result,fileH); } else if (function_option == 0.5) { //This is a call to open the file for reading and writing // //TODO: Replace this with an input to function 0 wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); result = ADI_OpenFile(w_file_path, &fileH, kOpenFileForReadAndWrite); out_result[0] = result; setFileHandle(plhs,result,fileH); } else if (function_option == 1) { // ADI_GetNumberOfRecords <> getNumberOfRecords // ====================================================== // [result_code,n_records] = sdk_mex(1,file_handle) long nRecords = 0; fileH = getFileHandle(prhs); //ADIResultCode ADI_GetNumberOfRecords(ADI_FileHandle fileH, long* nRecords); result = ADI_GetNumberOfRecords(fileH,&nRecords); out_result[0] = result; setLongOutput(plhs,1,nRecords); } else if (function_option == 2) { // ADI_GetNumberOfChannels <> getNumberOfChannels // ======================================================== // [result_code,n_channels] = sdk_mex(2,file_handle) long nChannels = 0; fileH = getFileHandle(prhs); //ADIResultCode ADI_GetNumberOfChannels(ADI_FileHandle fileH, long* nChannels); result = ADI_GetNumberOfChannels(fileH,&nChannels); out_result[0] = result; setLongOutput(plhs,1,nChannels); } else if (function_option == 3) { // ADI_GetNumTicksInRecord <> getNTicksInRecord // ====================================================== // [result,n_ticks] = sdk_mex(3,file_handle,record_idx_0b) fileH = getFileHandle(prhs); //0 or 1 based ... long record = getLongInput(prhs,2); long nTicks = 0; //ADIResultCode ADI_GetNumTicksInRecord(ADI_FileHandle fileH, long record, long* nTicks); result = ADI_GetNumTicksInRecord(fileH,record,&nTicks); out_result[0] = result; setLongOutput(plhs,1,nTicks); } else if (function_option == 4) { // ADI_GetRecordTickPeriod <> getTickPeriod // ========================================================= // [result,s_per_tick] = sdk_mex(4,file_handle,record_idx_0b,channel_idx_0b) fileH = getFileHandle(prhs); long record = getLongInput(prhs,2); long channel = getLongInput(prhs,3); double secsPerTick = 0; //ADIResultCode ADI_GetRecordTickPeriod(ADI_FileHandle fileH, long channel, long record, double* secsPerTick); out_result[0] = ADI_GetRecordTickPeriod(fileH,channel,record,&secsPerTick); setDoubleOutput(plhs,1,secsPerTick); } else if (function_option == 5) { // ADI_GetNumSamplesInRecord <> getNSamplesInRecord // ======================================================== // [result_code,n_samples] = sdk_mex(5,file_handle,record_idx_0b,channel_idx_0b); fileH = getFileHandle(prhs); long record = getLongInput(prhs,2); long channel = getLongInput(prhs,3); long nSamples = 0; //ADIResultCode ADI_GetNumSamplesInRecord(ADI_FileHandle fileH, long channel, long record, long* nSamples); out_result[0] = ADI_GetNumSamplesInRecord(fileH,channel,record,&nSamples); setLongOutput(plhs,1,nSamples); } else if (function_option == 6) { // ADI_CreateCommentsAccessor <> getCommentAccessor // ======================================================== // [result_code,comments_h] = sdk_mex(6,file_handle,record_idx_0b); ADI_CommentsHandle commentsH(0); fileH = getFileHandle(prhs); long record = getLongInput(prhs,2); //ADIResultCode ADI_CreateCommentsAccessor(ADI_FileHandle fileH, long record, ADI_CommentsHandle* commentsH); result = ADI_CreateCommentsAccessor(fileH,record,&commentsH); out_result[0] = result; int64_t *p_c; plhs[1] = mxCreateNumericMatrix(1,1,mxINT64_CLASS,mxREAL); p_c = (int64_t *) mxGetData(plhs[1]); if (result == 0) p_c[0] = (int64_t)commentsH; else p_c[0] = 0; } else if (function_option == 7) { // ADI_CloseCommentsAccessor <> closeCommentAccessor // ======================================================== // result_code = sdk_mex(7,comments_h); ADI_CommentsHandle commentsH = getCommentsHandle(prhs); //ADIResultCode ADI_CloseCommentsAccessor(ADI_CommentsHandle *commentsH); out_result[0] = ADI_CloseCommentsAccessor(&commentsH); } else if (function_option == 8) { // ADI_GetCommentInfo <> getCommentInfo // ==================================================== // [result_code,comment_string,comment_length,tick_pos,channel,comment_num] = sdk_mex(8,comment_h) // // Status: Done ADI_CommentsHandle commentsH = getCommentsHandle(prhs); wchar_t *messageOut = getStringOutputPointer(plhs,1); long tickPos = 0; long channel = 0; long commentNum = 0; long textLen = 0; //ADIResultCode ADI_GetCommentInfo(ADI_CommentsHandle commentsH, long *tickPos, long *channel, long *commentNum, wchar_t* text,long maxChars, long *textLen); // tickPos - receives the tick position of the comment in the record [outparam] // commentNum - receives the number of the comment [outparam] // channel - receives the channel of the comment (-1 for all channel comments) [outparam] // text - buffer to receive null terminated text for the comment (optional, may be NULL) [outparam] // maxChars - the size of the text buffer in wchar_t s. The text will be truncated to fit in this size // textLen - receives the number of characters needed to hold the full comment text, // even if parameter text is NULL (optional, may be NULL) [outparam] out_result[0] = ADI_GetCommentInfo(commentsH,&tickPos,&channel,&commentNum,messageOut,MAX_STRING_LENGTH,&textLen); setLongOutput(plhs,2,textLen); setLongOutput(plhs,3,tickPos); setLongOutput(plhs,4,channel); setLongOutput(plhs,5,commentNum); } else if (function_option == 9) { // ADI_NextComment <> advanceComments // ================================================== // result_code = adi.sdk_mex(9,comments_h); // // Returns kResultNoData if there are no more comments ... // // Status: Done ADI_CommentsHandle commentsH = getCommentsHandle(prhs); //ADIResultCode ADI_NextComment(ADI_CommentsHandle commentsH); out_result[0] = ADI_NextComment(commentsH); } else if (function_option == 10) { // ADI_GetSamples <> getChannelData // =========================================================== // [result,data,n_returned] = sdk_mex(10,file_h,channel_0b,record_0b,startPos,nLength,dataType) fileH = getFileHandle(prhs); long channel = getLongInput(prhs,2); long record = getLongInput(prhs,3); long startPos = getLongInput(prhs,4); long nLength = getLongInput(prhs,5); ADICDataFlags dataType = static_cast<ADICDataFlags>(getLongInput(prhs,6)); plhs[1] = mxCreateNumericMatrix(1,(mwSize)nLength,mxSINGLE_CLASS,mxREAL); float *data = (float *)mxGetData(plhs[1]); long returned = 0; // Retrieves a block of sample data from the file into a buffer. Samples are in physical // prefixed units. //DLLEXPORT ADIResultCode ADI_GetSamples(ADI_FileHandle fileH, long channel, long record, long startPos, // ADICDataFlags dataType, long nLength, float* data, long* returned); out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,dataType,nLength,data,&returned); //out_result[0] = ADI_GetSamples(fileH,channel,record,startPos,kADICDataAtSampleRate,nLength,data,&returned); setLongOutput(plhs,2,returned); //out_result[0] = 4; } else if (function_option == 11) { // ADI_GetUnitsName <> getUnits // ======================================= // [result_code,str_data,str_length] = sdk_mex(11,file_h,record,channel); //Inputs fileH = getFileHandle(prhs); long record = getLongInput(prhs,2); long channel = getLongInput(prhs,3); //Outputs long textLen = 0; wchar_t *unitsOut = getStringOutputPointer(plhs,1); // Retrieves the prefixed units of a channel, as a string. // //ADIResultCode ADI_GetUnitsName(ADI_FileHandle fileH, long channel, long record, wchar_t* units, long maxChars, long *textLen); out_result[0] = ADI_GetUnitsName(fileH, channel, record, unitsOut, MAX_STRING_LENGTH, &textLen); setLongOutput(plhs,2,textLen); } else if (function_option == 12) { // ADI_GetChannelName <> getChannelName // ============================================= // [result_code,str_data,str_length] = sdk_mex(12,file_h,channel); //Inputs fileH = getFileHandle(prhs); long channel = getLongInput(prhs,2); //Outputs long textLen = 0; wchar_t *nameOut = getStringOutputPointer(plhs,1); // Retrieves the name of a channel, as a string. //ADIResultCode ADI_GetChannelName(ADI_FileHandle fileH, long channel, wchar_t* name, long maxChars, long *textLen); out_result[0] = ADI_GetChannelName(fileH, channel, nameOut, MAX_STRING_LENGTH, &textLen); setLongOutput(plhs,2,textLen); } else if (function_option == 13) { // ADI_CloseFile <> closeFile // ============================================================== // fileH = getFileHandle(prhs); result = ADI_CloseFile(&fileH); out_result[0] = result; } else if (function_option == 14) { // ADI_GetErrorMessage <> getErrorMessage // ============================================================== // err_msg = sdk_mex(14,error_code) long textLen = 0; wchar_t *messageOut = getStringOutputPointer(plhs,1); ADIResultCode code = (ADIResultCode)getLongInput(prhs,1); //ADIResultCode ADI_GetErrorMessage(ADIResultCode code, wchar_t* messageOut, long maxChars, long *textLen); out_result[0] = ADI_GetErrorMessage(code, messageOut, MAX_STRING_LENGTH, &textLen); setLongOutput(plhs,2,textLen); } else if (function_option == 15) { // ADI_GetRecordSamplePeriod <> getSamplePeriod // ============================================================== // [result_code,dt_channel] = sdk_mex(15,file_h,record,channel) fileH = getFileHandle(prhs); long record = getLongInput(prhs,2); long channel = getLongInput(prhs,3); double secsPerSample = 0; out_result[0] = ADI_GetRecordSamplePeriod(fileH, channel, record, &secsPerSample); setDoubleOutput(plhs,1,secsPerSample); } else if (function_option == 16) { // ADI_GetRecordTime <> getRecordStartTime // ============================================================== // [result_code,trigger_time,frac_secs,trigger_minus_rec_start] = sdk_mex(16,file_h,record) fileH = getFileHandle(prhs); long record = getLongInput(prhs,2); time_t triggerTime = 0; double fracSecs = 0; long triggerMinusStartTicks = 0; //Retrieves time information about the specified record. //The trigger time is the time origin of the record and may differ from the start time if //there is a pre or post trigger delay, as specified by the trigMinusRecStart parameter. // Params: fileH - ADI_FileHandle for the open file // record - the record index (starting from 0) // triggerTime - time_t receives the date and time of the trigger // position for the new record. Measured as number of // seconds from 1 Jan 1970 // fracSecs - receives the fractional seconds part of // the record trigger time ('triggerTime' parameter) // trigMinusRecStart - trigger-time-minus-record-start-ticks. Receives the // difference between the time of trigger tick and the first // tick in the record. This +ve for pre-trigger delay and // -ve for post-trigger delay. // Return: a ADIResultCode for result of the operation //DLLEXPORT ADIResultCode ADI_GetRecordTime(ADI_FileHandle fileH, long record, time_t *triggerTime, //double *fracSecs, long *triggerMinusStartTicks); out_result[0] = ADI_GetRecordTime(fileH, record, &triggerTime, &fracSecs, &triggerMinusStartTicks); setDoubleOutput(plhs,1,(double)triggerTime); setDoubleOutput(plhs,2,fracSecs); setLongOutput(plhs,3,triggerMinusStartTicks); } else if (function_option == 17){ // // ADI_CreateFile <> createFile // ============================================================== // [result_code,file_h] = sdk_mex(17,file_path) // // Implemented via sdk.createFile wchar_t *w_file_path = (wchar_t *)mxGetData(prhs[1]); result = ADI_CreateFile(w_file_path, &fileH); out_result[0] = result; setFileHandle(plhs,result,fileH); } else if (function_option == 18){ // // ADI_SetChannelName <> setChannelName // ============================================================== // [result_code,file_h] = sdk_mex(18,file_h,channel,name) // // Implemented via sdk.setChannelName fileH = getFileHandle(prhs); long channel = getLongInput(prhs,2); wchar_t *channel_name = (wchar_t *)mxGetData(prhs[3]); out_result[0] = ADI_SetChannelName(fileH, channel, channel_name); } else if (function_option == 19){ // // ADI_CreateWriter <> createDataWriter // =========================================== // [result_code,writer_h] = sdk_mex(19,file_h) // // Implemented via sdk.createDataWriter ADI_WriterHandle writerH(0); fileH = getFileHandle(prhs); result = ADI_CreateWriter(fileH,&writerH); out_result[0] = result; setWriterHandle(plhs,result,writerH); } else if (function_option == 20){ // // ADI_SetChannelInfo <> setChannelInfo // =========================================== // [result_code] = sdk_mex(20,writer_h,channel,enabled,seconds_per_sample,units,limits) // // implemented via adi.sdk.setChannelInfo ADI_WriterHandle writerH = getWriterHandle(prhs); long channel = getLongInput(prhs,2); int enabled = getIntInput(prhs,3); double seconds_per_sample = getDoubleInput(prhs,4); wchar_t *units = (wchar_t *)mxGetData(prhs[5]); float *temp_limits = (float *)mxGetData(prhs[5]); ADIDataLimits limits; limits.mMaxLimit = temp_limits[1]; limits.mMinLimit = temp_limits[0]; out_result[0] = ADI_SetChannelInfo(writerH, channel, enabled, seconds_per_sample, units, &limits); // DLLEXPORT ADIResultCode ADI_SetChannelInfo(ADI_WriterHandle writerH, long channel, int enabled, // double secondsPerSample, const wchar_t* units, const ADIDataLimits *limits); } else if (function_option == 21){ // // ADI_StartRecord <> startRecord // =========================================== // result_code = sdk_mex(21, writerH, trigger_time, fractional_seconds, trigger_minus_rec_start) // // implemented via adi.sdk.startRecord ADI_WriterHandle writerH = getWriterHandle(prhs); time_t trigger_time = (time_t)getDoubleInput(prhs,2); double fractional_seconds = getDoubleInput(prhs,3); long trigger_minus_rec_start = getLongInput(prhs,4); out_result[0] = ADI_StartRecord(writerH, trigger_time, fractional_seconds, trigger_minus_rec_start); // DLLEXPORT ADIResultCode ADI_StartRecord(ADI_WriterHandle writerH, time_t triggerTime, // double fracSecs, long triggerMinusStartTicks); } else if (function_option == 22){ // // ADI_AddChannelSamples <> addChannelSamples // =========================================== // [result_code,new_ticks_added] = sdk_mex(22, writerH, channel, data, n_samples) // // adi.sdk.addChannelSamples ADI_WriterHandle writerH = getWriterHandle(prhs); long channel = getLongInput(prhs,2); float *data = (float *)mxGetData(prhs[3]); long n_samples = (long)mxGetNumberOfElements(prhs[3]); long new_ticks_added = 0; out_result[0] = ADI_AddChannelSamples(writerH, channel, data, n_samples, &new_ticks_added); setLongOutput(plhs,1,new_ticks_added); // DLLEXPORT ADIResultCode ADI_AddChannelSamples(ADI_WriterHandle writerH, long channel, // float* data, long nSamples, long *newTicksAdded); } else if (function_option == 23){ // // ADI_FinishRecord <> finishRecord // =========================================== // [result_code] = sdk_mex(23, writerH) // // Implemented via adi.sdk.finishRecord ADI_WriterHandle writerH = getWriterHandle(prhs); out_result[0] = ADI_FinishRecord(writerH); // DLLEXPORT ADIResultCode ADI_FinishRecord(ADI_WriterHandle writerH); } else if (function_option == 24){ // // ADI_CommitFile <> commitFile // =========================================== // [result_code] = sdk_mex(24, writerH, flags) // // Implemented via adi.sdk.commitFile ADI_WriterHandle writerH = getWriterHandle(prhs); //TODO: What are the flags?????? out_result[0] = ADI_CommitFile(writerH, 0); // DLLEXPORT ADIResultCode ADI_CommitFile(ADI_WriterHandle writerH, long flags); } else if (function_option == 25){ // // ADI_CloseWriter <> closeWriter // =========================================== // [result_code] = sdk_mex(25, writerH) // // Implemented via adi.sdk.closeWriter ADI_WriterHandle writerH = getWriterHandle(prhs); out_result[0] = ADI_CloseWriter(&writerH); // DLLEXPORT ADIResultCode ADI_CloseWriter(ADI_WriterHandle *writerH); } else if (function_option == 26){ // // ADI_AddComment <> addComment // =========================================== // [result_code, comment_number] = // sdk_mex(26, file_h, channel, record, tick_position, text) // // Implemented via adi.sdk.addComment fileH = getFileHandle(prhs); long channel = getLongInput(prhs,2); long record = getLongInput(prhs,3); long tick_position = getLongInput(prhs,4); wchar_t *text = (wchar_t *)mxGetData(prhs[5]); long comment_number = 0; //long comment_number = getLongInput(prhs,6); out_result[0] = ADI_AddComment(fileH, channel, record, tick_position, text, &comment_number); setLongOutput(plhs,1,comment_number); // DLLEXPORT ADIResultCode ADI_AddComment(ADI_FileHandle fileH, long channel, long record, long tickPos, // const wchar_t* text, long* commentNum); } else if (function_option == 27){ // // ADI_DeleteComment <> deleteComment // =========================================== // result_code = sdk_mex(27,file_h,comment_number) // // Implemented via adi.sdk.deleteComment fileH = getFileHandle(prhs); long comment_number = getLongInput(prhs,2); out_result[0] = ADI_DeleteComment(fileH,comment_number); // DLLEXPORT ADIResultCode ADI_DeleteComment(ADI_FileHandle fileH, long commentNum); } else if (function_option == 100){ mexUnlock(); locked = 0; } else { mexErrMsgIdAndTxt("adinstruments:sdk_mex", "Invalid function option"); } //ADI_GetRecordSamplePeriod //ADI_GetRecordTime }
extern bool aperture_bft_get(mxArray *plhs[], const mxArray* mx_handle, const size_t type) { const size_t n_odim = 2; mwSize o_dims[n_odim]; bool retval = true; size_t i; Aperture* p_aperture; Aperture* p_aperture_clone; float_type* p_flhs = NULL; bool* p_blhs = NULL; size_t* p_ilhs = NULL; int aperturetype = 0; Call(mxIsPointer, (mx_handle)); p_aperture = &(get_object<Aperture>(mx_handle)); switch (type) { case 0: // Positions o_dims[0] = mwSize(p_aperture->n_elements()); o_dims[1] = mwSize(3); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); for (i=0 ; i < 3*p_aperture->n_elements() ; i++ ) { p_flhs[i] = p_aperture->data->m_pos->m_data[0][i]; } break; case 1: // Focus point (VS) o_dims[0] = mwSize(0); o_dims[1] = mwSize(0); if (p_aperture->data->m_focus) { o_dims[0] = mwSize(1); o_dims[1] = mwSize(3); } Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); for (i=0 ; i < 3 ; i++ ) { if (p_aperture->data->m_focus) p_flhs[i] = p_aperture->data->m_focus[i]; } break; case 2: // Center focus o_dims[0] = mwSize(p_aperture->data->m_nemissions); o_dims[1] = mwSize(3); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); for (i=0 ; i < 3*p_aperture->data->m_nemissions ; i++ ) { p_flhs[i] = p_aperture->data->m_center_focus[i]; } break; case 3: // fs o_dims[0] = mwSize(1); o_dims[1] = mwSize(1); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); p_flhs[0] = Aperture::_fs; break; case 4: // f0 o_dims[0] = mwSize(1); o_dims[1] = mwSize(1); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); p_flhs[0] = Aperture::_f0; break; case 7: // c o_dims[0] = mwSize(1); o_dims[1] = mwSize(1); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); p_flhs[0] = Aperture::_c; break; case 5: // Receive delays if (p_aperture->data->m_delays) { o_dims[0] = mwSize(p_aperture->n_elements()); o_dims[1] = mwSize(1); } else { o_dims[0] = mwSize(0); o_dims[1] = mwSize(0); } Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); if (p_aperture->data->m_delays) for (i=0 ; i < p_aperture->n_elements() ; i++ ) p_flhs[i] = p_aperture->data->m_delays[i]; break; case 6: // Id o_dims[0] = mwSize(1); o_dims[1] = mwSize(1); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxPOINTER_CLASS, mxREAL)); // Use ptr_t p_ilhs = ((size_t*) mxGetData(plhs[0])); p_ilhs[0] = p_aperture->data->m_id; break; case 8: // Clone p_aperture_clone = p_aperture->Clone(); plhs[0] = create_handle<Aperture>(p_aperture_clone); enable_aperture_destructor = true; mexLock(); break; case 9: // Version Call(plhs[0] = mxCreateString, (PACKAGE_VERSION)); break; case 10: // Aperture type aperturetype = p_aperture->data->m_type; switch (aperturetype) { case Aperture::custom: Call(plhs[0] = mxCreateString, ("custom")); break; case Aperture::linear_array: Call(plhs[0] = mxCreateString, ("linear_array")); break; case Aperture::convex_array: Call(plhs[0] = mxCreateString, ("convex_array")); break; default: Call(plhs[0] = mxCreateString, ("unknown")); }; break; case 11: /// Focus delays o_dims[0] = mwSize(p_aperture->n_elements()); o_dims[1] = mwSize(1); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); retval = p_aperture->getFocusDelays(p_flhs); if (!retval) { retval = true; // Return zero values /* Fail("No focus delays available for un-focused array"); */ } break; case 12: // PP-wave on/off o_dims[0] = mwSize(1); o_dims[1] = mwSize(1); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxLOGICAL_CLASS, mxREAL)); p_blhs = ((bool*) mxGetData(plhs[0])); p_blhs[0] = p_aperture->data->m_ppwave; break; case 13: // Orientation // Center focus o_dims[0] = mwSize(p_aperture->data->m_nemissions); o_dims[1] = mwSize(3); Call(plhs[0] = mxCreateNumericArray, (n_odim, (const mwSize*)o_dims, mxFLOAT_CLASS, mxREAL)); p_flhs = ((float_type*) mxGetData(plhs[0])); for (i=0 ; i < 3*p_aperture->data->m_nemissions ; i++ ) { p_flhs[i] = p_aperture->data->m_euler[i]; } break; } return retval; }
void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { int rc, enabled; UINT32_T masterid = 0; time_t timallow = 0; UINT64_T memallow = 0; UINT64_T rss, vs; /* this function will be called upon unloading of the mex file */ mexAtExit(exitFun); if (nrhs<3) mexErrMsgTxt ("invalid number of input arguments"); if (mxIsScalar(prhs[0])) masterid = mxGetScalar(prhs[0]); else if (mxIsEmpty(prhs[0])) masterid = 0; else mexErrMsgTxt ("invalid input argument #1"); if (mxIsScalar(prhs[1])) timallow = mxGetScalar(prhs[1]); else if (mxIsEmpty(prhs[1])) timallow = 0; else mexErrMsgTxt ("invalid input argument #2"); if (mxIsScalar(prhs[2])) memallow = mxGetScalar(prhs[2]); else if (mxIsEmpty(prhs[2])) memallow = 0; else mexErrMsgTxt ("invalid input argument #3"); if (masterid!=0 || timallow!=0 || memallow!=0) { enabled = 1; /* in this case the mex file is not allowed to be cleared from memory */ if (!mexIsLocked()) mexLock(); } if (masterid==0 && timallow==0 && memallow==0) { enabled = 0; /* in this case the mex file is allowed to be cleared from memory */ #ifdef SOLUTION_FOR_UNEXPLAINED_CRASH if (mexIsLocked()) mexUnlock(); #endif } if (!peerInitialized) { mexPrintf("watchdog: init\n"); peerinit(NULL); peerInitialized = 1; } /* start the discover thread */ pthread_mutex_lock(&mutexstatus); if (!discoverStatus) { pthread_mutex_unlock(&mutexstatus); mexPrintf("watchdog: spawning discover thread\n"); rc = pthread_create(&discoverThread, NULL, discover, (void *)NULL); if (rc) mexErrMsgTxt("problem with return code from pthread_create()"); else { /* wait until the thread has properly started */ pthread_mutex_lock(&mutexstatus); if (!discoverStatus) pthread_cond_wait(&condstatus, &mutexstatus); pthread_mutex_unlock(&mutexstatus); } } else { pthread_mutex_unlock(&mutexstatus); } /* start the expire thread */ pthread_mutex_lock(&mutexstatus); if (!expireStatus) { pthread_mutex_unlock(&mutexstatus); mexPrintf("watchdog: spawning expire thread\n"); rc = pthread_create(&expireThread, NULL, expire, (void *)NULL); if (rc) mexErrMsgTxt("problem with return code from pthread_create()"); else { /* wait until the thread has properly started */ pthread_mutex_lock(&mutexstatus); if (!expireStatus) pthread_cond_wait(&condstatus, &mutexstatus); pthread_mutex_unlock(&mutexstatus); } } else { pthread_mutex_unlock(&mutexstatus); } if (timallow>0) { /* timallow should be relative to now */ timallow += time(NULL); } if (memallow>0) { /* memallow should be in absolute numbers, add the current memory footprint */ getmem(&rss, &vs); memallow += rss; } /* enable the watchdog: the expire thread will exit if the master is not seen any more */ pthread_mutex_lock(&mutexwatchdog); watchdog.enabled = enabled; watchdog.evidence = 0; watchdog.masterid = masterid; watchdog.memory = memallow; watchdog.time = timallow; pthread_mutex_unlock(&mutexwatchdog); if (enabled) mexPrintf("watchdog: enabled for masterid = %lu, time = %d, memory = %lu\n", masterid, timallow, memallow); else mexPrintf("watchdog: disabled for masterid = %lu, time = %d, memory = %lu\n", masterid, timallow, memallow); return; } /* main */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i,j, k, status,buflen,Cnt, Hndl, L,M,N, NumHandles, commandswitch; int *HndlArray; mxArray *mymxArray; double *myDblPr; chtype RequestType; char PVName[PV_NAME_LENGTH_MAX+1]; // char MCAMessageString[MCA_MESSAGE_STRING_LENGTH_MAX+1]; dbr_string_t StrBuffer; const char *MCAInfoFields[]={"PVName","ElementCount","NativeType","State","MCAMessage","Host"}; char *NativeTypeStrings[] = {"STRING","INT","FLOAT","ENUM","CHAR","LONG","DOUBLE"}; if(!CA_INITIALIZED) // Initialize CA if not initialized (first call) { mexPrintf("Initializing MATLAB Channel Access ... \n"); status = ca_task_initialize(); if(status!=ECA_NORMAL) mexErrMsgTxt("Unable to initialise Challel Access\n"); CA_INITIALIZED = true; // Register a function to be called when a this mex-file is cleared from memory // with 'clear' or when exitting MATLAB mexAtExit(mca_cleanup); // Lock the mex-file so that it can not be cleared without explicitly // mexUnclock mexLock(); //start periodic polling: /* PollTimerHandle = SetTimer(NULL,NULL,MCA_POLL_PERIOD,background_poll); if(PollTimerHandle) mexPrintf("Periodic CA polling started! System Timer ID: %u\n",PollTimerHandle); else mexWarnMsgTxt("Failed to start periodic CA polling\n"); */ } commandswitch = (int)mxGetScalar(prhs[0]); switch(commandswitch) { case 0: mexUnlock(); break; case 1: // MCAOPEN - add channel(s) by PV names, all arguments following prhs[0] // must be strings - names of PV's for(i=1;i<nrhs;i++) { mxGetString(prhs[i],PVName,PV_NAME_LENGTH_MAX+1); status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID)); if(status == ECA_NORMAL) // if not - go on to the next PV name { status = ca_pend_io(MCA_SEARCH_TIMEOUT); if (status == ECA_NORMAL) { // Allocate persistent memory for the DataBuffer on this channel // to hold all elements of the DBR_XXX type // nearest to the native type // RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); // Cnt=ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].MonitorEventCount = 0; switch(CHNLS[HandlesUsed].NativeType2DBR) { case DBR_STRING: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); break; case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_FLOAT: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); break; case DBR_ENUM: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); break; case DBR_CHAR: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); break; case DBR_LONG: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_DOUBLE: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); break; } mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer); if(CHNLS[HandlesUsed].NativeType2DBR==DBR_STRING) // CACHE { if(CHNLS[HandlesUsed].NumElements==1) // Create MATLAB string - originally empty CHNLS[HandlesUsed].CACHE = mxCreateString(""); else // Create MATLAB cell array of strings { CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements); for(k=0;k<CHNLS[HandlesUsed].NumElements;k++) { mymxArray = mxCreateString(""); mexMakeArrayPersistent(mymxArray); mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray); } } } else // Make CACHE a numeric mxArray { CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL); } mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE); plhs[i-1]=mxCreateScalarDouble(++HandlesUsed); } else plhs[i-1]=mxCreateScalarDouble(0); } else plhs[i-1]=mxCreateScalarDouble(0); } break; case 2:// MCAOPEN - add channel(s) by PV names. The arguments following prhs[0] // argument must be a cell array of strings - PV names L = mxGetM(prhs[1])*mxGetN(prhs[1]); plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<L;i++) { mymxArray = mxGetCell(prhs[1],i); mxGetString(mymxArray,PVName,PV_NAME_LENGTH_MAX+1); status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID)); if(status == ECA_NORMAL) // if not - go on to the next PV name { status = ca_pend_io(MCA_IO_TIMEOUT); if (status == ECA_NORMAL) { // Allcate persistent memory for the DataBuffer on this channel //RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].MonitorEventCount = 0; //Cnt=ca_element_count(CHNLS[HandlesUsed].CHID); switch(CHNLS[HandlesUsed].NativeType2DBR) { case DBR_STRING: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); break; case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_FLOAT: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); break; case DBR_ENUM: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); break; case DBR_CHAR: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); break; case DBR_LONG: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_DOUBLE: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); break; } mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer); if(CHNLS[HandlesUsed].NativeType2DBR == DBR_STRING) // CACHE { CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements); for(k=0;k<CHNLS[HandlesUsed].NumElements;k++) { mymxArray = mxCreateString(StrBuffer); mexMakeArrayPersistent(mymxArray); mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray); } } else { CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL); } mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE); myDblPr[i] = ++HandlesUsed; } else myDblPr[i] = 0; } else myDblPr[i] = 0; } break; case 3: // MCAOPEN Return names of connected channels as cell array of strings plhs[0] = mxCreateCellArray(1, &HandlesUsed); for(i=0;i<HandlesUsed;i++) { if(CHNLS[i].CHID!=NULL) { mymxArray = mxCreateString(ca_name(CHNLS[i].CHID)); mxSetCell(plhs[0], i, mymxArray); } else { mymxArray = mxCreateString(""); //mexPrintf("Handle: %d PV: %s\n",i+1, "Cleared Channel"); mxSetCell(plhs[0], i, mymxArray); } } break; case 5: // MCACLOSE permanently clear channel Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range"); // If a monitor is installed, set the EVID pointer to NULL // ca_clear_event dos not do it by itself if(CHNLS[Hndl-1].EVID) CHNLS[Hndl-1].EVID = NULL; // If there is Callback String - destroy it if(CHNLS[Hndl-1].MonitorCBString) { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString =NULL; } if(ca_state(CHNLS[Hndl-1].CHID)==3) mexWarnMsgTxt("Channel previously cleared"); else if(ca_clear_channel(CHNLS[Hndl-1].CHID)!=ECA_NORMAL) mexErrMsgTxt("ca_clear_channel failed"); break; case 10: // MCAINFO return channels info as MATLAB structure array if(HandlesUsed>0) { plhs[0] = mxCreateStructMatrix(1,HandlesUsed,6,MCAInfoFields); for(i=0;i<HandlesUsed;i++) { mxSetFieldByNumber(plhs[0],i,0,mxCreateString(ca_name(CHNLS[i].CHID))); mxSetFieldByNumber(plhs[0],i,1,mxCreateScalarDouble(ca_element_count(CHNLS[i].CHID))); mxSetFieldByNumber(plhs[0],i,5,mxCreateString(ca_host_name(CHNLS[i].CHID))); switch(ca_state(CHNLS[i].CHID)) { case 1: // Disconnected due to Server or Network - may reconnect mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Disconnected due to server or network problem")); break; case 2: // Normal connection mxSetFieldByNumber(plhs[0],i,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[i].CHID)])); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("connected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Normal connection")); break; case 3: // Disconnected by user mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Permanently disconnected (cleared) by the user")); break; } } } else { mexWarnMsgTxt("No connected PV's found"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } break; case 11: // MCAINFO return info for 1 channel by handle number Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range"); plhs[0] = mxCreateStructMatrix(1,1,6,MCAInfoFields); mxSetFieldByNumber(plhs[0],0,0,mxCreateString(ca_name(CHNLS[Hndl-1].CHID))); mxSetFieldByNumber(plhs[0],0,1,mxCreateScalarDouble(ca_element_count(CHNLS[Hndl-1].CHID))); mxSetFieldByNumber(plhs[0],0,5,mxCreateString(ca_host_name(CHNLS[Hndl-1].CHID))); switch(ca_state(CHNLS[Hndl-1].CHID)) { case 1: // Disconnected due to Server or Network - may reconnect mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Disconnected due to server or network problem")); break; case 2: // Normal connection mxSetFieldByNumber(plhs[0],0,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[Hndl-1].CHID)])); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("connected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Normal connection")); break; case 3: // Disconnected by user mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Permanently disconnected (cleared) by the user")); break; }; break; case 12: // MCASTATE return an array of status (1 - OK, 0 - disconnected or cleared) if(HandlesUsed>0) { plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<HandlesUsed;i++) myDblPr[i] = (double)(ca_state(CHNLS[i].CHID)==2); } else { mexWarnMsgTxt("No connected PV's found"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } break; case 30: // poll ca_poll(); break; case 50: // MCAGET Get PV values by their MCA handles for(i=0;i<nrhs-1;i++) // First loop: place all ca_get requests in the buffer { Hndl = (int)mxGetScalar(prhs[1+i]); //start from[1]: [0] argument is the commnads switch if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); status = ca_array_get(RequestType,Cnt,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer); if(status!=ECA_NORMAL) mexPrintf("Error in call to ca_array_get\n"); } status = ca_pend_io(MCA_GET_TIMEOUT); if(status!=ECA_NORMAL) mexErrMsgTxt("... ca_pend_io call timed out \n"); for(i=0;i<nrhs-1;i++) // Another loop to copy data from temp structures to MATLAB { Hndl = (int)mxGetScalar(prhs[1+i]); RequestType = RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); if(RequestType==DBR_STRING) { if(Cnt==1) plhs[i] = mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)))); else { plhs[i] = mxCreateCellMatrix(1,Cnt); for(j=0;j<Cnt;j++) mxSetCell(plhs[i], j, mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+j)))); } } else { plhs[i] = mxCreateDoubleMatrix(1,Cnt,mxREAL); myDblPr = mxGetPr(plhs[i]); switch(dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID))) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_FLOAT: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_ENUM: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_CHAR: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_LONG: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_DOUBLE: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; } } } break; case 51: // MCAGET Get scalar PV of the same type // second argument is an array of handles // returns an array of values myDblPr = mxGetPr(prhs[1]); M = mxGetM(prhs[1]); N = mxGetN(prhs[1]); NumHandles = M*N; plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL); for(i=0;i<NumHandles;i++) // First loop: place all ca_get requests in the buffer { Hndl = (int)myDblPr[i]; if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); status = ca_array_get(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(plhs[0])+i); if(status!=ECA_NORMAL) mexPrintf("Error in call to ca_array_get\n"); } status = ca_pend_io(MCA_GET_TIMEOUT); if(status!=ECA_NORMAL) mexErrMsgTxt("... ca_pend_io call timed out \n"); break; case 70: // MCAPUT NumHandles = (nrhs-1)/2; for(i=0;i<NumHandles;i++) { j = 2+i*2; Hndl = (int)mxGetScalar(prhs[1+i*2]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range - no values written"); // Set the status to 0 - mcaput_callback will write 1, if successful CHNLS[Hndl-1].LastPutStatus = 0; RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); // If a value to write is passed as a string - the number of elements to write // is 1 , NOT the length of the string returned by mxGetNumberOfElements if(mxIsChar(prhs[j])) L=1; else L = min(mxGetNumberOfElements(prhs[j]),Cnt); // Copy double or string data from MATLAB prhs[] to DataBuffer // on each channel if(RequestType==DBR_STRING) { // STRING type is is passed as a cell array of strings // A a 1-row MATLAB character array (1 string) may also be passed as a value if(mxIsChar(prhs[j])) { mxGetString(prhs[j], StrBuffer, sizeof(dbr_string_t)); strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))),StrBuffer); } else if(mxIsCell(prhs[j])) { for(k=0;k<L;k++) { mxGetString(mxGetCell(prhs[j],k), StrBuffer, sizeof(dbr_string_t)); strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+k)),StrBuffer); } } } else { myDblPr = mxGetPr(prhs[j]); switch(RequestType) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for(k=0;k<L;k++) *((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_short_t)(myDblPr[k]); break; case DBR_FLOAT: for(k=0;k<L;k++) *((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_float_t)(myDblPr[k]); break; case DBR_ENUM: for(k=0;k<L;k++) *((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_enum_t)(myDblPr[k]); break; case DBR_CHAR: for(k=0;k<L;k++) *((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_char_t)(myDblPr[k]); break; case DBR_LONG: for(k=0;k<L;k++) *((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_long_t)(myDblPr[k]); break; case DBR_DOUBLE: for(k=0;k<L;k++) *((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_double_t)(myDblPr[k]); break; } } // place request in the que status = ca_array_put_callback(RequestType,L,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer, mcaput_callback,&(CHNLS[Hndl-1].LastPutStatus)); if(status!=ECA_NORMAL) mexPrintf("ca_array_put_callback failed\n"); } status = ca_pend_event(MCA_PUT_TIMEOUT); plhs[0]=mxCreateDoubleMatrix(1,NumHandles,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<NumHandles;i++) { Hndl = (int)mxGetScalar(prhs[1+i*2]); myDblPr[i] = (double)CHNLS[Hndl-1].LastPutStatus; } break; case 80: // MCAPUT - fast unconfirmed put for scalar numeric PV's myDblPr = mxGetPr(prhs[1]); M = mxGetM(prhs[1]); N = mxGetN(prhs[1]); NumHandles = M*N; plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<NumHandles;i++) { myDblPr = mxGetPr(plhs[0]); Hndl = (int)(*(mxGetPr(prhs[1])+i)); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range - no values written"); status = ca_array_put(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(prhs[2])+i); if(status!=ECA_NORMAL) { myDblPr[i] = 0; //mexPrintf("ca_array_put_callback failed\n"); } else { myDblPr[i] = 1; } } status = ca_pend_io(MCA_PUT_TIMEOUT); break; case 100: // MCAMON install Monitor or replace MonitorCBString Hndl = (int)mxGetScalar(prhs[1]); // Check if the handle is within range if(Hndl<1 || Hndl>HandlesUsed) { plhs[0]=mxCreateScalarDouble(0); mexErrMsgTxt("Invalid Handle"); } if(CHNLS[Hndl-1].EVID) // if VID is not NULL - another monitor is already installed - replace MonitorCBString { if(CHNLS[Hndl-1].MonitorCBString) // Free memory for occupied by the old MonitorCBString { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString = NULL; } if(nrhs>2) // Check if the new string is specified { if(mxIsChar(prhs[2])) { buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1; CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen); mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString); mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); } else mexErrMsgTxt("Third argument must be a string\n"); } plhs[0]=mxCreateScalarDouble(1); } else // No monitor is presently installed; { RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); // Closest to the native if(nrhs>2) { if(mxIsChar(prhs[2])) { buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1; CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen); mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString); mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); } else mexErrMsgTxt("Third argument must be a string\n"); } else CHNLS[Hndl-1].MonitorCBString = NULL; // Set MonitorCBString to NULL so that mcaMonitorEventHandler only copies data to CACHE // Count argument set to 0 - native count status = ca_add_array_event(RequestType,0,CHNLS[Hndl-1].CHID, mcaMonitorEventHandler, &CHNLS[Hndl-1], 0.0, 0.0, 0.0, &(CHNLS[Hndl-1].EVID)); if(status!=ECA_NORMAL) { mexPrintf("ca_add_array_event failed\n"); plhs[0]=mxCreateScalarDouble(0); } else { ca_poll(); plhs[0]=mxCreateScalarDouble(1); } } break; case 200: // Clear Monitor MCACLEARMON Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); if(!CHNLS[Hndl-1].EVID) mexErrMsgTxt("No monitor installed - can not clear"); status = ca_clear_event(CHNLS[Hndl-1].EVID); if(status!=ECA_NORMAL) mexPrintf("ca_clear_event failed\n"); // Set the EVID pointer to NULL (ca_clear_event dos not do it by itself) // to use as a FLAG that no monitors are installed CHNLS[Hndl-1].EVID = NULL; // Reset CHNLS[Hndl-1].MonitorEventCount = 0; // If there is Callback String - destroy it if(CHNLS[Hndl-1].MonitorCBString) { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString =NULL; } break; case 300: // MCACACHE Get Cached values of a monitored PV for(i=0;i<nrhs-1;i++) { Hndl = (int)mxGetScalar(prhs[1+i]); // if(Hndl<1 || Hndl>HandlesUsed || !CHNLS[Hndl-1].CACHE) if(Hndl<1 || Hndl>HandlesUsed) plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL); else { plhs[i] = mxDuplicateArray(CHNLS[Hndl-1].CACHE); CHNLS[Hndl-1].MonitorEventCount = 0; } } break; case 500: // MCAMON Info on installed monitors L = 0; HndlArray = (int*)mxCalloc(HandlesUsed,sizeof(int)); for(i=0;i<HandlesUsed;i++) // Count installed monitors { if(CHNLS[i].EVID) HndlArray[L++]=i+1; } if(L>0) { plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL); myDblPr = mxGetPr(plhs[0]); plhs[1] = mxCreateCellMatrix(1,L); for(i=0;i<L;i++) { myDblPr[i] = (double)HndlArray[i]; mxSetCell(plhs[1],i,mxCreateString(CHNLS[HndlArray[i]-1].MonitorCBString)); } } else { plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); plhs[1] = mxCreateCellMatrix(0,0); } break; case 510: // MCAMONEVENTS Event count fot monitors plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<HandlesUsed;i++) myDblPr[i]=(double)(CHNLS[i].MonitorEventCount); break; case 1000: // print timeout settings plhs[0] = mxCreateDoubleMatrix(3,1,mxREAL); mexPrintf("MCA timeout settings\n:"); mexPrintf("mcaopen\t%f [s]\n", MCA_SEARCH_TIMEOUT ); mexPrintf("mcaget\t%f [s]\n", MCA_GET_TIMEOUT ); mexPrintf("mcaput\t%f [s]\n", MCA_PUT_TIMEOUT ); myDblPr = mxGetPr(plhs[0]); myDblPr[0] = MCA_SEARCH_TIMEOUT; myDblPr[1] = MCA_GET_TIMEOUT; myDblPr[2] = MCA_PUT_TIMEOUT; break; case 1001: // set MCA_SEARCH_TIMEOUT // return delay value MCA_SEARCH_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_SEARCH_TIMEOUT); break; case 1002: // set MCA_GET_TIMEOUT // return delay value MCA_GET_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_GET_TIMEOUT); break; case 1003: // set MCA_PUT_TIMEOUT // return delay value MCA_PUT_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_PUT_TIMEOUT); break; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char cmd[64]; metricTreeCPP *theTree; if(nrhs>4) { mexErrMsgTxt("Too many inputs."); } //Get the command string that is passed. mxGetString(prhs[0], cmd, sizeof(cmd)); //prhs[0] is assumed to be the string telling if(!strcmp("metricTreeCPP", cmd)){ size_t k, N; mxArray *retPtr; k=getSizeTFromMatlab(prhs[1]); N=getSizeTFromMatlab(prhs[2]); theTree = new metricTreeCPP(k,N); //Convert the pointer to a Matlab matrix to return. retPtr=ptr2Matlab<metricTreeCPP*>(theTree); //Lock this mex file so that it can not be cleared until the object //has been deleted (This avoids a memory leak). mexLock(); //Return the pointer to the tree plhs[0]=retPtr; } else if(!strcmp("buildTreeFromBatch",cmd)) { double *dataBatch; //Get the pointer back from Matlab. theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); checkRealDoubleArray(prhs[2]); dataBatch=reinterpret_cast<double*>(mxGetData(prhs[2])); theTree->buildTreeFromBatch(dataBatch); } else if(!strcmp("searchRadius",cmd)) { size_t numPoints; ClusterSetCPP<size_t> pointClust; ClusterSetCPP<double> distClust; double *point; double *radius; mxArray *clustParams[3]; //Get the inputs theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); checkRealDoubleArray(prhs[2]); checkRealDoubleArray(prhs[3]); point=reinterpret_cast<double*>(mxGetData(prhs[2])); radius=reinterpret_cast<double*>(mxGetData(prhs[3])); numPoints=mxGetN(prhs[2]); if(mxGetM(prhs[2])!=theTree->k){ mexErrMsgTxt("Invalid point size passed."); } //Run the search; rangeCluster now contains the results. theTree->searchRadius(pointClust,distClust,point,radius, numPoints); //Put the results into an instance of the ClusterSet container //class in Matlab. clustParams[0]=unsignedSizeMat2Matlab(pointClust.clusterEls,pointClust.totalNumEl,1); clustParams[1]=unsignedSizeMat2Matlab(pointClust.clusterSizes,pointClust.numClust,1); clustParams[2]=unsignedSizeMat2Matlab(pointClust.offsetArray,pointClust.numClust,1); //Return a ClusterSet containing the appropriate data. mexCallMATLAB(1, &(plhs[0]), 3, clustParams, "ClusterSet"); //If the distances should also be returned. if(nlhs>1) { clustParams[0]=doubleMat2Matlab(distClust.clusterEls,distClust.totalNumEl,1); clustParams[1]=unsignedSizeMat2Matlab(distClust.clusterSizes,distClust.numClust,1); clustParams[2]=unsignedSizeMat2Matlab(distClust.offsetArray,distClust.numClust,1); //Return a ClusterSet containing the appropriate data. mexCallMATLAB(1, &(plhs[1]), 3, clustParams, "ClusterSet"); } } else if(!strcmp("~metricTreeCPP", cmd)){ theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); delete theTree; //Unlock the mex file allowing it to be cleared. mexUnlock(); } else if(!strcmp("getAllData", cmd)){ size_t N; size_t k; theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); N=theTree->N; k=theTree->k; plhs[0]=unsignedSizeMat2Matlab(theTree->DATAIDX,N, 1); if(nlhs>1) { plhs[1]=signedSizeMat2Matlab(theTree->innerChild,N, 1); if(nlhs>2) { plhs[2]=signedSizeMat2Matlab(theTree->outerChild,N, 1); if(nlhs>3) { plhs[3]=doubleMat2Matlab(theTree->innerRadii,N, 1); if(nlhs>4) { plhs[4]=doubleMat2Matlab(theTree->outerRadii,N, 1); if(nlhs>5) { plhs[5]=doubleMat2Matlab(theTree->data,k, N); } } } } } } else if(!strcmp("getN", cmd)) { theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); plhs[0]=unsignedSizeMat2Matlab(&(theTree->N),1,1); } else if(!strcmp("getk", cmd)) { theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); plhs[0]=unsignedSizeMat2Matlab(&(theTree->k),1,1); }else { mexErrMsgTxt("Invalid string passed to metricTreeCPPInt."); } }