Beispiel #1
0
/*
 * Main entry
 */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    char uidstr[40];
    uuidgen(uidstr);

    const char *s = uidstr;
    const char **ps = &s;

    plhs[0] = mxCreateCharMatrixFromStrings(1, ps);
    
    if( nrhs == 1 ){
      mxSetN( plhs[0] , *(mxGetPr(prhs[0])) );
    }
}
Beispiel #2
0
void readLines(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nlhs < 1) mexErrMsgTxt("One output argument required.");

  NetClient *nc = GetNetClient(nrhs, prhs);
  try {
    char **lines = nc->receiveLines();
    int m;
    for (m = 0; lines[m]; m++) {} // count number of lines
    plhs[0] = mxCreateCharMatrixFromStrings(m, const_cast<const char **>(lines));
    NetClient::deleteReceivedLines(lines);
  } catch (const SocketException &e) {
    mexWarnMsgTxt(e.why().c_str());
    RETURN_NULL(); // empty return set
  }
}
void
mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    int i;
    char *str[100];
    
    /* Check for proper number of input and output arguments */
    if (nrhs < 2) {
        mexErrMsgIdAndTxt( "MATLAB:mxcreatecharmatrixfromstr:minrhs",
                "At least two input arguments required.");
    }
    if(nlhs > 1){
        mexErrMsgIdAndTxt( "MATLAB:mxcreatecharmatrixfromstr:maxlhs",
                "Too many output arguments.");
    }
    
    for (i=0; i<nrhs; i++){
        /* Check input to be sure it is of type char. */
        if(!mxIsChar(prhs[i])){
            mexErrMsgIdAndTxt( "MATLAB:mxcreatecharmatrixfromstr:invalidInputType",
                    "Input must be of type char.");
        }
        /* Copy the string data from prhs and place it into str. */
        str[i] = mxArrayToString(prhs[i]);
    }
    
    /* Create a 2-Dimensional string mxArray with NULL padding. */
    plhs[0]= mxCreateCharMatrixFromStrings((mwSize)nrhs, (const char **)str);
    
    /* If compile with -DSPACE_PADDING, convert NULLs to spaces */
#if defined(SPACE_PADDING)
    {
        mwSize j;
        mwSize nelem = mxGetNumberOfElements(plhs[0]);
        mxChar *charData = (mxChar *)mxGetData(plhs[0]);
        for(j=0; j < nelem; j++) {
            if(charData[j] == (mxChar) 0) {
                charData[j] = (mxChar) ' ';
            }
        }
    }
