Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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();
}
Ejemplo n.º 7
0
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();
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 12
0
//=============================================================================
// 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;
}
Ejemplo n.º 13
0
/* ----
 */
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");
}
Ejemplo n.º 14
0
/* 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;
    }
}
Ejemplo n.º 15
0
// 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;
    
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
/*
 * 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;
  }

}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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();
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
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();
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
/*
 * 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;
  }

}
Ejemplo n.º 24
0
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
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
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 */
Ejemplo n.º 28
0
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.");
    }
}