/* * 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])) ); } }
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]); } }
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; }
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; } }
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"); };
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; }
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; }