#endif
    /* Free the allocated memory */
    for (i=0; i<nrhs; i++) {
        mxFree(str[i]);
    }
}
Beispiel #4
0
mxArray *get_column(sqlite3_stmt *stmt, int index)
{
    int type = sqlite3_column_type(stmt, index);
    if (type == SQLITE_TEXT) {
        const char *text = sqlite3_column_text(stmt, index);
        return mxCreateCharMatrixFromStrings(1, &text);
    } else if (type == SQLITE_FLOAT) {
        return mxCreateDoubleScalar(sqlite3_column_double(stmt, index));
    } else if (type == SQLITE_INTEGER) {
        mxArray *a = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
        int64_t val = sqlite3_column_int64(stmt, index);
        memcpy(mxGetData(a), &val, sizeof val);
        return a;
    }
    mexErrMsgIdAndTxt("sqlite3:get_column", "unsupported column type");
    return NULL;
}
mxArray *dynListToCellArray(DYN_LIST *dl)
{
  int dims;
  int i;
  DYN_LIST **sublists;
  mxArray *retval = NULL, *cell;
  double *d;

  switch(DYN_LIST_DATATYPE(dl)) {
  case DF_LIST:
    dims = DYN_LIST_N(dl);
    retval = mxCreateCellArray(1, (const mwSize*)&dims);
    sublists = (DYN_LIST **) DYN_LIST_VALS(dl);
    for (i = 0; i < DYN_LIST_N(dl); i++) {
      cell = dynListToCellArray(sublists[i]);
      mxSetCell(retval, i, cell);
    }
    break;
  case DF_INT:
    {
      int *vals = (int *) DYN_LIST_VALS(dl);
      retval = mxCreateDoubleMatrix(DYN_LIST_N(dl), 1, mxREAL);
      d = mxGetPr(retval);
      for ( i = 0; i < DYN_LIST_N(dl); i++ ) 
	d[i] = (double) vals[i];
    }
    break;
  case DF_SHORT:
    {
      short *vals = (short *) DYN_LIST_VALS(dl);
      retval = mxCreateDoubleMatrix(DYN_LIST_N(dl), 1, mxREAL);
      d = mxGetPr(retval);
      for ( i = 0; i < DYN_LIST_N(dl); i++ ) 
	d[i] = (double) vals[i];
    }
    break;
  case DF_FLOAT:
    {
      float *vals = (float *) DYN_LIST_VALS(dl);
      retval = mxCreateDoubleMatrix(DYN_LIST_N(dl), 1, mxREAL);
      d = mxGetPr(retval);
      for ( i = 0; i < DYN_LIST_N(dl); i++ ) 
	d[i] = (double) vals[i];
    }
    break;
  case DF_CHAR:
    {
      char *vals = (char *) DYN_LIST_VALS(dl);
      retval = mxCreateDoubleMatrix(DYN_LIST_N(dl), 1, mxREAL);
      d = mxGetPr(retval);
      for ( i = 0; i < DYN_LIST_N(dl); i++ ) 
	d[i] = (double) vals[i];
    }
    break;
  case DF_STRING:
    {
      char **vals = (char **) DYN_LIST_VALS(dl);
      retval = mxCreateCharMatrixFromStrings(DYN_LIST_N(dl), (const char **)vals);
    }
  }
  return retval;
}
Beispiel #6
0
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    int        i,j,k;
    mwSize dims[] = {1,5};
    mwSize CIdims[] = {0,0,2};
    mwSize DSdims[] = {0,0,2};
    const char* field_names[] = {"Events", "CIs", "Sign", "Nab", "DS", "String"};
    int Events_field, CIs_field, Sign_field, Nab_field, DS_field, String_field;
    char *str;
    int  max_event_name,  max_event_indexes;
    double *pr;
    t_time_series ts;
    int Namax, buf[3], tid;
    t_pattern_list *tmp;
    t_pattern *Ip;
    mxArray *mArray;
    
    iteration_number = 0;
    
    ts.ci_strategy = T_SHORTEST_CI;
    ts.output = stdout;
    ts.alpha = 0.005;
    ts.Nmin = 3;
    ts.nlevels = 0;
    ts.allow_same_events_in_pattern = 1;
  	logfac_table_size = 0;
  	C_iz_N_po_k_table_K = C_iz_N_po_k_table_N = 0;
       

   
        ts.num_event_types = mxGetN( prhs[0] );
        ts.Nt = mxGetScalar(prhs[1]);
        ts.nlevels = mxGetN( prhs[2] );
        ts.event_i = (unsigned int**) malloc( ts.num_event_types * sizeof(unsigned int *));
        ts.event_sign = (char**) malloc( ts.num_event_types * sizeof(char*) );
        ts.N = (int*) malloc( ts.num_event_types * sizeof( unsigned int ) );
        ts.levels = (t_levels*) malloc( ts.nlevels * sizeof( t_levels ) );


        for ( i = 0; i < ts.num_event_types; i++ )
        {
            pr = mxGetField( prhs[0], i,  "indexes" );
            ts.N[i] = mxGetN( pr );
            ts.event_i[i] = (unsigned int*) malloc( ts.N[i] *sizeof( unsigned int ) );
            /*Can't use memcpy here!!*/
            for ( j = 0; j < ts.N[i]; j++ ) ts.event_i[i][j] = (unsigned int) *( mxGetPr(pr) + j) - 1 ;

            pr = mxGetField( prhs[0], i,  "event_name" );
            ts.event_sign[i] = (char*) mxArrayToString( pr );
        }

        /*copy alpha and Nab struct*/
        pr = mxGetPr( prhs[2] );
        for ( i = 0; i < ts.nlevels; i++ )
        {
            ts.levels[i].len =  pr[i*3 + 0];
            ts.levels[i].alpha = pr[i*3 + 1];
            ts.levels[i].Nmin =  pr[i*3 + 2];
        }

        /*Defaults*/
        ts.patterns = (t_pattern_list*) malloc( sizeof( t_pattern_list ) );
        ts.patterns->next=NULL;
        ts.ci_strategy = mxGetScalar(prhs[4]);
        ts.output = stdout;
        ts.alpha = 0.005;
        ts.Nmin = 3;
        ts.allow_same_events_in_pattern = mxGetScalar(prhs[3]);
        logfac_table_size = 0;
        C_iz_N_po_k_table_K = C_iz_N_po_k_table_N = 0; 

        /* Construct pseudo patterns */
        for ( i = 0; i < ts.num_event_types; i++ )
        {
            Namax =  Namax < ts.N[i] ? ts.N[i] : Namax;  
            buf[0] = i;
            tmp = add_pattern(ts.patterns, buf, 1);
            tmp->pat.ind = ( double_series*) malloc( sizeof(double_series) * ts.N[i] );
            tmp->pat.N = ts.N[i];
            for ( j = 0; j < ts.N[i]; j++)
            {
                tmp->pat.ind[j].l = tmp->pat.ind[j].r = ts.event_i[i][j];
            }
        }
        if (logfac_table_size)
        {
            fill_logfac_table( Namax+1 );
            fill_C_iz_N_po_k_table( Namax+1, Namax+1);
        }
    
    #pragma omp parallel private(tid)
    {
        tid = omp_get_thread_num();
        mexPrintf("Hello World from thread = %d\n", tid);
    }

    t_detect_patterns(&ts);
      
    mexPrintf("\n ITERATIONS %d\n", iteration_number); 
    dims[1] = num_patterns[ iteration_number - 1  ];
    plhs[0] = mxCreateStructArray(2, dims, 6, field_names);
    Events_field   = mxGetFieldNumber( plhs[0], "Events" );
    CIs_field      = mxGetFieldNumber( plhs[0], "CIs" );
    Sign_field     = mxGetFieldNumber( plhs[0], "Sign" );
    Nab_field      = mxGetFieldNumber( plhs[0], "Nab" );
    DS_field       = mxGetFieldNumber( plhs[0], "DS" );
    String_field   = mxGetFieldNumber( plhs[0], "String" );
    
    tmp = patterns_it[ iteration_number - 1 ]->next;
    for ( i = 0; i < num_patterns[ iteration_number - 1  ]; i++ )
    {
        Ip = &tmp->pat;
        /* Fill pattern field */
        mArray = mxCreateDoubleMatrix( 1, Ip->nevents, mxREAL );
        mxSetFieldByNumber(plhs[0], i, Events_field,  mArray );
        pr = mxGetPr( mArray );
        for ( j = 0; j < Ip->nevents; j++ )
            pr[j] = Ip->events[j] + 1; /*Matlab base index is 1 !!!*/            
        
        /* Fill significance field */
        mArray = mxCreateDoubleScalar( Ip->significance );
        mxSetFieldByNumber(plhs[0], i, Sign_field,  mArray );
               
        /* Fill Nab field */
        mArray = mxCreateDoubleScalar( Ip->N );
        mxSetFieldByNumber(plhs[0], i, Nab_field,  mArray );
                
        /* Fill CI field */
        mArray = mxCreateDoubleMatrix( Ip->nevents - 1, 2, mxREAL);
        mxSetFieldByNumber(plhs[0], i, CIs_field,  mArray );
        pr = mxGetPr( mArray );
        for ( j = 0; j < Ip->nevents - 1; j++ )
        {
            pr[ 0*(Ip->nevents - 1) + j ] = Ip->CI[j].l;
            pr[ 1*(Ip->nevents - 1) + j ] = Ip->CI[j].r;
        }
        
        /* Fill DS field */
        mArray = mxCreateDoubleMatrix( Ip->N, 2, mxREAL);
        mxSetFieldByNumber(plhs[0], i, DS_field,  mArray );
        pr = mxGetPr( mArray );
        for ( j = 0; j < Ip->N; j++ )
        {
            pr[ 0 * Ip->N + j ] = Ip->ind[j].l + 1; /*Matlab base index is 1 !!!*/   
            pr[ 1 * Ip->N + j ] = Ip->ind[j].r + 1; /*Matlab base index is 1 !!!*/   
        }
        
        mArray = mxCreateCharMatrixFromStrings( 1, &pattern_strings[i]);
        mxSetFieldByNumber(plhs[0], i, String_field,  mArray );
        tmp = tmp->next;
    }
    
}
Beispiel #7
0
void mexFunction(
    int           nlhs,           /* number of expected outputs */
    mxArray       *plhs[],        /* array of pointers to output arguments */
    int           nrhs,           /* number of inputs */
    const mxArray *prhs[]         /* array of pointers to input arguments */
)

{
	size_t 		k,k1;
	const mxArray	*arg;
	mxArray		*HDR;
	HDRTYPE		*hdr;
	CHANNEL_TYPE*	cp; 
	size_t 		count;
	time_t 		T0;
	char 		*FileName=NULL;  
	int 		status; 
	int		CHAN = 0;
	int		TARGETSEGMENT = 1; 
	double		*ChanList=NULL;
	int		NS = -1;
	char		FlagOverflowDetection = 1, FlagUCAL = 0;
	int		argSweepSel = -1;
	
#ifdef CHOLMOD_H
	cholmod_sparse RR,*rr=NULL;
	double dummy;
#endif 

// ToDO: output single data 
//	mxClassId	FlagMXclass=mxDOUBLE_CLASS;
	

	if (nrhs<1) {
#ifdef mexSOPEN
		mexPrintf("   Usage of mexSOPEN:\n");
		mexPrintf("\tHDR = mexSOPEN(f)\n");
		mexPrintf("   Input:\n\tf\tfilename\n");
		mexPrintf("   Output:\n\tHDR\theader structure\n\n");
#else
		mexPrintf("   Usage of mexSLOAD:\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f)\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan)\n\t\tchan must be sorted in ascending order\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,ReRef)\n\t\treref is a (sparse) matrix for rerefencing\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'...')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OVERFLOWDETECTION:ON')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OVERFLOWDETECTION:OFF')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'UCAL:ON')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'UCAL:OFF')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OUTPUT:SINGLE')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'TARGETSEGMENT:<N>')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'SWEEP',[NE, NG, NS])\n");
		mexPrintf("   Input:\n\tf\tfilename\n");
		mexPrintf("\tchan\tlist of selected channels; 0=all channels [default]\n");
		mexPrintf("\tUCAL\tON: do not calibrate data; default=OFF\n");
//		mexPrintf("\tOUTPUT\tSINGLE: single precision; default='double'\n");
		mexPrintf("\tOVERFLOWDETECTION\tdefault = ON\n\t\tON: values outside dynamic range are not-a-number (NaN)\n");
		mexPrintf("\tTARGETSEGMENT:<N>\n\t\tselect segment <N> in multisegment files (like Nihon-Khoden), default=1\n\t\tIt has no effect for other data formats.\n");
		mexPrintf("\t[NE, NG, NS] are the number of the experiment, the series and the sweep, resp. for sweep selection in HEKA/PatchMaster files. (0 indicates all)\n");
		mexPrintf("\t\t examples: [1,2,3] the 3rd sweep from the 2nd series of experiment 1; [1,3,0] selects all sweeps from experiment=1, series=3. \n\n");
		mexPrintf("   Output:\n\ts\tsignal data, each column is one channel\n");
		mexPrintf("\tHDR\theader structure\n\n");
#endif
		return; 
	}

/*
 	improve checks for input arguments
*/
	/* process input arguments */
	for (k = 0; k < nrhs; k++) {	
		arg = prhs[k];
		if (mxIsEmpty(arg) && (k>0)) {
#ifdef DEBUG		
			mexPrintf("arg[%i] Empty\n",k);
#endif
		}
		else if ((k==0) && mxIsCell(arg) && mxGetNumberOfElements(arg)==1 && mxGetCell(arg,0) && mxIsChar(mxGetCell(arg,0))) {
			FileName = mxArrayToString(mxGetCell(arg,0));
#ifdef DEBUG		
			mexPrintf("arg[%i] IsCell\n",k);
#endif
		}
		else if ((k==0) && mxIsStruct(arg)) {
			FileName = mxArrayToString(mxGetField(prhs[k],0,"FileName"));
#ifdef DEBUG		
			mexPrintf("arg[%i] IsStruct\n",k);
#endif
		}
#ifdef CHOLMOD_H
		else if ((k==1) && mxIsSparse(arg)) {
			rr = sputil_get_sparse(arg,&RR,&dummy,0);
		}
#endif 
		else if ((k==1) && mxIsNumeric(arg)) {
#ifdef DEBUG		
			mexPrintf("arg[%i] IsNumeric\n",k);
#endif
			ChanList = (double*)mxGetData(prhs[k]);
			NS = mxGetNumberOfElements(prhs[k]);
		}	
		else if (mxIsChar(arg)) {
#ifdef DEBUG		
			mexPrintf("arg[%i]=%s \n",k,mxArrayToString(prhs[k]));
#endif
			if (k==0)			
				FileName = mxArrayToString(prhs[k]);
			else if (!strcmp(mxArrayToString(prhs[k]), "CNT32"))
				; // obsolete - supported for backwards compatibility
			else if (!strcmp(mxArrayToString(prhs[k]), "OVERFLOWDETECTION:ON"))
				FlagOverflowDetection = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "OVERFLOWDETECTION:OFF"))
				FlagOverflowDetection = 0;
			else if (!strcmp(mxArrayToString(prhs[k]), "UCAL:ON")) 
				FlagUCAL = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "UCAL:OFF"))
				FlagUCAL = 0;
//			else if (!strcmp(mxArrayToString(prhs[k]),"OUTPUT:SINGLE"))
//				FlagMXclass = mxSINGLE_CLASS;
			else if (!strncmp(mxArrayToString(prhs[k]),"TARGETSEGMENT:",14))
				TARGETSEGMENT = atoi(mxArrayToString(prhs[k])+14);
			else if (!strcasecmp(mxArrayToString(prhs[k]), "SWEEP") && (prhs[k+1] != NULL) && mxIsNumeric(prhs[k+1]))
				argSweepSel = ++k;
		}
		else {
#ifndef mexSOPEN
			mexPrintf("mexSLOAD: argument #%i is invalid.",k+1);	
			mexErrMsgTxt("mexSLOAD failes because of unknown parameter\n");	
#else
			mexPrintf("mexSOPEN: argument #%i is invalid.",k+1);	
			mexErrMsgTxt("mexSOPEN fails because of unknown parameter\n");	
#endif
		}
	}

	if (VERBOSE_LEVEL>7) 
		mexPrintf("110: input arguments checked\n");

	hdr = constructHDR(0,0);

#ifdef __LIBBIOSIG2_H__

	unsigned flags = (!!FlagOverflowDetection)*BIOSIG_FLAG_OVERFLOWDETECTION + (!!FlagUCAL)*BIOSIG_FLAG_UCAL;
#ifdef CHOLMOD_H
	flags += (rr!=NULL)*BIOSIG_FLAG_ROW_BASED_CHANNELS;
#else
	biosig_reset_flag(hdr, BIOSIG_FLAG_ROW_BASED_CHANNELS);
#endif
	biosig_set_flag(hdr, flags);

	biosig_set_targetsegment(hdr, TARGETSEGMENT);

	// sweep selection for Heka format
	if (argSweepSel>0) {
		double *SZ     = (double*) mxGetData(prhs[argSweepSel]);
		k = 0;
		while (k < mxGetNumberOfElements(prhs[argSweepSel]) && k < 5) {
			biosig_set_segment_selection(hdr, k+1, (uint32_t)SZ[k]);
			k++;
		}
	}

#else //__LIBBIOSIG2_H__


	hdr->FLAG.OVERFLOWDETECTION = FlagOverflowDetection; 
	hdr->FLAG.UCAL = FlagUCAL;
#ifdef CHOLMOD_H
	hdr->FLAG.ROW_BASED_CHANNELS = (rr!=NULL); 
#else 	
	hdr->FLAG.ROW_BASED_CHANNELS = 0; 
#endif 
	hdr->FLAG.TARGETSEGMENT = TARGETSEGMENT;

	// sweep selection for Heka format 
	if (argSweepSel>0) { 				
		double *SZ     = (double*) mxGetData(prhs[argSweepSel]);
		k = 0;
		while (k < mxGetNumberOfElements(prhs[argSweepSel]) && k < 5) { 
			hdr->AS.SegSel[k] = (uint32_t)SZ[k];
			k++;
		}
	}


#endif // __LIBBIOSIG2_H__ : TODO: below, nothing is converted to level-2 interface, yet


	if (VERBOSE_LEVEL>7) 
		mexPrintf("120: going to sopen\n");

	hdr = sopen(FileName, "r", hdr);
/*
#ifdef WITH_PDP 
	if (hdr->AS.B4C_ERRNUM) {
		hdr->AS.B4C_ERRNUM = 0;
		sopen_pdp_read(hdr);
	}	
#endif
*/
	if (VERBOSE_LEVEL>7) 
		mexPrintf("121: sopen done\n");

	if ((status=serror2(hdr))) {

		const char* fields[]={"TYPE","VERSION","FileName","FLAG","ErrNum","ErrMsg"};
		HDR = mxCreateStructMatrix(1, 1, 6, fields);
#ifdef __LIBBIOSIG2_H__
		mxSetField(HDR,0,"FileName",mxCreateString(biosig_get_filename(hdr)));
		const char *FileTypeString = GetFileTypeString(biosig_get_filetype(hdr));
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(biosig_get_version(hdr)));
#else
		mxSetField(HDR,0,"FileName",mxCreateString(hdr->FileName));
		const char *FileTypeString = GetFileTypeString(hdr->TYPE);
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(hdr->VERSION));
#endif
		mxArray *errnum = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
		*(uint8_t*)mxGetData(errnum) = (uint8_t)status;
		mxSetField(HDR,0,"ErrNum",errnum);
		
#ifdef HAVE_OCTAVE
		// handle bug in octave: mxCreateString(NULL) causes segmentation fault
		// Octave 3.2.3 causes a seg-fault in mxCreateString(NULL)
		if (FileTypeString) FileTypeString="\0";
#endif
		mxSetField(HDR,0,"TYPE",mxCreateString(FileTypeString));


		char *msg = (char*)malloc(72+23+strlen(FileName)); // 72: max length of constant text, 23: max length of GetFileTypeString()
		if (msg == NULL) 
			mxSetField(HDR,0,"ErrMsg",mxCreateString("Error mexSLOAD: Cannot open file\n"));
		else {	
		    if (status==B4C_CANNOT_OPEN_FILE)
			sprintf(msg,"Error mexSLOAD: file %s not found.\n",FileName);		/* Flawfinder: ignore *** sufficient memory is allocated above */
		    else if (status==B4C_FORMAT_UNKNOWN)
			sprintf(msg,"Error mexSLOAD: Cannot open file %s - format %s not known.\n",FileName,FileTypeString);	/* Flawfinder: ignore *** sufficient memory is allocated above */
		    else if (status==B4C_FORMAT_UNSUPPORTED)
			sprintf(msg,"Error mexSLOAD: Cannot open file %s - format %s not supported [%s].\n", FileName, FileTypeString, hdr->AS.B4C_ERRMSG);	/* Flawfinder: ignore *** sufficient memory is allocated above */
		    else 	
			sprintf(msg,"Error %i mexSLOAD: Cannot open file %s - format %s not supported [%s].\n", status, FileName, FileTypeString, hdr->AS.B4C_ERRMSG); 	/* Flawfinder: ignore *** sufficient memory is allocated above */
			
		    mxSetField(HDR,0,"ErrMsg",mxCreateString(msg));
		    free(msg);
		}    

	if (VERBOSE_LEVEL>7) 
		mexPrintf("737: abort mexSLOAD - sopen failed\n");

		destructHDR(hdr);

	if (VERBOSE_LEVEL>7) 
		mexPrintf("757: abort mexSLOAD - sopen failed\n");

#ifdef mexSOPEN
		plhs[0] = HDR; 
#else
		plhs[0] = mxCreateDoubleMatrix(0,0, mxREAL);
		plhs[1] = HDR; 
#endif 		 
	if (VERBOSE_LEVEL>7) 
		mexPrintf("777: abort mexSLOAD - sopen failed\n");

		return; 
	}

#ifdef CHOLMOD_H
	RerefCHANNEL(hdr,rr,2);
#endif

	if (hdr->FLAG.OVERFLOWDETECTION != FlagOverflowDetection)
		mexPrintf("Warning mexSLOAD: Overflowdetection not supported in file %s\n",hdr->FileName);
	if (hdr->FLAG.UCAL != FlagUCAL)
		mexPrintf("Warning mexSLOAD: Flag UCAL is %i instead of %i (%s)\n",hdr->FLAG.UCAL,FlagUCAL,hdr->FileName);


	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"[112] SOPEN-R finished NS=%i %i\n",hdr->NS,NS);

//	convert2to4_eventtable(hdr); 
		
#ifdef CHOLMOD_H
	if (hdr->Calib != NULL) {
		NS = hdr->Calib->ncol;
	}
	else 
#endif
	if ((NS<0) || ((NS==1) && (ChanList[0] == 0.0))) { 	// all channels
		for (k=0, NS=0; k<hdr->NS; ++k) {
			if (hdr->CHANNEL[k].OnOff) NS++; 
		}	
	}		
	else {		
		for (k=0; k<hdr->NS; ++k)
			hdr->CHANNEL[k].OnOff = 0; 	// reset
		for (k=0; k<NS; ++k) {
			int ch = (int)ChanList[k];
			if ((ch < 1) || (ch > hdr->NS)) 
				mexPrintf("Invalid channel number CHAN(%i) = %i!\n",k+1,ch); 
			else 	
				hdr->CHANNEL[ch-1].OnOff = 1;  // set
		}		
	}
	
	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"[113] NS=%i %i\n",hdr->NS,NS);

#ifndef mexSOPEN
	if (hdr->FLAG.ROW_BASED_CHANNELS)
		plhs[0] = mxCreateDoubleMatrix(NS, hdr->NRec*hdr->SPR, mxREAL);
	else
		plhs[0] = mxCreateDoubleMatrix(hdr->NRec*hdr->SPR, NS, mxREAL);

	count = sread(mxGetPr(plhs[0]), 0, hdr->NRec, hdr);
	hdr->NRec = count; 
#endif
	sclose(hdr);
#ifdef CHOLMOD_H
        if (hdr->Calib && hdr->rerefCHANNEL) {
		hdr->NS = hdr->Calib->ncol; 
                free(hdr->CHANNEL);
                hdr->CHANNEL = hdr->rerefCHANNEL;
                hdr->rerefCHANNEL = NULL; 
                hdr->Calib = NULL; 
        }                
#endif 
	if ((status=serror2(hdr))) return;  

	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"\n[129] SREAD/SCLOSE on %s successful [%i,%i] [%i,%i] %i.\n",hdr->FileName,(int)hdr->data.size[0],(int)hdr->data.size[1],(int)hdr->NRec,(int)count,(int)NS);


//	hdr2ascii(hdr,stderr,4);	

#ifndef mexSOPEN 

	if (nlhs>1) { 
#endif

		char* mexFileName = (char*)mxMalloc(strlen(hdr->FileName)+1); 

		mxArray *tmp, *tmp2, *Patient, *Manufacturer, *ID, *EVENT, *Filter, *Flag, *FileType;
		uint16_t numfields;
		const char *fnames[] = {"TYPE","VERSION","FileName","T0","tzmin","FILE","Patient",\
		"HeadLen","NS","SPR","NRec","SampleRate", "FLAG", \
		"EVENT","Label","LeadIdCode","PhysDimCode","PhysDim","Filter",\
		"PhysMax","PhysMin","DigMax","DigMin","Transducer","Cal","Off","GDFTYP","TOffset",\
		"LowPass","HighPass","Notch","ELEC","Impedance","fZ","AS","Dur","REC","Manufacturer",NULL};

		for (numfields=0; fnames[numfields++] != NULL; );
		HDR = mxCreateStructMatrix(1, 1, --numfields, fnames);

		mxSetField(HDR,0,"TYPE",mxCreateString(GetFileTypeString(hdr->TYPE)));
		mxSetField(HDR,0,"HeadLen",mxCreateDoubleScalar(hdr->HeadLen));
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(hdr->VERSION));
		mxSetField(HDR,0,"NS",mxCreateDoubleScalar(NS));
		mxSetField(HDR,0,"SPR",mxCreateDoubleScalar(hdr->SPR));
		mxSetField(HDR,0,"NRec",mxCreateDoubleScalar(hdr->NRec));
		mxSetField(HDR,0,"SampleRate",mxCreateDoubleScalar(hdr->SampleRate));
		mxSetField(HDR,0,"Dur",mxCreateDoubleScalar(hdr->SPR/hdr->SampleRate));
		mxSetField(HDR,0,"FileName",mxCreateString(hdr->FileName));
                
		mxSetField(HDR,0,"T0",mxCreateDoubleScalar(ldexp(hdr->T0,-32)));
		mxSetField(HDR,0,"tzmin",mxCreateDoubleScalar(hdr->tzmin));

		/* Channel information */ 
#ifdef CHOLMOD_H
/*
        	if (hdr->Calib == NULL) { // is refering to &RR, do not destroy
		        mxArray *Calib = mxCreateDoubleMatrix(hdr->Calib->nrow, hdr->Calib->ncol, mxREAL);

        	}
*/
#endif
		mxArray *LeadIdCode  = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *PhysDimCode = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *GDFTYP      = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *PhysMax     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *PhysMin     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *DigMax      = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *DigMin      = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Cal         = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Off         = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Toffset     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *ELEC_POS    = mxCreateDoubleMatrix(NS,3, mxREAL);
/*
		mxArray *ELEC_Orient = mxCreateDoubleMatrix(NS,3, mxREAL);
		mxArray *ELEC_Area   = mxCreateDoubleMatrix(NS,1, mxREAL);
*/
		mxArray *LowPass     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *HighPass    = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Notch       = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Impedance   = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *fZ          = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *SPR         = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Label       = mxCreateCellMatrix(NS,1);
		mxArray *Transducer  = mxCreateCellMatrix(NS,1);
		mxArray *PhysDim1    = mxCreateCellMatrix(NS,1);

		for (k=0,k1=0; k1<NS; ++k) 
		if (hdr->CHANNEL[k].OnOff) {
			*(mxGetPr(LeadIdCode)+k1)	= (double)hdr->CHANNEL[k].LeadIdCode;
			*(mxGetPr(PhysDimCode)+k1)	= (double)hdr->CHANNEL[k].PhysDimCode;
			*(mxGetPr(GDFTYP)+k1)		= (double)hdr->CHANNEL[k].GDFTYP;
			*(mxGetPr(PhysMax)+k1)		= (double)hdr->CHANNEL[k].PhysMax;
			*(mxGetPr(PhysMin)+k1)		= (double)hdr->CHANNEL[k].PhysMin;
			*(mxGetPr(DigMax)+k1)		= (double)hdr->CHANNEL[k].DigMax;
			*(mxGetPr(DigMin)+k1)		= (double)hdr->CHANNEL[k].DigMin;
			*(mxGetPr(Toffset)+k1)		= (double)hdr->CHANNEL[k].TOffset;
			*(mxGetPr(Cal)+k1) 		= (double)hdr->CHANNEL[k].Cal;
			*(mxGetPr(Off)+k1) 		= (double)hdr->CHANNEL[k].Off;
			*(mxGetPr(SPR)+k1) 		= (double)hdr->CHANNEL[k].SPR;
			*(mxGetPr(LowPass)+k1) 		= (double)hdr->CHANNEL[k].LowPass;
			*(mxGetPr(HighPass)+k1) 	= (double)hdr->CHANNEL[k].HighPass;
			*(mxGetPr(Notch)+k1) 		= (double)hdr->CHANNEL[k].Notch;
			*(mxGetPr(Impedance)+k1)	= (double)hdr->CHANNEL[k].Impedance;
			*(mxGetPr(fZ)+k1)		= (double)hdr->CHANNEL[k].fZ;
			*(mxGetPr(ELEC_POS)+k1)    	= (double)hdr->CHANNEL[k].XYZ[0];
			*(mxGetPr(ELEC_POS)+k1+NS)	= (double)hdr->CHANNEL[k].XYZ[1];
			*(mxGetPr(ELEC_POS)+k1+NS*2)	= (double)hdr->CHANNEL[k].XYZ[2];
/*
			*(mxGetPr(ELEC_Orient)+k1)	= (double)hdr->CHANNEL[k].Orientation[0];
			*(mxGetPr(ELEC_Orient)+k1+NS)	= (double)hdr->CHANNEL[k].Orientation[1];
			*(mxGetPr(ELEC_Orient)+k1+NS*2)	= (double)hdr->CHANNEL[k].Orientation[2];
			*(mxGetPr(ELEC_Area)+k1)	= (double)hdr->CHANNEL[k].Area;
*/
			mxSetCell(Label,k1,mxCreateString(hdr->CHANNEL[k].Label));
			mxSetCell(Transducer,k1,mxCreateString(hdr->CHANNEL[k].Transducer));
			
			mxSetCell(PhysDim1,k1,mxCreateString(PhysDim3(hdr->CHANNEL[k].PhysDimCode)));
			k1++;
		} 

		mxSetField(HDR,0,"LeadIdCode",LeadIdCode);
		mxSetField(HDR,0,"PhysDimCode",PhysDimCode);
		mxSetField(HDR,0,"GDFTYP",GDFTYP);
		mxSetField(HDR,0,"PhysMax",PhysMax);
		mxSetField(HDR,0,"PhysMin",PhysMin);
		mxSetField(HDR,0,"DigMax",DigMax);
		mxSetField(HDR,0,"DigMin",DigMin);
		mxSetField(HDR,0,"TOffset",Toffset);
		mxSetField(HDR,0,"Cal",Cal);
		mxSetField(HDR,0,"Off",Off);
		mxSetField(HDR,0,"Impedance",Impedance);
		mxSetField(HDR,0,"fZ",fZ);
		mxSetField(HDR,0,"Off",Off);
		mxSetField(HDR,0,"PhysDim",PhysDim1);
		mxSetField(HDR,0,"Transducer",Transducer);
		mxSetField(HDR,0,"Label",Label);

		const char* field[] = {"XYZ","Orientation","Area","GND","REF",NULL};
		for (numfields=0; field[numfields++] != 0; );
		tmp = mxCreateStructMatrix(1, 1, --numfields, field);
		mxSetField(tmp,0,"XYZ",ELEC_POS);
/*
		mxSetField(tmp,0,"Orientation",ELEC_Orient);
		mxSetField(tmp,0,"Area",ELEC_Area);
*/
		mxSetField(HDR,0,"ELEC",tmp);

		const char* field2[] = {"SPR",NULL};
		for (numfields=0; field2[numfields++] != 0; );
		tmp2 = mxCreateStructMatrix(1, 1, --numfields, field2);
		mxSetField(tmp2,0,"SPR",SPR);
		if (hdr->AS.bci2000!=NULL) {
			mxAddField(tmp2, "BCI2000");
			mxSetField(tmp2,0,"BCI2000",mxCreateString(hdr->AS.bci2000));
		}
		if (hdr->TYPE==Sigma) {	
			mxAddField(tmp2, "H1");
			mxSetField(tmp2,0,"H1",mxCreateString((char*)hdr->AS.Header));
		}	
		mxSetField(HDR,0,"AS",tmp2);
				
		/* FLAG */
		const char* field3[] = {"UCAL","OVERFLOWDETECTION","ROW_BASED_CHANNELS",NULL};
		for (numfields=0; field3[numfields++] != 0; );
		Flag = mxCreateStructMatrix(1, 1, --numfields, field3);
#ifdef MX_API_VER
//#if 1
                // Matlab, Octave 3.6.1 
       		mxSetField(Flag,0,"UCAL",mxCreateLogicalScalar(hdr->FLAG.UCAL));
        	mxSetField(Flag,0,"OVERFLOWDETECTION",mxCreateLogicalScalar(hdr->FLAG.OVERFLOWDETECTION));
        	mxSetField(Flag,0,"ROW_BASED_CHANNELS",mxCreateLogicalScalar(hdr->FLAG.ROW_BASED_CHANNELS));
#else 
                // mxCreateLogicalScalar are not included in Octave 3.0 
	        mxSetField(Flag,0,"UCAL",mxCreateDoubleScalar(hdr->FLAG.UCAL));
       		mxSetField(Flag,0,"OVERFLOWDETECTION",mxCreateDoubleScalar(hdr->FLAG.OVERFLOWDETECTION));
       		mxSetField(Flag,0,"ROW_BASED_CHANNELS",mxCreateDoubleScalar(hdr->FLAG.ROW_BASED_CHANNELS));
#endif
		mxSetField(HDR,0,"FLAG",Flag);

		/* Filter */ 
		const char *filter_fields[] = {"HighPass","LowPass","Notch",NULL};
		for (numfields=0; filter_fields[numfields++] != 0; );
		Filter = mxCreateStructMatrix(1, 1, --numfields, filter_fields);
		mxSetField(Filter,0,"LowPass",LowPass);
		mxSetField(Filter,0,"HighPass",HighPass);
		mxSetField(Filter,0,"Notch",Notch);
		mxSetField(HDR,0,"Filter",Filter);

		/* annotation, marker, event table */
		const char *event_fields[] = {"SampleRate","TYP","POS","DUR","CHN","Desc",NULL};
		
		if (hdr->EVENT.DUR == NULL)
			EVENT = mxCreateStructMatrix(1, 1, 3, event_fields);
		else {	
			EVENT = mxCreateStructMatrix(1, 1, 5, event_fields);
			mxArray *DUR = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			mxArray *CHN = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			for (k=0; k<hdr->EVENT.N; ++k) {
				*(mxGetPr(DUR)+k) = (double)hdr->EVENT.DUR[k];
				*(mxGetPr(CHN)+k) = (double)hdr->EVENT.CHN[k];  // channels use a 1-based index, 0 indicates all channels
			} 
			mxSetField(EVENT,0,"DUR",DUR);
			mxSetField(EVENT,0,"CHN",CHN);
		}

		if (hdr->EVENT.CodeDesc != NULL) {
			mxAddField(EVENT, "CodeDesc");
			mxArray *CodeDesc = mxCreateCellMatrix(hdr->EVENT.LenCodeDesc-1,1);
			for (k=1; k < hdr->EVENT.LenCodeDesc; ++k) {
				mxSetCell(CodeDesc,k-1,mxCreateString(hdr->EVENT.CodeDesc[k]));
			} 
			mxSetField(EVENT,0,"CodeDesc",CodeDesc);
		}	

		mxArray *TYP = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
		mxArray *POS = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);

		for (k=0; k<hdr->EVENT.N; ++k) {
			*(mxGetPr(TYP)+k) = (double)hdr->EVENT.TYP[k];
			*(mxGetPr(POS)+k) = (double)hdr->EVENT.POS[k]+1;   // conversion from 0-based to 1-based indexing 
		} 
		mxSetField(EVENT,0,"TYP",TYP);
		mxSetField(EVENT,0,"POS",POS);

#if (BIOSIG_VERSION >= 10500)
		if (hdr->EVENT.TimeStamp) {
			mxArray *TimeStamp = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			for (k=0; k<hdr->EVENT.N; ++k) {
				*(mxGetPr(TimeStamp)+k) = ldexp(hdr->EVENT.TimeStamp[k],-32);
			} 
			mxAddField(EVENT, "TimeStamp");
			mxSetField(EVENT,0,"TimeStamp",TimeStamp);
		}	
#endif
		mxSetField(EVENT,0,"SampleRate",mxCreateDoubleScalar(hdr->EVENT.SampleRate));
		mxSetField(HDR,0,"EVENT",EVENT);

		/* Record identification */ 
		const char *ID_fields[] = {"Recording","Technician","Hospital","Equipment","IPaddr",NULL};
		for (numfields=0; ID_fields[numfields++] != 0; );
		ID = mxCreateStructMatrix(1, 1, --numfields, ID_fields);
		mxSetField(ID,0,"Recording",mxCreateString(hdr->ID.Recording));
		mxSetField(ID,0,"Technician",mxCreateString(hdr->ID.Technician));
		mxSetField(ID,0,"Hospital",mxCreateString(hdr->ID.Hospital));
		mxSetField(ID,0,"Equipment",mxCreateString((char*)&hdr->ID.Equipment));
		int len = 4; 
		uint8_t IPv6=0;
		for (k=4; k<16; k++) IPv6 |= hdr->IPaddr[k];
		if (IPv6) len=16; 
		mxArray *IPaddr = mxCreateNumericMatrix(1,len,mxUINT8_CLASS,mxREAL);
		memcpy(mxGetData(IPaddr),hdr->IPaddr,len);
		mxSetField(ID,0,"IPaddr",IPaddr); 
		mxSetField(HDR,0,"REC",ID);

		/* Patient Information */ 
		const char *patient_fields[] = {"Sex","Handedness","Id","Name","Weight","Height","Birthday",NULL};
		for (numfields=0; patient_fields[numfields++] != 0; );
		Patient = mxCreateStructMatrix(1, 1, --numfields, patient_fields);
		const char *strarray[1];
#ifdef __LIBBIOSIG2_H__
		strarray[0] = biosig_get_patient_name(hdr);
		if (strarray[0]) {
			mxSetField(Patient,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_patient_id(hdr);
		if (strarray[0]) {
			mxSetField(Patient,0,"Id",mxCreateCharMatrixFromStrings(1,strarray));
		}	
#else
		strarray[0] = hdr->Patient.Name;
		if (strarray[0]) {
			mxSetField(Patient,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->Patient.Id;
		if (strarray[0]) {
			mxSetField(Patient,0,"Id",mxCreateCharMatrixFromStrings(1,strarray));
		}
#endif
		mxSetField(Patient,0,"Handedness",mxCreateDoubleScalar(hdr->Patient.Handedness));

		mxSetField(Patient,0,"Sex",mxCreateDoubleScalar(hdr->Patient.Sex));
		mxSetField(Patient,0,"Weight",mxCreateDoubleScalar((double)hdr->Patient.Weight));
		mxSetField(Patient,0,"Height",mxCreateDoubleScalar((double)hdr->Patient.Height));
		mxSetField(Patient,0,"Birthday",mxCreateDoubleScalar(ldexp(hdr->Patient.Birthday,-32)));

		double d;
		if (hdr->Patient.Weight==0)		d = NAN;	// not-a-number		
		else if (hdr->Patient.Weight==255)	d = INFINITY;	// Overflow
		else					d = (double)hdr->Patient.Weight;
		mxSetField(Patient,0,"Weight",mxCreateDoubleScalar(d));
			
		if (hdr->Patient.Height==0)		d = NAN;	// not-a-number		
		else if (hdr->Patient.Height==255)	d = INFINITY;	// Overflow
		else					d = (double)hdr->Patient.Height;
		mxSetField(Patient,0,"Height",mxCreateDoubleScalar(d));
	
		/* Manufacturer Information */ 
		const char *manufacturer_fields[] = {"Name","Model","Version","SerialNumber",NULL};
		for (numfields=0; manufacturer_fields[numfields++] != 0; );
		Manufacturer = mxCreateStructMatrix(1, 1, --numfields, manufacturer_fields);

#ifdef __LIBBIOSIG2_H__
		strarray[0] = biosig_get_manufacturer_name(hdr);
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_manufacturer_model(hdr);
		if (strarray[0]) {
			biosig_get_manufacturer_model(hdr);
			mxSetField(Manufacturer,0,"Model",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_manufacturer_version(hdr);
		if (strarray[0]) {
			biosig_get_manufacturer_version(hdr);
			mxSetField(Manufacturer,0,"Version",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_manufacturer_serial_number(hdr);
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"SerialNumber",mxCreateCharMatrixFromStrings(1,strarray));
		}
#else
		strarray[0] = hdr->ID.Manufacturer.Name;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->ID.Manufacturer.Model;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Model",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->ID.Manufacturer.Version;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Version",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->ID.Manufacturer.SerialNumber;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"SerialNumber",mxCreateCharMatrixFromStrings(1,strarray));
		}
#endif
		mxSetField(HDR,0,"Manufacturer",Manufacturer);


	if (VERBOSE_LEVEL>7) 
		fprintf(stdout,"[148] going for SCLOSE\n");

		mxSetField(HDR,0,"Patient",Patient);

#ifndef mexSOPEN
		plhs[1] = HDR; 
	}
#else
	plhs[0] = HDR; 
#endif

	if (VERBOSE_LEVEL>7) fprintf(stdout,"[151] going for SCLOSE\n");
#ifdef CHOLMOD_H
	hdr->Calib = NULL; // is refering to &RR, do not destroy
#endif
	if (VERBOSE_LEVEL>7) fprintf(stdout,"[156] SCLOSE finished\n");
	destructHDR(hdr);
	hdr = NULL; 
	if (VERBOSE_LEVEL>7) fprintf(stdout,"[157] SCLOSE finished\n");
};
Beispiel #8
0
static mxArray* matlab_create_value(gld_property *prop)
{
	mxArray *value=NULL;
	switch ( prop->get_type() ) {
	case PT_double:
	case PT_random:
	case PT_enduse:
	case PT_loadshape:
		value = mxCreateDoubleScalar(*(double*)prop->get_addr());
		break;
	case PT_complex:
		{
			value = mxCreateDoubleMatrix(1,1,mxCOMPLEX);
			complex *v = (complex*)prop->get_addr();
			*mxGetPr(value) = v->Re();
			*mxGetPi(value) = v->Im();
		}
		break;
	case PT_int16:
		value = mxCreateDoubleScalar((double)*(int16*)prop->get_addr());
		break;
	case PT_enumeration:
	case PT_int32:
		value = mxCreateDoubleScalar((double)*(int32*)prop->get_addr());
		break;
	case PT_set:
	case PT_int64:
		value = mxCreateDoubleScalar((double)*(int64*)prop->get_addr());
		break;
	case PT_timestamp:
		value = mxCreateDoubleScalar((double)*(TIMESTAMP*)prop->get_addr());
		break;
	case PT_bool:
		value = mxCreateDoubleScalar((double)*(bool*)prop->get_addr());
		break;
	case PT_char8:
	case PT_char32:
	case PT_char256:
	case PT_char1024:
		{
			const char *str[] = {(char*)prop->get_addr()};
			value = mxCreateCharMatrixFromStrings(mwSize(1),str); 
		}
		break;
	case PT_double_array:
		{
			double_array *data = (double_array*)prop->get_addr();
			size_t n=data->get_rows(), m=data->get_cols();
			value = mxCreateDoubleMatrix(0,0,mxREAL);
			double *copy = (double*)mxMalloc(m*n);
			for ( int c=0 ; c<m ; c++ )
			{
				for ( int r=0 ; r<n ; r++ )
				{
					copy[c*m+r] = data->get_at(r,c);
				}
			}
			mxSetPr(value,copy);
			mxSetM(value,m);
			mxSetN(value,n);
		}
		break;
	case PT_complex_array:
		// TODO
		break;
	default:
		value = NULL;
		break;
	}
	return value;
}
Beispiel #9
0
EXPORT bool glx_init(glxlink *mod)
{
	gl_verbose("initializing matlab link");
	gl_verbose("PATH=%s", getenv("PATH"));

	// initialize matlab engine
	MATLABLINK *matlab = (MATLABLINK*)mod->get_data();
	matlab->status = 0;
#ifdef WIN32
	if ( matlab->command )
		matlab->engine = engOpen(matlab->command);
	else
		matlab->engine = engOpenSingleUse(NULL,NULL,&matlab->status);
	if ( matlab->engine==NULL )
	{
		gl_error("matlab engine start failed, status code is '%d'", matlab->status);
		return false;
	}
#else
	matlab->engine = engOpen(matlab->command);
	if ( matlab->engine==NULL )
	{
		gl_error("matlab engine start failed");
		return false;
	}
#endif

	// set the output buffer
	if ( matlab->output_buffer!=NULL )
		engOutputBuffer(matlab->engine,matlab->output_buffer,(int)matlab->output_size);

	// setup matlab engine
	engSetVisible(matlab->engine,window_show(matlab));

	gl_debug("matlab link is open");

	// special values needed by matlab
	mxArray *ts_never = mxCreateDoubleScalar((double)(TIMESTAMP)TS_NEVER);
	engPutVariable(matlab->engine,"TS_NEVER",ts_never);
	mxArray *ts_error = mxCreateDoubleScalar((double)(TIMESTAMP)TS_INVALID);
	engPutVariable(matlab->engine,"TS_ERROR",ts_error);
	mxArray *gld_ok = mxCreateDoubleScalar((double)(bool)true);
	engPutVariable(matlab->engine,"GLD_OK",gld_ok);
	mxArray *gld_err = mxCreateDoubleScalar((double)(bool)false);
	engPutVariable(matlab->engine,"GLD_ERROR",gld_err);

	// set the workdir
	if ( strcmp(matlab->workdir,"")!=0 )
	{
#ifdef WIN32
		_mkdir(matlab->workdir);
#else
		mkdir(matlab->workdir,0750);
#endif
		if ( matlab->workdir[0]=='/' )
			matlab_exec(matlab,"cd '%s'", matlab->workdir);
		else
			matlab_exec(matlab,"cd '%s/%s'", getcwd(NULL,0),matlab->workdir);
	}

	// run the initialization command(s)
	if ( matlab->init )
	{
		mxArray *ans = matlab_exec(matlab,"%s",matlab->init);
		if ( ans && mxIsDouble(ans) && (bool)*mxGetPr(ans)==false )
		{
			gl_error("matlab init failed");
			return false;
		}
		else if ( ans && mxIsChar(ans) )
		{
			int buflen = (mxGetM(ans) * mxGetN(ans)) + 1;
			char *string =(char*)malloc(buflen);
			int status_error = mxGetString(ans, string, buflen);
			if (status_error == 0)
			{
				gl_error("'%s'",string);
				return false;
			}
			else
			{			
				gl_error("Did not catch Matlab error");
				return false;
			}
		}
	}

	if ( matlab->rootname!=NULL )
	{
		// build gridlabd data
		mwSize dims[] = {1,1};
		mxArray *gridlabd_struct = mxCreateStructArray(2,dims,0,NULL);

		///////////////////////////////////////////////////////////////////////////
		// build global data
		LINKLIST *item;
		mxArray *global_struct = mxCreateStructArray(2,dims,0,NULL);
		for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) )
		{
			char *name = mod->get_name(item);
			GLOBALVAR *var = mod->get_globalvar(item);
			mxArray *var_struct = NULL;
			mwIndex var_index;
			if ( var==NULL ) continue;

			// do not map module or structured globals
			if ( strchr(var->prop->name,':')!=NULL )
			{
				// ignore module globals here
			}
			else if ( strchr(var->prop->name,'.')!=NULL )
			{
				char struct_name[256];
				if ( sscanf(var->prop->name,"%[^.]",struct_name)==0 )
				{
					gld_property prop(var);
					var_index = mxAddField(global_struct,prop.get_name());
					var_struct = matlab_create_value(&prop);
					if ( var_struct!=NULL )
					{
						//mod->add_copyto(var->prop->addr,mxGetData(var_struct));
						mxSetFieldByNumber(global_struct,0,var_index,var_struct);
					}
				}
			}
			else // simple data
			{
				gld_property prop(var);
				var_index = mxAddField(global_struct,prop.get_name());
				var_struct = matlab_create_value(&prop);
				if ( var_struct!=NULL )
				{
					//mod->add_copyto(var->prop->addr,mxGetData(var_struct));
					mxSetFieldByNumber(global_struct,0,var_index,var_struct);
				}
			}

			// update export list
			if ( var_struct!=NULL )
			{
				mod->set_addr(item,(void*)var_struct);
				mod->set_index(item,(size_t)var_index);
			}
		}

		// add globals structure to gridlabd structure
		mwIndex gridlabd_index = mxAddField(gridlabd_struct,"global");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,global_struct);

		///////////////////////////////////////////////////////////////////////////
		// build module data
		dims[0] = dims[1] = 1;
		mxArray *module_struct = mxCreateStructArray(2,dims,0,NULL);

		// add modules
		for ( MODULE *module = callback->module.getfirst() ; module!=NULL ; module=module->next )
		{
			// create module info struct
			mwIndex dims[] = {1,1};
			mxArray *module_data = mxCreateStructArray(2,dims,0,NULL);
			mwIndex module_index = mxAddField(module_struct,module->name);
			mxSetFieldByNumber(module_struct,0,module_index,module_data);
			
			// create version info struct
			const char *version_fields[] = {"major","minor"};
			mxArray *version_data = mxCreateStructArray(2,dims,sizeof(version_fields)/sizeof(version_fields[0]),version_fields);
			mxArray *major_data = mxCreateDoubleScalar((double)module->major);
			mxArray *minor_data = mxCreateDoubleScalar((double)module->minor);
			mxSetFieldByNumber(version_data,0,0,major_data);
			mxSetFieldByNumber(version_data,0,1,minor_data);

			// attach version info to module info
			mwIndex version_index = mxAddField(module_data,"version");
			mxSetFieldByNumber(module_data,0,version_index,version_data);

		}
		gridlabd_index = mxAddField(gridlabd_struct,"module");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,module_struct);

		///////////////////////////////////////////////////////////////////////////
		// build class data
		dims[0] = dims[1] = 1;
		mxArray *class_struct = mxCreateStructArray(2,dims,0,NULL);
		gridlabd_index = mxAddField(gridlabd_struct,"class");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,class_struct);
		mwIndex class_id[1024]; // index into class struct
		memset(class_id,0,sizeof(class_id));

		// add classes
		for ( CLASS *oclass = callback->class_getfirst() ; oclass!=NULL ; oclass=oclass->next )
		{
			// count objects in this class
			mwIndex dims[] = {0,1};
			for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
			{
				OBJECT *obj = mod->get_object(item);
				if ( obj==NULL || obj->oclass!=oclass ) continue;
				dims[0]++;
			}
			if ( dims[0]==0 ) continue;
			mxArray *runtime_struct = mxCreateStructArray(2,dims,0,NULL);

			// add class 
			mwIndex class_index = mxAddField(class_struct,oclass->name);
			mxSetFieldByNumber(class_struct,0,class_index,runtime_struct);

			// add properties to class
			for ( PROPERTY *prop=oclass->pmap ; prop!=NULL && prop->oclass==oclass ; prop=prop->next )
			{
				mwIndex dims[] = {1,1};
				mxArray *property_struct = mxCreateStructArray(2,dims,0,NULL);
				mwIndex runtime_index = mxAddField(runtime_struct,prop->name);
				mxSetFieldByNumber(runtime_struct,0,runtime_index,property_struct);
			}

			// add objects to class
			for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
			{
				OBJECT *obj = mod->get_object(item);
				if ( obj==NULL || obj->oclass!=oclass ) continue;
				mwIndex index = class_id[obj->oclass->id]++;
				
				// add properties to class
				for ( PROPERTY *prop=oclass->pmap ; prop!=NULL && prop->oclass==oclass ; prop=prop->next )
				{
					gld_property p(obj,prop);
					mxArray *data = matlab_create_value(&p);
					mxSetField(runtime_struct,index,prop->name,data);
				}

				// update export list
				mod->set_addr(item,(void*)runtime_struct);
				mod->set_index(item,(size_t)index);
			}
		}

		///////////////////////////////////////////////////////////////////////////
		// build the object data
		dims[0] = 0;
		for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
		{
			if ( mod->get_object(item)!=NULL ) dims[0]++;
		}
		dims[1] = 1;
		memset(class_id,0,sizeof(class_id));
		const char *objfields[] = {"name","class","id","parent","rank","clock","valid_to","schedule_skew",
			"latitude","longitude","in","out","rng_state","heartbeat","lock","flags"};
		mxArray *object_struct = mxCreateStructArray(2,dims,sizeof(objfields)/sizeof(objfields[0]),objfields);
		mwIndex n=0;
		for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
		{
			OBJECT *obj = mod->get_object(item);
			if ( obj==NULL ) continue;
			class_id[obj->oclass->id]++; // index into class struct

			const char *objname[] = {obj->name&&isdigit(obj->name[0])?NULL:obj->name};
			const char *oclassname[] = {obj->oclass->name};

			if (obj->name) mxSetFieldByNumber(object_struct,n,0,mxCreateCharMatrixFromStrings(mwSize(1),objname));
			mxSetFieldByNumber(object_struct,n,1,mxCreateCharMatrixFromStrings(mwSize(1),oclassname));
			mxSetFieldByNumber(object_struct,n,2,mxCreateDoubleScalar((double)class_id[obj->oclass->id]));
			if (obj->parent) mxSetFieldByNumber(object_struct,n,3,mxCreateDoubleScalar((double)obj->parent->id+1));
			mxSetFieldByNumber(object_struct,n,4,mxCreateDoubleScalar((double)obj->rank));
			mxSetFieldByNumber(object_struct,n,5,mxCreateDoubleScalar((double)obj->clock));
			mxSetFieldByNumber(object_struct,n,6,mxCreateDoubleScalar((double)obj->valid_to));
			mxSetFieldByNumber(object_struct,n,7,mxCreateDoubleScalar((double)obj->schedule_skew));
			if ( isfinite(obj->latitude) ) mxSetFieldByNumber(object_struct,n,8,mxCreateDoubleScalar((double)obj->latitude));
			if ( isfinite(obj->longitude) ) mxSetFieldByNumber(object_struct,n,9,mxCreateDoubleScalar((double)obj->longitude));
			mxSetFieldByNumber(object_struct,n,10,mxCreateDoubleScalar((double)obj->in_svc));
			mxSetFieldByNumber(object_struct,n,11,mxCreateDoubleScalar((double)obj->out_svc));
			mxSetFieldByNumber(object_struct,n,12,mxCreateDoubleScalar((double)obj->rng_state));
			mxSetFieldByNumber(object_struct,n,13,mxCreateDoubleScalar((double)obj->heartbeat));
			mxSetFieldByNumber(object_struct,n,14,mxCreateDoubleScalar((double)obj->lock));
			mxSetFieldByNumber(object_struct,n,15,mxCreateDoubleScalar((double)obj->flags));
			n++;
		}
		gridlabd_index = mxAddField(gridlabd_struct,"object");
		mxSetFieldByNumber(gridlabd_struct,0,gridlabd_index,object_struct);

		///////////////////////////////////////////////////////////////////////////
		// post the gridlabd structure
		matlab->root = gridlabd_struct;
		engPutVariable(matlab->engine,matlab->rootname,matlab->root);
	}

	///////////////////////////////////////////////////////////////////////////
	// build the import/export data
	for ( LINKLIST *item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) )
	{
		OBJECTPROPERTY *objprop = mod->get_export(item);
		if ( objprop==NULL ) continue;

		// add to published items
		gld_property prop(objprop->obj,objprop->prop);
		item->addr = (mxArray*)matlab_create_value(&prop);
		engPutVariable(matlab->engine,item->name,(mxArray*)item->addr);
	}
	for ( LINKLIST *item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) )
	{
		OBJECTPROPERTY *objprop = mod->get_import(item);
		if ( objprop==NULL ) continue;

		// check that not already in export list
		LINKLIST *export_item;
		bool found=false;
		for ( export_item=mod->get_exports() ; export_item!=NULL ; export_item=mod->get_next(export_item) )
		{
			OBJECTPROPERTY *other = mod->get_export(item);
			if ( memcmp(objprop,other,sizeof(OBJECTPROPERTY)) )
				found=true;
		}
		if ( !found )
		{
			gld_property prop(objprop->obj,objprop->prop);
			item->addr = (mxArray*)matlab_create_value(&prop);
			engPutVariable(matlab->engine,item->name,(mxArray*)item->addr);
		}
	}

	static int32 matlab_flag = 1;
	gl_global_create("MATLAB",PT_int32,&matlab_flag,PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"indicates that MATLAB is available",NULL);
	mod->last_t = gl_globalclock;
	return true;
}